Salome HOME
merge from V4_1_0_maintainance branch (from tag mergeto_BR_QT4_Dev_29Jul08)
authorvsr <vsr@opencascade.com>
Tue, 29 Jul 2008 14:08:56 +0000 (14:08 +0000)
committervsr <vsr@opencascade.com>
Tue, 29 Jul 2008 14:08:56 +0000 (14:08 +0000)
src/SMESH/SMESH_MesherHelper.cxx
src/SMESH/SMESH_MesherHelper.hxx
src/SMESH/SMESH_Pattern.cxx
src/StdMeshers/StdMeshers_ProjectionUtils.cxx
src/StdMeshers/StdMeshers_Projection_2D.cxx

index 2d29d7d8925098b9f4c02a0a03c51335907be1f9..68331f6634d0bb84a395ff5ade188e719253cfdb 100644 (file)
@@ -32,6 +32,7 @@
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepTools.hxx>
 #include <BRep_Tool.hxx>
+#include <BRepTools_WireExplorer.hxx>
 #include <Geom2d_Curve.hxx>
 #include <Geom_Curve.hxx>
 #include <Geom_Surface.hxx>
@@ -169,7 +170,7 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh)
     BRepAdaptor_Surface surface( face );
     if ( surface.IsUPeriodic() || surface.IsVPeriodic() )
     {
-      for ( TopExp_Explorer exp( face, TopAbs_EDGE ); exp.More(); exp.Next())
+      for (TopExp_Explorer exp( face, TopAbs_EDGE ); exp.More(); exp.Next())
       {
         // look for a seam edge
         const TopoDS_Edge& edge = TopoDS::Edge( exp.Current() );
@@ -190,10 +191,13 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh)
               myPar2 = surface.LastVParameter();
             }
           }
-          // store shapes indices
-          mySeamShapeIds.insert( meshDS->ShapeToIndex( edge ));
-          for ( TopExp_Explorer v( edge, TopAbs_VERTEX ); v.More(); v.Next() )
-            mySeamShapeIds.insert( meshDS->ShapeToIndex( v.Current() ));
+          // store seam shape indices, negative if shape encounters twice
+          int edgeID = meshDS->ShapeToIndex( edge );
+          mySeamShapeIds.insert( IsSeamShape( edgeID ) ? -edgeID : edgeID );
+          for ( TopExp_Explorer v( edge, TopAbs_VERTEX ); v.More(); v.Next() ) {
+            int vertexID = meshDS->ShapeToIndex( v.Current() );
+            mySeamShapeIds.insert( IsSeamShape( vertexID ) ? -vertexID : vertexID );
+          }
         }
 
         // look for a degenerated edge
@@ -318,7 +322,7 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face&   F,
     Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
     uv = C2d->Value( epos->GetUParameter() );
     // for a node on a seam edge select one of UVs on 2 pcurves
-    if ( n2 && mySeamShapeIds.find( edgeID ) != mySeamShapeIds.end() )
+    if ( n2 && IsSeamShape( edgeID ) )
       uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
   }
   else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX)
@@ -370,7 +374,7 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face&   F,
           }
         }
       }
-      if ( n2 && mySeamShapeIds.find( vertexID ) != mySeamShapeIds.end() )
+      if ( n2 && IsSeamShape( vertexID ) )
         uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 ));
     }
   }
index 7f05b08fc883110febcea4fe97b1583dc18c49b1..d3ac65dfd9d86a6b5f42afa2e95698431d8ef63a 100644 (file)
@@ -258,7 +258,8 @@ public:
     * \param subShape - edge or vertex index in SMESHDS
     * \retval bool - true if subShape is a seam shape
     *
-    * It works only if IsQuadraticSubMesh() or SetSubShape() has been called
+    * It works only if IsQuadraticSubMesh() or SetSubShape() has been called.
+    * Seam shape has two 2D alternative represenations on the face
    */
   bool IsSeamShape(const int subShape) const
   { return mySeamShapeIds.find( subShape ) != mySeamShapeIds.end(); }
@@ -267,10 +268,23 @@ public:
     * \param subShape - edge or vertex
     * \retval bool - true if subShape is a seam shape
     *
-    * It works only if IsQuadraticSubMesh() or SetSubShape() has been called
+    * It works only if IsQuadraticSubMesh() or SetSubShape() has been called.
+    * Seam shape has two 2D alternative represenations on the face
    */
   bool IsSeamShape(const TopoDS_Shape& subShape) const
   { return IsSeamShape( GetMeshDS()->ShapeToIndex( subShape )); }
+  /*!
+   * \brief Return true if an edge or a vertex encounters twice in face wire
+   *  \param subShape - Id of edge or vertex
+   */
+  bool IsRealSeam(const int subShape) const
+  { return mySeamShapeIds.find( -subShape ) != mySeamShapeIds.end(); }
+  /*!
+   * \brief Return true if an edge or a vertex encounters twice in face wire
+   *  \param subShape - edge or vertex
+   */
+  bool IsRealSeam(const TopoDS_Shape& subShape) const
+  { return IsRealSeam( GetMeshDS()->ShapeToIndex( subShape)); }
   /*!
    * \brief Check if the shape set through IsQuadraticSubMesh() or SetSubShape()
    *        has a seam edge
index 21690dfee8d880cfdb9c317ba5247992bf19cb6c..9dc5b08f159617804fe0cdfd355475ba9cfb2e5d 100644 (file)
@@ -251,7 +251,7 @@ bool SMESH_Pattern::Load (const char* theFileContents)
     MESSAGE(" Too few points ");
     return setErrorCode( ERR_READ_TOO_FEW_POINTS );
   }
-    
+
   // read the rest points
   int iPoint;
   for ( iPoint = 1; iPoint < nbPoints; iPoint++ )
@@ -398,7 +398,7 @@ bool SMESH_Pattern::Save (ostream& theFile)
   }
 
   theFile << endl;
-  
+
   return setErrorCode( ERR_OK );
 }
 
@@ -521,7 +521,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
 
   TopoDS_Face face = TopoDS::Face( theFace.Oriented( TopAbs_FORWARD ));
 
-  // check that face is not closed
+  // check if face is closed
   bool isClosed = helper.HasSeam();
   TopoDS_Vertex bidon;
   list<TopoDS_Edge> eList;
@@ -634,10 +634,13 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
     // vertices
     for ( elIt = eList.begin(); elIt != eList.end(); elIt++ ) {
       myShapeIDMap.Add( TopExp::FirstVertex( *elIt, true ));
-      if ( BRep_Tool::IsClosed( *elIt, theFace ) )
-        myShapeIDMap.Add( TopExp::LastVertex( *elIt, true ));
-      SMESHDS_SubMesh * eSubMesh = aMeshDS->MeshElements( *elIt );
-      if ( eSubMesh )
+      if ( helper.IsSeamShape( *elIt ) ) {
+        // vertices present twice in the wire have two corresponding key points
+        const TopoDS_Vertex& lastV = TopExp::LastVertex( *elIt, true );
+        if ( helper.IsRealSeam( lastV ))
+          myShapeIDMap.Add( lastV );// vertex orienation is REVERSED
+      }
+      if ( SMESHDS_SubMesh * eSubMesh = aMeshDS->MeshElements( *elIt ))
         nbNodes += eSubMesh->NbNodes() + 1;
     }
     // edges
@@ -665,15 +668,15 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
       v2.Reverse();
 
       // on closed face we must have REVERSED some of seam vertices
-      bool isSeam = helper.IsSeamShape( edge );
       if ( isClosed ) {
-        if ( isSeam ) { // reverse on reversed SEAM edge
-          if ( !isForward ) {
+        if ( helper.IsSeamShape( edge ) ) {
+          if ( helper.IsRealSeam( edge ) && !isForward ) {
+            // reverse on reversed SEAM edge
             v1.Reverse();
             v2.Reverse();
           }
         }
-        else { // on CLOSED edge
+        else { // on CLOSED edge (i.e. having one vertex with different orienations)
           for ( int is2 = 0; is2 < 2; ++is2 ) {
             TopoDS_Shape & v = is2 ? v2 : v1;
             if ( helper.IsSeamShape( v ) ) {
@@ -757,6 +760,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
           }
         }
         // put U in [0,1] so that the first key-point has U==0
+        bool isSeam = helper.IsRealSeam( edge );
         double du = l - f;
         TParamNodeMap::iterator         unIt  = paramNodeMap.begin();
         TParamNodeMap::reverse_iterator unRIt = paramNodeMap.rbegin();
@@ -851,6 +855,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
         p->myInitXYZ.SetCoord( p->myInitUV.X(), p->myInitUV.Y(), 0 );
       }
       // load elements
+      TNodePointIDMap::iterator n_id, not_found = closeNodePointIDMap.end();
       SMDS_ElemIteratorPtr elemIt = fSubMesh->GetElements();
       while ( elemIt->more() )
       {
@@ -864,10 +869,8 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
           const SMDS_MeshNode* node = smdsNode( nIt->next() );
           iPoint = nodePointIDMap[ node ]; // point index of interest
           // for a node on a seam edge there are two points
-          TNodePointIDMap::iterator n_id = closeNodePointIDMap.end();
-          if ( helper.IsSeamShape( node->GetPosition()->GetShapeId() ))
-            n_id = closeNodePointIDMap.find( node );
-          if ( n_id != closeNodePointIDMap.end() )
+          if ( helper.IsRealSeam( node->GetPosition()->GetShapeId() ) &&
+               ( n_id = closeNodePointIDMap.find( node )) != not_found )
           {
             TPoint & p1 = myPoints[ iPoint ];
             TPoint & p2 = myPoints[ n_id->second ];
@@ -999,7 +1002,7 @@ static bool intersectIsolines(const gp_XY& uv11, const gp_XY& uv12, const double
 //   resUV = loc1 * len2 / ( len1 + len2 ) + loc2 * len1 / ( len1 + len2 );
 //  return true;
 
-  
+
 //   gp_Lin2d line1( uv11, uv12 - uv11 );
 //   gp_Lin2d line2( uv21, uv22 - uv21 );
 //   double angle = Abs( line1.Angle( line2 ) );
@@ -1013,7 +1016,7 @@ static bool intersectIsolines(const gp_XY& uv11, const gp_XY& uv12, const double
 //   inter.Perform( line1, line2 );
 //   interUV = inter.Point(1).Value();
 //   resUV += interUV.XY();
-  
+
 //   resUV /= 2.;
 //     }
   if ( isDeformed ) {
@@ -1053,7 +1056,7 @@ bool SMESH_Pattern::compUVByIsoIntersection (const list< list< TPoint* > >& theB
       const list< TPoint* > & bndPoints = * bndIt;
       TPoint* prevP = bndPoints.back(); // this is the first point
       list< TPoint* >::const_iterator pIt = bndPoints.begin();
-      bool coincPrev = false; 
+      bool coincPrev = false;
       // loop on the edge-points
       for ( ; pIt != bndPoints.end(); pIt++ )
       {
@@ -1318,7 +1321,7 @@ static bool checkQuads (const TIsoNode* node,
       gp_XY uv1, uv2 = node->myUV;
       for ( i = isTriangle ? 2 : 0; i < 3; i++ ) // mark not computed vectors
         if ( wasOk[i] )
-          moveVec[ i ].SetCoord( 1, 2e100); // not use this vector 
+          moveVec[ i ].SetCoord( 1, 2e100); // not use this vector
       while ( !isOldOk ) {
         // find the least moveVec
         int i, iMin = 4;
@@ -1749,7 +1752,7 @@ bool SMESH_Pattern::
           aNorm[1-iDir].Normalize();
           double r = Abs ( ratio[iDir] - 0.5 ) * 2.0; // [0,1] - distance from the middle
           r *= r;
-          
+
           node->myDir[iDir] = //aTgt[iDir];
             aNorm[1-iDir] * r + aTgt[iDir] * ( 1. - r );
         }
@@ -1950,7 +1953,7 @@ bool SMESH_Pattern::
     }
     internNodes.push_back( node );
   }
-  
+
   // Move nodes
 
   static int maxNbIter = 100;
@@ -1962,7 +1965,7 @@ bool SMESH_Pattern::
   int nbNodeMove = 0;
   if ( !useNbMoveNode )
     maxNbIter = ( maxNbIter < 0 ) ? 100 : -1;
-#endif    
+#endif
   double maxMove;
   int nbIter = 0;
   do {
@@ -2059,8 +2062,7 @@ bool SMESH_Pattern::
       }
     }
   }
-      
-    
+
   return true;
 }
 
@@ -2086,7 +2088,7 @@ double SMESH_Pattern::setFirstEdge (list< TopoDS_Edge > & theWire, int theFirstE
   int eID = theFirstEdgeID;
   for ( iE = 0; iE < nbEdges; iE++ )
     maxNbPnt = Max ( maxNbPnt, getShapePoints( eID++ ).size() );
-  
+
   // compute bnd boxes
   TopoDS_Face face = TopoDS::Face( myShape );
   Bnd_Box2d bndBox, eBndBox;
@@ -2281,7 +2283,7 @@ bool SMESH_Pattern::sortSameSizeWires (TListOfEdgesList &                theWire
     bndIndWirePosMap.insert( TIntWirePosMap::value_type( bIndex, wlIt ));
   }
 
-  // Treat each wire  
+  // Treat each wire
 
   TIntWirePosMap::iterator bIndWPosIt = bndIndWirePosMap.begin();
   eID = theFirstEdgeID;
@@ -2292,7 +2294,7 @@ bool SMESH_Pattern::sortSameSizeWires (TListOfEdgesList &                theWire
 
     // choose the best first edge of a wire
     setFirstEdge( wire, eID );
-    
+
     // compute eventual UV and fill theEdgesPointsList
     theEdgesPointsList.push_back( list< TPoint* >() );
     list< TPoint* > & edgesPoints = theEdgesPointsList.back();
@@ -2354,8 +2356,24 @@ bool SMESH_Pattern::Apply (const TopoDS_Face&   theFace,
   list<TopoDS_Edge>::iterator elIt = eList.begin();
   for ( ; elIt != eList.end(); elIt++ ) {
     myShapeIDMap.Add( TopExp::FirstVertex( *elIt, true ));
-    if ( BRep_Tool::IsClosed( *elIt, theFace ) )
-      myShapeIDMap.Add( TopExp::LastVertex( *elIt, true ));
+    bool isClosed1 = BRep_Tool::IsClosed( *elIt, theFace );
+    // BEGIN: jfa for bug 0019943
+    if (isClosed1) {
+      isClosed1 = false;
+      for (TopExp_Explorer expw (theFace, TopAbs_WIRE); expw.More() && !isClosed1; expw.Next()) {
+        const TopoDS_Wire& wire = TopoDS::Wire(expw.Current());
+        int nbe = 0;
+        for (BRepTools_WireExplorer we (wire, theFace); we.More() && !isClosed1; we.Next()) {
+          if (we.Current().IsSame(*elIt)) {
+            nbe++;
+            if (nbe == 2) isClosed1 = true;
+          }
+        }
+      }
+    }
+    // END: jfa for bug 0019943
+    if (isClosed1)
+      myShapeIDMap.Add( TopExp::LastVertex( *elIt, true ));// vertex orienation is REVERSED
   }
   int nbVertices = myShapeIDMap.Extent();
 
@@ -2364,7 +2382,7 @@ bool SMESH_Pattern::Apply (const TopoDS_Face&   theFace,
 
   myShapeIDMap.Add( face );
 
-  if ( myShapeIDToPointsMap.size() != myShapeIDMap.Extent()/* + nbSeamShapes*/ ) {
+  if ( myShapeIDToPointsMap.size() != myShapeIDMap.Extent() ) {
     MESSAGE( myShapeIDToPointsMap.size() <<" != " << myShapeIDMap.Extent());
     return setErrorCode( ERR_APPLF_INTERNAL_EEROR );
   }
@@ -2461,7 +2479,7 @@ bool SMESH_Pattern::Apply (const TopoDS_Face&   theFace,
     }
 
     // find boundary - wire correspondence for several wires of same size
-    
+
     id1 = nbVertices + nbEdgesInOuterWire + 1;
     wlIt = wireList.begin();
     while ( wlIt != wireList.end() )
@@ -2481,7 +2499,7 @@ bool SMESH_Pattern::Apply (const TopoDS_Face&   theFace,
     }
 
     // add well-ordered edges to eList
-    
+
     for ( wlIt = wireList.begin(); wlIt != wireList.end(); wlIt++ )
     {
       list< TopoDS_Edge >& wire = (*wlIt);
@@ -2496,7 +2514,7 @@ bool SMESH_Pattern::Apply (const TopoDS_Face&   theFace,
     for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
       myShapeIDMap.Add( *elIt );
     myShapeIDMap.Add( face );
-    
+
   } // there are inner wires
 
   // Compute XYZ of on-edge points
@@ -2646,7 +2664,7 @@ bool SMESH_Pattern::Apply (const SMDS_MeshFace* theFace,
   {
     gp_XYZ& xyz1 = *xyzIt++;
     gp_XYZ& xyz2 = ( xyzIt != xyzList.end() ) ? *xyzIt : xyzList.front();
-    
+
     list< TPoint* > & ePoints = getShapePoints( iSub );
     ePoints.back()->myInitU = 1.0;
     list< TPoint* >::const_iterator pIt = ++ePoints.begin();
@@ -2920,7 +2938,7 @@ bool SMESH_Pattern::Apply (SMESH_Mesh*                     theMesh,
   // meshed geometry
   TopoDS_Shape shape;
 //   int          shapeID = 0;
-//   SMESH_MeshEditor editor( theMesh ); 
+//   SMESH_MeshEditor editor( theMesh );
 
   // apply to each face in theFaces set
   set<const SMDS_MeshFace*>::iterator face = theFaces.begin();
@@ -3701,7 +3719,7 @@ bool SMESH_Pattern::
       bndId = nn_IdList->second.front().front();
       ids.insert( bndId );
     }
-    else 
+    else
       myXYZIdToNodeMap.insert( make_pair( bndId, theBndNodes[ iN ] ));
     faceDef.push_back( bndId );
     // add ids on a link
@@ -3969,7 +3987,7 @@ void SMESH_Pattern::createElements(SMESH_Mesh*                            theMes
                                    const vector<const SMDS_MeshElement*>& theElements)
 {
   SMESHDS_Mesh* aMeshDS = theMesh->GetMeshDS();
-  SMESH_MeshEditor editor( theMesh ); 
+  SMESH_MeshEditor editor( theMesh );
 
   bool onMeshElements = !theElements.empty();
 
@@ -4185,7 +4203,7 @@ void SMESH_Pattern::arrangeBoundaries (list< list< TPoint* > >& boundaryList)
     if ( nbBoundaries > 2 )
     {
       // move boundaries in tmp list
-      list< list< TPoint* > > tmpList; 
+      list< list< TPoint* > > tmpList;
       tmpList.splice( tmpList.begin(), boundaryList, boundaryList.begin(), boundaryList.end());
       // make a map nb-key-points to boundary-position-in-tmpList,
       // boundary-positions get ordered in it
@@ -4228,7 +4246,7 @@ void SMESH_Pattern::arrangeBoundaries (list< list< TPoint* > >& boundaryList)
       boundaryList.splice( boundaryList.begin(), boundaryList, outerBndPos, ++outerBndPos );
 
   } // if nbBoundaries > 1
-                 
+
   // Check boundaries orientation and re-fill myKeyPointIDs
 
   set< TPoint* > keyPointSet;
@@ -4499,7 +4517,7 @@ bool SMESH_Pattern::findBoundaryPoints()
       getShapePoints( shapeID ).push_back( point );
       // detect key-points
       if ( SMESH_Block::IsVertexID( shapeID ))
-        myKeyPointIDs.push_back( i );        
+        myKeyPointIDs.push_back( i );
     }
   }
 
@@ -4547,13 +4565,19 @@ bool SMESH_Pattern::setShapeToMesh(const TopoDS_Shape& theShape)
   // check if a face is closed
   int nbNodeOnSeamEdge = 0;
   if ( myIs2D ) {
+    TopTools_MapOfShape seamVertices;
     TopoDS_Face face = TopoDS::Face( theShape );
     TopExp_Explorer eExp( theShape, TopAbs_EDGE );
-    for ( ; eExp.More() && nbNodeOnSeamEdge == 0; eExp.Next() )
-      if ( BRep_Tool::IsClosed( TopoDS::Edge( eExp.Current() ), face ))
-        nbNodeOnSeamEdge = 2;
+    for ( ; eExp.More() && nbNodeOnSeamEdge == 0; eExp.Next() ) {
+      const TopoDS_Edge& ee = TopoDS::Edge(eExp.Current());
+      if ( BRep_Tool::IsClosed(ee, face) ) {
+        // seam edge and vertices encounter twice in theFace
+        if ( !seamVertices.Add( TopExp::FirstVertex( ee ))) nbNodeOnSeamEdge++;
+        if ( !seamVertices.Add( TopExp::LastVertex( ee ))) nbNodeOnSeamEdge++;
+      }
+    }
   }
-    
+
   // check nb of vertices
   TopTools_IndexedMapOfShape vMap;
   TopExp::MapShapes( theShape, TopAbs_VERTEX, vMap );
@@ -4695,6 +4719,6 @@ ostream & operator <<(ostream & OS, const SMESH_Pattern::TPoint& p)
   OS << " uv( " <<  xy.X() << " " << xy.Y() << " )";
   u = p.myU;
   OS << " u( " <<  u << " ))" << endl;
-  
+
   return OS;
 }
index 01b04541f1617623b4077a8b6471bf5f507a1391..1ef60301f29360ec997ea6b5ee2c82ffbc833347 100644 (file)
@@ -1358,7 +1358,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face&     face1,
     }
     if ( nodesOfFaces )
     {
-      if ( BRep_Tool::IsClosed( e2, face2 )) {
+      if ( helper2.IsRealSeam( e2 )) {
         seam1 = e1; seam2 = e2;
       }
       else {
@@ -1430,7 +1430,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face&     face1,
     const TopoDS_Face &             face = is2 ? face2 : face1;
     SMDS_ElemIteratorPtr eIt = sm->GetElements();
 
-    if ( !helper->IsSeamShape( is2 ? edge2 : edge1 ))
+    if ( !helper->IsRealSeam( is2 ? edge2 : edge1 ))
     {
       while ( eIt->more() ) elems.insert( eIt->next() );
     }
@@ -1515,7 +1515,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face&     face1,
 
   // On a sphere, add matching nodes on the edge
 
-  if ( helper1.IsSeamShape( edge1 ))
+  if ( helper1.IsRealSeam( edge1 ))
   {
     // sort nodes on edges by param on edge
     map< double, const SMDS_MeshNode* > u2nodesMaps[2];
index a31487eefe6b40827458d56e6beb185294fc7b83..7f193fbf93f32f33010412a992f94c1dc7e4dae5 100644 (file)
@@ -295,16 +295,14 @@ namespace {
       // Find a new node connected to nV1 and belonging to edge submesh;
       const SMDS_MeshNode* nE = 0;
       SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
-      SMDS_ElemIteratorPtr vElems = nV1->GetInverseElementIterator();
+      SMDS_ElemIteratorPtr vElems = nV1->GetInverseElementIterator(SMDSAbs_Face);
       while ( vElems->more() && !nE ) {
         const SMDS_MeshElement* elem = vElems->next();
-        if ( elem->GetType() != SMDSAbs_Face )
-          continue; // new nodes are shared by faces
         int nbNodes = elem->NbNodes();
         if ( elem->IsQuadratic() )
           nbNodes /= 2;
         int iV1 = elem->GetNodeIndex( nV1 );
-        // try next aftre nV1
+        // try next after nV1
         int iE = SMESH_MesherHelper::WrapIndex( iV1 + 1, nbNodes );
         if ( smDS->Contains( elem->GetNode( iE ) ))
           nE = elem->GetNode( iE );
@@ -515,7 +513,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
 
     // Sort new and old nodes of a submesh separately
 
-    bool isSeam = helper.IsSeamShape( sm->GetId() );
+    bool isSeam = helper.IsRealSeam( sm->GetId() );
 
     enum { NEW_NODES = 0, OLD_NODES };
     map< double, const SMDS_MeshNode* > u2nodesMaps[2], u2nodesOnSeam;
@@ -537,7 +535,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
           continue; // node is already in the map
       }
 
-      // sort nodes on edges by its position
+      // sort nodes on edges by their position
       map< double, const SMDS_MeshNode* > & pos2nodes = u2nodesMaps[isOld ? OLD_NODES : NEW_NODES];
       switch ( node->GetPosition()->GetTypeOfPosition() )
       {
@@ -558,12 +556,13 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
     }
     if ( u2nodesMaps[ NEW_NODES ].size() != u2nodesMaps[ OLD_NODES ].size() )
     {
-      if ( u2nodesMaps[ NEW_NODES ].size() == 0                 &&
-           sm->GetSubShape().ShapeType() == TopAbs_EDGE         &&
-           BRep_Tool::Degenerated( TopoDS::Edge( sm->GetSubShape() )))
+      if ( u2nodesMaps[ NEW_NODES ].size() == 0         &&
+           sm->GetSubShape().ShapeType() == TopAbs_EDGE &&
+           helper.IsDegenShape( sm->GetId() )             )
         // NPAL15894 (tt88bis.py) - project mesh built by NETGEN_1d_2D that
-       // does not make segments/nodes on degenerated edges
+        // does not make segments/nodes on degenerated edges
         continue;
+
       RETURN_BAD_RESULT("Different nb of old and new nodes on shape #"<< sm->GetId() <<" "<<
                         u2nodesMaps[ OLD_NODES ].size() << " != " <<
                         u2nodesMaps[ NEW_NODES ].size());