diff --git a/src/osgUtil/PlaneIntersector.cpp b/src/osgUtil/PlaneIntersector.cpp index 1ceb4afed..829e22da6 100644 --- a/src/osgUtil/PlaneIntersector.cpp +++ b/src/osgUtil/PlaneIntersector.cpp @@ -24,12 +24,308 @@ using namespace osgUtil; namespace PlaneIntersectorUtils { - struct TriangleIntersection + struct RefPolyline : public osg::Referenced { - osg::Vec3d v[2]; + typedef std::vector Polyline; + Polyline _polyline; + + void reverse() + { + unsigned int s=0; + unsigned int e=_polyline.size()-1; + for(; s TriangleIntersections; + class PolylineConnector + { + public: + + typedef std::map > PolylineMap; + typedef std::vector< osg::ref_ptr > PolylineList; + + PolylineList _polylines; + PolylineMap _startPolylineMap; + PolylineMap _endPolylineMap; + + void add(const osg::Vec3d& v1, const osg::Vec3d& v2) + { + if (v1==v2) return; + + PolylineMap::iterator v1_start_itr = _startPolylineMap.find(v1); + PolylineMap::iterator v1_end_itr = _endPolylineMap.find(v1); + + PolylineMap::iterator v2_start_itr = _startPolylineMap.find(v2); + PolylineMap::iterator v2_end_itr = _endPolylineMap.find(v2); + + unsigned int v1_connections = 0; + if (v1_start_itr != _startPolylineMap.end()) ++v1_connections; + if (v1_end_itr != _endPolylineMap.end()) ++v1_connections; + + unsigned int v2_connections = 0; + if (v2_start_itr != _startPolylineMap.end()) ++v2_connections; + if (v2_end_itr != _endPolylineMap.end()) ++v2_connections; + + if (v1_connections==0) // v1 is no connected to anything. + { + if (v2_connections==0) + { + // new polyline + newline(v1,v2); + } + else if (v2_connections==1) + { + // v2 must connect to either a start or an end. + if (v2_start_itr != _startPolylineMap.end()) + { + insertAtStart(v1, v2_start_itr); + } + else if (v2_end_itr != _endPolylineMap.end()) + { + insertAtEnd(v1, v2_end_itr); + } + else + { + osg::notify(osg::NOTICE)<<"Error: should not get here!"<_polyline.push_back(v1); + polyline->_polyline.push_back(v2); + _startPolylineMap[v1] = polyline; + _endPolylineMap[v2] = polyline; + } + + void insertAtStart(const osg::Vec3d& v, PolylineMap::iterator v_start_itr) + { + // put v1 at the start of its poyline + RefPolyline* polyline = v_start_itr->second.get(); + polyline->_polyline.insert(polyline->_polyline.begin(),v); + + // reinsert the polyine at the new v1 end + _startPolylineMap[v] = polyline; + + // remove the original entry + _startPolylineMap.erase(v_start_itr); + + } + + void insertAtEnd(const osg::Vec3d& v, PolylineMap::iterator v_end_itr) + { + // put v1 at the end of its poyline + RefPolyline* polyline = v_end_itr->second.get(); + polyline->_polyline.push_back(v); + + // reinsert the polyine at the new v1 end + _endPolylineMap[v] = polyline; + + // remove the original entry + _endPolylineMap.erase(v_end_itr); + + } + + void fuse_start_to_start(PolylineMap::iterator start1_itr, PolylineMap::iterator start2_itr) + { + osg::notify(osg::NOTICE)<<"Fusing start to start - DONE 2"< poly1 = start1_itr->second; + osg::ref_ptr poly2 = start2_itr->second; + + PolylineMap::iterator end1_itr = _endPolylineMap.find(poly1->_polyline.back()); + PolylineMap::iterator end2_itr = _endPolylineMap.find(poly2->_polyline.back()); + + // clean up the iterators associated with the original polylines + _startPolylineMap.erase(start1_itr); + _startPolylineMap.erase(start2_itr); + _endPolylineMap.erase(end1_itr); + _endPolylineMap.erase(end2_itr); + + // reverse the first polyline + poly1->reverse(); + + // add the second polyline to the first + poly1->_polyline.insert( poly1->_polyline.end(), + poly2->_polyline.begin(), poly2->_polyline.end() ); + + _startPolylineMap[poly1->_polyline.front()] = poly1; + _endPolylineMap[poly1->_polyline.back()] = poly1; + + } + + void fuse_start_to_end(PolylineMap::iterator start_itr, PolylineMap::iterator end_itr) + { + osg::notify(osg::NOTICE)<<"Fusing start to end - DONE"< end_poly = end_itr->second; + osg::ref_ptr start_poly = start_itr->second; + + PolylineMap::iterator end_start_poly_itr = _endPolylineMap.find(start_poly->_polyline.back()); + + // add start_poly to end of end_poly + end_poly->_polyline.insert( end_poly->_polyline.end(), + start_poly->_polyline.begin(), start_poly->_polyline.end() ); + + // reassign the end of the start poly so that it now points to the merged end_poly + end_start_poly_itr->second = end_poly; + + + // remove entries for the end of the end_poly and the start of the start_poly + _endPolylineMap.erase(end_itr); + _startPolylineMap.erase(start_itr); + } + + void fuse_end_to_end(PolylineMap::iterator end1_itr, PolylineMap::iterator end2_itr) + { + + osg::notify(osg::NOTICE)<<"Fusing end to end - DONE 3"< poly1 = end1_itr->second; + osg::ref_ptr poly2 = end2_itr->second; + + PolylineMap::iterator start1_itr = _startPolylineMap.find(poly1->_polyline.front()); + PolylineMap::iterator start2_itr = _startPolylineMap.find(poly2->_polyline.front()); + + // clean up the iterators associated with the original polylines + _startPolylineMap.erase(start1_itr); + _startPolylineMap.erase(start2_itr); + _endPolylineMap.erase(end1_itr); + _endPolylineMap.erase(end2_itr); + + // reverse the first polyline + poly2->reverse(); + + // add the second polyline to the first + poly1->_polyline.insert( poly1->_polyline.end(), + poly2->_polyline.begin(), poly2->_polyline.end() ); + + _startPolylineMap[poly1->_polyline.front()] = poly1; + _endPolylineMap[poly1->_polyline.back()] = poly1; + + } + + void report() + { + osg::notify(osg::NOTICE)<<"report()"<second->_polyline; + for(RefPolyline::Polyline::iterator pitr = polyline.begin(); + pitr != polyline.end(); + ++pitr) + { + osg::notify(osg::NOTICE)<<" "<<*pitr<