Salome HOME
Temporarily rolling back the last integration
[modules/smesh.git] / src / SMDS / SMDS_Mesh.cxx
index 93c4cf56832050cd9ba9b2691bd81d08dc316a69..6381e547e626174de6c68a803cc0fee451c26efe 100644 (file)
 // 
 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
 
+#ifdef _MSC_VER
+#pragma warning(disable:4786)
+#endif
+
 #include "utilities.h"
 #include "SMDS_Mesh.hxx"
 #include "SMDS_VolumeOfNodes.hxx"
 #include "SMDS_VolumeOfFaces.hxx"
 #include "SMDS_FaceOfNodes.hxx"
-#include "SMDS_Tria3OfNodes.hxx"
-#include "SMDS_HexahedronOfNodes.hxx"
 #include "SMDS_FaceOfEdges.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_PolygonalFaceOfNodes.hxx"
 
 #include <algorithm>
+#include <map>
 using namespace std;
 
 ///////////////////////////////////////////////////////////////////////////////
 /// Create a new mesh object
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_Mesh::SMDS_Mesh()
-       :myNodeIDFactory(new SMDS_MeshElementIDFactory()),
+       :myParent(NULL),
+        myNodeIDFactory(new SMDS_MeshElementIDFactory()),
        myElementIDFactory(new SMDS_MeshElementIDFactory()),
        myHasConstructionEdges(false), myHasConstructionFaces(false),
        myHasInverseElements(true)
@@ -88,7 +94,7 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
   const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
   if(!node){
     SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
-    myNodes.insert(node);
+    myNodes.Add(node);
     myNodeIDFactory->BindID(ID,node);
     return node;
   }else
@@ -139,7 +145,7 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
     node2=const_cast<SMDS_MeshNode*>(n2);
     node1->AddInverseElement(edge);
     node2->AddInverseElement(edge);            
-    myEdges.insert(edge);
+    myEdges.Add(edge);
     return edge;
   } 
   else {
@@ -268,7 +274,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
   if (!hasConstructionEdges())
     return NULL;
   SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
-  myFaces.insert(face);
+  myFaces.Add(face);
 
   if (!registerElement(ID, face)) {
     RemoveElement(face, false);
@@ -305,7 +311,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
   if (!hasConstructionEdges())
     return NULL;
   SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
-  myFaces.insert(face);
+  myFaces.Add(face);
 
   if (!registerElement(ID, face))
   {
@@ -372,7 +378,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
     SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
-    myVolumes.insert(volume);
+    myVolumes.Add(volume);
   }
   else if(hasConstructionEdges()) {
     MESSAGE("Error : Not implemented");
@@ -380,7 +386,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
   }
   else {
     volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
-    myVolumes.insert(volume);
+    myVolumes.Add(volume);
   }
 
   if (!registerElement(ID, volume)) {
@@ -454,7 +460,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
     SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
-    myVolumes.insert(volume);
+    myVolumes.Add(volume);
   }
   else if(hasConstructionEdges()) {
     MESSAGE("Error : Not implemented");
@@ -462,7 +468,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
   }
   else {
     volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
-    myVolumes.insert(volume);
+    myVolumes.Add(volume);
   }
 
   if (!registerElement(ID, volume)) {
@@ -541,7 +547,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
     SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
-    myVolumes.insert(volume);
+    myVolumes.Add(volume);
   }
   else if(hasConstructionEdges()) {
     MESSAGE("Error : Not implemented");
@@ -549,7 +555,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
   }
   else {
     volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
-    myVolumes.insert(volume);
+    myVolumes.Add(volume);
   }
 
   if (!registerElement(ID, volume)) {
@@ -640,15 +646,16 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
     SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
-    myVolumes.insert(volume);
+    myVolumes.Add(volume);
   }
   else if(hasConstructionEdges()) {
     MESSAGE("Error : Not implemented");
     return NULL;
   }
   else {
-    volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
-    myVolumes.insert(volume);
+//    volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
+    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
+    myVolumes.Add(volume);
   }
 
   if (!registerElement(ID, volume)) {
@@ -688,7 +695,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
   if (!hasConstructionFaces())
     return NULL;
   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
-  myVolumes.insert(volume);
+  myVolumes.Add(volume);
 
   if (!registerElement(ID, volume)) {
     RemoveElement(volume, false);
@@ -729,7 +736,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
   if (!hasConstructionFaces())
     return NULL;
   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
-  myVolumes.insert(volume);
+  myVolumes.Add(volume);
 
   if (!registerElement(ID, volume)) {
     RemoveElement(volume, false);
@@ -772,7 +779,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
   if (!hasConstructionFaces())
     return NULL;
   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
-  myVolumes.insert(volume);
+  myVolumes.Add(volume);
 
   if (!registerElement(ID, volume)) {
     RemoveElement(volume, false);
@@ -781,6 +788,126 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
   return volume;
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// Add a polygon defined by its nodes IDs
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
+                                                  const int        ID)
+{
+  int nbNodes = nodes_ids.size();
+  std::vector<const SMDS_MeshNode*> nodes (nbNodes);
+  for (int i = 0; i < nbNodes; i++) {
+    nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
+    if (!nodes[i]) return NULL;
+  }
+  return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID); 
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a polygon defined by its nodes
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
+                          (std::vector<const SMDS_MeshNode*> nodes,
+                           const int                         ID)
+{
+  SMDS_MeshFace * face;
+
+  if (hasConstructionEdges())
+  {
+    MESSAGE("Error : Not implemented");
+    return NULL;
+  }
+  else
+  {
+    face = new SMDS_PolygonalFaceOfNodes(nodes);
+    myFaces.Add(face);
+  }
+
+  if (!registerElement(ID, face)) {
+    RemoveElement(face, false);
+    face = NULL;
+  }
+  return face;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a polygon defined by its nodes.
+/// An ID is automatically affected to the created face.
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes)
+{
+  return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Create a new polyhedral volume and add it to the mesh. 
+/// @param ID The ID of the new volume
+/// @return The created volume or NULL if an element with this ID already exists
+/// or if input nodes are not found.
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
+                             (std::vector<int> nodes_ids,
+                              std::vector<int> quantities,
+                              const int        ID)
+{
+  int nbNodes = nodes_ids.size();
+  std::vector<const SMDS_MeshNode*> nodes (nbNodes);
+  for (int i = 0; i < nbNodes; i++) {
+    nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
+    if (!nodes[i]) return NULL;
+  }
+  return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Create a new polyhedral volume and add it to the mesh. 
+/// @param ID The ID of the new volume
+/// @return The created  volume
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
+                            (std::vector<const SMDS_MeshNode*> nodes,
+                             std::vector<int>                  quantities,
+                             const int                         ID)
+{
+  SMDS_MeshVolume* volume;
+  if (hasConstructionFaces()) {
+    MESSAGE("Error : Not implemented");
+    return NULL;
+  } else if (hasConstructionEdges()) {
+    MESSAGE("Error : Not implemented");
+    return NULL;
+  } else {
+    volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
+    myVolumes.Add(volume);
+  }
+
+  if (!registerElement(ID, volume)) {
+    RemoveElement(volume, false);
+    volume = NULL;
+  }
+  return volume;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Create a new polyhedral volume and add it to the mesh. 
+/// @return The created  volume
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
+                            (std::vector<const SMDS_MeshNode*> nodes,
+                             std::vector<int>                  quantities)
+{
+  int ID = myElementIDFactory->GetFreeID();
+  SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
+  if (v == NULL) myElementIDFactory->ReleaseID(ID);
+  return v;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 /// Registers element with the given ID, maintains inverse connections
 ///////////////////////////////////////////////////////////////////////////////
@@ -822,13 +949,13 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
                edge3=FindEdgeOrCreate(node3,node1);
 
                SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
-               myFaces.insert(face);
+               myFaces.Add(face);
                return face;
        }
        else
        {
-               SMDS_MeshFace * face = new SMDS_Tria3OfNodes(node1,node2,node3);
-               myFaces.insert(face);
+               SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
+               myFaces.Add(face);
                return face;
        }
 }
@@ -851,13 +978,13 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
                edge4=FindEdgeOrCreate(node4,node1);
 
                SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
-               myFaces.insert(face);
+               myFaces.Add(face);
                return face;
        }
        else
        {
                SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
-               myFaces.insert(face);
+               myFaces.Add(face);
                return face;
        }
 }
@@ -932,6 +1059,146 @@ bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
        return found;
 }
 
+//=======================================================================
+//function : ChangeElementNodes
+//purpose  : 
+//=======================================================================
+
+bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
+                                   const SMDS_MeshNode    * nodes[],
+                                   const int                nbnodes)
+{
+  // keep current nodes of elem
+  set<const SMDS_MeshElement*> oldNodes;
+  SMDS_ElemIteratorPtr itn = elem->nodesIterator();
+  while(itn->more())
+    oldNodes.insert(  itn->next() );
+
+  // change nodes
+  bool Ok = false;
+  switch ( elem->GetType() )
+  {
+  case SMDSAbs_Edge: {
+    if ( nbnodes == 2 ) {
+      const SMDS_MeshEdge* edge = dynamic_cast<const SMDS_MeshEdge*>( elem );
+      if ( edge )
+        Ok = const_cast<SMDS_MeshEdge*>( edge )->ChangeNodes( nodes[0], nodes[1] );
+    }
+    break;
+  }
+  case SMDSAbs_Face: {
+    const SMDS_FaceOfNodes* face = dynamic_cast<const SMDS_FaceOfNodes*>( elem );
+    if ( face ) {
+      Ok = const_cast<SMDS_FaceOfNodes*>( face )->ChangeNodes( nodes, nbnodes );
+    } else {
+      /// ??? begin
+      const SMDS_PolygonalFaceOfNodes* face = dynamic_cast<const SMDS_PolygonalFaceOfNodes*>(elem);
+      if (face) {
+        Ok = const_cast<SMDS_PolygonalFaceOfNodes*>(face)->ChangeNodes(nodes, nbnodes);
+      }
+      /// ??? end
+    }
+    break;
+  }
+  //case SMDSAbs_PolygonalFace: {
+  //  const SMDS_PolygonalFaceOfNodes* face = dynamic_cast<const SMDS_PolygonalFaceOfNodes*>(elem);
+  //  if (face) {
+  //    Ok = const_cast<SMDS_PolygonalFaceOfNodes*>(face)->ChangeNodes(nodes, nbnodes);
+  //  }
+  //  break;
+  //}
+  case SMDSAbs_Volume: {
+    const SMDS_VolumeOfNodes* vol = dynamic_cast<const SMDS_VolumeOfNodes*>( elem );
+    if ( vol )
+      Ok = const_cast<SMDS_VolumeOfNodes*>( vol )->ChangeNodes( nodes, nbnodes );
+    break;
+  }
+  default:
+    MESSAGE ( "WRONG ELEM TYPE");
+  }
+
+  if ( Ok ) { // update InverseElements
+
+    // AddInverseElement to new nodes
+    for ( int i = 0; i < nbnodes; i++ )
+      if ( oldNodes.find( nodes[i] ) == oldNodes.end() )
+        // new node
+        const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
+      else
+        // remove from oldNodes a node that remains in elem
+        oldNodes.erase( nodes[i] );
+
+
+    // RemoveInverseElement from the nodes removed from elem
+    set<const SMDS_MeshElement*>::iterator it;
+    for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
+    {
+      SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
+        (const_cast<SMDS_MeshElement *>( *it ));
+      n->RemoveInverseElement( elem );
+    }
+  }
+
+  //MESSAGE ( "::ChangeNodes() Ok = " << Ok);
+
+  return Ok;
+}
+
+//=======================================================================
+//function : ChangePolyhedronNodes
+//purpose  : to change nodes of polyhedral volume
+//=======================================================================
+bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
+                                       std::vector<const SMDS_MeshNode*> nodes,
+                                       std::vector<int>                  quantities)
+{
+  if (elem->GetType() != SMDSAbs_Volume) {
+    MESSAGE("WRONG ELEM TYPE");
+    return false;
+  }
+
+  const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
+  if (!vol) {
+    return false;
+  }
+
+  // keep current nodes of elem
+  set<const SMDS_MeshElement*> oldNodes;
+  SMDS_ElemIteratorPtr itn = elem->nodesIterator();
+  while (itn->more()) {
+    oldNodes.insert(itn->next());
+  }
+
+  // change nodes
+  bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
+  if (!Ok) {
+    return false;
+  }
+
+  // update InverseElements
+
+  // AddInverseElement to new nodes
+  int nbnodes = nodes.size();
+  for (int i = 0; i < nbnodes; i++) {
+    if (oldNodes.find(nodes[i]) == oldNodes.end()) {
+      // new node
+      const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
+    } else {
+      // remove from oldNodes a node that remains in elem
+      oldNodes.erase(nodes[i]);
+    }
+  }
+
+  // RemoveInverseElement from the nodes removed from elem
+  set<const SMDS_MeshElement*>::iterator it;
+  for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
+    SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
+      (const_cast<SMDS_MeshElement *>( *it ));
+    n->RemoveInverseElement(elem);
+  }
+
+  return Ok;
+}
 
 //=======================================================================
 //function : FindEdge
@@ -948,7 +1215,7 @@ const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
 
 //#include "Profiler.h"
 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
-       const SMDS_MeshNode * node2) const
+                                         const SMDS_MeshNode * node2)
 {
        const SMDS_MeshEdge * toReturn=NULL;
        //PROFILER_Init();
@@ -983,7 +1250,7 @@ SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
        if(toReturn==NULL)      
        {
           toReturn=new SMDS_MeshEdge(node1,node2);
-          myEdges.insert(toReturn);
+          myEdges.Add(toReturn);
        } 
        return toReturn;
 }
@@ -1006,7 +1273,7 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
 const SMDS_MeshFace* SMDS_Mesh::FindFace(
                const SMDS_MeshNode *node1,
                const SMDS_MeshNode *node2,
-               const SMDS_MeshNode *node3) const
+               const SMDS_MeshNode *node3)
 {
        const SMDS_MeshFace * face;
        const SMDS_MeshElement * node;
@@ -1066,7 +1333,7 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(
                const SMDS_MeshNode *node1,
                const SMDS_MeshNode *node2,
                const SMDS_MeshNode *node3,
-               const SMDS_MeshNode *node4) const
+               const SMDS_MeshNode *node4)
 {
        const SMDS_MeshFace * face;
        const SMDS_MeshElement * node;
@@ -1118,6 +1385,55 @@ const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
        return myElementIDFactory->MeshElement(IDelem);
 }
 
+//=======================================================================
+//function : FindFace
+//purpose  : find polygon
+//=======================================================================
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
+{
+  int nbnodes = nodes_ids.size();
+  std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
+  for (int inode = 0; inode < nbnodes; inode++) {
+    const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
+    if (node == NULL) return NULL;
+  }
+  return FindFace(poly_nodes);
+}
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
+{
+  int nbNodes = nodes.size();
+  if (nbNodes < 1) return NULL;
+
+  bool isFound = true;
+  const SMDS_MeshFace * face;
+  set<const SMDS_MeshFace *> faces;
+
+  for (int inode = 0; inode < nbNodes && isFound; inode++) {
+    set<const SMDS_MeshFace *> new_faces;
+
+    SMDS_ElemIteratorPtr itF = nodes[inode]->facesIterator();
+    while (itF->more()) {
+      face = static_cast<const SMDS_MeshFace *>(itF->next());
+      if (face->NbNodes() == nbNodes) {
+        if (inode == 0 || faces.find(face) != faces.end()) {
+          new_faces.insert(face);
+        }
+      }
+    }
+    faces = new_faces;
+    if (new_faces.size() == 0) {
+      isFound = false;
+    }
+  }
+
+  if (isFound)
+    return face;
+
+  return NULL;
+}
+
 //=======================================================================
 //function : DumpNodes
 //purpose  : 
@@ -1221,7 +1537,7 @@ void SMDS_Mesh::DebugStats() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbNodes() const
 {
-       return myNodes.size();
+       return myNodes.Size();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1229,7 +1545,7 @@ int SMDS_Mesh::NbNodes() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbEdges() const
 {
-       return myEdges.size();
+       return myEdges.Size();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1237,7 +1553,7 @@ int SMDS_Mesh::NbEdges() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbFaces() const
 {
-       return myFaces.size();
+       return myFaces.Size();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1245,7 +1561,7 @@ int SMDS_Mesh::NbFaces() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbVolumes() const
 {
-       return myVolumes.size();
+       return myVolumes.Size();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1264,45 +1580,49 @@ int SMDS_Mesh::NbSubMesh() const
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_Mesh::~SMDS_Mesh()
 {
-       if(myParent==NULL)
-       {
-               delete myNodeIDFactory;
-               delete myElementIDFactory;
-       }
+  list<SMDS_Mesh*>::iterator itc=myChildren.begin();
+  while(itc!=myChildren.end())
+  {
+    delete *itc;
+    itc++;
+  }
 
-       list<SMDS_Mesh*>::iterator itc=myChildren.begin();
-       while(itc!=myChildren.end())
-       {
-               delete *itc;
-               itc++;
-       }
-       
-       SMDS_NodeIteratorPtr itn=nodesIterator();
-       while(itn->more())
-       {
-               delete itn->next();
-       }
+  SetOfNodes::Iterator itn(myNodes);
+  for (; itn.More(); itn.Next())
+    delete itn.Value();
 
-       set<SMDS_MeshEdge*>::iterator ite=myEdges.begin();
-       while(ite!=myEdges.end())
-       {
-               delete *ite;
-               ite++;
-       }
+  SetOfEdges::Iterator ite(myEdges);
+  for (; ite.More(); ite.Next())
+  {
+    SMDS_MeshElement* elem = ite.Value();
+    if(myParent!=NULL)
+      myElementIDFactory->ReleaseID(elem->GetID());
+    delete elem;
+  }
 
-       set<SMDS_MeshFace*>::iterator itf=myFaces.begin();
-       while(itf!=myFaces.end())
-       {
-               delete *itf;
-               itf++;
-       }
+  SetOfFaces::Iterator itf(myFaces);
+  for (; itf.More(); itf.Next())
+  {
+    SMDS_MeshElement* elem = itf.Value();
+    if(myParent!=NULL)
+      myElementIDFactory->ReleaseID(elem->GetID());
+    delete elem;
+  }
 
-       set<SMDS_MeshVolume*>::iterator itv=myVolumes.begin();
-       while(itv!=myVolumes.end())
-       {
-               delete *itv;
-               itv++;
-       }
+  SetOfVolumes::Iterator itv(myVolumes);
+  for (; itv.More(); itv.Next())
+  {
+    SMDS_MeshElement* elem = itv.Value();
+    if(myParent!=NULL)
+      myElementIDFactory->ReleaseID(elem->GetID());
+    delete elem;
+  }
+
+  if(myParent==NULL)
+  {
+    delete myNodeIDFactory;
+    delete myElementIDFactory;
+  }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1365,71 +1685,68 @@ void SMDS_Mesh::setInverseElements(bool b)
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Return an iterator on nodes of the current mesh. Once used this iterator
-/// must be free by the caller
+/// Return an iterator on nodes of the current mesh factory
 ///////////////////////////////////////////////////////////////////////////////
 class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator
 {
-  typedef SMDS_Mesh::SetOfNodes SetOfNodes;
-  const SetOfNodes& mySet;
-  SetOfNodes::iterator myIterator;
+  SMDS_ElemIteratorPtr myIterator;
  public:
-  SMDS_Mesh_MyNodeIterator(const SetOfNodes& s):mySet(s)
-  {
-    myIterator=mySet.begin();
-  }
+  SMDS_Mesh_MyNodeIterator(const SMDS_ElemIteratorPtr& it):myIterator(it)
+  {}
 
   bool more()
   {
-    return myIterator!=mySet.end();
+    return myIterator->more();
   }
 
   const SMDS_MeshNode* next()
   {
-    const SMDS_MeshNode* current=*myIterator;
-    myIterator++;
-    return current;    
-  }    
+    return static_cast<const SMDS_MeshNode*>(myIterator->next());
+  }
 };
 
 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
 {
-  return SMDS_NodeIteratorPtr(new SMDS_Mesh_MyNodeIterator(myNodes));
+  return SMDS_NodeIteratorPtr
+    (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return an iterator on elements of the current mesh factory
+///////////////////////////////////////////////////////////////////////////////
+SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const
+{
+  return myElementIDFactory->elementsIterator();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Return an iterator on volumes of the current mesh. Once used this iterator
-///must be free by the caller
+///Return an iterator on edges of the current mesh.
 ///////////////////////////////////////////////////////////////////////////////
 class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator
 {
   typedef SMDS_Mesh::SetOfEdges SetOfEdges;
-  const SetOfEdges& mySet;
-  const SMDS_MeshEdge * myEdge;
-  SetOfEdges::iterator myIterator;
+  SetOfEdges::Iterator myIterator;
  public:
-  SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):mySet(s)
-  {
-    myIterator=mySet.begin();
-  }
+  SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):myIterator(s)
+  {}
 
   bool more()
   {
-    while((myIterator!=mySet.end()))
+    while(myIterator.More())
     {
-      if((*myIterator)->GetID()!=-1)
+      if(myIterator.Value()->GetID()!=-1)
         return true;
-      myIterator++;
+      myIterator.Next();
     }
     return false;
   }
 
   const SMDS_MeshEdge* next()
   {
-    const SMDS_MeshEdge* current=*myIterator;
-    myIterator++;
-    return current;    
-  }    
+    const SMDS_MeshEdge* current = myIterator.Value();
+    myIterator.Next();
+    return current;
+  }
 };
 
 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
@@ -1438,37 +1755,33 @@ SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Return an iterator on faces of the current mesh. Once used this iterator
-///must be free by the caller
+///Return an iterator on faces of the current mesh.
 ///////////////////////////////////////////////////////////////////////////////
 class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator
 {
   typedef SMDS_Mesh::SetOfFaces SetOfFaces;
-  const SetOfFaces& mySet;
-  SetOfFaces::iterator myIterator;
+  SetOfFaces::Iterator myIterator;
  public:
-  SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):mySet(s)
-  {
-    myIterator=mySet.begin();
-  }
+  SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):myIterator(s)
+  {}
 
   bool more()
   {
-    while((myIterator!=mySet.end()))
+    while(myIterator.More())
     {
-      if((*myIterator)->GetID()!=-1)
+      if(myIterator.Value()->GetID()!=-1)
         return true;
-      myIterator++;
+      myIterator.Next();
     }
     return false;
   }
 
   const SMDS_MeshFace* next()
   {
-    const SMDS_MeshFace* current=*myIterator;
-    myIterator++;
-    return current;    
-  }    
+    const SMDS_MeshFace* current = myIterator.Value();
+    myIterator.Next();
+    return current;
+  }
 };
 
 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
@@ -1477,31 +1790,27 @@ SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Return an iterator on volumes of the current mesh. Once used this iterator
-///must be free by the caller
+///Return an iterator on volumes of the current mesh.
 ///////////////////////////////////////////////////////////////////////////////
 class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator
 {
   typedef SMDS_Mesh::SetOfVolumes SetOfVolumes;
-  const SetOfVolumes& mySet;
-  SetOfVolumes::iterator myIterator;
+  SetOfVolumes::Iterator myIterator;
  public:
-  SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):mySet(s)
-  {
-    myIterator=mySet.begin();
-  }
+  SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):myIterator(s)
+  {}
 
   bool more()
   {
-    return myIterator!=mySet.end();
+    return myIterator.More() != Standard_False;
   }
 
   const SMDS_MeshVolume* next()
   {
-    const SMDS_MeshVolume* current=*myIterator;
-    myIterator++;
-    return current;    
-  }    
+    const SMDS_MeshVolume* current = myIterator.Value();
+    myIterator.Next();
+    return current;
+  }
 };
 
 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
@@ -1537,7 +1846,7 @@ static set<const SMDS_MeshElement*> * intersectionOfSets(
 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
 {
        int numberOfSets=element->NbNodes();
-       set<const SMDS_MeshElement*> initSet[numberOfSets];
+       set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
 
        SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
 
@@ -1553,8 +1862,9 @@ static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement *
 
                i++;
        }
-       
-       return intersectionOfSets(initSet, numberOfSets);
+       set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
+        delete [] initSet;
+       return retSet;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1670,12 +1980,13 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
                               list<const SMDS_MeshElement *>& removedElems,
                               list<const SMDS_MeshElement *>& removedNodes,
-                              const bool                      removenodes)
+                              bool                            removenodes)
 {
   // get finite elements built on elem
   set<const SMDS_MeshElement*> * s1;
   if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
-      !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face)
+      !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face ||
+      elem->GetType() == SMDSAbs_Volume)
   {
     s1 = new set<const SMDS_MeshElement*>();
     s1->insert(elem);
@@ -1685,10 +1996,12 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
 
   // get exclusive nodes (which would become free afterwards)
   set<const SMDS_MeshElement*> * s2;
-  if (s1->empty() && elem->GetType() == SMDSAbs_Node)
+  if (elem->GetType() == SMDSAbs_Node) // a node is removed
   {
+    // do not remove nodes except elem
     s2 = new set<const SMDS_MeshElement*>();
     s2->insert(elem);
+    removenodes = true;
   }
   else
     s2 = getExclusiveNodes(*s1);
@@ -1723,15 +2036,15 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
       MESSAGE("Internal Error: This should not happen");
       break;
     case SMDSAbs_Edge:
-      myEdges.erase(static_cast<SMDS_MeshEdge*>
+      myEdges.Remove(static_cast<SMDS_MeshEdge*>
                     (const_cast<SMDS_MeshElement*>(*it)));
       break;
     case SMDSAbs_Face:
-      myFaces.erase(static_cast<SMDS_MeshFace*>
+      myFaces.Remove(static_cast<SMDS_MeshFace*>
                     (const_cast<SMDS_MeshElement*>(*it)));
       break;
     case SMDSAbs_Volume:
-      myVolumes.erase(static_cast<SMDS_MeshVolume*>
+      myVolumes.Remove(static_cast<SMDS_MeshVolume*>
                       (const_cast<SMDS_MeshElement*>(*it)));
       break;
     }
@@ -1749,7 +2062,7 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
     while(it!=s2->end())
     {
       //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
-      myNodes.erase(static_cast<SMDS_MeshNode*>
+      myNodes.Remove(static_cast<SMDS_MeshNode*>
                     (const_cast<SMDS_MeshElement*>(*it)));
       myNodeIDFactory->ReleaseID((*it)->GetID());
       removedNodes.push_back( (*it) );
@@ -1788,3 +2101,103 @@ bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
       return true;
   return false;
 }
+
+//=======================================================================
+//function : MaxNodeID
+//purpose  : 
+//=======================================================================
+
+int SMDS_Mesh::MaxNodeID() const
+{
+  return myNodeIDFactory->GetMaxID();
+}
+
+//=======================================================================
+//function : MinNodeID
+//purpose  : 
+//=======================================================================
+
+int SMDS_Mesh::MinNodeID() const
+{
+  return myNodeIDFactory->GetMinID();
+}
+
+//=======================================================================
+//function : MaxElementID
+//purpose  : 
+//=======================================================================
+
+int SMDS_Mesh::MaxElementID() const
+{
+  return myElementIDFactory->GetMaxID();
+}
+
+//=======================================================================
+//function : MinElementID
+//purpose  : 
+//=======================================================================
+
+int SMDS_Mesh::MinElementID() const
+{
+  return myElementIDFactory->GetMinID();
+}
+
+//=======================================================================
+//function : Renumber
+//purpose  : Renumber all nodes or elements.
+//=======================================================================
+
+void SMDS_Mesh::Renumber (const bool isNodes, const int  startID, const int  deltaID)
+{
+  if ( deltaID == 0 )
+    return;
+
+  SMDS_MeshElementIDFactory * idFactory =
+    isNodes ? myNodeIDFactory : myElementIDFactory;
+
+  // get existing elements in the order of ID increasing
+  map<int,SMDS_MeshElement*> elemMap;
+  SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
+  while ( idElemIt->more() ) {
+    SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
+    int id = elem->GetID();
+    elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
+  }
+  // release their ids
+  map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
+  for ( ; elemIt != elemMap.end(); elemIt++ )
+  {
+    int id = (*elemIt).first;
+    idFactory->ReleaseID( id );
+  }
+  // set new IDs
+  int ID = startID;
+  elemIt = elemMap.begin();
+  for ( ; elemIt != elemMap.end(); elemIt++ )
+  {
+    idFactory->BindID( ID, (*elemIt).second );
+    ID += deltaID;
+  }
+}
+
+//=======================================================================
+//function : GetElementType
+//purpose  : Return type of element or node with id
+//=======================================================================
+
+SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
+{
+  SMDS_MeshElement* elem = 0;
+  if( iselem )
+    elem = myElementIDFactory->MeshElement( id );
+  else
+    elem = myNodeIDFactory->MeshElement( id );
+
+  if( !elem )
+  {
+    //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
+    return SMDSAbs_All;
+  }
+  else
+    return elem->GetType();
+}
\ No newline at end of file