File indexing completed on 2024-11-15 09:47:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef NCollection_CellFilter_HeaderFile
0017 #define NCollection_CellFilter_HeaderFile
0018
0019 #include <NCollection_LocalArray.hxx>
0020 #include <NCollection_Array1.hxx>
0021 #include <NCollection_Map.hxx>
0022 #include <NCollection_IncAllocator.hxx>
0023 #include <NCollection_TypeDef.hxx>
0024
0025
0026 enum NCollection_CellFilter_Action
0027 {
0028 CellFilter_Keep = 0,
0029 CellFilter_Purge = 1
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
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112 template <class Inspector> class NCollection_CellFilter
0113 {
0114 public:
0115 typedef TYPENAME Inspector::Target Target;
0116 typedef TYPENAME Inspector::Point Point;
0117
0118 public:
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130 NCollection_CellFilter (const Standard_Integer theDim,
0131 const Standard_Real theCellSize = 0,
0132 const Handle(NCollection_IncAllocator)& theAlloc = 0)
0133 : myCellSize(0, theDim - 1)
0134 {
0135 myDim = theDim;
0136 Reset (theCellSize, theAlloc);
0137 }
0138
0139
0140 NCollection_CellFilter (const Standard_Real theCellSize = 0,
0141 const Handle(NCollection_IncAllocator)& theAlloc = 0)
0142 : myCellSize(0, Inspector::Dimension - 1)
0143 {
0144 myDim = Inspector::Dimension;
0145 Reset (theCellSize, theAlloc);
0146 }
0147
0148
0149 void Reset (Standard_Real theCellSize,
0150 const Handle(NCollection_IncAllocator)& theAlloc=0)
0151 {
0152 for (int i=0; i < myDim; i++)
0153 myCellSize(i) = theCellSize;
0154 resetAllocator ( theAlloc );
0155 }
0156
0157
0158 void Reset (NCollection_Array1<Standard_Real>& theCellSize,
0159 const Handle(NCollection_IncAllocator)& theAlloc=0)
0160 {
0161 myCellSize = theCellSize;
0162 resetAllocator ( theAlloc );
0163 }
0164
0165
0166 void Add (const Target& theTarget, const Point &thePnt)
0167 {
0168 Cell aCell (thePnt, myCellSize);
0169 add (aCell, theTarget);
0170 }
0171
0172
0173
0174
0175 void Add (const Target& theTarget,
0176 const Point &thePntMin, const Point &thePntMax)
0177 {
0178
0179 Cell aCellMin (thePntMin, myCellSize);
0180 Cell aCellMax (thePntMax, myCellSize);
0181 Cell aCell = aCellMin;
0182
0183 iterateAdd (myDim-1, aCell, aCellMin, aCellMax, theTarget);
0184 }
0185
0186
0187
0188 void Remove (const Target& theTarget, const Point &thePnt)
0189 {
0190 Cell aCell (thePnt, myCellSize);
0191 remove (aCell, theTarget);
0192 }
0193
0194
0195
0196
0197
0198
0199 void Remove (const Target& theTarget,
0200 const Point &thePntMin, const Point &thePntMax)
0201 {
0202
0203 Cell aCellMin (thePntMin, myCellSize);
0204 Cell aCellMax (thePntMax, myCellSize);
0205 Cell aCell = aCellMin;
0206
0207 iterateRemove (myDim-1, aCell, aCellMin, aCellMax, theTarget);
0208 }
0209
0210
0211 void Inspect (const Point& thePnt, Inspector &theInspector)
0212 {
0213 Cell aCell (thePnt, myCellSize);
0214 inspect (aCell, theInspector);
0215 }
0216
0217
0218
0219
0220 void Inspect (const Point& thePntMin, const Point& thePntMax,
0221 Inspector &theInspector)
0222 {
0223
0224 Cell aCellMin (thePntMin, myCellSize);
0225 Cell aCellMax (thePntMax, myCellSize);
0226 Cell aCell = aCellMin;
0227
0228 iterateInspect (myDim-1, aCell,
0229 aCellMin, aCellMax, theInspector);
0230 }
0231
0232 #if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
0233 public:
0234 #else
0235 protected:
0236 #endif
0237
0238
0239
0240
0241 struct ListNode
0242 {
0243 ListNode()
0244 {
0245
0246 throw Standard_NoSuchObject("NCollection_CellFilter::ListNode()");
0247 }
0248
0249 Target Object;
0250 ListNode *Next;
0251 };
0252
0253
0254 typedef Standard_Integer Cell_IndexType;
0255
0256
0257
0258
0259
0260
0261 struct Cell
0262 {
0263 public:
0264
0265
0266 Cell (const Point& thePnt,
0267 const NCollection_Array1<Standard_Real>& theCellSize)
0268 : index(theCellSize.Size()),
0269 Objects(0)
0270 {
0271 for (int i = 0; i < theCellSize.Size(); i++)
0272 {
0273 Standard_Real aVal = (Standard_Real)(Inspector::Coord(i, thePnt) / theCellSize(theCellSize.Lower() + i));
0274
0275
0276
0277
0278 index[i] = Cell_IndexType((aVal > INT_MAX - 1) ? fmod(aVal, (Standard_Real) INT_MAX)
0279 : (aVal < INT_MIN + 1) ? fmod(aVal, (Standard_Real) INT_MIN)
0280 : aVal);
0281 }
0282 }
0283
0284
0285 Cell (const Cell& theOther)
0286 : index(theOther.index.Size())
0287 {
0288 (*this) = theOther;
0289 }
0290
0291
0292 void operator = (const Cell& theOther)
0293 {
0294 Standard_Integer aDim = Standard_Integer(theOther.index.Size());
0295 for(Standard_Integer anIdx = 0; anIdx < aDim; anIdx++)
0296 index[anIdx] = theOther.index[anIdx];
0297
0298 Objects = theOther.Objects;
0299 ((Cell&)theOther).Objects = 0;
0300 }
0301
0302
0303 ~Cell ()
0304 {
0305 for ( ListNode* aNode = Objects; aNode; aNode = aNode->Next )
0306 aNode->Object.~Target();
0307
0308 Objects = 0;
0309 }
0310
0311
0312 Standard_Boolean IsEqual (const Cell& theOther) const
0313 {
0314 Standard_Integer aDim = Standard_Integer(theOther.index.Size());
0315 for (int i=0; i < aDim; i++)
0316 if ( index[i] != theOther.index[i] ) return Standard_False;
0317 return Standard_True;
0318 }
0319
0320
0321
0322
0323 Standard_Integer HashCode (const Standard_Integer theUpperBound) const
0324 {
0325
0326 const std::size_t aDim = index.Size();
0327 const std::size_t aShiftBits = (BITS (Cell_IndexType) - 1) / aDim;
0328 std::size_t aCode = 0;
0329
0330 for (std::size_t i = 0; i < aDim; ++i)
0331 {
0332 aCode = (aCode << aShiftBits) ^ std::size_t(index[i]);
0333 }
0334
0335 return ::HashCode(aCode, theUpperBound);
0336 }
0337
0338 public:
0339 NCollection_LocalArray<Cell_IndexType, 10> index;
0340 ListNode *Objects;
0341 };
0342
0343
0344
0345
0346
0347 friend Standard_Integer HashCode (const Cell& theCell, const Standard_Integer theUpperBound)
0348 {
0349 return theCell.HashCode (theUpperBound);
0350 }
0351
0352 friend Standard_Boolean IsEqual (const Cell &aCell1, const Cell &aCell2)
0353 { return aCell1.IsEqual(aCell2); }
0354
0355 protected:
0356
0357
0358 void resetAllocator (const Handle(NCollection_IncAllocator)& theAlloc)
0359 {
0360 if ( theAlloc.IsNull() )
0361 myAllocator = new NCollection_IncAllocator;
0362 else
0363 myAllocator = theAlloc;
0364 myCells.Clear ( myAllocator );
0365 }
0366
0367
0368 void add (const Cell& theCell, const Target& theTarget)
0369 {
0370
0371 Cell& aMapCell = (Cell&)myCells.Added (theCell);
0372
0373
0374 ListNode* aNode = (ListNode*)myAllocator->Allocate(sizeof(ListNode));
0375 new (&aNode->Object) Target (theTarget);
0376 aNode->Next = aMapCell.Objects;
0377 aMapCell.Objects = aNode;
0378 }
0379
0380
0381
0382 void iterateAdd (int idim, Cell &theCell,
0383 const Cell& theCellMin, const Cell& theCellMax,
0384 const Target& theTarget)
0385 {
0386 const Cell_IndexType aStart = theCellMin.index[idim];
0387 const Cell_IndexType anEnd = theCellMax.index[idim];
0388 for (Cell_IndexType i = aStart; i <= anEnd; ++i)
0389 {
0390 theCell.index[idim] = i;
0391 if ( idim )
0392 {
0393 iterateAdd (idim-1, theCell, theCellMin, theCellMax, theTarget);
0394 }
0395 else
0396 {
0397 add (theCell, theTarget);
0398 }
0399 }
0400 }
0401
0402
0403 void remove (const Cell& theCell, const Target& theTarget)
0404 {
0405
0406 if ( ! myCells.Contains (theCell) )
0407 return;
0408
0409
0410 Cell& aMapCell = (Cell&)myCells.Added (theCell);
0411 ListNode* aNode = aMapCell.Objects;
0412 ListNode* aPrev = NULL;
0413 while (aNode)
0414 {
0415 ListNode* aNext = aNode->Next;
0416 if (Inspector::IsEqual (aNode->Object, theTarget))
0417 {
0418 aNode->Object.~Target();
0419 (aPrev ? aPrev->Next : aMapCell.Objects) = aNext;
0420
0421 }
0422 else
0423 aPrev = aNode;
0424 aNode = aNext;
0425 }
0426 }
0427
0428
0429
0430 void iterateRemove (int idim, Cell &theCell,
0431 const Cell& theCellMin, const Cell& theCellMax,
0432 const Target& theTarget)
0433 {
0434 const Cell_IndexType aStart = theCellMin.index[idim];
0435 const Cell_IndexType anEnd = theCellMax.index[idim];
0436 for (Cell_IndexType i = aStart; i <= anEnd; ++i)
0437 {
0438 theCell.index[idim] = i;
0439 if ( idim )
0440 {
0441 iterateRemove (idim-1, theCell, theCellMin, theCellMax, theTarget);
0442 }
0443 else
0444 {
0445 remove (theCell, theTarget);
0446 }
0447 }
0448 }
0449
0450
0451 void inspect (const Cell& theCell, Inspector& theInspector)
0452 {
0453
0454 if ( ! myCells.Contains (theCell) )
0455 return;
0456
0457
0458 Cell& aMapCell = (Cell&)myCells.Added (theCell);
0459 ListNode* aNode = aMapCell.Objects;
0460 ListNode* aPrev = NULL;
0461 while(aNode) {
0462 ListNode* aNext = aNode->Next;
0463 NCollection_CellFilter_Action anAction =
0464 theInspector.Inspect (aNode->Object);
0465
0466 if ( anAction == CellFilter_Purge ) {
0467 aNode->Object.~Target();
0468 (aPrev ? aPrev->Next : aMapCell.Objects) = aNext;
0469
0470 }
0471 else
0472 aPrev = aNode;
0473 aNode = aNext;
0474 }
0475 }
0476
0477
0478 void iterateInspect (int idim, Cell &theCell,
0479 const Cell& theCellMin, const Cell& theCellMax,
0480 Inspector& theInspector)
0481 {
0482 const Cell_IndexType aStart = theCellMin.index[idim];
0483 const Cell_IndexType anEnd = theCellMax.index[idim];
0484 for (Cell_IndexType i = aStart; i <= anEnd; ++i)
0485 {
0486 theCell.index[idim] = i;
0487 if ( idim )
0488 {
0489 iterateInspect (idim-1, theCell, theCellMin, theCellMax, theInspector);
0490 }
0491 else
0492 {
0493 inspect (theCell, theInspector);
0494 }
0495 }
0496 }
0497
0498 protected:
0499 Standard_Integer myDim;
0500 Handle(NCollection_BaseAllocator) myAllocator;
0501 NCollection_Map<Cell> myCells;
0502 NCollection_Array1<Standard_Real> myCellSize;
0503 };
0504
0505
0506
0507
0508
0509
0510 class gp_XYZ;
0511 struct NCollection_CellFilter_InspectorXYZ
0512 {
0513
0514 enum { Dimension = 3 };
0515
0516
0517 typedef gp_XYZ Point;
0518
0519
0520 static Standard_Real Coord (int i, const Point &thePnt) { return thePnt.Coord(i+1); }
0521
0522
0523
0524 Point Shift (const Point& thePnt, Standard_Real theTol) const
0525 { return Point (thePnt.X() + theTol, thePnt.Y() + theTol, thePnt.Z() + theTol); }
0526 };
0527
0528
0529
0530
0531
0532
0533 class gp_XY;
0534 struct NCollection_CellFilter_InspectorXY
0535 {
0536
0537 enum { Dimension = 2 };
0538
0539
0540 typedef gp_XY Point;
0541
0542
0543 static Standard_Real Coord (int i, const Point &thePnt) { return thePnt.Coord(i+1); }
0544
0545
0546
0547 Point Shift (const Point& thePnt, Standard_Real theTol) const
0548 { return Point (thePnt.X() + theTol, thePnt.Y() + theTol); }
0549 };
0550
0551 #endif