From ef59152514df17c64ad01c8abab01331618a1fc4 Mon Sep 17 00:00:00 2001 From: prascle Date: Sat, 3 Aug 2013 11:11:12 +0000 Subject: [PATCH] PR : merge from V7_2_1p1 memory leaks, bug in import 1D for cracks M src/SMDS/SMDS_UnstructuredGrid.cxx M src/SMESH/SMESH_MeshEditor.cxx M src/SMESH/SMESH_MesherHelper.cxx M src/SMESHUtils/SMESH_MeshAlgos.cxx M src/SMESHUtils/SMESH_MeshAlgos.hxx M src/SMESHUtils/SMESH_Octree.hxx M src/SMESHUtils/SMESH_Tree.hxx M src/SMESH_PY/smeshstudytools.py M src/StdMeshers/StdMeshers_Import_1D.cxx --- src/SMDS/SMDS_UnstructuredGrid.cxx | 2 +- src/SMESH/SMESH_MeshEditor.cxx | 169 +++++++++++++++++++----- src/SMESH/SMESH_MesherHelper.cxx | 4 + src/SMESHUtils/SMESH_MeshAlgos.cxx | 8 +- src/SMESHUtils/SMESH_MeshAlgos.hxx | 1 + src/SMESHUtils/SMESH_Octree.hxx | 1 + src/SMESHUtils/SMESH_Tree.hxx | 2 + src/SMESH_PY/smeshstudytools.py | 7 +- src/StdMeshers/StdMeshers_Import_1D.cxx | 19 ++- 9 files changed, 168 insertions(+), 45 deletions(-) diff --git a/src/SMDS/SMDS_UnstructuredGrid.cxx b/src/SMDS/SMDS_UnstructuredGrid.cxx index 16eb2537e..99d39e4f0 100644 --- a/src/SMDS/SMDS_UnstructuredGrid.cxx +++ b/src/SMDS/SMDS_UnstructuredGrid.cxx @@ -326,7 +326,7 @@ void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes, int start, int end) { - MESSAGE("copyBloc " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start); + //MESSAGE("copyBloc " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start); for (int j = start; j < end; j++) { newTypes->SetValue(alreadyCopied, this->Types->GetValue(j)); diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 49d3e14c7..d817e9018 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -9891,12 +9891,14 @@ namespace { //================================================================================ /*! - \brief Identify the elements that will be affected by node duplication (actual duplication is not performed. + \brief Identify the elements that will be affected by node duplication (actual duplication is not performed). This method is the first step of DoubleNodeElemGroupsInRegion. \param theElems - list of groups of elements (edges or faces) to be replicated \param theNodesNot - list of groups of nodes not to replicated \param theShape - shape to detect affected elements (element which geometric center - located on or inside shape). + located on or inside shape). If the shape is null, detection is done on faces orientations + (select elements with a gravity center on the side given by faces normals). + This mode (null shape) is faster, but works only when theElems are faces, with coherents orientations. The replicated nodes should be associated to affected elements. \return groups of affected elements \sa DoubleNodeElemGroupsInRegion() @@ -9909,44 +9911,145 @@ bool SMESH_MeshEditor::AffectedElemGroupsInRegion( const TIDSortedElemSet& theEl TIDSortedElemSet& theAffectedElems) { if ( theShape.IsNull() ) - return false; - - const double aTol = Precision::Confusion(); - auto_ptr< BRepClass3d_SolidClassifier> bsc3d; - auto_ptr<_FaceClassifier> aFaceClassifier; - if ( theShape.ShapeType() == TopAbs_SOLID ) - { - bsc3d.reset( new BRepClass3d_SolidClassifier(theShape));; - bsc3d->PerformInfinitePoint(aTol); - } - else if (theShape.ShapeType() == TopAbs_FACE ) { - aFaceClassifier.reset( new _FaceClassifier(TopoDS::Face(theShape))); + std::set alreadyCheckedNodes; + std::set alreadyCheckedElems; + std::set edgesToCheck; + alreadyCheckedNodes.clear(); + alreadyCheckedElems.clear(); + edgesToCheck.clear(); + + // --- iterates on elements to be replicated and get elements by back references from their nodes + + TIDSortedElemSet::const_iterator elemItr = theElems.begin(); + int ielem = 1; + for ( ; elemItr != theElems.end(); ++elemItr ) + { + SMDS_MeshElement* anElem = (SMDS_MeshElement*)*elemItr; + if (!anElem || (anElem->GetType() != SMDSAbs_Face)) + continue; + gp_XYZ normal; + SMESH_MeshAlgos::FaceNormal( anElem, normal, /*normalized=*/true ); + MESSAGE("element " << ielem++ << " normal " << normal.X() << " " << normal.Y() << " " << normal.Z()); + std::set nodesElem; + nodesElem.clear(); + SMDS_ElemIteratorPtr nodeItr = anElem->nodesIterator(); + while ( nodeItr->more() ) + { + const SMDS_MeshNode* aNode = cast2Node(nodeItr->next()); + nodesElem.insert(aNode); + } + std::set::iterator nodit = nodesElem.begin(); + for (; nodit != nodesElem.end(); nodit++) + { + MESSAGE(" noeud "); + const SMDS_MeshNode* aNode = *nodit; + if ( !aNode || theNodesNot.find(aNode) != theNodesNot.end() ) + continue; + if (alreadyCheckedNodes.find(aNode) != alreadyCheckedNodes.end()) + continue; + alreadyCheckedNodes.insert(aNode); + SMDS_ElemIteratorPtr backElemItr = aNode->GetInverseElementIterator(); + while ( backElemItr->more() ) + { + MESSAGE(" backelem "); + const SMDS_MeshElement* curElem = backElemItr->next(); + if (alreadyCheckedElems.find(curElem) != alreadyCheckedElems.end()) + continue; + if (theElems.find(curElem) != theElems.end()) + continue; + alreadyCheckedElems.insert(curElem); + double x=0, y=0, z=0; + int nb = 0; + SMDS_ElemIteratorPtr nodeItr2 = curElem->nodesIterator(); + while ( nodeItr2->more() ) + { + const SMDS_MeshNode* anotherNode = cast2Node(nodeItr2->next()); + x += anotherNode->X(); + y += anotherNode->Y(); + z += anotherNode->Z(); + nb++; + } + gp_XYZ p; + p.SetCoord( x/nb -aNode->X(), + y/nb -aNode->Y(), + z/nb -aNode->Z() ); + MESSAGE(" check " << p.X() << " " << p.Y() << " " << p.Z()); + if (normal*p > 0) + { + MESSAGE(" --- inserted") + theAffectedElems.insert( curElem ); + } + else if (curElem->GetType() == SMDSAbs_Edge) + edgesToCheck.insert(curElem); + } + } + } + // --- add also edges lying on the set of faces (all nodes in alreadyCheckedNodes) + std::set::iterator eit = edgesToCheck.begin(); + for( ; eit != edgesToCheck.end(); eit++) + { + bool onside = true; + const SMDS_MeshElement* anEdge = *eit; + SMDS_ElemIteratorPtr nodeItr = anEdge->nodesIterator(); + while ( nodeItr->more() ) + { + const SMDS_MeshNode* aNode = cast2Node(nodeItr->next()); + if (alreadyCheckedNodes.find(aNode) == alreadyCheckedNodes.end()) + { + onside = false; + break; + } + } + if (onside) + { + MESSAGE(" --- edge onside inserted") + theAffectedElems.insert(anEdge); + } + } } - - // iterates on indicated elements and get elements by back references from their nodes - TIDSortedElemSet::const_iterator elemItr = theElems.begin(); - for ( ; elemItr != theElems.end(); ++elemItr ) + else { - SMDS_MeshElement* anElem = (SMDS_MeshElement*)*elemItr; - if (!anElem) - continue; + const double aTol = Precision::Confusion(); + auto_ptr< BRepClass3d_SolidClassifier> bsc3d; + auto_ptr<_FaceClassifier> aFaceClassifier; + if ( theShape.ShapeType() == TopAbs_SOLID ) + { + bsc3d.reset( new BRepClass3d_SolidClassifier(theShape));; + bsc3d->PerformInfinitePoint(aTol); + } + else if (theShape.ShapeType() == TopAbs_FACE ) + { + aFaceClassifier.reset( new _FaceClassifier(TopoDS::Face(theShape))); + } - SMDS_ElemIteratorPtr nodeItr = anElem->nodesIterator(); - while ( nodeItr->more() ) + // iterates on indicated elements and get elements by back references from their nodes + TIDSortedElemSet::const_iterator elemItr = theElems.begin(); + int ielem = 1; + for ( ; elemItr != theElems.end(); ++elemItr ) { - const SMDS_MeshNode* aNode = cast2Node(nodeItr->next()); - if ( !aNode || theNodesNot.find(aNode) != theNodesNot.end() ) + MESSAGE("element " << ielem++); + SMDS_MeshElement* anElem = (SMDS_MeshElement*)*elemItr; + if (!anElem) continue; - SMDS_ElemIteratorPtr backElemItr = aNode->GetInverseElementIterator(); - while ( backElemItr->more() ) + SMDS_ElemIteratorPtr nodeItr = anElem->nodesIterator(); + while ( nodeItr->more() ) { - const SMDS_MeshElement* curElem = backElemItr->next(); - if ( curElem && theElems.find(curElem) == theElems.end() && - ( bsc3d.get() ? - isInside( curElem, *bsc3d, aTol ) : - isInside( curElem, *aFaceClassifier, aTol ))) - theAffectedElems.insert( curElem ); + MESSAGE(" noeud "); + const SMDS_MeshNode* aNode = cast2Node(nodeItr->next()); + if ( !aNode || theNodesNot.find(aNode) != theNodesNot.end() ) + continue; + SMDS_ElemIteratorPtr backElemItr = aNode->GetInverseElementIterator(); + while ( backElemItr->more() ) + { + MESSAGE(" backelem "); + const SMDS_MeshElement* curElem = backElemItr->next(); + if ( curElem && theElems.find(curElem) == theElems.end() && + ( bsc3d.get() ? + isInside( curElem, *bsc3d, aTol ) : + isInside( curElem, *aFaceClassifier, aTol ))) + theAffectedElems.insert( curElem ); + } } } } diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index 316bcea62..48bd275be 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -909,6 +909,7 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E, { double r = Max( 0.5, 1 - tol*n->GetID()); // to get a unique u on edge u = f*r + l*(1-r); + MESSAGE("curve.IsNull: " << u); } } else @@ -944,6 +945,7 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E, } Quantity_Parameter U = projector->LowerDistanceParameter(); u = double( U ); + MESSAGE(" f " << f << " l " << l << " u " << u); curvPnt = curve->Value( u ); dist = nodePnt.Distance( curvPnt ); if ( distXYZ ) { @@ -964,10 +966,12 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E, } else if ( fabs( u ) > numeric_limits::min() ) { + MESSAGE("fabs( u ) > numeric_limits::min() ; u " << u << " f " << f << " l " << l); setPosOnShapeValidity( shapeID, true ); } if (( u < f-tol || u > l+tol ) && force ) { + MESSAGE("u < f-tol || u > l+tol ; u " << u << " f " << f << " l " << l); // node is on vertex but is set on periodic but trimmed edge (issue 0020890) try { diff --git a/src/SMESHUtils/SMESH_MeshAlgos.cxx b/src/SMESHUtils/SMESH_MeshAlgos.cxx index d0d6008d3..45acf33b1 100644 --- a/src/SMESHUtils/SMESH_MeshAlgos.cxx +++ b/src/SMESHUtils/SMESH_MeshAlgos.cxx @@ -210,7 +210,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint() void getElementsInSphere ( const gp_XYZ& center, const double radius, TIDSortedElemSet& foundElems); size_t getSize() { return std::max( _size, _elements.size() ); } - ~ElementBndBoxTree(); + virtual ~ElementBndBoxTree(); protected: ElementBndBoxTree():_size(0) {} @@ -410,6 +410,10 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint() */ //======================================================================= +SMESH_ElementSearcher::~SMESH_ElementSearcher() +{ +} + struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher { SMDS_Mesh* _mesh; @@ -423,7 +427,7 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher SMESH_ElementSearcherImpl( SMDS_Mesh& mesh, SMDS_ElemIteratorPtr elemIt=SMDS_ElemIteratorPtr()) : _mesh(&mesh),_meshPartIt(elemIt),_ebbTree(0),_nodeSearcher(0),_tolerance(-1),_outerFacesFound(false) {} - ~SMESH_ElementSearcherImpl() + virtual ~SMESH_ElementSearcherImpl() { if ( _ebbTree ) delete _ebbTree; _ebbTree = 0; if ( _nodeSearcher ) delete _nodeSearcher; _nodeSearcher = 0; diff --git a/src/SMESHUtils/SMESH_MeshAlgos.hxx b/src/SMESHUtils/SMESH_MeshAlgos.hxx index 42ff8923a..0236f6737 100644 --- a/src/SMESHUtils/SMESH_MeshAlgos.hxx +++ b/src/SMESHUtils/SMESH_MeshAlgos.hxx @@ -87,6 +87,7 @@ struct SMESH_ElementSearcher * \brief Find out if the given point is out of closed 2D mesh. */ virtual TopAbs_State GetPointState(const gp_Pnt& point) = 0; + virtual ~SMESH_ElementSearcher(); }; namespace SMESH_MeshAlgos diff --git a/src/SMESHUtils/SMESH_Octree.hxx b/src/SMESHUtils/SMESH_Octree.hxx index 5fa0e6533..adb74b560 100644 --- a/src/SMESHUtils/SMESH_Octree.hxx +++ b/src/SMESHUtils/SMESH_Octree.hxx @@ -49,6 +49,7 @@ public: // Constructor. limit must be provided at tree root construction. // limit will be deleted by SMESH_Octree SMESH_Octree (SMESH_TreeLimit* limit=0); + virtual ~SMESH_Octree() {}; // Compute the bigger dimension of my box double maxSize() const; diff --git a/src/SMESHUtils/SMESH_Tree.hxx b/src/SMESHUtils/SMESH_Tree.hxx index 61ee057f0..36d412420 100644 --- a/src/SMESHUtils/SMESH_Tree.hxx +++ b/src/SMESHUtils/SMESH_Tree.hxx @@ -219,6 +219,8 @@ void SMESH_Tree::buildChildren() myChildren[i] = newChild(); // and we assign to him its box. myChildren[i]->myFather = this; + if (myChildren[i]->myLimit) + delete myChildren[i]->myLimit; myChildren[i]->myLimit = myLimit; myChildren[i]->myLevel = myLevel + 1; myChildren[i]->myBox = newChildBox( i ); diff --git a/src/SMESH_PY/smeshstudytools.py b/src/SMESH_PY/smeshstudytools.py index 5bf1250b0..7b83e570e 100644 --- a/src/SMESH_PY/smeshstudytools.py +++ b/src/SMESH_PY/smeshstudytools.py @@ -27,10 +27,9 @@ import salome SMESH = None # SMESH module is loaded only when needed from salome.kernel.studyedit import getStudyEditor -try: - from salome.gui import helper -except ImportError: - pass +from salome.kernel.deprecation import is_called_by_sphinx +if not is_called_by_sphinx(): + from salome.gui import helper class SMeshStudyTools: """ diff --git a/src/StdMeshers/StdMeshers_Import_1D.cxx b/src/StdMeshers/StdMeshers_Import_1D.cxx index 03b89eda3..fbbe7198f 100644 --- a/src/StdMeshers/StdMeshers_Import_1D.cxx +++ b/src/StdMeshers/StdMeshers_Import_1D.cxx @@ -621,6 +621,7 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th { if ( !_sourceHyp ) return false; + //MESSAGE("---------> StdMeshers_Import_1D::Compute"); const vector& srcGroups = _sourceHyp->GetGroups(/*loaded=*/true); if ( srcGroups.empty() ) return error("Invalid source groups"); @@ -650,9 +651,11 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th { _gen->Compute(theMesh,v,/*anUpward=*/true); n = SMESH_Algo::VertexNode( v, tgtMesh ); + //MESSAGE("_gen->Compute " << n); if ( !n ) return false; // very strange } vertexNodes.push_back( SMESH_TNodeXYZ( n )); + //MESSAGE("SMESH_Algo::VertexNode " << n->GetID() << " " << n->X() << " " << n->Y() << " " << n->Z() ); } // import edges from groups @@ -670,17 +673,19 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements(); vector newNodes; SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0); - double u = 0; + double u = 0.314159; // "random" value between 0 and 1, avoid 0 and 1, false detection possible on edge restrictions while ( srcElems->more() ) // loop on group contents { const SMDS_MeshElement* edge = srcElems->next(); // find or create nodes of a new edge newNodes.resize( edge->NbNodes() ); + //MESSAGE("edge->NbNodes " << edge->NbNodes()); newNodes.back() = 0; SMDS_MeshElement::iterator node = edge->begin_nodes(); SMESH_TNodeXYZ a(edge->GetNode(0)); // --- define a tolerance relative to the length of an edge double mytol = a.Distance(edge->GetNode(edge->NbNodes()-1))/25; + //mytol = max(1.E-5, 10*edgeTol); // too strict and not necessary //MESSAGE("mytol = " << mytol); for ( unsigned i = 0; i < newNodes.size(); ++i, ++node ) { @@ -697,22 +702,26 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th for ( vNIt = vertexNodes.begin(); vNIt != vertexNodes.end(); ++vNIt) if ( vNIt->SquareDistance( *node ) < checktol) { - //MESSAGE("SquareDistance " << vNIt->SquareDistance( *node ) << " checktol " << checktol); + //MESSAGE("SquareDistance " << vNIt->SquareDistance( *node ) << " checktol " << checktol <<" "<X()<<" "<Y()<<" "<Z()); (*n2nIt).second = vNIt->_node; vertexNodes.erase( vNIt ); break; } + else if ( vNIt->SquareDistance( *node ) < 10*checktol) + MESSAGE("SquareDistance missed" << vNIt->SquareDistance( *node ) << " checktol " << checktol <<" "<X()<<" "<Y()<<" "<Z()); } if ( !n2nIt->second ) { // find out if node lies on theShape + //double dxyz[4]; tmpNode->setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z()); - if ( helper.CheckNodeU( geomEdge, tmpNode, u, mytol, /*force=*/true )) + if ( helper.CheckNodeU( geomEdge, tmpNode, u, mytol, /*force=*/true)) // , dxyz )) // dxyz used for debug purposes { SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z()); n2nIt->second = newNode; tgtMesh->SetNodeOnEdge( newNode, shapeID, u ); - //MESSAGE("u=" << u); + //MESSAGE("u=" << u << " " << newNode->X()<< " " << newNode->Y()<< " " << newNode->Z()); + //MESSAGE("d=" << dxyz[0] << " " << dxyz[1] << " " << dxyz[2] << " " << dxyz[3]); } } if ( !(newNodes[i] = n2nIt->second )) @@ -730,7 +739,7 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1], newNodes[2] ); else newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1]); - //MESSAGE("add Edge"); + //MESSAGE("add Edge " << newNodes[0]->GetID() << " " << newNodes[1]->GetID()); tgtMesh->SetMeshElementOnShape( newEdge, shapeID ); e2e->insert( make_pair( edge, newEdge )); } -- 2.39.2