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;
199template <
class E,
class O>
214template <OdUInt32 NUM_AXIS, OdUInt32 MAX_DEPTH, OdUInt64 MAX_NODE_OBJECT,
class E,
class P,
class O>
class OdGiExtentsSpaceTree
247 m_bIsAdaptive =
false;
248 m_iMaxNodeObjects = MAX_NODE_OBJECT;
261 if ( depth > MAX_DEPTH )
263 else if ( depth < 0 )
266 if ( m_pRootNode != NULL )
271 m_Nodes.push_back(m_pRootNode);
274 constructChilds(m_pRootNode, NUM_AXIS, depth, nTypeOfObjects);
284 while ( it != itEnd )
294 m_theSameObjects.clear();
295 m_theIntersectedLeaves.clear();
296 m_theCandidateLeaves.clear();
308 m_theSameObjects.clear();
309 m_theCandidateLeaves.clear();
311 if ( m_pRootNode == NULL )
314 nodeProcessObject(m_pRootNode, pObject, iObjectType, bCheckTheSame,
tol);
316 if ( m_theSameObjects.size() == 0 )
318 if ( !m_theCandidateLeaves.empty() )
322 while ( itNodes != itNodesEnd )
327 nodeProcessObject(pNode, pObject, iObjectType,
false,
tol);
332 m_theCandidateLeaves.clear();
336 m_theCandidateLeaves.clear();
338 return m_theSameObjects.front();
347 if ( m_pRootNode == NULL )
350 if(m_pRootNode->m_extents.isValidExtents())
352 exts = m_pRootNode->m_extents;
360 m_theIntersectedLeaves.clear();
362 if ( m_pRootNode == NULL )
365 nodeProcessExtent(m_pRootNode, ext);
367 if ( m_theIntersectedLeaves.size() == 0 )
370 return &m_theIntersectedLeaves;
375 m_theIntersectedLeaves.clear();
377 nodeProcessPoint(m_pRootNode, pt);
379 if ( m_theIntersectedLeaves.size() == 0 )
382 return &m_theIntersectedLeaves;
387 m_theIntersectedLeaves.clear();
389 nodeProcessPoint(m_pRootNode, pt, proximityRadius);
391 if (m_theIntersectedLeaves.size() == 0)
394 return &m_theIntersectedLeaves;
402 if ( pParentNode == NULL )
408 m_Leaves.push_back(pParentNode);
415 P leftBounPoint = pParentNode->m_extents.maxPoint();
419 middlez(pParentNode->m_extents.maxPoint(), pParentNode->m_extents.minPoint(), leftBounPoint);
422 leftBounPoint.x = (pParentNode->m_extents.maxPoint().x + pParentNode->m_extents.minPoint().x)/2.;
425 leftBounPoint.y = (pParentNode->m_extents.maxPoint().y + pParentNode->m_extents.minPoint().y)/2.;
429 leftChildExtents.set(pParentNode->m_extents.minPoint(), leftBounPoint);
432 pParentNode->m_pLeftChild =
new OdGiExtentsSpaceNode<E,O>(pParentNode, leftChildExtents, axislevel > 1 ? pParentNode->m_iDepth : pParentNode->m_iDepth + 1, nTypeOfObjects);
433 m_Nodes.push_back(pParentNode->m_pLeftChild);
437 constructChilds(pParentNode->m_pLeftChild, axislevel-1, curDepth, nTypeOfObjects);
439 constructChilds(pParentNode->m_pLeftChild, NUM_AXIS, curDepth-1, nTypeOfObjects);
444 P rightBounPoint = pParentNode->m_extents.minPoint();
448 middlez(pParentNode->m_extents.maxPoint(), pParentNode->m_extents.minPoint(), rightBounPoint);
451 rightBounPoint.x = (pParentNode->m_extents.maxPoint().x + pParentNode->m_extents.minPoint().x)/2.;
454 rightBounPoint.y = (pParentNode->m_extents.maxPoint().y + pParentNode->m_extents.minPoint().y)/2.;
458 rightChildExtents.set(rightBounPoint, pParentNode->m_extents.maxPoint());
461 pParentNode->m_pRightChild =
new OdGiExtentsSpaceNode<E,O>(pParentNode, rightChildExtents, axislevel > 1 ? pParentNode->m_iDepth : pParentNode->m_iDepth + 1, nTypeOfObjects);
462 m_Nodes.push_back(pParentNode->m_pRightChild);
466 constructChilds(pParentNode->m_pRightChild, axislevel-1, curDepth, nTypeOfObjects);
468 constructChilds(pParentNode->m_pRightChild, NUM_AXIS, curDepth-1, nTypeOfObjects);
476 if ( pNode == NULL || pObject == NULL )
479 bool bIntersect = pObject->isInExtents(pNode->m_extents);
492 if ( pNodeObjects == NULL )
494 if ( m_iMaxNodeObjects > 0 )
495 pNodeObjects = pNode->initObjectList(iObjectType, m_iMaxNodeObjects+1);
497 pNodeObjects = pNode->initObjectList(iObjectType, 50);
506 while ( itNodes != itNodesEnd )
508 O* pObjectInList = *itNodes;
511 if ( pObjectInList->isEqual(pObject,
tol) )
513 m_theSameObjects.push_back(pObjectInList);
519 m_theCandidateLeaves.push_back(pNode);
528 if ( m_bIsAdaptive && pNodeObjects->
size() > m_iMaxNodeObjects && pNode->m_iDepth <= MAX_DEPTH )
531 m_Leaves.remove(pNode);
534 constructChilds(pNode, NUM_AXIS, 1, pNode->m_iObjectsTypes);
537 for (
int i = 0; i < pNode->m_iObjectsTypes; i++)
544 while ( it != itEnd )
546 O* pObjectInList = *it;
550 nodeProcessObject(pNode->m_pLeftChild, pObjectInList, i,
false,
tol);
551 nodeProcessObject(pNode->m_pRightChild, pObjectInList, i,
false,
tol);
559 pNode->releaseObjectsStore();
564 nodeProcessObject(pNode->m_pLeftChild, pObject, iObjectType, bCheckTheSame,
tol);
565 nodeProcessObject(pNode->m_pRightChild, pObject, iObjectType, bCheckTheSame,
tol);
575 if ( pNode == NULL || !ext.isValidExtents() )
579 ext.intersectWith(pNode->m_extents, &isect);
581 if ( isect.isValidExtents() )
585 m_theIntersectedLeaves.push_back(pNode);
589 nodeProcessExtent(pNode->m_pLeftChild, ext);
590 nodeProcessExtent(pNode->m_pRightChild, ext);
603 if ( pNode->m_extents.contains(pt) )
607 m_theIntersectedLeaves.push_back(pNode);
611 nodeProcessPoint(pNode->m_pLeftChild, pt);
612 nodeProcessPoint(pNode->m_pRightChild, pt);
624 if (pNode->m_extents.isWithinRange(pt, r))
628 m_theIntersectedLeaves.push_back(pNode);
632 nodeProcessPoint(pNode->m_pLeftChild, pt, r);
633 nodeProcessPoint(pNode->m_pRightChild, pt, r);
648 ptRes.
z = (pt1.
z + pt2.
z)/2.;
669 std::set<OdUInt64> m_edges;
672 std::set<OdUInt64> m_invisibleedges;
692 m_invisibleedges.clear();
702 m_invisibleedges.insert(ID);
707 m_invisibleedges.erase(ID);
727 if ( pObjectVertex == NULL )
738 return m_edges.size();
741 const std::set<OdUInt64>*
getEdges(){
return &m_edges;}
774 pt1.m_edges.insert(uniqueID);
775 pt2.m_edges.insert(uniqueID);
828 if ( ptFirst == ptSecond &&
vertices.size() > 1)
836 if ( pPoints == NULL )
842 while ( it != itEnd )
856 if ( pPoints == NULL )
864 if ( ptFirst == ptSecond &&
vertices.size() > 1 )
868 while ( it != itEnd )
904 if ( leafs.size() > 0 )
908 while ( itLeafs != itLeafsEnd )
913 pStartVertex = pLeaf;
921 if ( pStartVertex == NULL )
923 int iVertNumber = points.
size();
924 for (
OdUInt64 i = 0; i < iVertNumber; i++)
929 pStartVertex = pVert;
941 if ( pVertex == NULL )
944 const std::set<OdUInt64>* pEdges = pVertex->
getEdges();
945 if ( pEdges == NULL )
948 std::set<OdUInt64>::const_iterator itEdge = pEdges->begin();
949 std::set<OdUInt64>::const_iterator itEdgeEnd = pEdges->end();
950 while ( itEdge != itEdgeEnd )
953 if ( edgeID < edges.
size() )
967template <
class T,
class E>
971 if ( pStartVertex == NULL )
982 if ( pFirstEdge == NULL )
995 pPath->addVertex(pFirstVertex);
997 pPath->addVertex(pNextVertex);
1003 pFirstVertex = pNextVertex;
1007 polylines.push_back(pPath);
1013template <
class T,
class E>
1018 int iVertNumber = points.
size();
1019 for (
OdUInt64 i = 0; i < iVertNumber; i++)
1026 leafVertices.push_back(pVert);
1027 else if ( vPower == 0 )
1034 while ( pStartVertex )
1036 constructPath(pStartVertex, points, edges, polylines);
1037 pStartVertex = getNextStartVertex(points, leafVertices);
1040 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
bool isEqualTo(const OdGePoint3d &point, const OdGeTol &tol=OdGeContext::gTol) const
OdGePoint3d & set(double xx, double yy, double zz)
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)
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
const std::set< OdUInt64 > * getInvisilbeEdges()
void removeInvisible(OdUInt64 ID)
const std::set< OdUInt64 > * getEdges()
void addInvisible(OdUInt64 ID)
~OdGiExtents3dSpacePoint()
bool isInExtents(OdGeExtents3d &extents) const
void setVisited(bool bVisit)
static OdInt64 calculateChainPolylinesFromEdges(OdArray< OdGiExtents3dSpacePoint * > &points, OdArray< E * > &edges, OdList< T * > &polylines)
OdGiExtentsSpaceNode(OdGiExtentsSpaceNode *parent, E &extents, int nDepth, int nTypeOfObjects)
OdVector< O *, OdMemoryAllocator< O * > > * getObjectPointersPtr(int iType)
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
O * processObject(O *pObject, int iObjectType, bool bCheckTheSame=false, const OdGeTol &tol=OdGeContext::gTol)
void setCallback(OdGiExtentsSpaceTreeCallback< E, O > *pCallback)
OdList< OdGiExtentsSpaceNode< E, O > * > * getPointLeaves(const P &pt, double proximityRadius)
OdList< OdGiExtentsSpaceNode< E, O > * > * getExtentsLeaves(E &ext)
OdList< OdGiExtentsSpaceNode< E, O > * > * retrieveLeaves()
bool getRootExtents(E &exts)
void setAdaptive(bool bAdaptive)
OdList< OdGiExtentsSpaceNode< E, O > * > * getPointLeaves(const P &pt)
void buildTree(E &extents, int nTypeOfObjects, OdInt depth=2)
void setMaxNodeObjects(OdUInt64 nObjects)
std::list< T, A >::iterator iterator
OdVector & setGrowLength(int growLength)
void push_back(const T &value)
OdVector & setPhysicalLength(size_type physicalLength)
static GE_STATIC_EXPORT OdGeTol gTol