mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-04 13:13:25 +03:00
0026395: Merge clasees NCollection_CellFilter_NDim and NCollection_CellFilter
Deleted exceed class CellFilterNDim. Now dimension count used as input parameter in NCollection_CellFilter. minor corrections.
This commit is contained in:
@@ -16,7 +16,6 @@ NCollection_BaseVector.cxx
|
||||
NCollection_BaseVector.hxx
|
||||
NCollection_Buffer.hxx
|
||||
NCollection_CellFilter.hxx
|
||||
NCollection_CellFilterNDim.hxx
|
||||
NCollection_Comparator.hxx
|
||||
NCollection_DataMap.hxx
|
||||
NCollection_DefaultHasher.hxx
|
||||
|
@@ -17,6 +17,8 @@
|
||||
#define NCollection_CellFilter_HeaderFile
|
||||
|
||||
#include <Standard_Real.hxx>
|
||||
#include <NCollection_LocalArray.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
#include <NCollection_List.hxx>
|
||||
#include <NCollection_Map.hxx>
|
||||
#include <NCollection_DataMap.hxx>
|
||||
@@ -110,37 +112,29 @@ enum NCollection_CellFilter_Action
|
||||
* Note that method Inspect() can be const and/or virtual.
|
||||
*/
|
||||
|
||||
template <class Inspector>
|
||||
class NCollection_CellFilter
|
||||
{
|
||||
template <class Inspector> class NCollection_CellFilter
|
||||
{
|
||||
public:
|
||||
typedef TYPENAME Inspector::Target Target;
|
||||
typedef TYPENAME Inspector::Point Point;
|
||||
|
||||
public:
|
||||
|
||||
//! Constructor; initialized by cell size.
|
||||
//! Constructor; initialized by dimension count and cell size.
|
||||
//!
|
||||
//! Note: the cell size must be ensured to be greater than
|
||||
//! Note: the cell size must be ensured to be greater than
|
||||
//! maximal co-ordinate of the involved points divided by INT_MAX,
|
||||
//! in order to avoid integer overflow of cell index.
|
||||
//!
|
||||
//! By default cell size is 0, which is invalid; thus if default
|
||||
//! constructor is used, the tool must be initialized later with
|
||||
//! appropriate cell size by call to Reset()
|
||||
NCollection_CellFilter (Standard_Real theCellSize=0,
|
||||
const Handle(NCollection_IncAllocator)& theAlloc=0)
|
||||
{
|
||||
Reset (theCellSize, theAlloc);
|
||||
}
|
||||
|
||||
//! Constructor; initialized by cell sizes along each dimension.
|
||||
//! Note: the cell size in each dimension must be ensured to be greater than
|
||||
//! maximal co-ordinate of the involved points by this dimension divided by INT_MAX,
|
||||
//! in order to avoid integer overflow of cell index.
|
||||
NCollection_CellFilter (Standard_Real theCellSize[],
|
||||
const Handle(NCollection_IncAllocator)& theAlloc=0)
|
||||
NCollection_CellFilter (const Standard_Integer theDim,
|
||||
const Standard_Real theCellSize = 0,
|
||||
const Handle(NCollection_IncAllocator)& theAlloc = 0)
|
||||
: myCellSize(0, theDim - 1)
|
||||
{
|
||||
myDim = theDim;
|
||||
Reset (theCellSize, theAlloc);
|
||||
}
|
||||
|
||||
@@ -148,17 +142,16 @@ public:
|
||||
void Reset (Standard_Real theCellSize,
|
||||
const Handle(NCollection_IncAllocator)& theAlloc=0)
|
||||
{
|
||||
for (int i=0; i < Inspector::Dimension; i++)
|
||||
myCellSize[i] = theCellSize;
|
||||
for (int i=0; i < myDim; i++)
|
||||
myCellSize(i) = theCellSize;
|
||||
resetAllocator ( theAlloc );
|
||||
}
|
||||
|
||||
//! Clear the data structures and set new cell sizes and allocator
|
||||
void Reset (Standard_Real theCellSize[],
|
||||
void Reset (NCollection_Array1<Standard_Real> theCellSize,
|
||||
const Handle(NCollection_IncAllocator)& theAlloc=0)
|
||||
{
|
||||
for (int i=0; i < Inspector::Dimension; i++)
|
||||
myCellSize[i] = theCellSize[i];
|
||||
myCellSize = theCellSize;
|
||||
resetAllocator ( theAlloc );
|
||||
}
|
||||
|
||||
@@ -180,7 +173,7 @@ public:
|
||||
Cell aCellMax (thePntMax, myCellSize);
|
||||
Cell aCell = aCellMin;
|
||||
// add object recursively into all cells in range
|
||||
iterateAdd (Inspector::Dimension-1, aCell, aCellMin, aCellMax, theTarget);
|
||||
iterateAdd (myDim-1, aCell, aCellMin, aCellMax, theTarget);
|
||||
}
|
||||
|
||||
//! Find a target object at a point and remove it from the structures.
|
||||
@@ -204,7 +197,7 @@ public:
|
||||
Cell aCellMax (thePntMax, myCellSize);
|
||||
Cell aCell = aCellMin;
|
||||
// remove object recursively from all cells in range
|
||||
iterateRemove (Inspector::Dimension-1, aCell, aCellMin, aCellMax, theTarget);
|
||||
iterateRemove (myDim-1, aCell, aCellMin, aCellMax, theTarget);
|
||||
}
|
||||
|
||||
//! Inspect all targets in the cell corresponding to the given point
|
||||
@@ -225,7 +218,7 @@ public:
|
||||
Cell aCellMax (thePntMax, myCellSize);
|
||||
Cell aCell = aCellMin;
|
||||
// inspect object recursively into all cells in range
|
||||
iterateInspect (Inspector::Dimension-1, aCell,
|
||||
iterateInspect (myDim-1, aCell,
|
||||
aCellMin, aCellMax, theInspector);
|
||||
}
|
||||
|
||||
@@ -238,7 +231,14 @@ protected:
|
||||
/**
|
||||
* Auxiliary class for storing points belonging to the cell as the list
|
||||
*/
|
||||
struct ListNode {
|
||||
struct ListNode
|
||||
{
|
||||
ListNode()
|
||||
{
|
||||
// Empty constructor is forbidden.
|
||||
Standard_NoSuchObject::Raise("NCollection_CellFilter::ListNode()");
|
||||
}
|
||||
|
||||
Target Object;
|
||||
ListNode *Next;
|
||||
};
|
||||
@@ -251,17 +251,16 @@ protected:
|
||||
struct Cell
|
||||
{
|
||||
public:
|
||||
//! Empty constructor -- required only for NCollection_Map,
|
||||
//! therefore does not initialize index (avoid cycle)
|
||||
Cell () : Objects(0) {}
|
||||
|
||||
//! Constructor; computes cell indices
|
||||
Cell (const Point& thePnt, const Standard_Real theCellSize[])
|
||||
: Objects(0)
|
||||
Cell (const Point& thePnt,
|
||||
const NCollection_Array1<Standard_Real>& theCellSize)
|
||||
: index(theCellSize.Size()),
|
||||
Objects(0)
|
||||
{
|
||||
for (int i=0; i < Inspector::Dimension; i++)
|
||||
for (int i = 0; i < theCellSize.Size(); i++)
|
||||
{
|
||||
Standard_Real val = (Standard_Real)(Inspector::Coord(i, thePnt) / theCellSize[i]);
|
||||
Standard_Real val = (Standard_Real)(Inspector::Coord(i, thePnt) / theCellSize(theCellSize.Lower() + i));
|
||||
//If the value of index is greater than
|
||||
//INT_MAX it is decreased correspondingly for the value of INT_MAX. If the value
|
||||
//of index is less than INT_MIN it is increased correspondingly for the absolute
|
||||
@@ -273,13 +272,19 @@ protected:
|
||||
}
|
||||
|
||||
//! Copy constructor: ensure that list is not deleted twice
|
||||
Cell (const Cell& theOther) { (*this) = theOther; }
|
||||
Cell (const Cell& theOther)
|
||||
: index(theOther.index.Size())
|
||||
{
|
||||
(*this) = theOther;
|
||||
}
|
||||
|
||||
//! Assignment operator: ensure that list is not deleted twice
|
||||
void operator = (const Cell& theOther)
|
||||
{
|
||||
for (int i=0; i < Inspector::Dimension; i++)
|
||||
index[i] = theOther.index[i];
|
||||
Standard_Integer myDim = Standard_Integer(theOther.index.Size());
|
||||
for(Standard_Integer anIdx = 0; anIdx < myDim; anIdx++)
|
||||
index[anIdx] = theOther.index[anIdx];
|
||||
|
||||
Objects = theOther.Objects;
|
||||
((Cell&)theOther).Objects = 0;
|
||||
}
|
||||
@@ -296,7 +301,8 @@ protected:
|
||||
//! Compare cell with other one
|
||||
Standard_Boolean IsEqual (const Cell& theOther) const
|
||||
{
|
||||
for (int i=0; i < Inspector::Dimension; i++)
|
||||
Standard_Integer myDim = Standard_Integer(theOther.index.Size());
|
||||
for (int i=0; i < myDim; i++)
|
||||
if ( index[i] != theOther.index[i] ) return Standard_False;
|
||||
return Standard_True;
|
||||
}
|
||||
@@ -305,15 +311,16 @@ protected:
|
||||
Standard_Integer HashCode (const Standard_Integer theUpper) const
|
||||
{
|
||||
// number of bits per each dimension in the hash code
|
||||
const Standard_Size aShiftBits = (BITS(long)-1) / Inspector::Dimension;
|
||||
Standard_Integer myDim = Standard_Integer(index.Size());
|
||||
const Standard_Size aShiftBits = (BITS(long)-1) / myDim;
|
||||
long aCode=0;
|
||||
for (int i=0; i < Inspector::Dimension; i++)
|
||||
for (int i=0; i < myDim; i++)
|
||||
aCode = ( aCode << aShiftBits ) ^ index[i];
|
||||
return (unsigned)aCode % theUpper;
|
||||
}
|
||||
|
||||
public:
|
||||
long index[Inspector::Dimension];
|
||||
NCollection_LocalArray<long, 10> index;
|
||||
ListNode *Objects;
|
||||
};
|
||||
|
||||
@@ -452,9 +459,10 @@ protected:
|
||||
}
|
||||
|
||||
protected:
|
||||
Standard_Integer myDim;
|
||||
Handle(NCollection_BaseAllocator) myAllocator;
|
||||
NCollection_Map<Cell> myCells;
|
||||
Standard_Real myCellSize [Inspector::Dimension];
|
||||
NCollection_Array1<Standard_Real> myCellSize;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -504,4 +512,3 @@ struct NCollection_CellFilter_InspectorXY
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@@ -1,404 +0,0 @@
|
||||
// Created on: 2015-06-17
|
||||
// Created by: Alexander Malyshev
|
||||
// Copyright (c) 2007-2015 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef NCollection_CellFilterNDim_HeaderFile
|
||||
#define NCollection_CellFilterNDim_HeaderFile
|
||||
|
||||
#include <NCollection_CellFilter.hxx>
|
||||
#include <Standard_Real.hxx>
|
||||
#include <NCollection_List.hxx>
|
||||
#include <NCollection_Map.hxx>
|
||||
#include <NCollection_DataMap.hxx>
|
||||
#include <NCollection_IncAllocator.hxx>
|
||||
#include <NCollection_TypeDef.hxx>
|
||||
#include <NCollection_Array1.hxx>
|
||||
|
||||
/**
|
||||
* A data structure for sorting geometric objects (called targets) in
|
||||
* n-dimensional space into cells, with associated algorithm for fast checking
|
||||
* of coincidence (overlapping, intersection, etc.) with other objects
|
||||
* (called here bullets).
|
||||
*
|
||||
* Purpose of this class is to add possibility to work with CellFilter with unknown
|
||||
dimension count at compilation time.
|
||||
*
|
||||
* For more details look at base class NCollection_CellFilter.
|
||||
*
|
||||
*/
|
||||
|
||||
template <class Inspector> class NCollection_CellFilterNDim
|
||||
{
|
||||
public:
|
||||
typedef TYPENAME Inspector::Target Target;
|
||||
typedef TYPENAME Inspector::Point Point;
|
||||
|
||||
public:
|
||||
|
||||
//! Constructor; initialized by dimension count and cell size.
|
||||
//!
|
||||
//! Note: the cell size must be ensured to be greater than
|
||||
//! maximal co-ordinate of the involved points divided by INT_MAX,
|
||||
//! in order to avoid integer overflow of cell index.
|
||||
//!
|
||||
//! By default cell size is 0, which is invalid; thus if default
|
||||
//! constructor is used, the tool must be initialized later with
|
||||
//! appropriate cell size by call to Reset()
|
||||
NCollection_CellFilterNDim (const Standard_Integer theDim,
|
||||
const Standard_Real theCellSize = 0,
|
||||
const Handle(NCollection_IncAllocator)& theAlloc = 0)
|
||||
: myCellSize(0, theDim - 1)
|
||||
{
|
||||
myDim = theDim;
|
||||
Reset (theCellSize, theAlloc);
|
||||
}
|
||||
|
||||
//! Constructor; initialized by dimension count and cell sizes along each dimension.
|
||||
//! Note: the cell size in each dimension must be ensured to be greater than
|
||||
//! maximal co-ordinate of the involved points by this dimension divided by INT_MAX,
|
||||
//! in order to avoid integer overflow of cell index.
|
||||
NCollection_CellFilterNDim (const Standard_Integer theDim,
|
||||
const NCollection_Array1<Standard_Real> theCellSize,
|
||||
const Handle(NCollection_IncAllocator)& theAlloc = 0)
|
||||
: myCellSize(0, theDim - 1)
|
||||
{
|
||||
myDim = theDim;
|
||||
Reset (theCellSize, theAlloc);
|
||||
}
|
||||
|
||||
//! Clear the data structures, set new cell size and allocator
|
||||
void Reset (Standard_Real theCellSize,
|
||||
const Handle(NCollection_IncAllocator)& theAlloc=0)
|
||||
{
|
||||
for (int i=0; i < myDim; i++)
|
||||
myCellSize(i) = theCellSize;
|
||||
resetAllocator ( theAlloc );
|
||||
}
|
||||
|
||||
//! Clear the data structures and set new cell sizes and allocator
|
||||
void Reset (NCollection_Array1<Standard_Real> theCellSize,
|
||||
const Handle(NCollection_IncAllocator)& theAlloc=0)
|
||||
{
|
||||
myCellSize = theCellSize;
|
||||
resetAllocator ( theAlloc );
|
||||
}
|
||||
|
||||
//! Adds a target object for further search at a point (into only one cell)
|
||||
void Add (const Target& theTarget, const Point &thePnt)
|
||||
{
|
||||
Cell aCell (thePnt, myCellSize);
|
||||
add (aCell, theTarget);
|
||||
}
|
||||
|
||||
//! Adds a target object for further search in the range of cells
|
||||
//! defined by two points (the first point must have all co-ordinates equal or
|
||||
//! less than the same co-ordinate of the second point)
|
||||
void Add (const Target& theTarget,
|
||||
const Point &thePntMin, const Point &thePntMax)
|
||||
{
|
||||
// get cells range by minimal and maximal co-ordinates
|
||||
Cell aCellMin (thePntMin, myCellSize);
|
||||
Cell aCellMax (thePntMax, myCellSize);
|
||||
Cell aCell = aCellMin;
|
||||
// add object recursively into all cells in range
|
||||
iterateAdd (myDim-1, aCell, aCellMin, aCellMax, theTarget);
|
||||
}
|
||||
|
||||
//! Find a target object at a point and remove it from the structures.
|
||||
//! For usage of this method "operator ==" should be defined for Target.
|
||||
void Remove (const Target& theTarget, const Point &thePnt)
|
||||
{
|
||||
Cell aCell (thePnt, myCellSize);
|
||||
remove (aCell, theTarget);
|
||||
}
|
||||
|
||||
//! Find a target object in the range of cells defined by two points and
|
||||
//! remove it from the structures
|
||||
//! (the first point must have all co-ordinates equal or
|
||||
//! less than the same co-ordinate of the second point).
|
||||
//! For usage of this method "operator ==" should be defined for Target.
|
||||
void Remove (const Target& theTarget,
|
||||
const Point &thePntMin, const Point &thePntMax)
|
||||
{
|
||||
// get cells range by minimal and maximal co-ordinates
|
||||
Cell aCellMin (thePntMin, myCellSize);
|
||||
Cell aCellMax (thePntMax, myCellSize);
|
||||
Cell aCell = aCellMin;
|
||||
// remove object recursively from all cells in range
|
||||
iterateRemove (myDim-1, aCell, aCellMin, aCellMax, theTarget);
|
||||
}
|
||||
|
||||
//! Inspect all targets in the cell corresponding to the given point
|
||||
void Inspect (const Point& thePnt, Inspector &theInspector)
|
||||
{
|
||||
Cell aCell (thePnt, myCellSize);
|
||||
inspect (aCell, theInspector);
|
||||
}
|
||||
|
||||
//! Inspect all targets in the cells range limited by two given points
|
||||
//! (the first point must have all co-ordinates equal or
|
||||
//! less than the same co-ordinate of the second point)
|
||||
void Inspect (const Point& thePntMin, const Point& thePntMax,
|
||||
Inspector &theInspector)
|
||||
{
|
||||
// get cells range by minimal and maximal co-ordinates
|
||||
Cell aCellMin (thePntMin, myCellSize);
|
||||
Cell aCellMax (thePntMax, myCellSize);
|
||||
Cell aCell = aCellMin;
|
||||
// inspect object recursively into all cells in range
|
||||
iterateInspect (myDim-1, aCell,
|
||||
aCellMin, aCellMax, theInspector);
|
||||
}
|
||||
|
||||
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
|
||||
public: // work-around against obsolete SUN WorkShop 5.3 compiler
|
||||
#else
|
||||
protected:
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Auxiliary class for storing points belonging to the cell as the list
|
||||
*/
|
||||
struct ListNode
|
||||
{
|
||||
ListNode()
|
||||
{
|
||||
// Empty constructor is forbidden.
|
||||
Standard_NoSuchObject::Raise("NCollection_CellFilterNDim::ListNode()");
|
||||
}
|
||||
|
||||
Target Object;
|
||||
ListNode *Next;
|
||||
};
|
||||
|
||||
/**
|
||||
* Auxilary structure representing a cell in the space.
|
||||
* Cells are stored in the map, each cell contains list of objects
|
||||
* that belong to that cell.
|
||||
*/
|
||||
struct Cell
|
||||
{
|
||||
public:
|
||||
|
||||
//! Constructor; computes cell indices
|
||||
Cell (const Point& thePnt,
|
||||
const NCollection_Array1<Standard_Real> theCellSize)
|
||||
: index(0, theCellSize.Size() - 1),
|
||||
Objects(0)
|
||||
{
|
||||
for (int i=0; i < theCellSize.Size(); i++)
|
||||
{
|
||||
Standard_Real val = (Standard_Real)(Inspector::Coord(i, thePnt) / theCellSize(i));
|
||||
//If the value of index is greater than
|
||||
//INT_MAX it is decreased correspondingly for the value of INT_MAX. If the value
|
||||
//of index is less than INT_MIN it is increased correspondingly for the absolute
|
||||
//value of INT_MIN.
|
||||
index(i) = long((val > INT_MAX - 1) ? fmod(val, (Standard_Real) INT_MAX)
|
||||
: (val < INT_MIN + 1) ? fmod(val, (Standard_Real) INT_MIN)
|
||||
: val);
|
||||
}
|
||||
}
|
||||
|
||||
//! Copy constructor: ensure that list is not deleted twice
|
||||
Cell (const Cell& theOther)
|
||||
: index(0, theOther.index.Size() - 1)
|
||||
{
|
||||
(*this) = theOther;
|
||||
}
|
||||
|
||||
//! Assignment operator: ensure that list is not deleted twice
|
||||
void operator = (const Cell& theOther)
|
||||
{
|
||||
index = theOther.index;
|
||||
Objects = theOther.Objects;
|
||||
((Cell&)theOther).Objects = 0;
|
||||
}
|
||||
|
||||
//! Destructor; calls destructors for targets contained in the list
|
||||
~Cell ()
|
||||
{
|
||||
for ( ListNode* aNode = Objects; aNode; aNode = aNode->Next )
|
||||
aNode->Object.~Target();
|
||||
// note that list nodes need not to be freed, since IncAllocator is used
|
||||
Objects = 0;
|
||||
}
|
||||
|
||||
//! Compare cell with other one
|
||||
Standard_Boolean IsEqual (const Cell& theOther) const
|
||||
{
|
||||
Standard_Integer myDim = theOther.index.Size();
|
||||
for (int i=0; i < myDim; i++)
|
||||
if ( index(i) != theOther.index(i) ) return Standard_False;
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//! Compute hash code
|
||||
Standard_Integer HashCode (const Standard_Integer theUpper) const
|
||||
{
|
||||
// number of bits per each dimension in the hash code
|
||||
Standard_Integer myDim = index.Size();
|
||||
const Standard_Size aShiftBits = (BITS(long)-1) / myDim;
|
||||
long aCode=0;
|
||||
for (int i=0; i < myDim; i++)
|
||||
aCode = ( aCode << aShiftBits ) ^ index(i);
|
||||
return (unsigned)aCode % theUpper;
|
||||
}
|
||||
|
||||
public:
|
||||
NCollection_Array1<long> index;
|
||||
ListNode *Objects;
|
||||
};
|
||||
|
||||
// definition of global functions is needed for map
|
||||
friend Standard_Integer HashCode (const Cell &aCell, const Standard_Integer theUpper)
|
||||
{ return aCell.HashCode(theUpper); }
|
||||
friend Standard_Boolean IsEqual (const Cell &aCell1, const Cell &aCell2)
|
||||
{ return aCell1.IsEqual(aCell2); }
|
||||
|
||||
protected:
|
||||
|
||||
//! Reset allocator to the new one
|
||||
void resetAllocator (const Handle(NCollection_IncAllocator)& theAlloc)
|
||||
{
|
||||
if ( theAlloc.IsNull() )
|
||||
myAllocator = new NCollection_IncAllocator;
|
||||
else
|
||||
myAllocator = theAlloc;
|
||||
myCells.Clear ( myAllocator );
|
||||
}
|
||||
|
||||
//! Add a new target object into the specified cell
|
||||
void add (const Cell& theCell, const Target& theTarget)
|
||||
{
|
||||
// add a new cell or get reference to existing one
|
||||
Cell& aMapCell = (Cell&)myCells.Added (theCell);
|
||||
|
||||
// create a new list node and add it to the beginning of the list
|
||||
ListNode* aNode = (ListNode*)myAllocator->Allocate(sizeof(ListNode));
|
||||
new (&aNode->Object) Target (theTarget);
|
||||
aNode->Next = aMapCell.Objects;
|
||||
aMapCell.Objects = aNode;
|
||||
}
|
||||
|
||||
//! Internal addition function, performing iteration for adjacent cells
|
||||
//! by one dimension; called recursively to cover all dimensions
|
||||
void iterateAdd (int idim, Cell &theCell,
|
||||
const Cell& theCellMin, const Cell& theCellMax,
|
||||
const Target& theTarget)
|
||||
{
|
||||
int start = theCellMin.index(idim);
|
||||
int end = theCellMax.index(idim);
|
||||
for (int i=start; i <= end; i++) {
|
||||
theCell.index(idim) = i;
|
||||
if ( idim ) // recurse
|
||||
iterateAdd (idim-1, theCell, theCellMin, theCellMax, theTarget);
|
||||
else // add to this cell
|
||||
add (theCell, theTarget);
|
||||
}
|
||||
}
|
||||
|
||||
//! Remove the target object from the specified cell
|
||||
void remove (const Cell& theCell, const Target& theTarget)
|
||||
{
|
||||
// check if any objects are recorded in that cell
|
||||
if ( ! myCells.Contains (theCell) )
|
||||
return;
|
||||
|
||||
// iterate by objects in the cell and check each
|
||||
Cell& aMapCell = (Cell&)myCells.Added (theCell);
|
||||
ListNode* aNode = aMapCell.Objects;
|
||||
ListNode* aPrev = NULL;
|
||||
while (aNode)
|
||||
{
|
||||
ListNode* aNext = aNode->Next;
|
||||
if (Inspector::IsEqual (aNode->Object, theTarget))
|
||||
{
|
||||
aNode->Object.~Target();
|
||||
(aPrev ? aPrev->Next : aMapCell.Objects) = aNext;
|
||||
// note that aNode itself need not to be freed, since IncAllocator is used
|
||||
}
|
||||
else
|
||||
aPrev = aNode;
|
||||
aNode = aNext;
|
||||
}
|
||||
}
|
||||
|
||||
//! Internal removal function, performing iteration for adjacent cells
|
||||
//! by one dimension; called recursively to cover all dimensions
|
||||
void iterateRemove (int idim, Cell &theCell,
|
||||
const Cell& theCellMin, const Cell& theCellMax,
|
||||
const Target& theTarget)
|
||||
{
|
||||
int start = theCellMin.index(idim);
|
||||
int end = theCellMax.index(idim);
|
||||
for (int i=start; i <= end; i++) {
|
||||
theCell.index(idim) = i;
|
||||
if ( idim ) // recurse
|
||||
iterateRemove (idim-1, theCell, theCellMin, theCellMax, theTarget);
|
||||
else // remove from this cell
|
||||
remove (theCell, theTarget);
|
||||
}
|
||||
}
|
||||
|
||||
//! Inspect the target objects in the specified cell.
|
||||
void inspect (const Cell& theCell, Inspector& theInspector)
|
||||
{
|
||||
// check if any objects are recorded in that cell
|
||||
if ( ! myCells.Contains (theCell) )
|
||||
return;
|
||||
|
||||
// iterate by objects in the cell and check each
|
||||
Cell& aMapCell = (Cell&)myCells.Added (theCell);
|
||||
ListNode* aNode = aMapCell.Objects;
|
||||
ListNode* aPrev = NULL;
|
||||
while(aNode) {
|
||||
ListNode* aNext = aNode->Next;
|
||||
NCollection_CellFilter_Action anAction =
|
||||
theInspector.Inspect (aNode->Object);
|
||||
// delete items requested to be purged
|
||||
if ( anAction == CellFilter_Purge ) {
|
||||
aNode->Object.~Target();
|
||||
(aPrev ? aPrev->Next : aMapCell.Objects) = aNext;
|
||||
// note that aNode itself need not to be freed, since IncAllocator is used
|
||||
}
|
||||
else
|
||||
aPrev = aNode;
|
||||
aNode = aNext;
|
||||
}
|
||||
}
|
||||
|
||||
//! Inspect the target objects in the specified range of the cells
|
||||
void iterateInspect (int idim, Cell &theCell,
|
||||
const Cell& theCellMin, const Cell& theCellMax,
|
||||
Inspector& theInspector)
|
||||
{
|
||||
int start = theCellMin.index(idim);
|
||||
int end = theCellMax.index(idim);
|
||||
for (int i=start; i <= end; i++) {
|
||||
theCell.index(idim) = i;
|
||||
if ( idim ) // recurse
|
||||
iterateInspect (idim-1, theCell, theCellMin, theCellMax, theInspector);
|
||||
else // inspect this cell
|
||||
inspect (theCell, theInspector);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
Standard_Integer myDim;
|
||||
Handle(NCollection_BaseAllocator) myAllocator;
|
||||
NCollection_Map<Cell> myCells;
|
||||
NCollection_Array1<Standard_Real> myCellSize;
|
||||
};
|
||||
|
||||
#endif
|
@@ -20,13 +20,10 @@
|
||||
|
||||
//! Auxiliary class optimizing creation of array buffer
|
||||
//! (using stack allocation for small arrays).
|
||||
template<class theItem> class NCollection_LocalArray
|
||||
template<class theItem, Standard_Integer MAX_ARRAY_SIZE = 1024> class NCollection_LocalArray
|
||||
{
|
||||
public:
|
||||
|
||||
// 1K * sizeof (theItem)
|
||||
static const size_t MAX_ARRAY_SIZE = 1024;
|
||||
|
||||
NCollection_LocalArray (const size_t theSize)
|
||||
: myPtr (myBuffer)
|
||||
{
|
||||
@@ -34,7 +31,7 @@ public:
|
||||
}
|
||||
|
||||
NCollection_LocalArray ()
|
||||
: myPtr (myBuffer) {}
|
||||
: myPtr (myBuffer), mySize(0) {}
|
||||
|
||||
~NCollection_LocalArray()
|
||||
{
|
||||
@@ -48,6 +45,13 @@ public:
|
||||
myPtr = (theItem*)Standard::Allocate (theSize * sizeof(theItem));
|
||||
else
|
||||
myPtr = myBuffer;
|
||||
|
||||
mySize = theSize;
|
||||
}
|
||||
|
||||
size_t Size() const
|
||||
{
|
||||
return mySize;
|
||||
}
|
||||
|
||||
operator theItem*() const
|
||||
@@ -72,6 +76,7 @@ protected:
|
||||
|
||||
theItem myBuffer[MAX_ARRAY_SIZE];
|
||||
theItem* myPtr;
|
||||
size_t mySize;
|
||||
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user