Salome HOME
Suppress memory leak when using Kernel_Utils::decode()
[modules/smesh.git] / src / SMESH / SMESH_MeshEditor.cxx
index 69cb3e94bedffe31246db959fbe1ad846c9c25b8..ff121002f5de4d992663f11670586a9ae1ab1a95 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2021  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 
 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
 
 
 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
 
+#include <smIdType.hxx>
+
 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
 
 using namespace std;
 #define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
 
 using namespace std;
@@ -161,8 +163,7 @@ SMESH_MeshEditor::ElemFeatures::Init( const SMDS_MeshElement* elem, bool basicOn
         myIsQuad = elem->IsQuadratic();
         if ( myType == SMDSAbs_Volume && !basicOnly )
         {
         myIsQuad = elem->IsQuadratic();
         if ( myType == SMDSAbs_Volume && !basicOnly )
         {
-          vector<int> quant = static_cast<const SMDS_MeshVolume* >( elem )->GetQuantities();
-          myPolyhedQuantities.swap( quant );
+          myPolyhedQuantities = static_cast<const SMDS_MeshVolume* >( elem )->GetQuantities();
         }
       }
     }
         }
       }
     }
@@ -187,7 +188,7 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
   SMDS_MeshElement* e = 0;
   int nbnode = node.size();
   SMESHDS_Mesh* mesh = GetMeshDS();
   SMDS_MeshElement* e = 0;
   int nbnode = node.size();
   SMESHDS_Mesh* mesh = GetMeshDS();
-  const int ID = features.myID;
+  const smIdType ID = features.myID;
 
   switch ( features.myType ) {
   case SMDSAbs_Face:
 
   switch ( features.myType ) {
   case SMDSAbs_Face:
@@ -297,6 +298,18 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
                                                  node[8], node[9], node[10],node[11],
                                                  node[12],node[13],node[14] );
       }
                                                  node[8], node[9], node[10],node[11],
                                                  node[12],node[13],node[14] );
       }
+      else if (nbnode == 18) {
+        if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],node[13],node[14],
+                                                 node[15],node[16],node[17],ID );
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
+                                                 node[4], node[5], node[6], node[7],
+                                                 node[8], node[9], node[10],node[11],
+                                                 node[12],node[13],node[14],
+                                                 node[15],node[16],node[17] );
+      }
       else if (nbnode == 20) {
         if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
                                                  node[4], node[5], node[6], node[7],
       else if (nbnode == 20) {
         if ( ID >= 1 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
                                                  node[4], node[5], node[6], node[7],
@@ -378,12 +391,12 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
  */
 //=======================================================================
 
  */
 //=======================================================================
 
-SMDS_MeshElement* SMESH_MeshEditor::AddElement(const vector<int> & nodeIDs,
-                                               const ElemFeatures& features)
+SMDS_MeshElement* SMESH_MeshEditor::AddElement(const vector<smIdType> & nodeIDs,
+                                               const ElemFeatures&      features)
 {
   vector<const SMDS_MeshNode*> nodes;
   nodes.reserve( nodeIDs.size() );
 {
   vector<const SMDS_MeshNode*> nodes;
   nodes.reserve( nodeIDs.size() );
-  vector<int>::const_iterator id = nodeIDs.begin();
+  vector<smIdType>::const_iterator id = nodeIDs.begin();
   while ( id != nodeIDs.end() ) {
     if ( const SMDS_MeshNode* node = GetMeshDS()->FindNode( *id++ ))
       nodes.push_back( node );
   while ( id != nodeIDs.end() ) {
     if ( const SMDS_MeshNode* node = GetMeshDS()->FindNode( *id++ ))
       nodes.push_back( node );
@@ -399,7 +412,7 @@ SMDS_MeshElement* SMESH_MeshEditor::AddElement(const vector<int> & nodeIDs,
 //           Modify a compute state of sub-meshes which become empty
 //=======================================================================
 
 //           Modify a compute state of sub-meshes which become empty
 //=======================================================================
 
-int SMESH_MeshEditor::Remove (const list< int >& theIDs,
+smIdType SMESH_MeshEditor::Remove (const list< smIdType >& theIDs,
                               const bool         isNodes )
 {
   ClearLastCreated();
                               const bool         isNodes )
 {
   ClearLastCreated();
@@ -407,8 +420,8 @@ int SMESH_MeshEditor::Remove (const list< int >& theIDs,
   SMESHDS_Mesh* aMesh = GetMeshDS();
   set< SMESH_subMesh *> smmap;
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
   set< SMESH_subMesh *> smmap;
 
-  int removed = 0;
-  list<int>::const_iterator it = theIDs.begin();
+  smIdType removed = 0;
+  list<smIdType>::const_iterator it = theIDs.begin();
   for ( ; it != theIDs.end(); it++ ) {
     const SMDS_MeshElement * elem;
     if ( isNodes )
   for ( ; it != theIDs.end(); it++ ) {
     const SMDS_MeshElement * elem;
     if ( isNodes )
@@ -1093,19 +1106,37 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
       MESSAGE("Warning: bad volumic element");
       return false;
     }
       MESSAGE("Warning: bad volumic element");
       return false;
     }
-    const int nbFaces = aPolyedre->NbFaces();
+    SMDS_VolumeTool vTool( aPolyedre );
+    const int nbFaces = vTool.NbFaces();
+    vector<int> quantities( nbFaces );
     vector<const SMDS_MeshNode *> poly_nodes;
     vector<const SMDS_MeshNode *> poly_nodes;
-    vector<int> quantities (nbFaces);
 
 
-    // reverse each face of the polyedre
-    for (int iface = 1; iface <= nbFaces; iface++) {
-      int inode, nbFaceNodes = aPolyedre->NbFaceNodes(iface);
-      quantities[iface - 1] = nbFaceNodes;
+    // check if all facets are oriented equally
+    bool sameOri = true;
+    vector<int>& facetOri = quantities; // keep orientation in quantities so far
+    for (int iface = 0; iface < nbFaces; iface++)
+    {
+      facetOri[ iface ] = vTool.IsFaceExternal( iface );
+      if ( facetOri[ iface ] != facetOri[ 0 ])
+        sameOri = false;
+    }
 
 
-      for (inode = nbFaceNodes; inode >= 1; inode--) {
-        const SMDS_MeshNode* curNode = aPolyedre->GetFaceNode(iface, inode);
-        poly_nodes.push_back(curNode);
-      }
+    // reverse faces of the polyhedron
+    int neededOri = sameOri ? 1 - facetOri[0] : 1;
+    poly_nodes.reserve( vTool.NbNodes() );
+    for ( int iface = 0; iface < nbFaces; iface++ )
+    {
+      int             nbFaceNodes = vTool.NbFaceNodes( iface );
+      const SMDS_MeshNode** nodes = vTool.GetFaceNodes( iface );
+      bool toReverse = ( facetOri[ iface ] != neededOri );
+
+      quantities[ iface ] = nbFaceNodes;
+
+      if ( toReverse )
+        for ( int inode = nbFaceNodes - 1; inode >= 0; inode-- )
+          poly_nodes.push_back( nodes[ inode ]);
+      else
+        poly_nodes.insert( poly_nodes.end(), nodes, nodes + nbFaceNodes );
     }
     return GetMeshDS()->ChangePolyhedronNodes( theElem, poly_nodes, quantities );
   }
     }
     return GetMeshDS()->ChangePolyhedronNodes( theElem, poly_nodes, quantities );
   }
@@ -1475,9 +1506,12 @@ void SMESH_MeshEditor::QuadTo4Tri (TIDSortedElemSet & theElems)
   SMESH_MesherHelper helper( *GetMesh() );
   helper.SetElementsOnShape( true );
 
   SMESH_MesherHelper helper( *GetMesh() );
   helper.SetElementsOnShape( true );
 
-  SMDS_ElemIteratorPtr faceIt;
-  if ( theElems.empty() ) faceIt = GetMeshDS()->elementsIterator(SMDSAbs_Face);
-  else                    faceIt = SMESHUtils::elemSetIterator( theElems );
+  // get standalone groups of faces
+  vector< SMDS_MeshGroup* > allFaceGroups, faceGroups;
+  for ( SMESHDS_GroupBase* grBase : GetMeshDS()->GetGroups() )
+    if ( SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( grBase ))
+      if ( group->GetType() == SMDSAbs_Face && !group->IsEmpty() )
+        allFaceGroups.push_back( & group->SMDSGroup() );
 
   bool   checkUV;
   gp_XY  uv [9]; uv[8] = gp_XY(0,0);
 
   bool   checkUV;
   gp_XY  uv [9]; uv[8] = gp_XY(0,0);
@@ -1488,6 +1522,10 @@ void SMESH_MeshEditor::QuadTo4Tri (TIDSortedElemSet & theElems)
   Handle(Geom_Surface)           surface;
   TopLoc_Location                loc;
 
   Handle(Geom_Surface)           surface;
   TopLoc_Location                loc;
 
+  SMDS_ElemIteratorPtr faceIt;
+  if ( theElems.empty() ) faceIt = GetMeshDS()->elementsIterator(SMDSAbs_Face);
+  else                    faceIt = SMESHUtils::elemSetIterator( theElems );
+
   while ( faceIt->more() )
   {
     const SMDS_MeshElement* quad = faceIt->next();
   while ( faceIt->more() )
   {
     const SMDS_MeshElement* quad = faceIt->next();
@@ -1564,13 +1602,19 @@ void SMESH_MeshEditor::QuadTo4Tri (TIDSortedElemSet & theElems)
       myLastCreatedNodes.push_back( nCentral );
     }
 
       myLastCreatedNodes.push_back( nCentral );
     }
 
-    // create 4 triangles
-
     helper.SetIsQuadratic  ( nodes.size() > 4 );
     helper.SetIsBiQuadratic( nodes.size() == 9 );
     if ( helper.GetIsQuadratic() )
       helper.AddTLinks( static_cast< const SMDS_MeshFace*>( quad ));
 
     helper.SetIsQuadratic  ( nodes.size() > 4 );
     helper.SetIsBiQuadratic( nodes.size() == 9 );
     if ( helper.GetIsQuadratic() )
       helper.AddTLinks( static_cast< const SMDS_MeshFace*>( quad ));
 
+    // select groups to update
+    faceGroups.clear();
+    for ( SMDS_MeshGroup* group : allFaceGroups )
+      if ( group->Remove( quad ))
+        faceGroups.push_back( group );
+
+    // create 4 triangles
+
     GetMeshDS()->RemoveFreeElement( quad, subMeshDS, /*fromGroups=*/false );
 
     for ( int i = 0; i < 4; ++i )
     GetMeshDS()->RemoveFreeElement( quad, subMeshDS, /*fromGroups=*/false );
 
     for ( int i = 0; i < 4; ++i )
@@ -1578,8 +1622,9 @@ void SMESH_MeshEditor::QuadTo4Tri (TIDSortedElemSet & theElems)
       SMDS_MeshElement* tria = helper.AddFace( nodes[ i ],
                                                nodes[(i+1)%4],
                                                nCentral );
       SMDS_MeshElement* tria = helper.AddFace( nodes[ i ],
                                                nodes[(i+1)%4],
                                                nCentral );
-      ReplaceElemInGroups( tria, quad, GetMeshDS() );
       myLastCreatedElems.push_back( tria );
       myLastCreatedElems.push_back( tria );
+      for ( SMDS_MeshGroup* group : faceGroups )
+        group->Add( tria );
     }
   }
 }
     }
   }
 }
@@ -1765,6 +1810,17 @@ namespace
     TSplitMethod( int nbTet=0, const int* conn=0, bool addNode=false)
       : _nbSplits(nbTet), _nbCorners(4), _connectivity(conn), _baryNode(addNode), _ownConn(false) {}
     ~TSplitMethod() { if ( _ownConn ) delete [] _connectivity; _connectivity = 0; }
     TSplitMethod( int nbTet=0, const int* conn=0, bool addNode=false)
       : _nbSplits(nbTet), _nbCorners(4), _connectivity(conn), _baryNode(addNode), _ownConn(false) {}
     ~TSplitMethod() { if ( _ownConn ) delete [] _connectivity; _connectivity = 0; }
+    TSplitMethod(const TSplitMethod &splitMethod)
+      : _nbSplits(splitMethod._nbSplits),
+        _nbCorners(splitMethod._nbCorners),
+        _baryNode(splitMethod._baryNode),
+        _ownConn(splitMethod._ownConn),
+        _faceBaryNode(splitMethod._faceBaryNode)
+    {
+      _connectivity = splitMethod._connectivity;
+      const_cast<TSplitMethod&>(splitMethod)._connectivity = nullptr;
+      const_cast<TSplitMethod&>(splitMethod)._ownConn = false;
+    }
     bool hasFacet( const TTriangleFacet& facet ) const
     {
       if ( _nbCorners == 4 )
     bool hasFacet( const TTriangleFacet& facet ) const
     {
       if ( _nbCorners == 4 )
@@ -1884,7 +1940,7 @@ namespace
       }
       for ( int variant = 0; variant < nbVariants && method._nbSplits == 0; ++variant )
       {
       }
       for ( int variant = 0; variant < nbVariants && method._nbSplits == 0; ++variant )
       {
-        // check method compliancy with adjacent tetras,
+        // check method compliance with adjacent tetras,
         // all found splits must be among facets of tetras described by this method
         method = TSplitMethod( nbTet, connVariants[variant] );
         if ( hasAdjacentSplits && method._nbSplits > 0 )
         // all found splits must be among facets of tetras described by this method
         method = TSplitMethod( nbTet, connVariants[variant] );
         if ( hasAdjacentSplits && method._nbSplits > 0 )
@@ -2015,6 +2071,8 @@ namespace
                                     const int        methodFlags,
                                     const int        facetToSplit)
   {
                                     const int        methodFlags,
                                     const int        facetToSplit)
   {
+    TSplitMethod method;
+
     // order of facets in HEX according to SMDS_VolumeTool::Hexa_F :
     // B, T, L, B, R, F
     const int iF = ( facetToSplit < 2 ) ? 0 : 1 + ( facetToSplit-2 ) % 2; // [0,1,2]
     // order of facets in HEX according to SMDS_VolumeTool::Hexa_F :
     // B, T, L, B, R, F
     const int iF = ( facetToSplit < 2 ) ? 0 : 1 + ( facetToSplit-2 ) % 2; // [0,1,2]
@@ -2045,12 +2103,12 @@ namespace
         to4methods[iF]._nbSplits  = 4;
         to4methods[iF]._nbCorners = 6;
       }
         to4methods[iF]._nbSplits  = 4;
         to4methods[iF]._nbCorners = 6;
       }
-      return to4methods[iF];
+      method = to4methods[iF];
+      to4methods[iF]._connectivity = method._connectivity; // as copy ctor resets _connectivity
+      return method;
     }
     // else if ( methodFlags == HEXA_TO_2_PRISMS )
 
     }
     // else if ( methodFlags == HEXA_TO_2_PRISMS )
 
-    TSplitMethod method;
-
     const int iQ = vol.Element()->IsQuadratic() ? 2 : 1;
 
     const int nbVariants = 2, nbSplits = 2;
     const int iQ = vol.Element()->IsQuadratic() ? 2 : 1;
 
     const int nbVariants = 2, nbSplits = 2;
@@ -2083,7 +2141,7 @@ namespace
       // there are adjacent prism
       for ( int variant = 0; variant < nbVariants; ++variant )
       {
       // there are adjacent prism
       for ( int variant = 0; variant < nbVariants; ++variant )
       {
-        // check method compliancy with adjacent prisms,
+        // check method compliance with adjacent prisms,
         // the found prism facets must be among facets of prisms described by current method
         method._nbSplits     = nbSplits;
         method._nbCorners    = 6;
         // the found prism facets must be among facets of prisms described by current method
         method._nbSplits     = nbSplits;
         method._nbCorners    = 6;
@@ -2162,7 +2220,7 @@ namespace
    */
   //=======================================================================
 
    */
   //=======================================================================
 
-  struct TVolumeFaceKey: pair< pair< int, int>, pair< int, int> >
+  struct TVolumeFaceKey: pair< pair< smIdType, smIdType>, pair< smIdType, smIdType> >
   {
     TVolumeFaceKey( SMDS_VolumeTool& vol, int iF )
     {
   {
     TVolumeFaceKey( SMDS_VolumeTool& vol, int iF )
     {
@@ -3076,10 +3134,10 @@ public:
     :myMesh( theMesh ), myMaxID( theMesh->MaxNodeID() + 1)
   {}
 
     :myMesh( theMesh ), myMaxID( theMesh->MaxNodeID() + 1)
   {}
 
-  long GetLinkID (const SMDS_MeshNode * n1,
+  smIdType GetLinkID (const SMDS_MeshNode * n1,
                   const SMDS_MeshNode * n2) const
   {
                   const SMDS_MeshNode * n2) const
   {
-    return ( Min(n1->GetID(),n2->GetID()) * myMaxID + Max(n1->GetID(),n2->GetID()));
+    return ( std::min(n1->GetID(),n2->GetID()) * myMaxID + std::max(n1->GetID(),n2->GetID()));
   }
 
   bool GetNodes (const long             theLinkID,
   }
 
   bool GetNodes (const long             theLinkID,
@@ -3586,7 +3644,7 @@ static bool getClosestUV (Extrema_GenExtPS& projector,
 {
   projector.Perform( point );
   if ( projector.IsDone() ) {
 {
   projector.Perform( point );
   if ( projector.IsDone() ) {
-    double u, v, minVal = DBL_MAX;
+    double u = 0, v = 0, minVal = DBL_MAX;
     for ( int i = projector.NbExt(); i > 0; i-- )
       if ( projector.SquareDistance( i ) < minVal ) {
         minVal = projector.SquareDistance( i );
     for ( int i = projector.NbExt(); i > 0; i-- )
       if ( projector.SquareDistance( i ) < minVal ) {
         minVal = projector.SquareDistance( i );
@@ -5623,10 +5681,10 @@ makeNodesByNormal2D( SMESHDS_Mesh*                     mesh,
 //=======================================================================
 
 int SMESH_MeshEditor::ExtrusParam::
 //=======================================================================
 
 int SMESH_MeshEditor::ExtrusParam::
-makeNodesByNormal1D( SMESHDS_Mesh*                     mesh,
-                     const SMDS_MeshNode*              srcNode,
-                     std::list<const SMDS_MeshNode*> & newNodes,
-                     const bool                        makeMediumNodes)
+makeNodesByNormal1D( SMESHDS_Mesh*                     /*mesh*/,
+                     const SMDS_MeshNode*              /*srcNode*/,
+                     std::list<const SMDS_MeshNode*> & /*newNodes*/,
+                     const bool                        /*makeMediumNodes*/)
 {
   throw SALOME_Exception("Extrusion 1D by Normal not implemented");
   return 0;
 {
   throw SALOME_Exception("Extrusion 1D by Normal not implemented");
   return 0;
@@ -5850,6 +5908,11 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet     theElemSets[2],
           }
           else
           {
           }
           else
           {
+            if ( theParams.ToMakeBoundary() )
+            {
+              GetMeshDS()->Modified();
+              throw SALOME_Exception( SMESH_Comment("Can't extrude node #") << node->GetID() );
+            }
             break; // newNodesItVec will be shorter than nbNodes
           }
         }
             break; // newNodesItVec will be shorter than nbNodes
           }
         }
@@ -6022,6 +6085,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet     theElements[2],
       if ( nbEdges > 0 )
         break;
     }
       if ( nbEdges > 0 )
         break;
     }
+    // fall through
     default:
     {
       for ( int di = -1; di <= 1; di += 2 )
     default:
     {
       for ( int di = -1; di <= 1; di += 2 )
@@ -6367,7 +6431,7 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
  *  \param [in] theValue - offset value
  *  \param [out] theTgtMesh - a mesh to add offset elements to
  *  \param [in] theMakeGroups - to generate groups
  *  \param [in] theValue - offset value
  *  \param [out] theTgtMesh - a mesh to add offset elements to
  *  \param [in] theMakeGroups - to generate groups
- *  \return PGroupIDs - IDs of created groups
+ *  \return PGroupIDs - IDs of created groups. NULL means failure
  */
 //================================================================================
 
  */
 //================================================================================
 
@@ -6419,7 +6483,7 @@ SMESH_MeshEditor::PGroupIDs SMESH_MeshEditor::Offset( TIDSortedElemSet & theElem
 
   // copy offsetMesh to theTgtMesh
 
 
   // copy offsetMesh to theTgtMesh
 
-  int idShift = meshDS->MaxNodeID();
+  smIdType idShift = meshDS->MaxNodeID();
   for ( size_t i = 0; i < new2OldNodes.size(); ++i )
     if ( const SMDS_MeshNode* n = new2OldNodes[ i ].first )
     {
   for ( size_t i = 0; i < new2OldNodes.size(); ++i )
     if ( const SMDS_MeshNode* n = new2OldNodes[ i ].first )
     {
@@ -6454,6 +6518,8 @@ SMESH_MeshEditor::PGroupIDs SMESH_MeshEditor::Offset( TIDSortedElemSet & theElem
   PGroupIDs newGroupIDs;
   if ( theMakeGroups )
     newGroupIDs = generateGroups( srcNodes, srcElems, "offset", theTgtMesh, false );
   PGroupIDs newGroupIDs;
   if ( theMakeGroups )
     newGroupIDs = generateGroups( srcNodes, srcElems, "offset", theTgtMesh, false );
+  else
+    newGroupIDs.reset( new std::list< int > );
 
   return newGroupIDs;
 }
 
   return newGroupIDs;
 }
@@ -6787,7 +6853,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes,
 
   TNodeNodeMap nodeNodeMap; // node to replace - new node
   set<const SMDS_MeshElement*> elems; // all elements with changed nodes
 
   TNodeNodeMap nodeNodeMap; // node to replace - new node
   set<const SMDS_MeshElement*> elems; // all elements with changed nodes
-  list< int > rmElemIds, rmNodeIds;
+  list< smIdType > rmElemIds, rmNodeIds;
   vector< ElemFeatures > newElemDefs;
 
   // Fill nodeNodeMap and elems
   vector< ElemFeatures > newElemDefs;
 
   // Fill nodeNodeMap and elems
@@ -6893,9 +6959,19 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes,
 
     for ( size_t i = 0; i < newElemDefs.size(); ++i )
     {
 
     for ( size_t i = 0; i < newElemDefs.size(); ++i )
     {
-      if ( i > 0 || !mesh->ChangeElementNodes( elem,
-                                               & newElemDefs[i].myNodes[0],
-                                               newElemDefs[i].myNodes.size() ))
+      bool elemChanged = false;
+      if ( i == 0 )
+      {
+        if ( elem->GetGeomType() == SMDSGeom_POLYHEDRA )
+          elemChanged = mesh->ChangePolyhedronNodes( elem,
+                                                     newElemDefs[i].myNodes,
+                                                     newElemDefs[i].myPolyhedQuantities );
+        else
+          elemChanged = mesh->ChangeElementNodes( elem,
+                                                  & newElemDefs[i].myNodes[0],
+                                                  newElemDefs[i].myNodes.size() );
+      }
+      if ( i > 0 || !elemChanged )
       {
         if ( i == 0 )
         {
       {
         if ( i == 0 )
         {
@@ -7062,6 +7138,7 @@ bool SMESH_MeshEditor::applyMerge( const SMDS_MeshElement* elem,
         // each face has to be analyzed in order to check volume validity
         if ( const SMDS_MeshVolume* aPolyedre = SMDS_Mesh::DownCast< SMDS_MeshVolume >( elem ))
         {
         // each face has to be analyzed in order to check volume validity
         if ( const SMDS_MeshVolume* aPolyedre = SMDS_Mesh::DownCast< SMDS_MeshVolume >( elem ))
         {
+          toRemove = false;
           int nbFaces = aPolyedre->NbFaces();
 
           vector<const SMDS_MeshNode *>& poly_nodes = newElemDefs[0].myNodes;
           int nbFaces = aPolyedre->NbFaces();
 
           vector<const SMDS_MeshNode *>& poly_nodes = newElemDefs[0].myNodes;
@@ -7382,12 +7459,12 @@ bool SMESH_MeshEditor::applyMerge( const SMDS_MeshElement* elem,
 // purpose : allow comparing elements basing on their nodes
 // ========================================================
 
 // purpose : allow comparing elements basing on their nodes
 // ========================================================
 
-class ComparableElement : public boost::container::flat_set< int >
+class ComparableElement : public boost::container::flat_set< smIdType >
 {
 {
-  typedef boost::container::flat_set< int >  int_set;
+  typedef boost::container::flat_set< smIdType >  int_set;
 
   const SMDS_MeshElement* myElem;
 
   const SMDS_MeshElement* myElem;
-  int                     mySumID;
+  smIdType                mySumID;
   mutable int             myGroupID;
 
 public:
   mutable int             myGroupID;
 
 public:
@@ -7398,7 +7475,7 @@ public:
     this->reserve( theElem->NbNodes() );
     for ( SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator(); nodeIt->more(); )
     {
     this->reserve( theElem->NbNodes() );
     for ( SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator(); nodeIt->more(); )
     {
-      int id = nodeIt->next()->GetID();
+      smIdType id = nodeIt->next()->GetID();
       mySumID += id;
       this->insert( id );
     }
       mySumID += id;
       this->insert( id );
     }
@@ -7410,9 +7487,10 @@ public:
   //int& GroupID() const { return const_cast< int& >( myGroupID ); }
 
   ComparableElement( const ComparableElement& theSource ) // move copy
   //int& GroupID() const { return const_cast< int& >( myGroupID ); }
 
   ComparableElement( const ComparableElement& theSource ) // move copy
+    : int_set()
   {
     ComparableElement& src = const_cast< ComparableElement& >( theSource );
   {
     ComparableElement& src = const_cast< ComparableElement& >( theSource );
-    (int_set&) (*this ) = boost::move( src );
+    (int_set&) (*this ) = std::move( src );
     myElem    = src.myElem;
     mySumID   = src.mySumID;
     myGroupID = src.myGroupID;
     myElem    = src.myElem;
     mySumID   = src.mySumID;
     myGroupID = src.myGroupID;
@@ -7420,7 +7498,7 @@ public:
 
   static int HashCode(const ComparableElement& se, int limit )
   {
 
   static int HashCode(const ComparableElement& se, int limit )
   {
-    return ::HashCode( se.mySumID, limit );
+    return ::HashCode( FromSmIdType<int>(se.mySumID), limit );
   }
   static Standard_Boolean IsEqual(const ComparableElement& se1, const ComparableElement& se2 )
   {
   }
   static Standard_Boolean IsEqual(const ComparableElement& se1, const ComparableElement& se2 )
   {
@@ -7445,7 +7523,7 @@ void SMESH_MeshEditor::FindEqualElements( TIDSortedElemSet &        theElements,
   else                       elemIt = SMESHUtils::elemSetIterator( theElements );
 
   typedef NCollection_Map< ComparableElement, ComparableElement > TMapOfElements;
   else                       elemIt = SMESHUtils::elemSetIterator( theElements );
 
   typedef NCollection_Map< ComparableElement, ComparableElement > TMapOfElements;
-  typedef std::list<int>                                          TGroupOfElems;
+  typedef std::list<smIdType>                                     TGroupOfElems;
   TMapOfElements               mapOfElements;
   std::vector< TGroupOfElems > arrayOfGroups;
   TGroupOfElems                groupOfElems;
   TMapOfElements               mapOfElements;
   std::vector< TGroupOfElems > arrayOfGroups;
   TGroupOfElems                groupOfElems;
@@ -7453,6 +7531,8 @@ void SMESH_MeshEditor::FindEqualElements( TIDSortedElemSet &        theElements,
   while ( elemIt->more() )
   {
     const SMDS_MeshElement* curElem = elemIt->next();
   while ( elemIt->more() )
   {
     const SMDS_MeshElement* curElem = elemIt->next();
+    if ( curElem->IsNull() )
+      continue;
     ComparableElement      compElem = curElem;
     // check uniqueness
     const ComparableElement& elemInSet = mapOfElements.Added( compElem );
     ComparableElement      compElem = curElem;
     // check uniqueness
     const ComparableElement& elemInSet = mapOfElements.Added( compElem );
@@ -7489,7 +7569,7 @@ void SMESH_MeshEditor::MergeElements(TListOfListOfElementsID & theGroupsOfElemen
 {
   ClearLastCreated();
 
 {
   ClearLastCreated();
 
-  typedef list<int> TListOfIDs;
+  typedef list<smIdType> TListOfIDs;
   TListOfIDs rmElemIds; // IDs of elems to remove
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
   TListOfIDs rmElemIds; // IDs of elems to remove
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
@@ -7588,35 +7668,37 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode*             theFirst
   theNodes.push_back( theSecondNode );
 
   const SMDS_MeshNode *nIgnore = theFirstNode, *nStart = theSecondNode;
   theNodes.push_back( theSecondNode );
 
   const SMDS_MeshNode *nIgnore = theFirstNode, *nStart = theSecondNode;
-  TIDSortedElemSet foundElems;
+  //TIDSortedElemSet foundElems;
   bool needTheLast = ( theLastNode != 0 );
 
   bool needTheLast = ( theLastNode != 0 );
 
+  vector<const SMDS_MeshNode*> nodes;
+  
   while ( nStart != theLastNode ) {
     if ( nStart == theFirstNode )
       return !needTheLast;
 
   while ( nStart != theLastNode ) {
     if ( nStart == theFirstNode )
       return !needTheLast;
 
-    // find all free border faces sharing form nStart
+    // find all free border faces sharing nStart
 
     list< const SMDS_MeshElement* > curElemList;
     list< const SMDS_MeshNode* >    nStartList;
     SMDS_ElemIteratorPtr invElemIt = nStart->GetInverseElementIterator(SMDSAbs_Face);
     while ( invElemIt->more() ) {
       const SMDS_MeshElement* e = invElemIt->next();
 
     list< const SMDS_MeshElement* > curElemList;
     list< const SMDS_MeshNode* >    nStartList;
     SMDS_ElemIteratorPtr invElemIt = nStart->GetInverseElementIterator(SMDSAbs_Face);
     while ( invElemIt->more() ) {
       const SMDS_MeshElement* e = invElemIt->next();
-      if ( e == curElem || foundElems.insert( e ).second ) {
+      //if ( e == curElem || foundElems.insert( e ).second ) // e can encounter twice in border
+      {
         // get nodes
         // get nodes
-        int iNode = 0, nbNodes = e->NbNodes();
-        vector<const SMDS_MeshNode*> nodes( nbNodes+1 );
         nodes.assign( SMDS_MeshElement::iterator( e->interlacedNodesIterator() ),
                       SMDS_MeshElement::iterator() );
         nodes.push_back( nodes[ 0 ]);
 
         // check 2 links
         nodes.assign( SMDS_MeshElement::iterator( e->interlacedNodesIterator() ),
                       SMDS_MeshElement::iterator() );
         nodes.push_back( nodes[ 0 ]);
 
         // check 2 links
+        int iNode = 0, nbNodes = nodes.size() - 1;
         for ( iNode = 0; iNode < nbNodes; iNode++ )
         for ( iNode = 0; iNode < nbNodes; iNode++ )
-          if (((nodes[ iNode ] == nStart && nodes[ iNode + 1] != nIgnore ) ||
-               (nodes[ iNode + 1] == nStart && nodes[ iNode ] != nIgnore )) &&
-              ControlFreeBorder( &nodes[ iNode ], e->GetID() ))
+          if ((( nodes[ iNode ] == nStart && nodes[ iNode + 1] != nIgnore ) ||
+               ( nodes[ iNode + 1] == nStart && nodes[ iNode ] != nIgnore )) &&
+              ( ControlFreeBorder( &nodes[ iNode ], e->GetID() )))
           {
           {
-            nStartList.push_back( nodes[ iNode + ( nodes[ iNode ] == nStart ? 1 : 0 )]);
+            nStartList.push_back( nodes[ iNode + ( nodes[ iNode ] == nStart )]);
             curElemList.push_back( e );
           }
       }
             curElemList.push_back( e );
           }
       }
@@ -7668,7 +7750,7 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode*             theFirst
         else if ( !contNodes[0].empty() && !contNodes[1].empty() ) {
           // choice: clear a worse one
           int iLongest = ( contNodes[0].size() < contNodes[1].size() ? 1 : 0 );
         else if ( !contNodes[0].empty() && !contNodes[1].empty() ) {
           // choice: clear a worse one
           int iLongest = ( contNodes[0].size() < contNodes[1].size() ? 1 : 0 );
-          int iWorse = ( needTheLast ? 1 - iLongest : iLongest );
+          int   iWorse = ( needTheLast ? 1 - iLongest : iLongest );
           contNodes[ iWorse ].clear();
           contFaces[ iWorse ].clear();
         }
           contNodes[ iWorse ].clear();
           contFaces[ iWorse ].clear();
         }
@@ -7679,13 +7761,11 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode*             theFirst
       // push_back the best free border
       cNL = & contNodes[ contNodes[0].empty() ? 1 : 0 ];
       cFL = & contFaces[ contFaces[0].empty() ? 1 : 0 ];
       // push_back the best free border
       cNL = & contNodes[ contNodes[0].empty() ? 1 : 0 ];
       cFL = & contFaces[ contFaces[0].empty() ? 1 : 0 ];
-      theNodes.pop_back(); // remove nIgnore
+      //theNodes.pop_back(); // remove nIgnore
       theNodes.pop_back(); // remove nStart
       theNodes.pop_back(); // remove nStart
-      theFaces.pop_back(); // remove curElem
-      list< const SMDS_MeshNode* >::iterator nIt = cNL->begin();
-      list< const SMDS_MeshElement* >::iterator fIt = cFL->begin();
-      for ( ; nIt != cNL->end(); nIt++ ) theNodes.push_back( *nIt );
-      for ( ; fIt != cFL->end(); fIt++ ) theFaces.push_back( *fIt );
+      //theFaces.pop_back(); // remove curElem
+      theNodes.splice( theNodes.end(), *cNL );
+      theFaces.splice( theFaces.end(), *cFL );
       return true;
 
     } // several continuations found
       return true;
 
     } // several continuations found
@@ -8026,6 +8106,10 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
     nIt[0] = nSide[0].begin(); eIt[0] = eSide[0].begin();
     nIt[1] = nSide[1].begin(); eIt[1] = eSide[1].begin();
 
     nIt[0] = nSide[0].begin(); eIt[0] = eSide[0].begin();
     nIt[1] = nSide[1].begin(); eIt[1] = eSide[1].begin();
 
+    // element can be split while iterating on border if it has two edges in the border
+    std::map< const SMDS_MeshElement* , const SMDS_MeshElement* > elemReplaceMap;
+    std::map< const SMDS_MeshElement* , const SMDS_MeshElement* >::iterator elemReplaceMapIt;
+
     TElemOfNodeListMap insertMap;
     TElemOfNodeListMap::iterator insertMapIt;
     // insertMap is
     TElemOfNodeListMap insertMap;
     TElemOfNodeListMap::iterator insertMapIt;
     // insertMap is
@@ -8073,12 +8157,15 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
         const SMDS_MeshNode*    nIns = *nIt [ 1 - intoBord ];
         if ( intoBord == 1 ) {
           // move node of the border to be on a link of elem of the side
         const SMDS_MeshNode*    nIns = *nIt [ 1 - intoBord ];
         if ( intoBord == 1 ) {
           // move node of the border to be on a link of elem of the side
-          gp_XYZ p1 (n1->X(), n1->Y(), n1->Z());
-          gp_XYZ p2 (n2->X(), n2->Y(), n2->Z());
+          SMESH_NodeXYZ p1( n1 ), p2( n2 );
           double ratio = du / ( param[ 1 ][ i[1] ] - param[ 1 ][ i[1]-1 ]);
           gp_XYZ p = p2 * ( 1 - ratio ) + p1 * ratio;
           GetMeshDS()->MoveNode( nIns, p.X(), p.Y(), p.Z() );
         }
           double ratio = du / ( param[ 1 ][ i[1] ] - param[ 1 ][ i[1]-1 ]);
           gp_XYZ p = p2 * ( 1 - ratio ) + p1 * ratio;
           GetMeshDS()->MoveNode( nIns, p.X(), p.Y(), p.Z() );
         }
+        elemReplaceMapIt = elemReplaceMap.find( elem );
+        if ( elemReplaceMapIt != elemReplaceMap.end() )
+          elem = elemReplaceMapIt->second;
+
         insertMapIt = insertMap.find( elem );
         bool  notFound = ( insertMapIt == insertMap.end() );
         bool otherLink = ( !notFound && (*insertMapIt).second.front() != n1 );
         insertMapIt = insertMap.find( elem );
         bool  notFound = ( insertMapIt == insertMap.end() );
         bool otherLink = ( !notFound && (*insertMapIt).second.front() != n1 );
@@ -8101,8 +8188,10 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
             UpdateVolumes(n12, n22, nodeList);
           }
           // 3. find an element appeared on n1 and n2 after the insertion
             UpdateVolumes(n12, n22, nodeList);
           }
           // 3. find an element appeared on n1 and n2 after the insertion
-          insertMap.erase( elem );
-          elem = findAdjacentFace( n1, n2, 0 );
+          insertMap.erase( insertMapIt );
+          const SMDS_MeshElement* elem2 = findAdjacentFace( n1, n2, 0 );
+          elemReplaceMap.insert( std::make_pair( elem, elem2 ));
+          elem = elem2;
         }
         if ( notFound || otherLink ) {
           // add element and nodes of the side into the insertMap
         }
         if ( notFound || otherLink ) {
           // add element and nodes of the side into the insertMap
@@ -8195,8 +8284,8 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
     TListOfListOfElementsID::iterator itGroups = equalGroups.begin();
     for ( ; itGroups != equalGroups.end(); ++itGroups )
     {
     TListOfListOfElementsID::iterator itGroups = equalGroups.begin();
     for ( ; itGroups != equalGroups.end(); ++itGroups )
     {
-      list< int >& group = *itGroups;
-      list< int >::iterator id = group.begin();
+      list< smIdType >& group = *itGroups;
+      list< smIdType >::iterator id = group.begin();
       for ( ++id; id != group.end(); ++id )
         if ( const SMDS_MeshElement* seg = GetMeshDS()->FindElement( *id ))
           segments.erase( seg );
       for ( ++id; id != group.end(); ++id )
         if ( const SMDS_MeshElement* seg = GetMeshDS()->FindElement( *id ))
           segments.erase( seg );
@@ -8628,12 +8717,12 @@ namespace
  */
 //=======================================================================
 
  */
 //=======================================================================
 
-int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh *   theSm,
-                                             SMESH_MesherHelper& theHelper,
-                                             const bool          theForce3d)
+smIdType SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh *   theSm,
+                                                  SMESH_MesherHelper& theHelper,
+                                                  const bool          theForce3d)
 {
   //MESSAGE("convertElemToQuadratic");
 {
   //MESSAGE("convertElemToQuadratic");
-  int nbElem = 0;
+  smIdType nbElem = 0;
   if( !theSm ) return nbElem;
 
   vector<int> nbNodeInFaces;
   if( !theSm ) return nbElem;
 
   vector<int> nbNodeInFaces;
@@ -8686,7 +8775,7 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh *   theSm,
     }
     // get elem data needed to re-create it
     //
     }
     // get elem data needed to re-create it
     //
-    const int id      = elem->GetID();
+    const smIdType id = elem->GetID();
     const int nbNodes = elem->NbCornerNodes();
     nodes.assign(elem->begin_nodes(), elem->end_nodes());
     if ( aGeomType == SMDSEntity_Polyhedra )
     const int nbNodes = elem->NbCornerNodes();
     nodes.assign(elem->begin_nodes(), elem->end_nodes());
     if ( aGeomType == SMDSEntity_Polyhedra )
@@ -8781,7 +8870,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theT
   aHelper.ToFixNodeParameters( true );
 
   // convert elements assigned to sub-meshes
   aHelper.ToFixNodeParameters( true );
 
   // convert elements assigned to sub-meshes
-  int nbCheckedElems = 0;
+  smIdType nbCheckedElems = 0;
   if ( myMesh->HasShapeToMesh() )
   {
     if ( SMESH_subMesh *aSubMesh = myMesh->GetSubMeshContaining(myMesh->GetShapeToMesh()))
   if ( myMesh->HasShapeToMesh() )
   {
     if ( SMESH_subMesh *aSubMesh = myMesh->GetSubMeshContaining(myMesh->GetShapeToMesh()))
@@ -8798,7 +8887,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theT
   }
 
   // convert elements NOT assigned to sub-meshes
   }
 
   // convert elements NOT assigned to sub-meshes
-  int totalNbElems = meshDS->NbEdges() + meshDS->NbFaces() + meshDS->NbVolumes();
+  smIdType totalNbElems = meshDS->NbEdges() + meshDS->NbFaces() + meshDS->NbVolumes();
   if ( nbCheckedElems < totalNbElems ) // not all elements are in sub-meshes
   {
     aHelper.SetElementsOnShape(false);
   if ( nbCheckedElems < totalNbElems ) // not all elements are in sub-meshes
   {
     aHelper.SetElementsOnShape(false);
@@ -8811,7 +8900,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theT
       const SMDS_MeshEdge* edge = aEdgeItr->next();
       if ( !edge->IsQuadratic() )
       {
       const SMDS_MeshEdge* edge = aEdgeItr->next();
       if ( !edge->IsQuadratic() )
       {
-        int                  id = edge->GetID();
+        smIdType                  id = edge->GetID();
         const SMDS_MeshNode* n1 = edge->GetNode(0);
         const SMDS_MeshNode* n2 = edge->GetNode(1);
 
         const SMDS_MeshNode* n1 = edge->GetNode(0);
         const SMDS_MeshNode* n2 = edge->GetNode(1);
 
@@ -8852,7 +8941,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theT
       if ( alreadyOK )
         continue;
 
       if ( alreadyOK )
         continue;
 
-      const int id = face->GetID();
+      const smIdType id = face->GetID();
       vector<const SMDS_MeshNode *> nodes ( face->begin_nodes(), face->end_nodes());
 
       meshDS->RemoveFreeElement(face, smDS, /*fromGroups=*/false);
       vector<const SMDS_MeshNode *> nodes ( face->begin_nodes(), face->end_nodes());
 
       meshDS->RemoveFreeElement(face, smDS, /*fromGroups=*/false);
@@ -8908,7 +8997,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, const bool theT
           continue;
         }
       }
           continue;
         }
       }
-      const int id = volume->GetID();
+      const smIdType id = volume->GetID();
       vector<const SMDS_MeshNode *> nodes (volume->begin_nodes(), volume->end_nodes());
       if ( type == SMDSEntity_Polyhedra )
         nbNodeInFaces = static_cast<const SMDS_MeshVolume* >(volume)->GetQuantities();
       vector<const SMDS_MeshNode *> nodes (volume->begin_nodes(), volume->end_nodes());
       if ( type == SMDSEntity_Polyhedra )
         nbNodeInFaces = static_cast<const SMDS_MeshVolume* >(volume)->GetQuantities();
@@ -9088,7 +9177,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool        theForce3d,
     if ( alreadyOK ) continue;
 
     const SMDSAbs_ElementType type = elem->GetType();
     if ( alreadyOK ) continue;
 
     const SMDSAbs_ElementType type = elem->GetType();
-    const int                   id = elem->GetID();
+    const smIdType              id = elem->GetID();
     const int              nbNodes = elem->NbCornerNodes();
     vector<const SMDS_MeshNode *> nodes ( elem->begin_nodes(), elem->end_nodes());
 
     const int              nbNodes = elem->NbCornerNodes();
     vector<const SMDS_MeshNode *> nodes ( elem->begin_nodes(), elem->end_nodes());
 
@@ -9149,15 +9238,15 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool        theForce3d,
 //=======================================================================
 /*!
  * \brief Convert quadratic elements to linear ones and remove quadratic nodes
 //=======================================================================
 /*!
  * \brief Convert quadratic elements to linear ones and remove quadratic nodes
- * \return int - nb of checked elements
+ * \return smIdType - nb of checked elements
  */
 //=======================================================================
 
  */
 //=======================================================================
 
-int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh *    theSm,
-                                     SMDS_ElemIteratorPtr theItr,
-                                     const int            theShapeID)
+smIdType SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh *    theSm,
+                                          SMDS_ElemIteratorPtr theItr,
+                                          const int            /*theShapeID*/)
 {
 {
-  int nbElem = 0;
+  smIdType nbElem = 0;
   SMESHDS_Mesh* meshDS = GetMeshDS();
   ElemFeatures elemType;
   vector<const SMDS_MeshNode *> nodes;
   SMESHDS_Mesh* meshDS = GetMeshDS();
   ElemFeatures elemType;
   vector<const SMDS_MeshNode *> nodes;
@@ -9202,7 +9291,7 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh *    theSm,
 
 bool SMESH_MeshEditor::ConvertFromQuadratic()
 {
 
 bool SMESH_MeshEditor::ConvertFromQuadratic()
 {
-  int nbCheckedElems = 0;
+  smIdType nbCheckedElems = 0;
   if ( myMesh->HasShapeToMesh() )
   {
     if ( SMESH_subMesh *aSubMesh = myMesh->GetSubMeshContaining(myMesh->GetShapeToMesh()))
   if ( myMesh->HasShapeToMesh() )
   {
     if ( SMESH_subMesh *aSubMesh = myMesh->GetSubMeshContaining(myMesh->GetShapeToMesh()))
@@ -9216,7 +9305,7 @@ bool SMESH_MeshEditor::ConvertFromQuadratic()
     }
   }
 
     }
   }
 
-  int totalNbElems =
+  smIdType totalNbElems =
     GetMeshDS()->NbEdges() + GetMeshDS()->NbFaces() + GetMeshDS()->NbVolumes();
   if ( nbCheckedElems < totalNbElems ) // not all elements are in submeshes
   {
     GetMeshDS()->NbEdges() + GetMeshDS()->NbFaces() + GetMeshDS()->NbVolumes();
   if ( nbCheckedElems < totalNbElems ) // not all elements are in submeshes
   {
@@ -9255,7 +9344,7 @@ void SMESH_MeshEditor::ConvertFromQuadratic(TIDSortedElemSet& theElements)
   if ( theElements.empty() ) return;
 
   // collect IDs of medium nodes of theElements; some of these nodes will be removed
   if ( theElements.empty() ) return;
 
   // collect IDs of medium nodes of theElements; some of these nodes will be removed
-  set<int> mediumNodeIDs;
+  set<smIdType> mediumNodeIDs;
   TIDSortedElemSet::iterator eIt = theElements.begin();
   for ( ; eIt != theElements.end(); ++eIt )
   {
   TIDSortedElemSet::iterator eIt = theElements.begin();
   for ( ; eIt != theElements.end(); ++eIt )
   {
@@ -9274,7 +9363,7 @@ void SMESH_MeshEditor::ConvertFromQuadratic(TIDSortedElemSet& theElements)
 
   // get remaining medium nodes
   TIDSortedNodeSet mediumNodes;
 
   // get remaining medium nodes
   TIDSortedNodeSet mediumNodes;
-  set<int>::iterator nIdsIt = mediumNodeIDs.begin();
+  set<smIdType>::iterator nIdsIt = mediumNodeIDs.begin();
   for ( ; nIdsIt != mediumNodeIDs.end(); ++nIdsIt )
     if ( const SMDS_MeshNode* n = GetMeshDS()->FindNode( *nIdsIt ))
       mediumNodes.insert( mediumNodes.end(), n );
   for ( ; nIdsIt != mediumNodeIDs.end(); ++nIdsIt )
     if ( const SMDS_MeshNode* n = GetMeshDS()->FindNode( *nIdsIt ))
       mediumNodes.insert( mediumNodes.end(), n );
@@ -9302,7 +9391,7 @@ void SMESH_MeshEditor::ConvertFromQuadratic(TIDSortedElemSet& theElements)
             const SMDS_MeshElement* eComplex = invIt2->next();
             if ( eComplex->IsQuadratic() && !allMediumNodesIn( eComplex, mediumNodes))
             {
             const SMDS_MeshElement* eComplex = invIt2->next();
             if ( eComplex->IsQuadratic() && !allMediumNodesIn( eComplex, mediumNodes))
             {
-              int nbCommonNodes = SMESH_MeshAlgos::GetCommonNodes( e, eComplex ).size();
+              int nbCommonNodes = SMESH_MeshAlgos::NbCommonNodes( e, eComplex );
               if ( nbCommonNodes == e->NbNodes())
               {
                 complexFound = true;
               if ( nbCommonNodes == e->NbNodes())
               {
                 complexFound = true;
@@ -9763,7 +9852,7 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
   if ( aResult != SEW_OK)
     return aResult;
 
   if ( aResult != SEW_OK)
     return aResult;
 
-  list< int > nodeIDsToRemove;
+  list< smIdType > nodeIDsToRemove;
   vector< const SMDS_MeshNode*> nodes;
   ElemFeatures elemType;
 
   vector< const SMDS_MeshNode*> nodes;
   ElemFeatures elemType;
 
@@ -9844,10 +9933,10 @@ SMESH_MeshEditor::FindMatchingNodes(set<const SMDS_MeshElement*>& theSide1,
   set<const SMDS_MeshElement*> * faceSetPtr[] = { &theSide1, &theSide2 };
 
   nReplaceMap.clear();
   set<const SMDS_MeshElement*> * faceSetPtr[] = { &theSide1, &theSide2 };
 
   nReplaceMap.clear();
-  if ( theFirstNode1 != theFirstNode2 )
-    nReplaceMap.insert( make_pair( theFirstNode1, theFirstNode2 ));
-  if ( theSecondNode1 != theSecondNode2 )
-    nReplaceMap.insert( make_pair( theSecondNode1, theSecondNode2 ));
+  //if ( theFirstNode1 != theFirstNode2 )
+  nReplaceMap.insert( make_pair( theFirstNode1, theFirstNode2 ));
+  //if ( theSecondNode1 != theSecondNode2 )
+  nReplaceMap.insert( make_pair( theSecondNode1, theSecondNode2 ));
 
   set< SMESH_TLink > linkSet; // set of nodes where order of nodes is ignored
   linkSet.insert( SMESH_TLink( theFirstNode1, theSecondNode1 ));
 
   set< SMESH_TLink > linkSet; // set of nodes where order of nodes is ignored
   linkSet.insert( SMESH_TLink( theFirstNode1, theSecondNode1 ));
@@ -10137,7 +10226,7 @@ namespace // automatically find theAffectedElems for DoubleNodes()
         if ( SMESH_MeshAlgos::FaceNormal( _elems[1], norm ))
           avgNorm += norm;
 
         if ( SMESH_MeshAlgos::FaceNormal( _elems[1], norm ))
           avgNorm += norm;
 
-        gp_XYZ bordDir( SMESH_NodeXYZ( _nodes[0] ) - SMESH_NodeXYZ( _nodes[1] ));
+        gp_XYZ bordDir( SMESH_NodeXYZ( this->_nodes[0] ) - SMESH_NodeXYZ( this->_nodes[1] ));
         norm = bordDir ^ avgNorm;
       }
       else
         norm = bordDir ^ avgNorm;
       }
       else
@@ -10163,7 +10252,8 @@ namespace // automatically find theAffectedElems for DoubleNodes()
       if ( maxX < 0 )
       {
         _elems[0]->setIsMarked( false );
       if ( maxX < 0 )
       {
         _elems[0]->setIsMarked( false );
-        _elems[1]->setIsMarked( true );
+        if ( _elems[1] )
+          _elems[1]->setIsMarked( true );
       }
     }
 
       }
     }
 
@@ -10335,7 +10425,11 @@ namespace // automatically find theAffectedElems for DoubleNodes()
     {
       fissure.reserve( theElemsOrNodes.size() );
       for ( ; elIt != theElemsOrNodes.end(); ++elIt )
     {
       fissure.reserve( theElemsOrNodes.size() );
       for ( ; elIt != theElemsOrNodes.end(); ++elIt )
+      {
         fissure.push_back( std::move( FissureBorder( *elIt, elemsByFacet )));
         fissure.push_back( std::move( FissureBorder( *elIt, elemsByFacet )));
+        if ( !fissure.back()._elems[1] )
+          fissure.pop_back();
+      }
     }
     if ( fissure.empty() )
       return;
     }
     if ( fissure.empty() )
       return;
@@ -10842,7 +10936,7 @@ namespace {
   \brief Identify the elements that will be affected by node duplication (actual duplication is not performed).
   This method is the first step of DoubleNodeElemGroupsInRegion.
   \param theElems - list of groups of elements (edges or faces) to be replicated
   \brief Identify the elements that will be affected by node duplication (actual duplication is not performed).
   This method is the first step of DoubleNodeElemGroupsInRegion.
   \param theElems - list of groups of elements (edges or faces) to be replicated
-  \param theNodesNot - list of groups of nodes not to replicated
+  \param theNodesNot - list of groups of nodes not to replicate
   \param theShape - shape to detect affected elements (element which geometric center
          located on or inside shape). If the shape is null, detection is done on faces orientations
          (select elements with a gravity center on the side given by faces normals).
   \param theShape - shape to detect affected elements (element which geometric center
          located on or inside shape). If the shape is null, detection is done on faces orientations
          (select elements with a gravity center on the side given by faces normals).
@@ -10984,7 +11078,7 @@ double SMESH_MeshEditor::OrientedAngle(const gp_Pnt& p0, const gp_Pnt& p1, const
   try {
     return n2.AngleWithRef(n1, vref);
   }
   try {
     return n2.AngleWithRef(n1, vref);
   }
-  catch ( Standard_Failure ) {
+  catch ( Standard_Failure& ) {
   }
   return Max( v1.Magnitude(), v2.Magnitude() );
 }
   }
   return Max( v1.Magnitude(), v2.Magnitude() );
 }
@@ -11024,16 +11118,9 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
   //     build the list of nodes shared by 2 or more domains, with their domain indexes
 
   std::map<DownIdType, std::map<int,int>, DownIdCompare> faceDomains; // face --> (id domain --> id volume)
   //     build the list of nodes shared by 2 or more domains, with their domain indexes
 
   std::map<DownIdType, std::map<int,int>, DownIdCompare> faceDomains; // face --> (id domain --> id volume)
-  std::map<int,int>celldom; // cell vtkId --> domain
+  std::map<int,int> celldom; // cell vtkId --> domain
   std::map<DownIdType, std::map<int,int>, DownIdCompare> cellDomains;  // oldNode --> (id domain --> id cell)
   std::map<int, std::map<int,int> > nodeDomains; // oldId -->  (domainId --> newId)
   std::map<DownIdType, std::map<int,int>, DownIdCompare> cellDomains;  // oldNode --> (id domain --> id cell)
   std::map<int, std::map<int,int> > nodeDomains; // oldId -->  (domainId --> newId)
-  faceDomains.clear();
-  celldom.clear();
-  cellDomains.clear();
-  nodeDomains.clear();
-  std::map<int,int> emptyMap;
-  std::set<int> emptySet;
-  emptyMap.clear();
 
   //MESSAGE(".. Number of domains :"<<theElems.size());
 
 
   //MESSAGE(".. Number of domains :"<<theElems.size());
 
@@ -11083,7 +11170,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
       const SMDS_MeshElement* anElem = *elemItr;
       if (!anElem)
         continue;
       const SMDS_MeshElement* anElem = *elemItr;
       if (!anElem)
         continue;
-      int vtkId = anElem->GetVtkID();
+      vtkIdType vtkId = anElem->GetVtkID();
       //MESSAGE("  vtkId " << vtkId << " smdsId " << anElem->GetID());
       int neighborsVtkIds[NBMAXNEIGHBORS];
       int downIds[NBMAXNEIGHBORS];
       //MESSAGE("  vtkId " << vtkId << " smdsId " << anElem->GetID());
       int neighborsVtkIds[NBMAXNEIGHBORS];
       int downIds[NBMAXNEIGHBORS];
@@ -11091,7 +11178,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
       int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId);
       for (int n = 0; n < nbNeighbors; n++)
       {
       int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId);
       for (int n = 0; n < nbNeighbors; n++)
       {
-        int smdsId = meshDS->FromVtkToSmds(neighborsVtkIds[n]);
+        smIdType smdsId = meshDS->FromVtkToSmds(neighborsVtkIds[n]);
         const SMDS_MeshElement* elem = meshDS->FindElement(smdsId);
         if (elem && ! domain.count(elem)) // neighbor is in another domain : face is shared
         {
         const SMDS_MeshElement* elem = meshDS->FindElement(smdsId);
         if (elem && ! domain.count(elem)) // neighbor is in another domain : face is shared
         {
@@ -11143,14 +11230,13 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
       DownIdType face = itface->first;
       //MESSAGE(" --- face " << face.cellId);
       std::set<int> oldNodes;
       DownIdType face = itface->first;
       //MESSAGE(" --- face " << face.cellId);
       std::set<int> oldNodes;
-      oldNodes.clear();
       grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
       std::set<int>::iterator itn = oldNodes.begin();
       for (; itn != oldNodes.end(); ++itn)
       {
         int oldId = *itn;
         //MESSAGE("     node " << oldId);
       grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
       std::set<int>::iterator itn = oldNodes.begin();
       for (; itn != oldNodes.end(); ++itn)
       {
         int oldId = *itn;
         //MESSAGE("     node " << oldId);
-        vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId);
+        vtkCellLinks::Link l = (static_cast <vtkCellLinks *>(grid->GetCellLinks()))->GetLink(oldId);
         for (int i=0; i<l.ncells; i++)
         {
           int vtkId = l.cells[i];
         for (int i=0; i<l.ncells; i++)
         {
           int vtkId = l.cells[i];
@@ -11198,7 +11284,6 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
       DownIdType face = itface->first;
       //MESSAGE(" --- face " << face.cellId);
       std::set<int> oldNodes;
       DownIdType face = itface->first;
       //MESSAGE(" --- face " << face.cellId);
       std::set<int> oldNodes;
-      oldNodes.clear();
       grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
       std::set<int>::iterator itn = oldNodes.begin();
       for (; itn != oldNodes.end(); ++itn)
       grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
       std::set<int>::iterator itn = oldNodes.begin();
       for (; itn != oldNodes.end(); ++itn)
@@ -11259,7 +11344,6 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
       DownIdType face = itface->first;
       //MESSAGE(" --- face " << face.cellId);
       std::set<int> oldNodes;
       DownIdType face = itface->first;
       //MESSAGE(" --- face " << face.cellId);
       std::set<int> oldNodes;
-      oldNodes.clear();
       grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
       int nbMultipleNodes = 0;
       std::set<int>::iterator itn = oldNodes.begin();
       grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
       int nbMultipleNodes = 0;
       std::set<int>::iterator itn = oldNodes.begin();
@@ -11320,7 +11404,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
                   const TIDSortedElemSet& domain = (idom == iRestDom) ? theRestDomElems : theElems[idom];
                   for ( int ivol = 0; ivol < nbvol; ivol++ )
                   {
                   const TIDSortedElemSet& domain = (idom == iRestDom) ? theRestDomElems : theElems[idom];
                   for ( int ivol = 0; ivol < nbvol; ivol++ )
                   {
-                    int smdsId = meshDS->FromVtkToSmds(vtkVolIds[ivol]);
+                    smIdType smdsId = meshDS->FromVtkToSmds(vtkVolIds[ivol]);
                     const SMDS_MeshElement* elem = meshDS->FindElement(smdsId);
                     if (domain.count(elem))
                     {
                     const SMDS_MeshElement* elem = meshDS->FindElement(smdsId);
                     if (domain.count(elem))
                     {
@@ -11329,7 +11413,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
                       //MESSAGE("  domain " << idom << " volume " << elem->GetID());
                       double values[3] = { 0,0,0 };
                       vtkIdType npts = 0;
                       //MESSAGE("  domain " << idom << " volume " << elem->GetID());
                       double values[3] = { 0,0,0 };
                       vtkIdType npts = 0;
-                      vtkIdType* pts = 0;
+                      vtkIdType const *pts(nullptr);
                       grid->GetCellPoints(vtkVolIds[ivol], npts, pts);
                       for ( vtkIdType i = 0; i < npts; ++i )
                       {
                       grid->GetCellPoints(vtkVolIds[ivol], npts, pts);
                       for ( vtkIdType i = 0; i < npts; ++i )
                       {
@@ -11384,7 +11468,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
   std::map<std::string, SMESH_Group*> mapOfJunctionGroups;
 
   //MESSAGE(".. Creation of elements: simple junction");
   std::map<std::string, SMESH_Group*> mapOfJunctionGroups;
 
   //MESSAGE(".. Creation of elements: simple junction");
-  if (createJointElems)
+  if ( createJointElems )
   {
     string joints2DName = "joints2D";
     mapOfJunctionGroups[joints2DName] = this->myMesh->AddGroup(SMDSAbs_Face, joints2DName.c_str());
   {
     string joints2DName = "joints2D";
     mapOfJunctionGroups[joints2DName] = this->myMesh->AddGroup(SMDSAbs_Face, joints2DName.c_str());
@@ -11399,15 +11483,14 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
       DownIdType face = itface->first;
       std::set<int> oldNodes;
       std::set<int>::iterator itn;
       DownIdType face = itface->first;
       std::set<int> oldNodes;
       std::set<int>::iterator itn;
-      oldNodes.clear();
       grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
 
       grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
 
-      std::map<int, int> domvol = itface->second;
+      std::map<int, int>          domvol = itface->second;
       std::map<int, int>::iterator itdom = domvol.begin();
       std::map<int, int>::iterator itdom = domvol.begin();
-      int dom1 = itdom->first;
+      int     dom1 = itdom->first;
       int vtkVolId = itdom->second;
       itdom++;
       int vtkVolId = itdom->second;
       itdom++;
-      int dom2 = itdom->first;
+      int           dom2 = itdom->first;
       SMDS_MeshCell *vol = grid->extrudeVolumeFromFace(vtkVolId, dom1, dom2, oldNodes, nodeDomains,
                                                        nodeQuadDomains);
       stringstream grpname;
       SMDS_MeshCell *vol = grid->extrudeVolumeFromFace(vtkVolId, dom1, dom2, oldNodes, nodeDomains,
                                                        nodeQuadDomains);
       stringstream grpname;
@@ -11464,7 +11547,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
     std::map<std::vector<int>, std::vector<int> >::iterator ite = edgesMultiDomains.begin();
     for (; ite != edgesMultiDomains.end(); ++ite)
     {
     std::map<std::vector<int>, std::vector<int> >::iterator ite = edgesMultiDomains.begin();
     for (; ite != edgesMultiDomains.end(); ++ite)
     {
-      vector<int> nodes = ite->first;
+      vector<int>    nodes = ite->first;
       vector<int> orderDom = ite->second;
       vector<vtkIdType> orderedNodes;
       if (nodes.size() == 2)
       vector<int> orderDom = ite->second;
       vector<vtkIdType> orderedNodes;
       if (nodes.size() == 2)
@@ -11501,10 +11584,9 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
 
   std::map<DownIdType, std::map<int,int>, DownIdCompare> faceOrEdgeDom; // cellToModify --> (id domain --> id cell)
   std::map<int,int> feDom; // vtk id of cell to modify --> id domain
 
   std::map<DownIdType, std::map<int,int>, DownIdCompare> faceOrEdgeDom; // cellToModify --> (id domain --> id cell)
   std::map<int,int> feDom; // vtk id of cell to modify --> id domain
-  faceOrEdgeDom.clear();
-  feDom.clear();
 
   //MESSAGE(".. Modification of elements");
 
   //MESSAGE(".. Modification of elements");
+  SMDSAbs_ElementType domainType = (*theElems[0].begin())->GetType();
   for (int idomain = idom0; idomain < nbDomains; idomain++)
   {
     std::map<int, std::map<int, int> >::const_iterator itnod = nodeDomains.begin();
   for (int idomain = idom0; idomain < nbDomains; idomain++)
   {
     std::map<int, std::map<int, int> >::const_iterator itnod = nodeDomains.begin();
@@ -11512,7 +11594,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
     {
       int oldId = itnod->first;
       //MESSAGE("     node " << oldId);
     {
       int oldId = itnod->first;
       //MESSAGE("     node " << oldId);
-      vtkCellLinks::Link l = grid->GetCellLinks()->GetLink(oldId);
+      vtkCellLinks::Link l = (static_cast< vtkCellLinks *>(grid->GetCellLinks()))->GetLink(oldId);
       for (int i = 0; i < l.ncells; i++)
       {
         int vtkId = l.cells[i];
       for (int i = 0; i < l.ncells; i++)
       {
         int vtkId = l.cells[i];
@@ -11522,13 +11604,29 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
           continue; // new cells: not to be modified
         DownIdType aCell(downId, vtkType);
         int volParents[1000];
           continue; // new cells: not to be modified
         DownIdType aCell(downId, vtkType);
         int volParents[1000];
-        int nbvol = grid->GetParentVolumes(volParents, vtkId);
+        int nbvol = 0;
+        nbvol = grid->GetParentVolumes(volParents, vtkId);
+        if ( domainType == SMDSAbs_Volume )
+        {
+          nbvol = grid->GetParentVolumes(volParents, vtkId);
+        }
+        else // domainType == SMDSAbs_Face
+        {
+          const int            nbFaces = grid->getDownArray(vtkType)->getNumberOfUpCells(downId);
+          const int           *upCells = grid->getDownArray(vtkType)->getUpCells(downId);
+          const unsigned char* upTypes = grid->getDownArray(vtkType)->getUpTypes(downId);
+          for (int i=0; i< nbFaces; i++)
+          {
+            int vtkFaceId = grid->getDownArray( upTypes[i] )->getVtkCellId(upCells[i]);
+            if (vtkFaceId >= 0)
+              volParents[nbvol++] = vtkFaceId;
+          }
+        }
         for (int j = 0; j < nbvol; j++)
           if (celldom.count(volParents[j]) && (celldom[volParents[j]] == idomain))
             if (!feDom.count(vtkId))
             {
               feDom[vtkId] = idomain;
         for (int j = 0; j < nbvol; j++)
           if (celldom.count(volParents[j]) && (celldom[volParents[j]] == idomain))
             if (!feDom.count(vtkId))
             {
               feDom[vtkId] = idomain;
-              faceOrEdgeDom[aCell] = emptyMap;
               faceOrEdgeDom[aCell][idomain] = vtkId; // affect face or edge to the first domain only
               //MESSAGE("affect cell " << this->GetMeshDS()->FromVtkToSmds(vtkId) << " domain " << idomain
               //        << " type " << vtkType << " downId " << downId);
               faceOrEdgeDom[aCell][idomain] = vtkId; // affect face or edge to the first domain only
               //MESSAGE("affect cell " << this->GetMeshDS()->FromVtkToSmds(vtkId) << " domain " << idomain
               //        << " type " << vtkType << " downId " << downId);
@@ -11551,7 +11649,6 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSorted
       DownIdType face = itface->first;
       std::set<int> oldNodes;
       std::set<int>::iterator itn;
       DownIdType face = itface->first;
       std::set<int> oldNodes;
       std::set<int>::iterator itn;
-      oldNodes.clear();
       grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
       //MESSAGE("examine cell, downId " << face.cellId << " type " << int(face.cellType));
       std::map<int, int> localClonedNodeIds;
       grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
       //MESSAGE("examine cell, downId " << face.cellId << " type " << int(face.cellType));
       std::map<int, int> localClonedNodeIds;
@@ -11618,10 +11715,7 @@ bool SMESH_MeshEditor::CreateFlatElementsOnFacesGroups(const std::vector<TIDSort
 
   std::map<const SMDS_MeshNode*, const SMDS_MeshNode*> clonedNodes;
   std::map<const SMDS_MeshNode*, const SMDS_MeshNode*> intermediateNodes;
 
   std::map<const SMDS_MeshNode*, const SMDS_MeshNode*> clonedNodes;
   std::map<const SMDS_MeshNode*, const SMDS_MeshNode*> intermediateNodes;
-  clonedNodes.clear();
-  intermediateNodes.clear();
   std::map<std::string, SMESH_Group*> mapOfJunctionGroups;
   std::map<std::string, SMESH_Group*> mapOfJunctionGroups;
-  mapOfJunctionGroups.clear();
 
   for ( size_t idom = 0; idom < theElems.size(); idom++ )
   {
 
   for ( size_t idom = 0; idom < theElems.size(); idom++ )
   {
@@ -11868,7 +11962,6 @@ void SMESH_MeshEditor::CreateHoleSkin(double                          radius,
   std::set<int> setOfVolToCheck;
 
   std::vector<gp_Pnt> gpnts;
   std::set<int> setOfVolToCheck;
 
   std::vector<gp_Pnt> gpnts;
-  gpnts.clear();
 
   if (isNodeGroup) // --- a group of nodes is provided : find all the volumes using one or more of this nodes
   {
 
   if (isNodeGroup) // --- a group of nodes is provided : find all the volumes using one or more of this nodes
   {
@@ -11955,7 +12048,6 @@ void SMESH_MeshEditor::CreateHoleSkin(double                          radius,
     //     Fill the group of inside volumes
 
     std::map<int, double> mapOfNodeDistance2;
     //     Fill the group of inside volumes
 
     std::map<int, double> mapOfNodeDistance2;
-    mapOfNodeDistance2.clear();
     std::set<int> setOfOutsideVol;
     while (!setOfVolToCheck.empty())
     {
     std::set<int> setOfOutsideVol;
     while (!setOfVolToCheck.empty())
     {
@@ -11964,7 +12056,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double                          radius,
       //MESSAGE("volume to check,  vtkId " << vtkId << " smdsId " << meshDS->FromVtkToSmds(vtkId));
       bool volInside = false;
       vtkIdType npts = 0;
       //MESSAGE("volume to check,  vtkId " << vtkId << " smdsId " << meshDS->FromVtkToSmds(vtkId));
       bool volInside = false;
       vtkIdType npts = 0;
-      vtkIdType* pts = 0;
+      vtkIdType const *pts(nullptr);
       grid->GetCellPoints(vtkId, npts, pts);
       for (int i=0; i<npts; i++)
       {
       grid->GetCellPoints(vtkId, npts, pts);
       for (int i=0; i<npts; i++)
       {
@@ -12132,9 +12224,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double                          radius,
   //     project polylines on subshapes, and partition, to get geom faces
 
   std::map<int, std::set<int> > shapeIdToVtkIdSet; // shapeId --> set of vtkId on skin
   //     project polylines on subshapes, and partition, to get geom faces
 
   std::map<int, std::set<int> > shapeIdToVtkIdSet; // shapeId --> set of vtkId on skin
-  std::set<int> emptySet;
-  emptySet.clear();
-  std::set<int> shapeIds;
+  std::set<int>                 shapeIds;
 
   SMDS_ElemIteratorPtr itelem = sgrps->GetElements();
   while (itelem->more())
 
   SMDS_ElemIteratorPtr itelem = sgrps->GetElements();
   while (itelem->more())
@@ -12144,7 +12234,6 @@ void SMESH_MeshEditor::CreateHoleSkin(double                          radius,
     int   vtkId = elem->GetVtkID();
     if (!shapeIdToVtkIdSet.count(shapeId))
     {
     int   vtkId = elem->GetVtkID();
     if (!shapeIdToVtkIdSet.count(shapeId))
     {
-      shapeIdToVtkIdSet[shapeId] = emptySet;
       shapeIds.insert(shapeId);
     }
     shapeIdToVtkIdSet[shapeId].insert(vtkId);
       shapeIds.insert(shapeId);
     }
     shapeIdToVtkIdSet[shapeId].insert(vtkId);
@@ -12152,7 +12241,6 @@ void SMESH_MeshEditor::CreateHoleSkin(double                          radius,
 
   std::map<int, std::set<DownIdType, DownIdCompare> > shapeIdToEdges; // shapeId --> set of downward edges
   std::set<DownIdType, DownIdCompare> emptyEdges;
 
   std::map<int, std::set<DownIdType, DownIdCompare> > shapeIdToEdges; // shapeId --> set of downward edges
   std::set<DownIdType, DownIdCompare> emptyEdges;
-  emptyEdges.clear();
 
   std::map<int, std::set<int> >::iterator itShape =  shapeIdToVtkIdSet.begin();
   for (; itShape != shapeIdToVtkIdSet.end(); ++itShape)
 
   std::map<int, std::set<int> >::iterator itShape =  shapeIdToVtkIdSet.begin();
   for (; itShape != shapeIdToVtkIdSet.end(); ++itShape)
@@ -12176,7 +12264,7 @@ void SMESH_MeshEditor::CreateHoleSkin(double                          radius,
       {
         if (neighborsVtkIds[n]<0) // only smds faces are considered as neighbors here
           continue;
       {
         if (neighborsVtkIds[n]<0) // only smds faces are considered as neighbors here
           continue;
-        int smdsId = meshDS->FromVtkToSmds(neighborsVtkIds[n]);
+        smIdType smdsId = meshDS->FromVtkToSmds(neighborsVtkIds[n]);
         const SMDS_MeshElement* elem = meshDS->FindElement(smdsId);
         if ( shapeIds.count(elem->getshapeId()) && !sgrps->Contains(elem)) // edge : neighbor in the set of shape, not in the group
         {
         const SMDS_MeshElement* elem = meshDS->FindElement(smdsId);
         if ( shapeIds.count(elem->getshapeId()) && !sgrps->Contains(elem)) // edge : neighbor in the set of shape, not in the group
         {
@@ -12195,7 +12283,6 @@ void SMESH_MeshEditor::CreateHoleSkin(double                          radius,
     }
 
     std::list<int> order;
     }
 
     std::list<int> order;
-    order.clear();
     if (nodesEdges.size() > 0)
     {
       order.push_back(nodesEdges[0]); //MESSAGE("       --- back " << order.back()+1); // SMDS id = VTK id + 1;
     if (nodesEdges.size() > 0)
     {
       order.push_back(nodesEdges[0]); //MESSAGE("       --- back " << order.back()+1); // SMDS id = VTK id + 1;
@@ -12531,8 +12618,8 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
         for ( inode = 0; inode < srcNodes.size(); ++inode )
           tgtNodes[inode] = getNodeWithSameID( tgtMeshDS, srcNodes[inode] );
         if ( /*aroundElements && */tgtEditor.GetMeshDS()->FindElement( tgtNodes,
         for ( inode = 0; inode < srcNodes.size(); ++inode )
           tgtNodes[inode] = getNodeWithSameID( tgtMeshDS, srcNodes[inode] );
         if ( /*aroundElements && */tgtEditor.GetMeshDS()->FindElement( tgtNodes,
-                                                                   missType,
-                                                                   /*noMedium=*/false))
+                                                                       missType,
+                                                                       /*noMedium=*/false))
           continue;
         tgtEditor.AddElement( tgtNodes, elemKind.SetPoly( tgtNodes.size()/(iQuad+1) > 4 ));
         ++nbAddedBnd;
           continue;
         tgtEditor.AddElement( tgtNodes, elemKind.SetPoly( tgtNodes.size()/(iQuad+1) > 4 ));
         ++nbAddedBnd;
@@ -12542,8 +12629,8 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
       {
         TConnectivity& nodes = missingBndElems[ i ];
         if ( /*aroundElements && */tgtEditor.GetMeshDS()->FindElement( nodes,
       {
         TConnectivity& nodes = missingBndElems[ i ];
         if ( /*aroundElements && */tgtEditor.GetMeshDS()->FindElement( nodes,
-                                                                   missType,
-                                                                   /*noMedium=*/false))
+                                                                       missType,
+                                                                       /*noMedium=*/false))
           continue;
         SMDS_MeshElement* newElem =
           tgtEditor.AddElement( nodes, elemKind.SetPoly( nodes.size()/(iQuad+1) > 4 ));
           continue;
         SMDS_MeshElement* newElem =
           tgtEditor.AddElement( nodes, elemKind.SetPoly( nodes.size()/(iQuad+1) > 4 ));