Salome HOME
Fix regressions caused by improvements
authoreap <eap@opencascade.com>
Wed, 5 Aug 2015 17:59:31 +0000 (20:59 +0300)
committereap <eap@opencascade.com>
Wed, 5 Aug 2015 17:59:31 +0000 (20:59 +0300)
doc/salome/gui/SMESH/images/sew_after_merge.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/sew_using_merge.png [new file with mode: 0644]
doc/salome/gui/SMESH/input/sewing_meshes.doc
src/SMESHDS/SMESHDS_SubMesh.cxx
src/SMESHDS/SMESHDS_SubMesh.hxx
src/SMESH_SWIG/smesh_algorithm.py
src/StdMeshers/StdMeshers_FaceSide.cxx
src/StdMeshers/StdMeshers_Projection_2D.cxx
src/StdMeshers/StdMeshers_Quadrangle_2D.cxx

diff --git a/doc/salome/gui/SMESH/images/sew_after_merge.png b/doc/salome/gui/SMESH/images/sew_after_merge.png
new file mode 100644 (file)
index 0000000..43d6869
Binary files /dev/null and b/doc/salome/gui/SMESH/images/sew_after_merge.png differ
diff --git a/doc/salome/gui/SMESH/images/sew_using_merge.png b/doc/salome/gui/SMESH/images/sew_using_merge.png
new file mode 100644 (file)
index 0000000..80cc44c
Binary files /dev/null and b/doc/salome/gui/SMESH/images/sew_using_merge.png differ
index ad5f15e65f5eda18e608abea4b3be6a9c4a2243e..b7640f30b868c530b4bb4705614407a9c43050b2 100644 (file)
@@ -53,8 +53,12 @@ the opposite border.
 In practice the borders to sew often coincide and in this case it is
 difficult to specify the first and the last nodes of a border since
 they coincide with the first and the last nodes of the other
 In practice the borders to sew often coincide and in this case it is
 difficult to specify the first and the last nodes of a border since
 they coincide with the first and the last nodes of the other
-border. To cope with this, manually \ref merging_nodes_page to fuse
-each pair of coincident nodes into one.
+border. To cope with this,
+\ref merging_nodes_page "merge" coincident nodes into one
+beforehand. Two figures below illustrate this approach.
+\image html sew_using_merge.png "Merge coincident nodes which are difficult to distinguish"
+<br>
+\image html sew_after_merge.png "After merging nodes it is easy to specify border nodes"
 
 The sewing algorithm is as follows:
 <ol>
 
 The sewing algorithm is as follows:
 <ol>
index f06ec6e315433c8f6a4472d2cd0968ef15068805..04a0021fc0fc2ef501ec1209d7c075c485fe3e8f 100644 (file)
@@ -46,8 +46,6 @@ using namespace std;
 SMESHDS_SubMesh::SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index)
 {
   myParent = parent;
 SMESHDS_SubMesh::SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index)
 {
   myParent = parent;
-  myElements.clear();
-  myNodes.clear();
   myIndex = index;
   myUnusedIdNodes = 0;
   myUnusedIdElements = 0;
   myIndex = index;
   myUnusedIdNodes = 0;
   myUnusedIdElements = 0;
@@ -65,61 +63,54 @@ SMESHDS_SubMesh::~SMESHDS_SubMesh()
 
 //=======================================================================
 //function : AddElement
 
 //=======================================================================
 //function : AddElement
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME)
 {
   if (!IsComplexSubmesh())
 //=======================================================================
 
 void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME)
 {
   if (!IsComplexSubmesh())
+  {
+    if ( ME->GetType() == SMDSAbs_Node )
+    {
+      AddNode( static_cast< const SMDS_MeshNode* >( ME ));
+      return;
+    }
+    int oldShapeId = ME->getshapeId();
+    if ( oldShapeId > 0 )
     {
     {
-      if ( ME->GetType() == SMDSAbs_Node )
+      if (oldShapeId != myIndex)
       {
       {
-        AddNode( static_cast< const SMDS_MeshNode* >( ME ));
-        return;
+        throw SALOME_Exception
+          (LOCALIZED("add element in subshape already belonging to a subshape"));
       }
       }
-      int oldShapeId = ME->getshapeId();
-      if ( oldShapeId > 0 )
+      int idInSubShape = ME->getIdInShape();
+      if (idInSubShape >= 0)
+      {
+        MESSAGE("add element in subshape already belonging to that subshape "
+                << ME->GetID() << " " << oldShapeId << " " << idInSubShape);
+        // check if ok: do nothing if ok
+        if (idInSubShape >= myElements.size())
         {
         {
-          if (oldShapeId != myIndex)
-            {
-              MESSAGE("add element in subshape already belonging to another subshape "
-                << ME->GetID() << " " << oldShapeId << " " << myIndex);
-              throw SALOME_Exception(LOCALIZED("add element in subshape already belonging to a subshape"));
-            }
-          else
-            {
-              int idInSubShape = ME->getIdInShape();
-              if (idInSubShape >= 0)
-                {
-                  MESSAGE("add element in subshape already belonging to that subshape "
-                      << ME->GetID() << " " << oldShapeId << " " << idInSubShape);
-                  // check if ok: do nothing if ok
-                  if (idInSubShape >= myElements.size())
-                    {
-                      MESSAGE("out of bounds " << idInSubShape << " " << myElements.size());
-                      throw SALOME_Exception(LOCALIZED("out of bounds"));
-                    }
-                  if (ME != myElements[idInSubShape])
-                    {
-                      MESSAGE("not the same element");
-                      throw SALOME_Exception(LOCALIZED("not the same element"));
-                    }
-                  MESSAGE("already done, OK, nothing to do");
-                  return;
-                }
-            }
+          throw SALOME_Exception(LOCALIZED("out of bounds"));
         }
         }
-
-      SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME);
-      elem->setShapeId(myIndex);
-      elem->setIdInShape(myElements.size());
-      myElements.push_back(ME);
+        if (ME != myElements[idInSubShape])
+        {
+          throw SALOME_Exception(LOCALIZED("not the same element"));
+        }
+        return;
+      }
     }
     }
+
+    SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME);
+    elem->setShapeId(myIndex);
+    elem->setIdInShape(myElements.size());
+    myElements.push_back(ME);
+  }
 }
 
 //=======================================================================
 //function : RemoveElement
 }
 
 //=======================================================================
 //function : RemoveElement
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDeleted)
 //=======================================================================
 
 bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDeleted)
@@ -183,7 +174,7 @@ void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
 
 //=======================================================================
 //function : RemoveNode
 
 //=======================================================================
 //function : RemoveNode
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted)
 //=======================================================================
 
 bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted)
@@ -385,29 +376,52 @@ bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const
   if (!ME)
     return false;
 
   if (!ME)
     return false;
 
-  if (IsComplexSubmesh())
-    {
-      set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
-      for (; aSubIt != mySubMeshes.end(); aSubIt++)
-        if ((*aSubIt)->Contains(ME))
-          return true;
-      return false;
-    }
+  if ( IsComplexSubmesh() )
+  {
+    set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
+    for (; aSubIt != mySubMeshes.end(); aSubIt++)
+      if ((*aSubIt)->Contains(ME))
+        return true;
+    return false;
+  }
 
   if (ME->GetType() == SMDSAbs_Node)
 
   if (ME->GetType() == SMDSAbs_Node)
-    {
-      int idInShape = ME->getIdInShape();
-      if ((idInShape >= 0) && (idInShape < myNodes.size()))
-        if (myNodes[idInShape] == ME)
-          return true;
-    }
+  {
+    int idInShape = ME->getIdInShape();
+    if ((idInShape >= 0) && (idInShape < myNodes.size()))
+      if (myNodes[idInShape] == ME)
+        return true;
+  }
   else
   else
-    {
-      int idInShape = ME->getIdInShape();
-      if ((idInShape >= 0) && (idInShape < myElements.size()))
-        if (myElements[idInShape] == ME)
-          return true;
-    }
+  {
+    int idInShape = ME->getIdInShape();
+    if ((idInShape >= 0) && (idInShape < myElements.size()))
+      if (myElements[idInShape] == ME)
+        return true;
+  }
+  return false;
+}
+
+//=======================================================================
+//function : IsQuadratic
+//purpose  : Return true if my 1st element is quadratic
+//=======================================================================
+
+bool SMESHDS_SubMesh::IsQuadratic() const
+{
+  if ( IsComplexSubmesh() )
+  {
+    set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
+    for (; aSubIt != mySubMeshes.end(); aSubIt++)
+      if ((*aSubIt)->IsQuadratic())
+        return true;
+    return false;
+  }
+
+  for ( size_t i = 0; i < myElements.size(); ++i )
+    if ( myElements[i] )
+      return myElements[i]->IsQuadratic();
+
   return false;
 }
 
   return false;
 }
 
index 3460b8cdb61db4777a1667236b6cab309c26cde2..c70857c6028dbb30952e6fa6671643a764a11e23 100644 (file)
@@ -67,19 +67,20 @@ class SMESHDS_EXPORT SMESHDS_SubMesh
   virtual int NbNodes() const;
   virtual SMDS_NodeIteratorPtr GetNodes() const;
   virtual bool Contains(const SMDS_MeshElement * ME) const;      // check if elem or node is in
   virtual int NbNodes() const;
   virtual SMDS_NodeIteratorPtr GetNodes() const;
   virtual bool Contains(const SMDS_MeshElement * ME) const;      // check if elem or node is in
+  virtual bool IsQuadratic() const;
 
   // clear the contents
   virtual void Clear();
 
   // clear the contents
   virtual void Clear();
-  int getSize();
+  int  getSize();
   void compactList();
 
   SMESHDS_Mesh* GetParent() const { return const_cast< SMESHDS_Mesh*>( myParent ); }
   int           GetID()     const { return myIndex; }
 
  private:
   void compactList();
 
   SMESHDS_Mesh* GetParent() const { return const_cast< SMESHDS_Mesh*>( myParent ); }
   int           GetID()     const { return myIndex; }
 
  private:
-  SMESHDS_Mesh * myParent;
+  SMESHDS_Mesh *                       myParent;
   std::vector<const SMDS_MeshElement*> myElements;
   std::vector<const SMDS_MeshElement*> myElements;
-  std::vector<const SMDS_MeshNode*> myNodes;
+  std::vector<const SMDS_MeshNode*>    myNodes;
 
   int myUnusedIdNodes;
   int myUnusedIdElements;
 
   int myUnusedIdNodes;
   int myUnusedIdElements;
index df027244b26b8f67a01cb5943e83e1564af2ff3a..9481ff1d743df8a849b48b320e8964176140c751 100644 (file)
@@ -287,8 +287,11 @@ class Mesh_Algorithm:
         if not "ViscousLayers" in self.GetCompatibleHypothesis():
             raise TypeError, "ViscousLayers are not supported by %s"%self.algo.GetName()
         if faces and isinstance( faces[0], geomBuilder.GEOM._objref_GEOM_Object ):
         if not "ViscousLayers" in self.GetCompatibleHypothesis():
             raise TypeError, "ViscousLayers are not supported by %s"%self.algo.GetName()
         if faces and isinstance( faces[0], geomBuilder.GEOM._objref_GEOM_Object ):
-            import GEOM
-            faceIDs = [self.mesh.geompyD.GetSubShapeID(self.mesh.geom, f) for f in faces]
+            faceIDs = []
+            for shape in faces:
+                ff = self.mesh.geompyD.SubShapeAll( shape, self.mesh.geompyD.ShapeType["FACE"] )
+                for f in ff:
+                    faceIDs.append( self.mesh.geompyD.GetSubShapeID(self.mesh.geom, f))
             faces = faceIDs
         hyp = self.Hypothesis("ViscousLayers",
                               [thickness, numberOfLayers, stretchFactor, faces, isFacesToIgnore],
             faces = faceIDs
         hyp = self.Hypothesis("ViscousLayers",
                               [thickness, numberOfLayers, stretchFactor, faces, isFacesToIgnore],
@@ -320,7 +323,12 @@ class Mesh_Algorithm:
         if not "ViscousLayers2D" in self.GetCompatibleHypothesis():
             raise TypeError, "ViscousLayers2D are not supported by %s"%self.algo.GetName()
         if edges and isinstance( edges[0], geomBuilder.GEOM._objref_GEOM_Object ):
         if not "ViscousLayers2D" in self.GetCompatibleHypothesis():
             raise TypeError, "ViscousLayers2D are not supported by %s"%self.algo.GetName()
         if edges and isinstance( edges[0], geomBuilder.GEOM._objref_GEOM_Object ):
-            edges = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, f) for f in edges ]
+            edgeIDs = []
+            for shape in edges:
+                ee = self.mesh.geompyD.SubShapeAll( shape, self.mesh.geompyD.ShapeType["EDGE"])
+                for e in ee:
+                    edgeIDs.append( self.mesh.geompyD.GetSubShapeID( self.mesh.geom, e ))
+            edges = edgeIDs
         hyp = self.Hypothesis("ViscousLayers2D",
                               [thickness, numberOfLayers, stretchFactor, edges, isEdgesToIgnore],
                               toAdd=False)
         hyp = self.Hypothesis("ViscousLayers2D",
                               [thickness, numberOfLayers, stretchFactor, edges, isEdgesToIgnore],
                               toAdd=False)
index 377a79c5d2e907bc4de64ea09ab44d69624eb17d..d1d20245d4858158eaccc04221b357aefba97717 100644 (file)
@@ -311,7 +311,9 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool   isXConst,
 
     StdMeshers_FaceSide* me = const_cast< StdMeshers_FaceSide* >( this );
     SMESHDS_Mesh*    meshDS = myProxyMesh->GetMeshDS();
 
     StdMeshers_FaceSide* me = const_cast< StdMeshers_FaceSide* >( this );
     SMESHDS_Mesh*    meshDS = myProxyMesh->GetMeshDS();
-    SMESH_MesherHelper helper( *myProxyMesh->GetMesh() );
+    SMESH_MesherHelper eHelper( *myProxyMesh->GetMesh() );
+    SMESH_MesherHelper fHelper( *myProxyMesh->GetMesh() );
+    fHelper.SetSubShape( myFace );
     bool paramOK;
     double eps = 1e-100;
 
     bool paramOK;
     double eps = 1e-100;
 
@@ -346,7 +348,8 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool   isXConst,
       const double  prevNormPar = ( iE == 0 ? 0 : myNormPar[ iE-1 ]); // normalized param
       if ( node ) // nodes on internal vertices may be missing
       {
       const double  prevNormPar = ( iE == 0 ? 0 : myNormPar[ iE-1 ]); // normalized param
       if ( node ) // nodes on internal vertices may be missing
       {
-        if ( vertexNodes.insert( node ).second )
+        if ( vertexNodes.insert( node ).second ||
+             fHelper.IsRealSeam( node->getshapeId() ))
           u2node.insert( u2node.end(), make_pair( prevNormPar, node ));
       }
       else if ( iE == 0 )
           u2node.insert( u2node.end(), make_pair( prevNormPar, node ));
       }
       else if ( iE == 0 )
@@ -373,12 +376,12 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool   isXConst,
         u2nodeVec.clear();
         double paramSize = myLast[iE] - myFirst[iE];
         double r         = myNormPar[iE] - prevNormPar;
         u2nodeVec.clear();
         double paramSize = myLast[iE] - myFirst[iE];
         double r         = myNormPar[iE] - prevNormPar;
-        helper.SetSubShape( myEdge[iE] );
-        helper.ToFixNodeParameters( true );
+        eHelper.SetSubShape( myEdge[iE] );
+        eHelper.ToFixNodeParameters( true );
         if ( !myIsUniform[iE] )
           for ( size_t i = 0; i < nodes.size(); ++i )
           {
         if ( !myIsUniform[iE] )
           for ( size_t i = 0; i < nodes.size(); ++i )
           {
-            double     u = helper.GetNodeU( myEdge[iE], nodes[i], 0, &paramOK );
+            double     u = eHelper.GetNodeU( myEdge[iE], nodes[i], 0, &paramOK );
             double aLenU = GCPnts_AbscissaPoint::Length( me->myC3dAdaptor[iE], myFirst[iE], u );
             if ( myEdgeLength[iE] < aLenU ) // nonregression test "3D_mesh_NETGEN/G6"
             {
             double aLenU = GCPnts_AbscissaPoint::Length( me->myC3dAdaptor[iE], myFirst[iE], u );
             if ( myEdgeLength[iE] < aLenU ) // nonregression test "3D_mesh_NETGEN/G6"
             {
@@ -391,7 +394,7 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool   isXConst,
         if ( u2nodeVec.empty() )
           for ( size_t i = 0; i < nodes.size(); ++i )
           {
         if ( u2nodeVec.empty() )
           for ( size_t i = 0; i < nodes.size(); ++i )
           {
-            double u = helper.GetNodeU( myEdge[iE], nodes[i], 0, &paramOK );
+            double u = eHelper.GetNodeU( myEdge[iE], nodes[i], 0, &paramOK );
             // paramSize is signed so orientation is taken into account
             double normPar = prevNormPar + r * ( u - myFirst[iE] ) / paramSize;
             u2nodeVec.push_back( make_pair( normPar, nodes[i] ));
             // paramSize is signed so orientation is taken into account
             double normPar = prevNormPar + r * ( u - myFirst[iE] ) / paramSize;
             u2nodeVec.push_back( make_pair( normPar, nodes[i] ));
@@ -401,10 +404,11 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool   isXConst,
       }
     } // loop on myEdge's
 
       }
     } // loop on myEdge's
 
-    if ( u2node.empty() ) return myPoints;
-
     // Add 2nd VERTEX node for a last EDGE
     // Add 2nd VERTEX node for a last EDGE
+    if ( !proxySubMesh.back() )
     {
     {
+      if ( u2node.empty() ) return myPoints;
+
       const SMDS_MeshNode* node;
       if ( IsClosed() )
         node = u2node.begin()->second;
       const SMDS_MeshNode* node;
       if ( IsClosed() )
         node = u2node.begin()->second;
@@ -576,7 +580,9 @@ std::vector<const SMDS_MeshNode*> StdMeshers_FaceSide::GetOrderedNodes(int theEd
     if ( NbEdges() == 0 ) return resultNodes;
 
     SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS();
     if ( NbEdges() == 0 ) return resultNodes;
 
     SMESHDS_Mesh* meshDS = myProxyMesh->GetMeshDS();
-    SMESH_MesherHelper helper(*myProxyMesh->GetMesh());
+    SMESH_MesherHelper eHelper( *myProxyMesh->GetMesh() );
+    SMESH_MesherHelper fHelper( *myProxyMesh->GetMesh() );
+    fHelper.SetSubShape( myFace );
     bool paramOK = true;
 
     // Sort nodes of all edges putting them into a map
     bool paramOK = true;
 
     // Sort nodes of all edges putting them into a map
@@ -606,7 +612,8 @@ std::vector<const SMDS_MeshNode*> StdMeshers_FaceSide::GetOrderedNodes(int theEd
       // Add 1st vertex node of a current EDGE
       const SMDS_MeshNode* node = VertexNode( iE );
       if ( node ) { // nodes on internal vertices may be missing
       // Add 1st vertex node of a current EDGE
       const SMDS_MeshNode* node = VertexNode( iE );
       if ( node ) { // nodes on internal vertices may be missing
-        if ( vertexNodes.insert( node ).second )
+        if ( vertexNodes.insert( node ).second ||
+             fHelper.IsRealSeam( node->getshapeId() ))
           u2node.insert( make_pair( prevNormPar, node ));
       }
       else if ( iE == 0 )
           u2node.insert( make_pair( prevNormPar, node ));
       }
       else if ( iE == 0 )
@@ -632,11 +639,11 @@ std::vector<const SMDS_MeshNode*> StdMeshers_FaceSide::GetOrderedNodes(int theEd
       {
         double paramSize = myLast[iE] - myFirst[iE];
         double r         = myNormPar[iE] - prevNormPar;
       {
         double paramSize = myLast[iE] - myFirst[iE];
         double r         = myNormPar[iE] - prevNormPar;
-        helper.SetSubShape( myEdge[iE] );
-        helper.ToFixNodeParameters( true );
+        eHelper.SetSubShape( myEdge[iE] );
+        eHelper.ToFixNodeParameters( true );
         for ( size_t i = 0; i < nodes.size(); ++i )
         {
         for ( size_t i = 0; i < nodes.size(); ++i )
         {
-          double u = helper.GetNodeU( myEdge[iE], nodes[i], 0, &paramOK );
+          double u = eHelper.GetNodeU( myEdge[iE], nodes[i], 0, &paramOK );
           // paramSize is signed so orientation is taken into account
           double normPar = prevNormPar + r * ( u - myFirst[iE] ) / paramSize;
           u2node.insert( u2node.end(), make_pair( normPar, nodes[i] ));
           // paramSize is signed so orientation is taken into account
           double normPar = prevNormPar + r * ( u - myFirst[iE] ) / paramSize;
           u2node.insert( u2node.end(), make_pair( normPar, nodes[i] ));
@@ -707,9 +714,8 @@ bool StdMeshers_FaceSide::GetEdgeNodes(size_t                        i,
 
   if ( inlude1stVertex )
   {
 
   if ( inlude1stVertex )
   {
-    const SMDS_MeshNode* n0 = VertexNode( i );
-    if ( !n0 ) return false;
-    nodes.push_back( n0 );
+    if ( const SMDS_MeshNode* n0 = VertexNode( i ))
+      nodes.push_back( n0 );
   }
 
   if ( sm && ( sm->NbElements() > 0 || sm->NbNodes() > 0 ))
   }
 
   if ( sm && ( sm->NbElements() > 0 || sm->NbNodes() > 0 ))
@@ -764,9 +770,8 @@ bool StdMeshers_FaceSide::GetEdgeNodes(size_t                        i,
 
   if ( inludeLastVertex )
   {
 
   if ( inludeLastVertex )
   {
-    const SMDS_MeshNode* n1 = VertexNode( i+1 );
-    if ( !n1 ) return false;
-    nodes.push_back( n1 );
+    if ( const SMDS_MeshNode* n1 = VertexNode( i+1 ))
+      nodes.push_back( n1 );
   }
   return true;
 }
   }
   return true;
 }
@@ -943,27 +948,43 @@ int StdMeshers_FaceSide::NbPoints(const bool update) const
     me->myNbSegments = 0;
     me->myMissingVertexNodes = false;
 
     me->myNbSegments = 0;
     me->myMissingVertexNodes = false;
 
+    vector<const SMDS_MeshNode*> nodes;
     for ( int i = 0; i < NbEdges(); ++i )
     {
     for ( int i = 0; i < NbEdges(); ++i )
     {
-      if ( const SMESHDS_SubMesh* sm = myProxyMesh->GetSubMesh( Edge(i) )) {
-        int nbN = sm->NbNodes();
-        if ( sm->NbElements() > 0 ) {
-          nbN = sm->NbElements() - 1; // nodes can be moved to other shapes by MergeNodes()
-          if ( !myIgnoreMediumNodes &&
-               sm->GetElements()->next()->IsQuadratic() )
-            nbN += sm->NbElements();
+      if ( const SMESHDS_SubMesh* sm = myProxyMesh->GetSubMesh( Edge(i) ))
+      {
+        if ( sm->NbNodes() == sm->NbElements() - 1 )
+        {
+          me->myNbPonits += sm->NbNodes();
+          if ( myIgnoreMediumNodes && sm->IsQuadratic() )
+            me->myNbPonits -= sm->NbElements();
+        }
+        else // nodes can be moved to other shapes by MergeNodes()
+        {
+          nodes.clear();
+          GetEdgeNodes( i, nodes, /*v1=*/false, /*v2=*/false );
+          me->myNbPonits += nodes.size();
         }
         }
-        me->myNbPonits   += nbN;
         me->myNbSegments += sm->NbElements();
       }
     }
 
         me->myNbSegments += sm->NbElements();
       }
     }
 
+    SMESH_MesherHelper helper( *myProxyMesh->GetMesh() );
+    helper.SetSubShape( myFace );
+
     std::set< const SMDS_MeshNode* > vNodes;
     std::set< const SMDS_MeshNode* > vNodes;
-    for ( int i = 0; i <= NbEdges(); ++i )
+    for ( int i = 0; i <= NbEdges(); ++i ) // nb VERTEXes is more than NbEdges() if !IsClosed()
       if ( const SMDS_MeshNode* n = VertexNode( i ))
       if ( const SMDS_MeshNode* n = VertexNode( i ))
-        vNodes.insert( n );
+      {
+        if ( !vNodes.insert( n ).second &&
+             helper.IsRealSeam( n->getshapeId() ) &&
+             i < NbEdges())
+          me->myNbPonits++;
+      }
       else
       else
+      {
         me->myMissingVertexNodes = true;
         me->myMissingVertexNodes = true;
+      }
     me->myNbPonits += vNodes.size();
 
     if ( IsClosed() )
     me->myNbPonits += vNodes.size();
 
     if ( IsClosed() )
index d038ded9f827a5182fe83cfb54058cf3e6ee098b..87572c18f40434ceaa3e70cdc6b57de13e21dd5b 100644 (file)
@@ -513,18 +513,18 @@ namespace {
           if ( !tgtNodes.empty() )
           {
             vector< const SMDS_MeshNode* >::iterator tn = tgtNodes.begin();
           if ( !tgtNodes.empty() )
           {
             vector< const SMDS_MeshNode* >::iterator tn = tgtNodes.begin();
-            if ( srcWire->Edge(iE).Orientation() == tgtWire->Edge(iE).Orientation() )
+            //if ( srcWire->Edge(iE).Orientation() == tgtWire->Edge(iE).Orientation() )
             {
               vector< const SMDS_MeshNode* >::iterator sn = srcNodes.begin();
               for ( ; tn != tgtNodes.end(); ++tn, ++sn)
                 src2tgtNodes.insert( make_pair( *sn, *tn ));
             }
             {
               vector< const SMDS_MeshNode* >::iterator sn = srcNodes.begin();
               for ( ; tn != tgtNodes.end(); ++tn, ++sn)
                 src2tgtNodes.insert( make_pair( *sn, *tn ));
             }
-            else
-            {
-              vector< const SMDS_MeshNode* >::reverse_iterator sn = srcNodes.rbegin();
-              for ( ; tn != tgtNodes.end(); ++tn, ++sn)
-                src2tgtNodes.insert( make_pair( *sn, *tn ));
-            }
+            // else
+            // {
+            //   vector< const SMDS_MeshNode* >::reverse_iterator sn = srcNodes.rbegin();
+            //   for ( ; tn != tgtNodes.end(); ++tn, ++sn)
+            //     src2tgtNodes.insert( make_pair( *sn, *tn ));
+            // }
             is1DComputed = true;
           }
         }
             is1DComputed = true;
           }
         }
index 30c91c4cdf366945808b72e67002e500b2730a92..c173428be1f6a2d2e9875c82b634083a4fdbf74f 100644 (file)
@@ -4276,9 +4276,12 @@ int StdMeshers_Quadrangle_2D::getCorners(const TopoDS_Face&          theFace,
     return error(COMPERR_BAD_SHAPE,
                  TComm("Face must have 4 sides but not ") << faceSide.NbEdges() );
 
     return error(COMPERR_BAD_SHAPE,
                  TComm("Face must have 4 sides but not ") << faceSide.NbEdges() );
 
-  const int nbSegments = Max( faceSide.NbPoints()-1, faceSide.NbSegments() );
-  if ( nbSegments < nbCorners )
-    return error(COMPERR_BAD_INPUT_MESH, TComm("Too few boundary nodes: ") << nbSegments);
+  if ( theConsiderMesh )
+  {
+    const int nbSegments = Max( faceSide.NbPoints()-1, faceSide.NbSegments() );
+    if ( nbSegments < nbCorners )
+      return error(COMPERR_BAD_INPUT_MESH, TComm("Too few boundary nodes: ") << nbSegments);
+  }
 
   if ( nbCorners == 3 )
   {
 
   if ( nbCorners == 3 )
   {