mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-25 09:20: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
|
* Constructor. limit must be provided at tree root construction.
|
||||||
* \param maxLevel - The level max the octree can reach (If <0 unlimited)
|
* limit will be deleted by SMESH_Octree.
|
||||||
*/
|
*/
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
SMESH_Octree::SMESH_Octree (const int maxLevel, const double minBoxSize):
|
|
||||||
myChildren(NULL),
|
SMESH_Octree::SMESH_Octree (SMESH_Octree::Limit* limit):
|
||||||
myFather(NULL),
|
myChildren(NULL),
|
||||||
myLevel(0),
|
myFather(NULL),
|
||||||
myMaxLevel(maxLevel),
|
myIsLeaf( false ),
|
||||||
myMinBoxSize(minBoxSize),
|
myLimit( limit ),
|
||||||
myIsLeaf(-1)
|
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
|
* \brief SMESH_Octree Destructor
|
||||||
*/
|
*/
|
||||||
//======================================
|
//======================================
|
||||||
|
|
||||||
SMESH_Octree::~SMESH_Octree ()
|
SMESH_Octree::~SMESH_Octree ()
|
||||||
{
|
{
|
||||||
if(myChildren != NULL)
|
if(myChildren != NULL)
|
||||||
{
|
{
|
||||||
if(!myIsLeaf)
|
if(!isLeaf())
|
||||||
{
|
{
|
||||||
for(int i = 0; i<8; i++)
|
for(int i = 0; i<8; i++)
|
||||||
delete myChildren[i];
|
delete myChildren[i];
|
||||||
delete[] myChildren;
|
delete[] myChildren;
|
||||||
|
myChildren = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete myBox;
|
if ( myBox )
|
||||||
}
|
delete myBox;
|
||||||
|
myBox = 0;
|
||||||
//===========================================================================
|
if ( level() == 0 )
|
||||||
/*!
|
delete myLimit;
|
||||||
* \brief Set the bounding box of the Octree
|
myLimit = 0;
|
||||||
* \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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=================================================================
|
//=================================================================
|
||||||
@ -136,8 +94,11 @@ void SMESH_Octree::Compute()
|
|||||||
* \brief Build the 8 children boxes and call buildChildrenData()
|
* \brief Build the 8 children boxes and call buildChildrenData()
|
||||||
*/
|
*/
|
||||||
//=================================================================
|
//=================================================================
|
||||||
|
|
||||||
void SMESH_Octree::buildChildren()
|
void SMESH_Octree::buildChildren()
|
||||||
{
|
{
|
||||||
|
if ( isLeaf() ) return;
|
||||||
|
|
||||||
myChildren = new SMESH_Octree*[8];
|
myChildren = new SMESH_Octree*[8];
|
||||||
|
|
||||||
gp_XYZ min = myBox->CornerMin();
|
gp_XYZ min = myBox->CornerMin();
|
||||||
@ -147,7 +108,6 @@ void SMESH_Octree::buildChildren()
|
|||||||
gp_XYZ childHsize = HSize/2.;
|
gp_XYZ childHsize = HSize/2.;
|
||||||
|
|
||||||
Standard_Real XminChild, YminChild, ZminChild;
|
Standard_Real XminChild, YminChild, ZminChild;
|
||||||
Bnd_B3d* box;
|
|
||||||
gp_XYZ minChild;
|
gp_XYZ minChild;
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
@ -166,19 +126,53 @@ void SMESH_Octree::buildChildren()
|
|||||||
ZminChild = (i<4)?min.Z():mid.Z();
|
ZminChild = (i<4)?min.Z():mid.Z();
|
||||||
minChild.SetCoord(XminChild, YminChild, ZminChild);
|
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)
|
// The child is of the same type than its father (For instance, a SMESH_OctreeNode)
|
||||||
// We allocate the memory we need for the child
|
// We allocate the memory we need for the child
|
||||||
myChildren[i] = allocateOctreeChild();
|
myChildren[i] = allocateOctreeChild();
|
||||||
// and we assign to him its box.
|
// and we assign to him its box.
|
||||||
myChildren[i]->setBox(box);
|
myChildren[i]->myFather = this;
|
||||||
delete box;
|
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();
|
buildChildrenData();
|
||||||
|
|
||||||
//After we pass to the next level of the Octree
|
//After we pass to the next level of the Octree
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i<8; i++)
|
||||||
myChildren[i]->Compute();
|
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 {
|
class SMESH_Octree {
|
||||||
|
|
||||||
public:
|
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
|
// Destructor
|
||||||
virtual ~SMESH_Octree ();
|
virtual ~SMESH_Octree ();
|
||||||
|
|
||||||
// Tell if Octree is a leaf or not (has to be implemented in inherited classes)
|
// Compute the Octree. Must be called by constructor of inheriting class
|
||||||
virtual const bool isLeaf() = 0;
|
void compute();
|
||||||
|
|
||||||
// Compute the Octree
|
// Tell if Octree is a leaf or not.
|
||||||
void Compute();
|
// An inheriting class can influence it via myIsLeaf protected field
|
||||||
|
bool isLeaf() const;
|
||||||
// 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);
|
|
||||||
|
|
||||||
// Return its level
|
// Return its level
|
||||||
int level() const { return myLevel; }
|
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:
|
protected:
|
||||||
// Constructor for children (has to be implemented in inherited classes)
|
// Return box of the whole tree
|
||||||
virtual SMESH_Octree* allocateOctreeChild() = 0;
|
virtual Bnd_B3d* buildRootBox() = 0;
|
||||||
|
|
||||||
// Build the 8 children boxes
|
// Constructor for children
|
||||||
void buildChildren();
|
virtual SMESH_Octree* allocateOctreeChild() const = 0;
|
||||||
|
|
||||||
// Build the data in the 8 children (has to be implemented in inherited classes)
|
// Build the data in the 8 children
|
||||||
virtual void buildChildrenData() = 0;
|
virtual void buildChildrenData() = 0;
|
||||||
|
|
||||||
// members
|
// members
|
||||||
|
|
||||||
// Box of the Octree
|
|
||||||
Bnd_B3d* myBox;
|
|
||||||
|
|
||||||
// Array of 8 Octree children
|
// Array of 8 Octree children
|
||||||
SMESH_Octree** myChildren;
|
SMESH_Octree** myChildren;
|
||||||
|
|
||||||
// Point the father, set to NULL for the level 0
|
// Point the father, set to NULL for the level 0
|
||||||
SMESH_Octree* myFather;
|
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
|
// Level of the Octree
|
||||||
int myLevel;
|
int myLevel;
|
||||||
|
|
||||||
// MaxLevel of the Octree
|
Bnd_B3d* myBox;
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \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
|
#endif
|
||||||
|
@ -46,18 +46,22 @@ using namespace std;
|
|||||||
//================================================================
|
//================================================================
|
||||||
SMESH_OctreeNode::SMESH_OctreeNode (const set<const SMDS_MeshNode*> & theNodes, const int maxLevel,
|
SMESH_OctreeNode::SMESH_OctreeNode (const set<const SMDS_MeshNode*> & theNodes, const int maxLevel,
|
||||||
const int maxNbNodes , const double minBoxSize )
|
const int maxNbNodes , const double minBoxSize )
|
||||||
:SMESH_Octree(maxLevel,minBoxSize),
|
:SMESH_Octree( new SMESH_Octree::Limit( maxLevel,minBoxSize)),
|
||||||
myMaxNbNodes(maxNbNodes),
|
myMaxNbNodes(maxNbNodes),
|
||||||
myNodes(theNodes)
|
myNodes(theNodes)
|
||||||
{
|
{
|
||||||
// We need to compute the first bounding box via a special method
|
compute();
|
||||||
computeBoxForFather();
|
}
|
||||||
myNbNodes = myNodes.size();
|
|
||||||
myIsLeaf = ((myLevel == myMaxLevel) ||
|
//================================================================================
|
||||||
(myNbNodes <= myMaxNbNodes) ||
|
/*!
|
||||||
(maxSize(myBox) <= myMinBoxSize));
|
* \brief Constructor used to allocate a child
|
||||||
// All the children (Boxes and Data) are computed in Compute()
|
*/
|
||||||
Compute();
|
//================================================================================
|
||||||
|
|
||||||
|
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()
|
* \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();
|
return new SMESH_OctreeNode(myMaxNbNodes);
|
||||||
theOctree->myFather = this;
|
|
||||||
theOctree->myLevel = myLevel + 1;
|
|
||||||
theOctree->myMaxLevel = myMaxLevel;
|
|
||||||
theOctree->myMaxNbNodes = myMaxNbNodes;
|
|
||||||
theOctree->myMinBoxSize = myMinBoxSize;
|
|
||||||
theOctree->myNbNodes = 0;
|
|
||||||
return theOctree;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//======================================
|
//======================================
|
||||||
@ -84,25 +82,20 @@ SMESH_Octree* SMESH_OctreeNode::allocateOctreeChild()
|
|||||||
* We take the max/min coord of the nodes
|
* 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();
|
set<const SMDS_MeshNode*>::iterator it = myNodes.begin();
|
||||||
for (; it != myNodes.end(); it++) {
|
for (; it != myNodes.end(); it++) {
|
||||||
const SMDS_MeshNode* n1 = *it;
|
const SMDS_MeshNode* n1 = *it;
|
||||||
gp_XYZ p1( n1->X(), n1->Y(), n1->Z() );
|
gp_XYZ p1( n1->X(), n1->Y(), n1->Z() );
|
||||||
myBox->Add(p1);
|
box->Add(p1);
|
||||||
}
|
}
|
||||||
}
|
if ( myNodes.size() <= myMaxNbNodes )
|
||||||
|
myIsLeaf = true;
|
||||||
|
|
||||||
//====================================================================================
|
return box;
|
||||||
/*!
|
|
||||||
* \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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//====================================================================================
|
//====================================================================================
|
||||||
@ -113,19 +106,15 @@ const bool SMESH_OctreeNode::isLeaf()
|
|||||||
* \retval bool - True if Node is in the box within precision
|
* \retval bool - True if Node is in the box within precision
|
||||||
*/
|
*/
|
||||||
//====================================================================================
|
//====================================================================================
|
||||||
|
|
||||||
const bool SMESH_OctreeNode::isInside (const SMDS_MeshNode * Node, const double precision)
|
const bool SMESH_OctreeNode::isInside (const SMDS_MeshNode * Node, const double precision)
|
||||||
{
|
{
|
||||||
double X = Node->X();
|
gp_XYZ p (Node->X(),Node->Y(),Node->Z());
|
||||||
double Y = Node->Y();
|
|
||||||
double Z = Node->Z();
|
|
||||||
bool Out = 1 ;
|
|
||||||
if (precision <= 0.)
|
if (precision <= 0.)
|
||||||
return !(myBox->IsOut(gp_XYZ(X,Y,Z)));
|
return !(getBox().IsOut(p));
|
||||||
Bnd_B3d BoxWithPrecision;
|
Bnd_B3d BoxWithPrecision = getBox();
|
||||||
getBox(BoxWithPrecision);
|
|
||||||
BoxWithPrecision.Enlarge(precision);
|
BoxWithPrecision.Enlarge(precision);
|
||||||
Out = BoxWithPrecision.IsOut(gp_XYZ(X,Y,Z));
|
return ! BoxWithPrecision.IsOut(p);
|
||||||
return !(Out);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//================================================
|
//================================================
|
||||||
@ -136,16 +125,15 @@ const bool SMESH_OctreeNode::isInside (const SMDS_MeshNode * Node, const double
|
|||||||
//================================================
|
//================================================
|
||||||
void SMESH_OctreeNode::buildChildrenData()
|
void SMESH_OctreeNode::buildChildrenData()
|
||||||
{
|
{
|
||||||
gp_XYZ min = myBox->CornerMin();
|
gp_XYZ min = getBox().CornerMin();
|
||||||
gp_XYZ max = myBox->CornerMax();
|
gp_XYZ max = getBox().CornerMax();
|
||||||
gp_XYZ mid = (min + max)/2.;
|
gp_XYZ mid = (min + max)/2.;
|
||||||
|
|
||||||
set<const SMDS_MeshNode*>::iterator it = myNodes.begin();
|
set<const SMDS_MeshNode*>::iterator it = myNodes.begin();
|
||||||
int ChildBoxNum;
|
|
||||||
while (it != myNodes.end())
|
while (it != myNodes.end())
|
||||||
{
|
{
|
||||||
const SMDS_MeshNode* n1 = *it;
|
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]);
|
SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[ChildBoxNum]);
|
||||||
myChild->myNodes.insert(myChild->myNodes.end(),n1);
|
myChild->myNodes.insert(myChild->myNodes.end(),n1);
|
||||||
myNodes.erase( it );
|
myNodes.erase( it );
|
||||||
@ -154,10 +142,8 @@ void SMESH_OctreeNode::buildChildrenData()
|
|||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[i]);
|
SMESH_OctreeNode* myChild = dynamic_cast<SMESH_OctreeNode*> (myChildren[i]);
|
||||||
myChild->myNbNodes = (myChild->myNodes).size();
|
if ( myChild->myNodes.size() <= myMaxNbNodes )
|
||||||
myChild->myIsLeaf = ((myChild->myLevel == myMaxLevel) ||
|
myChild->myIsLeaf = true;
|
||||||
(myChild->myNbNodes <= myMaxNbNodes) ||
|
|
||||||
(maxSize(myChild->myBox) <= myMinBoxSize));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +161,7 @@ void SMESH_OctreeNode::NodesAround (const SMDS_MeshNode * Node,
|
|||||||
{
|
{
|
||||||
if (isInside(Node,precision))
|
if (isInside(Node,precision))
|
||||||
{
|
{
|
||||||
if (myIsLeaf)
|
if (isLeaf())
|
||||||
{
|
{
|
||||||
Result->insert(Result->end(), myNodes.begin(), myNodes.end());
|
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
|
* \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
|
* \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,
|
list< list< const SMDS_MeshNode*> >* theGroupsOfNodes,
|
||||||
const double theTolerance,
|
const double theTolerance,
|
||||||
const int maxLevel,
|
const int maxLevel,
|
||||||
const int maxNbNodes)
|
const int maxNbNodes)
|
||||||
{
|
{
|
||||||
SMESH_OctreeNode* theOctreeNode = new SMESH_OctreeNode(theSetOfNodes, maxLevel, maxNbNodes, theTolerance);
|
SMESH_OctreeNode theOctreeNode(theSetOfNodes, maxLevel, maxNbNodes, theTolerance);
|
||||||
theOctreeNode->FindCoincidentNodes (&theSetOfNodes, theTolerance, theGroupsOfNodes);
|
theOctreeNode.FindCoincidentNodes (&theSetOfNodes, theTolerance, theGroupsOfNodes);
|
||||||
delete theOctreeNode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================
|
//=============================
|
||||||
@ -285,7 +325,7 @@ void SMESH_OctreeNode::FindCoincidentNodes (const SMDS_MeshNode * Node,
|
|||||||
if (isInsideBool)
|
if (isInsideBool)
|
||||||
{
|
{
|
||||||
// I'm only looking in the leaves, since all the nodes are stored there.
|
// 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());
|
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
|
* \brief Return iterator over children
|
||||||
@ -342,7 +419,7 @@ SMESH_OctreeNodeIteratorPtr SMESH_OctreeNode::GetChildrenIterator()
|
|||||||
{
|
{
|
||||||
return SMESH_OctreeNodeIteratorPtr
|
return SMESH_OctreeNodeIteratorPtr
|
||||||
( new SMDS_SetIterator< SMESH_OctreeNode*, SMESH_Octree** >
|
( 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
|
return SMDS_NodeIteratorPtr
|
||||||
( new SMDS_SetIterator< SMDS_pNode, set< SMDS_pNode >::const_iterator >
|
( 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 <list>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "SMDS_ElemIterator.hxx"
|
#include "SMDS_ElemIterator.hxx"
|
||||||
|
|
||||||
@ -44,7 +45,7 @@ class SMESH_OctreeNode;
|
|||||||
typedef SMDS_Iterator<SMESH_OctreeNode*> SMESH_OctreeNodeIterator;
|
typedef SMDS_Iterator<SMESH_OctreeNode*> SMESH_OctreeNodeIterator;
|
||||||
typedef boost::shared_ptr<SMESH_OctreeNodeIterator> SMESH_OctreeNodeIteratorPtr;
|
typedef boost::shared_ptr<SMESH_OctreeNodeIterator> SMESH_OctreeNodeIteratorPtr;
|
||||||
|
|
||||||
class SMESH_OctreeNode : public SMESH_Octree{
|
class SMESH_OctreeNode : public SMESH_Octree {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -59,9 +60,6 @@ public:
|
|||||||
//=============================
|
//=============================
|
||||||
virtual ~SMESH_OctreeNode () {};
|
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"
|
// 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.);
|
virtual const bool isInside(const SMDS_MeshNode * Node, const double precision = 0.);
|
||||||
|
|
||||||
@ -70,6 +68,11 @@ public:
|
|||||||
std::list<const SMDS_MeshNode*>* Result,
|
std::list<const SMDS_MeshNode*>* Result,
|
||||||
const double precision = 0.);
|
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
|
// Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance
|
||||||
// Search for all the nodes in nodes
|
// Search for all the nodes in nodes
|
||||||
void FindCoincidentNodes ( std::set<const SMDS_MeshNode*>* 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
|
// 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
|
// 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,
|
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);
|
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
|
* \brief Return iterator over children
|
||||||
*/
|
*/
|
||||||
@ -93,25 +101,20 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief Return nb nodes in a tree
|
* \brief Return nb nodes in a tree
|
||||||
*/
|
*/
|
||||||
int NbNodes() const { return myNbNodes; }
|
int NbNodes() const { return myNodes.size(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
//=============================
|
SMESH_OctreeNode (int maxNbNodes );
|
||||||
/*!
|
|
||||||
* \brief Empty constructor
|
// Compute the bounding box of the whole set of nodes myNodes
|
||||||
*/
|
virtual Bnd_B3d* buildRootBox();
|
||||||
//=============================
|
|
||||||
SMESH_OctreeNode (){};
|
|
||||||
|
|
||||||
// Shares the father's data with each of his child
|
// Shares the father's data with each of his child
|
||||||
virtual void buildChildrenData();
|
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()
|
// 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
|
// Return in result a list of nodes closed to Node and remove it from SetOfNodes
|
||||||
void FindCoincidentNodes( const SMDS_MeshNode * Node,
|
void FindCoincidentNodes( const SMDS_MeshNode * Node,
|
||||||
@ -120,13 +123,11 @@ protected:
|
|||||||
const double precision);
|
const double precision);
|
||||||
|
|
||||||
// The max number of nodes a leaf box can contain
|
// 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)
|
// The set of nodes inside the box of the Octree (Empty if Octree is not a leaf)
|
||||||
std::set<const SMDS_MeshNode*> myNodes;
|
std::set<const SMDS_MeshNode*> myNodes;
|
||||||
|
|
||||||
// The number of nodes I have inside the box
|
|
||||||
int myNbNodes;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user