]> SALOME platform Git repositories - modules/smesh.git/commitdiff
Salome HOME
Take care of having predictable results. Keep results of the last operation.
authoreap <eap@opencascade.com>
Thu, 4 May 2006 13:37:38 +0000 (13:37 +0000)
committereap <eap@opencascade.com>
Thu, 4 May 2006 13:37:38 +0000 (13:37 +0000)
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_MeshEditor.hxx

index 731cbfdf52a8622d7489369fbf9731e57fefad34..1650e1bd746f45c641e9fe5ab175be4e1cd3d551 100644 (file)
@@ -102,6 +102,8 @@ myMesh( theMesh )
 bool SMESH_MeshEditor::Remove (const list< int >& theIDs,
                                const bool         isNodes )
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
   set< SMESH_subMesh *> smmap;
@@ -158,6 +160,9 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs,
 
 int SMESH_MeshEditor::FindShape (const SMDS_MeshElement * theElem)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   SMESHDS_Mesh * aMesh = GetMeshDS();
   if ( aMesh->ShapeToMesh().IsNull() )
     return 0;
@@ -310,6 +315,9 @@ static bool GetNodesFromTwoTria(const SMDS_MeshElement * theTria1,
 bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1,
                                     const SMDS_MeshElement * theTria2 )
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   if (!theTria1 || !theTria2)
     return false;
 
@@ -453,7 +461,14 @@ static bool findTriangles(const SMDS_MeshNode *    theNode1,
     if ( elem->GetType() == SMDSAbs_Face &&
          emap.find( elem ) != emap.end() )
       if ( theTria1 ) {
-        theTria2 = elem;
+        // theTria1 must be element with minimum ID
+        if( theTria1->GetID() < elem->GetID() ) {
+          theTria2 = elem;
+        }
+        else {
+          theTria2 = theTria1;
+          theTria1 = elem;
+        }
         break;
       }
       else {
@@ -473,6 +488,9 @@ static bool findTriangles(const SMDS_MeshNode *    theNode1,
 bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1,
                                     const SMDS_MeshNode * theNode2)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   MESSAGE( "::InverseDiag()" );
 
   const SMDS_MeshElement *tr1, *tr2;
@@ -604,6 +622,9 @@ bool getQuadrangleNodes(const SMDS_MeshNode *    theQuadNodes [],
 bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1,
                                    const SMDS_MeshNode * theNode2)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   MESSAGE( "::DeleteDiag()" );
 
   const SMDS_MeshElement *tr1, *tr2;
@@ -623,6 +644,7 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1,
     //MESSAGE( endl << tr1 << tr2 );
 
     GetMeshDS()->ChangeElementNodes( tr1, aNodes, 4 );
+    myLastCreatedElems.Append(tr1);
     GetMeshDS()->RemoveElement( tr2 );
 
     //MESSAGE( endl << tr1 );
@@ -667,6 +689,7 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1,
   aNodes[7] = N1[5];
 
   GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
+  myLastCreatedElems.Append(tr1);
   GetMeshDS()->RemoveElement( tr2 );
 
   // remove middle node (9)
@@ -682,6 +705,9 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1,
 
 bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   if (!theElem)
     return false;
   SMDS_ElemIteratorPtr it = theElem->nodesIterator();
@@ -785,9 +811,12 @@ static double getBadRate (const SMDS_MeshElement*               theElem,
 //           theCrit is used to select a diagonal to cut
 //=======================================================================
 
-bool SMESH_MeshEditor::QuadToTri (set<const SMDS_MeshElement*> &       theElems,
+bool SMESH_MeshEditor::QuadToTri (map<int,const SMDS_MeshElement*> &       theElems,
                                   SMESH::Controls::NumericalFunctorPtr theCrit)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   MESSAGE( "::QuadToTri()" );
 
   if ( !theCrit.get() )
@@ -795,9 +824,9 @@ bool SMESH_MeshEditor::QuadToTri (set<const SMDS_MeshElement*> &       theElems,
 
   SMESHDS_Mesh * aMesh = GetMeshDS();
 
-  set< const SMDS_MeshElement * >::iterator itElem;
+  map<int, const SMDS_MeshElement * >::iterator itElem;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
-    const SMDS_MeshElement* elem = (*itElem);
+    const SMDS_MeshElement* elem = (*itElem).second;
     if ( !elem || elem->GetType() != SMDSAbs_Face )
       continue;
 
@@ -839,6 +868,7 @@ bool SMESH_MeshEditor::QuadToTri (set<const SMDS_MeshElement*> &       theElems,
         elem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
       }
       //MESSAGE( endl << elem );
+      myLastCreatedElems.Append(elem);
 
       // put a new triangle on the same shape
       if ( aShapeId )
@@ -875,6 +905,7 @@ bool SMESH_MeshEditor::QuadToTri (set<const SMDS_MeshElement*> &       theElems,
         z += aNodes[i]->Z();
       }
       const SMDS_MeshNode* newN = aMesh->AddNode(x/4, y/4, z/4);
+      myLastCreatedNodes.Append(newN);
 
       if ( aBadRate1 <= aBadRate2 ) {
         // tr1 + tr2 is better
@@ -902,6 +933,7 @@ bool SMESH_MeshEditor::QuadToTri (set<const SMDS_MeshElement*> &       theElems,
         elem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
                               aNodes[7], aNodes[4], newN );
       }
+      myLastCreatedElems.Append(elem);
       // put a new triangle on the same shape
       if ( aShapeId ) {
         aMesh->SetMeshElementOnShape( elem, aShapeId );
@@ -919,6 +951,9 @@ bool SMESH_MeshEditor::QuadToTri (set<const SMDS_MeshElement*> &       theElems,
 int SMESH_MeshEditor::BestSplit (const SMDS_MeshElement*              theQuad,
                                  SMESH::Controls::NumericalFunctorPtr theCrit)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   if (!theCrit.get())
     return -1;
 
@@ -954,7 +989,6 @@ int SMESH_MeshEditor::BestSplit (const SMDS_MeshElement*              theQuad,
   return -1;
 }
 
-
 //=======================================================================
 //function : AddToSameGroups
 //purpose  : add elemToAdd to the groups the elemInGroups belongs to
@@ -973,6 +1007,7 @@ void SMESH_MeshEditor::AddToSameGroups (const SMDS_MeshElement* elemToAdd,
   }
 }
 
+
 //=======================================================================
 //function : RemoveElemFromGroups
 //purpose  : Remove removeelem to the groups the elemInGroups belongs to
@@ -992,22 +1027,27 @@ void SMESH_MeshEditor::RemoveElemFromGroups (const SMDS_MeshElement* removeelem,
     }
   }
 }
+
+
 //=======================================================================
 //function : QuadToTri
 //purpose  : Cut quadrangles into triangles.
 //           theCrit is used to select a diagonal to cut
 //=======================================================================
 
-bool SMESH_MeshEditor::QuadToTri (std::set<const SMDS_MeshElement*> & theElems,
+bool SMESH_MeshEditor::QuadToTri (std::map<int,const SMDS_MeshElement*> & theElems,
                                   const bool                          the13Diag)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   MESSAGE( "::QuadToTri()" );
 
   SMESHDS_Mesh * aMesh = GetMeshDS();
 
-  set< const SMDS_MeshElement * >::iterator itElem;
+  map<int, const SMDS_MeshElement * >::iterator itElem;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
-    const SMDS_MeshElement* elem = (*itElem);
+    const SMDS_MeshElement* elem = (*itElem).second;
     if ( !elem || elem->GetType() != SMDSAbs_Face )
       continue;
     bool isquad = elem->NbNodes()==4 || elem->NbNodes()==8;
@@ -1031,6 +1071,7 @@ bool SMESH_MeshEditor::QuadToTri (std::set<const SMDS_MeshElement*> & theElems,
         aMesh->ChangeElementNodes( elem, &aNodes[1], 3 );
         newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
       }
+      myLastCreatedElems.Append(newElem);
       // put a new triangle on the same shape and add to the same groups
       if ( aShapeId )
         aMesh->SetMeshElementOnShape( newElem, aShapeId );
@@ -1054,6 +1095,7 @@ bool SMESH_MeshEditor::QuadToTri (std::set<const SMDS_MeshElement*> & theElems,
         z += aNodes[i]->Z();
       }
       const SMDS_MeshNode* newN = aMesh->AddNode(x/4, y/4, z/4);
+      myLastCreatedNodes.Append(newN);
 
       int aShapeId = FindShape( elem );
       const SMDS_MeshElement* newElem = 0;
@@ -1081,6 +1123,7 @@ bool SMESH_MeshEditor::QuadToTri (std::set<const SMDS_MeshElement*> & theElems,
         elem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
                               aNodes[7], aNodes[4], newN );
       }
+      myLastCreatedElems.Append(elem);
       // put a new triangle on the same shape and add to the same groups
       if ( aShapeId )
         aMesh->SetMeshElementOnShape( newElem, aShapeId );
@@ -1194,10 +1237,13 @@ class LinkID_Gen {
 //           fusion is still performed.
 //=======================================================================
 
-bool SMESH_MeshEditor::TriToQuad (set<const SMDS_MeshElement*> &       theElems,
+bool SMESH_MeshEditor::TriToQuad (map<int,const SMDS_MeshElement*> &       theElems,
                                   SMESH::Controls::NumericalFunctorPtr theCrit,
                                   const double                         theMaxAngle)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   MESSAGE( "::TriToQuad()" );
 
   if ( !theCrit.get() )
@@ -1220,9 +1266,9 @@ bool SMESH_MeshEditor::TriToQuad (set<const SMDS_MeshElement*> &       theElems,
   map< const SMDS_MeshElement*, set< NLink > >  mapEl_setLi;
   map< const SMDS_MeshElement*, set< NLink > >::iterator itEL;
 
-  set<const SMDS_MeshElement*>::iterator itElem;
+  map<int,const SMDS_MeshElement*>::iterator itElem;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
-    const SMDS_MeshElement* elem = (*itElem);
+    const SMDS_MeshElement* elem = (*itElem).second;
     //if ( !elem || elem->NbNodes() != 3 )
     //  continue;
     if(!elem || elem->GetType() != SMDSAbs_Face ) continue;
@@ -1413,8 +1459,16 @@ bool SMESH_MeshEditor::TriToQuad (set<const SMDS_MeshElement*> &       theElems,
           mapEl_setLi.erase( tr2 );
           mapLi_listEl.erase( link12 );
           if(tr1->NbNodes()==3) {
-            aMesh->ChangeElementNodes( tr1, n12, 4 );
-            aMesh->RemoveElement( tr2 );
+            if( tr1->GetID() < tr2->GetID() ) {
+              aMesh->ChangeElementNodes( tr1, n12, 4 );
+              myLastCreatedElems.Append(tr1);
+              aMesh->RemoveElement( tr2 );
+            }
+            else {
+              aMesh->ChangeElementNodes( tr2, n12, 4 );
+              myLastCreatedElems.Append(tr2);
+              aMesh->RemoveElement( tr1);
+            }
           }
           else {
             const SMDS_MeshNode* N1 [6];
@@ -1432,8 +1486,16 @@ bool SMESH_MeshEditor::TriToQuad (set<const SMDS_MeshElement*> &       theElems,
             aNodes[5] = N2[5];
             aNodes[6] = N2[3];
             aNodes[7] = N1[5];
-            GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
-            GetMeshDS()->RemoveElement( tr2 );
+            if( tr1->GetID() < tr2->GetID() ) {
+              GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
+              myLastCreatedElems.Append(tr1);
+              GetMeshDS()->RemoveElement( tr2 );
+            }
+            else {
+              GetMeshDS()->ChangeElementNodes( tr2, aNodes, 8 );
+              myLastCreatedElems.Append(tr2);
+              GetMeshDS()->RemoveElement( tr1 );
+            }
             // remove middle node (9)
             GetMeshDS()->RemoveNode( N1[4] );
           }
@@ -1442,8 +1504,16 @@ bool SMESH_MeshEditor::TriToQuad (set<const SMDS_MeshElement*> &       theElems,
           mapEl_setLi.erase( tr3 );
           mapLi_listEl.erase( link13 );
           if(tr1->NbNodes()==3) {
-            aMesh->ChangeElementNodes( tr1, n13, 4 );
-            aMesh->RemoveElement( tr3 );
+            if( tr1->GetID() < tr2->GetID() ) {
+              aMesh->ChangeElementNodes( tr1, n13, 4 );
+              myLastCreatedElems.Append(tr1);
+              aMesh->RemoveElement( tr3 );
+            }
+            else {
+              aMesh->ChangeElementNodes( tr3, n13, 4 );
+              myLastCreatedElems.Append(tr3);
+              aMesh->RemoveElement( tr1 );
+            }
           }
           else {
             const SMDS_MeshNode* N1 [6];
@@ -1461,8 +1531,16 @@ bool SMESH_MeshEditor::TriToQuad (set<const SMDS_MeshElement*> &       theElems,
             aNodes[5] = N2[5];
             aNodes[6] = N2[3];
             aNodes[7] = N1[5];
-            GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
-            GetMeshDS()->RemoveElement( tr3 );
+            if( tr1->GetID() < tr2->GetID() ) {
+              GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
+              myLastCreatedElems.Append(tr1);
+              GetMeshDS()->RemoveElement( tr3 );
+            }
+            else {
+              GetMeshDS()->ChangeElementNodes( tr3, aNodes, 8 );
+              myLastCreatedElems.Append(tr3);
+              GetMeshDS()->RemoveElement( tr1 );
+            }
             // remove middle node (9)
             GetMeshDS()->RemoveNode( N1[4] );
           }
@@ -1931,13 +2009,16 @@ static bool getClosestUV (Extrema_GenExtPS& projector,
 //           on edges and boundary nodes are always fixed.
 //=======================================================================
 
-void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
+void SMESH_MeshEditor::Smooth (map<int,const SMDS_MeshElement*> & theElems,
                                set<const SMDS_MeshNode*> &    theFixedNodes,
                                const SmoothMethod             theSmoothMethod,
                                const int                      theNbIterations,
                                double                         theTgtAspectRatio,
                                const bool                     the2D)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   MESSAGE((theSmoothMethod==LAPLACIAN ? "LAPLACIAN" : "CENTROIDAL") << "--::Smooth()");
 
   if ( theTgtAspectRatio < 1.0 )
@@ -1952,15 +2033,17 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
   if ( theElems.empty() ) {
     // add all faces to theElems
     SMDS_FaceIteratorPtr fIt = aMesh->facesIterator();
-    while ( fIt->more() )
-      theElems.insert( fIt->next() );
+    while ( fIt->more() ) {
+      const SMDS_MeshElement* face = fIt->next();
+      theElems.insert( make_pair(face->GetID(),face) );
+    }
   }
   // get all face ids theElems are on
   set< int > faceIdSet;
-  set< const SMDS_MeshElement* >::iterator itElem;
+  map<int, const SMDS_MeshElement* >::iterator itElem;
   if ( the2D )
     for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
-      int fId = FindShape( *itElem );
+      int fId = FindShape( (*itElem).second );
       // check that corresponding submesh exists and a shape is face
       if (fId &&
           faceIdSet.find( fId ) == faceIdSet.end() &&
@@ -2023,7 +2106,7 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
       if ( faceSubMesh && nbElemOnFace == faceSubMesh->NbElements() )
         break; // all elements found
 
-      const SMDS_MeshElement* elem = (*itElem);
+      const SMDS_MeshElement* elem = (*itElem).second;
       if ( !elem || elem->GetType() != SMDSAbs_Face || elem->NbNodes() < 3 ||
           ( faceSubMesh && !faceSubMesh->Contains( elem ))) {
         ++itElem;
@@ -2413,7 +2496,7 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
             Ns.push_back( anIter->next() );
           Ns.push_back( Ns[0] );
           double x, y, z;
-          for ( int i=0; i<QF->NbNodes(); i=i+2 ) {
+          for(int i=0; i<QF->NbNodes(); i=i+2) {
             if ( !surface.IsNull() ) {
               gp_XY uv1 = helper.GetNodeUV( face, Ns[i], Ns[i+2] );
               gp_XY uv2 = helper.GetNodeUV( face, Ns[i+2], Ns[i] );
@@ -2480,7 +2563,8 @@ static void sweepElement(SMESHDS_Mesh*                         aMesh,
                          const SMDS_MeshElement*               elem,
                          const vector<TNodeOfNodeListMapItr> & newNodesItVec,
                          list<const SMDS_MeshElement*>&        newElems,
-                         const int nbSteps)
+                         const int nbSteps,
+                         SMESH_SequenceOfElemPtr& myLastCreatedElems)
 {
   // Loop on elem nodes:
   // find new nodes and detect same nodes indices
@@ -2773,6 +2857,7 @@ static void sweepElement(SMESHDS_Mesh*                         aMesh,
 
     if ( aNewElem ) {
       newElems.push_back( aNewElem );
+      myLastCreatedElems.Append(aNewElem);
     }
 
     // set new prev nodes
@@ -2791,8 +2876,9 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
                        TNodeOfNodeListMap &          mapNewNodes,
                        TElemOfElemListMap &          newElemsMap,
                        TElemOfVecOfNnlmiMap &        elemNewNodesMap,
-                       set<const SMDS_MeshElement*>& elemSet,
-                       const int nbSteps)
+                       map<int,const SMDS_MeshElement*>& elemSet,
+                       const int nbSteps,
+                       SMESH_SequenceOfElemPtr& myLastCreatedElems)
 {
   ASSERT( newElemsMap.size() == elemNewNodesMap.size() );
 
@@ -2808,7 +2894,7 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
     while ( eIt->more() && nbInitElems < 2 ) {
       el = eIt->next();
       //if ( elemSet.find( eIt->next() ) != elemSet.end() )
-      if ( elemSet.find(el) != elemSet.end() )
+      if ( elemSet.find(el->GetID()) != elemSet.end() )
         nbInitElems++;
     }
     if ( nbInitElems < 2 ) {
@@ -2816,7 +2902,7 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
       if(!NotCreateEdge) {
         vector<TNodeOfNodeListMapItr> newNodesItVec( 1, nList );
         list<const SMDS_MeshElement*> newEdges;
-        sweepElement( aMesh, node, newNodesItVec, newEdges, nbSteps );
+        sweepElement( aMesh, node, newNodesItVec, newEdges, nbSteps, myLastCreatedElems );
       }
     }
   }
@@ -2833,23 +2919,25 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
     if ( elem->GetType() == SMDSAbs_Edge ) {
       if(!elem->IsQuadratic()) {
         // create a ceiling edge
-        aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
-                       vecNewNodes[ 1 ]->second.back() );
+        myLastCreatedElems.Append(aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
+                                           vecNewNodes[ 1 ]->second.back()));
       }
       else {
         // create a ceiling edge
-        aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
-                       vecNewNodes[ 1 ]->second.back(),
-                       vecNewNodes[ 2 ]->second.back());
+        myLastCreatedElems.Append(aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
+                                           vecNewNodes[ 1 ]->second.back(),
+                                           vecNewNodes[ 2 ]->second.back()));
       }
     }
     if ( elem->GetType() != SMDSAbs_Face )
       continue;
 
+    if(itElem->second.size()==0) continue;
+
     bool hasFreeLinks = false;
 
-    set<const SMDS_MeshElement*> avoidSet;
-    avoidSet.insert( elem );
+    map<int,const SMDS_MeshElement*> avoidSet;
+    avoidSet.insert( make_pair(elem->GetID(),elem) );
 
     set<const SMDS_MeshNode*> aFaceLastNodes;
     int iNode, nbNodes = vecNewNodes.size();
@@ -2866,12 +2954,12 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
           hasFreeLinks = true;
           // make an edge and a ceiling for a new edge
           if ( !aMesh->FindEdge( n1, n2 )) {
-            aMesh->AddEdge( n1, n2 );
+            myLastCreatedElems.Append(aMesh->AddEdge( n1, n2 ));
           }
           n1 = vecNewNodes[ iNode ]->second.back();
           n2 = vecNewNodes[ iNext ]->second.back();
           if ( !aMesh->FindEdge( n1, n2 )) {
-            aMesh->AddEdge( n1, n2 );
+            myLastCreatedElems.Append(aMesh->AddEdge( n1, n2 ));
           }
         }
       }
@@ -2890,13 +2978,13 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
           // find medium node
           const SMDS_MeshNode* n3 = vecNewNodes[ iNode+nbn ]->first;
           if ( !aMesh->FindEdge( n1, n2, n3 )) {
-            aMesh->AddEdge( n1, n2, n3 );
+            myLastCreatedElems.Append(aMesh->AddEdge( n1, n2, n3 ));
           }
           n1 = vecNewNodes[ iNode ]->second.back();
           n2 = vecNewNodes[ iNext ]->second.back();
           n3 = vecNewNodes[ iNode+nbn ]->second.back();
           if ( !aMesh->FindEdge( n1, n2, n3 )) {
-            aMesh->AddEdge( n1, n2, n3 );
+            myLastCreatedElems.Append(aMesh->AddEdge( n1, n2, n3 ));
           }
         }
       }
@@ -2944,19 +3032,19 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
             //switch ( vTool.NbFaceNodes( *ind ) ) {
             switch ( nbn ) {
             case 3:
-              aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ); break;
+              myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] )); break;
             case 4:
-              aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] ); break;
+              myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] )); break;
             default:
               {
                 if( (*v)->IsQuadratic() ) {
                   if(nbn==6) {
-                    aMesh->AddFace(nodes[0], nodes[2], nodes[4],
-                                   nodes[1], nodes[3], nodes[5]); break;
+                    myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4],
+                                                       nodes[1], nodes[3], nodes[5])); break;
                   }
                   else {
-                      aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6],
-                                     nodes[1], nodes[3], nodes[5], nodes[7]);
+                      myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6],
+                                     nodes[1], nodes[3], nodes[5], nodes[7]));
                       break;
                   }
                 }
@@ -2966,7 +3054,7 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
                   for (int inode = 0; inode < nbPolygonNodes; inode++) {
                     polygon_nodes[inode] = nodes[inode];
                   }
-                  aMesh->AddPolygonalFace(polygon_nodes);
+                  myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes));
                 }
                 break;
               }
@@ -2992,12 +3080,12 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
       case 3:
         if (!hasFreeLinks ||
             !aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ]))
-          aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] );
+          myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ));
         break;
       case 4:
         if (!hasFreeLinks ||
             !aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ]))
-          aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] );
+          myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] ));
         break;
       default:
         {
@@ -3006,16 +3094,16 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
               if (!hasFreeLinks ||
                   !aMesh->FindFace(nodes[0], nodes[2], nodes[4],
                                    nodes[1], nodes[3], nodes[5]) ) {
-                aMesh->AddFace(nodes[0], nodes[2], nodes[4],
-                               nodes[1], nodes[3], nodes[5]); break;
+                myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4],
+                                                   nodes[1], nodes[3], nodes[5])); break;
               }
             }
             else { // nbn==8
               if (!hasFreeLinks ||
                   !aMesh->FindFace(nodes[0], nodes[2], nodes[4], nodes[6],
                                    nodes[1], nodes[3], nodes[5], nodes[7]) )
-                aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6],
-                               nodes[1], nodes[3], nodes[5], nodes[7]);
+                myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6],
+                                                   nodes[1], nodes[3], nodes[5], nodes[7]));
             }
           }
           else {
@@ -3025,7 +3113,7 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
               polygon_nodes[inode] = nodes[inode];
             }
             if (!hasFreeLinks || !aMesh->FindFace(polygon_nodes))
-              aMesh->AddPolygonalFace(polygon_nodes);
+              myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes));
           }
         }
         break;
@@ -3039,12 +3127,15 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
 //purpose  :
 //=======================================================================
 
-void SMESH_MeshEditor::RotationSweep(set<const SMDS_MeshElement*> & theElems,
+void SMESH_MeshEditor::RotationSweep(map<int,const SMDS_MeshElement*> & theElems,
                                      const gp_Ax1&                  theAxis,
                                      const double                   theAngle,
                                      const int                      theNbSteps,
                                      const double                   theTol)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   MESSAGE( "RotationSweep()");
   gp_Trsf aTrsf;
   aTrsf.SetRotation( theAxis, theAngle );
@@ -3061,9 +3152,9 @@ void SMESH_MeshEditor::RotationSweep(set<const SMDS_MeshElement*> & theElems,
   TElemOfElemListMap newElemsMap;
 
   // loop on theElems
-  set< const SMDS_MeshElement* >::iterator itElem;
+  map<int, const SMDS_MeshElement* >::iterator itElem;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
-    const SMDS_MeshElement* elem = (*itElem);
+    const SMDS_MeshElement* elem = (*itElem).second;
     if ( !elem )
       continue;
     vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
@@ -3094,6 +3185,7 @@ void SMESH_MeshEditor::RotationSweep(set<const SMDS_MeshElement*> & theElems,
               aTrsf2.Transforms( coord[0], coord[1], coord[2] );
               //aTrsf.Transforms( coord[0], coord[1], coord[2] );
               newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+              myLastCreatedNodes.Append(newNode);
               listNewNodes.push_back( newNode );
               aTrsf2.Transforms( coord[0], coord[1], coord[2] );
               //aTrsf.Transforms( coord[0], coord[1], coord[2] );
@@ -3102,6 +3194,7 @@ void SMESH_MeshEditor::RotationSweep(set<const SMDS_MeshElement*> & theElems,
               aTrsf.Transforms( coord[0], coord[1], coord[2] );
             }
             newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+            myLastCreatedNodes.Append(newNode);
           }
           listNewNodes.push_back( newNode );
         }
@@ -3121,9 +3214,11 @@ void SMESH_MeshEditor::RotationSweep(set<const SMDS_MeshElement*> & theElems,
             for(int i = 0; i<theNbSteps; i++) {
               aTrsf2.Transforms( coord[0], coord[1], coord[2] );
               newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+              myLastCreatedNodes.Append(newNode);
               listNewNodes.push_back( newNode );
               aTrsf2.Transforms( coord[0], coord[1], coord[2] );
               newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+              myLastCreatedNodes.Append(newNode);
               listNewNodes.push_back( newNode );
             }
           }
@@ -3132,10 +3227,10 @@ void SMESH_MeshEditor::RotationSweep(set<const SMDS_MeshElement*> & theElems,
       newNodesItVec.push_back( nIt );
     }
     // make new elements
-    sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], theNbSteps );
+    sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], theNbSteps, myLastCreatedElems );
   }
 
-  makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, theNbSteps );
+  makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, theNbSteps, myLastCreatedElems );
 
 }
 
@@ -3150,6 +3245,9 @@ const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x,
                                                   const double tolnode,
                                                   SMESH_SequenceOfNode& aNodes)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   gp_Pnt P1(x,y,z);
   SMESHDS_Mesh * aMesh = myMesh->GetMeshDS();
 
@@ -3176,6 +3274,7 @@ const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x,
 
   // create new node and return it
   const SMDS_MeshNode* NewNode = aMesh->AddNode(x,y,z);
+  myLastCreatedNodes.Append(NewNode);
   return NewNode;
 }
 
@@ -3186,7 +3285,7 @@ const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x,
 //=======================================================================
 
 void SMESH_MeshEditor::ExtrusionSweep
-                    (set<const SMDS_MeshElement*> & theElems,
+                    (map<int,const SMDS_MeshElement*> & theElems,
                      const gp_Vec&                  theStep,
                      const int                      theNbSteps,
                      TElemOfElemListMap&            newElemsMap,
@@ -3212,12 +3311,15 @@ void SMESH_MeshEditor::ExtrusionSweep
 //=======================================================================
 
 void SMESH_MeshEditor::ExtrusionSweep
-                    (set<const SMDS_MeshElement*> & theElems,
+                    (map<int,const SMDS_MeshElement*> & theElems,
                      ExtrusParam&                   theParams,
                      TElemOfElemListMap&            newElemsMap,
                      const int                      theFlags,
                      const double                   theTolerance)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
   int nbsteps = theParams.mySteps->Length();
@@ -3228,10 +3330,10 @@ void SMESH_MeshEditor::ExtrusionSweep
   //TElemOfVecOfMapNodesMap mapElemNewNodes;
 
   // loop on theElems
-  set< const SMDS_MeshElement* >::iterator itElem;
+  map<int, const SMDS_MeshElement* >::iterator itElem;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
     // check element type
-    const SMDS_MeshElement* elem = (*itElem);
+    const SMDS_MeshElement* elem = (*itElem).second;
     if ( !elem )
       continue;
 
@@ -3271,6 +3373,7 @@ void SMESH_MeshEditor::ExtrusionSweep
             }
             else {
               const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z);
+              myLastCreatedNodes.Append(newNode);
               listNewNodes.push_back( newNode );
             }
           }
@@ -3286,6 +3389,7 @@ void SMESH_MeshEditor::ExtrusionSweep
           }
           else {
             const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+            myLastCreatedNodes.Append(newNode);
             listNewNodes.push_back( newNode );
             //vecNewNodes[i]=newNode;
           }
@@ -3310,6 +3414,7 @@ void SMESH_MeshEditor::ExtrusionSweep
               }
               else {
                 const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z);
+                myLastCreatedNodes.Append(newNode);
                 listNewNodes.push_back( newNode );
               }
               coord[0] = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1);
@@ -3322,6 +3427,7 @@ void SMESH_MeshEditor::ExtrusionSweep
               }
               else {
                 const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+                myLastCreatedNodes.Append(newNode);
                 listNewNodes.push_back( newNode );
               }
             }
@@ -3331,10 +3437,11 @@ void SMESH_MeshEditor::ExtrusionSweep
       newNodesItVec.push_back( nIt );
     }
     // make new elements
-    sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], nbsteps );
+    sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], nbsteps, myLastCreatedElems );
   }
+
   if( theFlags & EXTRUSION_FLAG_BOUNDARY ) {
-    makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbsteps );
+    makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbsteps, myLastCreatedElems );
   }
 }
 
@@ -3388,7 +3495,7 @@ protected:
 //purpose  :
 //=======================================================================
 SMESH_MeshEditor::Extrusion_Error
-  SMESH_MeshEditor::ExtrusionAlongTrack (std::set<const SMDS_MeshElement*> & theElements,
+  SMESH_MeshEditor::ExtrusionAlongTrack (std::map<int,const SMDS_MeshElement*> & theElements,
                                         SMESH_subMesh* theTrack,
                                         const SMDS_MeshNode* theN1,
                                         const bool theHasAngles,
@@ -3396,12 +3503,15 @@ SMESH_MeshEditor::Extrusion_Error
                                         const bool theHasRefPoint,
                                         const gp_Pnt& theRefPoint)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   MESSAGE("SMESH_MeshEditor::ExtrusionAlongTrack")
   int j, aNbTP, aNbE, aNb;
   double aT1, aT2, aT, aAngle, aX, aY, aZ;
   std::list<double> aPrms;
   std::list<double>::iterator aItD;
-  std::set< const SMDS_MeshElement* >::iterator itElem;
+  std::map<int, const SMDS_MeshElement* >::iterator itElem;
 
   Standard_Real aTx1, aTx2, aL2, aTolVec, aTolVec2;
   gp_Pnt aP3D, aV0;
@@ -3541,7 +3651,7 @@ SMESH_MeshEditor::Extrusion_Error
 
     itElem = theElements.begin();
     for ( ; itElem != theElements.end(); itElem++ ) {
-      const SMDS_MeshElement* elem = (*itElem);
+      const SMDS_MeshElement* elem = (*itElem).second;
 
       SMDS_ElemIteratorPtr itN = elem->nodesIterator();
       while ( itN->more() ) {
@@ -3570,7 +3680,7 @@ SMESH_MeshEditor::Extrusion_Error
 
   for ( itElem = theElements.begin(); itElem != theElements.end(); itElem++ ) {
     // check element type
-    const SMDS_MeshElement* elem = (*itElem);
+    const SMDS_MeshElement* elem = (*itElem).second;
     aTypeE = elem->GetType();
     if ( !elem || ( aTypeE != SMDSAbs_Face && aTypeE != SMDSAbs_Edge ) )
       continue;
@@ -3649,12 +3759,14 @@ SMESH_MeshEditor::Extrusion_Error
             double y = ( aPN1.Y() + aPN0.Y() )/2.;
             double z = ( aPN1.Z() + aPN0.Z() )/2.;
             const SMDS_MeshNode* newNode = aMesh->AddNode(x,y,z);
+            myLastCreatedNodes.Append(newNode);
             listNewNodes.push_back( newNode );
           }
          aX = aPN1.X();
          aY = aPN1.Y();
          aZ = aPN1.Z();
          const SMDS_MeshNode* newNode = aMesh->AddNode( aX, aY, aZ );
+          myLastCreatedNodes.Append(newNode);
          listNewNodes.push_back( newNode );
 
          aPN0 = aPN1;
@@ -3680,6 +3792,7 @@ SMESH_MeshEditor::Extrusion_Error
               double y = ( N->Y() + P.Y() )/2.;
               double z = ( N->Z() + P.Z() )/2.;
               const SMDS_MeshNode* newN = aMesh->AddNode(x,y,z);
+              myLastCreatedNodes.Append(newN);
               aNodes[2*i] = newN;
               aNodes[2*i+1] = N;
               P = gp_XYZ(N->X(),N->Y(),N->Z());
@@ -3695,12 +3808,14 @@ SMESH_MeshEditor::Extrusion_Error
       newNodesItVec.push_back( nIt );
     }
     // make new elements
+    //sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem],
+    //              newNodesItVec[0]->second.size(), myLastCreatedElems );
     sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem],
-                  newNodesItVec[0]->second.size() );
+                  aNbTP-1, myLastCreatedElems );
   }
 
   makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElements,
-            aNbTP-1 );
+             aNbTP-1, myLastCreatedElems );
 
   return EXTR_OK;
 }
@@ -3710,10 +3825,13 @@ SMESH_MeshEditor::Extrusion_Error
 //purpose  :
 //=======================================================================
 
-void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
+void SMESH_MeshEditor::Transform (map<int,const SMDS_MeshElement*> & theElems,
                                   const gp_Trsf&                 theTrsf,
                                   const bool                     theCopy)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   bool needReverse;
   switch ( theTrsf.Form() ) {
   case gp_PntMirror:
@@ -3731,12 +3849,12 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
 
   // elements sharing moved nodes; those of them which have all
   // nodes mirrored but are not in theElems are to be reversed
-  set<const SMDS_MeshElement*> inverseElemSet;
+  map<int,const SMDS_MeshElement*> inverseElemSet;
 
   // loop on theElems
-  set< const SMDS_MeshElement* >::iterator itElem;
+  map<int, const SMDS_MeshElement* >::iterator itElem;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
-    const SMDS_MeshElement* elem = (*itElem);
+    const SMDS_MeshElement* elem = (*itElem).second;
     if ( !elem )
       continue;
 
@@ -3756,8 +3874,10 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
       coord[2] = node->Z();
       theTrsf.Transforms( coord[0], coord[1], coord[2] );
       const SMDS_MeshNode * newNode = node;
-      if ( theCopy )
+      if ( theCopy ) {
         newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+        myLastCreatedNodes.Append(newNode);
+      }
       else {
         aMesh->MoveNode( node, coord[0], coord[1], coord[2] );
         // node position on shape becomes invalid
@@ -3769,8 +3889,10 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
       // keep inverse elements
       if ( !theCopy && needReverse ) {
         SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
-        while ( invElemIt->more() )
-          inverseElemSet.insert( invElemIt->next() );
+        while ( invElemIt->more() ) {
+          const SMDS_MeshElement* iel = invElemIt->next(); 
+          inverseElemSet.insert( make_pair(iel->GetID(),iel) );
+        }
       }
     }
   }
@@ -3781,7 +3903,7 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
     return;
 
   if ( !inverseElemSet.empty()) {
-    set<const SMDS_MeshElement*>::iterator invElemIt = inverseElemSet.begin();
+    map<int,const SMDS_MeshElement*>::iterator invElemIt = inverseElemSet.begin();
     for ( ; invElemIt != inverseElemSet.end(); invElemIt++ )
       theElems.insert( *invElemIt );
   }
@@ -3806,7 +3928,7 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
   };
 
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
-    const SMDS_MeshElement* elem = (*itElem);
+    const SMDS_MeshElement* elem = (*itElem).second;
     if ( !elem || elem->GetType() == SMDSAbs_Node )
       continue;
 
@@ -3839,8 +3961,9 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
             continue; // not all nodes transformed
 
           if ( theCopy ) {
-            aMesh->AddPolygonalFace(poly_nodes);
-          } else {
+            myLastCreatedElems.Append(aMesh->AddPolygonalFace(poly_nodes));
+          }
+          else {
             aMesh->ChangePolygonNodes(elem, poly_nodes);
           }
         }
@@ -3877,8 +4000,9 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
             continue; // not all nodes transformed
 
           if ( theCopy ) {
-            aMesh->AddPolyhedralVolume(poly_nodes, quantities);
-          } else {
+            myLastCreatedElems.Append(aMesh->AddPolyhedralVolume(poly_nodes, quantities));
+          }
+          else {
             aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
           }
         }
@@ -3951,50 +4075,50 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
       switch ( elemType ) {
       case SMDSAbs_Edge:
         if ( nbNodes == 2 )
-          aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ] );
+          myLastCreatedElems.Append(aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ] ));
         else
-          aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] );
+          myLastCreatedElems.Append(aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ));
         break;
       case SMDSAbs_Face:
         if ( nbNodes == 3 )
-          aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] );
+          myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ));
         else if(nbNodes==4)
-          aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ]);
+          myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ]));
         else if(nbNodes==6)
-          aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
-                         nodes[4], nodes[5]);
+          myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
+                                             nodes[4], nodes[5]));
         else // nbNodes==8
-          aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
-                         nodes[4], nodes[5], nodes[6], nodes[7]);
+          myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
+                                             nodes[4], nodes[5], nodes[6], nodes[7]));
         break;
       case SMDSAbs_Volume:
         if ( nbNodes == 4 )
-          aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ] );
+          myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ] ));
         else if ( nbNodes == 8 )
-          aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
-                            nodes[ 4 ], nodes[ 5 ], nodes[ 6 ] , nodes[ 7 ]);
+          myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
+                                               nodes[ 4 ], nodes[ 5 ], nodes[ 6 ] , nodes[ 7 ]));
         else if ( nbNodes == 6 )
-          aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
-                            nodes[ 4 ], nodes[ 5 ]);
+          myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
+                                               nodes[ 4 ], nodes[ 5 ]));
         else if ( nbNodes == 5 )
-          aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
-                            nodes[ 4 ]);
+          myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
+                                               nodes[ 4 ]));
         else if(nbNodes==10)
-          aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
-                           nodes[5], nodes[6], nodes[7], nodes[8], nodes[9]);
+          myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
+                                               nodes[5], nodes[6], nodes[7], nodes[8], nodes[9]));
         else if(nbNodes==13)
-          aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
-                           nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
-                           nodes[10], nodes[11], nodes[12]);
+          myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
+                                               nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
+                                               nodes[10], nodes[11], nodes[12]));
         else if(nbNodes==15)
-          aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
-                           nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
-                           nodes[10], nodes[11], nodes[12], nodes[13], nodes[14]);
+          myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
+                                               nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
+                                               nodes[10], nodes[11], nodes[12], nodes[13], nodes[14]));
         else // nbNodes==20
-          aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
-                           nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
-                           nodes[10], nodes[11], nodes[12], nodes[13], nodes[14],
-                           nodes[15], nodes[16], nodes[17], nodes[18], nodes[19]);
+          myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
+                                               nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
+                                               nodes[10], nodes[11], nodes[12], nodes[13], nodes[14],
+                                               nodes[15], nodes[16], nodes[17], nodes[18], nodes[19]));
         break;
       default:;
       }
@@ -4018,6 +4142,9 @@ void SMESH_MeshEditor::FindCoincidentNodes (set<const SMDS_MeshNode*> & theNodes
                                             const double                theTolerance,
                                             TListOfListOfNodes &        theGroupsOfNodes)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   double tol2 = theTolerance * theTolerance;
 
   list<const SMDS_MeshNode*> nodes;
@@ -4051,7 +4178,10 @@ void SMESH_MeshEditor::FindCoincidentNodes (set<const SMDS_MeshNode*> & theNodes
           groupPtr = & theGroupsOfNodes.back();
           groupPtr->push_back( n1 );
         }
-        groupPtr->push_back( n2 );
+        if(groupPtr->front()>n2)
+          groupPtr->push_front( n2 );
+        else
+          groupPtr->push_back( n2 );
         it2 = nodes.erase( it2 );
         it2--;
       }
@@ -4149,6 +4279,9 @@ int SMESH_MeshEditor::SimplifyFace (const vector<const SMDS_MeshNode *> faceNode
 
 void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
   TNodeNodeMap nodeNodeMap; // node to replace - new node
@@ -4236,6 +4369,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
                 poly_nodes[ii] = polygons_nodes[inode];
               }
               SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes);
+              myLastCreatedElems.Append(newElem);
               if (aShapeId)
                 aMesh->SetMeshElementOnShape(newElem, aShapeId);
             }
@@ -4350,6 +4484,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
                                curNodes[ 4 ],
                                curNodes[ 5 ],
                                curNodes[ iRepl[ 0 ] == 2 ? 1 : 2 ]);
+            myLastCreatedElems.Append(newElem);
             if ( aShapeId )
               aMesh->SetMeshElementOnShape( newElem, aShapeId );
             // 2. : reverse a bottom
@@ -4515,6 +4650,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
                                    curNodes[ind[ 3 ]],
                                    curNodes[ind[ 2 ]],
                                    curNodes[indTop[ 0 ]]);
+                myLastCreatedElems.Append(newElem);
                 if ( aShapeId )
                   aMesh->SetMeshElementOnShape( newElem, aShapeId );
                 isOk = true;
@@ -4580,6 +4716,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
                                                          curNodes[ i2 ],
                                                          curNodes[ i3d ],
                                                          curNodes[ i2t ]);
+            myLastCreatedElems.Append(newElem);
             if ( aShapeId )
               aMesh->SetMeshElementOnShape( newElem, aShapeId );
             isOk = true;
@@ -4676,6 +4813,35 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
 
 }
 
+
+// =================================================
+// class   : SortableElement
+// purpose : auxilary
+// =================================================
+class SortableElement : public set <const SMDS_MeshElement*>
+{
+ public:
+
+  SortableElement( const SMDS_MeshElement* theElem )
+    {
+      myID = theElem->GetID();
+      SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator();
+      while ( nodeIt->more() )
+        this->insert( nodeIt->next() );
+    }
+
+  const long GetID() const
+    { return myID; }
+
+  void SetID(const long anID) const
+    { myID = anID; }
+
+
+ private:
+  mutable long myID;
+};
+
+
 //=======================================================================
 //function : MergeEqualElements
 //purpose  : Remove all but one of elements built on the same nodes.
@@ -4683,6 +4849,9 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
 
 void SMESH_MeshEditor::MergeEqualElements()
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
   SMDS_EdgeIteratorPtr   eIt = aMesh->edgesIterator();
@@ -4693,8 +4862,7 @@ void SMESH_MeshEditor::MergeEqualElements()
 
   for ( int iDim = 1; iDim <= 3; iDim++ ) {
 
-    set< set <const SMDS_MeshElement*> > setOfNodeSet;
-
+    set< SortableElement > setOfNodeSet;
     while ( 1 ) {
       // get next element
       const SMDS_MeshElement* elem = 0;
@@ -4707,16 +4875,21 @@ void SMESH_MeshEditor::MergeEqualElements()
       }
       if ( !elem ) break;
 
-      // get elem nodes
-      set <const SMDS_MeshElement*> nodeSet;
-      SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
-      while ( nodeIt->more() )
-        nodeSet.insert( nodeIt->next() );
+      SortableElement SE(elem);
 
       // check uniqueness
-      bool isUnique = setOfNodeSet.insert( nodeSet ).second;
-      if ( !isUnique )
-        rmElemIds.push_back( elem->GetID() );
+      pair< set<SortableElement>::iterator, bool> pp = setOfNodeSet.insert(SE);
+      if( !(pp.second) ) {
+        set<SortableElement>::iterator itSE = pp.first;
+        SortableElement SEold = *itSE;
+        if( SEold.GetID() > SE.GetID() ) {
+          rmElemIds.push_back( SEold.GetID() );
+          (*itSE).SetID(SE.GetID());
+        }
+        else {
+          rmElemIds.push_back( SE.GetID() );
+        }
+      }
     }
   }
 
@@ -4733,17 +4906,17 @@ void SMESH_MeshEditor::MergeEqualElements()
 const SMDS_MeshElement*
   SMESH_MeshEditor::FindFaceInSet(const SMDS_MeshNode*                n1,
                                   const SMDS_MeshNode*                n2,
-                                  const set<const SMDS_MeshElement*>& elemSet,
-                                  const set<const SMDS_MeshElement*>& avoidSet)
+                                  const map<int,const SMDS_MeshElement*>& elemSet,
+                                  const map<int,const SMDS_MeshElement*>& avoidSet)
 
 {
   SMDS_ElemIteratorPtr invElemIt = n1->GetInverseElementIterator();
   while ( invElemIt->more() ) { // loop on inverse elements of n1
     const SMDS_MeshElement* elem = invElemIt->next();
     if (elem->GetType() != SMDSAbs_Face ||
-        avoidSet.find( elem ) != avoidSet.end() )
+        avoidSet.find( elem->GetID() ) != avoidSet.end() )
       continue;
-    if ( !elemSet.empty() && elemSet.find( elem ) == elemSet.end())
+    if ( !elemSet.empty() && elemSet.find( elem->GetID() ) == elemSet.end())
       continue;
     // get face nodes and find index of n1
     int i1, nbN = elem->NbNodes(), iNode = 0;
@@ -4815,9 +4988,9 @@ static const SMDS_MeshElement* findAdjacentFace(const SMDS_MeshNode* n1,
                                                 const SMDS_MeshNode* n2,
                                                 const SMDS_MeshElement* elem)
 {
-  set<const SMDS_MeshElement*> elemSet, avoidSet;
+  map<int,const SMDS_MeshElement*> elemSet, avoidSet;
   if ( elem )
-    avoidSet.insert ( elem );
+    avoidSet.insert ( make_pair(elem->GetID(),elem) );
   return SMESH_MeshEditor::FindFaceInSet( n1, n2, elemSet, avoidSet );
 }
 
@@ -4994,6 +5167,9 @@ SMESH_MeshEditor::Sew_Error
                                    const bool           toCreatePolygons,
                                    const bool           toCreatePolyedrs)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   MESSAGE("::SewFreeBorder()");
   Sew_Error aResult = SEW_OK;
 
@@ -5560,6 +5736,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
       int aShapeId = FindShape( theFace );
 
       SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes);
+      myLastCreatedElems.Append(newElem);
       if ( aShapeId && newElem )
         aMesh->SetMeshElementOnShape( newElem, aShapeId );
 
@@ -5632,6 +5809,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
         newElem = aMesh->AddFace (linkNodes[ i1++ ],
                                   linkNodes[ i2++ ],
                                   nodes[ iSplit < iBestQuad ? i4 : i3 ]);
+      myLastCreatedElems.Append(newElem);
       if ( aShapeId && newElem )
         aMesh->SetMeshElementOnShape( newElem, aShapeId );
     }
@@ -5677,11 +5855,13 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     if(nbFaceNodes==6) { // quadratic triangle
       SMDS_MeshElement* newElem =
         aMesh->AddFace(nodes[3],nodes[4],nodes[5]);
+      myLastCreatedElems.Append(newElem);
       if ( aShapeId && newElem )
         aMesh->SetMeshElementOnShape( newElem, aShapeId );
       if(theFace->IsMediumNode(nodes[il1])) {
         // create quadrangle
         newElem = aMesh->AddFace(nodes[0],nodes[1],nodes[3],nodes[5]);
+        myLastCreatedElems.Append(newElem);
         if ( aShapeId && newElem )
           aMesh->SetMeshElementOnShape( newElem, aShapeId );
         n1 = 1;
@@ -5691,6 +5871,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
       else {
         // create quadrangle
         newElem = aMesh->AddFace(nodes[1],nodes[2],nodes[3],nodes[5]);
+        myLastCreatedElems.Append(newElem);
         if ( aShapeId && newElem )
           aMesh->SetMeshElementOnShape( newElem, aShapeId );
         n1 = 0;
@@ -5701,17 +5882,21 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     else { // nbFaceNodes==8 - quadratic quadrangle
       SMDS_MeshElement* newElem =
         aMesh->AddFace(nodes[3],nodes[4],nodes[5]);
+      myLastCreatedElems.Append(newElem);
       if ( aShapeId && newElem )
         aMesh->SetMeshElementOnShape( newElem, aShapeId );
       newElem = aMesh->AddFace(nodes[5],nodes[6],nodes[7]);
+      myLastCreatedElems.Append(newElem);
       if ( aShapeId && newElem )
         aMesh->SetMeshElementOnShape( newElem, aShapeId );
       newElem = aMesh->AddFace(nodes[5],nodes[7],nodes[3]);
+      myLastCreatedElems.Append(newElem);
       if ( aShapeId && newElem )
         aMesh->SetMeshElementOnShape( newElem, aShapeId );
       if(theFace->IsMediumNode(nodes[il1])) {
         // create quadrangle
         newElem = aMesh->AddFace(nodes[0],nodes[1],nodes[3],nodes[7]);
+        myLastCreatedElems.Append(newElem);
         if ( aShapeId && newElem )
           aMesh->SetMeshElementOnShape( newElem, aShapeId );
         n1 = 1;
@@ -5721,6 +5906,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
       else {
         // create quadrangle
         newElem = aMesh->AddFace(nodes[1],nodes[2],nodes[3],nodes[7]);
+        myLastCreatedElems.Append(newElem);
         if ( aShapeId && newElem )
           aMesh->SetMeshElementOnShape( newElem, aShapeId );
         n1 = 0;
@@ -5740,6 +5926,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     for(i=1; i<nbn; i++) {
       SMDS_MeshElement* newElem =
         aMesh->AddFace(aNodes[i-1],aNodes[i],nodes[n3]);
+      myLastCreatedElems.Append(newElem);
       if ( aShapeId && newElem )
         aMesh->SetMeshElementOnShape( newElem, aShapeId );
     }
@@ -5756,6 +5943,9 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode*        theBetweenNode
                                       const SMDS_MeshNode*        theBetweenNode2,
                                       list<const SMDS_MeshNode*>& theNodesToInsert)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   SMDS_ElemIteratorPtr invElemIt = theBetweenNode1->GetInverseElementIterator();
   while (invElemIt->more()) { // loop on inverse elements of theBetweenNode1
     const SMDS_MeshElement* elem = invElemIt->next();
@@ -5824,6 +6014,7 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode*        theBetweenNode
 
       SMDS_MeshElement* newElem =
         aMesh->AddPolyhedralVolume(poly_nodes, quantities);
+      myLastCreatedElems.Append(newElem);
       if (aShapeId && newElem)
         aMesh->SetMeshElementOnShape(newElem, aShapeId);
 
@@ -6171,13 +6362,16 @@ bool  SMESH_MeshEditor::ConvertFromQuadratic()
 //=======================================================================
 
 SMESH_MeshEditor::Sew_Error
-  SMESH_MeshEditor::SewSideElements (set<const SMDS_MeshElement*>& theSide1,
-                                     set<const SMDS_MeshElement*>& theSide2,
+  SMESH_MeshEditor::SewSideElements (map<int,const SMDS_MeshElement*>& theSide1,
+                                     map<int,const SMDS_MeshElement*>& theSide2,
                                      const SMDS_MeshNode*          theFirstNode1,
                                      const SMDS_MeshNode*          theFirstNode2,
                                      const SMDS_MeshNode*          theSecondNode1,
                                      const SMDS_MeshNode*          theSecondNode2)
 {
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
   MESSAGE ("::::SewSideElements()");
   if ( theSide1.size() != theSide2.size() )
     return SEW_DIFF_NB_OF_ELEMENTS;
@@ -6204,15 +6398,16 @@ SMESH_MeshEditor::Sew_Error
   set<const SMDS_MeshElement*> * faceSetPtr[] = { &faceSet1, &faceSet2 };
   set<const SMDS_MeshElement*>  * volSetPtr[] = { &volSet1,  &volSet2  };
   set<const SMDS_MeshNode*>    * nodeSetPtr[] = { &nodeSet1, &nodeSet2 };
-  set<const SMDS_MeshElement*> * elemSetPtr[] = { &theSide1, &theSide2 };
+  map<int,const SMDS_MeshElement*> * elemSetPtr[] = { &theSide1, &theSide2 };
   int iSide, iFace, iNode;
 
   for ( iSide = 0; iSide < 2; iSide++ ) {
     set<const SMDS_MeshNode*>    * nodeSet = nodeSetPtr[ iSide ];
-    set<const SMDS_MeshElement*> * elemSet = elemSetPtr[ iSide ];
+    map<int,const SMDS_MeshElement*> * elemSet = elemSetPtr[ iSide ];
     set<const SMDS_MeshElement*> * faceSet = faceSetPtr[ iSide ];
     set<const SMDS_MeshElement*> * volSet  = volSetPtr [ iSide ];
-    set<const SMDS_MeshElement*>::iterator vIt, eIt;
+    set<const SMDS_MeshElement*>::iterator vIt;
+    map<int,const SMDS_MeshElement*>::iterator eIt;
     set<const SMDS_MeshNode*>::iterator    nIt;
 
     // check that given nodes belong to given elements
@@ -6220,7 +6415,7 @@ SMESH_MeshEditor::Sew_Error
     const SMDS_MeshNode* n2 = ( iSide == 0 ) ? theSecondNode1 : theSecondNode2;
     int firstIndex = -1, secondIndex = -1;
     for (eIt = elemSet->begin(); eIt != elemSet->end(); eIt++ ) {
-      const SMDS_MeshElement* elem = *eIt;
+      const SMDS_MeshElement* elem = (*eIt).second;
       if ( firstIndex  < 0 ) firstIndex  = elem->GetNodeIndex( n1 );
       if ( secondIndex < 0 ) secondIndex = elem->GetNodeIndex( n2 );
       if ( firstIndex > -1 && secondIndex > -1 ) break;
@@ -6240,7 +6435,8 @@ SMESH_MeshEditor::Sew_Error
 
     // loop on the given element of a side
     for (eIt = elemSet->begin(); eIt != elemSet->end(); eIt++ ) {
-      const SMDS_MeshElement* elem = *eIt;
+      //const SMDS_MeshElement* elem = *eIt;
+      const SMDS_MeshElement* elem = (*eIt).second;
       if ( elem->GetType() == SMDSAbs_Face ) {
         faceSet->insert( elem );
         set <const SMDS_MeshNode*> faceNodeSet;
@@ -6356,7 +6552,7 @@ SMESH_MeshEditor::Sew_Error
                 const SMDS_MeshElement* e = invElemIt->next();
                 if ( faceSet->find( e ) != faceSet->end() )
                   nbSharedNodes++;
-                if ( elemSet->find( e ) != elemSet->end() )
+                if ( elemSet->find( e->GetID() ) != elemSet->end() )
                   nbSharedNodes++;
               }
             }
@@ -6373,10 +6569,10 @@ SMESH_MeshEditor::Sew_Error
             // choose a face most close to the bary center of the opposite side
             gp_XYZ aBC( 0., 0., 0. );
             set <const SMDS_MeshNode*> addedNodes;
-            set<const SMDS_MeshElement*> * elemSet2 = elemSetPtr[ 1 - iSide ];
+            map<int,const SMDS_MeshElement*> * elemSet2 = elemSetPtr[ 1 - iSide ];
             eIt = elemSet2->begin();
             for ( eIt = elemSet2->begin(); eIt != elemSet2->end(); eIt++ ) {
-              SMDS_ElemIteratorPtr nodeIt = (*eIt)->nodesIterator();
+              SMDS_ElemIteratorPtr nodeIt = (*eIt).second->nodesIterator();
               while ( nodeIt->more() ) { // loop on free face nodes
                 const SMDS_MeshNode* n =
                   static_cast<const SMDS_MeshNode*>( nodeIt->next() );
index c95ded87b7d4dc44695016bf910a0daa3a254060..68a15d1b37ed584f04744c3fc9dade77119deea6 100644 (file)
@@ -33,6 +33,7 @@
 #include "SMESH_Mesh.hxx"
 #include "SMESH_Controls.hxx"
 #include "SMESH_SequenceOfNode.hxx"
+#include "SMESH_SequenceOfElemPtr.hxx"
 #include "gp_Dir.hxx"
 #include "TColStd_HSequenceOfReal.hxx"
 #include "SMESH_MesherHelper.hxx"
@@ -89,7 +90,7 @@ class SMESH_MeshEditor {
    *                       is still performed; theMaxAngle is mesured in radians.
    * \retval bool - Success or not.
    */
-  bool TriToQuad (std::set<const SMDS_MeshElement*> &  theElems,
+  bool TriToQuad (std::map<int,const SMDS_MeshElement*> & theElems,
                   SMESH::Controls::NumericalFunctorPtr theCriterion,
                   const double                         theMaxAngle);
 
@@ -99,7 +100,7 @@ class SMESH_MeshEditor {
    * \param theCriterion - Is used to choose a diagonal for splitting.
    * \retval bool - Success or not.
    */
-  bool QuadToTri (std::set<const SMDS_MeshElement*> &  theElems,
+  bool QuadToTri (std::map<int,const SMDS_MeshElement*> &  theElems,
                   SMESH::Controls::NumericalFunctorPtr theCriterion);
 
   /*!
@@ -108,7 +109,7 @@ class SMESH_MeshEditor {
    * \param the13Diag - Is used to choose a diagonal for splitting.
    * \retval bool - Success or not.
    */
-  bool QuadToTri (std::set<const SMDS_MeshElement*> & theElems,
+  bool QuadToTri (std::map<int,const SMDS_MeshElement*> & theElems,
                   const bool                          the13Diag);
 
   /*!
@@ -123,7 +124,7 @@ class SMESH_MeshEditor {
 
   enum SmoothMethod { LAPLACIAN = 0, CENTROIDAL };
 
-  void Smooth (std::set<const SMDS_MeshElement*> & theElements,
+  void Smooth (std::map<int,const SMDS_MeshElement*> & theElements,
                std::set<const SMDS_MeshNode*> &    theFixedNodes,
                const SmoothMethod                  theSmoothMethod,
                const int                           theNbIterations,
@@ -139,7 +140,7 @@ class SMESH_MeshEditor {
   // on geometrical faces
 
 
-  void RotationSweep (std::set<const SMDS_MeshElement*> & theElements,
+  void RotationSweep (std::map<int,const SMDS_MeshElement*> & theElements,
                       const gp_Ax1&                       theAxis,
                       const double                        theAngle,
                       const int                           theNbSteps,
@@ -189,7 +190,7 @@ class SMESH_MeshEditor {
    *   EXTRUSION_FLAG_SEW is set
    */
   void ExtrusionSweep
-           (set<const SMDS_MeshElement*> & theElems,
+           (map<int,const SMDS_MeshElement*> & theElems,
             const gp_Vec&                  theStep,
             const int                      theNbSteps,
             TElemOfElemListMap&            newElemsMap,
@@ -206,7 +207,7 @@ class SMESH_MeshEditor {
    *   EXTRUSION_FLAG_SEW is set
    * param theParams - special structure for manage of extrusion
    */
-  void ExtrusionSweep (set<const SMDS_MeshElement*> & theElems,
+  void ExtrusionSweep (map<int,const SMDS_MeshElement*> & theElems,
                        ExtrusParam&                   theParams,
                        TElemOfElemListMap&            newElemsMap,
                        const int                      theFlags,
@@ -226,7 +227,7 @@ class SMESH_MeshEditor {
     EXTR_CANT_GET_TANGENT
     };
   
-  Extrusion_Error ExtrusionAlongTrack (std::set<const SMDS_MeshElement*> & theElements,
+  Extrusion_Error ExtrusionAlongTrack (std::map<int,const SMDS_MeshElement*> & theElements,
                                        SMESH_subMesh*                      theTrackPattern,
                                        const SMDS_MeshNode*                theNodeStart,
                                        const bool                          theHasAngles,
@@ -236,7 +237,7 @@ class SMESH_MeshEditor {
   // Generate new elements by extrusion of theElements along path given by theTrackPattern,
   // theHasAngles are the rotation angles, base point can be given by theRefPoint
 
-  void Transform (std::set<const SMDS_MeshElement*> & theElements,
+  void Transform (std::map<int,const SMDS_MeshElement*> & theElements,
                   const gp_Trsf&                      theTrsf,
                   const bool                          theCopy);
   // Move or copy theElements applying theTrsf to their nodes
@@ -313,8 +314,8 @@ class SMESH_MeshEditor {
   // nodes are inserted.
   // Return false, if sewing failed.
 
-  Sew_Error SewSideElements (std::set<const SMDS_MeshElement*>& theSide1,
-                             std::set<const SMDS_MeshElement*>& theSide2,
+  Sew_Error SewSideElements (std::map<int,const SMDS_MeshElement*>& theSide1,
+                             std::map<int,const SMDS_MeshElement*>& theSide2,
                              const SMDS_MeshNode*               theFirstNode1ToMerge,
                              const SMDS_MeshNode*               theFirstNode2ToMerge,
                              const SMDS_MeshNode*               theSecondNode1ToMerge,
@@ -372,8 +373,8 @@ class SMESH_MeshEditor {
   static const SMDS_MeshElement*
     FindFaceInSet(const SMDS_MeshNode*                     n1,
                   const SMDS_MeshNode*                     n2,
-                  const std::set<const SMDS_MeshElement*>& elemSet,
-                  const std::set<const SMDS_MeshElement*>& avoidSet);
+                  const std::map<int,const SMDS_MeshElement*>& elemSet,
+                  const std::map<int,const SMDS_MeshElement*>& avoidSet);
   // Return a face having linked nodes n1 and n2 and which is
   // - not in avoidSet,
   // - in elemSet provided that !elemSet.empty()
@@ -395,6 +396,10 @@ class SMESH_MeshEditor {
 
   SMESHDS_Mesh * GetMeshDS() { return myMesh->GetMeshDS(); }
 
+  SMESH_SequenceOfElemPtr GetLastCreatedNodes() { return myLastCreatedNodes; }
+
+  SMESH_SequenceOfElemPtr GetLastCreatedElems() { return myLastCreatedElems; }
+
 private:
 
   void ConvertElemToQuadratic(SMESHDS_SubMesh *theSm,
@@ -412,6 +417,16 @@ private:
 
   SMESH_Mesh * myMesh;
 
+  /*!
+   * Sequence for keeping nodes created during last operation
+   */
+  SMESH_SequenceOfElemPtr myLastCreatedNodes;
+
+  /*!
+   * Sequence for keeping elements created during last operation
+   */
+  SMESH_SequenceOfElemPtr myLastCreatedElems;
+
 };
 
 #endif