Salome HOME
PAL16202,16203 (Propagation 1D on edges group)
[modules/smesh.git] / src / StdMeshers / StdMeshers_MEFISTO_2D.cxx
index fcaefa535e9270b8a01e603a4b950a3bd4f49c5d..7b76b35455e95acc1fba4b4cfcb831cb2a266415 100644 (file)
@@ -34,6 +34,7 @@
 #include "SMESH_subMesh.hxx"
 #include "SMESH_Block.hxx"
 #include "SMESH_MesherHelper.hxx"
+#include "SMESH_Comment.hxx"
 
 #include "StdMeshers_FaceSide.hxx"
 #include "StdMeshers_MaxElementArea.hxx"
 
 #include "utilities.h"
 
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Edge.hxx>
-#include <Geom_Surface.hxx>
-#include <Geom2d_Curve.hxx>
-#include <gp_Pnt2d.hxx>
-#include <BRep_Tool.hxx>
 #include <BRepTools.hxx>
+#include <BRep_Tool.hxx>
+#include <Geom2d_Curve.hxx>
+#include <Geom_Surface.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_MapOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <gp_Pnt2d.hxx>
 
 using namespace std;
 
@@ -179,52 +184,40 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
 
   TopoDS_Face F = TopoDS::Face(aShape.Oriented(TopAbs_FORWARD));
 
+  // helper builds quadratic mesh if necessary
+  SMESH_MesherHelper helper(aMesh);
+  myTool = &helper;
+  _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
+  const bool ignoreMediumNodes = _quadraticMesh;
+
   // get all edges of a face
-  TopoDS_Vertex V1;
-  list< TopoDS_Edge > edges;
-  list< int > nbEdgesInWires;
-  int nbWires = SMESH_Block::GetOrderedEdges (F, V1, edges, nbEdgesInWires);
-
-  if (_hypLengthFromEdges) _edgeLength = 0;
-
-  // split list of all edges into separate wires
-  TWireVector wires ( nbWires );
-  list< int >::iterator nbE = nbEdgesInWires.begin();
-  list< TopoDS_Edge >::iterator from, to;
-  from = to = edges.begin();
-  for ( int iW = 0; iW < nbWires; ++iW )
+  TError problem;
+  TWireVector wires = StdMeshers_FaceSide::GetFaceWires( F, aMesh, ignoreMediumNodes, problem );
+  int nbWires = wires.size();
+  if ( problem && !problem->IsOK() ) return error( problem );
+  if ( nbWires == 0 ) return error( "Problem in StdMeshers_FaceSide::GetFaceWires()");
+  if ( wires[0]->NbSegments() < 3 ) // ex: a circle with 2 segments
+    return error(COMPERR_BAD_INPUT_MESH,
+                 SMESH_Comment("Too few segments: ")<<wires[0]->NbSegments());
+
+  // compute average edge length
+  if (_hypLengthFromEdges)
   {
-    std::advance( to, *nbE++ );
-    list< TopoDS_Edge > wireEdges( from, to );
-    // assure that there is a node on the first vertex
-    // as StdMeshers_FaceSide::GetUVPtStruct() requires
-    while ( !VertexNode( TopExp::FirstVertex( wireEdges.front(), true),
-                         aMesh.GetMeshDS()))
+    _edgeLength = 0;
+    int nbSegments = 0;
+    for ( int iW = 0; iW < nbWires; ++iW )
     {
-      wireEdges.splice(wireEdges.end(), wireEdges,
-                       wireEdges.begin(), ++wireEdges.begin());
-      if ( from->IsSame( wireEdges.front() )) {
-        MESSAGE( "No nodes on vertices on wire " << iW+1);
-        return false;
-      }
+      StdMeshers_FaceSidePtr wire = wires[ iW ];
+      _edgeLength += wire->Length();
+      nbSegments  += wire->NbSegments();
     }
-    StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( F, wireEdges, &aMesh, true );
-    wires[ iW ] = StdMeshers_FaceSidePtr( wire );
-    if (_hypLengthFromEdges && wire->NbSegments() )
-      _edgeLength += wire->Length() / wire->NbSegments();
-    from = to;
+    if ( nbSegments )
+      _edgeLength /= nbSegments;
   }
-  if ( wires[0]->NbSegments() < 3 ) // ex: a circle with 2 segments
-    return false;
 
   if (_hypLengthFromEdges && _edgeLength < DBL_MIN )
     _edgeLength = 100;
 
-  // helper builds a quadratic mesh if necessary
-  myTool = new SMESH_MesherHelper(aMesh);
-  auto_ptr<SMESH_MesherHelper> helperDeleter( myTool );
-  _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
-
   Z nblf;                 //nombre de lignes fermees (enveloppe en tete)
   Z *nudslf = NULL;       //numero du dernier sommet de chaque ligne fermee
   R2 *uvslf = NULL;       
@@ -251,7 +244,7 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
   // count nb of input points
   for ( int iW = 0; iW < nbWires; ++iW )
   {
-    nbpnt += wires[iW]->NbSegments();
+    nbpnt += wires[iW]->NbPoints() - 1;
     nudslf[iw++] = nbpnt;
   }
 
@@ -263,24 +256,26 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
   // correspondence mefisto index --> Nodes
   vector< const SMDS_MeshNode*> mefistoToDS(nbpnt, (const SMDS_MeshNode*)0);
 
-  // fill input points UV
-  LoadPoints(wires, uvslf, mefistoToDS, scalex, scaley);
-
-  // Compute
-  aptrte(nutysu, aretmx,
-         nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr);
-
   bool isOk = false;
-  if (ierr == 0)
-  {
-    MESSAGE("... End Triangulation Generated Triangle Number " << nbt);
-    MESSAGE("                                    Node Number " << nbst);
-    StoreResult(nbst, uvst, nbt, nust, mefistoToDS, scalex, scaley);
-    isOk = true;
-  }
-  else
+
+  // fill input points UV
+  if ( LoadPoints(wires, uvslf, mefistoToDS, scalex, scaley) )
   {
-    MESSAGE("Error in Triangulation");
+    // Compute
+    aptrte(nutysu, aretmx,
+           nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr);
+
+    if (ierr == 0)
+    {
+      MESSAGE("... End Triangulation Generated Triangle Number " << nbt);
+      MESSAGE("                                    Node Number " << nbst);
+      StoreResult(nbst, uvst, nbt, nust, mefistoToDS, scalex, scaley);
+      isOk = true;
+    }
+    else
+    {
+      error(ierr,"Error in Triangulation (aptrte())");
+    }
   }
   if (nudslf != NULL) delete[]nudslf;
   if (uvslf != NULL)  delete[]uvslf;
@@ -493,20 +488,25 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector &                 wires,
     TopExp::MapShapesAndAncestors( F, TopAbs_VERTEX, TopAbs_WIRE, VWMap );
     int nbVertices = 0;
     for ( int iW = 0; iW < wires.size(); ++iW )
-      nbVertices += wires[ iW ]->NbSegments();
+      nbVertices += wires[ iW ]->NbEdges();
     if ( nbVertices == VWMap.Extent() )
       VWMap.Clear(); // wires have no common vertices
   }
 
-  const bool isXConst = false; // meaningles here
-  const double constValue = 0; // meaningles here
-
   int m = 0;
   list< int > mOnVertex;
 
   for ( int iW = 0; iW < wires.size(); ++iW )
   {
-    const vector<UVPtStruct>& uvPtVec = wires[ iW ]->GetUVPtStruct(isXConst,constValue);
+    const vector<UVPtStruct>& uvPtVec = wires[ iW ]->GetUVPtStruct();
+    if ( uvPtVec.size() != wires[ iW ]->NbPoints() ) {
+      return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Unexpected nb of points on wire ")
+                   << iW << uvPtVec.size()<<" != "<<wires[ iW ]->NbPoints());
+    }
+    if ( m + uvPtVec.size()-1 > mefistoToDS.size() ) {
+      MESSAGE("Wrong mefistoToDS.size: "<<mefistoToDS.size()<<" < "<<m + uvPtVec.size()-1);
+      return error("Internal error");
+    }
 
     vector<UVPtStruct>::const_iterator uvPt = uvPtVec.begin();
     for ( ++uvPt; uvPt != uvPtVec.end(); ++uvPt )