210template <OdUInt32 NUM_AXIS, OdUInt32 MAX_DEPTH, OdUInt32 MAX_NODE_OBJECT,
class E,
class P,
class O>
class OdGiExtentsSpaceTree
243 m_bIsAdaptive =
false;
244 m_iMaxNodeObjects = MAX_NODE_OBJECT;
257 if ( depth > MAX_DEPTH )
259 else if ( depth < 0 )
262 if ( m_pRootNode != NULL )
267 m_Nodes.push_back(m_pRootNode);
270 constructChilds(m_pRootNode, NUM_AXIS, depth, nTypeOfObjects);
280 while ( it != itEnd )
290 m_theSameObjects.clear();
291 m_theIntersectedLeaves.clear();
292 m_theCandidateLeaves.clear();
304 m_theSameObjects.clear();
305 m_theCandidateLeaves.clear();
307 if ( m_pRootNode == NULL )
310 nodeProcessObject(m_pRootNode, pObject, iObjectType, bCheckTheSame,
tol);
312 if ( m_theSameObjects.size() == 0 )
314 if ( !m_theCandidateLeaves.empty() )
318 while ( itNodes != itNodesEnd )
323 nodeProcessObject(pNode, pObject, iObjectType,
false,
tol);
328 m_theCandidateLeaves.clear();
332 m_theCandidateLeaves.clear();
334 return m_theSameObjects.front();
343 if ( m_pRootNode == NULL )
346 if(m_pRootNode->m_extents.isValidExtents())
348 exts = m_pRootNode->m_extents;
356 m_theIntersectedLeaves.clear();
358 if ( m_pRootNode == NULL )
361 nodeProcessExtent(m_pRootNode, ext);
363 if ( m_theIntersectedLeaves.size() == 0 )
366 return &m_theIntersectedLeaves;
371 m_theIntersectedLeaves.clear();
373 nodeProcessPoint(m_pRootNode, pt);
375 if ( m_theIntersectedLeaves.size() == 0 )
378 return &m_theIntersectedLeaves;
383 m_theIntersectedLeaves.clear();
385 nodeProcessPoint(m_pRootNode, pt, proximityRadius);
387 if (m_theIntersectedLeaves.size() == 0)
390 return &m_theIntersectedLeaves;
398 if ( pParentNode == NULL )
404 m_Leaves.push_back(pParentNode);
411 P leftBounPoint = pParentNode->m_extents.maxPoint();
415 middlez(pParentNode->m_extents.maxPoint(), pParentNode->m_extents.minPoint(), leftBounPoint);
418 leftBounPoint.x = (pParentNode->m_extents.maxPoint().
x + pParentNode->m_extents.minPoint().x)/2.;
421 leftBounPoint.y = (pParentNode->m_extents.maxPoint().
y + pParentNode->m_extents.minPoint().y)/2.;
425 leftChildExtents.set(pParentNode->m_extents.minPoint(), leftBounPoint);
428 pParentNode->m_pLeftChild =
new OdGiExtentsSpaceNode<E,O>(pParentNode, leftChildExtents, axislevel > 1 ? pParentNode->m_iDepth : pParentNode->m_iDepth + 1, nTypeOfObjects);
429 m_Nodes.push_back(pParentNode->m_pLeftChild);
433 constructChilds(pParentNode->m_pLeftChild, axislevel-1, curDepth, nTypeOfObjects);
435 constructChilds(pParentNode->m_pLeftChild, NUM_AXIS, curDepth-1, nTypeOfObjects);
440 P rightBounPoint = pParentNode->m_extents.minPoint();
444 middlez(pParentNode->m_extents.maxPoint(), pParentNode->m_extents.minPoint(), rightBounPoint);
447 rightBounPoint.x = (pParentNode->m_extents.maxPoint().
x + pParentNode->m_extents.minPoint().x)/2.;
450 rightBounPoint.y = (pParentNode->m_extents.maxPoint().
y + pParentNode->m_extents.minPoint().y)/2.;
454 rightChildExtents.set(rightBounPoint, pParentNode->m_extents.maxPoint());
457 pParentNode->m_pRightChild =
new OdGiExtentsSpaceNode<E,O>(pParentNode, rightChildExtents, axislevel > 1 ? pParentNode->m_iDepth : pParentNode->m_iDepth + 1, nTypeOfObjects);
458 m_Nodes.push_back(pParentNode->m_pRightChild);
462 constructChilds(pParentNode->m_pRightChild, axislevel-1, curDepth, nTypeOfObjects);
464 constructChilds(pParentNode->m_pRightChild, NUM_AXIS, curDepth-1, nTypeOfObjects);
470 void nodeProcessObject(OdGiExtentsSpaceNode<E,O>* pNode, O* pObject,
int iObjectType,
bool bCheckTheSame,
const OdGeTol&
tol =
OdGeContext::gTol)
472 if ( pNode == NULL || pObject == NULL )
475 bool bIntersect = pObject->isInExtents(pNode->m_extents);
483 if ( !m_pCallback->notifyObjectPlacedAtNode(pObject, iObjectType, pNode) )
488 if ( pNodeObjects == NULL )
490 if ( m_iMaxNodeObjects > 0 )
491 pNodeObjects = pNode->initObjectList(iObjectType, m_iMaxNodeObjects+1);
493 pNodeObjects = pNode->initObjectList(iObjectType, 50);
500 OD_TYPENAME OdVector<O*, OdMemoryAllocator<O*> >::iterator itNodes = pNodeObjects->
begin();
501 OD_TYPENAME OdVector<O*, OdMemoryAllocator<O*> >::iterator itNodesEnd = pNodeObjects->
end();
502 while ( itNodes != itNodesEnd )
504 O* pObjectInList = *itNodes;
507 if ( pObjectInList->isEqual(pObject,
tol) )
509 m_theSameObjects.push_back(pObjectInList);
515 m_theCandidateLeaves.push_back(pNode);
524 if ( m_bIsAdaptive && pNodeObjects->
size() > m_iMaxNodeObjects && pNode->m_iDepth <= MAX_DEPTH )
527 m_Leaves.remove(pNode);
530 constructChilds(pNode, NUM_AXIS, 1, pNode->m_iObjectsTypes);
533 for (
int i = 0; i < pNode->m_iObjectsTypes; i++)
538 OD_TYPENAME OdVector<O*, OdMemoryAllocator<O*> >::iterator it = pNodeObjects->
begin();
539 OD_TYPENAME OdVector<O*, OdMemoryAllocator<O*> >::iterator itEnd = pNodeObjects->
end();
540 while ( it != itEnd )
542 O* pObjectInList = *it;
546 nodeProcessObject(pNode->m_pLeftChild, pObjectInList, i,
false,
tol);
547 nodeProcessObject(pNode->m_pRightChild, pObjectInList, i,
false,
tol);
555 pNode->releaseObjectsStore();
560 nodeProcessObject(pNode->m_pLeftChild, pObject, iObjectType, bCheckTheSame,
tol);
561 nodeProcessObject(pNode->m_pRightChild, pObject, iObjectType, bCheckTheSame,
tol);
569 void nodeProcessExtent(OdGiExtentsSpaceNode<E,O>* pNode,
E& ext)
571 if ( pNode == NULL || !ext.isValidExtents() )
575 ext.intersectWith(pNode->m_extents, &isect);
577 if ( isect.isValidExtents() )
581 m_theIntersectedLeaves.push_back(pNode);
585 nodeProcessExtent(pNode->m_pLeftChild, ext);
586 nodeProcessExtent(pNode->m_pRightChild, ext);
594 void nodeProcessPoint(OdGiExtentsSpaceNode<E,O>* pNode,
const P& pt)
599 if ( pNode->m_extents.contains(pt) )
603 m_theIntersectedLeaves.push_back(pNode);
607 nodeProcessPoint(pNode->m_pLeftChild, pt);
608 nodeProcessPoint(pNode->m_pRightChild, pt);
615 void nodeProcessPoint(OdGiExtentsSpaceNode<E, O>* pNode,
const P& pt,
double r)
620 if (pNode->m_extents.isWithinRange(pt, r))
624 m_theIntersectedLeaves.push_back(pNode);
628 nodeProcessPoint(pNode->m_pLeftChild, pt, r);
629 nodeProcessPoint(pNode->m_pRightChild, pt, r);
636 void middlez(
const OdGePoint2d& pt1,
const OdGePoint2d& pt2, OdGePoint2d& ptRes)
642 void middlez(
const OdGePoint3d& pt1,
const OdGePoint3d& pt2, OdGePoint3d& ptRes)
644 ptRes.
z = (pt1.
z + pt2.
z)/2.;