Salome HOME
[bos #40653][CEA] New mesh import export formats with meshio.
[modules/smesh.git] / src / SMDS / SMDS_Mesh.cxx
index 1d7ba140b7005d9644b21af7cd56d99a6eac3bb0..c948100ac26ad48d0cbe096191c2fc31646fa557 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -47,7 +47,8 @@
 #include <iostream>
 #include <fstream>
 
-#include <boost/make_shared.hpp>
+//#include <boost/make_shared.hpp>
+#include <boost/container/flat_set.hpp>
 
 #if !defined WIN32 && !defined __APPLE__
 #include <sys/sysinfo.h>
@@ -63,12 +64,12 @@ int SMDS_Mesh::chunkSize = 1024;
 //================================================================================
 /*!
  * \brief Raise an exception if free memory (ram+swap) too low
- * \param doNotRaise - if true, suppres exception, just return free memory size
+ * \param doNotRaise - if true, suppress exception, just return free memory size
  * \retval int - amount of available memory in MB or negative number in failure case
  */
 //================================================================================
 
-int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
+int SMDS_Mesh::CheckMemory(const bool doNotRaise)
 {
   return -1;
 #if !defined WIN32 && !defined __APPLE__
@@ -183,7 +184,7 @@ SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
 ///@param ID : The ID of the MeshNode to create
 ///@return : The created node or NULL if a node with this ID already exists
 ///////////////////////////////////////////////////////////////////////////////
-SMDS_MeshNode * SMDS_Mesh::AddNodeWithID( double x, double y, double z, int ID )
+SMDS_MeshNode * SMDS_Mesh::AddNodeWithID( double x, double y, double z, smIdType ID )
 {
   // find the MeshNode corresponding to ID
   SMDS_MeshNode *node = myNodeFactory->NewNode( ID );
@@ -201,7 +202,7 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID( double x, double y, double z, int ID )
 /// create a Mesh0DElement and add it to the current Mesh
 /// @return : The created Mesh0DElement
 ///////////////////////////////////////////////////////////////////////////////
-SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
+SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(smIdType idnode, smIdType ID)
 {
   const SMDS_MeshNode * node = myNodeFactory->FindNode(idnode);
   if (!node) return NULL;
@@ -224,7 +225,7 @@ SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
 /// @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)
+SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, smIdType ID)
 {
   if (!n) return 0;
 
@@ -244,7 +245,7 @@ SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int I
 /// create a Ball and add it to the current Mesh
 /// @return : The created Ball
 ///////////////////////////////////////////////////////////////////////////////
-SMDS_BallElement* SMDS_Mesh::AddBallWithID( int idnode, double diameter, int ID )
+SMDS_BallElement* SMDS_Mesh::AddBallWithID( smIdType idnode, double diameter, smIdType ID )
 {
   const SMDS_MeshNode * node = myNodeFactory->FindNode( idnode );
   if (!node) return NULL;
@@ -268,7 +269,7 @@ SMDS_BallElement* SMDS_Mesh::AddBall(const SMDS_MeshNode * node, double diameter
 /// @return The created 0D element or NULL if an element with this
 ///         ID already exists or if input node is not found.
 ///////////////////////////////////////////////////////////////////////////////
-SMDS_BallElement* SMDS_Mesh::AddBallWithID(const SMDS_MeshNode * n, double diameter, int ID)
+SMDS_BallElement* SMDS_Mesh::AddBallWithID(const SMDS_MeshNode * n, double diameter, smIdType ID)
 {
   if (!n) return 0;
 
@@ -288,7 +289,7 @@ SMDS_BallElement* SMDS_Mesh::AddBallWithID(const SMDS_MeshNode * n, double diame
 /// @return : The created MeshEdge
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID)
+SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(smIdType idnode1, smIdType idnode2, smIdType ID)
 {
   const SMDS_MeshNode * node1 = myNodeFactory->FindNode(idnode1);
   const SMDS_MeshNode * node2 = myNodeFactory->FindNode(idnode2);
@@ -318,7 +319,7 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
 
 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n2,
-                                        int                   ID)
+                                        smIdType              ID)
 {
   if ( !n1 || !n2 ) return 0;
 
@@ -347,7 +348,10 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
 /// Add a triangle defined by its nodes IDs
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType idnode1,
+                                        smIdType idnode2,
+                                        smIdType idnode3,
+                                        smIdType ID)
 {
   const SMDS_MeshNode * node1 = myNodeFactory->FindNode(idnode1);
   const SMDS_MeshNode * node2 = myNodeFactory->FindNode(idnode2);
@@ -363,7 +367,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, i
 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n2,
                                         const SMDS_MeshNode * n3,
-                                        int ID)
+                                        smIdType ID)
 {
   if ( !n1 || !n2 || !n3 ) return 0;
   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
@@ -394,11 +398,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(smIdType idnode1,
+                                        smIdType idnode2,
+                                        smIdType idnode3,
+                                        smIdType idnode4,
+                                        smIdType ID)
 {
   const SMDS_MeshNode *node1, *node2, *node3, *node4;
   node1 = myNodeFactory->FindNode(idnode1);
@@ -417,7 +421,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n2,
                                         const SMDS_MeshNode * n3,
                                         const SMDS_MeshNode * n4,
-                                        int ID)
+                                        smIdType ID)
 {
   if ( !n1 || !n2 || !n3 || !n4 ) return 0;
   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
@@ -451,11 +455,11 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 ///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(smIdType idnode1,
+                                             smIdType idnode2,
+                                             smIdType idnode3,
+                                             smIdType idnode4,
+                                             smIdType ID)
 {
   const SMDS_MeshNode *node1, *node2, *node3, *node4;
   node1 = myNodeFactory->FindNode(idnode1);
@@ -476,7 +480,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n2,
                                             const SMDS_MeshNode * n3,
                                             const SMDS_MeshNode * n4,
-                                            int ID)
+                                            smIdType ID)
 {
   if ( !n1 || !n2 || !n3 || !n4 ) return 0;
   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
@@ -513,12 +517,12 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 ///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(smIdType idnode1,
+                                             smIdType idnode2,
+                                             smIdType idnode3,
+                                             smIdType idnode4,
+                                             smIdType idnode5,
+                                             smIdType ID)
 {
   const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
   node1 = myNodeFactory->FindNode(idnode1);
@@ -542,7 +546,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n3,
                                             const SMDS_MeshNode * n4,
                                             const SMDS_MeshNode * n5,
-                                            int ID)
+                                            smIdType ID)
 {
   if ( !n1 || !n2 || !n3 || !n4 || !n5 ) return 0;
   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
@@ -569,7 +573,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
                                       const SMDS_MeshNode * n5,
                                       const SMDS_MeshNode * n6)
 {
-  int ID = myCellFactory->GetFreeID();
+  smIdType ID = myCellFactory->GetFreeID();
   return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
 }
 
@@ -581,13 +585,13 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 ///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(smIdType idnode1,
+                                             smIdType idnode2,
+                                             smIdType idnode3,
+                                             smIdType idnode4,
+                                             smIdType idnode5,
+                                             smIdType idnode6,
+                                             smIdType ID)
 {
   const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
   node1 = myNodeFactory->FindNode(idnode1);
@@ -612,7 +616,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n4,
                                             const SMDS_MeshNode * n5,
                                             const SMDS_MeshNode * n6,
-                                            int ID)
+                                            smIdType ID)
 {
   if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 ) return 0;
   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
@@ -656,19 +660,19 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 ///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 idnode9,
-                                             int idnode10,
-                                             int idnode11,
-                                             int idnode12,
-                                             int ID)
+SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(smIdType idnode1,
+                                             smIdType idnode2,
+                                             smIdType idnode3,
+                                             smIdType idnode4,
+                                             smIdType idnode5,
+                                             smIdType idnode6,
+                                             smIdType idnode7,
+                                             smIdType idnode8,
+                                             smIdType idnode9,
+                                             smIdType idnode10,
+                                             smIdType idnode11,
+                                             smIdType idnode12,
+                                             smIdType ID)
 {
   const SMDS_MeshNode *node1 = myNodeFactory->FindNode(idnode1);
   const SMDS_MeshNode *node2 = myNodeFactory->FindNode(idnode2);
@@ -705,7 +709,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n10,
                                             const SMDS_MeshNode * n11,
                                             const SMDS_MeshNode * n12,
-                                            int ID)
+                                            smIdType ID)
 {
   SMDS_MeshVolume* volume = 0;
   if(!n1 || !n2 || !n3 || !n4 || !n5 || !n6 ||
@@ -738,7 +742,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
                                       const SMDS_MeshNode * n7,
                                       const SMDS_MeshNode * n8)
 {
-  int ID = myCellFactory->GetFreeID();
+  smIdType ID = myCellFactory->GetFreeID();
   return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
 }
 
@@ -750,15 +754,15 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 ///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(smIdType idnode1,
+                                             smIdType idnode2,
+                                             smIdType idnode3,
+                                             smIdType idnode4,
+                                             smIdType idnode5,
+                                             smIdType idnode6,
+                                             smIdType idnode7,
+                                             smIdType idnode8,
+                                             smIdType ID)
 {
   const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
   node1 = myNodeFactory->FindNode(idnode1);
@@ -789,7 +793,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n6,
                                             const SMDS_MeshNode * n7,
                                             const SMDS_MeshNode * n8,
-                                            int ID)
+                                            smIdType ID)
 {
   SMDS_MeshVolume* volume = 0;
   if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
@@ -809,12 +813,12 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
 /// Add a polygon defined by its nodes IDs
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const std::vector<int> & nodes_ids,
-                                                  const int               ID)
+SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const std::vector<smIdType> & nodes_ids,
+                                                  const smIdType               ID)
 {
-  int nbNodes = nodes_ids.size();
+  size_t nbNodes = nodes_ids.size();
   std::vector<const SMDS_MeshNode*> nodes (nbNodes);
-  for (int i = 0; i < nbNodes; i++) {
+  for ( size_t i = 0; i < nbNodes; i++) {
     nodes[i] = myNodeFactory->FindNode( nodes_ids[i] );
     if (!nodes[i]) return NULL;
   }
@@ -827,10 +831,12 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const std::vector<int> & nodes
 
 SMDS_MeshFace*
 SMDS_Mesh::AddPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*> & nodes,
-                                   const int                                 ID)
+                                   const smIdType                                 ID)
 {
   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
 
+  if ( nodes.empty() )
+    throw std::invalid_argument("Polygon without nodes is forbidden");
   if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
   {
     cell->init( SMDSEntity_Polygon, nodes );
@@ -854,8 +860,8 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const std::vector<const SMDS_MeshNod
 /// Add a quadratic polygon defined by its nodes IDs
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<int> & nodes_ids,
-                                                      const int                ID)
+SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<smIdType> & nodes_ids,
+                                                      const smIdType                ID)
 {
   std::vector<const SMDS_MeshNode*> nodes( nodes_ids.size() );
   for ( size_t i = 0; i < nodes.size(); i++) {
@@ -871,9 +877,11 @@ SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<int> & n
 
 SMDS_MeshFace*
 SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*> & nodes,
-                                       const int                                 ID)
+                                       const smIdType                                 ID)
 {
   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  if ( nodes.empty() )
+    throw std::invalid_argument("Polygon without nodes is forbidden");
   if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
   {
     cell->init( SMDSEntity_Quad_Polygon, nodes );
@@ -900,13 +908,13 @@ SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFace (const std::vector<const SMDS_Mes
 /// or if input nodes are not found.
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID (const std::vector<int> & nodes_ids,
-                                                        const std::vector<int> & quantities,
-                                                        const int                ID)
+SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID (const std::vector<smIdType> & nodes_ids,
+                                                        const std::vector<int>      & quantities,
+                                                        const smIdType                ID)
 {
-  int nbNodes = nodes_ids.size();
+  size_t nbNodes = nodes_ids.size();
   std::vector<const SMDS_MeshNode*> nodes (nbNodes);
-  for (int i = 0; i < nbNodes; i++) {
+  for ( size_t i = 0; i < nbNodes; i++) {
     nodes[i] = myNodeFactory->FindNode(nodes_ids[i]);
     if (!nodes[i]) return NULL;
   }
@@ -922,7 +930,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID (const std::vector<int> &
 SMDS_MeshVolume*
 SMDS_Mesh::AddPolyhedralVolumeWithID (const std::vector<const SMDS_MeshNode*>& nodes,
                                       const std::vector<int>                 & quantities,
-                                      const int                           ID)
+                                      const smIdType                           ID)
 {
   if ( nodes.empty() || quantities.empty() )
     return NULL;
@@ -947,7 +955,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
 (const std::vector<const SMDS_MeshNode*> & nodes,
  const std::vector<int>                  & quantities)
 {
-  int ID = myCellFactory->GetFreeID();
+  smIdType ID = myCellFactory->GetFreeID();
   return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
 }
 
@@ -983,7 +991,7 @@ void SMDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
 ///////////////////////////////////////////////////////////////////////////////
 /// Return the node whose SMDS ID is 'ID'.
 ///////////////////////////////////////////////////////////////////////////////
-const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
+const SMDS_MeshNode * SMDS_Mesh::FindNode(smIdType ID) const
 {
   return myNodeFactory->FindNode( ID );
 }
@@ -991,12 +999,12 @@ const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
 ///////////////////////////////////////////////////////////////////////////////
 /// Return the node whose VTK ID is 'vtkId'.
 ///////////////////////////////////////////////////////////////////////////////
-const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const
+const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(vtkIdType vtkId) const
 {
   return myNodeFactory->FindNode( vtkId + 1 );
 }
 
-const SMDS_MeshElement * SMDS_Mesh::FindElementVtk(int IDelem) const
+const SMDS_MeshElement * SMDS_Mesh::FindElementVtk(vtkIdType IDelem) const
 {
   return myCellFactory->FindElement( FromVtkToSmds( IDelem ));
 }
@@ -1044,6 +1052,62 @@ bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
   return found;
 }
 
+//=======================================================================
+//function : SetAllNodesNotMarked
+//purpose  : Clear marked flag of all nodes
+//=======================================================================
+
+void SMDS_Mesh::SetAllNodesNotMarked()
+{
+  myNodeFactory->SetAllNotMarked();
+}
+
+//=======================================================================
+//function : SetAllCellsNotMarked
+//purpose  : Clear marked flag of all cells
+//=======================================================================
+
+void SMDS_Mesh::SetAllCellsNotMarked()
+{
+  myCellFactory->SetAllNotMarked();
+}
+
+//=======================================================================
+//function : ChangePolyhedronNodes
+//purpose  :
+//=======================================================================
+
+bool SMDS_Mesh::ChangePolyhedronNodes(const SMDS_MeshElement *                 element,
+                                      const std::vector<const SMDS_MeshNode*>& nodes,
+                                      const std::vector<int>&                  quantities)
+{
+  // keep current nodes of element
+  std::set<const SMDS_MeshNode*> oldNodes( element->begin_nodes(), element->end_nodes() );
+
+  bool Ok = false;
+
+  // change vtkUnstructuredGrid::Faces
+  if ( const SMDS_MeshVolume* vol = DownCast<SMDS_MeshVolume>( element ))
+    Ok = vol->ChangeNodes( nodes, quantities );
+
+  // change vtkUnstructuredGrid::Connectivity and inverse connectivity
+  if ( Ok )
+    if ( SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element))
+    {
+      boost::container::flat_set< const SMDS_MeshNode* > uniqueNodes( nodes.begin(), nodes.end() );
+      const SMDS_MeshNode** nodesPtr = &( *uniqueNodes.begin());
+      const int              nbNodes = (int) uniqueNodes.size();
+      Ok = cell->ChangeNodes( nodesPtr, nbNodes );
+      if ( Ok )
+      {
+        updateInverseElements( element, nodesPtr, nbNodes, oldNodes );
+        setMyModified();
+      }
+    }
+
+  return Ok;
+}
+
 //=======================================================================
 //function : ChangeElementNodes
 //purpose  :
@@ -1062,14 +1126,30 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
     Ok = cell->ChangeNodes(nodes, nbnodes);
 
   if ( Ok )
+  {
     setMyModified();
+    updateInverseElements( element, nodes, nbnodes, oldNodes );
+  }
+  return Ok;
+}
 
-  if ( Ok && GetGrid()->HasLinks() ) // update InverseElements
+//=======================================================================
+//function : updateInverseElements
+//purpose  : update InverseElements when element changes node
+//=======================================================================
+
+void SMDS_Mesh::updateInverseElements( const SMDS_MeshElement *        element,
+                                       const SMDS_MeshNode* const*     nodes,
+                                       const int                       nbnodes,
+                                       std::set<const SMDS_MeshNode*>& oldNodes )
+{
+  if ( GetGrid()->HasLinks() ) // update InverseElements
   {
     std::set<const SMDS_MeshNode*>::iterator it;
 
     // AddInverseElement to new nodes
-    for ( int i = 0; i < nbnodes; i++ ) {
+    for ( int i = 0; i < nbnodes; i++ )
+    {
       it = oldNodes.find( nodes[i] );
       if ( it == oldNodes.end() )
         // new node
@@ -1086,7 +1166,6 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
     }
   }
 
-  return Ok;
 }
 
 const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
@@ -1312,7 +1391,7 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
 //purpose  :
 //=======================================================================
 
-const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
+const SMDS_MeshElement* SMDS_Mesh::FindElement(smIdType IDelem) const
 {
   return myCellFactory->FindElement( IDelem );
 }
@@ -1391,7 +1470,7 @@ int SMDS_Mesh::GetElementsByNodes(const std::vector<const SMDS_MeshNode *>& node
     }
 
   foundElems.clear();
-  if ( n0 )
+  if ( n0 && minNbInverse > 0 )
   {
     foundElems.reserve( minNbInverse );
     SMDS_ElemIteratorPtr eIt = n0->GetInverseElementIterator( type );
@@ -1412,7 +1491,7 @@ int SMDS_Mesh::GetElementsByNodes(const std::vector<const SMDS_MeshNode *>& node
 ///////////////////////////////////////////////////////////////////////////////
 /// Return the number of nodes
 ///////////////////////////////////////////////////////////////////////////////
-int SMDS_Mesh::NbNodes() const
+smIdType SMDS_Mesh::NbNodes() const
 {
   return myInfo.NbNodes();
 }
@@ -1420,14 +1499,14 @@ int SMDS_Mesh::NbNodes() const
 ///////////////////////////////////////////////////////////////////////////////
 /// Return the number of elements
 ///////////////////////////////////////////////////////////////////////////////
-int SMDS_Mesh::NbElements() const
+smIdType SMDS_Mesh::NbElements() const
 {
   return myInfo.NbElements();
 }
 ///////////////////////////////////////////////////////////////////////////////
 /// Return the number of 0D elements
 ///////////////////////////////////////////////////////////////////////////////
-int SMDS_Mesh::Nb0DElements() const
+smIdType SMDS_Mesh::Nb0DElements() const
 {
   return myInfo.Nb0DElements();
 }
@@ -1435,7 +1514,7 @@ int SMDS_Mesh::Nb0DElements() const
 ///////////////////////////////////////////////////////////////////////////////
 /// Return the number of 0D elements
 ///////////////////////////////////////////////////////////////////////////////
-int SMDS_Mesh::NbBalls() const
+smIdType SMDS_Mesh::NbBalls() const
 {
   return myInfo.NbBalls();
 }
@@ -1443,7 +1522,7 @@ int SMDS_Mesh::NbBalls() const
 ///////////////////////////////////////////////////////////////////////////////
 /// Return the number of edges (including construction edges)
 ///////////////////////////////////////////////////////////////////////////////
-int SMDS_Mesh::NbEdges() const
+smIdType SMDS_Mesh::NbEdges() const
 {
   return myInfo.NbEdges();
 }
@@ -1451,7 +1530,7 @@ int SMDS_Mesh::NbEdges() const
 ///////////////////////////////////////////////////////////////////////////////
 /// Return the number of faces (including construction faces)
 ///////////////////////////////////////////////////////////////////////////////
-int SMDS_Mesh::NbFaces() const
+smIdType SMDS_Mesh::NbFaces() const
 {
   return myInfo.NbFaces();
 }
@@ -1459,7 +1538,7 @@ int SMDS_Mesh::NbFaces() const
 ///////////////////////////////////////////////////////////////////////////////
 /// Return the number of volumes
 ///////////////////////////////////////////////////////////////////////////////
-int SMDS_Mesh::NbVolumes() const
+smIdType SMDS_Mesh::NbVolumes() const
 {
   return myInfo.NbVolumes();
 }
@@ -1468,7 +1547,7 @@ int SMDS_Mesh::NbVolumes() const
 /// Return the number of child mesh of this mesh.
 /// Note that the tree structure of SMDS_Mesh is unused in SMESH
 ///////////////////////////////////////////////////////////////////////////////
-int SMDS_Mesh::NbSubMesh() const
+smIdType SMDS_Mesh::NbSubMesh() const
 {
   return myChildren.size();
 }
@@ -1542,8 +1621,9 @@ SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
 
 SMDS_ElemIteratorPtr SMDS_Mesh::elementGeomIterator(SMDSAbs_GeometryType type) const
 {
+  smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbElements( type );
   return myCellFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::GeomFilter( type ),
-                                                          myInfo.NbElements( type ));
+                                                          nbElems);
 }
 
 SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) const
@@ -1552,8 +1632,9 @@ SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) c
   {
     return myNodeFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::NonNullFilter );
   }
+  smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbElements( type );
   return myCellFactory->GetIterator<SMDS_ElemIterator>( new SMDS_MeshElement::EntityFilter( type ),
-                                                        myInfo.NbElements( type ));
+                                                        nbElems);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1571,8 +1652,9 @@ SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
     return myNodeFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter );
 
   default:
+    smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbElements( type );
     return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( type ),
-                                                    myInfo.NbElements( type ));
+                                                    nbElems);
   }
   return SMDS_ElemIteratorPtr();
 }
@@ -1584,8 +1666,9 @@ SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
 {
   typedef SMDS_EdgeIterator TIterator;
+  smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbEdges();
   return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Edge ),
-                                                  myInfo.NbEdges());
+                                                  nbElems);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1595,8 +1678,9 @@ SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
 {
   typedef SMDS_FaceIterator TIterator;
+  smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbFaces();
   return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Face ),
-                                                  myInfo.NbFaces());
+                                                  nbElems);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1606,19 +1690,24 @@ SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
 {
   typedef SMDS_VolumeIterator TIterator;
+  smIdType nbElems = myCellFactory->CompactChangePointers() ? -1 : myInfo.NbVolumes();
   return
     myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Volume ),
-                                             myInfo.NbVolumes());
+                                             nbElems );
 }
 
-SMDS_NodeIteratorPtr SMDS_Mesh::shapeNodesIterator(int shapeID, size_t nbElemsToReturn) const
+SMDS_NodeIteratorPtr SMDS_Mesh::shapeNodesIterator(int                  shapeID,
+                                                   size_t               nbElemsToReturn,
+                                                   const SMDS_MeshNode* sm1stNode) const
 {
-  return myNodeFactory->GetShapeIterator< SMDS_NodeIterator >( shapeID, nbElemsToReturn );
+  return myNodeFactory->GetShapeIterator< SMDS_NodeIterator >( shapeID, nbElemsToReturn, sm1stNode );
 }
 
-SMDS_ElemIteratorPtr SMDS_Mesh::shapeElementsIterator(int shapeID, size_t nbElemsToReturn) const
+SMDS_ElemIteratorPtr SMDS_Mesh::shapeElementsIterator(int                     shapeID,
+                                                      size_t                  nbElemsToReturn,
+                                                      const SMDS_MeshElement* sm1stElem) const
 {
-  return myCellFactory->GetShapeIterator< SMDS_ElemIterator >( shapeID, nbElemsToReturn );
+  return myCellFactory->GetShapeIterator< SMDS_ElemIterator >( shapeID, nbElemsToReturn, sm1stElem );
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1817,7 +1906,7 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *               elem,
       n->RemoveInverseElement((*it));
     }
 
-    int vtkid = (*it)->GetVtkID();
+    vtkIdType vtkid = (*it)->GetVtkID();
 
     switch ((*it)->GetType()) {
     case SMDSAbs_Node:
@@ -1831,6 +1920,7 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *               elem,
     case SMDSAbs_All: // avoid compilation warning
     case SMDSAbs_NbElementTypes: break;
     }
+    removedElems.push_back( *it);
 
     myCellFactory->Free( static_cast< const SMDS_MeshCell*>( *it ));
 
@@ -1861,7 +1951,7 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *               elem,
 ///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
 {
-  const int           vtkId = elem->GetVtkID();
+  const vtkIdType     vtkId = elem->GetVtkID();
   SMDSAbs_ElementType aType = elem->GetType();
   if ( aType == SMDSAbs_Node )
   {
@@ -1922,7 +2012,7 @@ bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
 //purpose  :
 //=======================================================================
 
-int SMDS_Mesh::MaxNodeID() const
+smIdType SMDS_Mesh::MaxNodeID() const
 {
   return myNodeFactory->GetMaxID();
 }
@@ -1932,7 +2022,7 @@ int SMDS_Mesh::MaxNodeID() const
 //purpose  :
 //=======================================================================
 
-int SMDS_Mesh::MinNodeID() const
+smIdType SMDS_Mesh::MinNodeID() const
 {
   return myNodeFactory->GetMinID();
 }
@@ -1942,7 +2032,7 @@ int SMDS_Mesh::MinNodeID() const
 //purpose  :
 //=======================================================================
 
-int SMDS_Mesh::MaxElementID() const
+smIdType SMDS_Mesh::MaxElementID() const
 {
   return myCellFactory->GetMaxID();
 }
@@ -1952,7 +2042,7 @@ int SMDS_Mesh::MaxElementID() const
 //purpose  :
 //=======================================================================
 
-int SMDS_Mesh::MinElementID() const
+smIdType SMDS_Mesh::MinElementID() const
 {
   return myCellFactory->GetMinID();
 }
@@ -1974,7 +2064,7 @@ int SMDS_Mesh::MinElementID() const
 //purpose  : Return type of element or node with id
 //=======================================================================
 
-SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
+SMDSAbs_ElementType SMDS_Mesh::GetElementType( const smIdType id, const bool iselem ) const
 {
   const SMDS_MeshElement* elem = 0;
   if( iselem )
@@ -1999,7 +2089,7 @@ SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem )
 //function : AddEdgeWithID
 //purpose  :
 //=======================================================================
-SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int n1, int n2, int n12, int ID)
+SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(smIdType n1, smIdType n2, smIdType n12, smIdType ID)
 {
   return SMDS_Mesh::AddEdgeWithID (myNodeFactory->FindNode(n1),
                                    myNodeFactory->FindNode(n2),
@@ -2025,7 +2115,7 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode* n1,
 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n2,
                                         const SMDS_MeshNode * n12,
-                                        int                   ID)
+                                        smIdType                   ID)
 {
   if ( !n1 || !n2 || !n12 ) return 0;
 
@@ -2058,8 +2148,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
 //function : AddFaceWithID
 //purpose  :
 //=======================================================================
-SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
-                                        int n12,int n23,int n31, int ID)
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3,
+                                        smIdType n12,smIdType n23,smIdType n31, smIdType ID)
 {
   return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
                                    myNodeFactory->FindNode(n2) ,
@@ -2080,7 +2170,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n12,
                                         const SMDS_MeshNode * n23,
                                         const SMDS_MeshNode * n31,
-                                        int ID)
+                                        smIdType ID)
 {
   if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 ) return 0;
   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
@@ -2115,8 +2205,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
 //function : AddFaceWithID
 //purpose  :
 //=======================================================================
-SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3,
-                                        int n12,int n23,int n31, int nCenter, int ID)
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3,
+                                        smIdType n12,smIdType n23,smIdType n31, smIdType nCenter, smIdType ID)
 {
   return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
                                    myNodeFactory->FindNode(n2) ,
@@ -2139,7 +2229,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n23,
                                         const SMDS_MeshNode * n31,
                                         const SMDS_MeshNode * nCenter,
-                                        int ID)
+                                        smIdType ID)
 {
   if ( !n1 || !n2 || !n3 || !n12 || !n23 || !n31 || !nCenter) return 0;
   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
@@ -2175,8 +2265,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
 //function : AddFaceWithID
 //purpose  :
 //=======================================================================
-SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
-                                        int n12,int n23,int n34,int n41, int ID)
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
+                                        smIdType n12,smIdType n23,smIdType n34,smIdType n41, smIdType ID)
 {
   return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
                                    myNodeFactory->FindNode(n2) ,
@@ -2201,7 +2291,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n23,
                                         const SMDS_MeshNode * n34,
                                         const SMDS_MeshNode * n41,
-                                        int ID)
+                                        smIdType ID)
 {
   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
@@ -2237,8 +2327,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
 //function : AddFaceWithID
 //purpose  :
 //=======================================================================
-SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4,
-                                        int n12,int n23,int n34,int n41, int nCenter, int ID)
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
+                                        smIdType n12,smIdType n23,smIdType n34,smIdType n41, smIdType nCenter, smIdType ID)
 {
   return SMDS_Mesh::AddFaceWithID (myNodeFactory->FindNode(n1) ,
                                    myNodeFactory->FindNode(n2) ,
@@ -2265,7 +2355,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n34,
                                         const SMDS_MeshNode * n41,
                                         const SMDS_MeshNode * nCenter,
-                                        int ID)
+                                        smIdType ID)
 {
   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41 || !nCenter) return 0;
   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
@@ -2304,9 +2394,9 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 //function : AddVolumeWithID
 //purpose  :
 //=======================================================================
-SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
-                                            int n12,int n23,int n31,
-                                            int n14,int n24,int n34, int ID)
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
+                                            smIdType n12,smIdType n23,smIdType n31,
+                                            smIdType n14,smIdType n24,smIdType n34, smIdType ID)
 {
   return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
                                      myNodeFactory->FindNode(n2) ,
@@ -2335,7 +2425,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n14,
                                             const SMDS_MeshNode * n24,
                                             const SMDS_MeshNode * n34,
-                                            int ID)
+                                            smIdType ID)
 {
   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n31 || !n14 || !n24 || !n34)
     return 0;
@@ -2378,9 +2468,9 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 //function : AddVolumeWithID
 //purpose  :
 //=======================================================================
-SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5,
-                                            int n12,int n23,int n34,int n41,
-                                            int n15,int n25,int n35,int n45, int ID)
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4, smIdType n5,
+                                            smIdType n12,smIdType n23,smIdType n34,smIdType n41,
+                                            smIdType n15,smIdType n25,smIdType n35,smIdType n45, smIdType ID)
 {
   return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
                                      myNodeFactory->FindNode(n2) ,
@@ -2415,7 +2505,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n25,
                                             const SMDS_MeshNode * n35,
                                             const SMDS_MeshNode * n45,
-                                            int ID)
+                                            smIdType ID)
 {
   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n12 || !n23 ||
       !n34 || !n41 || !n15 || !n25 || !n35 || !n45)
@@ -2461,11 +2551,11 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 //function : AddVolumeWithID
 //purpose  : 2d order Pentahedron (prism) with 15 nodes
 //=======================================================================
-SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
-                                            int n4, int n5, int n6,
-                                            int n12,int n23,int n31,
-                                            int n45,int n56,int n64,
-                                            int n14,int n25,int n36, int ID)
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3,
+                                            smIdType n4, smIdType n5, smIdType n6,
+                                            smIdType n12,smIdType n23,smIdType n31,
+                                            smIdType n45,smIdType n56,smIdType n64,
+                                            smIdType n14,smIdType n25,smIdType n36, smIdType ID)
 {
   return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
                                      myNodeFactory->FindNode(n2) ,
@@ -2504,7 +2594,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n14,
                                             const SMDS_MeshNode * n25,
                                             const SMDS_MeshNode * n36,
-                                            int ID)
+                                            smIdType ID)
 {
   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
       !n31 || !n45 || !n56 || !n64 || !n14 || !n25 || !n36)
@@ -2553,12 +2643,12 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 //function : AddVolumeWithID
 //purpose  : 2d order Pentahedron (prism) with 18 nodes
 //=======================================================================
-SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3,
-                                            int n4, int n5, int n6,
-                                            int n12,int n23,int n31,
-                                            int n45,int n56,int n64,
-                                            int n14,int n25,int n36,
-                                            int n1245, int n2356, int n1346, int ID)
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3,
+                                            smIdType n4, smIdType n5, smIdType n6,
+                                            smIdType n12,smIdType n23,smIdType n31,
+                                            smIdType n45,smIdType n56,smIdType n64,
+                                            smIdType n14,smIdType n25,smIdType n36,
+                                            smIdType n1245, smIdType n2356, smIdType n1346, smIdType ID)
 {
   return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1) ,
                                      myNodeFactory->FindNode(n2) ,
@@ -2603,7 +2693,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n1245,
                                             const SMDS_MeshNode * n2356,
                                             const SMDS_MeshNode * n1346,
-                                            int ID)
+                                            smIdType ID)
 {
   //MESSAGE("AddVolumeWithID penta18 "<< ID);
   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n12 || !n23 ||
@@ -2656,11 +2746,11 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 //function : AddVolumeWithID
 //purpose  :
 //=======================================================================
-SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
-                                            int n5, int n6, int n7, int n8,
-                                            int n12,int n23,int n34,int n41,
-                                            int n56,int n67,int n78,int n85,
-                                            int n15,int n26,int n37,int n48, int ID)
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
+                                            smIdType n5, smIdType n6, smIdType n7, smIdType n8,
+                                            smIdType n12,smIdType n23,smIdType n34,smIdType n41,
+                                            smIdType n56,smIdType n67,smIdType n78,smIdType n85,
+                                            smIdType n15,smIdType n26,smIdType n37,smIdType n48, smIdType ID)
 {
   return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1),
                                      myNodeFactory->FindNode(n2),
@@ -2709,7 +2799,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n26,
                                             const SMDS_MeshNode * n37,
                                             const SMDS_MeshNode * n48,
-                                            int ID)
+                                            smIdType ID)
 {
   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
       !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48)
@@ -2768,13 +2858,13 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
 //function : AddVolumeWithID
 //purpose  :
 //=======================================================================
-SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4,
-                                            int n5, int n6, int n7, int n8,
-                                            int n12,int n23,int n34,int n41,
-                                            int n56,int n67,int n78,int n85,
-                                            int n15,int n26,int n37,int n48,
-                                            int n1234,int n1256,int n2367,int n3478,
-                                            int n1458,int n5678,int nCenter, int ID)
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(smIdType n1, smIdType n2, smIdType n3, smIdType n4,
+                                            smIdType n5, smIdType n6, smIdType n7, smIdType n8,
+                                            smIdType n12,smIdType n23,smIdType n34,smIdType n41,
+                                            smIdType n56,smIdType n67,smIdType n78,smIdType n85,
+                                            smIdType n15,smIdType n26,smIdType n37,smIdType n48,
+                                            smIdType n1234,smIdType n1256,smIdType n2367,smIdType n3478,
+                                            smIdType n1458,smIdType n5678,smIdType nCenter, smIdType ID)
 {
   return SMDS_Mesh::AddVolumeWithID (myNodeFactory->FindNode(n1),
                                      myNodeFactory->FindNode(n2),
@@ -2837,7 +2927,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n1458,
                                             const SMDS_MeshNode * n5678,
                                             const SMDS_MeshNode * nCenter,
-                                            int ID)
+                                            smIdType ID)
 {
   if (!n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8 || !n12 || !n23 ||
       !n34 || !n41 || !n56 || !n67 || !n78 || !n85 || !n15 || !n26 || !n37 || !n48 ||
@@ -2876,7 +2966,7 @@ void SMDS_Mesh::dumpGrid(std::string ficdump)
   }
   int nbCells = myGrid->GetNumberOfCells();
   ficcon << "-------------------------------- cells " <<  nbCells << endl;
-  for (int i=0; i<nbCells; i++)
+  for (vtkIdType i=0; i<nbCells; i++)
   {
     ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
     int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
@@ -2908,36 +2998,48 @@ void SMDS_Mesh::CompactMesh()
 {
   this->myCompactTime = this->myModifTime;
 
-  bool idsChange = ( myNodeFactory->CompactChangePointers() ||
-                     myCellFactory->CompactChangePointers() );
+  bool idsChange = HasNumerationHoles();
   if ( idsChange )
   {
     std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
     for ( ; holder != myElemHolders.end(); ++holder )
       (*holder)->beforeCompacting();
   }
+  smIdType oldCellSize = myCellFactory->GetMaxID();
 
   // remove "holes" in SMDS numeration
-  std::vector<int> idNodesOldToNew, idCellsNewToOld;
+  std::vector<smIdType> idNodesOldToNew, idCellsNewToOld, idCellsOldToNew;
   myNodeFactory->Compact( idNodesOldToNew );
   myCellFactory->Compact( idCellsNewToOld );
 
   // make VTK IDs correspond to SMDS IDs
-  int newNodeSize = myNodeFactory->NbUsedElements();
-  int newCellSize = myCellFactory->NbUsedElements();
+  smIdType newNodeSize = myNodeFactory->NbUsedElements();
+  smIdType newCellSize = myCellFactory->NbUsedElements();
   myGrid->compactGrid( idNodesOldToNew, newNodeSize, idCellsNewToOld, newCellSize );
 
+  if ( idsChange && !myElemHolders.empty() )
+  {
+    // idCellsNewToOld -> idCellsOldToNew
+    idCellsOldToNew.resize( oldCellSize, oldCellSize );
+    for ( size_t iNew = 0; iNew < idCellsNewToOld.size(); ++iNew )
+    {
+      if ( idCellsNewToOld[ iNew ] >= (smIdType) idCellsOldToNew.size() )
+        idCellsOldToNew.resize( ( 1 + idCellsNewToOld[ iNew ]) * 1.5, oldCellSize );
+      idCellsOldToNew[ idCellsNewToOld[ iNew ]] = iNew;
+    }
+  }
+
   std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
   for ( ; holder != myElemHolders.end(); ++holder )
     if ( idsChange )
-      (*holder)->restoreElements( idNodesOldToNew, idCellsNewToOld );
+      (*holder)->restoreElements( idNodesOldToNew, idCellsOldToNew );
     else
       (*holder)->compact();
 
   return;
 }
 
-int SMDS_Mesh::FromVtkToSmds( int vtkid ) const
+smIdType SMDS_Mesh::FromVtkToSmds( vtkIdType vtkid ) const
 {
   return myCellFactory->FromVtkToSmds( vtkid );
 }
@@ -2956,6 +3058,7 @@ void SMDS_Mesh::Modified()
 {
   if (this->myModified)
   {
+    myGrid->Modified();
     this->myModifTime++;
     myModified = false;
   }
@@ -2972,6 +3075,13 @@ bool SMDS_Mesh::IsCompacted()
   return ( this->myCompactTime == this->myModifTime );
 }
 
+//! are there holes in elements or nodes numeration
+bool SMDS_Mesh::HasNumerationHoles()
+{
+  return ( myNodeFactory->CompactChangePointers() ||
+           myCellFactory->CompactChangePointers() );
+}
+
 void SMDS_Mesh::setNbShapes( size_t nbShapes )
 {
   myNodeFactory->SetNbShapes( nbShapes );