File indexing completed on 2025-01-18 10:04:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef NCollection_UBTree_HeaderFile
0017 #define NCollection_UBTree_HeaderFile
0018
0019 #include <NCollection_BaseAllocator.hxx>
0020 #include <NCollection_DefineAlloc.hxx>
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 template <class TheObjType, class TheBndType> class NCollection_UBTree
0064 {
0065 public:
0066
0067 DEFINE_STANDARD_ALLOC
0068 DEFINE_NCOLLECTION_ALLOC
0069
0070 public:
0071
0072
0073
0074
0075
0076 class Selector
0077 {
0078 public:
0079
0080
0081
0082 Selector () : myStop(Standard_False) {}
0083
0084
0085
0086
0087
0088
0089 virtual Standard_Boolean Reject (const TheBndType&) const = 0;
0090
0091
0092
0093
0094
0095
0096
0097
0098 virtual Standard_Boolean Accept (const TheObjType&) = 0;
0099
0100
0101
0102
0103
0104
0105 Standard_Boolean Stop () const { return myStop; }
0106
0107
0108
0109
0110 virtual ~Selector () {}
0111
0112 protected:
0113
0114
0115
0116
0117 Standard_Boolean myStop;
0118 };
0119
0120
0121
0122
0123
0124
0125
0126
0127 class TreeNode
0128 {
0129 public:
0130 DEFINE_STANDARD_ALLOC
0131 DEFINE_NCOLLECTION_ALLOC
0132
0133 public:
0134 TreeNode (const TheObjType& theObj, const TheBndType& theBnd)
0135 : myBnd(theBnd), myObject(theObj), myChildren(0), myParent(0) {}
0136
0137 Standard_Boolean IsLeaf () const { return !myChildren; }
0138 Standard_Boolean IsRoot () const { return !myParent; }
0139 const TheBndType& Bnd () const { return myBnd; }
0140 TheBndType& ChangeBnd () { return myBnd; }
0141 const TheObjType& Object () const { return myObject; }
0142 const TreeNode& Child (const Standard_Integer i) const
0143 { return myChildren[i]; }
0144 TreeNode& ChangeChild (const Standard_Integer i)
0145 { return myChildren[i]; }
0146 const TreeNode& Parent () const { return *myParent; }
0147 TreeNode& ChangeParent () { return *myParent; }
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163 void Gemmate (const TheBndType& theNewBnd,
0164 const TheObjType& theObj,
0165 const TheBndType& theBnd,
0166 const Handle(NCollection_BaseAllocator)& theAlloc)
0167 {
0168
0169 TreeNode *children = (TreeNode *) theAlloc->Allocate (2*sizeof(TreeNode));
0170 new (&children[0]) TreeNode;
0171 new (&children[1]) TreeNode;
0172 children[0] = *this;
0173 children[1].myObject = theObj;
0174 children[1].myBnd = theBnd;
0175 children[0].myParent = children[1].myParent = this;
0176 if (!IsLeaf()) {
0177 myChildren[0].myParent = children;
0178 myChildren[1].myParent = children;
0179 }
0180 myChildren = children;
0181 myBnd = theNewBnd;
0182 myObject = TheObjType();
0183 }
0184
0185
0186
0187
0188 void Kill (const Standard_Integer i,
0189 const Handle(NCollection_BaseAllocator)& theAlloc)
0190 {
0191 if (!IsLeaf()) {
0192 TreeNode *oldChildren = myChildren;
0193 const Standard_Integer iopp = 1 - i;
0194 myBnd = oldChildren[iopp].myBnd;
0195 myObject = oldChildren[iopp].myObject;
0196 myChildren = oldChildren[iopp].myChildren;
0197 if (!IsLeaf()) {
0198 myChildren[0].myParent = this;
0199 myChildren[1].myParent = this;
0200 }
0201
0202
0203 oldChildren[iopp].~TreeNode();
0204 delNode(&oldChildren[i], theAlloc);
0205 theAlloc->Free(oldChildren);
0206 }
0207 }
0208
0209
0210 ~TreeNode () { myChildren = 0L; }
0211
0212
0213
0214
0215
0216 static void delNode (TreeNode * theNode,
0217 const Handle(NCollection_BaseAllocator)& theAlloc)
0218 {
0219 if (theNode) {
0220 if (theNode -> myChildren) {
0221 delNode (&theNode -> myChildren[0], theAlloc);
0222 delNode (&theNode -> myChildren[1], theAlloc);
0223 theAlloc->Free(theNode -> myChildren);
0224 }
0225 theNode->~TreeNode();
0226 }
0227 }
0228
0229 private:
0230 TreeNode () : myChildren(0L), myParent(0L) {}
0231
0232 TheBndType myBnd;
0233 TheObjType myObject;
0234 TreeNode *myChildren;
0235 TreeNode *myParent;
0236 };
0237
0238
0239
0240
0241
0242
0243 NCollection_UBTree() : myRoot(0L), myLastNode(0L), myAlloc (NCollection_BaseAllocator::CommonBaseAllocator()) {}
0244
0245
0246
0247
0248 explicit NCollection_UBTree (const Handle(NCollection_BaseAllocator)& theAllocator)
0249 : myRoot(0L), myLastNode(0L), myAlloc (!theAllocator.IsNull() ? theAllocator : NCollection_BaseAllocator::CommonBaseAllocator()) {}
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260 virtual Standard_Boolean Add (const TheObjType& theObj, const TheBndType& theBnd);
0261
0262
0263
0264
0265
0266
0267 virtual Standard_Integer Select (Selector& theSelector) const
0268 { return (IsEmpty() ? 0 : Select (Root(), theSelector)); }
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278 virtual void Clear (const Handle(NCollection_BaseAllocator)& aNewAlloc = 0L)
0279
0280 {
0281 if (myRoot) {
0282 TreeNode::delNode (myRoot, this->myAlloc);
0283 this->myAlloc->Free (myRoot);
0284 myRoot = 0L;
0285 }
0286 if (aNewAlloc.IsNull() == Standard_False)
0287 myAlloc = aNewAlloc;
0288 }
0289
0290 Standard_Boolean IsEmpty () const { return !myRoot; }
0291
0292
0293
0294
0295
0296 const TreeNode& Root () const { return *myRoot; }
0297
0298
0299
0300
0301 virtual ~NCollection_UBTree () { Clear(); }
0302
0303
0304
0305
0306
0307
0308 const Handle(NCollection_BaseAllocator)& Allocator () const
0309 { return myAlloc; }
0310
0311 protected:
0312
0313
0314
0315
0316
0317
0318 TreeNode& ChangeLastNode () { return *myLastNode; }
0319
0320
0321
0322
0323
0324
0325 Standard_Integer Select (const TreeNode& theBranch, Selector& theSelector) const;
0326
0327 private:
0328
0329
0330
0331 NCollection_UBTree (const NCollection_UBTree&);
0332
0333
0334 NCollection_UBTree& operator = (const NCollection_UBTree&);
0335
0336
0337
0338 TreeNode *myRoot;
0339 TreeNode *myLastNode;
0340 Handle(NCollection_BaseAllocator) myAlloc;
0341 };
0342
0343
0344
0345
0346
0347
0348
0349 template <class TheObjType, class TheBndType>
0350 Standard_Boolean NCollection_UBTree<TheObjType,TheBndType>::Add
0351 (const TheObjType& theObj,
0352 const TheBndType& theBnd)
0353 {
0354 if (IsEmpty()) {
0355
0356 myRoot = new (this->myAlloc) TreeNode (theObj, theBnd);
0357 myLastNode = myRoot;
0358 return Standard_True;
0359 }
0360
0361 TreeNode *pBranch = myRoot;
0362 Standard_Boolean isOutOfBranch = pBranch->Bnd().IsOut (theBnd);
0363
0364 for(;;) {
0365
0366 if (isOutOfBranch || pBranch->IsLeaf()) {
0367 TheBndType aNewBnd = theBnd;
0368 aNewBnd.Add (pBranch->Bnd());
0369
0370 pBranch->Gemmate (aNewBnd, theObj, theBnd, this->myAlloc);
0371 myLastNode = &pBranch->ChangeChild(1);
0372 break;
0373 }
0374
0375
0376 pBranch->ChangeBnd().Add (theBnd);
0377
0378
0379
0380
0381 Standard_Integer iBest = 0;
0382 Standard_Boolean isOut[] = { pBranch->Child(0).Bnd().IsOut (theBnd),
0383 pBranch->Child(1).Bnd().IsOut (theBnd) };
0384 if (isOut[0] != isOut[1])
0385 iBest = (isOut[0] ? 1 : 0);
0386 else {
0387 TheBndType aUnion[] = { theBnd, theBnd };
0388 aUnion[0].Add (pBranch->Child(0).Bnd());
0389 aUnion[1].Add (pBranch->Child(1).Bnd());
0390 const Standard_Real d1 = aUnion[0].SquareExtent();
0391 const Standard_Real d2 = aUnion[1].SquareExtent();
0392 if (d1 > d2)
0393 iBest = 1;
0394 }
0395
0396
0397 isOutOfBranch = isOut[iBest];
0398 pBranch = &pBranch->ChangeChild(iBest);
0399 }
0400 return Standard_True;
0401 }
0402
0403
0404
0405
0406
0407
0408
0409
0410 template <class TheObjType, class TheBndType>
0411 Standard_Integer NCollection_UBTree<TheObjType,TheBndType>::Select
0412 (const TreeNode& theBranch,
0413 Selector& theSelector) const
0414 {
0415
0416 if (theSelector.Reject (theBranch.Bnd()))
0417 return 0;
0418
0419 Standard_Integer nSel = 0;
0420
0421 if (theBranch.IsLeaf()) {
0422
0423 if (theSelector.Accept (theBranch.Object()))
0424 nSel++;
0425 }
0426 else {
0427
0428 nSel += Select (theBranch.Child(0), theSelector);
0429 if (!theSelector.Stop())
0430 nSel += Select (theBranch.Child(1), theSelector);
0431 }
0432
0433 return nSel;
0434 }
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445 #define DEFINE_HUBTREE(_HUBTREE, _OBJTYPE, _BNDTYPE, _HPARENT) \
0446 class _HUBTREE : public _HPARENT \
0447 { \
0448 public: \
0449 typedef NCollection_UBTree <_OBJTYPE, _BNDTYPE> UBTree; \
0450 \
0451 _HUBTREE () : myTree(new UBTree) {} \
0452 \
0453 _HUBTREE (const Handle(NCollection_BaseAllocator)& theAlloc) \
0454 : myTree(new UBTree(theAlloc)) {} \
0455 \
0456 \
0457 \
0458 \
0459 Standard_Boolean Add (const _OBJTYPE& theObj, \
0460 const _BNDTYPE& theBnd) \
0461 { return ChangeTree().Add (theObj, theBnd); } \
0462 \
0463 Standard_Integer Select (UBTree::Selector& theSelector) const \
0464 { return Tree().Select (theSelector); } \
0465 \
0466 void Clear () { ChangeTree().Clear (); } \
0467 \
0468 Standard_Boolean IsEmpty () const { return Tree().IsEmpty(); } \
0469 \
0470 const UBTree::TreeNode& Root () const { return Tree().Root(); } \
0471 \
0472 \
0473 \
0474 \
0475 const UBTree& Tree () const { return *myTree; } \
0476 UBTree& ChangeTree () { return *myTree; } \
0477 \
0478 ~_HUBTREE () { delete myTree; } \
0479 \
0480 \
0481 DEFINE_STANDARD_RTTI_INLINE(_HUBTREE,_HPARENT) \
0482 \
0483 \
0484 private: \
0485 \
0486 _HUBTREE (UBTree*); \
0487 _HUBTREE (const _HUBTREE&); \
0488 void operator = (const _HUBTREE&); \
0489 \
0490 private: \
0491 UBTree *myTree; \
0492 }; \
0493 DEFINE_STANDARD_HANDLE (_HUBTREE, _HPARENT)
0494
0495 #define IMPLEMENT_HUBTREE(_HUBTREE, _HPARENT)
0496
0497
0498
0499 #endif