/** * Fire the test ray at the instrument and perform a bread-first search of the * object tree to find the objects that were intersected. * @param testRay :: An input/output parameter that defines the track and accumulates the * intersection results */ void InstrumentRayTracer::fireRay(Track & testRay) const { // Go through the instrument tree and see if we get any hits by // (a) first testing the bounding box and if we're inside that then // (b) test the lower components. std::deque<IComponent_const_sptr> nodeQueue; //Start at the root of the tree nodeQueue.push_back(m_instrument); IComponent_const_sptr node; while( !nodeQueue.empty() ) { node = nodeQueue.front(); nodeQueue.pop_front(); BoundingBox bbox; node->getBoundingBox(bbox); // Quick test. If this suceeds moved on to test the children if( bbox.doesLineIntersect(testRay) ) { if( ICompAssembly_const_sptr assembly = boost::dynamic_pointer_cast<const ICompAssembly>(node) ) { assembly->testIntersectionWithChildren(testRay, nodeQueue); } else { throw Kernel::Exception::NotImplementedError("Implement non-comp assembly interactions"); } } } }
/** * Given a track, fill the track with valid section * @param UT :: Initial track * @return Number of segments added */ int MeshObject::interceptSurface(Geometry::Track &UT) const { int originalCount = UT.count(); // Number of intersections original track BoundingBox bb = getBoundingBox(); if (!bb.doesLineIntersect(UT)) { return 0; } std::vector<Kernel::V3D> intersectionPoints; std::vector<TrackDirection> entryExit; getIntersections(UT.startPoint(), UT.direction(), intersectionPoints, entryExit); if (intersectionPoints.empty()) return 0; // Quit if no intersections found // For a 3D mesh, a ray may intersect several segments for (size_t i = 0; i < intersectionPoints.size(); ++i) { UT.addPoint(entryExit[i], intersectionPoints[i], *this); } UT.buildLink(); return UT.count() - originalCount; }