Salome HOME
IPAL54027: Projection algo is very long on a face with many edges
authoreap <eap@opencascade.com>
Tue, 7 Mar 2017 18:35:05 +0000 (21:35 +0300)
committereap <eap@opencascade.com>
Tue, 7 Mar 2017 18:35:05 +0000 (21:35 +0300)
14 files changed:
src/SMESH/SMESH_MesherHelper.cxx
src/SMESH/SMESH_MesherHelper.hxx
src/StdMeshers/StdMeshers_FaceSide.cxx
src/StdMeshers/StdMeshers_FaceSide.hxx
src/StdMeshers/StdMeshers_MEFISTO_2D.cxx
src/StdMeshers/StdMeshers_PolygonPerFace_2D.cxx
src/StdMeshers/StdMeshers_Prism_3D.cxx
src/StdMeshers/StdMeshers_Projection_1D2D.cxx
src/StdMeshers/StdMeshers_Projection_2D.cxx
src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx
src/StdMeshers/StdMeshers_Quadrangle_2D.cxx
src/StdMeshers/StdMeshers_Quadrangle_2D.hxx
src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx
src/StdMeshers/StdMeshers_ViscousLayers2D.cxx

index ce4e90c..e03128d 100644 (file)
@@ -139,9 +139,9 @@ SMESHDS_Mesh* SMESH_MesherHelper::GetMeshDS() const
 
 //=======================================================================
 //function : IsQuadraticSubMesh
-//purpose  : Check submesh for given shape: if all elements on this shape 
+//purpose  : Check sub-meshes of a given shape: if all elements on sub-shapes
 //           are quadratic, quadratic elements will be created.
-//           Also fill myTLinkNodeMap
+//           Fill myTLinkNodeMap
 //=======================================================================
 
 bool SMESH_MesherHelper::IsQuadraticSubMesh(const TopoDS_Shape& aSh)
@@ -149,7 +149,6 @@ bool SMESH_MesherHelper::IsQuadraticSubMesh(const TopoDS_Shape& aSh)
   SMESHDS_Mesh* meshDS = GetMeshDS();
   // we can create quadratic elements only if all elements
   // created on sub-shapes of given shape are quadratic
-  // also we have to fill myTLinkNodeMap
   myCreateQuadratic = true;
   mySeamShapeIds.clear();
   myDegenShapeIds.clear();
@@ -162,9 +161,6 @@ bool SMESH_MesherHelper::IsQuadraticSubMesh(const TopoDS_Shape& aSh)
   }
   SMDSAbs_ElementType elemType( subType==TopAbs_FACE ? SMDSAbs_Face : SMDSAbs_Edge );
 
-
-  //int nbOldLinks = myTLinkNodeMap.size();
-
   if ( !myMesh->HasShapeToMesh() )
   {
     if (( myCreateQuadratic = myMesh->NbFaces( ORDER_QUADRATIC )))
@@ -374,6 +370,27 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh)
 }
 
 //=======================================================================
+/*!
+ * \brief Copy shape information from another helper. Used to improve performance
+ *        since SetSubShape() can be time consuming if there are many edges
+ */
+//=======================================================================
+
+void SMESH_MesherHelper::CopySubShapeInfo(const SMESH_MesherHelper& other)
+{
+  this->myShape         = other.myShape;
+  this->myShapeID       = other.myShapeID;
+  this->myDegenShapeIds = other.myDegenShapeIds;
+  this->mySeamShapeIds  = other.mySeamShapeIds;
+  this->myPar1[0]       = other.myPar1[0];
+  this->myPar1[1]       = other.myPar1[1];
+  this->myPar2[0]       = other.myPar2[0];
+  this->myPar2[1]       = other.myPar2[1];
+  this->myParIndex      = other.myParIndex;
+  this->myFace2Surface  = other.myFace2Surface;
+}
+
+//=======================================================================
 //function : ShapeToIndex
 //purpose  : Convert a shape to its index in the SMESHDS_Mesh
 //=======================================================================
@@ -2825,8 +2842,9 @@ bool SMESH_MesherHelper::IsStructured( SMESH_subMesh* faceSM )
 //purpose  : Return true if 2D mesh on FACE is ditorted
 //=======================================================================
 
-bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM,
-                                        bool           checkUV)
+bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh*      faceSM,
+                                        bool                checkUV,
+                                        SMESH_MesherHelper* faceHelper)
 {
   if ( !faceSM || faceSM->GetSubShape().ShapeType() != TopAbs_FACE )
     return false;
@@ -2834,12 +2852,26 @@ bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM,
   bool haveBadFaces = false;
 
   SMESH_MesherHelper helper( *faceSM->GetFather() );
+  if ( faceHelper )
+    helper.CopySubShapeInfo( *faceHelper );
   helper.SetSubShape( faceSM->GetSubShape() );
 
   const TopoDS_Face&  F = TopoDS::Face( faceSM->GetSubShape() );
   SMESHDS_SubMesh* smDS = helper.GetMeshDS()->MeshElements( F );
   if ( !smDS || smDS->NbElements() == 0 ) return false;
 
+  bool subIdsValid = true; // shape ID of nodes is OK
+  if ( helper.HasSeam() )
+  {
+    // check if nodes are bound to seam edges
+    SMESH_subMeshIteratorPtr smIt = faceSM->getDependsOnIterator(/*includeSelf=*/false);
+    while ( smIt->more() && subIdsValid )
+    {
+      SMESH_subMesh* sm = smIt->next();
+      if ( helper.IsSeamShape( sm->GetId() ) && sm->IsEmpty() )
+        subIdsValid = false;
+    }
+  }
   SMDS_ElemIteratorPtr faceIt = smDS->GetElements();
   double prevArea = 0;
   vector< const SMDS_MeshNode* > nodes;
@@ -2864,12 +2896,20 @@ bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM,
       if ( isOnDegen )
         continue;
     }
-    // prepare to getting UVs
+    // prepare for getting UVs
     const SMDS_MeshNode* inFaceNode = 0;
     if ( helper.HasSeam() ) {
       for ( size_t i = 0; ( i < nodes.size() && !inFaceNode ); ++i )
         if ( !helper.IsSeamShape( nodes[ i ]->getshapeId() ))
+        {
           inFaceNode = nodes[ i ];
+          if ( !subIdsValid )
+          {
+            gp_XY uv = helper.GetNodeUV( F, inFaceNode );
+            if ( helper.IsOnSeam( uv ))
+              inFaceNode = NULL;
+          }
+        }
       if ( !inFaceNode )
         continue;
     }
@@ -2878,6 +2918,14 @@ bool SMESH_MesherHelper::IsDistorted2D( SMESH_subMesh* faceSM,
     for ( size_t i = 0; i < nodes.size(); ++i )
       uv[ i ] = helper.GetNodeUV( F, nodes[ i ], inFaceNode, toCheckUV );
 
+    if ( !subIdsValid ) // fix uv on seam
+    {
+      gp_XY uvInFace = helper.GetNodeUV( F, inFaceNode );
+      for ( size_t i = 0; i < uv.size(); ++i )
+        if ( helper.IsOnSeam( uv[i] ))
+          uv[i] = helper.getUVOnSeam( uv[i], uvInFace ).XY();
+    }
+
     // compare orientation of triangles
     double faceArea = 0;
     for ( int iT = 0, nbT = nodes.size()-2; iT < nbT; ++iT )
@@ -3087,7 +3135,7 @@ TopAbs_Orientation SMESH_MesherHelper::GetSubShapeOri(const TopoDS_Shape& shape,
 
 //=======================================================================
 //function : IsSubShape
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 bool SMESH_MesherHelper::IsSubShape( const TopoDS_Shape& shape,
@@ -3395,6 +3443,25 @@ double SMESH_MesherHelper::GetOtherParam(const double param) const
   return fabs(param-myPar1[i]) < fabs(param-myPar2[i]) ? myPar2[i] : myPar1[i];
 }
 
+//=======================================================================
+//function : IsOnSeam
+//purpose  : Check if UV is on seam. Return 0 if not, 1 for U seam, 2 for V seam
+//=======================================================================
+
+int SMESH_MesherHelper::IsOnSeam(const gp_XY& uv) const
+{
+  for ( int i = U_periodic; i <= V_periodic ; ++i )
+    if ( myParIndex & i )
+    {
+      double p   = uv.Coord( i );
+      double tol = ( myPar2[i-1] - myPar1[i-1] ) / 100.;
+      if ( Abs( p - myPar1[i-1] ) < tol ||
+           Abs( p - myPar2[i-1] ) < tol )
+        return i;
+    }
+  return 0;
+}
+
 namespace {
 
   //=======================================================================
index 7e60e6d..cf3506f 100644 (file)
@@ -122,7 +122,9 @@ class SMESH_EXPORT SMESH_MesherHelper
   /*!
    * \brief Return true if 2D mesh on FACE is distored
    */
-  static bool IsDistorted2D( SMESH_subMesh* faceSM, bool checkUV=false );
+  static bool IsDistorted2D( SMESH_subMesh*      faceSM,
+                             bool                checkUV = false,
+                             SMESH_MesherHelper* faceHelper = NULL);
 
   /*!
    * \brief Returns true if given node is medium
@@ -318,6 +320,12 @@ public:
    * \brief Return the shape set by IsQuadraticSubMesh() or SetSubShape() 
    */
   const TopoDS_Shape& GetSubShape() const  { return myShape; }
+  /*!
+   * \brief Copy shape information from another helper to improve performance
+   *        since SetSubShape() can be time consuming if there are many edges
+   */
+  void CopySubShapeInfo(const SMESH_MesherHelper& other);
+
 
   /*!
    * \brief Convert a shape to its index in the SMESHDS_Mesh
@@ -611,6 +619,10 @@ public:
    * \brief Return an alternative parameter for a node on seam
    */
   double GetOtherParam(const double param) const;
+  /*!
+   * \brief Check if UV is on seam. Return 0 if not, 1 for U seam, 2 for V seam
+   */
+  int IsOnSeam(const gp_XY& uv) const;
 
   /*!
    * \brief Return existing or create new medium nodes between given ones
@@ -693,6 +705,7 @@ public:
 
   static void WriteShape(const TopoDS_Shape& s);
 
+
  protected:
 
   /*!
@@ -709,6 +722,7 @@ public:
 
   double getFaceMaxTol( const TopoDS_Shape& face ) const;
 
+
  private:
 
   // forbidden copy constructor
index 3f1ce2d..9f5929e 100644 (file)
@@ -63,7 +63,7 @@ using namespace std;
  * \brief Constructor of a side of one edge
   * \param theFace - the face
   * \param theEdge - the edge
- */
 */
 //================================================================================
 
 StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face&   theFace,
@@ -71,11 +71,15 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face&   theFace,
                                          SMESH_Mesh*          theMesh,
                                          const bool           theIsForward,
                                          const bool           theIgnoreMediumNodes,
+                                         SMESH_MesherHelper*  theFaceHelper,
                                          SMESH_ProxyMesh::Ptr theProxyMesh)
 {
   std::list<TopoDS_Edge> edges(1,theEdge);
-  *this = StdMeshers_FaceSide( theFace, edges, theMesh, theIsForward,
-                               theIgnoreMediumNodes, theProxyMesh );
+  StdMeshers_FaceSide tmp( theFace, edges, theMesh, theIsForward,
+                           theIgnoreMediumNodes, theFaceHelper, theProxyMesh );
+  *this = tmp;
+
+  tmp.myHelper = NULL;
 }
 
 //================================================================================
@@ -89,6 +93,7 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face&      theFace,
                                          SMESH_Mesh*             theMesh,
                                          const bool              theIsForward,
                                          const bool              theIgnoreMediumNodes,
+                                         SMESH_MesherHelper*     theFaceHelper,
                                          SMESH_ProxyMesh::Ptr    theProxyMesh)
 {
   int nbEdges = theEdges.size();
@@ -108,7 +113,13 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face&      theFace,
   myMissingVertexNodes = false;
   myIgnoreMediumNodes  = theIgnoreMediumNodes;
   myDefaultPnt2d       = gp_Pnt2d( 1e+100, 1e+100 );
+  myHelper             = NULL;
   if ( !myProxyMesh ) myProxyMesh.reset( new SMESH_ProxyMesh( *theMesh ));
+  if ( theFaceHelper && theFaceHelper->GetSubShape() == myFace )
+  {
+    myHelper           = new SMESH_MesherHelper( * myProxyMesh->GetMesh() );
+    myHelper->CopySubShapeInfo( *theFaceHelper );
+  }
   if ( nbEdges == 0 ) return;
 
   SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS();
@@ -203,6 +214,7 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const StdMeshers_FaceSide*  theSide,
   myLast.push_back     ( theULast );
   myNormPar.push_back  ( 1. );
   myIsUniform.push_back( true );
+  myHelper       = NULL;
   myLength       = 0;
   myProxyMesh    = theSide->myProxyMesh;
   myDefaultPnt2d = *thePnt2d1;
@@ -260,6 +272,7 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(UVPtStructVec&     theSideNodes,
   }
 
   myFace       = theFace;
+  myHelper     = NULL;
   myPoints     = theSideNodes;
   myNbPonits   = myPoints.size();
   myNbSegments = myNbPonits + 1;
@@ -313,6 +326,17 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(UVPtStructVec&     theSideNodes,
 }
 
 //================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+StdMeshers_FaceSide::~StdMeshers_FaceSide()
+{
+  delete myHelper; myHelper = NULL;
+}
+
+//================================================================================
 /*
  * Return info on nodes on the side
  */
@@ -326,12 +350,12 @@ const std::vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool   isXCons
     if ( NbEdges() == 0 ) return myPoints;
 
     StdMeshers_FaceSide* me = const_cast< StdMeshers_FaceSide* >( this );
-    SMESH_MesherHelper eHelper( *myProxyMesh->GetMesh() );
-    SMESH_MesherHelper fHelper( *myProxyMesh->GetMesh() );
-    fHelper.SetSubShape( myFace );
     bool paramOK = true;
     double eps = 1e-100;
 
+    SMESH_MesherHelper  eHelper( *myProxyMesh->GetMesh() );
+    SMESH_MesherHelper& fHelper = *FaceHelper();
+
     // sort nodes of all edges by putting them into a map
 
     map< double, const SMDS_MeshNode*>            u2node;
@@ -618,9 +642,8 @@ std::vector<const SMDS_MeshNode*> StdMeshers_FaceSide::GetOrderedNodes(int theEd
     if ( NbEdges() == 0 ) return resultNodes;
 
     //SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS();
-    SMESH_MesherHelper eHelper( *myProxyMesh->GetMesh() );
-    SMESH_MesherHelper fHelper( *myProxyMesh->GetMesh() );
-    fHelper.SetSubShape( myFace );
+    SMESH_MesherHelper  eHelper( *myProxyMesh->GetMesh() );
+    SMESH_MesherHelper& fHelper = * FaceHelper();
     bool paramOK = true;
 
     // Sort nodes of all edges putting them into a map
@@ -1014,8 +1037,7 @@ int StdMeshers_FaceSide::NbPoints(const bool update) const
       }
     }
 
-    SMESH_MesherHelper helper( *myProxyMesh->GetMesh() );
-    helper.SetSubShape( myFace );
+    SMESH_MesherHelper* helper = FaceHelper();
 
     std::set< const SMDS_MeshNode* > vNodes;
     const int nbV = NbEdges() + !IsClosed();
@@ -1023,8 +1045,8 @@ int StdMeshers_FaceSide::NbPoints(const bool update) const
       if ( const SMDS_MeshNode* n = VertexNode( i ))
       {
         if ( !vNodes.insert( n ).second &&
-             ( helper.IsRealSeam  ( n->getshapeId() ) ||
-               helper.IsDegenShape( n->getshapeId() )))
+             ( helper->IsRealSeam  ( n->getshapeId() ) ||
+               helper->IsDegenShape( n->getshapeId() )))
           me->myNbPonits++;
       }
       else
@@ -1241,9 +1263,14 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face&   theFace,
                                               SMESH_Mesh &         theMesh,
                                               const bool           theIgnoreMediumNodes,
                                               TError &             theError,
+                                              SMESH_MesherHelper*  theFaceHelper,
                                               SMESH_ProxyMesh::Ptr theProxyMesh,
                                               const bool           theCheckVertexNodes)
 {
+  SMESH_MesherHelper helper( theMesh );
+  if ( theFaceHelper && theFaceHelper->GetSubShape() == theFace )
+    helper.CopySubShapeInfo( *theFaceHelper );
+
   list< TopoDS_Edge > edges, internalEdges;
   list< int > nbEdgesInWires;
   int nbWires = SMESH_Block::GetOrderedEdges (theFace, edges, nbEdgesInWires);
@@ -1287,7 +1314,7 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face&   theFace,
 
     StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, wireEdges, &theMesh,
                                                          /*isForward=*/true, theIgnoreMediumNodes,
-                                                         theProxyMesh );
+                                                         &helper, theProxyMesh );
     wires[ iW ] = StdMeshers_FaceSidePtr( wire );
     from = to;
   }
@@ -1295,7 +1322,7 @@ TSideVector StdMeshers_FaceSide::GetFaceWires(const TopoDS_Face&   theFace,
   {
     StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( theFace, internalEdges.back(), &theMesh,
                                                          /*isForward=*/true, theIgnoreMediumNodes,
-                                                         theProxyMesh );
+                                                         &helper, theProxyMesh );
     wires.push_back( StdMeshers_FaceSidePtr( wire ));
     internalEdges.pop_back();
   }
@@ -1351,3 +1378,20 @@ bool StdMeshers_FaceSide::IsClosed() const
 {
   return myEdge.empty() ? false : FirstVertex().IsSame( LastVertex() );
 }
+
+//================================================================================
+/*!
+ * \brief Return a helper initialized with the FACE
+ */
+//================================================================================
+
+SMESH_MesherHelper* StdMeshers_FaceSide::FaceHelper() const
+{
+  StdMeshers_FaceSide* me = const_cast< StdMeshers_FaceSide* >( this );
+  if ( !myHelper && myProxyMesh )
+  {
+    me->myHelper = new SMESH_MesherHelper( *myProxyMesh->GetMesh() );
+    me->myHelper->SetSubShape( myFace );
+  }
+  return me->myHelper;
+}
index 37e025f..6759f50 100644 (file)
 #include <list>
 #include <boost/shared_ptr.hpp>
 
-class SMDS_MeshNode;
-class SMESH_Mesh;
 class Adaptor2d_Curve2d;
 class Adaptor3d_Curve;
 class BRepAdaptor_CompCurve;
-struct SMESH_ComputeError;
+class SMDS_MeshNode;
+class SMESH_Mesh;
+class SMESH_MesherHelper;
 class StdMeshers_FaceSide;
+struct SMESH_ComputeError;
 
 typedef boost::shared_ptr< SMESH_ComputeError >  TError;
 typedef boost::shared_ptr< StdMeshers_FaceSide > StdMeshers_FaceSidePtr;
@@ -65,6 +66,9 @@ typedef std::vector< StdMeshers_FaceSidePtr >    TSideVector;
 class STDMESHERS_EXPORT StdMeshers_FaceSide
 {
 public:
+
+  enum { ALL_EDGES = -1, LAST_EDGE = -1 }; //!< constants
+
   /*!
    * \brief Wrap one edge
    */
@@ -73,6 +77,7 @@ public:
                       SMESH_Mesh*          theMesh,
                       const bool           theIsForward,
                       const bool           theIgnoreMediumNodes,
+                      SMESH_MesherHelper*  theFaceHelper = NULL,
                       SMESH_ProxyMesh::Ptr theProxyMesh = SMESH_ProxyMesh::Ptr());
   /*!
    * \brief Wrap several edges. Edges must be properly ordered and oriented.
@@ -82,6 +87,7 @@ public:
                       SMESH_Mesh*             theMesh,
                       const bool              theIsForward,
                       const bool              theIgnoreMediumNodes,
+                      SMESH_MesherHelper*     theFaceHelper = NULL,
                       SMESH_ProxyMesh::Ptr    theProxyMesh = SMESH_ProxyMesh::Ptr());
   /*!
    * \brief Simulate a side from a vertex using data from other FaceSide
@@ -89,10 +95,10 @@ public:
   StdMeshers_FaceSide(const StdMeshers_FaceSide*  theSide,
                       const SMDS_MeshNode*        theNode,
                       const gp_Pnt2d*             thePnt2d1,
-                      const gp_Pnt2d*             thePnt2d2=NULL,
-                      const Handle(Geom2d_Curve)& theC2d=NULL,
-                      const double                theUFirst=0.,
-                      const double                theULast=1.);
+                      const gp_Pnt2d*             thePnt2d2 = NULL,
+                      const Handle(Geom2d_Curve)& theC2d = NULL,
+                      const double                theUFirst = 0.,
+                      const double                theULast = 1.);
   /*!
    * \brief Create a side from an UVPtStructVec
    */
@@ -101,32 +107,36 @@ public:
                       const TopoDS_Edge& theEdge = TopoDS_Edge(),
                       SMESH_Mesh*        theMesh = 0);
 
+  ~StdMeshers_FaceSide();
+
   // static "consrtuctors"
   static StdMeshers_FaceSidePtr New(const TopoDS_Face&   Face,
                                     const TopoDS_Edge&   Edge,
                                     SMESH_Mesh*          Mesh,
                                     const bool           IsForward,
                                     const bool           IgnoreMediumNodes,
+                                    SMESH_MesherHelper*  FaceHelper = NULL,
                                     SMESH_ProxyMesh::Ptr ProxyMesh = SMESH_ProxyMesh::Ptr())
   { return StdMeshers_FaceSidePtr
-      ( new StdMeshers_FaceSide( Face,Edge,Mesh,IsForward,IgnoreMediumNodes,ProxyMesh ));
+      ( new StdMeshers_FaceSide( Face,Edge,Mesh,IsForward,IgnoreMediumNodes,FaceHelper,ProxyMesh ));
   }
   static StdMeshers_FaceSidePtr New (const TopoDS_Face&      Face,
                                      std::list<TopoDS_Edge>& Edges,
                                      SMESH_Mesh*             Mesh,
                                      const bool              IsForward,
                                      const bool              IgnoreMediumNodes,
+                                     SMESH_MesherHelper*     FaceHelper = NULL,
                                      SMESH_ProxyMesh::Ptr    ProxyMesh = SMESH_ProxyMesh::Ptr())
   { return StdMeshers_FaceSidePtr
-      ( new StdMeshers_FaceSide( Face,Edges,Mesh,IsForward,IgnoreMediumNodes,ProxyMesh ));
+      ( new StdMeshers_FaceSide( Face,Edges,Mesh,IsForward,IgnoreMediumNodes,FaceHelper,ProxyMesh ));
   }
   static StdMeshers_FaceSidePtr New (const StdMeshers_FaceSide*  Side,
                                      const SMDS_MeshNode*        Node,
                                      const gp_Pnt2d*             Pnt2d1,
-                                     const gp_Pnt2d*             Pnt2d2=NULL,
-                                     const Handle(Geom2d_Curve)& C2d=NULL,
-                                     const double                UFirst=0.,
-                                     const double                ULast=1.)
+                                     const gp_Pnt2d*             Pnt2d2 = NULL,
+                                     const Handle(Geom2d_Curve)& C2d = NULL,
+                                     const double                UFirst = 0.,
+                                     const double                ULast = 1.)
   { return StdMeshers_FaceSidePtr
       ( new StdMeshers_FaceSide( Side,Node,Pnt2d1,Pnt2d2,C2d,UFirst,ULast ));
   }
@@ -143,8 +153,9 @@ public:
                                   SMESH_Mesh &         theMesh,
                                   const bool           theIgnoreMediumNodes,
                                   TError &             theError,
+                                  SMESH_MesherHelper*  theFaceHelper = NULL,
                                   SMESH_ProxyMesh::Ptr theProxyMesh = SMESH_ProxyMesh::Ptr(),
-                                  const bool           theCheckVertexNodes=true);
+                                  const bool           theCheckVertexNodes = true);
   /*!
    * \brief Change orientation of side geometry
    */
@@ -183,7 +194,7 @@ public:
     * Missing nodes are allowed only on internal vertices.
     * For a closed side, the 1st point repeats at end
    */
-  const UVPtStructVec& GetUVPtStruct(bool isXConst =0, double constValue =0) const;
+  const UVPtStructVec& GetUVPtStruct( bool isXConst = 0, double constValue = 0 ) const;
   /*!
    * \brief Simulates detailed data on nodes
     * \param isXConst - true if normalized parameter X is constant
@@ -194,10 +205,10 @@ public:
                                           double constValue = 0) const;
   /*!
    * \brief Return nodes in the order they encounter while walking along
-   *  the while side or a specified EDGE.
-    * For a closed side, the 1st point repeats at end
+   *  the while side or a specified EDGE. For a closed side, the 1st point repeats at end.
+   *  \param iE - index of the EDGE. Default is "all EDGEs".
    */
-  std::vector<const SMDS_MeshNode*> GetOrderedNodes(int iE=-1) const;
+  std::vector<const SMDS_MeshNode*> GetOrderedNodes( int iE = ALL_EDGES ) const;
 
   /*!
    * \brief Return nodes of the i-th EDGE.
@@ -262,7 +273,7 @@ public:
   /*!
    * \brief Return last vertex of the i-th edge (count starts from zero)
    */
-  TopoDS_Vertex LastVertex(int i=-1) const;
+  TopoDS_Vertex LastVertex(int i = LAST_EDGE) const;
   /*!
    * \brief Return \c true if the chain of EDGEs is closed
    */
@@ -276,8 +287,6 @@ public:
    */
   inline int EdgeIndex( double U ) const;
 
-  //virtual gp_Pnt Value(double U) const;
-  
   void dump(const char* msg=0) const;
   
   /*!
@@ -314,6 +323,10 @@ public:
    * \brief Return orientation of i-th wrapped edge (count starts from zero)
    */
   inline bool IsReversed(int i) const;
+  /*!
+   * \brief Return a helper initialized with the FACE
+   */
+  SMESH_MesherHelper* FaceHelper() const;
 
 protected:
 
@@ -335,6 +348,7 @@ protected:
   SMESH_ProxyMesh::Ptr              myProxyMesh;
   bool                              myMissingVertexNodes, myIgnoreMediumNodes;
   gp_Pnt2d                          myDefaultPnt2d;
+  SMESH_MesherHelper*               myHelper;
 };
 
 
index de7de3b..972d4b1 100644 (file)
@@ -203,7 +203,7 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
   // get all edges of a face
   TError problem;
   TWireVector wires =
-    StdMeshers_FaceSide::GetFaceWires( F, aMesh, skipMediumNodes, problem, proxyMesh );
+    StdMeshers_FaceSide::GetFaceWires( F, aMesh, skipMediumNodes, problem, _helper, proxyMesh );
   int nbWires = wires.size();
   if ( problem && !problem->IsOK() ) return error( problem );
   if ( nbWires == 0 ) return error( "Problem in StdMeshers_FaceSide::GetFaceWires()");
index 5f3a21e..78c4d62 100644 (file)
@@ -87,10 +87,10 @@ bool StdMeshers_PolygonPerFace_2D::Compute(SMESH_Mesh&         theMesh,
   if ( !proxyMesh )
     return false;
 
-  TError erorr;
+  TError err;
   TSideVector wires = StdMeshers_FaceSide::GetFaceWires(face, theMesh,
                                                         /*skipMediumNodes=*/_quadraticMesh,
-                                                        erorr, proxyMesh,
+                                                        err, &helper, proxyMesh,
                                                         /*checkVertexNodes=*/false);
   if ( wires.size() != 1 )
     return error( COMPERR_BAD_SHAPE, SMESH_Comment("One wire required, not ") << wires.size() );
index 538cbdd..a7dae02 100644 (file)
@@ -3258,9 +3258,11 @@ bool StdMeshers_Prism_3D::initPrism(Prism_3D::TPrismTopo& thePrism,
                     "Non-quadrilateral faces are not opposite"));
 
     // check that the found top and bottom FACEs are opposite
+    TopTools_IndexedMapOfShape topEdgesMap( thePrism.myBottomEdges.size() );
+    TopExp::MapShapes( thePrism.myTop, topEdgesMap );
     list< TopoDS_Edge >::iterator edge = thePrism.myBottomEdges.begin();
     for ( ; edge != thePrism.myBottomEdges.end(); ++edge )
-      if ( myHelper->IsSubShape( *edge, thePrism.myTop ))
+      if ( topEdgesMap.Contains( *edge ))
         return toSM( error
                      (notQuadGeomSubMesh.empty() ? COMPERR_BAD_INPUT_MESH : COMPERR_BAD_SHAPE,
                       "Non-quadrilateral faces are not opposite"));
index d0966d7..c0e53ce 100644 (file)
@@ -160,8 +160,8 @@ bool StdMeshers_Projection_1D2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape
   }
   TopoDS_Face F = TopoDS::Face( theShape );
   TError err;
-  TSideVector wires = StdMeshers_FaceSide::GetFaceWires( F, theMesh,
-                                                         /*ignoreMediumNodes=*/false, err);
+  TSideVector wires = StdMeshers_FaceSide::GetFaceWires( F, theMesh, /*ignoreMediumNodes=*/false,
+                                                         err, &helper);
   if ( err && !err->IsOK() )
     return error( err );
 
index 9c11691..eeb20f0 100644 (file)
@@ -426,6 +426,7 @@ namespace {
                   const TopoDS_Face&                 srcFace,
                   SMESH_Mesh *                       tgtMesh,
                   SMESH_Mesh *                       srcMesh,
+                  SMESH_MesherHelper*                tgtHelper,
                   const TAssocTool::TShapeShapeMap&  shape2ShapeMap,
                   TSideVector&                       srcWires,
                   TSideVector&                       tgtWires,
@@ -436,7 +437,7 @@ namespace {
 
     // get ordered src EDGEs
     TError err;
-    srcWires = StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*skipMediumNodes=*/0, err);
+    srcWires = StdMeshers_FaceSide::GetFaceWires( srcFace, *srcMesh,/*skipMediumNodes=*/0, err );
     if (( err && !err->IsOK() ) ||
         ( srcWires.empty() ))
       return err;
@@ -445,8 +446,6 @@ namespace {
          << tgtMesh->GetMeshDS()->ShapeToIndex( tgtFace ) << " <- "
          << srcMesh->GetMeshDS()->ShapeToIndex( srcFace ) << endl;
 #endif
-    SMESH_MesherHelper srcHelper( *srcMesh );
-    srcHelper.SetSubShape( srcFace );
 
     // make corresponding sequence of tgt EDGEs
     tgtWires.resize( srcWires.size() );
@@ -493,7 +492,8 @@ namespace {
 
       tgtWires[ iW ].reset( new StdMeshers_FaceSide( tgtFace, tgtEdges, tgtMesh,
                                                      /*theIsForward = */ true,
-                                                     /*theIgnoreMediumNodes = */false));
+                                                     /*theIgnoreMediumNodes = */false,
+                                                     tgtHelper ));
       StdMeshers_FaceSidePtr tgtWire = tgtWires[ iW ];
 
       // Fill map of src to tgt nodes with nodes on edges
@@ -517,9 +517,11 @@ namespace {
         else
         {
           const bool skipMedium = true, isFwd = true;
-          StdMeshers_FaceSide srcEdge( srcFace, srcWire->Edge(iE), srcMesh, isFwd, skipMedium);
-          StdMeshers_FaceSide tgtEdge( tgtFace, tgtWire->Edge(iE), tgtMesh, isFwd, skipMedium);
-          
+          StdMeshers_FaceSide srcEdge( srcFace, srcWire->Edge(iE),
+                                       srcMesh, isFwd, skipMedium, srcWires[0]->FaceHelper() );
+          StdMeshers_FaceSide tgtEdge( tgtFace, tgtWire->Edge(iE),
+                                       tgtMesh, isFwd, skipMedium, tgtHelper);
+
           vector< const SMDS_MeshNode* > srcNodes = srcEdge.GetOrderedNodes();
           vector< const SMDS_MeshNode* > tgtNodes = tgtEdge.GetOrderedNodes();
 
@@ -566,11 +568,11 @@ namespace {
                       TAssocTool::TNodeNodeMap&          src2tgtNodes,
                       const bool                         is1DComputed)
   {
-    SMESH_Mesh *    tgtMesh = tgtWires[0]->GetMesh();
-    SMESH_Mesh *    srcMesh = srcWires[0]->GetMesh();
-    SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
-    SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
-    SMESH_MesherHelper helper( *tgtMesh );
+    SMESH_Mesh *       tgtMesh = tgtWires[0]->GetMesh();
+    SMESH_Mesh *       srcMesh = srcWires[0]->GetMesh();
+    SMESHDS_Mesh*    tgtMeshDS = tgtMesh->GetMeshDS();
+    SMESHDS_Mesh*    srcMeshDS = srcMesh->GetMeshDS();
+    SMESH_MesherHelper* helper = tgtWires[0]->FaceHelper();
 
     const double tol = 1.e-7 * srcMeshDS->getMaxDim();
 
@@ -647,7 +649,7 @@ namespace {
                          0.123 * ( srcSurf.FirstVParameter() + srcSurf.LastVParameter() ));
         gp_Pnt tgtTrsfP = trsf.Transform( srcP );
         TopLoc_Location loc;
-        GeomAPI_ProjectPointOnSurf& proj = helper.GetProjector( tgtFace, loc, 0.1*tol );
+        GeomAPI_ProjectPointOnSurf& proj = helper->GetProjector( tgtFace, loc, 0.1*tol );
         if ( !loc.IsIdentity() )
           tgtTrsfP.Transform( loc.Transformation().Inverted() );
         proj.Perform( tgtTrsfP );
@@ -662,16 +664,14 @@ namespace {
     // Make new faces
 
     // prepare the helper to adding quadratic elements if necessary
-    //helper.SetSubShape( tgtFace );
-    helper.IsQuadraticSubMesh( tgtFace );
+    helper->IsQuadraticSubMesh( tgtFace );
 
     SMESHDS_SubMesh* srcSubDS = srcMeshDS->MeshElements( srcFace );
     if ( !is1DComputed && srcSubDS->NbElements() )
-      helper.SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() );
+      helper->SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() );
 
-    SMESH_MesherHelper srcHelper( *srcMesh );
-    srcHelper.SetSubShape( srcFace );
-    SMESH_MesherHelper edgeHelper( *tgtMesh );
+    SMESH_MesherHelper* srcHelper = srcWires[0]->FaceHelper();
+    SMESH_MesherHelper  edgeHelper( *tgtMesh );
     edgeHelper.ToFixNodeParameters( true );
 
     const SMDS_MeshNode* nullNode = 0;
@@ -690,7 +690,7 @@ namespace {
       const SMDS_MeshElement* elem = elemIt->next();
       const int nbN = elem->NbCornerNodes(); 
       tgtNodes.resize( nbN );
-      helper.SetElementsOnShape( false );
+      helper->SetElementsOnShape( false );
       for ( int i = 0; i < nbN; ++i ) // loop on nodes of the source element
       {
         const SMDS_MeshNode* srcNode = elem->GetNode(i);
@@ -699,21 +699,21 @@ namespace {
         {
           // create a new node
           gp_Pnt tgtP = trsf.Transform( SMESH_TNodeXYZ( srcNode ));
-          SMDS_MeshNode* n = helper.AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() );
+          SMDS_MeshNode* n = helper->AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() );
           srcN_tgtN->second = n;
           switch ( srcNode->GetPosition()->GetTypeOfPosition() )
           {
           case SMDS_TOP_FACE:
           {
-            gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode );
-            tgtMeshDS->SetNodeOnFace( n, helper.GetSubShapeID(), srcUV.X(), srcUV.Y() );
+            gp_Pnt2d srcUV = srcHelper->GetNodeUV( srcFace, srcNode );
+            tgtMeshDS->SetNodeOnFace( n, helper->GetSubShapeID(), srcUV.X(), srcUV.Y() );
             break;
           }
           case SMDS_TOP_EDGE:
           {
             const TopoDS_Edge& srcE = TopoDS::Edge( srcMeshDS->IndexToShape( srcNode->getshapeId()));
             const TopoDS_Edge& tgtE = TopoDS::Edge( shape2ShapeMap( srcE, /*isSrc=*/true ));
-            double srcU = srcHelper.GetNodeU( srcE, srcNode );
+            double srcU = srcHelper->GetNodeU( srcE, srcNode );
             tgtMeshDS->SetNodeOnEdge( n, tgtE, srcU );
             if ( !tgtFace.IsPartner( srcFace ))
             {
@@ -749,14 +749,14 @@ namespace {
         tgtNodes[i] = srcN_tgtN->second;
       }
       // create a new face
-      helper.SetElementsOnShape( true );
+      helper->SetElementsOnShape( true );
       switch ( nbN )
       {
-      case 3: helper.AddFace(tgtNodes[0], tgtNodes[tri1], tgtNodes[tri2]); break;
-      case 4: helper.AddFace(tgtNodes[0], tgtNodes[quad1], tgtNodes[2], tgtNodes[quad3]); break;
+      case 3: helper->AddFace(tgtNodes[0], tgtNodes[tri1], tgtNodes[tri2]); break;
+      case 4: helper->AddFace(tgtNodes[0], tgtNodes[quad1], tgtNodes[2], tgtNodes[quad3]); break;
       default:
         if ( isReverse ) std::reverse( tgtNodes.begin(), tgtNodes.end() );
-        helper.AddPolygonalFace( tgtNodes );
+        helper->AddPolygonalFace( tgtNodes );
       }
     }
 
@@ -764,7 +764,7 @@ namespace {
 
     if ( !tgtFace.IsPartner( srcFace ) )
     {
-      helper.ToFixNodeParameters( true );
+      helper->ToFixNodeParameters( true );
 
       int nbOkPos = 0;
       const double tol2d = 1e-12;
@@ -777,8 +777,8 @@ namespace {
         case SMDS_TOP_FACE:
         {
           if ( nbOkPos > 10 ) break;
-          gp_XY uv = helper.GetNodeUV( tgtFace, n ), uvBis = uv;
-          if (( helper.CheckNodeUV( tgtFace, n, uv, tol )) &&
+          gp_XY uv = helper->GetNodeUV( tgtFace, n ), uvBis = uv;
+          if (( helper->CheckNodeUV( tgtFace, n, uv, tol )) &&
               (( uv - uvBis ).SquareModulus() < tol2d ))
             ++nbOkPos;
           else
@@ -898,18 +898,16 @@ namespace {
 
     SMESHDS_SubMesh* srcSubDS = srcMesh->GetMeshDS()->MeshElements( srcFace );
 
-    SMESH_MesherHelper helper( *tgtMesh );
-    helper.SetSubShape( tgtFace );
+    SMESH_MesherHelper* helper = tgtWires[0]->FaceHelper();
     if ( is1DComputed )
-      helper.IsQuadraticSubMesh( tgtFace );
+      helper->IsQuadraticSubMesh( tgtFace );
     else
-      helper.SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() );
-    helper.SetElementsOnShape( true );
+      helper->SetIsQuadratic( srcSubDS->GetElements()->next()->IsQuadratic() );
+    helper->SetElementsOnShape( true );
     Handle(Geom_Surface) tgtSurface = BRep_Tool::Surface( tgtFace );
     SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
 
-    SMESH_MesherHelper srcHelper( *srcMesh );
-    srcHelper.SetSubShape( srcFace );
+    SMESH_MesherHelper* srcHelper = srcWires[0]->FaceHelper();
 
     const SMDS_MeshNode* nullNode = 0;
     TAssocTool::TNodeNodeMap::iterator srcN_tgtN;
@@ -920,7 +918,7 @@ namespace {
     while ( elemIt->more() ) // loop on all mesh faces on srcFace
     {
       const SMDS_MeshElement* elem = elemIt->next();
-      const int nbN = elem->NbCornerNodes(); 
+      const int nbN = elem->NbCornerNodes();
       tgtNodes.resize( nbN );
       for ( int i = 0; i < nbN; ++i ) // loop on nodes of the source element
       {
@@ -929,27 +927,27 @@ namespace {
         if ( srcN_tgtN->second == nullNode )
         {
           // create a new node
-          gp_Pnt2d srcUV = srcHelper.GetNodeUV( srcFace, srcNode,
-                                                elem->GetNode( helper.WrapIndex(i+1,nbN)), &uvOK);
+          gp_Pnt2d srcUV = srcHelper->GetNodeUV( srcFace, srcNode,
+                                                 elem->GetNode( helper->WrapIndex(i+1,nbN)), &uvOK);
           gp_Pnt2d   tgtUV = trsf.Transform( srcUV );
           gp_Pnt      tgtP = tgtSurface->Value( tgtUV.X(), tgtUV.Y() );
           SMDS_MeshNode* n = tgtMeshDS->AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() );
           switch ( srcNode->GetPosition()->GetTypeOfPosition() )
           {
           case SMDS_TOP_FACE: {
-            tgtMeshDS->SetNodeOnFace( n, helper.GetSubShapeID(), tgtUV.X(), tgtUV.Y() );
+            tgtMeshDS->SetNodeOnFace( n, helper->GetSubShapeID(), tgtUV.X(), tgtUV.Y() );
             break;
           }
           case SMDS_TOP_EDGE: {
-            TopoDS_Shape srcEdge = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() );
+            TopoDS_Shape srcEdge = srcHelper->GetSubShapeByNode( srcNode, srcHelper->GetMeshDS() );
             TopoDS_Edge  tgtEdge = TopoDS::Edge( shape2ShapeMap( srcEdge, /*isSrc=*/true ));
             double U = Precision::Infinite();
-            helper.CheckNodeU( tgtEdge, n, U, Precision::PConfusion());
+            helper->CheckNodeU( tgtEdge, n, U, Precision::PConfusion());
             tgtMeshDS->SetNodeOnEdge( n, TopoDS::Edge( tgtEdge ), U );
             break;
           }
           case SMDS_TOP_VERTEX: {
-            TopoDS_Shape srcV = srcHelper.GetSubShapeByNode( srcNode, srcHelper.GetMeshDS() );
+            TopoDS_Shape srcV = srcHelper->GetSubShapeByNode( srcNode, srcHelper->GetMeshDS() );
             TopoDS_Shape tgtV = shape2ShapeMap( srcV, /*isSrc=*/true );
             tgtMeshDS->SetNodeOnVertex( n, TopoDS::Vertex( tgtV ));
             break;
@@ -963,8 +961,8 @@ namespace {
       // create a new face (with reversed orientation)
       switch ( nbN )
       {
-      case 3: helper.AddFace(tgtNodes[0], tgtNodes[2], tgtNodes[1]); break;
-      case 4: helper.AddFace(tgtNodes[0], tgtNodes[3], tgtNodes[2], tgtNodes[1]); break;
+      case 3: helper->AddFace(tgtNodes[0], tgtNodes[2], tgtNodes[1]); break;
+      case 4: helper->AddFace(tgtNodes[0], tgtNodes[3], tgtNodes[2], tgtNodes[1]); break;
       }
     }  // loop on all mesh faces on srcFace
 
@@ -1082,8 +1080,7 @@ namespace {
 
     // // as all XY are computed, create tgt nodes and faces
 
-    // SMESH_MesherHelper helper( *tgtMesh );
-    // helper.SetSubShape( tgtFace );
+    // SMESH_MesherHelper helper = *tgtWires[0]->FaceHelper();
     // if ( is1DComputed )
     //   helper.IsQuadraticSubMesh( tgtFace );
     // else
@@ -1091,8 +1088,7 @@ namespace {
     // helper.SetElementsOnShape( true );
     // Handle(Geom_Surface) tgtSurface = BRep_Tool::Surface( tgtFace );
 
-    // SMESH_MesherHelper srcHelper( *srcMesh );
-    // srcHelper.SetSubShape( srcFace );
+    // SMESH_MesherHelper srcHelper = *srcWires[0]->FaceHelper();
 
     // vector< const SMDS_MeshNode* > tgtNodes;
     // gp_XY uv;
@@ -1541,7 +1537,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   // get ordered src and tgt EDGEs
   TSideVector srcWires, tgtWires;
   bool is1DComputed = false; // if any tgt EDGE is meshed
-  TError err = getWires( tgtFace, srcFace, tgtMesh, srcMesh,
+  TError err = getWires( tgtFace, srcFace, tgtMesh, srcMesh, &helper,
                          shape2ShapeMap, srcWires, tgtWires, _src2tgtNodes, is1DComputed );
   if ( err && !err->IsOK() )
     return error( err );
@@ -1935,7 +1931,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
     // boundary, also bad face can be created if EDGEs already discretized
     // --> fix bad faces by smoothing
     // ----------------------------------------------------------------
-    if ( helper.IsDistorted2D( tgtSubMesh, /*checkUV=*/false ))
+    if ( helper.IsDistorted2D( tgtSubMesh, /*checkUV=*/false, &helper ))
     {
       morph( helper, tgtFace, srcFace, tgtWires, srcWires, _src2tgtNodes );
 
index c7df8a3..a4d3ffb 100644 (file)
@@ -1384,10 +1384,13 @@ namespace
                    const SMESH_MAT2d::MedialAxis& theMA,
                    TMAPar2NPoints &               thePointsOnE )
   {
+    SMESH_Mesh*     mesh = theHelper.GetMesh();
+    SMESHDS_Mesh* meshDS = theHelper.GetMeshDS();
+
     list< TopoDS_Edge > ee1( theSinuFace._sinuSide [0].begin(), theSinuFace._sinuSide [0].end() );
     list< TopoDS_Edge > ee2( theSinuFace._sinuSide [1].begin(), theSinuFace._sinuSide [1].end() );
-    StdMeshers_FaceSide sideOut( theSinuFace.Face(), ee1, theHelper.GetMesh(), true, true );
-    StdMeshers_FaceSide sideIn ( theSinuFace.Face(), ee2, theHelper.GetMesh(), true, true );
+    StdMeshers_FaceSide sideOut( theSinuFace.Face(), ee1, mesh, true, true, &theHelper );
+    StdMeshers_FaceSide sideIn ( theSinuFace.Face(), ee2, mesh, true, true, &theHelper );
     const UVPtStructVec& uvsOut = sideOut.GetUVPtStruct();
     const UVPtStructVec& uvsIn  = sideIn.GetUVPtStruct();
     // if ( uvs1.size() != uvs2.size() )
@@ -1396,7 +1399,6 @@ namespace
     const SMESH_MAT2d::Branch& branch = *theMA.getBranch(0);
     SMESH_MAT2d::BoundaryPoint bp[2];
     SMESH_MAT2d::BranchPoint   brp;
-    SMESHDS_Mesh*              meshDS = theHelper.GetMeshDS();
 
     map< double, const SMDS_MeshNode* > nodeParams; // params of existing nodes
     map< double, const SMDS_MeshNode* >::iterator u2n;
@@ -1510,7 +1512,8 @@ namespace
     for ( int i = 0; i < 4; ++i )
     {
       theFace._quad->side[i] = StdMeshers_FaceSide::New( face, side[i], mesh, i < QUAD_TOP_SIDE,
-                                                         /*skipMediumNodes=*/true, proxyMesh );
+                                                         /*skipMediumNodes=*/true,
+                                                         &theHelper, proxyMesh );
     }
 
     if ( theFace.IsRing() )
@@ -1892,7 +1895,7 @@ namespace
           continue;
 
         StdMeshers_FaceSide side( face, theSinuEdges[i], mesh,
-                                  /*isFwd=*/true, /*skipMediumNodes=*/true );
+                                  /*isFwd=*/true, /*skipMediumNodes=*/true, &theHelper );
         vector<const SMDS_MeshNode*> nodes = side.GetOrderedNodes();
         for ( size_t in = 1; in < nodes.size(); ++in )
         {
index 8f909f2..ef472e4 100644 (file)
@@ -230,7 +230,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh&         aMesh,
   myNeedSmooth = false;
   myCheckOri   = false;
 
-  FaceQuadStruct::Ptr quad = CheckNbEdges( aMesh, F, /*considerMesh=*/true );
+  FaceQuadStruct::Ptr quad = CheckNbEdges( aMesh, F, /*considerMesh=*/true, myHelper );
   if (!quad)
     return false;
   myQuadList.clear();
@@ -1052,7 +1052,8 @@ static bool twoEdgesMeatAtVertex(const TopoDS_Edge& e1,
 
 FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh &         aMesh,
                                                            const TopoDS_Shape & aShape,
-                                                           const bool           considerMesh)
+                                                           const bool           considerMesh,
+                                                           SMESH_MesherHelper*  aFaceHelper)
 {
   if ( !myQuadList.empty() && myQuadList.front()->face.IsSame( aShape ))
     return myQuadList.front();
@@ -1071,6 +1072,7 @@ FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh &
   }
 
   // find corner vertices of the quad
+  myHelper = ( aFaceHelper && aFaceHelper->GetSubShape() == aShape ) ? aFaceHelper : NULL;
   vector<TopoDS_Vertex> corners;
   int nbDegenEdges, nbSides = getCorners( F, aMesh, edges, corners, nbDegenEdges, considerMesh );
   if ( nbSides == 0 )
@@ -1096,7 +1098,7 @@ FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh &
           sideEdges.push_back( *edgeIt++ );
       if ( !sideEdges.empty() )
         quad->side.push_back( StdMeshers_FaceSide::New(F, sideEdges, &aMesh, iSide < QUAD_TOP_SIDE,
-                                                       ignoreMediumNodes, myProxyMesh));
+                                                       ignoreMediumNodes, myHelper, myProxyMesh));
       else
         --iSide;
     }
@@ -1150,7 +1152,7 @@ FaceQuadStruct::Ptr StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh &
       {
         quad->side.push_back
           ( StdMeshers_FaceSide::New( F, sideEdges, &aMesh, iSide < QUAD_TOP_SIDE,
-                                      ignoreMediumNodes, myProxyMesh ));
+                                      ignoreMediumNodes, myHelper, myProxyMesh ));
         ++iSide;
       }
       if ( quad->side.size() == 4 )
@@ -4110,7 +4112,7 @@ bool StdMeshers_Quadrangle_2D::check()
   {
     TError err;
     TSideVector wireVec =
-      StdMeshers_FaceSide::GetFaceWires( geomFace, *myHelper->GetMesh(), true, err );
+      StdMeshers_FaceSide::GetFaceWires( geomFace, *myHelper->GetMesh(), true, err, myHelper );
     StdMeshers_FaceSidePtr wire = wireVec[0];
 
     // find a right angle VERTEX
@@ -4251,7 +4253,10 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face&          theFace,
   theNbDegenEdges = 0;
 
   SMESH_MesherHelper helper( theMesh );
-  StdMeshers_FaceSide faceSide( theFace, theWire, &theMesh, /*isFwd=*/true, /*skipMedium=*/true);
+  if ( myHelper )
+    helper.CopySubShapeInfo( *myHelper );
+  StdMeshers_FaceSide faceSide( theFace, theWire, &theMesh,
+                                /*isFwd=*/true, /*skipMedium=*/true, &helper );
 
   // sort theVertices by angle
   multimap<double, TopoDS_Vertex> vertexByAngle;
index fd40f12..a1938bd 100644 (file)
@@ -155,7 +155,8 @@ class STDMESHERS_EXPORT StdMeshers_Quadrangle_2D: public SMESH_2D_Algo
 
   FaceQuadStruct::Ptr CheckNbEdges(SMESH_Mesh&         aMesh,
                                    const TopoDS_Shape& aShape,
-                                   const bool          considerMesh=false);
+                                   const bool          considerMesh = false,
+                                   SMESH_MesherHelper* aFaceHelper = 0);
 
   static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll);
 
index ec3c297..dc57382 100644 (file)
@@ -208,7 +208,8 @@ namespace
                   SMESH_Mesh*             aMesh,
                   StdMeshers_FaceSidePtr& aCircSide,
                   StdMeshers_FaceSidePtr& aLinSide1,
-                  StdMeshers_FaceSidePtr& aLinSide2)
+                  StdMeshers_FaceSidePtr& aLinSide2,
+                  SMESH_MesherHelper*     helper)
   {
     const TopoDS_Face& face = TopoDS::Face( aShape );
     aCircSide.reset(); aLinSide1.reset(); aLinSide2.reset();
@@ -259,7 +260,7 @@ namespace
       StdMeshers_FaceSidePtr side;
       if ( aMesh ) 
         side = StdMeshers_FaceSide::New( face, sideEdges, aMesh,
-                                         /*isFwd=*/true, /*skipMedium=*/ true );
+                                         /*isFwd=*/true, /*skipMedium=*/ true, helper );
       sides.push_back( side );
     }
 
@@ -357,7 +358,7 @@ namespace
           edges.push_back( aCircSide->Edge( iE % aCircSide->NbEdges() ));
 
         aCircSide = StdMeshers_FaceSide::New( face, edges, aMesh,
-                                              /*isFwd=*/true, /*skipMedium=*/ true );
+                                              /*isFwd=*/true, /*skipMedium=*/ true, helper );
       }
     }
 
@@ -773,8 +774,11 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh&         aMesh,
   StdMeshers_Quadrangle_2D::myCheckOri   = false;
   StdMeshers_Quadrangle_2D::myQuadList.clear();
 
+  myHelper->SetSubShape( aShape );
+  myHelper->SetElementsOnShape( true );
+
   StdMeshers_FaceSidePtr circSide, linSide1, linSide2;
-  int nbSides = analyseFace( aShape, &aMesh, circSide, linSide1, linSide2 );
+  int nbSides = analyseFace( aShape, &aMesh, circSide, linSide1, linSide2, myHelper );
   if( nbSides > 3 || nbSides < 1 )
     return error("The face must be a full ellipse or a part of ellipse (i.e. the number "
                  "of edges is less or equal to 3 and one of them is an ellipse curve)");
@@ -797,7 +801,6 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh&         aMesh,
   Handle(Geom_Surface) S = BRep_Tool::Surface(F);
 
   myHelper->IsQuadraticSubMesh( aShape );
-  myHelper->SetElementsOnShape( true );
 
   vector< double > layerPositions; // [0,1]
 
@@ -811,7 +814,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh&         aMesh,
     TopoDS_Edge linEdge = makeEdgeToCenter( circSide, F, circNode );
 
     StdMeshers_FaceSidePtr tmpSide =
-      StdMeshers_FaceSide::New( F, linEdge, &aMesh, /*isFrw=*/true, /*skipMedium=*/true );
+      StdMeshers_FaceSide::New( F, linEdge, &aMesh, /*isFrw=*/true, /*skipMedium=*/true, myHelper );
 
     if ( !computeLayerPositions( tmpSide, layerPositions ))
       return false;
@@ -855,7 +858,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh&         aMesh,
       isVIn0Shared = vIn0.IsSame( circSide->FirstVertex( iE ));
 
     linSide1 = StdMeshers_FaceSide::New( F, edges, &aMesh,
-                                         /*isFrw=*/isVIn0Shared, /*skipMedium=*/true );
+                                         /*isFrw=*/isVIn0Shared, /*skipMedium=*/true, myHelper );
 
     int nbMeshedEdges;
     if ( !computeLayerPositions( linSide1, layerPositions, &nbMeshedEdges ))
@@ -1105,7 +1108,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Evaluate(SMESH_Mesh&         aMesh,
   TNodeDistributor* algo1d = TNodeDistributor::GetDistributor(aMesh);
 
   StdMeshers_FaceSidePtr circSide, linSide1, linSide2;
-  int nbSides = analyseFace( aShape, &aMesh, circSide, linSide1, linSide2 );
+  int nbSides = analyseFace( aShape, &aMesh, circSide, linSide1, linSide2, myHelper );
   if( nbSides > 3 || nbSides < 1 )
     return false;
 
@@ -1123,7 +1126,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::Evaluate(SMESH_Mesh&         aMesh,
     TopoDS_Edge linEdge = makeEdgeToCenter( circSide, F, circNode );
 
     StdMeshers_FaceSidePtr tmpSide =
-      StdMeshers_FaceSide::New( F, linEdge, &aMesh, /*isFrw=*/true, /*skipMedium=*/true );
+      StdMeshers_FaceSide::New( F, linEdge, &aMesh, /*isFrw=*/true, /*skipMedium=*/true, myHelper );
 
     if ( !computeLayerPositions( tmpSide, layerPositions ))
       return false;
@@ -1220,7 +1223,7 @@ bool StdMeshers_RadialQuadrangle_1D2D::IsApplicable( const TopoDS_Shape & aShape
   for (TopExp_Explorer exp( aShape, TopAbs_FACE ); exp.More(); exp.Next(), ++nbFoundFaces )
   {
     StdMeshers_FaceSidePtr circSide, linSide1, linSide2;
-    int nbSides = analyseFace( exp.Current(), NULL, circSide, linSide1, linSide2 );
+    int nbSides = analyseFace( exp.Current(), NULL, circSide, linSide1, linSide2, NULL );
     bool ok = ( 0 < nbSides && nbSides <= 3 &&
                 isCornerInsideCircle( circSide, linSide1, linSide2 ));
     if( toCheckAll  && !ok ) return false;
index af66439..ecd62ab 100644 (file)
@@ -585,7 +585,7 @@ StdMeshers_ViscousLayers2D::CheckHypothesis(SMESH_Mesh&
       VISCOUS_2D::_ViscousBuilder2D builder( theMesh, face, hyps, hypShapes );
       builder._faceSideVec =
         StdMeshers_FaceSide::GetFaceWires( face, theMesh, true, error,
-                                           SMESH_ProxyMesh::Ptr(),
+                                           NULL, SMESH_ProxyMesh::Ptr(),
                                            /*theCheckVertexNodes=*/false);
       if ( error->IsOK() && !builder.findEdgesWithLayers())
       {
@@ -686,7 +686,7 @@ bool _ViscousBuilder2D::error(const string& text )
 
 SMESH_ProxyMesh::Ptr _ViscousBuilder2D::Compute()
 {
-  _faceSideVec = StdMeshers_FaceSide::GetFaceWires( _face, *_mesh, true, _error);
+  _faceSideVec = StdMeshers_FaceSide::GetFaceWires( _face, *_mesh, true, _error, &_helper );
 
   if ( !_error->IsOK() )
     return _proxyMesh;