Salome HOME
PR : merge from V7_2_1p1
authorprascle <prascle>
Sat, 3 Aug 2013 11:11:12 +0000 (11:11 +0000)
committerprascle <prascle>
Sat, 3 Aug 2013 11:11:12 +0000 (11:11 +0000)
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
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_MesherHelper.cxx
src/SMESHUtils/SMESH_MeshAlgos.cxx
src/SMESHUtils/SMESH_MeshAlgos.hxx
src/SMESHUtils/SMESH_Octree.hxx
src/SMESHUtils/SMESH_Tree.hxx
src/SMESH_PY/smeshstudytools.py
src/StdMeshers/StdMeshers_Import_1D.cxx

index 16eb2537e7e08ed230422fae528e3e348073df57..99d39e4f08bda5a155263da05df9f94f24be8ddf 100644 (file)
@@ -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));
index 49d3e14c7ed6f452ce8e775e72c38f5c489806fb..d817e9018145976f86c14ec0e17261d6c7ad7f98 100644 (file)
@@ -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<const SMDS_MeshNode*> alreadyCheckedNodes;
+    std::set<const SMDS_MeshElement*> alreadyCheckedElems;
+    std::set<const SMDS_MeshElement*> 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<const SMDS_MeshNode*> nodesElem;
+      nodesElem.clear();
+      SMDS_ElemIteratorPtr nodeItr = anElem->nodesIterator();
+      while ( nodeItr->more() )
+      {
+        const SMDS_MeshNode* aNode = cast2Node(nodeItr->next());
+        nodesElem.insert(aNode);
+      }
+      std::set<const SMDS_MeshNode*>::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<const SMDS_MeshElement*>::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 );
+        }
       }
     }
   }
index 316bcea6291e41a45c3577966e31417912df9202..48bd275bea85c1ea85f127ffd677aa6a93b78c07 100644 (file)
@@ -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<double>::min() )
       {
+        MESSAGE("fabs( u ) > numeric_limits<double>::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
         {
index d0d6008d373f426e51dbfc49d9891fef1ebfb276..45acf33b115cb4067aa23516ee4a774f59d5fdec 100644 (file)
@@ -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;
index 42ff8923a067a043138509828c318381f8144368..0236f67371581c221e688c8d64ecac7505ab134f 100644 (file)
@@ -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
index 5fa0e6533a3edb95ceb7f1bb8df23a716e473307..adb74b560f5d5119c853ede6777a810a59998eab 100644 (file)
@@ -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;
index 61ee057f0975f7c7f9dbde090cc1551330691b51..36d4124209ca08835bd4148ca63c4383f9c7a932 100644 (file)
@@ -219,6 +219,8 @@ void SMESH_Tree<BND_BOX,NB_CHILDREN>::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 );
index 5bf1250b06ce045d435bf5ae540ff4acc17dc51c..7b83e570e25e0dc5339059e417d7d205dad53bb8 100644 (file)
@@ -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:
     """
index 03b89eda3091c521bb96165c03850eb0128d821c..fbbe7198f5bea29e9fa125b3114472005d20e17a 100644 (file)
@@ -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<SMESH_Group*>& 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<const SMDS_MeshNode*> 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 <<" "<<vNIt->X()<<" "<<vNIt->Y()<<" "<<vNIt->Z());
               (*n2nIt).second = vNIt->_node;
               vertexNodes.erase( vNIt );
               break;
             }
+            else if ( vNIt->SquareDistance( *node ) < 10*checktol)
+              MESSAGE("SquareDistance missed" << vNIt->SquareDistance( *node ) << " checktol " << checktol <<" "<<vNIt->X()<<" "<<vNIt->Y()<<" "<<vNIt->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 ));
     }