From c113b9f92eda39a04caed33d839213a3fefc00af Mon Sep 17 00:00:00 2001 From: jfa Date: Fri, 3 Apr 2009 08:54:51 +0000 Subject: [PATCH] Bug 0020185: EDF SMESH 967 : Anomaly in Merge Nodes. --- src/SMESH/SMESH_Octree.cxx | 27 ++++--- src/SMESH/SMESH_Octree.hxx | 10 ++- src/SMESH/SMESH_OctreeNode.cxx | 140 +++++++++++++++++---------------- src/SMESH/SMESH_OctreeNode.hxx | 19 +++-- 4 files changed, 104 insertions(+), 92 deletions(-) diff --git a/src/SMESH/SMESH_Octree.cxx b/src/SMESH/SMESH_Octree.cxx index 63457088e..4642fa61d 100644 --- a/src/SMESH/SMESH_Octree.cxx +++ b/src/SMESH/SMESH_Octree.cxx @@ -20,11 +20,12 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // SMESH SMESH_Octree : global Octree implementation -// File : SMESH_Octree.cxx -// Created : Tue Jan 16 16:00:00 2007 -// Author : Nicolas Geimer & Aurélien Motteux(OCC) -// Module : SMESH // +// File : SMESH_Octree.cxx +// Created : Tue Jan 16 16:00:00 2007 +// Author : Nicolas Geimer & Aurélien Motteux(OCC) +// Module : SMESH + #include "SMESH_Octree.hxx" //=========================================================================== @@ -57,7 +58,7 @@ SMESH_Octree::~SMESH_Octree () { for(int i = 0; i<8; i++) delete myChildren[i]; - delete[] myChildren ; + delete[] myChildren; } } delete myBox; @@ -148,10 +149,10 @@ void SMESH_Octree::buildChildren() Standard_Real XminChild, YminChild, ZminChild; Bnd_B3d* box; gp_XYZ minChild; - for (int i =0; i<8; i++) + for (int i = 0; i < 8; i++) { - // We build the eight boxes, we need 2 points to do that. - // Min, and Mid + // We build the eight boxes, we need 2 points to do that: + // Min and Mid // In binary, we can write i from 0 to 7 // For instance : // 5 is 101, it corresponds here in coordinates to ZYX @@ -160,14 +161,14 @@ void SMESH_Octree::buildChildren() // Same scheme for X and Z // I need the minChild to build the Bnd_B3d box. - XminChild= (i%2==0)?min.X():mid.X(); - YminChild= ((i%4)/2==0)?min.Y():mid.Y(); - ZminChild= (i<4)?min.Z():mid.Z(); + XminChild = (i%2==0)?min.X():mid.X(); + YminChild = ((i%4)/2==0)?min.Y():mid.Y(); + 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 fot the child + // We allocate the memory we need for the child myChildren[i] = allocateOctreeChild(); // and we assign to him its box. myChildren[i]->setBox(box); @@ -178,6 +179,6 @@ void SMESH_Octree::buildChildren() buildChildrenData(); //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(); } diff --git a/src/SMESH/SMESH_Octree.hxx b/src/SMESH/SMESH_Octree.hxx index 1d40b39e6..f906c2a08 100644 --- a/src/SMESH/SMESH_Octree.hxx +++ b/src/SMESH/SMESH_Octree.hxx @@ -20,11 +20,12 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // SMESH SMESH_Octree : global Octree implementation -// File : SMESH_Octree.hxx -// Created : Tue Jan 16 16:00:00 2007 -// Author : Nicolas Geimer & Aurélien Motteux (OCC) -// Module : SMESH // +// File : SMESH_Octree.hxx +// Created : Tue Jan 16 16:00:00 2007 +// Author : Nicolas Geimer & Aurélien Motteux (OCC) +// Module : SMESH + #ifndef _SMESH_OCTREE_HXX_ #define _SMESH_OCTREE_HXX_ @@ -96,4 +97,5 @@ protected: // Tell us if the Octree is a leaf or not (-1 if not initialized) int myIsLeaf; }; + #endif diff --git a/src/SMESH/SMESH_OctreeNode.cxx b/src/SMESH/SMESH_OctreeNode.cxx index 48e8c5a79..9a74d71bd 100644 --- a/src/SMESH/SMESH_OctreeNode.cxx +++ b/src/SMESH/SMESH_OctreeNode.cxx @@ -21,11 +21,12 @@ // // SMESH SMESH_OctreeNode : Octree with Nodes set // inherites global class SMESH_Octree -// File : SMESH_OctreeNode.cxx -// Created : Tue Jan 16 16:00:00 2007 -// Author : Nicolas Geimer & Aurélien Motteux (OCC) -// Module : SMESH // +// File : SMESH_OctreeNode.cxx +// Created : Tue Jan 16 16:00:00 2007 +// Author : Nicolas Geimer & Aurélien Motteux (OCC) +// Module : SMESH + #include "SMESH_OctreeNode.hxx" #include "SMDS_MeshNode.hxx" @@ -52,7 +53,9 @@ SMESH_OctreeNode::SMESH_OctreeNode (const set & theNodes, // We need to compute the first bounding box via a special method computeBoxForFather(); myNbNodes = myNodes.size(); - myIsLeaf = (myLevel == myMaxLevel)||(myNbNodes<=myMaxNbNodes)||(myMinBoxSize>=maxSize(myBox)); + myIsLeaf = ((myLevel == myMaxLevel) || + (myNbNodes <= myMaxNbNodes) || + (maxSize(myBox) <= myMinBoxSize)); // All the children (Boxes and Data) are computed in Compute() Compute(); } @@ -74,19 +77,17 @@ SMESH_Octree* SMESH_OctreeNode::allocateOctreeChild() return theOctree; } - - //====================================== /*! * \brief Compute the first bounding box * - * We take the max/min coord of the nodes + * We take the max/min coord of the nodes */ //====================================== void SMESH_OctreeNode::computeBoxForFather() { - set::iterator it=myNodes.begin(); - for( ;it!=myNodes.end();it++){ + 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); @@ -112,22 +113,21 @@ 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 ) +const bool SMESH_OctreeNode::isInside (const SMDS_MeshNode * Node, const double precision) { - double X=Node->X(); - double Y=Node->Y(); - double Z=Node->Z(); + double X = Node->X(); + double Y = Node->Y(); + double Z = Node->Z(); bool Out = 1 ; - if (precision<=0.) - return !(myBox->IsOut(gp_XYZ(X,Y,Z))); + if (precision <= 0.) + return !(myBox->IsOut(gp_XYZ(X,Y,Z))); Bnd_B3d BoxWithPrecision; getBox(BoxWithPrecision); BoxWithPrecision.Enlarge(precision); - Out=BoxWithPrecision.IsOut(gp_XYZ(X,Y,Z)); + Out = BoxWithPrecision.IsOut(gp_XYZ(X,Y,Z)); return !(Out); } - //================================================ /*! * \brief Set the data of the children @@ -140,22 +140,24 @@ void SMESH_OctreeNode::buildChildrenData() gp_XYZ max = myBox->CornerMax(); gp_XYZ mid = (min + max)/2.; - set::iterator it=myNodes.begin(); + set::iterator it = myNodes.begin(); int ChildBoxNum; - while( it!=myNodes.end()) + while (it != myNodes.end()) { const SMDS_MeshNode* n1 = *it; - ChildBoxNum= (n1->X()>mid.X()) + (n1->Y()>mid.Y())*2 + (n1->Z()>mid.Z())*4; + ChildBoxNum = (n1->X() > mid.X()) + (n1->Y() > mid.Y())*2 + (n1->Z() > mid.Z())*4; SMESH_OctreeNode* myChild = dynamic_cast (myChildren[ChildBoxNum]); myChild->myNodes.insert(myChild->myNodes.end(),n1); myNodes.erase( it ); - it=myNodes.begin(); + it = myNodes.begin(); } - for (int i = 0; i<8; i++) + 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)||(myMinBoxSize>=maxSize(myChild->myBox)); + myChild->myIsLeaf = ((myChild->myLevel == myMaxLevel) || + (myChild->myNbNodes <= myMaxNbNodes) || + (maxSize(myChild->myBox) <= myMinBoxSize)); } } @@ -167,80 +169,81 @@ void SMESH_OctreeNode::buildChildrenData() * \param Result - list of Nodes potentials to be near Node */ //==================================================================== -void SMESH_OctreeNode::NodesAround( const SMDS_MeshNode * Node, - list* Result, const double precision) +void SMESH_OctreeNode::NodesAround (const SMDS_MeshNode * Node, + list* Result, + const double precision) { if (isInside(Node,precision)) { if (myIsLeaf) { - Result->insert( Result->end(), myNodes.begin(), myNodes.end() ); + Result->insert(Result->end(), myNodes.begin(), myNodes.end()); } else { - for(int i=0;i<8;i++) + for (int i = 0; i < 8; i++) { SMESH_OctreeNode* myChild = dynamic_cast (myChildren[i]); - myChild->NodesAround( Node, Result, precision); + myChild->NodesAround(Node, Result, precision); } } } } - - //============================= /*! * \brief 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 theSetOfNodes * Static Method : no need to create an SMESH_OctreeNode - * \param nodes - set of nodes we look at, modified during research + * \param theSetOfNodes - set of nodes we look at, modified during research * \param theGroupsOfNodes - list of nodes closed to each other returned * \param theTolerance - Precision used, default value is 0.00001 * \param maxLevel - Maximum level for SMESH_OctreeNode constructed, default value is -1 (Infinite) * \param maxNbNodes - maximum Nodes in a Leaf of the SMESH_OctreeNode constructed, default value is 5 */ //============================= -void SMESH_OctreeNode::FindCoincidentNodes ( set nodes, - list< list< const SMDS_MeshNode*> >* theGroupsOfNodes, - const double theTolerance, const int maxLevel, - const int maxNbNodes) +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(nodes, maxLevel, maxNbNodes, theTolerance); - theOctreeNode->FindCoincidentNodes (&nodes, theTolerance, theGroupsOfNodes); + SMESH_OctreeNode* theOctreeNode = new SMESH_OctreeNode(theSetOfNodes, maxLevel, maxNbNodes, theTolerance); + theOctreeNode->FindCoincidentNodes (&theSetOfNodes, theTolerance, theGroupsOfNodes); delete theOctreeNode; } - //============================= /*! * \brief Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance - * Search for all the nodes in nodes - * \param nodes - set of nodes we look at, modified during research + * Search for all the nodes in theSetOfNodes + * \note The Octree itself is also modified by this method + * \param theSetOfNodes - set of nodes we look at, modified during research * \param theTolerance - Precision used * \param theGroupsOfNodes - list of nodes closed to each other returned */ //============================= -void SMESH_OctreeNode::FindCoincidentNodes ( set* nodes, - const double theTolerance, +void SMESH_OctreeNode::FindCoincidentNodes ( set* theSetOfNodes, + const double theTolerance, list< list< const SMDS_MeshNode*> >* theGroupsOfNodes) { - set::iterator it1 = nodes->begin(); + set::iterator it1 = theSetOfNodes->begin(); list::iterator it2; - while (it1 != nodes->end()) + while (it1 != theSetOfNodes->end()) { const SMDS_MeshNode * n1 = *it1; - list ListofCoincidentNodes;// Initialize the lists via a declaration, it's enough + list ListOfCoincidentNodes;// Initialize the lists via a declaration, it's enough list * groupPtr = 0; - // Searching for Nodes around n1 and put them in ListofCoincidentNodes - FindCoincidentNodes(n1, nodes, &ListofCoincidentNodes, theTolerance); + // Searching for Nodes around n1 and put them in ListofCoincidentNodes. + // Found nodes are also erased from theSetOfNodes + FindCoincidentNodes(n1, theSetOfNodes, &ListOfCoincidentNodes, theTolerance); // We build a list {n1 + his neigbours} and add this list in theGroupsOfNodes - for (it2=ListofCoincidentNodes.begin();it2 != ListofCoincidentNodes.end(); it2++) + for (it2 = ListOfCoincidentNodes.begin(); it2 != ListOfCoincidentNodes.end(); it2++) { const SMDS_MeshNode* n2 = *it2; if ( !groupPtr ) @@ -249,29 +252,30 @@ void SMESH_OctreeNode::FindCoincidentNodes ( set* nodes, groupPtr = & theGroupsOfNodes->back(); groupPtr->push_back( n1 ); } - if(groupPtr->front()>n2) + if (groupPtr->front() > n2) groupPtr->push_front( n2 ); else groupPtr->push_back( n2 ); } - if(groupPtr != 0) + if (groupPtr != 0) groupPtr->sort(); - nodes->erase(it1); - it1=nodes->begin(); + theSetOfNodes->erase(it1); + it1 = theSetOfNodes->begin(); } } //====================================================================================== /*! * \brief Return a list of nodes closed to Node and remove it from SetOfNodes + * \note The Octree itself is also modified by this method * \param Node - We're searching the nodes next to him. * \param SetOfNodes - set of nodes in which we erase the found nodes * \param Result - list of nodes closed to Node * \param precision - Precision used */ //====================================================================================== -void SMESH_OctreeNode::FindCoincidentNodes( const SMDS_MeshNode * Node, +void SMESH_OctreeNode::FindCoincidentNodes (const SMDS_MeshNode * Node, set* SetOfNodes, list* Result, const double precision) @@ -283,7 +287,7 @@ void SMESH_OctreeNode::FindCoincidentNodes( const SMDS_MeshNode * Node, // I'm only looking in the leaves, since all the nodes are stored there. if (myIsLeaf) { - gp_Pnt p1( Node->X(), Node->Y(), Node->Z() ); + gp_Pnt p1 (Node->X(), Node->Y(), Node->Z()); set myNodesCopy = myNodes; set::iterator it = myNodesCopy.begin(); @@ -294,32 +298,36 @@ void SMESH_OctreeNode::FindCoincidentNodes( const SMDS_MeshNode * Node, { const SMDS_MeshNode* n2 = *it; // We're only looking at nodes with a superior Id. - if(Node->GetID() < n2->GetID()) + // JFA: Why? + //if (Node->GetID() < n2->GetID()) + if (Node->GetID() != n2->GetID()) // JFA: for bug 0020185 { - gp_Pnt p2( n2->X(), n2->Y(), n2->Z() ); + gp_Pnt p2 (n2->X(), n2->Y(), n2->Z()); // Distance optimized computation squareBool = (p1.SquareDistance( p2 ) <= tol2); - // If n2 inside the SquareDistance, we add it in Result and remove it from SetOfNodes and myNodes - if(squareBool) + // If n2 inside the SquareDistance, we add it in Result and remove it from SetOfNodes and myNodes + if (squareBool) { Result->insert(Result->begin(), n2); SetOfNodes->erase( n2 ); myNodes.erase( n2 ); } } - myNodesCopy.erase( it ); - it = myNodesCopy.begin(); + //myNodesCopy.erase( it ); + //it = myNodesCopy.begin(); + it++; } - + if (Result->size() > 0) + myNodes.erase(Node); // JFA: for bug 0020185 } else { // If I'm not a leaf, I'm going to see my children ! - for(int i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) { SMESH_OctreeNode* myChild = dynamic_cast (myChildren[i]); - myChild->FindCoincidentNodes(Node, SetOfNodes, Result, precision); + myChild->FindCoincidentNodes(Node, SetOfNodes, Result, precision); } } } @@ -330,7 +338,6 @@ void SMESH_OctreeNode::FindCoincidentNodes( const SMDS_MeshNode * Node, * \brief Return iterator over children */ //================================================================================ - SMESH_OctreeNodeIteratorPtr SMESH_OctreeNode::GetChildrenIterator() { return SMESH_OctreeNodeIteratorPtr @@ -343,7 +350,6 @@ SMESH_OctreeNodeIteratorPtr SMESH_OctreeNode::GetChildrenIterator() * \brief Return nodes iterator */ //================================================================================ - SMDS_NodeIteratorPtr SMESH_OctreeNode::GetNodeIterator() { return SMDS_NodeIteratorPtr diff --git a/src/SMESH/SMESH_OctreeNode.hxx b/src/SMESH/SMESH_OctreeNode.hxx index 54ab75cc8..6a3b0cb39 100644 --- a/src/SMESH/SMESH_OctreeNode.hxx +++ b/src/SMESH/SMESH_OctreeNode.hxx @@ -21,11 +21,12 @@ // // SMESH SMESH_OctreeNode : Octree with Nodes set // inherites global class SMESH_Octree -// File : SMESH_OctreeNode.hxx -// Created : Tue Jan 16 16:00:00 2007 -// Author : Nicolas Geimer & Aurélien Motteux (OCC) -// Module : SMESH // +// File : SMESH_OctreeNode.hxx +// Created : Tue Jan 16 16:00:00 2007 +// Author : Nicolas Geimer & Aurélien Motteux (OCC) +// Module : SMESH + #ifndef _SMESH_OCTREENODE_HXX_ #define _SMESH_OCTREENODE_HXX_ @@ -49,7 +50,7 @@ public: // Constructor SMESH_OctreeNode (const std::set& theNodes, const int maxLevel = -1, - const int maxNbNodes = 5 , const double minBoxSize = 0.); + const int maxNbNodes = 5, const double minBoxSize = 0.); //============================= /*! @@ -62,11 +63,12 @@ public: 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. ); + virtual const bool isInside(const SMDS_MeshNode * Node, const double precision = 0.); // Return in Result a list of Nodes potentials to be near Node - void NodesAround( const SMDS_MeshNode * Node , std::list* Result, - const double precision = 0. ); + void NodesAround(const SMDS_MeshNode * Node, + std::list* Result, + const double precision = 0.); // Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance // Search for all the nodes in nodes @@ -126,4 +128,5 @@ protected: // The number of nodes I have inside the box int myNbNodes; }; + #endif -- 2.39.2