Salome HOME
PR: adjust points number
[modules/smesh.git] / src / SMDS / SMDS_Mesh.cxx
index e8d8af69741b1a6fca138db954aaab98cda10f2c..1fbe8d3242dfeed12b3baa2fd118fe8fd394c99e 100644 (file)
@@ -20,7 +20,7 @@
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 //  SMESH SMDS : implementaion of Salome mesh data structure
-//
+
 #ifdef _MSC_VER
 #pragma warning(disable:4786)
 #endif
 #include "SMDS_QuadraticEdge.hxx"
 #include "SMDS_QuadraticFaceOfNodes.hxx"
 #include "SMDS_QuadraticVolumeOfNodes.hxx"
+#include "SMDS_SpacePosition.hxx"
+
+#include <vtkUnstructuredGrid.h>
+#include <vtkUnsignedCharArray.h>
 
 #include <algorithm>
 #include <map>
@@ -45,9 +49,13 @@ using namespace std;
 #include <sys/sysinfo.h>
 #endif
 
-// number of added entitis to check memory after
+// number of added entities to check memory after
 #define CHECKMEMORY_INTERVAL 1000
 
+vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
+int SMDS_Mesh::chunkSize = 1024;
+
+
 //================================================================================
 /*!
  * \brief Raise an exception if free memory (ram+swap) too low
@@ -103,12 +111,42 @@ int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
 /// Create a new mesh object
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_Mesh::SMDS_Mesh()
-       :myParent(NULL),
-        myNodeIDFactory(new SMDS_MeshElementIDFactory()),
-       myElementIDFactory(new SMDS_MeshElementIDFactory()),
-       myHasConstructionEdges(false), myHasConstructionFaces(false),
-       myHasInverseElements(true)
-{
+        :myParent(NULL),
+         myNodeIDFactory(new SMDS_MeshNodeIDFactory()),
+         myElementIDFactory(new SMDS_MeshElementIDFactory()),
+         myHasConstructionEdges(false), myHasConstructionFaces(false),
+         myHasInverseElements(true),
+         myNodeMin(0), myNodeMax(0), myCellLinksSize(0),
+         myNodePool(0), myEdgePool(0), myFacePool(0), myVolumePool(0)
+{
+  myMeshId = _meshList.size();         // --- index of the mesh to push back in the vector
+  MESSAGE("myMeshId=" << myMeshId);
+  MESSAGE("sizeof(SMDS_MeshElement) " << sizeof(SMDS_MeshElement) );
+  MESSAGE("sizeof(SMDS_MeshNode) " << sizeof(SMDS_MeshNode) );
+  MESSAGE("sizeof(SMDS_MeshCell) " << sizeof(SMDS_MeshCell) );
+  MESSAGE("sizeof(SMDS_VtkVolume) " << sizeof(SMDS_VtkVolume) );
+  MESSAGE("sizeof(SMDS_Position) " << sizeof(SMDS_Position) );
+  MESSAGE("sizeof(SMDS_SpacePosition) " << sizeof(SMDS_SpacePosition) );
+  myNodeIDFactory->SetMesh(this);
+  myElementIDFactory->SetMesh(this);
+  _meshList.push_back(this);
+  myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
+  myEdgePool = new ObjectPool<SMDS_VtkEdge>(SMDS_Mesh::chunkSize);
+  myFacePool = new ObjectPool<SMDS_VtkFace>(SMDS_Mesh::chunkSize);
+  myVolumePool = new ObjectPool<SMDS_VtkVolume>(SMDS_Mesh::chunkSize);
+
+  myNodes.clear();
+  myCells.clear();
+  myIDElements.clear();
+  myVtkIndex.clear();
+  myGrid = vtkUnstructuredGrid::New();
+  myGrid->Initialize();
+  myGrid->Allocate();
+  vtkPoints* points = vtkPoints::New();
+  points->SetNumberOfPoints(SMDS_Mesh::chunkSize);
+  myGrid->SetPoints( points );
+  points->Delete();
+  myGrid->BuildLinks();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -117,10 +155,14 @@ SMDS_Mesh::SMDS_Mesh()
 /// (2003-09-08) of SMESH
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
-       :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
-       myElementIDFactory(parent->myElementIDFactory),
-       myHasConstructionEdges(false), myHasConstructionFaces(false),
-       myHasInverseElements(true)
+        :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
+         myElementIDFactory(parent->myElementIDFactory),
+         myHasConstructionEdges(false), myHasConstructionFaces(false),
+         myHasInverseElements(true),
+         myNodePool(parent->myNodePool),
+         myEdgePool(parent->myEdgePool),
+         myFacePool(parent->myFacePool),
+         myVolumePool(parent->myVolumePool)
 {
 }
 
@@ -130,9 +172,9 @@ SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
 
 SMDS_Mesh *SMDS_Mesh::AddSubMesh()
 {
-       SMDS_Mesh *submesh = new SMDS_Mesh(this);
-       myChildren.insert(myChildren.end(), submesh);
-       return submesh;
+        SMDS_Mesh *submesh = new SMDS_Mesh(this);
+        myChildren.insert(myChildren.end(), submesh);
+        return submesh;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -156,9 +198,16 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
   // find the MeshNode corresponding to ID
   const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
   if(!node){
-    if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-    SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
-    myNodes.Add(node);
+    //if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+    //SMDS_MeshNode * node=new SMDS_MeshNode(ID, myMeshId, -1, x, y, z);
+    SMDS_MeshNode * node = myNodePool->getNew();
+    node->init(ID, myMeshId, -1, x, y, z);
+    if (ID >= myNodes.size())
+    {
+        myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
+        //MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
+    }
+    myNodes[ID] = node;
     myNodeIDFactory->BindID(ID,node);
     myInfo.myNbNodes++;
     return node;
@@ -166,12 +215,59 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
     return NULL;
 }
 
+///////////////////////////////////////////////////////////////////////////////
+/// create a Mesh0DElement and add it to the current Mesh
+/// @return : The created Mesh0DElement
+///////////////////////////////////////////////////////////////////////////////
+SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
+{
+  SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
+  if (!node) return NULL;
+  return SMDS_Mesh::Add0DElementWithID(node, ID);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// create a Mesh0DElement and add it to the current Mesh
+/// @return : The created Mesh0DElement
+///////////////////////////////////////////////////////////////////////////////
+SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
+{
+  return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Create a new Mesh0DElement and at it to the mesh
+/// @param idnode ID of the node
+/// @param ID ID of the 0D element to create
+/// @return The created 0D element or NULL if an element with this
+///         ID already exists or if input node is not found.
+///////////////////////////////////////////////////////////////////////////////
+SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int ID)
+{
+  if (!n) return 0;
+
+  //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
+  //MESSAGE("Add0DElementWithID" << ID)
+  SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
+  if (myElementIDFactory->BindID(ID, el0d)) {
+    SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
+    //node->AddInverseElement(el0d);// --- fait avec BindID
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = el0d;
+    myInfo.myNb0DElements++;
+    return el0d;
+  }
+
+  delete el0d;
+  return NULL;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 /// create a MeshEdge and add it to the current Mesh
 /// @return : The created MeshEdge
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) 
+SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
 {
   SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
   SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
@@ -185,7 +281,7 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
-                                 const SMDS_MeshNode * node2)
+                                  const SMDS_MeshNode * node2)
 {
   return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
 }
@@ -200,28 +296,31 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
-                                       const SMDS_MeshNode * n2, 
-                                       int ID)
+                                        const SMDS_MeshNode * n2,
+                                        int ID)
 {
   if ( !n1 || !n2 ) return 0;
-
-  if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-
-  SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
-  if(myElementIDFactory->BindID(ID, edge)) {
-    SMDS_MeshNode *node1,*node2;
-    node1=const_cast<SMDS_MeshNode*>(n1);
-    node2=const_cast<SMDS_MeshNode*>(n2);
-    node1->AddInverseElement(edge);
-    node2->AddInverseElement(edge);            
-    myEdges.Add(edge);
-    myInfo.myNbEdges++;
-    return edge;
-  } 
-  else {
-    delete edge;
-    return NULL;
+  SMDS_MeshEdge * edge = 0;
+
+  // --- retreive nodes ID
+  vector<vtkIdType> nodeIds;
+  nodeIds.clear();
+  nodeIds.push_back(n1->getId());
+  nodeIds.push_back(n2->getId());
+
+  SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
+  edgevtk->init(nodeIds, this);
+  edge = edgevtk;
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = edge;
+  myInfo.myNbEdges++;
+
+  if (edge && !registerElement(ID, edge))
+  {
+    RemoveElement(edge, false);
+    edge = NULL;
   }
+  return edge;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -230,8 +329,8 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
-                                 const SMDS_MeshNode * n2,
-                                 const SMDS_MeshNode * n3)
+                                  const SMDS_MeshNode * n2,
+                                  const SMDS_MeshNode * n3)
 {
   return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
 }
@@ -246,7 +345,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, i
   SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
   SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
   if(!node1 || !node2 || !node3) return NULL;
-  return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);    
+  return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -258,7 +357,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n3,
                                         int ID)
 {
-  SMDS_MeshFace * face=createTriangle(n1, n2, n3);
+    //MESSAGE("AddFaceWithID " << ID)
+  SMDS_MeshFace * face=createTriangle(n1, n2, n3, myElementIDFactory->GetFreeID());
 
   if (face && !registerElement(ID, face)) {
     RemoveElement(face, false);
@@ -273,9 +373,9 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
-                                 const SMDS_MeshNode * n2,
-                                 const SMDS_MeshNode * n3,
-                                 const SMDS_MeshNode * n4)
+                                  const SMDS_MeshNode * n2,
+                                  const SMDS_MeshNode * n3,
+                                  const SMDS_MeshNode * n4)
 {
   return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
 }
@@ -284,11 +384,11 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
 /// Add a quadrangle defined by its nodes IDs
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, 
-                                       int idnode2, 
-                                       int idnode3,
-                                       int idnode4, 
-                                       int ID)
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
+                                        int idnode2,
+                                        int idnode3,
+                                        int idnode4,
+                                        int ID)
 {
   SMDS_MeshNode *node1, *node2, *node3, *node4;
   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
@@ -296,7 +396,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
   node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
   node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
   if(!node1 || !node2 || !node3 || !node4) return NULL;
-  return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);     
+  return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -309,7 +409,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n4,
                                         int ID)
 {
-  SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4);
+  //MESSAGE("AddFaceWithID " << ID);
+  SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
 
   if (face && !registerElement(ID, face)) {
     RemoveElement(face, false);
@@ -329,7 +430,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
 {
   if (!hasConstructionEdges())
     return NULL;
-  return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
+     //MESSAGE("AddFaceWithID");
+ return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -345,10 +447,12 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
     return NULL;
   if ( !e1 || !e2 || !e3 ) return 0;
 
-  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+    //MESSAGE("AddFaceWithID" << ID);
 
   SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
-  myFaces.Add(face);
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = face;
   myInfo.myNbTriangles++;
 
   if (!registerElement(ID, face)) {
@@ -370,7 +474,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
 {
   if (!hasConstructionEdges())
     return NULL;
-  return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
+     //MESSAGE("AddFaceWithID" );
+ return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -385,10 +490,12 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
 {
   if (!hasConstructionEdges())
     return NULL;
+    //MESSAGE("AddFaceWithID" << ID);
   if ( !e1 || !e2 || !e3 || !e4 ) return 0;
-  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
-  myFaces.Add(face);
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = face;
   myInfo.myNbQuadrangles++;
 
   if (!registerElement(ID, face))
@@ -400,34 +507,36 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Create a new tetrahedron and add it to the mesh. 
-///@return The created tetrahedron 
+///Create a new tetrahedron and add it to the mesh.
+///@return The created tetrahedron
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
-                                     const SMDS_MeshNode * n2, 
-                                     const SMDS_MeshNode * n3,
-                                     const SMDS_MeshNode * n4)
+                                      const SMDS_MeshNode * n2,
+                                      const SMDS_MeshNode * n3,
+                                      const SMDS_MeshNode * n4)
 {
   int ID = myElementIDFactory->GetFreeID();
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
   if(v==NULL) myElementIDFactory->ReleaseID(ID);
   return v;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Create a new tetrahedron and add it to the mesh. 
+///Create a new tetrahedron and add it to the mesh.
 ///@param ID The ID of the new volume
 ///@return The created tetrahedron or NULL if an element with this ID already exists
 ///or if input nodes are not found.
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, 
-                                            int idnode2,
-                                            int idnode3, 
-                                            int idnode4, 
-                                            int ID)
+SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
+                                             int idnode2,
+                                             int idnode3,
+                                             int idnode4,
+                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID" << ID);
   SMDS_MeshNode *node1, *node2, *node3, *node4;
   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
@@ -436,11 +545,11 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
   if(!node1 || !node2 || !node3 || !node4) return NULL;
   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
 }
-       
+
 ///////////////////////////////////////////////////////////////////////////////
-///Create a new tetrahedron and add it to the mesh. 
+///Create a new tetrahedron and add it to the mesh.
 ///@param ID The ID of the new volume
-///@return The created tetrahedron 
+///@return The created tetrahedron
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
@@ -449,16 +558,18 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n4,
                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshVolume* volume = 0;
   if ( !n1 || !n2 || !n3 || !n4) return volume;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if(hasConstructionFaces()) {
     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
     SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
     SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
-    myVolumes.Add(volume);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbTetras++;
   }
   else if(hasConstructionEdges()) {
@@ -466,8 +577,19 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
-    myVolumes.Add(volume);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getId());
+    nodeIds.push_back(n3->getId()); // order SMDS-->VTK
+    nodeIds.push_back(n2->getId());
+    nodeIds.push_back(n4->getId());
+
+    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+    volvtk->init(nodeIds, this);
+    volume = volvtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbTetras++;
   }
 
@@ -479,38 +601,40 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Create a new pyramid and add it to the mesh. 
+///Create a new pyramid and add it to the mesh.
 ///Nodes 1,2,3 and 4 define the base of the pyramid
-///@return The created pyramid 
+///@return The created pyramid
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
-                                     const SMDS_MeshNode * n2, 
-                                     const SMDS_MeshNode * n3,
-                                     const SMDS_MeshNode * n4, 
-                                     const SMDS_MeshNode * n5)
+                                      const SMDS_MeshNode * n2,
+                                      const SMDS_MeshNode * n3,
+                                      const SMDS_MeshNode * n4,
+                                      const SMDS_MeshNode * n5)
 {
   int ID = myElementIDFactory->GetFreeID();
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
   if(v==NULL) myElementIDFactory->ReleaseID(ID);
   return v;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Create a new pyramid and add it to the mesh. 
+///Create a new pyramid and add it to the mesh.
 ///Nodes 1,2,3 and 4 define the base of the pyramid
 ///@param ID The ID of the new volume
 ///@return The created pyramid or NULL if an element with this ID already exists
 ///or if input nodes are not found.
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, 
-                                            int idnode2,
-                                            int idnode3, 
-                                            int idnode4, 
-                                            int idnode5, 
-                                            int ID)
+SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
+                                             int idnode2,
+                                             int idnode3,
+                                             int idnode4,
+                                             int idnode5,
+                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
@@ -520,7 +644,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
   if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
 }
-       
+
 ///////////////////////////////////////////////////////////////////////////////
 ///Create a new pyramid and add it to the mesh.
 ///Nodes 1,2,3 and 4 define the base of the pyramid
@@ -535,16 +659,18 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n5,
                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshVolume* volume = 0;
   if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if(hasConstructionFaces()) {
     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
     SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
     SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
     SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
-    myVolumes.Add(volume);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbPyramids++;
   }
   else if(hasConstructionEdges()) {
@@ -552,8 +678,20 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
-    myVolumes.Add(volume);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getId());
+    nodeIds.push_back(n4->getId());
+    nodeIds.push_back(n3->getId());
+    nodeIds.push_back(n2->getId());
+    nodeIds.push_back(n5->getId());
+
+    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+    volvtk->init(nodeIds, this);
+    volume = volvtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbPyramids++;
   }
 
@@ -565,40 +703,42 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Create a new prism and add it to the mesh. 
+///Create a new prism and add it to the mesh.
 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
-///@return The created prism 
+///@return The created prism
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
-                                     const SMDS_MeshNode * n2, 
-                                     const SMDS_MeshNode * n3,
-                                     const SMDS_MeshNode * n4, 
-                                     const SMDS_MeshNode * n5,
-                                     const SMDS_MeshNode * n6)
+                                      const SMDS_MeshNode * n2,
+                                      const SMDS_MeshNode * n3,
+                                      const SMDS_MeshNode * n4,
+                                      const SMDS_MeshNode * n5,
+                                      const SMDS_MeshNode * n6)
 {
   int ID = myElementIDFactory->GetFreeID();
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
   if(v==NULL) myElementIDFactory->ReleaseID(ID);
   return v;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Create a new prism and add it to the mesh. 
+///Create a new prism and add it to the mesh.
 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
 ///@param ID The ID of the new volume
 ///@return The created prism or NULL if an element with this ID already exists
 ///or if input nodes are not found.
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, 
-                                            int idnode2,
-                                            int idnode3, 
-                                            int idnode4, 
-                                            int idnode5, 
-                                            int idnode6, 
-                                            int ID)
+SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
+                                             int idnode2,
+                                             int idnode3,
+                                             int idnode4,
+                                             int idnode5,
+                                             int idnode6,
+                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
@@ -609,7 +749,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
   if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
 }
-       
+
 ///////////////////////////////////////////////////////////////////////////////
 ///Create a new prism and add it to the mesh.
 ///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
@@ -625,9 +765,10 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n6,
                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshVolume* volume = 0;
   if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if(hasConstructionFaces()) {
     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
     SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
@@ -635,7 +776,8 @@ 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.Add(volume);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbPrisms++;
   }
   else if(hasConstructionEdges()) {
@@ -643,8 +785,21 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
-    myVolumes.Add(volume);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getId());
+    nodeIds.push_back(n3->getId());
+    nodeIds.push_back(n2->getId());
+    nodeIds.push_back(n4->getId());
+    nodeIds.push_back(n6->getId());
+    nodeIds.push_back(n5->getId());
+
+    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+    volvtk->init(nodeIds, this);
+    volume = volvtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbPrisms++;
   }
 
@@ -656,44 +811,46 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Create a new hexahedron and add it to the mesh. 
+///Create a new hexahedron and add it to the mesh.
 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
-///@return The created hexahedron 
+///@return The created hexahedron
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
-                                     const SMDS_MeshNode * n2, 
-                                     const SMDS_MeshNode * n3,
-                                     const SMDS_MeshNode * n4, 
-                                     const SMDS_MeshNode * n5,
-                                     const SMDS_MeshNode * n6, 
-                                     const SMDS_MeshNode * n7,
-                                     const SMDS_MeshNode * n8)
+                                      const SMDS_MeshNode * n2,
+                                      const SMDS_MeshNode * n3,
+                                      const SMDS_MeshNode * n4,
+                                      const SMDS_MeshNode * n5,
+                                      const SMDS_MeshNode * n6,
+                                      const SMDS_MeshNode * n7,
+                                      const SMDS_MeshNode * n8)
 {
   int ID = myElementIDFactory->GetFreeID();
-  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
+     //MESSAGE("AddVolumeWithID " << ID);
+ SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
   if(v==NULL) myElementIDFactory->ReleaseID(ID);
   return v;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Create a new hexahedron and add it to the mesh. 
+///Create a new hexahedron and add it to the mesh.
 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
 ///@param ID The ID of the new volume
 ///@return The created hexahedron or NULL if an element with this ID already
 ///exists or if input nodes are not found.
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, 
-                                            int idnode2,
-                                            int idnode3, 
-                                            int idnode4, 
-                                            int idnode5, 
-                                            int idnode6, 
-                                            int idnode7,
-                                            int idnode8, 
-                                            int ID)
+SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
+                                             int idnode2,
+                                             int idnode3,
+                                             int idnode4,
+                                             int idnode5,
+                                             int idnode6,
+                                             int idnode7,
+                                             int idnode8,
+                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
@@ -708,7 +865,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
                                     node7, node8, ID);
 }
-       
+
 ///////////////////////////////////////////////////////////////////////////////
 ///Create a new hexahedron and add it to the mesh.
 ///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
@@ -727,9 +884,10 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n8,
                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshVolume* volume = 0;
   if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if(hasConstructionFaces()) {
     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
     SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
@@ -738,7 +896,8 @@ 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.Add(volume);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbHexas++;
   }
   else if(hasConstructionEdges()) {
@@ -746,12 +905,26 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-//    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);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getId());
+    nodeIds.push_back(n4->getId());
+    nodeIds.push_back(n3->getId());
+    nodeIds.push_back(n2->getId());
+    nodeIds.push_back(n5->getId());
+    nodeIds.push_back(n8->getId());
+    nodeIds.push_back(n7->getId());
+    nodeIds.push_back(n6->getId());
+
+    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+    volvtk->init(nodeIds, this);
+    volume = volvtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbHexas++;
   }
-
   if (!registerElement(ID, volume)) {
     RemoveElement(volume, false);
     volume = NULL;
@@ -769,6 +942,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
                                       const SMDS_MeshFace * f3,
                                       const SMDS_MeshFace * f4)
 {
+    //MESSAGE("AddVolumeWithID");
   if (!hasConstructionFaces())
     return NULL;
   return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
@@ -777,7 +951,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
 ///////////////////////////////////////////////////////////////////////////////
 ///Create a new tetrahedron defined by its faces and add it to the mesh.
 ///@param ID The ID of the new volume
-///@return The created tetrahedron 
+///@return The created tetrahedron
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
@@ -786,12 +960,14 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
                                             const SMDS_MeshFace * f4,
                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID" << ID);
   if (!hasConstructionFaces())
     return NULL;
   if ( !f1 || !f2 || !f3 || !f4) return 0;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
-  myVolumes.Add(volume);
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volume;
   myInfo.myNbTetras++;
 
   if (!registerElement(ID, volume)) {
@@ -812,7 +988,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
                                       const SMDS_MeshFace * f4,
                                       const SMDS_MeshFace * f5)
 {
-  if (!hasConstructionFaces())
+     //MESSAGE("AddVolumeWithID");
+ if (!hasConstructionFaces())
     return NULL;
   return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
 }
@@ -820,7 +997,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
 ///////////////////////////////////////////////////////////////////////////////
 ///Create a new pyramid defined by its faces and add it to the mesh.
 ///@param ID The ID of the new volume
-///@return The created pyramid 
+///@return The created pyramid
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
@@ -830,12 +1007,14 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
                                             const SMDS_MeshFace * f5,
                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID" << ID);
   if (!hasConstructionFaces())
     return NULL;
   if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
-  myVolumes.Add(volume);
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volume;
   myInfo.myNbPyramids++;
 
   if (!registerElement(ID, volume)) {
@@ -857,7 +1036,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
                                       const SMDS_MeshFace * f5,
                                       const SMDS_MeshFace * f6)
 {
-  if (!hasConstructionFaces())
+     //MESSAGE("AddVolumeWithID" );
+ if (!hasConstructionFaces())
     return NULL;
   return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
 }
@@ -865,7 +1045,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
 ///////////////////////////////////////////////////////////////////////////////
 ///Create a new prism defined by its faces and add it to the mesh.
 ///@param ID The ID of the new volume
-///@return The created prism 
+///@return The created prism
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
@@ -876,12 +1056,14 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
                                             const SMDS_MeshFace * f6,
                                             int ID)
 {
+     //MESSAGE("AddVolumeWithID" << ID);
   if (!hasConstructionFaces())
     return NULL;
   if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
-  myVolumes.Add(volume);
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volume;
   myInfo.myNbPrisms++;
 
   if (!registerElement(ID, volume)) {
@@ -904,7 +1086,7 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
     nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
     if (!nodes[i]) return NULL;
   }
-  return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID); 
+  return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -917,7 +1099,7 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
 {
   SMDS_MeshFace * face;
 
-  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if (hasConstructionEdges())
   {
     MESSAGE("Error : Not implemented");
@@ -928,7 +1110,8 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
     for ( int i = 0; i < nodes.size(); ++i )
       if ( !nodes[ i ] ) return 0;
     face = new SMDS_PolygonalFaceOfNodes(nodes);
-    myFaces.Add(face);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
     myInfo.myNbPolygons++;
   }
 
@@ -950,7 +1133,7 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> no
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Create a new polyhedral volume and add it to the mesh. 
+/// 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.
@@ -971,7 +1154,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Create a new polyhedral volume and add it to the mesh. 
+/// Create a new polyhedral volume and add it to the mesh.
 /// @param ID The ID of the new volume
 /// @return The created  volume
 ///////////////////////////////////////////////////////////////////////////////
@@ -982,7 +1165,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
                              const int                         ID)
 {
   SMDS_MeshVolume* volume;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if (hasConstructionFaces()) {
     MESSAGE("Error : Not implemented");
     return NULL;
@@ -993,7 +1176,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
     for ( int i = 0; i < nodes.size(); ++i )
       if ( !nodes[ i ] ) return 0;
     volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
-    myVolumes.Add(volume);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbPolyhedrons++;
   }
 
@@ -1005,7 +1189,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Create a new polyhedral volume and add it to the mesh. 
+/// Create a new polyhedral volume and add it to the mesh.
 /// @return The created  volume
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -1022,18 +1206,42 @@ SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
 ///////////////////////////////////////////////////////////////////////////////
 /// Registers element with the given ID, maintains inverse connections
 ///////////////////////////////////////////////////////////////////////////////
-bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
+bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
 {
-  if (myElementIDFactory->BindID(ID, element)) {
-    SMDS_ElemIteratorPtr it = element->nodesIterator();
-    while (it->more()) {
-      SMDS_MeshNode *node = static_cast<SMDS_MeshNode*>
-        (const_cast<SMDS_MeshElement*>(it->next()));
-      node->AddInverseElement(element);
-    }
-    return true;
+  //MESSAGE("registerElement " << ID)
+  if ((ID < myIDElements.size()) && myIDElements[ID] >= 0) // --- already bound
+  {
+    MESSAGE(" --------------------------------- already bound "<< ID << " " << myIDElements[ID]);
+    return false;
   }
-  return false;
+
+  element->myID = ID;
+  element->myMeshId = myMeshId;
+
+  SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
+  MYASSERT(cell);
+  int vtkId = cell->getVtkId();  
+  if (vtkId == -1)
+    vtkId = myElementIDFactory->SetInVtkGrid(element);
+  
+  if (ID >= myIDElements.size()) // --- resize local vector
+  {
+    MESSAGE(" ------------------- resize myIDElements " << ID << " --> " << ID + SMDS_Mesh::chunkSize);
+    myIDElements.resize(ID + SMDS_Mesh::chunkSize, -1); // fill new elements with -1
+  }
+
+  myIDElements[ID] = vtkId;
+  //MESSAGE("smds:" << ID << " vtk:" << cellId );
+
+  if (vtkId >= myVtkIndex.size()) // --- resize local vector
+  {
+    MESSAGE(" --------------------- resize myVtkIndex " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
+    myVtkIndex.resize(vtkId + SMDS_Mesh::chunkSize, -1);
+  }
+  myVtkIndex[vtkId] = ID;
+
+  myElementIDFactory->updateMinMax(ID);
+  return true;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1041,19 +1249,25 @@ bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
 ///////////////////////////////////////////////////////////////////////////////
 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
 {
-  return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
+  if (ID < 0 || ID >= myNodes.size())
+  {
+    MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
+    return 0;
+  }
+  return (const SMDS_MeshNode *)myNodes[ID];
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Create a triangle and add it to the current mesh. This methode do not bind a
+///Create a triangle and add it to the current mesh. This method do not bind an
 ///ID to the create triangle.
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
                                           const SMDS_MeshNode * node2,
-                                          const SMDS_MeshNode * node3)
+                                          const SMDS_MeshNode * node3,
+                                          int ID)
 {
   if ( !node1 || !node2 || !node3) return 0;
-  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+//  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if(hasConstructionEdges())
   {
     SMDS_MeshEdge *edge1, *edge2, *edge3;
@@ -1061,15 +1275,28 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
     edge2=FindEdgeOrCreate(node2,node3);
     edge3=FindEdgeOrCreate(node3,node1);
 
+    //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
     SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
-    myFaces.Add(face);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
     myInfo.myNbTriangles++;
     return face;
   }
   else
   {
-    SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
-    myFaces.Add(face);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(node1->getId());
+    nodeIds.push_back(node2->getId());
+    nodeIds.push_back(node3->getId());
+
+    SMDS_MeshFace * face = 0;
+    SMDS_VtkFace *facevtk = myFacePool->getNew();
+    facevtk->init(nodeIds, this);
+    face = facevtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
     myInfo.myNbTriangles++;
     return face;
   }
@@ -1080,14 +1307,16 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
 ///a ID to the create triangle.
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
-                                           const SMDS_MeshNode * node2,
-                                           const SMDS_MeshNode * node3,
-                                           const SMDS_MeshNode * node4)
+                                            const SMDS_MeshNode * node2,
+                                            const SMDS_MeshNode * node3,
+                                            const SMDS_MeshNode * node4,
+                                            int ID)
 {
   if ( !node1 || !node2 || !node3 || !node4 ) return 0;
-  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+//  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if(hasConstructionEdges())
   {
+      //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
     SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
     edge1=FindEdgeOrCreate(node1,node2);
     edge2=FindEdgeOrCreate(node2,node3);
@@ -1095,14 +1324,27 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
     edge4=FindEdgeOrCreate(node4,node1);
 
     SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
-    myFaces.Add(face);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
     myInfo.myNbQuadrangles++;
     return face;
   }
   else
   {
-    SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
-    myFaces.Add(face);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(node1->getId());
+    nodeIds.push_back(node2->getId());
+    nodeIds.push_back(node3->getId());
+    nodeIds.push_back(node4->getId());
+
+    SMDS_MeshFace * face = 0;
+    SMDS_VtkFace *facevtk = myFacePool->getNew();
+    facevtk->init(nodeIds, this);
+    face = facevtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
     myInfo.myNbQuadrangles++;
     return face;
   }
@@ -1114,7 +1356,18 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
 
 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
 {
-       RemoveElement(node, true);
+    MESSAGE("RemoveNode");
+        RemoveElement(node, true);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Remove an edge and all the elements which own this edge
+///////////////////////////////////////////////////////////////////////////////
+
+void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
+{
+    MESSAGE("Remove0DElement");
+  RemoveElement(elem0d,true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1123,7 +1376,8 @@ void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
 
 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
 {
-       RemoveElement(edge,true);
+    MESSAGE("RemoveEdge");
+        RemoveElement(edge,true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1132,7 +1386,8 @@ void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
 
 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
 {
-       RemoveElement(face, true);
+    MESSAGE("RemoveFace");
+        RemoveElement(face, true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1141,7 +1396,8 @@ void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
 
 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
 {
-       RemoveElement(volume, true);
+    MESSAGE("RemoveVolume");
+        RemoveElement(volume, true);
 }
 
 //=======================================================================
@@ -1151,8 +1407,8 @@ void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
 
 bool SMDS_Mesh::RemoveFromParent()
 {
-       if (myParent==NULL) return false;
-       else return (myParent->RemoveSubMesh(this));
+        if (myParent==NULL) return false;
+        else return (myParent->RemoveSubMesh(this));
 }
 
 //=======================================================================
@@ -1162,31 +1418,32 @@ bool SMDS_Mesh::RemoveFromParent()
 
 bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
 {
-       bool found = false;
+        bool found = false;
 
-       list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
-       for (; itmsh!=myChildren.end() && !found; itmsh++)
-       {
-               SMDS_Mesh * submesh = *itmsh;
-               if (submesh == aMesh)
-               {
-                       found = true;
-                       myChildren.erase(itmsh);
-               }
-       }
+        list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
+        for (; itmsh!=myChildren.end() && !found; itmsh++)
+        {
+                SMDS_Mesh * submesh = *itmsh;
+                if (submesh == aMesh)
+                {
+                        found = true;
+                        myChildren.erase(itmsh);
+                }
+        }
 
-       return found;
+        return found;
 }
 
 //=======================================================================
 //function : ChangeElementNodes
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
                                    const SMDS_MeshNode    * nodes[],
                                    const int                nbnodes)
 {
+  MYASSERT(0); // REVOIR LES TYPES
   // keep current nodes of elem
   set<const SMDS_MeshElement*> oldNodes;
   SMDS_ElemIteratorPtr itn = element->nodesIterator();
@@ -1201,9 +1458,14 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
   SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(element);
   switch ( elem->GetType() )
   {
+  case SMDSAbs_0DElement: {
+    if ( SMDS_Mesh0DElement* elem0d = dynamic_cast<SMDS_Mesh0DElement*>( elem ))
+      Ok = elem0d->ChangeNode( nodes[0] );
+    break;
+  }
   case SMDSAbs_Edge: {
     if ( nbnodes == 2 ) {
-      if ( SMDS_MeshEdge* edge = dynamic_cast<SMDS_MeshEdge*>( elem ))
+      if ( SMDS_VtkEdge* edge = dynamic_cast<SMDS_VtkEdge*>( elem ))
         Ok = edge->ChangeNodes( nodes[0], nodes[1] );
     }
     else if ( nbnodes == 3 ) {
@@ -1226,7 +1488,7 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
   case SMDSAbs_Volume: {
     if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
       Ok = vol->ChangeNodes( nodes, nbnodes );
-    else 
+    else
       if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
         Ok = QV->ChangeNodes( nodes, nbnodes );
     break;
@@ -1322,6 +1584,50 @@ bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement *            elem,
 }
 
 
+//=======================================================================
+//function : Find0DElement
+//purpose  :
+//=======================================================================
+const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(int idnode) const
+{
+  const SMDS_MeshNode * node = FindNode(idnode);
+  if(node == NULL) return NULL;
+  return Find0DElement(node);
+}
+
+const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
+{
+  if (!node) return 0;
+  const SMDS_Mesh0DElement* toReturn = NULL;
+  SMDS_ElemIteratorPtr it1 = node->GetInverseElementIterator(SMDSAbs_0DElement);
+  while (it1->more() && (toReturn == NULL)) {
+    const SMDS_MeshElement* e = it1->next();
+    if (e->NbNodes() == 1) {
+      toReturn = static_cast<const SMDS_Mesh0DElement*>(e);
+    }
+  }
+  return toReturn;
+}
+
+//=======================================================================
+//function : Find0DElementOrCreate
+//purpose  :
+//=======================================================================
+//SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
+//{
+//  if (!node) return 0;
+//  SMDS_Mesh0DElement * toReturn = NULL;
+//  toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
+//  if (toReturn == NULL) {
+//    //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
+//    toReturn = new SMDS_Mesh0DElement(node);
+//    my0DElements.Add(toReturn);
+//    myInfo.myNb0DElements++;
+//  }
+//  return toReturn;
+//}
+
+
 //=======================================================================
 //function : FindEdge
 //purpose  :
@@ -1364,15 +1670,24 @@ const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
 //=======================================================================
 
 SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
-                                           const SMDS_MeshNode * node2) 
+                                           const SMDS_MeshNode * node2)
 {
   if ( !node1 || !node2) return 0;
   SMDS_MeshEdge * toReturn=NULL;
   toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
   if(toReturn==NULL) {
-    if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-    toReturn=new SMDS_MeshEdge(node1,node2);
-    myEdges.Add(toReturn);
+    //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+    int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
+    adjustmyCellsCapacity(ID);
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(node1->getId());
+    nodeIds.push_back(node2->getId());
+
+    SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
+    edgevtk->init(nodeIds, this);
+    toReturn = edgevtk;
+    myCells[ID] = toReturn;
     myInfo.myNbEdges++;
   }
   return toReturn;
@@ -1427,7 +1742,7 @@ const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
 //=======================================================================
 
 const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
-       int idnode3) const
+        int idnode3) const
 {
   const SMDS_MeshNode * node1=FindNode(idnode1);
   const SMDS_MeshNode * node2=FindNode(idnode2);
@@ -1469,7 +1784,8 @@ SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
   SMDS_MeshFace * toReturn=NULL;
   toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
   if(toReturn==NULL) {
-    toReturn = createTriangle(node1,node2,node3);
+    int ID = myElementIDFactory->GetFreeID();
+    toReturn = createTriangle(node1,node2,node3, ID);
   }
   return toReturn;
 }
@@ -1527,7 +1843,8 @@ SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
   SMDS_MeshFace * toReturn=NULL;
   toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
   if(toReturn==NULL) {
-    toReturn=createQuadrangle(node1,node2,node3,node4);
+    int ID = myElementIDFactory->GetFreeID();
+    toReturn=createQuadrangle(node1,node2,node3,node4,ID);
   }
   return toReturn;
 }
@@ -1651,7 +1968,12 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
 
 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
 {
-  return myElementIDFactory->MeshElement(IDelem);
+  if ((IDelem < 0) || IDelem >= myCells.size())
+  {
+    MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
+    return 0;
+  }
+  return myCells[IDelem];
 }
 
 //=======================================================================
@@ -1666,6 +1988,7 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
   for (int inode = 0; inode < nbnodes; inode++) {
     const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
     if (node == NULL) return NULL;
+    poly_nodes[inode] = node;
   }
   return FindFace(poly_nodes);
 }
@@ -1694,100 +2017,111 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nod
 
 //=======================================================================
 //function : DumpNodes
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMDS_Mesh::DumpNodes() const
 {
-       MESSAGE("dump nodes of mesh : ");
-       SMDS_NodeIteratorPtr itnode=nodesIterator();
-       while(itnode->more()) MESSAGE(itnode->next());
+        MESSAGE("dump nodes of mesh : ");
+        SMDS_NodeIteratorPtr itnode=nodesIterator();
+        while(itnode->more()) ; //MESSAGE(itnode->next());
+}
+
+//=======================================================================
+//function : Dump0DElements
+//purpose  :
+//=======================================================================
+void SMDS_Mesh::Dump0DElements() const
+{
+  MESSAGE("dump 0D elements of mesh : ");
+  SMDS_0DElementIteratorPtr it0d = elements0dIterator();
+  while(it0d->more()) ; //MESSAGE(it0d->next());
 }
 
 //=======================================================================
 //function : DumpEdges
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMDS_Mesh::DumpEdges() const
 {
-       MESSAGE("dump edges of mesh : ");
-       SMDS_EdgeIteratorPtr itedge=edgesIterator();
-       while(itedge->more()) MESSAGE(itedge->next());
+        MESSAGE("dump edges of mesh : ");
+        SMDS_EdgeIteratorPtr itedge=edgesIterator();
+        while(itedge->more()) ; //MESSAGE(itedge->next());
 }
 
 //=======================================================================
 //function : DumpFaces
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMDS_Mesh::DumpFaces() const
 {
-       MESSAGE("dump faces of mesh : ");
-       SMDS_FaceIteratorPtr itface=facesIterator();
-       while(itface->more()) MESSAGE(itface->next());
+        MESSAGE("dump faces of mesh : ");
+        SMDS_FaceIteratorPtr itface=facesIterator();
+        while(itface->more()) ; //MESSAGE(itface->next());
 }
 
 //=======================================================================
 //function : DumpVolumes
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMDS_Mesh::DumpVolumes() const
 {
-       MESSAGE("dump volumes of mesh : ");
-       SMDS_VolumeIteratorPtr itvol=volumesIterator();
-       while(itvol->more()) MESSAGE(itvol->next());
+        MESSAGE("dump volumes of mesh : ");
+        SMDS_VolumeIteratorPtr itvol=volumesIterator();
+        while(itvol->more()) ; //MESSAGE(itvol->next());
 }
 
 //=======================================================================
 //function : DebugStats
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMDS_Mesh::DebugStats() const
 {
-       MESSAGE("Debug stats of mesh : ");
+  MESSAGE("Debug stats of mesh : ");
 
-       MESSAGE("===== NODES ====="<<NbNodes());
-       MESSAGE("===== EDGES ====="<<NbEdges());
-       MESSAGE("===== FACES ====="<<NbFaces());
-       MESSAGE("===== VOLUMES ====="<<NbVolumes());
+  MESSAGE("===== NODES ====="<<NbNodes());
+  MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
+  MESSAGE("===== EDGES ====="<<NbEdges());
+  MESSAGE("===== FACES ====="<<NbFaces());
+  MESSAGE("===== VOLUMES ====="<<NbVolumes());
 
-       MESSAGE("End Debug stats of mesh ");
+  MESSAGE("End Debug stats of mesh ");
 
-       //#ifdef DEB
-       
-       SMDS_NodeIteratorPtr itnode=nodesIterator();
-       int sizeofnodes = 0;
-       int sizeoffaces = 0;
+  //#ifdef DEB
 
-       while(itnode->more())
-       {
-               const SMDS_MeshNode *node = itnode->next();
+  SMDS_NodeIteratorPtr itnode=nodesIterator();
+  int sizeofnodes = 0;
+  int sizeoffaces = 0;
+
+  while(itnode->more())
+  {
+    const SMDS_MeshNode *node = itnode->next();
 
-               sizeofnodes += sizeof(*node);
-               
-               SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
-               while(it->more())
-               {
-                       const SMDS_MeshElement *me = it->next();
-                       sizeofnodes += sizeof(me);
-               }
+    sizeofnodes += sizeof(*node);
 
-       }
+    SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
+    while(it->more())
+    {
+      const SMDS_MeshElement *me = it->next();
+      sizeofnodes += sizeof(me);
+    }
+  }
 
-       SMDS_FaceIteratorPtr itface=facesIterator();
-       while(itface->more())
-       {
-               const SMDS_MeshElement *face = itface->next();          
-               sizeoffaces += sizeof(*face);
+  SMDS_FaceIteratorPtr itface=facesIterator();
+  while(itface->more())
+  {
+    const SMDS_MeshElement *face = itface->next();
+    sizeoffaces += sizeof(*face);
+  }
 
-       }
-       MESSAGE("total size of node elements = " << sizeofnodes);;
-       MESSAGE("total size of face elements = " << sizeoffaces);;
+  MESSAGE("total size of node elements = " << sizeofnodes);;
+  MESSAGE("total size of face elements = " << sizeoffaces);;
 
-       //#endif
+  //#endif
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1795,7 +2129,15 @@ void SMDS_Mesh::DebugStats() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbNodes() const
 {
-       return myNodes.Size();
+        return myNodes.size();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the number of 0D elements
+///////////////////////////////////////////////////////////////////////////////
+int SMDS_Mesh::Nb0DElements() const
+{
+  return myInfo.Nb0DElements(); // -PR- a verfier
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1803,7 +2145,7 @@ int SMDS_Mesh::NbNodes() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbEdges() const
 {
-       return myEdges.Size();
+        return myInfo.NbEdges(); // -PR- a verfier
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1811,7 +2153,7 @@ int SMDS_Mesh::NbEdges() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbFaces() const
 {
-       return myFaces.Size();
+        return myInfo.NbFaces();  // -PR- a verfier
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1819,7 +2161,7 @@ int SMDS_Mesh::NbFaces() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbVolumes() const
 {
-       return myVolumes.Size();
+        return myInfo.NbVolumes(); // -PR- a verfier
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1829,7 +2171,7 @@ int SMDS_Mesh::NbVolumes() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbSubMesh() const
 {
-       return myChildren.size();
+        return myChildren.size();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1859,31 +2201,38 @@ SMDS_Mesh::~SMDS_Mesh()
     while (itn->more())
       myNodeIDFactory->ReleaseID(itn->next()->GetID());
   }
-  SetOfNodes::Iterator itn(myNodes);
-  for (; itn.More(); itn.Next())
-    delete itn.Value();
 
-  SetOfEdges::Iterator ite(myEdges);
-  for (; ite.More(); ite.Next())
-  {
-    SMDS_MeshElement* elem = ite.Value();
-    delete elem;
-  }
+//   SetOfNodes::Iterator itn(myNodes);
+//   for (; itn.More(); itn.Next())
+//     delete itn.Value();
 
-  SetOfFaces::Iterator itf(myFaces);
-  for (; itf.More(); itf.Next())
-  {
-    SMDS_MeshElement* elem = itf.Value();
-    delete elem;
-  }
+//   SetOf0DElements::Iterator it0d (my0DElements);
+//   for (; it0d.More(); it0d.Next())
+//   {
+//     SMDS_MeshElement* elem = it0d.Value();
+//     delete elem;
+//   }
 
-  SetOfVolumes::Iterator itv(myVolumes);
-  for (; itv.More(); itv.Next())
-  {
-    SMDS_MeshElement* elem = itv.Value();
-    delete elem;
-  }
+//   SetOfEdges::Iterator ite(myEdges);
+//   for (; ite.More(); ite.Next())
+//   {
+//     SMDS_MeshElement* elem = ite.Value();
+//     delete elem;
+//   }
 
+//   SetOfFaces::Iterator itf(myFaces);
+//   for (; itf.More(); itf.Next())
+//   {
+//     SMDS_MeshElement* elem = itf.Value();
+//     delete elem;
+//   }
+
+//   SetOfVolumes::Iterator itv(myVolumes);
+//   for (; itv.More(); itv.Next())
+//   {
+//     SMDS_MeshElement* elem = itv.Value();
+//     delete elem;
+//   }
 }
 
 //================================================================================
@@ -1906,25 +2255,36 @@ void SMDS_Mesh::Clear()
     myNodeIDFactory->Clear();
     myElementIDFactory->Clear();
   }
-  SMDS_VolumeIteratorPtr itv = volumesIterator();
+
+  SMDS_ElemIteratorPtr itv = elementsIterator();
   while (itv->more())
     delete itv->next();
-  myVolumes.Clear();
+  myCells.clear();
 
-  SMDS_FaceIteratorPtr itf = facesIterator();
-  while (itf->more())
-    delete itf->next();
-  myFaces.Clear();
-      
-  SMDS_EdgeIteratorPtr ite = edgesIterator();
-  while (ite->more())
-    delete ite->next();
-  myEdges.Clear();
+//  SMDS_VolumeIteratorPtr itv = volumesIterator();
+//  while (itv->more())
+//    delete itv->next();
+//  myVolumes.Clear();
+//
+//  SMDS_FaceIteratorPtr itf = facesIterator();
+//  while (itf->more())
+//    delete itf->next();
+//  myFaces.Clear();
+//
+//  SMDS_EdgeIteratorPtr ite = edgesIterator();
+//  while (ite->more())
+//    delete ite->next();
+//  myEdges.Clear();
+//
+//  SMDS_0DElementIteratorPtr it0d = elements0dIterator();
+//  while (it0d->more())
+//    delete it0d->next();
+//  my0DElements.Clear();
 
   SMDS_NodeIteratorPtr itn = nodesIterator();
   while (itn->more())
     delete itn->next();
-  myNodes.Clear();
+  myNodes.clear();
 
   list<SMDS_Mesh*>::iterator itc=myChildren.begin();
   while(itc!=myChildren.end())
@@ -1940,7 +2300,7 @@ void SMDS_Mesh::Clear()
 ///////////////////////////////////////////////////////////////////////////////
 bool SMDS_Mesh::hasConstructionEdges()
 {
-       return myHasConstructionEdges;
+        return myHasConstructionEdges;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1952,7 +2312,7 @@ bool SMDS_Mesh::hasConstructionEdges()
 ///////////////////////////////////////////////////////////////////////////////
 bool SMDS_Mesh::hasConstructionFaces()
 {
-       return myHasConstructionFaces;
+        return myHasConstructionFaces;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1961,7 +2321,7 @@ bool SMDS_Mesh::hasConstructionFaces()
 ///////////////////////////////////////////////////////////////////////////////
 bool SMDS_Mesh::hasInverseElements()
 {
-       return myHasInverseElements;
+        return myHasInverseElements;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1970,7 +2330,7 @@ bool SMDS_Mesh::hasInverseElements()
 ///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::setConstructionEdges(bool b)
 {
-       myHasConstructionEdges=b;
+        myHasConstructionEdges=b;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1979,7 +2339,7 @@ void SMDS_Mesh::setConstructionEdges(bool b)
 ///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::setConstructionFaces(bool b)
 {
-        myHasConstructionFaces=b;
+         myHasConstructionFaces=b;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1988,283 +2348,309 @@ void SMDS_Mesh::setConstructionFaces(bool b)
 ///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::setInverseElements(bool b)
 {
-       if(!b) MESSAGE("Error : inverseElement=false not implemented");
-       myHasInverseElements=b;
+        if(!b) MESSAGE("Error : inverseElement=false not implemented");
+        myHasInverseElements=b;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Return an iterator on nodes of the current mesh factory
+///Iterator on NCollection_Map
 ///////////////////////////////////////////////////////////////////////////////
-class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator
+template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
+struct MYNode_Map_Iterator: public FATHER
+{
+  int _ctr;
+  const MAP& _map;
+  MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
+  {
+      _ctr = 0;
+  }
+
+  bool more()
+  {
+      while (_ctr < _map.size())
+      {
+          if (_map[_ctr])
+              return true;
+          _ctr++;
+      }
+          return false;
+  }
+
+  ELEM next()
+  {
+    ELEM current = _map[_ctr];
+    _ctr++;
+    return current;
+  }
+};
+
+template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
+struct MYElem_Map_Iterator: public FATHER
 {
-  SMDS_ElemIteratorPtr myIterator;
- public:
-  SMDS_Mesh_MyNodeIterator(const SMDS_ElemIteratorPtr& it):myIterator(it)
-  {}
+  int _ctr;
+  int _type;
+  const MAP& _map;
+  MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
+  {
+      _ctr = 0;
+      _type = typ;
+  }
 
   bool more()
   {
-    return myIterator->more();
+      while (_ctr < _map.size())
+      {
+          if (_map[_ctr])
+            if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
+              return true;
+          _ctr++;
+      }
+          return false;
   }
 
-  const SMDS_MeshNode* next()
+  ELEM next()
   {
-    return static_cast<const SMDS_MeshNode*>(myIterator->next());
+    ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
+    _ctr++;
+    return current;
   }
 };
 
+///////////////////////////////////////////////////////////////////////////////
+/// Return an iterator on nodes of the current mesh factory
+///////////////////////////////////////////////////////////////////////////////
+
 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
 {
-  return SMDS_NodeIteratorPtr
-    (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
+  //return SMDS_NodeIteratorPtr
+  //  (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
+  typedef MYNode_Map_Iterator
+    < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
+  return SMDS_NodeIteratorPtr(new TIterator(myNodes));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Return an iterator on elements of the current mesh factory
+///Return an iterator on 0D elements of the current mesh.
 ///////////////////////////////////////////////////////////////////////////////
-SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const
+
+SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator() const
 {
-  return myElementIDFactory->elementsIterator();
+  typedef MYElem_Map_Iterator
+    < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
+  return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 ///Return an iterator on edges of the current mesh.
 ///////////////////////////////////////////////////////////////////////////////
-class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator
-{
-  typedef SMDS_Mesh::SetOfEdges SetOfEdges;
-  SetOfEdges::Iterator myIterator;
- public:
-  SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):myIterator(s)
-  {}
-
-  bool more()
-  {
-    while(myIterator.More())
-    {
-      if(myIterator.Value()->GetID()!=-1)
-        return true;
-      myIterator.Next();
-    }
-    return false;
-  }
-
-  const SMDS_MeshEdge* next()
-  {
-    const SMDS_MeshEdge* current = myIterator.Value();
-    myIterator.Next();
-    return current;
-  }
-};
 
 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
 {
-  return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges));
+  typedef MYElem_Map_Iterator
+    < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
+  return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 ///Return an iterator on faces of the current mesh.
 ///////////////////////////////////////////////////////////////////////////////
-class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator
-{
-  typedef SMDS_Mesh::SetOfFaces SetOfFaces;
-  SetOfFaces::Iterator myIterator;
- public:
-  SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):myIterator(s)
-  {}
-
-  bool more()
-  {
-    while(myIterator.More())
-    {
-      if(myIterator.Value()->GetID()!=-1)
-        return true;
-      myIterator.Next();
-    }
-    return false;
-  }
-
-  const SMDS_MeshFace* next()
-  {
-    const SMDS_MeshFace* current = myIterator.Value();
-    myIterator.Next();
-    return current;
-  }
-};
 
 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
 {
-  return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces));
+  typedef MYElem_Map_Iterator
+    < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
+  return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 ///Return an iterator on volumes of the current mesh.
 ///////////////////////////////////////////////////////////////////////////////
-class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator
-{
-  typedef SMDS_Mesh::SetOfVolumes SetOfVolumes;
-  SetOfVolumes::Iterator myIterator;
- public:
-  SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):myIterator(s)
-  {}
-
-  bool more()
-  {
-    return myIterator.More() != Standard_False;
-  }
-
-  const SMDS_MeshVolume* next()
-  {
-    const SMDS_MeshVolume* current = myIterator.Value();
-    myIterator.Next();
-    return current;
-  }
-};
 
 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
 {
-  return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes));
+  typedef MYElem_Map_Iterator
+    < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
+  return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return an iterator on elements of the current mesh factory
+///////////////////////////////////////////////////////////////////////////////
+SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
+{
+  switch (type) {
+  case SMDSAbs_All:
+    return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
+    break;
+  case SMDSAbs_Volume:
+    return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
+  case SMDSAbs_Face:
+    return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
+  case SMDSAbs_Edge:
+    return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
+  case SMDSAbs_0DElement:
+    return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
+  case SMDSAbs_Node:
+    return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
+    //return myNodeIDFactory->elementsIterator();
+  default:;
+  }
+  return myElementIDFactory->elementsIterator();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 /// Do intersection of sets (more than 2)
 ///////////////////////////////////////////////////////////////////////////////
 static set<const SMDS_MeshElement*> * intersectionOfSets(
-       set<const SMDS_MeshElement*> vs[], int numberOfSets)
+        set<const SMDS_MeshElement*> vs[], int numberOfSets)
 {
-       set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
-       set<const SMDS_MeshElement*>* rsetB;
+        set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
+        set<const SMDS_MeshElement*>* rsetB;
 
-       for(int i=0; i<numberOfSets-1; i++)
-       {
-               rsetB=new set<const SMDS_MeshElement*>();
-               set_intersection(
-                       rsetA->begin(), rsetA->end(),
-                       vs[i+1].begin(), vs[i+1].end(),
-                       inserter(*rsetB, rsetB->begin()));
-               delete rsetA;
-               rsetA=rsetB;
-       }
-       return rsetA;
+        for(int i=0; i<numberOfSets-1; i++)
+        {
+                rsetB=new set<const SMDS_MeshElement*>();
+                set_intersection(
+                        rsetA->begin(), rsetA->end(),
+                        vs[i+1].begin(), vs[i+1].end(),
+                        inserter(*rsetB, rsetB->begin()));
+                delete rsetA;
+                rsetA=rsetB;
+        }
+        return rsetA;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Return the list of finit elements owning the given element
+/// Return the list of finite elements owning the given element: elements
+/// containing all the nodes of the given element, for instance faces and
+/// volumes containing a given edge.
 ///////////////////////////////////////////////////////////////////////////////
 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
 {
-       int numberOfSets=element->NbNodes();
-       set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
+        int numberOfSets=element->NbNodes();
+        set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
 
-       SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
+        SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
+
+        int i=0;
+        while(itNodes->more())
+        {
+          const SMDS_MeshElement* node = itNodes->next();
+          MYASSERT(node);
+                const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
+                SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
 
-       int i=0;
-       while(itNodes->more())
-       {
-               const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
-               SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
+                //initSet[i]=set<const SMDS_MeshElement*>();
+                while(itFe->more())
+                {
+                  const SMDS_MeshElement* elem = itFe->next();
+                  MYASSERT(elem);
+                  initSet[i].insert(elem);
 
-               //initSet[i]=set<const SMDS_MeshElement*>();
-               while(itFe->more())
-                  initSet[i].insert(itFe->next());
+                }
 
-               i++;
-       }
-       set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
+                i++;
+        }
+        set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
+        MESSAGE("nb elems " << i << " intersection " << retSet->size());
         delete [] initSet;
-       return retSet;
+        return retSet;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 /// Return the list of nodes used only by the given elements
 ///////////////////////////////////////////////////////////////////////////////
 static set<const SMDS_MeshElement*> * getExclusiveNodes(
-       set<const SMDS_MeshElement*>& elements)
-{
-       set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
-       set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
-
-       while(itElements!=elements.end())
-       {
-               SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
-               itElements++;
-       
-               while(itNodes->more())
-               {
-                       const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
-                       SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
-                       set<const SMDS_MeshElement*> s;
-                       while(itFe->more())
+        set<const SMDS_MeshElement*>& elements)
+{
+        set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
+        set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
+
+        while(itElements!=elements.end())
+        {
+                SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
+                itElements++;
+
+                while(itNodes->more())
+                {
+                        const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
+                        SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
+                        set<const SMDS_MeshElement*> s;
+                        while(itFe->more())
                           s.insert(itFe->next());
-                       if(s==elements) toReturn->insert(n);
-               }
-       }
-       return toReturn;        
+                        if(s==elements) toReturn->insert(n);
+                }
+        }
+        return toReturn;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Find the children of an element that are made of given nodes 
+///Find the children of an element that are made of given nodes
 ///@param setOfChildren The set in which matching children will be inserted
 ///@param element The element were to search matching children
 ///@param nodes The nodes that the children must have to be selected
 ///////////////////////////////////////////////////////////////////////////////
-void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>&     setOfChildren, 
-       const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
-{
-       
-       switch(element->GetType())
-       {
-       case SMDSAbs_Node:
-               MESSAGE("Internal Error: This should not append");
-               break;
-       case SMDSAbs_Edge:
-       {
-               SMDS_ElemIteratorPtr itn=element->nodesIterator();
-               while(itn->more())
-               {
-                       const SMDS_MeshElement * e=itn->next();
-                       if(nodes.find(e)!=nodes.end())
+void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren,
+                                     const SMDS_MeshElement *      element,
+                                     set<const SMDS_MeshElement*>& nodes)
+{
+  switch(element->GetType())
+    {
+    case SMDSAbs_Node:
+      MESSAGE("Internal Error: This should not happend");
+      break;
+    case SMDSAbs_0DElement:
+      {
+      }
+      break;
+    case SMDSAbs_Edge:
+        {
+                SMDS_ElemIteratorPtr itn=element->nodesIterator();
+                while(itn->more())
+                {
+                        const SMDS_MeshElement * e=itn->next();
+                        if(nodes.find(e)!=nodes.end())
                         {
                           setOfChildren.insert(element);
                           break;
                         }
-               }
-       } break;
-       case SMDSAbs_Face:
-       {
-               SMDS_ElemIteratorPtr itn=element->nodesIterator();
-               while(itn->more())
-               {
-                       const SMDS_MeshElement * e=itn->next();
-                       if(nodes.find(e)!=nodes.end())
+                }
+        } break;
+    case SMDSAbs_Face:
+        {
+                SMDS_ElemIteratorPtr itn=element->nodesIterator();
+                while(itn->more())
+                {
+                        const SMDS_MeshElement * e=itn->next();
+                        if(nodes.find(e)!=nodes.end())
                         {
                           setOfChildren.insert(element);
                           break;
                         }
-               }
-               if(hasConstructionEdges())
-               {
-                       SMDS_ElemIteratorPtr ite=element->edgesIterator();
-                       while(ite->more())
-                               addChildrenWithNodes(setOfChildren, ite->next(), nodes);
-               }
-       } break;        
-       case SMDSAbs_Volume:
-       {
-               if(hasConstructionFaces())
-               {
-                       SMDS_ElemIteratorPtr ite=element->facesIterator();
-                       while(ite->more())
-                               addChildrenWithNodes(setOfChildren, ite->next(), nodes);
-               }
-               else if(hasConstructionEdges())
-               {
-                       SMDS_ElemIteratorPtr ite=element->edgesIterator();
-                       while(ite->more())
-                               addChildrenWithNodes(setOfChildren, ite->next(), nodes);
-               }
-       }
-       }
+                }
+                if(hasConstructionEdges())
+                {
+                        SMDS_ElemIteratorPtr ite=element->edgesIterator();
+                        while(ite->more())
+                                addChildrenWithNodes(setOfChildren, ite->next(), nodes);
+                }
+        } break;
+    case SMDSAbs_Volume:
+        {
+                if(hasConstructionFaces())
+                {
+                        SMDS_ElemIteratorPtr ite=element->facesIterator();
+                        while(ite->more())
+                                addChildrenWithNodes(setOfChildren, ite->next(), nodes);
+                }
+                else if(hasConstructionEdges())
+                {
+                        SMDS_ElemIteratorPtr ite=element->edgesIterator();
+                        while(ite->more())
+                                addChildrenWithNodes(setOfChildren, ite->next(), nodes);
+                }
+        }
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -2272,17 +2658,17 @@ void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>&      setOfChildren
 ///@param removenodes if true remaining nodes will be removed
 ///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
-       const bool removenodes)
+                              const bool removenodes)
 {
   list<const SMDS_MeshElement *> removedElems;
   list<const SMDS_MeshElement *> removedNodes;
   RemoveElement( elem, removedElems, removedNodes, removenodes );
 }
-  
+
 ///////////////////////////////////////////////////////////////////////////////
 ///@param elem The element to delete
-///@param removedElems contains all removed elements
-///@param removedNodes contains all removed nodes
+///@param removedElems to be filled with all removed elements
+///@param removedNodes to be filled with all removed nodes
 ///@param removenodes if true remaining nodes will be removed
 ///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
@@ -2290,10 +2676,12 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
                               list<const SMDS_MeshElement *>& removedNodes,
                               bool                            removenodes)
 {
+  MESSAGE("SMDS_Mesh::RemoveElement " << elem->GetID() << " " << removenodes);
   // get finite elements built on elem
   set<const SMDS_MeshElement*> * s1;
-  if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
-      !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face ||
+  if (elem->GetType() == SMDSAbs_0DElement ||
+      elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges() ||
+      elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() ||
       elem->GetType() == SMDSAbs_Volume)
   {
     s1 = new set<const SMDS_MeshElement*>();
@@ -2341,27 +2729,29 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
     switch((*it)->GetType())
     {
     case SMDSAbs_Node:
-      MESSAGE("Internal Error: This should not happen");
+      MYASSERT("Internal Error: This should not happen");
+      break;
+    case SMDSAbs_0DElement:
+      myCells[(*it)->GetID()] = 0;  // -PR- ici ou dans myElementIDFactory->ReleaseID ?
+      myInfo.remove(*it);
       break;
     case SMDSAbs_Edge:
-      myEdges.Remove(static_cast<SMDS_MeshEdge*>
-                    (const_cast<SMDS_MeshElement*>(*it)));
+      myCells[(*it)->GetID()] = 0;
       myInfo.RemoveEdge(*it);
       break;
     case SMDSAbs_Face:
-      myFaces.Remove(static_cast<SMDS_MeshFace*>
-                    (const_cast<SMDS_MeshElement*>(*it)));
+      myCells[(*it)->GetID()] = 0;
       myInfo.RemoveFace(*it);
       break;
     case SMDSAbs_Volume:
-      myVolumes.Remove(static_cast<SMDS_MeshVolume*>
-                      (const_cast<SMDS_MeshElement*>(*it)));
+      myCells[(*it)->GetID()] = 0;
       myInfo.RemoveVolume(*it);
       break;
     }
     //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
     removedElems.push_back( (*it) );
     myElementIDFactory->ReleaseID((*it)->GetID());
+    MYASSERT("problem delete elem")
     delete (*it);
     it++;
   }
@@ -2373,11 +2763,11 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
     while(it!=s2->end())
     {
       //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
-      myNodes.Remove(static_cast<SMDS_MeshNode*>
-                    (const_cast<SMDS_MeshElement*>(*it)));
+      myNodes[(*it)->GetID()] = 0;
       myInfo.myNbNodes--;
       myNodeIDFactory->ReleaseID((*it)->GetID());
       removedNodes.push_back( (*it) );
+      MYASSERT("problem delete node")
       delete *it;
       it++;
     }
@@ -2387,28 +2777,33 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
   delete s1;
 }
 
-  
+
 ///////////////////////////////////////////////////////////////////////////////
 ///@param elem The element to delete
 ///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
 {
+  int elemId = elem->GetID();
+  MESSAGE("SMDS_Mesh::RemoveFreeElement " << elemId);
   SMDSAbs_ElementType aType = elem->GetType();
+  SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
   if (aType == SMDSAbs_Node) {
     // only free node can be removed by this method
-    const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
+    const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
     SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
     if (!itFe->more()) { // free node
-      myNodes.Remove(const_cast<SMDS_MeshNode*>(n));
+      myNodes[elemId] = 0;
       myInfo.myNbNodes--;
-      myNodeIDFactory->ReleaseID(elem->GetID());
-      delete elem;
+      myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
+      myNodeIDFactory->ReleaseID(elemId);
     }
   } else {
     if (hasConstructionEdges() || hasConstructionFaces())
       // this methods is only for meshes without descendants
       return;
 
+    int vtkid = this->fromSmdsToVtk(elemId);
+
     // Remove element from <InverseElements> of its nodes
     SMDS_ElemIteratorPtr itn = elem->nodesIterator();
     while (itn->more()) {
@@ -2418,27 +2813,34 @@ void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
     }
 
     // in meshes without descendants elements are always free
-    switch (aType) {
+     switch (aType) {
+    case SMDSAbs_0DElement:
+      myCells[elemId] = 0;
+      myInfo.remove(elem);
+      delete elem;
+      break;
     case SMDSAbs_Edge:
-      myEdges.Remove(static_cast<SMDS_MeshEdge*>
-                     (const_cast<SMDS_MeshElement*>(elem)));
+      myCells[elemId] = 0;
       myInfo.RemoveEdge(elem);
+      myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
       break;
     case SMDSAbs_Face:
-      myFaces.Remove(static_cast<SMDS_MeshFace*>
-                     (const_cast<SMDS_MeshElement*>(elem)));
+      myCells[elemId] = 0;
       myInfo.RemoveFace(elem);
+      myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
       break;
     case SMDSAbs_Volume:
-      myVolumes.Remove(static_cast<SMDS_MeshVolume*>
-                       (const_cast<SMDS_MeshElement*>(elem)));
+      myCells[elemId] = 0;
       myInfo.RemoveVolume(elem);
+      myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
       break;
     default:
       break;
     }
-    myElementIDFactory->ReleaseID(elem->GetID());
-    delete elem;
+    myElementIDFactory->ReleaseID(elemId);
+
+    this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
+    // --- to do: keep vtkid in a list of reusable cells
   }
 }
 
@@ -2454,6 +2856,10 @@ bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
   while (itn->more())
     if (elem == itn->next())
       return true;
+  SMDS_0DElementIteratorPtr it0d = elements0dIterator();
+  while (it0d->more())
+    if (elem == it0d->next())
+      return true;
   SMDS_EdgeIteratorPtr ite = edgesIterator();
   while (ite->more())
     if (elem == ite->next())
@@ -2471,27 +2877,27 @@ bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
 
 //=======================================================================
 //function : MaxNodeID
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 int SMDS_Mesh::MaxNodeID() const
 {
-  return myNodeIDFactory->GetMaxID();
+  return myNodeMax;
 }
 
 //=======================================================================
 //function : MinNodeID
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 int SMDS_Mesh::MinNodeID() const
 {
-  return myNodeIDFactory->GetMinID();
+  return myNodeMin;
 }
 
 //=======================================================================
 //function : MaxElementID
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 int SMDS_Mesh::MaxElementID() const
@@ -2501,7 +2907,7 @@ int SMDS_Mesh::MaxElementID() const
 
 //=======================================================================
 //function : MinElementID
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 int SMDS_Mesh::MinElementID() const
@@ -2516,10 +2922,11 @@ int SMDS_Mesh::MinElementID() const
 
 void SMDS_Mesh::Renumber (const bool isNodes, const int  startID, const int  deltaID)
 {
+    MESSAGE("Renumber");
   if ( deltaID == 0 )
     return;
 
-  SMDS_MeshElementIDFactory * idFactory =
+  SMDS_MeshNodeIDFactory * idFactory =
     isNodes ? myNodeIDFactory : myElementIDFactory;
 
   // get existing elements in the order of ID increasing
@@ -2582,9 +2989,9 @@ SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem )
 
 //=======================================================================
 //function : AddEdgeWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
-SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID) 
+SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
 {
   return SMDS_Mesh::AddEdgeWithID
     ((SMDS_MeshNode*) myNodeIDFactory->MeshElement(n1),
@@ -2595,10 +3002,10 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
 
 //=======================================================================
 //function : AddEdge
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
-                                 const SMDS_MeshNode* n2,
+                                  const SMDS_MeshNode* n2,
                                   const SMDS_MeshNode* n12)
 {
   return SMDS_Mesh::AddEdgeWithID(n1, n2, n12, myElementIDFactory->GetFreeID());
@@ -2606,27 +3013,28 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
 
 //=======================================================================
 //function : AddEdgeWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
-                                       const SMDS_MeshNode * n2, 
-                                       const SMDS_MeshNode * n12, 
-                                       int ID)
+                                        const SMDS_MeshNode * n2,
+                                        const SMDS_MeshNode * n12,
+                                        int ID)
 {
   if ( !n1 || !n2 || !n12 ) return 0;
   SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
   if(myElementIDFactory->BindID(ID, edge)) {
     SMDS_MeshNode *node1,*node2, *node12;
-    node1 = const_cast<SMDS_MeshNode*>(n1);
-    node2 = const_cast<SMDS_MeshNode*>(n2);
-    node12 = const_cast<SMDS_MeshNode*>(n12);
-    node1->AddInverseElement(edge);
-    node2->AddInverseElement(edge);
-    node12->AddInverseElement(edge);
-    myEdges.Add(edge);
+    //node1 = const_cast<SMDS_MeshNode*>(n1);
+    //node2 = const_cast<SMDS_MeshNode*>(n2);
+    //node12 = const_cast<SMDS_MeshNode*>(n12);
+    //node1->AddInverseElement(edge); // --- fait avec BindID
+    //node2->AddInverseElement(edge);
+    //node12->AddInverseElement(edge);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = edge;
     myInfo.myNbQuadEdges++;
     return edge;
-  } 
+  }
   else {
     delete edge;
     return NULL;
@@ -2636,11 +3044,11 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddFace
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
-                                 const SMDS_MeshNode * n2,
-                                 const SMDS_MeshNode * n3,
+                                  const SMDS_MeshNode * n2,
+                                  const SMDS_MeshNode * n3,
                                   const SMDS_MeshNode * n12,
                                   const SMDS_MeshNode * n23,
                                   const SMDS_MeshNode * n31)
@@ -2651,7 +3059,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddFaceWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
                                         int n12,int n23,int n31, int ID)
@@ -2668,14 +3076,14 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
 
 //=======================================================================
 //function : AddFaceWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n2,
                                         const SMDS_MeshNode * n3,
                                         const SMDS_MeshNode * n12,
                                         const SMDS_MeshNode * n23,
-                                        const SMDS_MeshNode * n31, 
+                                        const SMDS_MeshNode * n31,
                                         int ID)
 {
   if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31) return 0;
@@ -2685,7 +3093,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
   }
   SMDS_QuadraticFaceOfNodes* face =
     new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
-  myFaces.Add(face);
+    adjustmyCellsCapacity(ID);
+  myCells[ID] = face;
   myInfo.myNbQuadTriangles++;
 
   if (!registerElement(ID, face)) {
@@ -2698,12 +3107,12 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddFace
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
-                                 const SMDS_MeshNode * n2,
-                                 const SMDS_MeshNode * n3,
-                                 const SMDS_MeshNode * n4,
+                                  const SMDS_MeshNode * n2,
+                                  const SMDS_MeshNode * n3,
+                                  const SMDS_MeshNode * n4,
                                   const SMDS_MeshNode * n12,
                                   const SMDS_MeshNode * n23,
                                   const SMDS_MeshNode * n34,
@@ -2715,7 +3124,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddFaceWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
                                         int n12,int n23,int n34,int n41, int ID)
@@ -2734,7 +3143,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
 
 //=======================================================================
 //function : AddFaceWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n2,
@@ -2742,8 +3151,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n4,
                                         const SMDS_MeshNode * n12,
                                         const SMDS_MeshNode * n23,
-                                        const SMDS_MeshNode * n34, 
-                                        const SMDS_MeshNode * n41, 
+                                        const SMDS_MeshNode * n34,
+                                        const SMDS_MeshNode * n41,
                                         int ID)
 {
   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
@@ -2752,7 +3161,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
   }
   SMDS_QuadraticFaceOfNodes* face =
     new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
-  myFaces.Add(face);
+    adjustmyCellsCapacity(ID);
+  myCells[ID] = face;
   myInfo.myNbQuadQuadrangles++;
 
   if (!registerElement(ID, face)) {
@@ -2765,16 +3175,16 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolume
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
-                                     const SMDS_MeshNode * n2, 
-                                     const SMDS_MeshNode * n3,
-                                     const SMDS_MeshNode * n4,
+                                      const SMDS_MeshNode * n2,
+                                      const SMDS_MeshNode * n3,
+                                      const SMDS_MeshNode * n4,
                                       const SMDS_MeshNode * n12,
                                       const SMDS_MeshNode * n23,
                                       const SMDS_MeshNode * n31,
-                                      const SMDS_MeshNode * n14, 
+                                      const SMDS_MeshNode * n14,
                                       const SMDS_MeshNode * n24,
                                       const SMDS_MeshNode * n34)
 {
@@ -2787,7 +3197,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolumeWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
                                             int n12,int n23,int n31,
@@ -2818,7 +3228,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n12,
                                             const SMDS_MeshNode * n23,
                                             const SMDS_MeshNode * n31,
-                                            const SMDS_MeshNode * n14, 
+                                            const SMDS_MeshNode * n14,
                                             const SMDS_MeshNode * n24,
                                             const SMDS_MeshNode * n34,
                                             int ID)
@@ -2831,7 +3241,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
   }
   SMDS_QuadraticVolumeOfNodes * volume =
     new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
-  myVolumes.Add(volume);
+    adjustmyCellsCapacity(ID);
+  myCells[ID] = volume;
   myInfo.myNbQuadTetras++;
 
   if (!registerElement(ID, volume)) {
@@ -2844,18 +3255,18 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolume
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
-                                     const SMDS_MeshNode * n2, 
-                                     const SMDS_MeshNode * n3,
-                                     const SMDS_MeshNode * n4,
-                                      const SMDS_MeshNode * n5, 
+                                      const SMDS_MeshNode * n2,
+                                      const SMDS_MeshNode * n3,
+                                      const SMDS_MeshNode * n4,
+                                      const SMDS_MeshNode * n5,
                                       const SMDS_MeshNode * n12,
                                       const SMDS_MeshNode * n23,
                                       const SMDS_MeshNode * n34,
                                       const SMDS_MeshNode * n41,
-                                      const SMDS_MeshNode * n15, 
+                                      const SMDS_MeshNode * n15,
                                       const SMDS_MeshNode * n25,
                                       const SMDS_MeshNode * n35,
                                       const SMDS_MeshNode * n45)
@@ -2870,7 +3281,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolumeWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
                                             int n12,int n23,int n34,int n41,
@@ -2901,12 +3312,12 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n2,
                                             const SMDS_MeshNode * n3,
                                             const SMDS_MeshNode * n4,
-                                            const SMDS_MeshNode * n5, 
+                                            const SMDS_MeshNode * n5,
                                             const SMDS_MeshNode * n12,
                                             const SMDS_MeshNode * n23,
                                             const SMDS_MeshNode * n34,
                                             const SMDS_MeshNode * n41,
-                                            const SMDS_MeshNode * n15, 
+                                            const SMDS_MeshNode * n15,
                                             const SMDS_MeshNode * n25,
                                             const SMDS_MeshNode * n35,
                                             const SMDS_MeshNode * n45,
@@ -2922,7 +3333,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
   SMDS_QuadraticVolumeOfNodes * volume =
     new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
                                     n34,n41,n15,n25,n35,n45);
-  myVolumes.Add(volume);
+    adjustmyCellsCapacity(ID);
+  myCells[ID] = volume;
   myInfo.myNbQuadPyramids++;
 
   if (!registerElement(ID, volume)) {
@@ -2935,20 +3347,20 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolume
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
-                                     const SMDS_MeshNode * n2, 
-                                     const SMDS_MeshNode * n3,
-                                     const SMDS_MeshNode * n4,
-                                      const SMDS_MeshNode * n5, 
-                                      const SMDS_MeshNode * n6, 
+                                      const SMDS_MeshNode * n2,
+                                      const SMDS_MeshNode * n3,
+                                      const SMDS_MeshNode * n4,
+                                      const SMDS_MeshNode * n5,
+                                      const SMDS_MeshNode * n6,
                                       const SMDS_MeshNode * n12,
                                       const SMDS_MeshNode * n23,
-                                      const SMDS_MeshNode * n31, 
+                                      const SMDS_MeshNode * n31,
                                       const SMDS_MeshNode * n45,
                                       const SMDS_MeshNode * n56,
-                                      const SMDS_MeshNode * n64, 
+                                      const SMDS_MeshNode * n64,
                                       const SMDS_MeshNode * n14,
                                       const SMDS_MeshNode * n25,
                                       const SMDS_MeshNode * n36)
@@ -2963,7 +3375,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolumeWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
                                             int n4, int n5, int n6,
@@ -2998,14 +3410,14 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n2,
                                             const SMDS_MeshNode * n3,
                                             const SMDS_MeshNode * n4,
-                                            const SMDS_MeshNode * n5, 
-                                            const SMDS_MeshNode * n6, 
+                                            const SMDS_MeshNode * n5,
+                                            const SMDS_MeshNode * n6,
                                             const SMDS_MeshNode * n12,
                                             const SMDS_MeshNode * n23,
-                                            const SMDS_MeshNode * n31, 
+                                            const SMDS_MeshNode * n31,
                                             const SMDS_MeshNode * n45,
                                             const SMDS_MeshNode * n56,
-                                            const SMDS_MeshNode * n64, 
+                                            const SMDS_MeshNode * n64,
                                             const SMDS_MeshNode * n14,
                                             const SMDS_MeshNode * n25,
                                             const SMDS_MeshNode * n36,
@@ -3021,7 +3433,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
   SMDS_QuadraticVolumeOfNodes * volume =
     new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
                                     n45,n56,n64,n14,n25,n36);
-  myVolumes.Add(volume);
+    adjustmyCellsCapacity(ID);
+  myCells[ID] = volume;
   myInfo.myNbQuadPrisms++;
 
   if (!registerElement(ID, volume)) {
@@ -3034,24 +3447,24 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolume
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
-                                     const SMDS_MeshNode * n2, 
-                                     const SMDS_MeshNode * n3,
-                                     const SMDS_MeshNode * n4,
-                                      const SMDS_MeshNode * n5, 
-                                      const SMDS_MeshNode * n6, 
+                                      const SMDS_MeshNode * n2,
+                                      const SMDS_MeshNode * n3,
+                                      const SMDS_MeshNode * n4,
+                                      const SMDS_MeshNode * n5,
+                                      const SMDS_MeshNode * n6,
                                       const SMDS_MeshNode * n7,
-                                      const SMDS_MeshNode * n8, 
+                                      const SMDS_MeshNode * n8,
                                       const SMDS_MeshNode * n12,
                                       const SMDS_MeshNode * n23,
                                       const SMDS_MeshNode * n34,
-                                      const SMDS_MeshNode * n41, 
+                                      const SMDS_MeshNode * n41,
                                       const SMDS_MeshNode * n56,
                                       const SMDS_MeshNode * n67,
                                       const SMDS_MeshNode * n78,
-                                      const SMDS_MeshNode * n85, 
+                                      const SMDS_MeshNode * n85,
                                       const SMDS_MeshNode * n15,
                                       const SMDS_MeshNode * n26,
                                       const SMDS_MeshNode * n37,
@@ -3067,7 +3480,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 
 //=======================================================================
 //function : AddVolumeWithID
-//purpose  : 
+//purpose  :
 //=======================================================================
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
                                             int n5, int n6, int n7, int n8,
@@ -3107,18 +3520,18 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n2,
                                             const SMDS_MeshNode * n3,
                                             const SMDS_MeshNode * n4,
-                                            const SMDS_MeshNode * n5, 
-                                            const SMDS_MeshNode * n6, 
+                                            const SMDS_MeshNode * n5,
+                                            const SMDS_MeshNode * n6,
                                             const SMDS_MeshNode * n7,
-                                            const SMDS_MeshNode * n8, 
+                                            const SMDS_MeshNode * n8,
                                             const SMDS_MeshNode * n12,
                                             const SMDS_MeshNode * n23,
                                             const SMDS_MeshNode * n34,
-                                            const SMDS_MeshNode * n41, 
+                                            const SMDS_MeshNode * n41,
                                             const SMDS_MeshNode * n56,
                                             const SMDS_MeshNode * n67,
                                             const SMDS_MeshNode * n78,
-                                            const SMDS_MeshNode * n85, 
+                                            const SMDS_MeshNode * n85,
                                             const SMDS_MeshNode * n15,
                                             const SMDS_MeshNode * n26,
                                             const SMDS_MeshNode * n37,
@@ -3135,7 +3548,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
   SMDS_QuadraticVolumeOfNodes * volume =
     new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
                                     n56,n67,n78,n85,n15,n26,n37,n48);
-  myVolumes.Add(volume);
+    adjustmyCellsCapacity(ID);
+  myCells[ID] = volume;
   myInfo.myNbQuadHexas++;
 
   if (!registerElement(ID, volume)) {
@@ -3144,3 +3558,39 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
   }
   return volume;
 }
+
+void SMDS_Mesh::updateNodeMinMax()
+{
+  myNodeMin = 0;
+  while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
+    myNodeMin++;
+  myNodeMax=myNodes.size()-1;
+  while (!myNodes[myNodeMax] && (myNodeMin>=0))
+    myNodeMin--;
+}
+
+void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
+{
+  int val = myIDElements.size();
+  MESSAGE(" ------------------- resize myIDElements " << val << " --> " << val + nbNodes);
+  myIDElements.resize(val + nbNodes, -1); // fill new elements with -1
+  val = myNodes.size();
+  MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
+  myNodes.resize(val +nbNodes, 0);
+}
+
+void SMDS_Mesh::incrementCellsCapacity(int nbCells)
+{
+  int val = myVtkIndex.size();
+  MESSAGE(" ------------------- resize myVtkIndex " << val << " --> " << val + nbCells);
+  myVtkIndex.resize(val + nbCells, -1); // fill new elements with -1
+  val = myCells.size();
+  MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
+  myNodes.resize(val +nbCells, 0);
+}
+
+void SMDS_Mesh::adjustStructure()
+{
+  myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID()+1);
+}
+