File indexing completed on 2025-02-18 10:08:13
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 <Standard_HashUtils.hxx>
0022 #include <NCollection_Map.hxx>
0023 #include <NCollection_IncAllocator.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 bool operator==(const Cell& theOther) const
0321 {
0322 return IsEqual(theOther);
0323 }
0324
0325 public:
0326 NCollection_LocalArray<Cell_IndexType, 10> index;
0327 ListNode *Objects;
0328 };
0329
0330 struct CellHasher
0331 {
0332 size_t operator()(const Cell& theCell) const noexcept
0333 {
0334
0335 const std::size_t aDim = theCell.index.Size();
0336 return opencascade::hashBytes(&theCell.index[0], static_cast<int>(aDim * sizeof(Cell_IndexType)));
0337 }
0338
0339 bool operator()(const Cell& theCell1,
0340 const Cell& theCell2) const noexcept
0341 {
0342 return theCell1 == theCell2;
0343 }
0344 };
0345
0346 typedef NCollection_Map<Cell, CellHasher> CellMap;
0347
0348 protected:
0349
0350
0351 void resetAllocator (const Handle(NCollection_IncAllocator)& theAlloc)
0352 {
0353 if ( theAlloc.IsNull() )
0354 myAllocator = new NCollection_IncAllocator;
0355 else
0356 myAllocator = theAlloc;
0357 myCells.Clear ( myAllocator );
0358 }
0359
0360
0361 void add (const Cell& theCell, const Target& theTarget)
0362 {
0363
0364 Cell& aMapCell = (Cell&)myCells.Added (theCell);
0365
0366
0367 ListNode* aNode = (ListNode*)myAllocator->Allocate(sizeof(ListNode));
0368 new (&aNode->Object) Target (theTarget);
0369 aNode->Next = aMapCell.Objects;
0370 aMapCell.Objects = aNode;
0371 }
0372
0373
0374
0375 void iterateAdd (int idim, Cell &theCell,
0376 const Cell& theCellMin, const Cell& theCellMax,
0377 const Target& theTarget)
0378 {
0379 const Cell_IndexType aStart = theCellMin.index[idim];
0380 const Cell_IndexType anEnd = theCellMax.index[idim];
0381 for (Cell_IndexType i = aStart; i <= anEnd; ++i)
0382 {
0383 theCell.index[idim] = i;
0384 if ( idim )
0385 {
0386 iterateAdd (idim-1, theCell, theCellMin, theCellMax, theTarget);
0387 }
0388 else
0389 {
0390 add (theCell, theTarget);
0391 }
0392 }
0393 }
0394
0395
0396 void remove (const Cell& theCell, const Target& theTarget)
0397 {
0398
0399 if ( ! myCells.Contains (theCell) )
0400 return;
0401
0402
0403 Cell& aMapCell = (Cell&)myCells.Added (theCell);
0404 ListNode* aNode = aMapCell.Objects;
0405 ListNode* aPrev = NULL;
0406 while (aNode)
0407 {
0408 ListNode* aNext = aNode->Next;
0409 if (Inspector::IsEqual (aNode->Object, theTarget))
0410 {
0411 aNode->Object.~Target();
0412 (aPrev ? aPrev->Next : aMapCell.Objects) = aNext;
0413
0414 }
0415 else
0416 aPrev = aNode;
0417 aNode = aNext;
0418 }
0419 }
0420
0421
0422
0423 void iterateRemove (int idim, Cell &theCell,
0424 const Cell& theCellMin, const Cell& theCellMax,
0425 const Target& theTarget)
0426 {
0427 const Cell_IndexType aStart = theCellMin.index[idim];
0428 const Cell_IndexType anEnd = theCellMax.index[idim];
0429 for (Cell_IndexType i = aStart; i <= anEnd; ++i)
0430 {
0431 theCell.index[idim] = i;
0432 if ( idim )
0433 {
0434 iterateRemove (idim-1, theCell, theCellMin, theCellMax, theTarget);
0435 }
0436 else
0437 {
0438 remove (theCell, theTarget);
0439 }
0440 }
0441 }
0442
0443
0444 void inspect (const Cell& theCell, Inspector& theInspector)
0445 {
0446
0447 if ( ! myCells.Contains (theCell) )
0448 return;
0449
0450
0451 Cell& aMapCell = (Cell&)myCells.Added (theCell);
0452 ListNode* aNode = aMapCell.Objects;
0453 ListNode* aPrev = NULL;
0454 while(aNode) {
0455 ListNode* aNext = aNode->Next;
0456 NCollection_CellFilter_Action anAction =
0457 theInspector.Inspect (aNode->Object);
0458
0459 if ( anAction == CellFilter_Purge ) {
0460 aNode->Object.~Target();
0461 (aPrev ? aPrev->Next : aMapCell.Objects) = aNext;
0462
0463 }
0464 else
0465 aPrev = aNode;
0466 aNode = aNext;
0467 }
0468 }
0469
0470
0471 void iterateInspect (int idim, Cell &theCell,
0472 const Cell& theCellMin, const Cell& theCellMax,
0473 Inspector& theInspector)
0474 {
0475 const Cell_IndexType aStart = theCellMin.index[idim];
0476 const Cell_IndexType anEnd = theCellMax.index[idim];
0477 for (Cell_IndexType i = aStart; i <= anEnd; ++i)
0478 {
0479 theCell.index[idim] = i;
0480 if ( idim )
0481 {
0482 iterateInspect (idim-1, theCell, theCellMin, theCellMax, theInspector);
0483 }
0484 else
0485 {
0486 inspect (theCell, theInspector);
0487 }
0488 }
0489 }
0490
0491 protected:
0492 Standard_Integer myDim;
0493 Handle(NCollection_BaseAllocator) myAllocator;
0494 CellMap myCells;
0495 NCollection_Array1<Standard_Real> myCellSize;
0496 };
0497
0498
0499
0500
0501
0502
0503 class gp_XYZ;
0504 struct NCollection_CellFilter_InspectorXYZ
0505 {
0506
0507 enum { Dimension = 3 };
0508
0509
0510 typedef gp_XYZ Point;
0511
0512
0513 static Standard_Real Coord (int i, const Point &thePnt) { return thePnt.Coord(i+1); }
0514
0515
0516
0517 Point Shift (const Point& thePnt, Standard_Real theTol) const
0518 { return Point (thePnt.X() + theTol, thePnt.Y() + theTol, thePnt.Z() + theTol); }
0519 };
0520
0521
0522
0523
0524
0525
0526 class gp_XY;
0527 struct NCollection_CellFilter_InspectorXY
0528 {
0529
0530 enum { Dimension = 2 };
0531
0532
0533 typedef gp_XY Point;
0534
0535
0536 static Standard_Real Coord (int i, const Point &thePnt) { return thePnt.Coord(i+1); }
0537
0538
0539
0540 Point Shift (const Point& thePnt, Standard_Real theTol) const
0541 { return Point (thePnt.X() + theTol, thePnt.Y() + theTol); }
0542 };
0543
0544 #endif