]> SALOME platform Git repositories - modules/smesh.git/blobdiff - src/SMDS/SMDS_Mesh.cxx
Salome HOME
PR: adjust points number
[modules/smesh.git] / src / SMDS / SMDS_Mesh.cxx
index 693fd38fd1ba6b49005e98998d067654873a7615..1fbe8d3242dfeed12b3baa2fd118fe8fd394c99e 100644 (file)
 #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>
@@ -47,11 +49,12 @@ 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 = 1000;
+int SMDS_Mesh::chunkSize = 1024;
+
 
 //================================================================================
 /*!
@@ -113,15 +116,29 @@ SMDS_Mesh::SMDS_Mesh()
          myElementIDFactory(new SMDS_MeshElementIDFactory()),
          myHasConstructionEdges(false), myHasConstructionFaces(false),
          myHasInverseElements(true),
-         myNodeMin(0), myNodeMax(0), myCellLinksSize(0)
+         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();
@@ -139,9 +156,13 @@ SMDS_Mesh::SMDS_Mesh()
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
         :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
-        myElementIDFactory(parent->myElementIDFactory),
-        myHasConstructionEdges(false), myHasConstructionFaces(false),
-        myHasInverseElements(true)
+         myElementIDFactory(parent->myElementIDFactory),
+         myHasConstructionEdges(false), myHasConstructionFaces(false),
+         myHasInverseElements(true),
+         myNodePool(parent->myNodePool),
+         myEdgePool(parent->myEdgePool),
+         myFacePool(parent->myFacePool),
+         myVolumePool(parent->myVolumePool)
 {
 }
 
@@ -178,7 +199,9 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
   const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
   if(!node){
     //if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-    SMDS_MeshNode * node=new SMDS_MeshNode(ID, myMeshId, -1, x, y, z);
+    //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);
@@ -277,10 +300,17 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
                                         int ID)
 {
   if ( !n1 || !n2 ) return 0;
+  SMDS_MeshEdge * edge = 0;
+
+  // --- retreive nodes ID
+  vector<vtkIdType> nodeIds;
+  nodeIds.clear();
+  nodeIds.push_back(n1->getId());
+  nodeIds.push_back(n2->getId());
 
-  //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-  //MESSAGE("AddEdgeWithID " << ID)
-  SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
+  SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
+  edgevtk->init(nodeIds, this);
+  edge = edgevtk;
   adjustmyCellsCapacity(ID);
   myCells[ID] = edge;
   myInfo.myNbEdges++;
@@ -328,7 +358,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         int ID)
 {
     //MESSAGE("AddFaceWithID " << ID)
-  SMDS_MeshFace * face=createTriangle(n1, n2, n3);
+  SMDS_MeshFace * face=createTriangle(n1, n2, n3, myElementIDFactory->GetFreeID());
 
   if (face && !registerElement(ID, face)) {
     RemoveElement(face, false);
@@ -547,7 +577,17 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
+    // --- 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++;
@@ -638,7 +678,18 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
+    // --- 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++;
@@ -734,7 +785,19 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
+    // --- 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++;
@@ -842,13 +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);
+    // --- 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;
@@ -1130,14 +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)
 {
-    //MESSAGE("registerElement " << ID)
-  if (myElementIDFactory->BindID(ID, element)) {
-    return true;
+  //MESSAGE("registerElement " << ID)
+  if ((ID < myIDElements.size()) && myIDElements[ID] >= 0) // --- already bound
+  {
+    MESSAGE(" --------------------------------- already bound "<< ID << " " << myIDElements[ID]);
+    return false;
   }
-  MESSAGE("BindID " << ID << " 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;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1145,18 +1249,22 @@ bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
 ///////////////////////////////////////////////////////////////////////////////
 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
 {
-  if (ID <0 || ID >= myNodes.size())
-    return NULL;
+  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();
@@ -1167,7 +1275,7 @@ 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
+    //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
     SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
     adjustmyCellsCapacity(ID);
     myCells[ID] = face;
@@ -1176,8 +1284,17 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
   }
   else
   {
-    int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
-    SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
+    // --- 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++;
@@ -1214,8 +1331,18 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
   }
   else
   {
-      //MESSAGE("createQuadrangle " << ID);
-    SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
+    // --- 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++;
@@ -1316,6 +1443,7 @@ 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();
@@ -1337,7 +1465,7 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
   }
   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 ) {
@@ -1551,7 +1679,14 @@ SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
     //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
     int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
     adjustmyCellsCapacity(ID);
-    toReturn=new SMDS_MeshEdge(node1,node2);
+    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++;
   }
@@ -1649,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;
 }
@@ -1833,7 +1969,10 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
 {
   if ((IDelem < 0) || IDelem >= myCells.size())
-      return 0;
+  {
+    MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
+    return 0;
+  }
   return myCells[IDelem];
 }
 
@@ -2382,7 +2521,9 @@ static set<const SMDS_MeshElement*> * intersectionOfSets(
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// 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)
 {
@@ -2394,16 +2535,24 @@ static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement *
         int i=0;
         while(itNodes->more())
         {
-                const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
+          const SMDS_MeshElement* node = itNodes->next();
+          MYASSERT(node);
+                const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
                 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
 
                 //initSet[i]=set<const SMDS_MeshElement*>();
                 while(itFe->more())
-                  initSet[i].insert(itFe->next());
+                {
+                  const SMDS_MeshElement* elem = itFe->next();
+                  MYASSERT(elem);
+                  initSet[i].insert(elem);
+
+                }
 
                 i++;
         }
         set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
+        MESSAGE("nb elems " << i << " intersection " << retSet->size());
         delete [] initSet;
         return retSet;
 }
@@ -2518,8 +2667,8 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
 
 ///////////////////////////////////////////////////////////////////////////////
 ///@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,
@@ -2527,6 +2676,7 @@ 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 (elem->GetType() == SMDSAbs_0DElement ||
@@ -2579,7 +2729,7 @@ 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 ?
@@ -2601,6 +2751,7 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
     //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
     removedElems.push_back( (*it) );
     myElementIDFactory->ReleaseID((*it)->GetID());
+    MYASSERT("problem delete elem")
     delete (*it);
     it++;
   }
@@ -2616,6 +2767,7 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
       myInfo.myNbNodes--;
       myNodeIDFactory->ReleaseID((*it)->GetID());
       removedNodes.push_back( (*it) );
+      MYASSERT("problem delete node")
       delete *it;
       it++;
     }
@@ -2631,22 +2783,27 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
 ///////////////////////////////////////////////////////////////////////////////
 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[elem->GetID()] = 0;
+      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()) {
@@ -2656,28 +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[elem->GetID()] = 0;
+      myCells[elemId] = 0;
       myInfo.remove(elem);
+      delete elem;
       break;
     case SMDSAbs_Edge:
-      myCells[elem->GetID()] = 0;
+      myCells[elemId] = 0;
       myInfo.RemoveEdge(elem);
+      myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
       break;
     case SMDSAbs_Face:
-      myCells[elem->GetID()] = 0;
+      myCells[elemId] = 0;
       myInfo.RemoveFace(elem);
+      myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
       break;
     case SMDSAbs_Volume:
-      myCells[elem->GetID()] = 0;
+      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
   }
 }
 
@@ -3405,3 +3568,29 @@ void SMDS_Mesh::updateNodeMinMax()
   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);
+}
+