24 #ifndef __ODGIEXTENTS3DSPACETREE_H__
25 #define __ODGIEXTENTS3DSPACETREE_H__
36 #pragma warning(disable: 4244)
82 template <OdUInt32 NUM_AXIS, OdUInt32 MAX_DEPTH, OdUInt64 MAX_NODE_OBJECT,
class EE,
class P,
class OO>
friend class OdGiExtentsSpaceTree;
95 std::map<int, OdVector<O*, OdMemoryAllocator<O*> >* >* m_pObjectPointers;
109 m_pRightChild =
NULL;
112 m_pObjectPointers =
NULL;
113 if ( nTypeOfObjects > 0 )
114 m_iObjectsTypes = nTypeOfObjects;
122 releaseObjectsStore();
129 return (m_pLeftChild ==
NULL && m_pRightChild ==
NULL);
139 if ( m_pObjectPointers ==
NULL )
142 if ( iType < m_iObjectsTypes )
144 OD_TYPENAME std::map<int, OdVector<O*, OdMemoryAllocator<O*> >* >::iterator it = m_pObjectPointers->find(iType);
145 if ( it != m_pObjectPointers->end() )
157 if ( m_pObjectPointers ==
NULL )
158 m_pObjectPointers =
new std::map<int, OdVector<O*, OdMemoryAllocator<O*> >* >;
161 (*m_pObjectPointers)[iType] = pNewVector;
169 void releaseObjectsStore()
171 if ( m_pObjectPointers )
173 OD_TYPENAME std::map<int, OdVector<O*, OdMemoryAllocator<O*> >*>::iterator it = m_pObjectPointers->begin();
174 OD_TYPENAME std::map<int, OdVector<O*, OdMemoryAllocator<O*> >*>::iterator itEnd = m_pObjectPointers->end();
175 while ( it != itEnd )
182 m_pObjectPointers->clear();
183 delete m_pObjectPointers;
184 m_pObjectPointers =
NULL;
199 template <
class E,
class O>
214 template <OdUInt32 NUM_AXIS, OdUInt32 MAX_DEPTH, OdUInt64 MAX_NODE_OBJECT,
class E,
class P,
class O>
class OdGiExtentsSpaceTree
244 m_bIsAdaptive =
false;
245 m_iMaxNodeObjects = MAX_NODE_OBJECT;
258 if ( depth > MAX_DEPTH )
260 else if ( depth < 0 )
263 if ( m_pRootNode !=
NULL )
268 m_Nodes.push_back(m_pRootNode);
271 constructChilds(m_pRootNode, NUM_AXIS, depth, nTypeOfObjects);
281 while ( it != itEnd )
291 m_theSameObjects.clear();
292 m_theIntersectedLeaves.clear();
304 m_theSameObjects.clear();
306 if ( m_pRootNode ==
NULL )
309 nodeProcessObject(m_pRootNode, pObject, iObjectType, bCheckTheSame,
tol);
311 if ( m_theSameObjects.size() == 0 )
314 return m_theSameObjects.front();
323 if ( m_pRootNode ==
NULL )
326 if(m_pRootNode->m_extents.isValidExtents())
328 exts = m_pRootNode->m_extents;
336 m_theIntersectedLeaves.clear();
338 if ( m_pRootNode ==
NULL )
341 nodeProcessExtent(m_pRootNode, ext);
343 if ( m_theIntersectedLeaves.size() == 0 )
346 return &m_theIntersectedLeaves;
351 m_theIntersectedLeaves.clear();
353 if ( m_pRootNode ==
NULL )
356 nodeProcessPoint(m_pRootNode, pt);
358 if ( m_theIntersectedLeaves.size() == 0 )
361 return &m_theIntersectedLeaves;
369 if ( pParentNode ==
NULL )
375 m_Leaves.push_back(pParentNode);
382 P leftBounPoint = pParentNode->m_extents.maxPoint();
386 middlez(pParentNode->m_extents.maxPoint(), pParentNode->m_extents.minPoint(), leftBounPoint);
389 leftBounPoint.x = (pParentNode->m_extents.maxPoint().x + pParentNode->m_extents.minPoint().x)/2.;
392 leftBounPoint.y = (pParentNode->m_extents.maxPoint().y + pParentNode->m_extents.minPoint().y)/2.;
396 leftChildExtents.set(pParentNode->m_extents.minPoint(), leftBounPoint);
399 pParentNode->m_pLeftChild =
new OdGiExtentsSpaceNode<E,O>(pParentNode, leftChildExtents, axislevel > 1 ? pParentNode->m_iDepth : pParentNode->m_iDepth + 1, nTypeOfObjects);
400 m_Nodes.push_back(pParentNode->m_pLeftChild);
404 constructChilds(pParentNode->m_pLeftChild, axislevel-1, curDepth, nTypeOfObjects);
406 constructChilds(pParentNode->m_pLeftChild, NUM_AXIS, curDepth-1, nTypeOfObjects);
411 P rightBounPoint = pParentNode->m_extents.minPoint();
415 middlez(pParentNode->m_extents.maxPoint(), pParentNode->m_extents.minPoint(), rightBounPoint);
418 rightBounPoint.x = (pParentNode->m_extents.maxPoint().x + pParentNode->m_extents.minPoint().x)/2.;
421 rightBounPoint.y = (pParentNode->m_extents.maxPoint().y + pParentNode->m_extents.minPoint().y)/2.;
425 rightChildExtents.set(rightBounPoint, pParentNode->m_extents.maxPoint());
428 pParentNode->m_pRightChild =
new OdGiExtentsSpaceNode<E,O>(pParentNode, rightChildExtents, axislevel > 1 ? pParentNode->m_iDepth : pParentNode->m_iDepth + 1, nTypeOfObjects);
429 m_Nodes.push_back(pParentNode->m_pRightChild);
433 constructChilds(pParentNode->m_pRightChild, axislevel-1, curDepth, nTypeOfObjects);
435 constructChilds(pParentNode->m_pRightChild, NUM_AXIS, curDepth-1, nTypeOfObjects);
443 if ( pNode ==
NULL || pObject ==
NULL )
446 bool bIntersect = pObject->isInExtents(pNode->m_extents);
459 if ( pNodeObjects ==
NULL )
461 if ( m_iMaxNodeObjects > 0 )
462 pNodeObjects = pNode->initObjectList(iObjectType, m_iMaxNodeObjects+1);
464 pNodeObjects = pNode->initObjectList(iObjectType, 50);
473 while ( itNodes != itNodesEnd )
475 O* pObjectInList = *itNodes;
478 if ( pObjectInList->isEqual(pObject,
tol) )
480 m_theSameObjects.push_back(pObjectInList);
495 if ( m_bIsAdaptive && pNodeObjects->
size() > m_iMaxNodeObjects && pNode->m_iDepth <= MAX_DEPTH )
498 m_Leaves.remove(pNode);
501 constructChilds(pNode, NUM_AXIS, 1, pNode->m_iObjectsTypes);
504 for (
int i = 0; i < pNode->m_iObjectsTypes; i++)
511 while ( it != itEnd )
513 O* pObjectInList = *it;
517 nodeProcessObject(pNode->m_pLeftChild, pObjectInList, i,
false,
tol);
518 nodeProcessObject(pNode->m_pRightChild, pObjectInList, i,
false,
tol);
526 pNode->releaseObjectsStore();
531 nodeProcessObject(pNode->m_pLeftChild, pObject, iObjectType, bCheckTheSame,
tol);
532 nodeProcessObject(pNode->m_pRightChild, pObject, iObjectType, bCheckTheSame,
tol);
542 if ( pNode ==
NULL || !ext.isValidExtents() )
546 ext.intersectWith(pNode->m_extents, &isect);
548 if ( isect.isValidExtents() )
552 m_theIntersectedLeaves.push_back(pNode);
556 nodeProcessExtent(pNode->m_pLeftChild, ext);
557 nodeProcessExtent(pNode->m_pRightChild, ext);
570 if ( pNode->m_extents.contains(pt) )
574 m_theIntersectedLeaves.push_back(pNode);
578 nodeProcessPoint(pNode->m_pLeftChild, pt);
579 nodeProcessPoint(pNode->m_pRightChild, pt);
594 ptRes.
z = (pt1.
z + pt2.
z)/2.;
615 std::set<OdUInt64> m_edges;
618 std::set<OdUInt64> m_invisibleedges;
638 m_invisibleedges.clear();
648 m_invisibleedges.insert(ID);
653 m_invisibleedges.erase(ID);
673 if ( pObjectVertex ==
NULL )
684 return m_edges.size();
687 const std::set<OdUInt64>*
getEdges(){
return &m_edges;}
720 pt1.m_edges.insert(uniqueID);
721 pt2.m_edges.insert(uniqueID);
774 if ( ptFirst == ptSecond &&
vertices.size() > 1)
782 if ( pPoints ==
NULL )
788 while ( it != itEnd )
802 if ( pPoints ==
NULL )
810 if ( ptFirst == ptSecond &&
vertices.size() > 1 )
814 while ( it != itEnd )
850 if ( leafs.size() > 0 )
854 while ( itLeafs != itLeafsEnd )
859 pStartVertex = pLeaf;
867 if ( pStartVertex ==
NULL )
869 int iVertNumber = points.
size();
870 for (
OdUInt64 i = 0; i < iVertNumber; i++)
875 pStartVertex = pVert;
887 if ( pVertex ==
NULL )
890 const std::set<OdUInt64>* pEdges = pVertex->
getEdges();
891 if ( pEdges ==
NULL )
894 std::set<OdUInt64>::const_iterator itEdge = pEdges->begin();
895 std::set<OdUInt64>::const_iterator itEdgeEnd = pEdges->end();
896 while ( itEdge != itEdgeEnd )
899 if ( edgeID < edges.
size() )
913 template <
class T,
class E>
917 if ( pStartVertex ==
NULL )
928 if ( pFirstEdge ==
NULL )
941 pPath->addVertex(pFirstVertex);
943 pPath->addVertex(pNextVertex);
949 pFirstVertex = pNextVertex;
953 polylines.push_back(pPath);
959 template <
class T,
class E>
964 int iVertNumber = points.
size();
965 for (
OdUInt64 i = 0; i < iVertNumber; i++)
972 leafVertices.push_back(pVert);
973 else if ( vPower == 0 )
980 while ( pStartVertex )
982 constructPath(pStartVertex, points, edges, polylines);
983 pStartVertex = getNextStartVertex(points, leafVertices);
986 return polylines.size();
OdGiExtentsSpaceTree< 3, 5, 20, OdGeExtents3d, OdGePoint3d, OdGiExtentsSpaceObject > OdGiExtents3dSpaceTree
OdGiExtentsSpaceTree< 2, 10, 10, OdGeExtents2d, OdGePoint2d, OdGiExtentsSpaceObject > OdGiExtents2dSpaceTree
OdGiExtentsSpaceNode< OdGeExtents3d, OdGiExtentsSpaceObject > OdGiExtents3dSpaceNode
OdGiExtentsSpaceNode< OdGeExtents2d, OdGiExtentsSpaceObject > OdGiExtents2dSpaceNode
bool contains(const OdGePoint3d &point, const OdGeTol &tol=OdGeContext::gTol) const
OdGePoint3d & set(double xx, double yy, double zz)
bool isEqualTo(const OdGePoint3d &point, const OdGeTol &tol=OdGeContext::gTol) const
virtual void addVertex(OdGiExtents3dSpacePoint *pVertex)
bool isInExtents(OdGeExtents2d &extents) const
void getPoints(OdGePoint3dVector &pts)
bool isInExtents(OdGeExtents3d &extents) const
~OdGiExtents3dSpaceChainPolyline()
OdUInt64 getNumberOfVertices_closed()
void getPoints(OdGePoint3d *pPoints)
OdUInt64 getNumberOfVertices()
void getPoints_closed(OdGePoint3dVector &pts)
OdGiExtents3dSpaceChainPolyline(OdInt64 uniqueID)
void getPoints_closed(OdGePoint3d *pPoints)
bool isEqual(OdGiExtentsSpaceObject *pObject, const OdGeTol &tol=OdGeContext::gTol) const
OdList< OdGiExtents3dSpacePoint * > vertices
void setVisited(bool bVisit)
OdGiExtents3dSpaceEdge(OdGiExtents3dSpacePoint &pt1, OdGiExtents3dSpacePoint &pt2, OdInt64 uniqueID)
bool isEqual(OdGiExtentsSpaceObject *pObject, const OdGeTol &tol=OdGeContext::gTol) const
bool isInExtents(OdGeExtents3d &extents) const
bool isInExtents(OdGeExtents2d &extents) const
OdUInt64 getSecondVertex(OdUInt64 iDfirst)
const std::set< OdUInt64 > * getEdges()
bool isInExtents(OdGeExtents2d &extents) const
void addEdge(OdUInt64 ID)
OdGiExtents3dSpacePoint(const OdGePoint3d &pt, OdUInt64 uniqueID)
bool isEqual(OdGiExtentsSpaceObject *pObject, const OdGeTol &tol=OdGeContext::gTol) const
void removeInvisible(OdUInt64 ID)
void addInvisible(OdUInt64 ID)
~OdGiExtents3dSpacePoint()
bool isInExtents(OdGeExtents3d &extents) const
void setVisited(bool bVisit)
const std::set< OdUInt64 > * getInvisilbeEdges()
static OdInt64 calculateChainPolylinesFromEdges(OdArray< OdGiExtents3dSpacePoint * > &points, OdArray< E * > &edges, OdList< T * > &polylines)
OdVector< O *, OdMemoryAllocator< O * > > * getObjectPointersPtr(int iType)
OdGiExtentsSpaceNode(OdGiExtentsSpaceNode *parent, E &extents, int nDepth, int nTypeOfObjects)
virtual bool isEqual(OdGiExtentsSpaceObject *pObject, const OdGeTol &tol=OdGeContext::gTol) const =0
virtual bool isInExtents(OdGeExtents3d &extents) const =0
OdGiExtentsSpaceObject(OdUInt64 uniqueID)
virtual bool isInExtents(OdGeExtents2d &extents) const =0
void setID(OdUInt64 uniqueID)
virtual bool notifyObjectPlacedAtNode(O *, int, OdGiExtentsSpaceNode< E, O > *pNode)=0
void setCallback(OdGiExtentsSpaceTreeCallback< E, O > *pCallback)
OdList< OdGiExtentsSpaceNode< E, O > * > * retrieveLeaves()
OdList< OdGiExtentsSpaceNode< E, O > * > * getExtentsLeaves(E &ext)
bool getRootExtents(E &exts)
O * processObject(O *pObject, int iObjectType, bool bCheckTheSame=false, const OdGeTol &tol=OdGeContext::gTol)
OdList< OdGiExtentsSpaceNode< E, O > * > * getPointLeaves(const P &pt)
void setAdaptive(bool bAdaptive)
void buildTree(E &extents, int nTypeOfObjects, OdInt depth=2)
void setMaxNodeObjects(OdUInt64 nObjects)
OdVector & setGrowLength(int growLength)
void push_back(const T &value)
OdVector & setPhysicalLength(size_type physicalLength)
static GE_STATIC_EXPORT OdGeTol gTol