mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-25 02:10:32 +05:00
0020464: EDF 1100 SMESH: Performance issue of the function MoveNode
0020139: EDF 944 SMESH : Get 2D/3D element with X, Y, Z coordinates optimize for performance
This commit is contained in:
parent
58a4d3cca6
commit
7512099966
@ -30,19 +30,37 @@
|
||||
|
||||
//===========================================================================
|
||||
/*!
|
||||
* \brief SMESH_Octree Constructor
|
||||
* \param maxLevel - The level max the octree can reach (If <0 unlimited)
|
||||
* Constructor. limit must be provided at tree root construction.
|
||||
* limit will be deleted by SMESH_Octree.
|
||||
*/
|
||||
//===========================================================================
|
||||
SMESH_Octree::SMESH_Octree (const int maxLevel, const double minBoxSize):
|
||||
myChildren(NULL),
|
||||
myFather(NULL),
|
||||
myLevel(0),
|
||||
myMaxLevel(maxLevel),
|
||||
myMinBoxSize(minBoxSize),
|
||||
myIsLeaf(-1)
|
||||
|
||||
SMESH_Octree::SMESH_Octree (SMESH_Octree::Limit* limit):
|
||||
myChildren(NULL),
|
||||
myFather(NULL),
|
||||
myIsLeaf( false ),
|
||||
myLimit( limit ),
|
||||
myLevel(0),
|
||||
myBox(NULL)
|
||||
{
|
||||
myBox = new Bnd_B3d();
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Compute the Octree
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
void SMESH_Octree::compute()
|
||||
{
|
||||
if ( myLevel==0 )
|
||||
{
|
||||
myBox = buildRootBox();
|
||||
if ( myLimit->myMinBoxSize > 0. && maxSize() <= myLimit->myMinBoxSize )
|
||||
myIsLeaf = true;
|
||||
else
|
||||
buildChildren();
|
||||
}
|
||||
}
|
||||
|
||||
//======================================
|
||||
@ -50,85 +68,25 @@ SMESH_Octree::SMESH_Octree (const int maxLevel, const double minBoxSize):
|
||||
* \brief SMESH_Octree Destructor
|
||||
*/
|
||||
//======================================
|
||||
|
||||
SMESH_Octree::~SMESH_Octree ()
|
||||
{
|
||||
if(myChildren != NULL)
|
||||
{
|
||||
if(!myIsLeaf)
|
||||
if(!isLeaf())
|
||||
{
|
||||
for(int i = 0; i<8; i++)
|
||||
delete myChildren[i];
|
||||
delete[] myChildren;
|
||||
myChildren = 0;
|
||||
}
|
||||
}
|
||||
delete myBox;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
/*!
|
||||
* \brief Set the bounding box of the Octree
|
||||
* \param box - 3d Bounding Box of the Octree
|
||||
*/
|
||||
//===========================================================================
|
||||
void SMESH_Octree::setBox(const Bnd_B3d* box)
|
||||
{
|
||||
// delete myBox;
|
||||
// myBox=new Bnd_B3d(*box);
|
||||
*myBox = *box;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
/*!
|
||||
* \brief Set box to the 3d Bounding Box of the Octree
|
||||
* \param box - Set box to the 3d Bounding Box of the Octree
|
||||
*/
|
||||
//===========================================================================
|
||||
void SMESH_Octree::getBox(Bnd_B3d& box)
|
||||
{
|
||||
// if(box != NULL)
|
||||
// delete box;
|
||||
// box = new Bnd_B3d (*myBox);
|
||||
box = *myBox;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
/*!
|
||||
* \brief Set the max level of the Octree
|
||||
* \param maxLevel - The level max the octree can reach (If <0 unlimited)
|
||||
*/
|
||||
//===========================================================================
|
||||
void SMESH_Octree::setMaxLevel(const int maxLevel)
|
||||
{myMaxLevel = maxLevel;}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
/*!
|
||||
* \brief Compute the bigger dimension of the box
|
||||
* \param box - 3d Box
|
||||
* \retval double - bigger dimension of the box
|
||||
*/
|
||||
//===========================================================================
|
||||
double SMESH_Octree::maxSize(const Bnd_B3d* box)
|
||||
{
|
||||
if(box ==NULL)
|
||||
return 0;
|
||||
gp_XYZ min = box->CornerMin();
|
||||
gp_XYZ max = box->CornerMax();
|
||||
gp_XYZ Size = (max - min);
|
||||
double returnVal = (Size.X()>Size.Y())?Size.X():Size.Y();
|
||||
return (returnVal>Size.Z())?returnVal:Size.Z();
|
||||
}
|
||||
|
||||
//=============================
|
||||
/*!
|
||||
* \brief Compute the Octree
|
||||
*/
|
||||
//=============================
|
||||
void SMESH_Octree::Compute()
|
||||
{
|
||||
// As soon as the Octree is a Leaf, I stop building his children
|
||||
if(!isLeaf())
|
||||
buildChildren();
|
||||
if ( myBox )
|
||||
delete myBox;
|
||||
myBox = 0;
|
||||
if ( level() == 0 )
|
||||
delete myLimit;
|
||||
myLimit = 0;
|
||||
}
|
||||
|
||||
//=================================================================
|
||||
@ -136,8 +94,11 @@ void SMESH_Octree::Compute()
|
||||
* \brief Build the 8 children boxes and call buildChildrenData()
|
||||
*/
|
||||
//=================================================================
|
||||
|
||||
void SMESH_Octree::buildChildren()
|
||||
{
|
||||
if ( isLeaf() ) return;
|
||||
|
||||
myChildren = new SMESH_Octree*[8];
|
||||
|
||||
gp_XYZ min = myBox->CornerMin();
|
||||
@ -147,7 +108,6 @@ void SMESH_Octree::buildChildren()
|
||||
gp_XYZ childHsize = HSize/2.;
|
||||
|
||||
Standard_Real XminChild, YminChild, ZminChild;
|
||||
Bnd_B3d* box;
|
||||
gp_XYZ minChild;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
@ -166,19 +126,53 @@ void SMESH_Octree::buildChildren()
|
||||
ZminChild = (i<4)?min.Z():mid.Z();
|
||||
minChild.SetCoord(XminChild, YminChild, ZminChild);
|
||||
|
||||
box = new Bnd_B3d(minChild+childHsize,childHsize);
|
||||
// The child is of the same type than its father (For instance, a SMESH_OctreeNode)
|
||||
// We allocate the memory we need for the child
|
||||
myChildren[i] = allocateOctreeChild();
|
||||
// and we assign to him its box.
|
||||
myChildren[i]->setBox(box);
|
||||
delete box;
|
||||
myChildren[i]->myFather = this;
|
||||
myChildren[i]->myLimit = myLimit;
|
||||
myChildren[i]->myLevel = myLevel + 1;
|
||||
myChildren[i]->myBox = new Bnd_B3d(minChild+childHsize,childHsize);
|
||||
if ( myLimit->myMinBoxSize > 0. && myChildren[i]->maxSize() <= myLimit->myMinBoxSize )
|
||||
myChildren[i]->myIsLeaf = true;
|
||||
}
|
||||
|
||||
// After building the 8 boxes, we put the data into the children..
|
||||
// After building the 8 boxes, we put the data into the children.
|
||||
buildChildrenData();
|
||||
|
||||
//After we pass to the next level of the Octree
|
||||
for (int i = 0; i < 8; i++)
|
||||
myChildren[i]->Compute();
|
||||
for (int i = 0; i<8; i++)
|
||||
myChildren[i]->buildChildren();
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Tell if Octree is a leaf or not
|
||||
* An inheriting class can influence it via myIsLeaf protected field
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
bool SMESH_Octree::isLeaf() const
|
||||
{
|
||||
return myIsLeaf || ((myLimit->myMaxLevel > 0) ? (level() >= myLimit->myMaxLevel) : false );
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
/*!
|
||||
* \brief Compute the bigger dimension of my box
|
||||
*/
|
||||
//===========================================================================
|
||||
|
||||
double SMESH_Octree::maxSize() const
|
||||
{
|
||||
if ( myBox )
|
||||
{
|
||||
gp_XYZ min = myBox->CornerMin();
|
||||
gp_XYZ max = myBox->CornerMax();
|
||||
gp_XYZ Size = (max - min);
|
||||
double returnVal = (Size.X()>Size.Y())?Size.X():Size.Y();
|
||||
return (returnVal>Size.Z())?returnVal:Size.Z();
|
||||
}
|
||||
return 0.;
|
||||
}
|
||||
|
@ -34,68 +34,90 @@
|
||||
class SMESH_Octree {
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
SMESH_Octree (const int maxLevel = -1, const double minBoxSize = 0.);
|
||||
|
||||
// Data limiting the tree height
|
||||
struct Limit {
|
||||
// MaxLevel of the Octree
|
||||
int myMaxLevel;
|
||||
// Minimal size of the Box
|
||||
double myMinBoxSize;
|
||||
|
||||
// Default:
|
||||
// maxLevel-> 8^8 = 16777216 terminal trees
|
||||
// minSize -> box size not checked
|
||||
Limit(int maxLevel=8, double minSize=0.):myMaxLevel(maxLevel),myMinBoxSize(minSize) {}
|
||||
virtual ~Limit() {} // it can be inherited
|
||||
};
|
||||
|
||||
// Constructor. limit must be provided at tree root construction.
|
||||
// limit will be deleted by SMESH_Octree
|
||||
SMESH_Octree (Limit* limit=0);
|
||||
|
||||
// Destructor
|
||||
virtual ~SMESH_Octree ();
|
||||
|
||||
// Tell if Octree is a leaf or not (has to be implemented in inherited classes)
|
||||
virtual const bool isLeaf() = 0;
|
||||
// Compute the Octree. Must be called by constructor of inheriting class
|
||||
void compute();
|
||||
|
||||
// Compute the Octree
|
||||
void Compute();
|
||||
|
||||
// Set the maximal level of the Octree
|
||||
void setMaxLevel(const int maxLevel);
|
||||
|
||||
// Set the minimal size of the Box
|
||||
void setMinBoxSize(const double minBoxSize){myMinBoxSize = minBoxSize;};
|
||||
|
||||
// Set the bounding box of the Octree
|
||||
void setBox(const Bnd_B3d* box);
|
||||
|
||||
// Set box to the 3d Bounding Box of the Octree
|
||||
void getBox(Bnd_B3d & box);
|
||||
|
||||
// Compute the bigger dimension of the box
|
||||
static double maxSize(const Bnd_B3d* box);
|
||||
// Tell if Octree is a leaf or not.
|
||||
// An inheriting class can influence it via myIsLeaf protected field
|
||||
bool isLeaf() const;
|
||||
|
||||
// Return its level
|
||||
int level() const { return myLevel; }
|
||||
|
||||
// Get box to the 3d Bounding Box of the Octree
|
||||
const Bnd_B3d& getBox() const { return *myBox; }
|
||||
|
||||
// Compute the bigger dimension of my box
|
||||
double maxSize() const;
|
||||
|
||||
// Return index of a child the given point is in
|
||||
inline int getChildIndex(double x, double y, double z, const gp_XYZ& boxMiddle)const;
|
||||
|
||||
protected:
|
||||
// Constructor for children (has to be implemented in inherited classes)
|
||||
virtual SMESH_Octree* allocateOctreeChild() = 0;
|
||||
// Return box of the whole tree
|
||||
virtual Bnd_B3d* buildRootBox() = 0;
|
||||
|
||||
// Build the 8 children boxes
|
||||
void buildChildren();
|
||||
// Constructor for children
|
||||
virtual SMESH_Octree* allocateOctreeChild() const = 0;
|
||||
|
||||
// Build the data in the 8 children (has to be implemented in inherited classes)
|
||||
virtual void buildChildrenData() = 0;
|
||||
// Build the data in the 8 children
|
||||
virtual void buildChildrenData() = 0;
|
||||
|
||||
// members
|
||||
|
||||
// Box of the Octree
|
||||
Bnd_B3d* myBox;
|
||||
|
||||
// Array of 8 Octree children
|
||||
SMESH_Octree** myChildren;
|
||||
|
||||
// Point the father, set to NULL for the level 0
|
||||
SMESH_Octree* myFather;
|
||||
|
||||
// Tell us if the Octree is a leaf or not
|
||||
bool myIsLeaf;
|
||||
|
||||
// Tree limit
|
||||
const Limit* myLimit;
|
||||
|
||||
private:
|
||||
// Build the 8 children boxes recursively
|
||||
void buildChildren();
|
||||
|
||||
// Level of the Octree
|
||||
int myLevel;
|
||||
|
||||
// MaxLevel of the Octree
|
||||
int myMaxLevel;
|
||||
|
||||
// Minimal size of the Box
|
||||
double myMinBoxSize;
|
||||
|
||||
// Tell us if the Octree is a leaf or not (-1 if not initialized)
|
||||
int myIsLeaf;
|
||||
Bnd_B3d* myBox;
|
||||
};
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Return index of a child the given point is in
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
inline int SMESH_Octree::getChildIndex(double x, double y, double z, const gp_XYZ& mid) const
|
||||
{
|
||||
return (x > mid.X()) + ( y > mid.Y())*2 + (z > mid.Z())*4;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -46,18 +46,22 @@ using namespace std;
|
||||
//================================================================
|
||||
SMESH_OctreeNode::SMESH_OctreeNode (const set<const SMDS_MeshNode*> & theNodes, const int maxLevel,
|
||||
const int maxNbNodes , const double minBoxSize )
|
||||
:SMESH_Octree(maxLevel,minBoxSize),
|
||||
:SMESH_Octree( new SMESH_Octree::Limit( maxLevel,minBoxSize)),
|
||||
myMaxNbNodes(maxNbNodes),
|
||||
myNodes(theNodes)
|
||||
{
|
||||
// We need to compute the first bounding box via a special method
|
||||
computeBoxForFather();
|
||||
myNbNodes = myNodes.size();
|
||||
myIsLeaf = ((myLevel == myMaxLevel) ||
|
||||
(myNbNodes <= myMaxNbNodes) ||
|
||||
(maxSize(myBox) <= myMinBoxSize));
|
||||
// All the children (Boxes and Data) are computed in Compute()
|
||||
Compute();
|
||||
compute();
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Constructor used to allocate a child
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
SMESH_OctreeNode::SMESH_OctreeNode (int maxNbNodes):
|
||||
SMESH_Octree(), myMaxNbNodes(maxNbNodes)
|
||||
{
|
||||
}
|
||||
|
||||
//==================================================================================
|
||||
@ -65,16 +69,10 @@ SMESH_OctreeNode::SMESH_OctreeNode (const set<const SMDS_MeshNode*> & theNodes,
|
||||
* \brief Construct an empty SMESH_OctreeNode used by SMESH_Octree::buildChildren()
|
||||
*/
|
||||
//==================================================================================
|
||||
SMESH_Octree* SMESH_OctreeNode::allocateOctreeChild()
|
||||
|
||||
SMESH_Octree* SMESH_OctreeNode::allocateOctreeChild() const
|
||||
{
|
||||
SMESH_OctreeNode * theOctree = new SMESH_OctreeNode();
|
||||
theOctree->myFather = this;
|
||||
theOctree->myLevel = myLevel + 1;
|
||||
theOctree->myMaxLevel = myMaxLevel;
|
||||
theOctree->myMaxNbNodes = myMaxNbNodes;
|
||||
theOctree->myMinBoxSize = myMinBoxSize;
|
||||
theOctree->myNbNodes = 0;
|
||||
return theOctree;
|
||||
return new SMESH_OctreeNode(myMaxNbNodes);
|
||||
}
|
||||
|
||||
//======================================
|
||||
@ -84,25 +82,20 @@ SMESH_Octree* SMESH_OctreeNode::allocateOctreeChild()
|
||||
* We take the max/min coord of the nodes
|
||||
*/
|
||||
//======================================
|
||||
void SMESH_OctreeNode::computeBoxForFather()
|
||||
|
||||
Bnd_B3d* SMESH_OctreeNode::buildRootBox()
|
||||
{
|
||||
Bnd_B3d* box = new Bnd_B3d;
|
||||
set<const SMDS_MeshNode*>::iterator it = myNodes.begin();
|
||||
for (; it != myNodes.end(); it++) {
|
||||
const SMDS_MeshNode* n1 = *it;
|
||||
gp_XYZ p1( n1->X(), n1->Y(), n1->Z() );
|
||||
myBox->Add(p1);
|
||||
box->Add(p1);
|
||||
}
|
||||
}
|
||||
if ( myNodes.size() <= myMaxNbNodes )
|
||||
myIsLeaf = true;
|
||||
|
||||
//====================================================================================
|
||||
/*!
|
||||
* \brief Tell if Octree is a leaf or not (has to be implemented in inherited classes)
|
||||
* \retval - True if the Octree is a leaf
|
||||
*/
|
||||
//====================================================================================
|
||||
const bool SMESH_OctreeNode::isLeaf()
|
||||
{
|
||||
return myIsLeaf;
|
||||
return box;
|
||||
}
|
||||
|
||||
//====================================================================================
|
||||
@ -113,19 +106,15 @@ const bool SMESH_OctreeNode::isLeaf()
|
||||
* \retval bool - True if Node is in the box within precision
|
||||
*/
|
||||
//====================================================================================
|
||||
|
||||
const bool SMESH_OctreeNode::isInside (const SMDS_MeshNode * Node, const double precision)
|
||||
{
|
||||
double X = Node->X();
|
||||
double Y = Node->Y();
|
||||
double Z = Node->Z();
|
||||
bool Out = 1 ;
|
||||
gp_XYZ p (Node->X(),Node->Y(),Node->Z());
|
||||
if (precision <= 0.)
|
||||
return !(myBox->IsOut(gp_XYZ(X,Y,Z)));
|
||||
Bnd_B3d BoxWithPrecision;
|
||||
getBox(BoxWithPrecision);
|
||||
return !(getBox().IsOut(p));
|
||||
Bnd_B3d BoxWithPrecision = getBox();
|
||||
BoxWithPrecision.Enlarge(precision);
|
||||
Out = BoxWithPrecision.IsOut(gp_XYZ(X,Y,Z));
|
||||
return !(Out);
|
||||
return ! BoxWithPrecision.IsOut(p);
|
||||
}
|
||||
|
||||
//================================================
|
||||
@ -136,16 +125,15 @@ const bool SMESH_OctreeNode::isInside (const SMDS_MeshNode * Node, const double
|
||||
//================================================
|
||||
void SMESH_OctreeNode::buildChildrenData()
|
||||
{
|
||||
gp_XYZ min = myBox->CornerMin();
|
||||
gp_XYZ max = myBox->CornerMax();
|
||||
gp_XYZ min = getBox().CornerMin();
|
||||
gp_XYZ max = getBox().CornerMax();
|
||||
gp_XYZ mid = (min + max)/2.;
|
||||
|
||||
set<const SMDS_MeshNode*>::iterator it = myNodes.begin();
|
||||
int ChildBoxNum;
|
||||
while (it != myNodes.end())
|
||||
{
|
||||
const SMDS_MeshNode* n1 = *it;
|
||||
ChildBoxNum = (n1->X() > mid.X()) + (n1->Y() > mid.Y())*2 + (n1->Z() > mid.Z())*4;
|
||||
int ChildBoxNum = getChildIndex( n1->X(), n1->Y(), n1->Z(), mid );
|
||||
SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[ChildBoxNum]);
|
||||
myChild->myNodes.insert(myChild->myNodes.end(),n1);
|
||||
myNodes.erase( it );
|
||||
@ -154,10 +142,8 @@ void SMESH_OctreeNode::buildChildrenData()
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[i]);
|
||||
myChild->myNbNodes = (myChild->myNodes).size();
|
||||
myChild->myIsLeaf = ((myChild->myLevel == myMaxLevel) ||
|
||||
(myChild->myNbNodes <= myMaxNbNodes) ||
|
||||
(maxSize(myChild->myBox) <= myMinBoxSize));
|
||||
if ( myChild->myNodes.size() <= myMaxNbNodes )
|
||||
myChild->myIsLeaf = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,7 +161,7 @@ void SMESH_OctreeNode::NodesAround (const SMDS_MeshNode * Node,
|
||||
{
|
||||
if (isInside(Node,precision))
|
||||
{
|
||||
if (myIsLeaf)
|
||||
if (isLeaf())
|
||||
{
|
||||
Result->insert(Result->end(), myNodes.begin(), myNodes.end());
|
||||
}
|
||||
@ -190,6 +176,61 @@ void SMESH_OctreeNode::NodesAround (const SMDS_MeshNode * Node,
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Return in dist2Nodes nodes mapped to their square distance from Node
|
||||
* \param node - node to find nodes closest to
|
||||
* \param dist2Nodes - map of found nodes and their distances
|
||||
* \param precision - radius of a sphere to check nodes inside
|
||||
* \retval bool - true if an exact overlapping found
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
bool SMESH_OctreeNode::NodesAround(const SMDS_MeshNode * node,
|
||||
map<double, const SMDS_MeshNode*>& dist2Nodes,
|
||||
double precision)
|
||||
{
|
||||
if ( !dist2Nodes.empty() )
|
||||
precision = min ( precision, sqrt( dist2Nodes.begin()->first ));
|
||||
else if ( precision == 0. )
|
||||
precision = maxSize() / 2;
|
||||
|
||||
if (isInside(node,precision))
|
||||
{
|
||||
if (!isLeaf())
|
||||
{
|
||||
// first check a child containing node
|
||||
gp_XYZ mid = (getBox().CornerMin() + getBox().CornerMax()) / 2.;
|
||||
int nodeChild = getChildIndex( node->X(), node->Y(), node->Z(), mid );
|
||||
if ( ((SMESH_OctreeNode*) myChildren[nodeChild])->NodesAround(node, dist2Nodes, precision))
|
||||
return true;
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
if ( i != nodeChild )
|
||||
if (((SMESH_OctreeNode*) myChildren[i])->NodesAround(node, dist2Nodes, precision))
|
||||
return true;
|
||||
}
|
||||
else if ( NbNodes() > 0 )
|
||||
{
|
||||
double minDist = precision * precision;
|
||||
gp_Pnt p1 ( node->X(), node->Y(), node->Z() );
|
||||
set<const SMDS_MeshNode*>::iterator nIt = myNodes.begin();
|
||||
for ( ; nIt != myNodes.end(); ++nIt )
|
||||
{
|
||||
gp_Pnt p2 ( (*nIt)->X(), (*nIt)->Y(), (*nIt)->Z() );
|
||||
double dist2 = p1.SquareDistance( p2 );
|
||||
if ( dist2 < minDist )
|
||||
dist2Nodes.insert( make_pair( minDist = dist2, *nIt ));
|
||||
}
|
||||
// if ( dist2Nodes.size() > 1 ) // leave only closest node in dist2Nodes
|
||||
// dist2Nodes.erase( ++dist2Nodes.begin(), dist2Nodes.end());
|
||||
|
||||
return ( sqrt( minDist) <= precision * 1e-12 );
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//=============================
|
||||
/*!
|
||||
* \brief Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance
|
||||
@ -202,15 +243,14 @@ void SMESH_OctreeNode::NodesAround (const SMDS_MeshNode * Node,
|
||||
* \param maxNbNodes - maximum Nodes in a Leaf of the SMESH_OctreeNode constructed, default value is 5
|
||||
*/
|
||||
//=============================
|
||||
void SMESH_OctreeNode::FindCoincidentNodes (set<const SMDS_MeshNode*> theSetOfNodes,
|
||||
void SMESH_OctreeNode::FindCoincidentNodes (set<const SMDS_MeshNode*>& theSetOfNodes,
|
||||
list< list< const SMDS_MeshNode*> >* theGroupsOfNodes,
|
||||
const double theTolerance,
|
||||
const int maxLevel,
|
||||
const int maxNbNodes)
|
||||
{
|
||||
SMESH_OctreeNode* theOctreeNode = new SMESH_OctreeNode(theSetOfNodes, maxLevel, maxNbNodes, theTolerance);
|
||||
theOctreeNode->FindCoincidentNodes (&theSetOfNodes, theTolerance, theGroupsOfNodes);
|
||||
delete theOctreeNode;
|
||||
SMESH_OctreeNode theOctreeNode(theSetOfNodes, maxLevel, maxNbNodes, theTolerance);
|
||||
theOctreeNode.FindCoincidentNodes (&theSetOfNodes, theTolerance, theGroupsOfNodes);
|
||||
}
|
||||
|
||||
//=============================
|
||||
@ -285,7 +325,7 @@ void SMESH_OctreeNode::FindCoincidentNodes (const SMDS_MeshNode * Node,
|
||||
if (isInsideBool)
|
||||
{
|
||||
// I'm only looking in the leaves, since all the nodes are stored there.
|
||||
if (myIsLeaf)
|
||||
if (isLeaf())
|
||||
{
|
||||
gp_Pnt p1 (Node->X(), Node->Y(), Node->Z());
|
||||
|
||||
@ -333,6 +373,43 @@ void SMESH_OctreeNode::FindCoincidentNodes (const SMDS_MeshNode * Node,
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Update data according to node movement
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
void SMESH_OctreeNode::UpdateByMoveNode( const SMDS_MeshNode* node, const gp_Pnt& toPnt )
|
||||
{
|
||||
if ( isLeaf() )
|
||||
{
|
||||
set<const SMDS_MeshNode*>::iterator pNode = myNodes.find( node );
|
||||
bool nodeInMe = ( pNode != myNodes.end() );
|
||||
|
||||
SMDS_MeshNode pointNode( toPnt.X(), toPnt.Y(), toPnt.Z() );
|
||||
bool pointInMe = isInside( &pointNode, 1e-10 );
|
||||
|
||||
if ( pointInMe != nodeInMe )
|
||||
{
|
||||
if ( pointInMe )
|
||||
myNodes.insert( node );
|
||||
else
|
||||
myNodes.erase( node );
|
||||
}
|
||||
}
|
||||
else if ( myChildren )
|
||||
{
|
||||
gp_XYZ mid = (getBox().CornerMin() + getBox().CornerMax()) / 2.;
|
||||
int nodeChild = getChildIndex( node->X(), node->Y(), node->Z(), mid );
|
||||
int pointChild = getChildIndex( toPnt.X(), toPnt.Y(), toPnt.Z(), mid );
|
||||
if ( nodeChild != pointChild )
|
||||
{
|
||||
((SMESH_OctreeNode*) myChildren[ nodeChild ])->UpdateByMoveNode( node, toPnt );
|
||||
((SMESH_OctreeNode*) myChildren[ pointChild ])->UpdateByMoveNode( node, toPnt );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Return iterator over children
|
||||
@ -342,7 +419,7 @@ SMESH_OctreeNodeIteratorPtr SMESH_OctreeNode::GetChildrenIterator()
|
||||
{
|
||||
return SMESH_OctreeNodeIteratorPtr
|
||||
( new SMDS_SetIterator< SMESH_OctreeNode*, SMESH_Octree** >
|
||||
( myChildren, ( isLeaf() ? myChildren : &myChildren[ 8 ] )));
|
||||
( myChildren, (( isLeaf() || !myChildren ) ? myChildren : &myChildren[ 8 ] )));
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
@ -354,5 +431,5 @@ SMDS_NodeIteratorPtr SMESH_OctreeNode::GetNodeIterator()
|
||||
{
|
||||
return SMDS_NodeIteratorPtr
|
||||
( new SMDS_SetIterator< SMDS_pNode, set< SMDS_pNode >::const_iterator >
|
||||
( myNodes.begin(), myNodes.end() ));
|
||||
( myNodes.begin(), myNodes.size() ? myNodes.end() : myNodes.begin()));
|
||||
}
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
#include "SMDS_ElemIterator.hxx"
|
||||
|
||||
@ -44,7 +45,7 @@ class SMESH_OctreeNode;
|
||||
typedef SMDS_Iterator<SMESH_OctreeNode*> SMESH_OctreeNodeIterator;
|
||||
typedef boost::shared_ptr<SMESH_OctreeNodeIterator> SMESH_OctreeNodeIteratorPtr;
|
||||
|
||||
class SMESH_OctreeNode : public SMESH_Octree{
|
||||
class SMESH_OctreeNode : public SMESH_Octree {
|
||||
|
||||
public:
|
||||
|
||||
@ -59,9 +60,6 @@ public:
|
||||
//=============================
|
||||
virtual ~SMESH_OctreeNode () {};
|
||||
|
||||
// Tells us if SMESH_OctreeNode is a leaf or not (-1 = not initialiazed)
|
||||
virtual const bool isLeaf();
|
||||
|
||||
// Tells us if Node is inside the current box with the precision "precision"
|
||||
virtual const bool isInside(const SMDS_MeshNode * Node, const double precision = 0.);
|
||||
|
||||
@ -70,6 +68,11 @@ public:
|
||||
std::list<const SMDS_MeshNode*>* Result,
|
||||
const double precision = 0.);
|
||||
|
||||
// Return in dist2Nodes nodes mapped to their square distance from Node
|
||||
bool NodesAround(const SMDS_MeshNode * Node,
|
||||
std::map<double, const SMDS_MeshNode*>& dist2Nodes,
|
||||
double precision);
|
||||
|
||||
// Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance
|
||||
// Search for all the nodes in nodes
|
||||
void FindCoincidentNodes ( std::set<const SMDS_MeshNode*>* nodes,
|
||||
@ -78,10 +81,15 @@ public:
|
||||
|
||||
// Static method that return in theGroupsOfNodes a list of group of nodes close to each other within
|
||||
// theTolerance search for all the nodes in nodes
|
||||
static void FindCoincidentNodes ( std::set<const SMDS_MeshNode*> nodes,
|
||||
static void FindCoincidentNodes ( std::set<const SMDS_MeshNode*>& nodes,
|
||||
std::list< std::list< const SMDS_MeshNode*> >* theGroupsOfNodes,
|
||||
const double theTolerance = 0.00001, const int maxLevel = -1,
|
||||
const double theTolerance = 0.00001,
|
||||
const int maxLevel = -1,
|
||||
const int maxNbNodes = 5);
|
||||
/*!
|
||||
* \brief Update data according to node movement
|
||||
*/
|
||||
void UpdateByMoveNode( const SMDS_MeshNode* node, const gp_Pnt& toPnt );
|
||||
/*!
|
||||
* \brief Return iterator over children
|
||||
*/
|
||||
@ -93,25 +101,20 @@ public:
|
||||
/*!
|
||||
* \brief Return nb nodes in a tree
|
||||
*/
|
||||
int NbNodes() const { return myNbNodes; }
|
||||
int NbNodes() const { return myNodes.size(); }
|
||||
|
||||
protected:
|
||||
|
||||
//=============================
|
||||
/*!
|
||||
* \brief Empty constructor
|
||||
*/
|
||||
//=============================
|
||||
SMESH_OctreeNode (){};
|
||||
SMESH_OctreeNode (int maxNbNodes );
|
||||
|
||||
// Compute the bounding box of the whole set of nodes myNodes
|
||||
virtual Bnd_B3d* buildRootBox();
|
||||
|
||||
// Shares the father's data with each of his child
|
||||
virtual void buildChildrenData();
|
||||
|
||||
// Compute the bounding box of the whole set of nodes myNodes (only used for OctreeNode level 0)
|
||||
void computeBoxForFather();
|
||||
|
||||
// Construct an empty SMESH_OctreeNode used by SMESH_Octree::buildChildren()
|
||||
virtual SMESH_Octree* allocateOctreeChild();
|
||||
virtual SMESH_Octree* allocateOctreeChild() const;
|
||||
|
||||
// Return in result a list of nodes closed to Node and remove it from SetOfNodes
|
||||
void FindCoincidentNodes( const SMDS_MeshNode * Node,
|
||||
@ -120,13 +123,11 @@ protected:
|
||||
const double precision);
|
||||
|
||||
// The max number of nodes a leaf box can contain
|
||||
int myMaxNbNodes;
|
||||
int myMaxNbNodes;
|
||||
|
||||
// The set of nodes inside the box of the Octree (Empty if Octree is not a leaf)
|
||||
std::set<const SMDS_MeshNode*> myNodes;
|
||||
|
||||
// The number of nodes I have inside the box
|
||||
int myNbNodes;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user