def done(self): """ Discard internal data structures. This should be called after all information on the latest bundle's results have been extracted already. """ GeometryManager.done(self) if hasattr(self, '_global'): del self._global if hasattr(self, '_idxs'): del self._idxs
def done(self): """ Discard internal data structures. This should be called after all information on the latest bundle's results have been extracted already. """ if hasattr(self, "_vertices"): del self._vertices if hasattr(self, "_idxs"): del self._norm del self._idxs GeometryManager.done(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]. 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. """ GeometryManager.find_intersections(self, frame, ray_bundle) #print 'ffffframe', frame d = ray_bundle.get_directions() v = ray_bundle.get_vertices() - frame[:3, 3][:, None] n = ray_bundle.get_num_rays() # Vet out parallel rays: dt = N.dot(d.T, frame[:3, 2]) unparallel = abs(dt) > 1e-10 # `params` holds the parametric location of intersections along the ray params = N.empty(n) params.fill(N.inf) # print 'uuuunparallele', unparallel # print 'dt',dt[unparallel] #print 'dt_parallll', dt[unparallel] vt = N.dot(frame[:3, 2], v[:, unparallel]) params[unparallel] = -vt / dt[unparallel] # Takes into account a negative depth # Note that only the 3rd row of params is relevant here! negative = params < 1e-10 params[negative] = N.inf self._params = params self._backside = dt > 1e-10 return params
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]. 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. """ GeometryManager.find_intersections(self, frame, ray_bundle) d = ray_bundle.get_directions() v = ray_bundle.get_vertices() - frame[:3,3][:,None] n = ray_bundle.get_num_rays() # Vet out parallel rays: dt = N.dot(d.T, frame[:3,2]) unparallel = abs(dt) > 1e-10 # `params` holds the parametric location of intersections along the ray params = N.empty(n) params.fill(N.inf) vt = N.dot(frame[:3,2], v[:,unparallel]) params[unparallel] = -vt/dt[unparallel] # Takes into account a negative depth # Note that only the 3rd row of params is relevant here! negative = params < 0 params[negative] = N.Inf self._params = params self._backside = dt > 0 return params
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. 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. """ GeometryManager.find_intersections(self, frame, ray_bundle) d = ray_bundle.get_directions() v = ray_bundle.get_vertices() n = ray_bundle.get_num_rays() c = self._working_frame[:3, 3] params = N.empty(n) params.fill(N.inf) vertices = N.empty((3, n)) # Gets the relevant A, B, C from whichever quadric surface, see [1] A, B, C = self.get_ABC(ray_bundle) # Identify quadric intersections delta = B**2. - 4. * A * C any_inters = delta >= 1e-6 num_inters = any_inters.sum() if num_inters == 0: self._vertices = vertices self._params = params # return params A = A[any_inters] B = B[any_inters] C = C[any_inters] delta = N.sqrt(B**2. - 4. * A * C) hits = N.empty((2, num_inters)) hits.fill(N.nan) # Identify linear equations is_linear = A == 0 # Identify B = 0 cases is_Bnull = B == 0 # Solve linear intersections hits[:, is_linear & ~is_Bnull] = N.tile( -C[is_linear & ~is_Bnull] / B[is_linear & ~is_Bnull], (2, 1)) # Solve B = 0 cases (give bad information on N.sign(0)) hits[0, ~is_linear & is_Bnull] = -N.sqrt( -C[~is_linear & is_Bnull] / A[~is_linear & is_Bnull]) hits[1, ~is_linear & is_Bnull] = N.sqrt(-C[~is_linear & is_Bnull] / A[~is_linear & is_Bnull]) # Solve quadric regular intersections q = -0.5 * (B + N.sign(B) * delta) hits[0, ~is_linear & ~is_Bnull] = q[~is_linear & ~is_Bnull] / A[~is_linear & ~is_Bnull] hits[1, ~is_linear & ~is_Bnull] = C[~is_linear & ~is_Bnull] / q[~is_linear & ~is_Bnull] # Get intersection coordinates using rays parameters inters_coords = v[:, any_inters] + d[:, any_inters] * hits.reshape( 2, 1, -1) # Quadrics can have two intersections. Here we allow child classes # to choose based on own method: select = self._select_coords(inters_coords, hits) not_missed = ~N.isnan(select) any_inters[any_inters] = not_missed select = N.array(select[not_missed], dtype=N.int_) params[any_inters] = N.choose(select, hits[:, not_missed]) vertices[:, any_inters] = N.choose(select, inters_coords[..., not_missed]) # Storage for later reference: self._vertices = vertices self._params = params # return params
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. 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. """ GeometryManager.find_intersections(self, frame, ray_bundle) d = ray_bundle.get_directions() v = ray_bundle.get_vertices() n = ray_bundle.get_num_rays() c = self._working_frame[:3,3] params = N.empty(n) params.fill(N.inf) vertices = N.empty((3,n)) # Gets the relevant A, B, C from whichever quadric surface, see [1] A, B, C = self.get_ABC(ray_bundle) # Identify quadric intersections delta = B**2. - 4.*A*C any_inters = delta >= 1e-9 num_inters = any_inters.sum() if num_inters == 0: self._vertices = vertices self._params = params # return params A = A[any_inters] B = B[any_inters] C = C[any_inters] delta = N.sqrt(B**2. - 4.*A*C) hits = N.empty((2,num_inters)) hits.fill(N.nan) # Identify linear equations is_linear = A == 0 # Identify B = 0 cases is_Bnull = B == 0 # Solve linear intersections hits[:,is_linear & ~is_Bnull] = N.tile(-C[is_linear & ~is_Bnull]/B[is_linear & ~is_Bnull], (2,1)) # Solve B = 0 cases (give bad information on N.sign(0)) hits[0,~is_linear & is_Bnull] = -N.sqrt(-C[~is_linear & is_Bnull]/A[~is_linear & is_Bnull]) hits[1,~is_linear & is_Bnull] = N.sqrt(-C[~is_linear & is_Bnull]/A[~is_linear & is_Bnull]) # Solve quadric regular intersections q = -0.5*(B+N.sign(B)*delta) hits[0,~is_linear & ~is_Bnull] = q[~is_linear & ~is_Bnull]/A[~is_linear & ~is_Bnull] hits[1,~is_linear & ~is_Bnull] = C[~is_linear & ~is_Bnull]/q[~is_linear & ~is_Bnull] # Get intersection coordinates using rays parameters inters_coords = v[:,any_inters] + d[:,any_inters]*hits.reshape(2,1,-1) # Quadrics can have two intersections. Here we allow child classes # to choose based on own method: select = self._select_coords(inters_coords, hits) not_missed = ~N.isnan(select) any_inters[any_inters] = not_missed select = N.array(select[not_missed], dtype=N.int_) params[any_inters] = N.choose(select, hits[:,not_missed]) vertices[:,any_inters] = N.choose(select, inters_coords[...,not_missed]) # Storage for later reference: self._vertices = vertices self._params = params # return params
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. 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. """ GeometryManager.find_intersections(self, frame, ray_bundle) d = ray_bundle.get_directions() v = ray_bundle.get_vertices() n = ray_bundle.get_num_rays() c = self._working_frame[:3, 3] params = N.empty(n) params.fill(N.inf) vertices = N.empty((3, n)) # Gets the relevant A, B, C from whichever quadric surface, see [1] A, B, C = self.get_ABC(ray_bundle) delta = B**2 - 4 * A * C any_inters = delta >= 0 num_inters = any_inters.sum() if num_inters == 0: self._vertices = vertices return params A = A[any_inters] B = B[any_inters] C = C[any_inters] delta = N.sqrt(delta[any_inters]) pm = N.c_[[-1, 1]] hits = N.empty((2, num_inters)) almost_planar = A <= 1e-10 really_quadric = ~almost_planar hits[:, almost_planar] = N.tile(-C[almost_planar] / B[almost_planar], (2, 1)) hits[:,really_quadric] = \ (-B[really_quadric] + pm*delta[really_quadric])/(2*A[really_quadric]) inters_coords = v[:, any_inters] + d[:, any_inters] * hits.reshape( 2, 1, -1) # Quadrics can have two intersections. Here we allow child classes # to choose based on own method: select = self._select_coords(inters_coords, hits) not_missed = ~N.isnan(select) any_inters[any_inters] = not_missed select = N.array(select[not_missed], dtype=N.int_) params[any_inters] = N.choose(select, hits[:, not_missed]) vertices[:, any_inters] = N.choose(select, inters_coords[..., not_missed]) # Storage for later reference: self._vertices = vertices return params
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. 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. """ GeometryManager.find_intersections(self, frame, ray_bundle) d = ray_bundle.get_directions() v = ray_bundle.get_vertices() n = ray_bundle.get_num_rays() c = self._working_frame[:3, 3] params = N.empty(n) params.fill(N.inf) vertices = N.empty((3, n)) # Gets the relevant A, B, C from whichever quadric surface, see [1] A, B, C = self.get_ABC(ray_bundle) delta = B ** 2 - 4 * A * C any_inters = delta >= 0 num_inters = any_inters.sum() if num_inters == 0: self._vertices = vertices return params A = A[any_inters] B = B[any_inters] C = C[any_inters] delta = N.sqrt(delta[any_inters]) pm = N.c_[[-1, 1]] hits = N.empty((2, num_inters)) almost_planar = A <= 1e-10 really_quadric = ~almost_planar hits[:, almost_planar] = N.tile(-C[almost_planar] / B[almost_planar], (2, 1)) hits[:, really_quadric] = (-B[really_quadric] + pm * delta[really_quadric]) / (2 * A[really_quadric]) inters_coords = v[:, any_inters] + d[:, any_inters] * hits.reshape(2, 1, -1) # Quadrics can have two intersections. Here we allow child classes # to choose based on own method: select = self._select_coords(inters_coords, hits) not_missed = ~N.isnan(select) any_inters[any_inters] = not_missed select = N.array(select[not_missed], dtype=N.int_) params[any_inters] = N.choose(select, hits[:, not_missed]) vertices[:, any_inters] = N.choose(select, inters_coords[..., not_missed]) # Storage for later reference: self._vertices = vertices return params