# Path: tracer/flat_surface.py
# class FiniteFlatGM(FlatGeometryManager):
#     """
#     Calculates intersection points before select_rays(), so that those outside
#     the aperture can be dropped, and on select_rays trims it.
#     """
#     def __init__(self):
#         FlatGeometryManager.__init__(self)
#     
#     def find_intersections(self, frame, ray_bundle):
#         """
#         Register the working frame and ray bundle, calculate intersections
#         and save the parametric locations of intersection on the surface.
#         Algorithm taken from [1].
#         
#         In this class, global- and local-coordinates of intersection points
#         are calculated and kept. _global is handled in select_rays(), but
#         _local must be taken care off by subclasses.
#         
#         Arguments:
#         frame - the current frame, represented as a homogenous transformation
#             matrix stored in a 4x4 array.
#         ray_bundle - a RayBundle object with the incoming rays' data.
#         
#         Returns:
#         A 1D array with the parametric position of intersection along each of
#             the rays. Rays that missed the surface return +infinity.
#         """
#         ray_prms = FlatGeometryManager.find_intersections(self, frame, ray_bundle)
#         v = self._working_bundle.get_vertices() 
#         d = self._working_bundle.get_directions()
#         p = self._params
#         del self._params
#         
#         # Global coordinates on the surface:
#         oldsettings = N.seterr(invalid='ignore')
#         self._global = v + p[None,:]*d
#         N.seterr(**oldsettings)
#         # above we ignore invalid values. Those rays can't be selected anyway.
#         
#         # Local should be deleted by children in their find_intersections.
#         self._local = N.dot(N.linalg.inv(self._working_frame),
#             N.vstack((self._global, N.ones(self._global.shape[1]))))
#         
#         return ray_prms
#         
#     def select_rays(self, idxs):
#         """
#         Inform the geometry manager that only the given rays are to be used,
#         so that internal data size is kept small.
#         
#         Arguments: 
#         idxs - an index array stating which rays of the working bundle
#             are active.
#         """
#         self._idxs = idxs
#         self._backside = N.nonzero(self._backside[idxs])[0]
#         self._global = self._global[:,idxs].copy()


import numpy as np
from .flat_surface import FiniteFlatGM
            the origin, on the XY plane. The 3rd vertex is the origin.
        """
        FiniteFlatGM.__init__(self)
        self.set_vertices(verts)
    
    def set_vertices(self, verts):
        """
        replace the defined vertices with new ones.
        """
        self._verts = verts
    
    def find_intersections(self, frame, ray_bundle):
        """
        Register the working frame and ray bundle, calculate intersections
        and save the parametric locations of intersection on the surface.
        plane intersection is done in the base class, triangle trimming done
        here.
        
        In this class, global coordinates of intersection points
        are calculated and kept. _global is handled in select_rays().
        
        Arguments:
        frame - the current frame, represented as a homogenous transformation
            matrix stored in a 4x4 array.
        ray_bundle - a RayBundle object with the incoming rays' data.
        
        Returns:
        A 1D array with the parametric position of intersection along each of
            the rays. Rays that missed the surface return +infinity.
        """

# Path: tracer/flat_surface.py
# class FiniteFlatGM(FlatGeometryManager):
#     """
#     Calculates intersection points before select_rays(), so that those outside
#     the aperture can be dropped, and on select_rays trims it.
#     """
#     def __init__(self):
#         FlatGeometryManager.__init__(self)
#     
#     def find_intersections(self, frame, ray_bundle):
#         """
#         Register the working frame and ray bundle, calculate intersections
#         and save the parametric locations of intersection on the surface.
#         Algorithm taken from [1].
#         
#         In this class, global- and local-coordinates of intersection points
#         are calculated and kept. _global is handled in select_rays(), but
#         _local must be taken care off by subclasses.
#         
#         Arguments:
#         frame - the current frame, represented as a homogenous transformation
#             matrix stored in a 4x4 array.
#         ray_bundle - a RayBundle object with the incoming rays' data.
#         
#         Returns:
#         A 1D array with the parametric position of intersection along each of
#             the rays. Rays that missed the surface return +infinity.
#         """
#         ray_prms = FlatGeometryManager.find_intersections(self, frame, ray_bundle)
#         v = self._working_bundle.get_vertices() 
#         d = self._working_bundle.get_directions()
#         p = self._params
#         del self._params
#         
#         # Global coordinates on the surface:
#         oldsettings = N.seterr(invalid='ignore')
#         self._global = v + p[None,:]*d
#         N.seterr(**oldsettings)
#         # above we ignore invalid values. Those rays can't be selected anyway.
#         
#         # Local should be deleted by children in their find_intersections.
#         self._local = N.dot(N.linalg.inv(self._working_frame),
#             N.vstack((self._global, N.ones(self._global.shape[1]))))
#         
#         return ray_prms
#         
#     def select_rays(self, idxs):
#         """
#         Inform the geometry manager that only the given rays are to be used,
#         so that internal data size is kept small.
#         
#         Arguments: 
#         idxs - an index array stating which rays of the working bundle
#             are active.
#         """
#         self._idxs = idxs
#         self._backside = N.nonzero(self._backside[idxs])[0]
#         self._global = self._global[:,idxs].copy()


# Path: tracer/triangular_face.py
import numpy as np
from .flat_surface import FiniteFlatGM

            the origin, on the XY plane. The 3rd vertex is the origin.
        """
        FiniteFlatGM.__init__(self)
        self.set_vertices(verts)
    
    def set_vertices(self, verts):
        """
        replace the defined vertices with new ones.
        """
        self._verts = verts
    
    def find_intersections(self, frame, ray_bundle):
        """
        Register the working frame and ray bundle, calculate intersections
        and save the parametric locations of intersection on the surface.
        plane intersection is done in the base class, triangle trimming done
        here.
        
        In this class, global coordinates of intersection points
        are calculated and kept. _global is handled in select_rays().
        
        Arguments:
        frame - the current frame, represented as a homogenous transformation
            matrix stored in a 4x4 array.
        ray_bundle - a RayBundle object with the incoming rays' data.
        
        Returns:
        A 1D array with the parametric position of intersection along each of
            the rays. Rays that missed the surface return +infinity.
        """

        ray_prms = FiniteFlatGM.find_intersections(self, frame, ray_bundle)