From: eap Date: Thu, 10 Sep 2009 05:49:16 +0000 (+0000) Subject: 0020464: EDF 1100 SMESH: Performance issue of the function MoveNode X-Git-Tag: V5_1_3rc1~79 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=75120999666523dff19d30f4456f300b0d6a1857;p=modules%2Fsmesh.git 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 --- diff --git a/src/SMESH/SMESH_Octree.cxx b/src/SMESH/SMESH_Octree.cxx index 4642fa61d..00bdb2669 100644 --- a/src/SMESH/SMESH_Octree.cxx +++ b/src/SMESH/SMESH_Octree.cxx @@ -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) +{ +} + +//================================================================================ +/*! + * \brief Compute the Octree + */ +//================================================================================ + +void SMESH_Octree::compute() { - myBox = new Bnd_B3d(); + 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.; } diff --git a/src/SMESH/SMESH_Octree.hxx b/src/SMESH/SMESH_Octree.hxx index f906c2a08..79a641dd4 100644 --- a/src/SMESH/SMESH_Octree.hxx +++ b/src/SMESH/SMESH_Octree.hxx @@ -34,68 +34,90 @@ class SMESH_Octree { public: - // Constructor - SMESH_Octree (const int maxLevel = -1, const double minBoxSize = 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; + // Data limiting the tree height + struct Limit { + // MaxLevel of the Octree + int myMaxLevel; + // Minimal size of the Box + double myMinBoxSize; - // Compute the Octree - void Compute(); + // 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 + }; - // Set the maximal level of the Octree - void setMaxLevel(const int maxLevel); + // Constructor. limit must be provided at tree root construction. + // limit will be deleted by SMESH_Octree + SMESH_Octree (Limit* limit=0); - // 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); + // Destructor + virtual ~SMESH_Octree (); - // Set box to the 3d Bounding Box of the Octree - void getBox(Bnd_B3d & box); + // Compute the Octree. Must be called by constructor of inheriting class + void compute(); - // 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; + Bnd_B3d* myBox; +}; - // Minimal size of the Box - double myMinBoxSize; +//================================================================================ +/*! + * \brief Return index of a child the given point is in + */ +//================================================================================ - // Tell us if the Octree is a leaf or not (-1 if not initialized) - int myIsLeaf; -}; +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 diff --git a/src/SMESH/SMESH_OctreeNode.cxx b/src/SMESH/SMESH_OctreeNode.cxx index 9a74d71bd..8a230d72e 100644 --- a/src/SMESH/SMESH_OctreeNode.cxx +++ b/src/SMESH/SMESH_OctreeNode.cxx @@ -46,18 +46,22 @@ using namespace std; //================================================================ SMESH_OctreeNode::SMESH_OctreeNode (const set & 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 & 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::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::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 (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 (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& 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::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 theSetOfNodes, +void SMESH_OctreeNode::FindCoincidentNodes (set& 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::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())); } diff --git a/src/SMESH/SMESH_OctreeNode.hxx b/src/SMESH/SMESH_OctreeNode.hxx index 6a3b0cb39..7799765d0 100644 --- a/src/SMESH/SMESH_OctreeNode.hxx +++ b/src/SMESH/SMESH_OctreeNode.hxx @@ -34,6 +34,7 @@ #include #include +#include #include "SMDS_ElemIterator.hxx" @@ -44,7 +45,7 @@ class SMESH_OctreeNode; typedef SMDS_Iterator SMESH_OctreeNodeIterator; typedef boost::shared_ptr 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* Result, const double precision = 0.); + // Return in dist2Nodes nodes mapped to their square distance from Node + bool NodesAround(const SMDS_MeshNode * Node, + std::map& 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* 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 nodes, + static void FindCoincidentNodes ( std::set& 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 myNodes; - // The number of nodes I have inside the box - int myNbNodes; }; #endif