Salome HOME
0020511: EDF 1101 SMESH : Add CGNS to Mesh Format Supported
[modules/smesh.git] / src / StdMeshers / StdMeshers_Import_1D2D.cxx
index 5513a1077c85d41ba9e227107fb9a1ecafad5a55..7b3aed36884faf181f63eef3d5272edb998378de 100644 (file)
@@ -1,23 +1,23 @@
-//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 //  SMESH SMESH : implementaion of SMESH idl descriptions
@@ -51,6 +51,7 @@
 #include <TopoDS_Compound.hxx>
 #include <TopoDS_Edge.hxx>
 #include <TopoDS_Vertex.hxx>
+#include <Precision.hxx>
 
 #include <numeric>
 
@@ -153,16 +154,16 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
   const bool toCheckOri = (helper.NbAncestors( geomFace, theMesh, TopAbs_SOLID ) == 1 );
 
   Handle(Geom_Surface) surface = BRep_Tool::Surface( geomFace );
-  if ( helper.GetSubShapeOri( tgtMesh->ShapeToMesh(), geomFace) == TopAbs_REVERSED )
-    surface->UReverse();
+  const bool reverse = 
+    ( helper.GetSubShapeOri( tgtMesh->ShapeToMesh(), geomFace) == TopAbs_REVERSED );
   gp_Pnt p; gp_Vec du, dv;
 
   set<int> subShapeIDs;
   subShapeIDs.insert( shapeID );
 
   // get nodes on vertices
-  list < SMESH_MeshEditor::TNodeXYZ > vertexNodes;
-  list < SMESH_MeshEditor::TNodeXYZ >::iterator vNIt;
+  list < SMESH_TNodeXYZ > vertexNodes;
+  list < SMESH_TNodeXYZ >::iterator vNIt;
   TopExp_Explorer exp( theShape, TopAbs_VERTEX );
   for ( ; exp.More(); exp.Next() )
   {
@@ -176,12 +177,13 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
       n = SMESH_Algo::VertexNode( v, tgtMesh );
       if ( !n ) return false; // very strange
     }
-    vertexNodes.push_back( SMESH_MeshEditor::TNodeXYZ( n ));
+    vertexNodes.push_back( SMESH_TNodeXYZ( n ));
   }
 
   // to count now many times a link between nodes encounters
   map<TLink, int> linkCount;
   map<TLink, int>::iterator link2Nb;
+  double minLinkLen2 = Precision::Infinite();
 
   // =========================
   // Import faces from groups
@@ -200,8 +202,8 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
     StdMeshers_Import_1D::getMaps( srcMesh, &theMesh, n2n, e2e );
 
     SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
-    SMDS_MeshNode tmpNode(0,0,0);
-    gp_XY uv;
+    SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0);
+    gp_XY uv( Precision::Infinite(), Precision::Infinite() );
     while ( srcElems->more() ) // loop on group contents
     {
       const SMDS_MeshElement* face = srcElems->next();
@@ -212,10 +214,10 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
       SMDS_MeshElement::iterator node = face->begin_nodes();
       for ( unsigned i = 0; i < newNodes.size(); ++i, ++node )
       {
-        TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first;
+        StdMeshers_Import_1D::TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first;
         if ( n2nIt->second )
         {
-          if ( !subShapeIDs.count( n2nIt->second->GetPosition()->GetShapeId() ))
+          if ( !subShapeIDs.count( n2nIt->second->getshapeId() ))
             break;
         }
         else
@@ -232,8 +234,8 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
         if ( !n2nIt->second )
         {
           // find out if node lies on theShape
-          tmpNode.setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z());
-          if ( helper.CheckNodeUV( geomFace, &tmpNode, uv, 10 * faceTol, /*force=*/true ))
+          tmpNode->setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z());
+          if ( helper.CheckNodeUV( geomFace, tmpNode, uv, 10 * faceTol, /*force=*/true ))
           {
             SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z());
             n2nIt->second = newNode;
@@ -262,16 +264,16 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
         {
           uv = helper.GetNodeUV( geomFace, newNodes[++iNode] );
           surface->D1( uv.X(),uv.Y(), p, du,dv );
-          geomNorm = du ^ dv;
+          geomNorm = reverse ? dv^du : du^dv;
         }
         while ( geomNorm.SquareMagnitude() < 1e-6 && iNode+1 < face->NbCornerNodes());
 
         int iNext = helper.WrapIndex( iNode+1, face->NbCornerNodes() );
         int iPrev = helper.WrapIndex( iNode-1, face->NbCornerNodes() );
 
-        SMESH_MeshEditor::TNodeXYZ prevNode( newNodes[iPrev] );
-        SMESH_MeshEditor::TNodeXYZ curNode ( newNodes[iNode] );
-        SMESH_MeshEditor::TNodeXYZ nextNode( newNodes[iNext] );
+        SMESH_TNodeXYZ prevNode( newNodes[iPrev] );
+        SMESH_TNodeXYZ curNode ( newNodes[iNode] );
+        SMESH_TNodeXYZ nextNode( newNodes[iNext] );
         gp_Vec n1n0( prevNode - curNode);
         gp_Vec n1n2( nextNode - curNode );
         gp_Vec meshNorm = n1n2 ^ n1n0;
@@ -313,8 +315,16 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
           medium = newNodes[i+nbNodes];
         link2Nb = linkCount.insert( make_pair( TLink( n1, n2, medium ), 0)).first;
         ++link2Nb->second;
+        if ( link2Nb->second == 1 )
+        {
+          // measure link length
+          double len2 = SMESH_TNodeXYZ( n1 ).SquareDistance( n2 );
+          if ( len2 < minLinkLen2 )
+            minLinkLen2 = len2;
+        }
       }
     }
+    helper.GetMeshDS()->RemoveNode(tmpNode);
   }
 
   // ==========================================================
@@ -327,6 +337,10 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
     if ( subShapeIDs.insert( tgtMesh->ShapeToIndex( exp.Current() )).second )
       edges.push_back( TopoDS::Edge( exp.Current() ));
 
+  // use large tolerance for projection of nodes to edges because of
+  // BLSURF mesher specifics (issue 0020918, Study2.hdf)
+  const double projTol = 1e-3 * sqrt( minLinkLen2 );
+
   bool isFaceMeshed = false;
   if ( SMESHDS_SubMesh* tgtSM = tgtMesh->MeshElements( theShape ))
   {
@@ -340,25 +354,26 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
       int nbFaces = link2Nb->second;
       if ( nbFaces == 1 )
       {
-        // check if the link lie on face boundary
+        // check if a not shared link lie on face boundary
         bool nodesOnBoundary = true;
         list< TopoDS_Shape > bndShapes;
         for ( int is1stN = 0; is1stN < 2 && nodesOnBoundary; ++is1stN )
         {
           const SMDS_MeshNode* n = is1stN ? link.node1() : link.node2();
-          if ( !subShapeIDs.count( n->GetPosition()->GetShapeId() ))
+          if ( !subShapeIDs.count( n->getshapeId() ))
           {
             for ( unsigned iE = 0; iE < edges.size(); ++iE )
-              if ( helper.CheckNodeU( edges[iE], n, u, 10 * faceTol, /*force=*/true ))
+              if ( helper.CheckNodeU( edges[iE], n, u=0, projTol, /*force=*/true ))
               {
                 BRep_Tool::Range(edges[iE],f,l);
                 if ( Abs(u-f) < 2 * faceTol || Abs(u-l) < 2 * faceTol )
                   // duplicated node on vertex
                   return error("Source elements overlap one another");
+                tgtSM->RemoveNode( n, /*isNodeDeleted=*/false );
                 tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)n, edges[iE], u );
                 break;
               }
-            nodesOnBoundary = subShapeIDs.count( n->GetPosition()->GetShapeId());
+            nodesOnBoundary = subShapeIDs.count( n->getshapeId());
           }
           if ( nodesOnBoundary )
           {
@@ -370,10 +385,10 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
           }
         }
         if ( !nodesOnBoundary )
-          break; // free internal link
+          break; // error: free internal link
         if ( bndShapes.front().ShapeType() == TopAbs_EDGE &&
              bndShapes.front() != bndShapes.back() )
-          break; // link nodes on different geom edges
+          break; // error: link nodes on different geom edges
 
         // find geom edge the link is on
         if ( bndShapes.back().ShapeType() != TopAbs_EDGE )
@@ -388,7 +403,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
               geomEdge.Nullify();
           }
           if ( geomEdge.IsNull() )
-            break; // vertices belong to different edges -> free internal link
+            break; // vertices belong to different edges -> error: free internal link
           bndShapes.push_back( geomEdge );
         }
 
@@ -406,15 +421,13 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
 
           TopoDS_Edge geomEdge = TopoDS::Edge(bndShapes.back());
           helper.CheckNodeU( geomEdge, link._medium, u, 10*faceTol, /*force=*/true );
+          tgtSM->RemoveNode( link._medium, /*isNodeDeleted=*/false );
           tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)link._medium, geomEdge, u );
         }
         else
         {
           edge = tgtMesh->AddEdge( newNodes[0], newNodes[1]);
         }
-        // remove nodes from submesh of theShape
-        for ( unsigned i = 0; i < newNodes.size(); ++i )
-          tgtSM->RemoveNode( newNodes[i], /*isNodeDeleted=*/false );
         if ( !edge )
           return false;
 
@@ -529,7 +542,7 @@ bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh &         theMesh,
   else
   {
     // std-like iterator used to get coordinates of nodes of mesh element
-    typedef SMDS_StdIterator< SMESH_MeshEditor::TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator;
+    typedef SMDS_StdIterator< SMESH_TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator;
 
     SMESH_MesherHelper helper(theMesh);
     helper.SetSubShape(theShape);
@@ -554,7 +567,7 @@ bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh &         theMesh,
     {
       const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
       SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
-      SMDS_MeshNode tmpNode(0,0,0);
+      SMDS_MeshNode *tmpNode =helper.AddNode(0,0,0);
       while ( srcElems->more() ) // loop on group contents
       {
         const SMDS_MeshElement* face = srcElems->next();
@@ -562,8 +575,8 @@ bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh &         theMesh,
         // a gravity center of face to geomFace
         gp_XYZ gc(0,0,0);
         gc = accumulate( TXyzIterator(face->nodesIterator()), TXyzIterator(), gc)/face->NbNodes();
-        tmpNode.setXYZ( gc.X(), gc.Y(), gc.Z());
-        if ( helper.CheckNodeUV( geomFace, &tmpNode, uv, 10 * faceTol, /*force=*/true ))
+        tmpNode->setXYZ( gc.X(), gc.Y(), gc.Z());
+        if ( helper.CheckNodeUV( geomFace, tmpNode, uv, 10 * faceTol, /*force=*/true ))
         {
           ++aVec[ face->GetEntityType() ];
 
@@ -585,6 +598,7 @@ bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh &         theMesh,
           }
         }
       }
+      helper.GetMeshDS()->RemoveNode(tmpNode);
     }
 
     int nbNodes = allNodes.size();