Salome HOME
23418: [OCC] Mesh: Minimization of memory usage of SMESH
authoreap <eap@opencascade.com>
Fri, 22 Dec 2017 11:14:24 +0000 (14:14 +0300)
committereap <eap@opencascade.com>
Thu, 5 Apr 2018 12:08:14 +0000 (15:08 +0300)
148 files changed:
src/Controls/SMESH_Controls.cxx
src/Driver/CMakeLists.txt
src/DriverCGNS/DriverCGNS_Read.cxx
src/DriverCGNS/DriverCGNS_Write.cxx
src/DriverDAT/DriverDAT_W_SMDS_Mesh.cxx
src/DriverGMF/DriverGMF_Read.cxx
src/DriverMED/DriverMED_Family.cxx
src/DriverMED/DriverMED_Family.h
src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx
src/DriverMED/DriverMED_W_Field.cxx
src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx
src/DriverMED/DriverMED_W_SMESHDS_Mesh.h
src/DriverSTL/DriverSTL_R_SMDS_Mesh.cxx
src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx
src/DriverUNV/DriverUNV_R_SMDS_Mesh.h
src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx
src/DriverUNV/UNV2417_Structure.hxx
src/OBJECT/SMESH_Object.cxx
src/SMDS/CMakeLists.txt
src/SMDS/Notes [deleted file]
src/SMDS/ObjectPool.hxx
src/SMDS/SMDS_BallElement.cxx
src/SMDS/SMDS_BallElement.hxx
src/SMDS/SMDS_CellOfNodes.cxx [new file with mode: 0644]
src/SMDS/SMDS_CellOfNodes.hxx [new file with mode: 0644]
src/SMDS/SMDS_Downward.cxx
src/SMDS/SMDS_EdgePosition.cxx [deleted file]
src/SMDS/SMDS_EdgePosition.hxx
src/SMDS/SMDS_ElementFactory.cxx [new file with mode: 0644]
src/SMDS/SMDS_ElementFactory.hxx [new file with mode: 0644]
src/SMDS/SMDS_ElementHolder.cxx [new file with mode: 0644]
src/SMDS/SMDS_ElementHolder.hxx [new file with mode: 0644]
src/SMDS/SMDS_FaceOfEdges.cxx [deleted file]
src/SMDS/SMDS_FaceOfEdges.hxx [deleted file]
src/SMDS/SMDS_FaceOfNodes.cxx
src/SMDS/SMDS_FaceOfNodes.hxx
src/SMDS/SMDS_FacePosition.cxx
src/SMDS/SMDS_FacePosition.hxx
src/SMDS/SMDS_Iterator.hxx
src/SMDS/SMDS_IteratorOfElements.cxx [deleted file]
src/SMDS/SMDS_IteratorOfElements.hxx [deleted file]
src/SMDS/SMDS_LinearEdge.cxx
src/SMDS/SMDS_LinearEdge.hxx
src/SMDS/SMDS_Mesh.cxx
src/SMDS/SMDS_Mesh.hxx
src/SMDS/SMDS_Mesh0DElement.cxx [deleted file]
src/SMDS/SMDS_Mesh0DElement.hxx
src/SMDS/SMDS_MeshCell.cxx
src/SMDS/SMDS_MeshCell.hxx
src/SMDS/SMDS_MeshEdge.cxx [deleted file]
src/SMDS/SMDS_MeshEdge.hxx
src/SMDS/SMDS_MeshElement.cxx
src/SMDS/SMDS_MeshElement.hxx
src/SMDS/SMDS_MeshElementIDFactory.cxx [deleted file]
src/SMDS/SMDS_MeshElementIDFactory.hxx [deleted file]
src/SMDS/SMDS_MeshFace.cxx [deleted file]
src/SMDS/SMDS_MeshFace.hxx
src/SMDS/SMDS_MeshGroup.cxx
src/SMDS/SMDS_MeshGroup.hxx
src/SMDS/SMDS_MeshIDFactory.cxx [deleted file]
src/SMDS/SMDS_MeshIDFactory.hxx [deleted file]
src/SMDS/SMDS_MeshNode.cxx
src/SMDS/SMDS_MeshNode.hxx
src/SMDS/SMDS_MeshNodeIDFactory.cxx [deleted file]
src/SMDS/SMDS_MeshNodeIDFactory.hxx [deleted file]
src/SMDS/SMDS_MeshVolume.cxx
src/SMDS/SMDS_MeshVolume.hxx
src/SMDS/SMDS_PolygonalFaceOfNodes.cxx
src/SMDS/SMDS_PolygonalFaceOfNodes.hxx
src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx [deleted file]
src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx [deleted file]
src/SMDS/SMDS_Position.cxx [deleted file]
src/SMDS/SMDS_Position.hxx
src/SMDS/SMDS_QuadraticEdge.cxx [deleted file]
src/SMDS/SMDS_QuadraticEdge.hxx [deleted file]
src/SMDS/SMDS_QuadraticFaceOfNodes.cxx [deleted file]
src/SMDS/SMDS_QuadraticFaceOfNodes.hxx [deleted file]
src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx [deleted file]
src/SMDS/SMDS_QuadraticVolumeOfNodes.hxx [deleted file]
src/SMDS/SMDS_SpacePosition.cxx
src/SMDS/SMDS_SpacePosition.hxx
src/SMDS/SMDS_UnstructuredGrid.cxx
src/SMDS/SMDS_UnstructuredGrid.hxx
src/SMDS/SMDS_VertexPosition.cxx [deleted file]
src/SMDS/SMDS_VertexPosition.hxx
src/SMDS/SMDS_VolumeOfFaces.cxx [deleted file]
src/SMDS/SMDS_VolumeOfFaces.hxx [deleted file]
src/SMDS/SMDS_VolumeOfNodes.cxx
src/SMDS/SMDS_VolumeOfNodes.hxx
src/SMDS/SMDS_VolumeTool.cxx
src/SMDS/SMDS_VolumeTool.hxx
src/SMDS/SMDS_VtkCellIterator.cxx
src/SMDS/SMDS_VtkCellIterator.hxx
src/SMDS/SMDS_VtkEdge.cxx [deleted file]
src/SMDS/SMDS_VtkEdge.hxx [deleted file]
src/SMDS/SMDS_VtkFace.cxx [deleted file]
src/SMDS/SMDS_VtkFace.hxx [deleted file]
src/SMDS/SMDS_VtkVolume.cxx [deleted file]
src/SMDS/SMDS_VtkVolume.hxx [deleted file]
src/SMESH/SMESH_Algo.cxx
src/SMESH/SMESH_Algo.hxx
src/SMESH/SMESH_Gen.cxx
src/SMESH/SMESH_Mesh.cxx
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_MesherHelper.cxx
src/SMESH/SMESH_Pattern.cxx
src/SMESH/SMESH_ProxyMesh.cxx
src/SMESH/SMESH_ProxyMesh.hxx
src/SMESH/SMESH_subMesh.cxx
src/SMESHClient/SMESH_Client.cxx
src/SMESHDS/SMESHDS_Group.cxx
src/SMESHDS/SMESHDS_GroupOnFilter.cxx
src/SMESHDS/SMESHDS_GroupOnFilter.hxx
src/SMESHDS/SMESHDS_Mesh.cxx
src/SMESHDS/SMESHDS_Mesh.hxx
src/SMESHDS/SMESHDS_SubMesh.cxx
src/SMESHDS/SMESHDS_SubMesh.hxx
src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx
src/SMESHGUI/SMESHGUI_GroupDlg.cxx
src/SMESHGUI/SMESHGUI_MeshInfo.cxx
src/SMESHGUI/SMESHGUI_PreVisualObj.cxx
src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx
src/SMESHUtils/SMESH_ComputeError.hxx
src/SMESHUtils/SMESH_FillHole.cxx
src/SMESHUtils/SMESH_FreeBorders.cxx
src/SMESHUtils/SMESH_MeshAlgos.cxx
src/SMESHUtils/SMESH_TryCatch.cxx
src/SMESH_I/SMESH_Gen_i.cxx
src/SMESH_I/SMESH_Measurements_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_I/SMESH_MeshPartDS.hxx
src/SMESH_I/SMESH_Mesh_i.cxx
src/SMESH_I/SMESH_PreMeshInfo.cxx
src/StdMeshers/StdMeshers_Cartesian_3D.cxx
src/StdMeshers/StdMeshers_FaceSide.cxx
src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx
src/StdMeshers/StdMeshers_Import_1D2D.cxx
src/StdMeshers/StdMeshers_MEFISTO_2D.cxx
src/StdMeshers/StdMeshers_Penta_3D.cxx
src/StdMeshers/StdMeshers_Prism_3D.cxx
src/StdMeshers/StdMeshers_ProjectionUtils.cxx
src/StdMeshers/StdMeshers_Projection_1D2D.cxx
src/StdMeshers/StdMeshers_Projection_2D.cxx
src/StdMeshers/StdMeshers_Projection_3D.cxx
src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx
src/StdMeshers/StdMeshers_Quadrangle_2D.cxx
src/StdMeshers/StdMeshers_ViscousLayers.cxx
src/StdMeshers/StdMeshers_ViscousLayers2D.cxx

index b1279a6..1ccd96f 100644 (file)
@@ -28,8 +28,6 @@
 #include "SMDS_Mesh.hxx"
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
-#include "SMDS_QuadraticEdge.hxx"
-#include "SMDS_QuadraticFaceOfNodes.hxx"
 #include "SMDS_VolumeTool.hxx"
 #include "SMESHDS_GroupBase.hxx"
 #include "SMESHDS_GroupOnFilter.hxx"
@@ -253,26 +251,7 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem,
   theRes.setElement( anElem );
 
   // Get nodes of the element
-  SMDS_ElemIteratorPtr anIter;
-
-  if ( anElem->IsQuadratic() ) {
-    switch ( anElem->GetType() ) {
-    case SMDSAbs_Edge:
-      anIter = dynamic_cast<const SMDS_VtkEdge*>
-        (anElem)->interlacedNodesElemIterator();
-      break;
-    case SMDSAbs_Face:
-      anIter = dynamic_cast<const SMDS_VtkFace*>
-        (anElem)->interlacedNodesElemIterator();
-      break;
-    default:
-      anIter = anElem->nodesIterator();
-    }
-  }
-  else {
-    anIter = anElem->nodesIterator();
-  }
-
+  SMDS_NodeIteratorPtr anIter= anElem->interlacedNodesIterator();
   if ( anIter ) {
     SMESH_NodeXYZ p;
     while( anIter->more() ) {
@@ -771,8 +750,8 @@ double AspectRatio::GetValue( long theId )
   if ( myCurrElement && myCurrElement->GetVtkType() == VTK_QUAD )
   {
     // issue 21723
-    vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myCurrElement->getMeshId()]->getGrid();
-    if ( vtkCell* avtkCell = grid->GetCell( myCurrElement->getVtkId() ))
+    vtkUnstructuredGrid* grid = const_cast<SMDS_Mesh*>( myMesh )->GetGrid();
+    if ( vtkCell* avtkCell = grid->GetCell( myCurrElement->GetVtkID() ))
       aVal = Round( vtkMeshQuality::QuadAspectRatio( avtkCell ));
   }
   else
@@ -1015,8 +994,8 @@ double AspectRatio3D::GetValue( long theId )
     // Action from CoTech | ACTION 31.3:
     // EURIWARE BO: Homogenize the formulas used to calculate the Controls in SMESH to fit with
     // those of ParaView. The library used by ParaView for those calculations can be reused in SMESH.
-    vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myCurrElement->getMeshId()]->getGrid();
-    if ( vtkCell* avtkCell = grid->GetCell( myCurrElement->getVtkId() ))
+    vtkUnstructuredGrid* grid = const_cast<SMDS_Mesh*>( myMesh )->GetGrid();
+    if ( vtkCell* avtkCell = grid->GetCell( myCurrElement->GetVtkID() ))
       aVal = Round( vtkMeshQuality::TetAspectRatio( avtkCell ));
   }
   else
@@ -1035,7 +1014,7 @@ double AspectRatio3D::GetValue( const TSequenceOfXYZ& P )
 
   int nbNodes = P.size();
 
-  if(myCurrElement->IsQuadratic()) {
+  if( myCurrElement->IsQuadratic() ) {
     if(nbNodes==10) nbNodes=4; // quadratic tetrahedron
     else if(nbNodes==13) nbNodes=5; // quadratic pyramid
     else if(nbNodes==15) nbNodes=6; // quadratic pentahedron
@@ -1827,35 +1806,33 @@ bool Length2D::Value::operator<(const Length2D::Value& x) const
 void Length2D::GetValues(TValues& theValues)
 {
   TValues aValues;
-  SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
-  for(; anIter->more(); ){
+  for ( SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); anIter->more(); )
+  {
     const SMDS_MeshFace* anElem = anIter->next();
-
-    if(anElem->IsQuadratic()) {
-      const SMDS_VtkFace* F =
-        dynamic_cast<const SMDS_VtkFace*>(anElem);
+    if ( anElem->IsQuadratic() )
+    {
       // use special nodes iterator
-      SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
+      SMDS_NodeIteratorPtr anIter = anElem->interlacedNodesIterator();
       long aNodeId[4] = { 0,0,0,0 };
       gp_Pnt P[4];
 
       double aLength = 0;
-      const SMDS_MeshElement* aNode;
-      if(anIter->more()){
-        aNode = anIter->next();
-        const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode;
-        P[0] = P[1] = gp_Pnt(aNodes->X(),aNodes->Y(),aNodes->Z());
+      if ( anIter->more() )
+      {
+        const SMDS_MeshNode* aNode = anIter->next();
+        P[0] = P[1] = SMESH_NodeXYZ( aNode );
         aNodeId[0] = aNodeId[1] = aNode->GetID();
         aLength = 0;
       }
-      for(; anIter->more(); ){
-        const SMDS_MeshNode* N1 = static_cast<const SMDS_MeshNode*> (anIter->next());
-        P[2] = gp_Pnt(N1->X(),N1->Y(),N1->Z());
+      for ( ; anIter->more(); )
+      {
+        const SMDS_MeshNode* N1 = anIter->next();
+        P[2] = SMESH_NodeXYZ( N1 );
         aNodeId[2] = N1->GetID();
         aLength = P[1].Distance(P[2]);
         if(!anIter->more()) break;
-        const SMDS_MeshNode* N2 = static_cast<const SMDS_MeshNode*> (anIter->next());
-        P[3] = gp_Pnt(N2->X(),N2->Y(),N2->Z());
+        const SMDS_MeshNode* N2 = anIter->next();
+        P[3] = SMESH_NodeXYZ( N2 );
         aNodeId[3] = N2->GetID();
         aLength += P[2].Distance(P[3]);
         Value aValue1(aLength,aNodeId[1],aNodeId[2]);
@@ -1872,28 +1849,28 @@ void Length2D::GetValues(TValues& theValues)
       theValues.insert(aValue2);
     }
     else {
-      SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
+      SMDS_NodeIteratorPtr aNodesIter = anElem->nodeIterator();
       long aNodeId[2] = {0,0};
       gp_Pnt P[3];
 
       double aLength;
       const SMDS_MeshElement* aNode;
-      if(aNodesIter->more()){
+      if ( aNodesIter->more())
+      {
         aNode = aNodesIter->next();
-        const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode;
-        P[0] = P[1] = gp_Pnt(aNodes->X(),aNodes->Y(),aNodes->Z());
+        P[0] = P[1] = SMESH_NodeXYZ( aNode );
         aNodeId[0] = aNodeId[1] = aNode->GetID();
         aLength = 0;
       }
-      for(; aNodesIter->more(); ){
+      for( ; aNodesIter->more(); )
+      {
         aNode = aNodesIter->next();
-        const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode;
         long anId = aNode->GetID();
-        
-        P[2] = gp_Pnt(aNodes->X(),aNodes->Y(),aNodes->Z());
-        
+
+        P[2] = SMESH_NodeXYZ( aNode );
+
         aLength = P[1].Distance(P[2]);
-        
+
         Value aValue(aLength,aNodeId[1],anId);
         aNodeId[1] = anId;
         P[1] = P[2];
@@ -1947,8 +1924,7 @@ double Deflection2D::GetValue( const TSequenceOfXYZ& P )
       {
         gc += P(i+1);
 
-        if ( const SMDS_FacePosition* fPos = dynamic_cast<const SMDS_FacePosition*>
-             ( P.getElement()->GetNode( i )->GetPosition() ))
+        if ( SMDS_FacePositionPtr fPos = P.getElement()->GetNode( i )->GetPosition() )
         {
           uv.ChangeCoord(1) += fPos->GetUParameter();
           uv.ChangeCoord(2) += fPos->GetVParameter();
@@ -2124,59 +2100,24 @@ bool MultiConnection2D::Value::operator<(const MultiConnection2D::Value& x) cons
 void MultiConnection2D::GetValues(MValues& theValues)
 {
   if ( !myMesh ) return;
-  SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
-  for(; anIter->more(); ){
-    const SMDS_MeshFace* anElem = anIter->next();
-    SMDS_ElemIteratorPtr aNodesIter;
-    if ( anElem->IsQuadratic() )
-      aNodesIter = dynamic_cast<const SMDS_VtkFace*>
-        (anElem)->interlacedNodesElemIterator();
-    else
-      aNodesIter = anElem->nodesIterator();
-    long aNodeId[3] = {0,0,0};
+  for ( SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); anIter->more(); )
+  {
+    const SMDS_MeshFace*     anElem = anIter->next();
+    SMDS_NodeIteratorPtr aNodesIter = anElem->interlacedNodesIterator();
 
-    //int aNbConnects=0;
-    const SMDS_MeshNode* aNode0;
-    const SMDS_MeshNode* aNode1;
+    const SMDS_MeshNode* aNode1 = anElem->GetNode( anElem->NbNodes() - 1 );
     const SMDS_MeshNode* aNode2;
-    if(aNodesIter->more()){
-      aNode0 = (SMDS_MeshNode*) aNodesIter->next();
-      aNode1 = aNode0;
-      const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode1;
-      aNodeId[0] = aNodeId[1] = aNodes->GetID();
-    }
-    for(; aNodesIter->more(); ) {
-      aNode2 = (SMDS_MeshNode*) aNodesIter->next();
-      long anId = aNode2->GetID();
-      aNodeId[2] = anId;
-
-      Value aValue(aNodeId[1],aNodeId[2]);
-      MValues::iterator aItr = theValues.find(aValue);
-      if (aItr != theValues.end()){
-        aItr->second += 1;
-        //aNbConnects = nb;
-      }
-      else {
-        theValues[aValue] = 1;
-        //aNbConnects = 1;
-      }
-      //cout << "NodeIds: "<<aNodeId[1]<<","<<aNodeId[2]<<" nbconn="<<aNbConnects<<endl;
-      aNodeId[1] = aNodeId[2];
+    for ( ; aNodesIter->more(); )
+    {
+      aNode2 = aNodesIter->next();
+
+      Value aValue ( aNode1->GetID(), aNode2->GetID() );
+      MValues::iterator aItr = theValues.insert( std::make_pair( aValue, 0 )).first;
+      aItr->second++;
       aNode1 = aNode2;
     }
-    Value aValue(aNodeId[0],aNodeId[2]);
-    MValues::iterator aItr = theValues.find(aValue);
-    if (aItr != theValues.end()) {
-      aItr->second += 1;
-      //aNbConnects = nb;
-    }
-    else {
-      theValues[aValue] = 1;
-      //aNbConnects = 1;
-    }
-    //cout << "NodeIds: "<<aNodeId[0]<<","<<aNodeId[2]<<" nbconn="<<aNbConnects<<endl;
   }
-
+  return;
 }
 
 //================================================================================
@@ -2191,7 +2132,7 @@ double BallDiameter::GetValue( long theId )
   double diameter = 0;
 
   if ( const SMDS_BallElement* ball =
-       dynamic_cast<const SMDS_BallElement*>( myMesh->FindElement( theId )))
+       myMesh->DownCast< SMDS_BallElement >( myMesh->FindElement( theId )))
   {
     diameter = ball->GetDiameter();
   }
@@ -2429,7 +2370,7 @@ void CoincidentNodes::SetMesh( const SMDS_Mesh* theMesh )
   if ( myMeshModifTracer.IsMeshModified() )
   {
     TIDSortedNodeSet nodesToCheck;
-    SMDS_NodeIteratorPtr nIt = theMesh->nodesIterator(/*idInceasingOrder=*/true);
+    SMDS_NodeIteratorPtr nIt = theMesh->nodesIterator();
     while ( nIt->more() )
       nodesToCheck.insert( nodesToCheck.end(), nIt->next() );
 
@@ -2632,31 +2573,21 @@ inline void UpdateBorders(const FreeEdges::Border& theBorder,
 void FreeEdges::GetBoreders(TBorders& theBorders)
 {
   TBorders aRegistry;
-  SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
-  for(; anIter->more(); ){
+  for ( SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); anIter->more(); )
+  {
     const SMDS_MeshFace* anElem = anIter->next();
     long anElemId = anElem->GetID();
-    SMDS_ElemIteratorPtr aNodesIter;
-    if ( anElem->IsQuadratic() )
-      aNodesIter = static_cast<const SMDS_VtkFace*>(anElem)->
-        interlacedNodesElemIterator();
-    else
-      aNodesIter = anElem->nodesIterator();
+    SMDS_NodeIteratorPtr aNodesIter = anElem->interlacedNodesIterator();
+    if ( !aNodesIter->more() ) continue;
     long aNodeId[2] = {0,0};
-    const SMDS_MeshElement* aNode;
-    if(aNodesIter->more()){
-      aNode = aNodesIter->next();
-      aNodeId[0] = aNodeId[1] = aNode->GetID();
-    }
-    for(; aNodesIter->more(); ){
-      aNode = aNodesIter->next();
-      long anId = aNode->GetID();
-      Border aBorder(anElemId,aNodeId[1],anId);
-      aNodeId[1] = anId;
-      UpdateBorders(aBorder,aRegistry,theBorders);
+    aNodeId[0] = anElem->GetNode( anElem->NbNodes()-1 )->GetID();
+    for ( ; aNodesIter->more(); )
+    {
+      aNodeId[1] = aNodesIter->next()->GetID();
+      Border aBorder( anElemId, aNodeId[0], aNodeId[1] );
+      UpdateBorders( aBorder, aRegistry, theBorders );
+      aNodeId[0] = aNodeId[1];
     }
-    Border aBorder(anElemId,aNodeId[0],aNodeId[1]);
-    UpdateBorders(aBorder,aRegistry,theBorders);
   }
 }
 
@@ -4008,24 +3939,20 @@ void ManifoldPart::expandBoundary
 void ManifoldPart::getFacesByLink( const ManifoldPart::Link& theLink,
                                    ManifoldPart::TVectorOfFacePtr& theFaces ) const
 {
-  std::set<SMDS_MeshCell *> aSetOfFaces;
+
   // take all faces that shared first node
-  SMDS_ElemIteratorPtr anItr = theLink.myNode1->facesIterator();
-  for ( ; anItr->more(); )
-  {
-    SMDS_MeshFace* aFace = (SMDS_MeshFace*)anItr->next();
-    if ( !aFace )
-      continue;
-    aSetOfFaces.insert( aFace );
-  }
+  SMDS_ElemIteratorPtr anItr = theLink.myNode1->GetInverseElementIterator( SMDSAbs_Face );
+  SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > faces( anItr ), facesEnd;
+  std::set<const SMDS_MeshElement *> aSetOfFaces( faces, facesEnd );
+
   // take all faces that shared second node
-  anItr = theLink.myNode2->facesIterator();
+  anItr = theLink.myNode2->GetInverseElementIterator( SMDSAbs_Face );
   // find the common part of two sets
   for ( ; anItr->more(); )
   {
-    SMDS_MeshFace* aFace = (SMDS_MeshFace*)anItr->next();
-    if ( aSetOfFaces.count( aFace ) )
-      theFaces.push_back( aFace );
+    const SMDS_MeshElement* aFace = anItr->next();
+    if ( aSetOfFaces.count( aFace ))
+      theFaces.push_back( (SMDS_MeshFace*) aFace );
   }
 }
 
index 40d6942..d4a1d5c 100644 (file)
@@ -25,6 +25,7 @@ INCLUDE_DIRECTORIES(
   ${KERNEL_INCLUDE_DIRS}
   ${PROJECT_SOURCE_DIR}/src/SMESHUtils
   ${PROJECT_SOURCE_DIR}/src/SMESHDS
+  ${PROJECT_SOURCE_DIR}/src/SMDS
 )
 
 # additional preprocessor / compiler flags
index c784acc..ba8daa4 100644 (file)
@@ -884,7 +884,7 @@ Driver_Mesh::Status DriverCGNS_Read::Perform()
                 {
                   const bool reverse = ( elemData[ pos-1 ] < 0 );
                   const int    iQuad = face->IsQuadratic() ? 1 : 0;
-                  SMDS_ElemIteratorPtr nIter = face->interlacedNodesElemIterator();
+                  SMDS_NodeIteratorPtr nIter = face->interlacedNodesIterator();
                   faceNodes.assign( SMDS_MeshElement::iterator( nIter ),
                                     SMDS_MeshElement::iterator());
                   if ( iQuad && reverse )
@@ -1184,6 +1184,9 @@ Driver_Mesh::Status DriverCGNS_Read::Perform()
 
   aResult = myErrorMessages.empty() ? DRS_OK : DRS_WARN_SKIP_ELEM;
 
+  myMesh->Modified();
+  myMesh->CompactMesh();
+
   return aResult;
 }
 
index 4d79e0f..25dab65 100644 (file)
@@ -301,26 +301,26 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
     vector< double > coords( myMesh->NbNodes() );
     int iC;
     // X
-    SMDS_NodeIteratorPtr nIt = myMesh->nodesIterator( /*idInceasingOrder=*/true );
+    SMDS_NodeIteratorPtr nIt = myMesh->nodesIterator();
     for ( int i = 0; nIt->more(); ++i ) coords[i] = nIt->next()->X();
     if ( cg_coord_write( _fn, iBase, iZone, CGNS_ENUMV(RealDouble),
                           "CoordinateX", &coords[0], &iC) != CG_OK )
       return addMessage( cg_get_error(), /*fatal = */true );
     // Y
-    nIt = myMesh->nodesIterator( /*idInceasingOrder=*/true );
+    nIt = myMesh->nodesIterator();
     for ( int i = 0; nIt->more(); ++i ) coords[i] = nIt->next()->Y();
     if ( cg_coord_write( _fn, iBase, iZone, CGNS_ENUMV(RealDouble),
                           "CoordinateY", &coords[0], &iC) != CG_OK )
       return addMessage( cg_get_error(), /*fatal = */true );
     // Z
-    nIt = myMesh->nodesIterator( /*idInceasingOrder=*/true );
+    nIt = myMesh->nodesIterator();
     for ( int i = 0; nIt->more(); ++i ) coords[i] = nIt->next()->Z();
     if ( cg_coord_write( _fn, iBase, iZone, CGNS_ENUMV(RealDouble),
                           "CoordinateZ", &coords[0], &iC) != CG_OK )
       return addMessage( cg_get_error(), /*fatal = */true );
 
     // store CGNS ids of nodes
-    nIt = myMesh->nodesIterator( /*idInceasingOrder=*/true );
+    nIt = myMesh->nodesIterator();
     for ( int i = 0; nIt->more(); ++i )
     {
       const SMDS_MeshElement* n = nIt->next();
index 7ab288f..403dad4 100644 (file)
@@ -117,7 +117,7 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform()
   }
 
   SMDS_VolumeIteratorPtr itVolumes=myMesh->volumesIterator();
-  const SMDS_VtkVolume* v;
+  const SMDS_MeshVolume* v;
   while(itVolumes->more())
   {
     const SMDS_MeshElement * elem = itVolumes->next();
@@ -125,7 +125,7 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform()
     {
       fprintf(aFileId, "%d %d ", elem->GetID(), 500+elem->NbNodes());
 
-      if (( v = dynamic_cast< const SMDS_VtkVolume*>( elem )))
+      if (( v = myMesh->DownCast< SMDS_MeshVolume >( elem )))
       {
         std::vector<int> quant = v->GetQuantities();
         if ( !quant.empty() )
@@ -146,7 +146,7 @@ Driver_Mesh::Status DriverDAT_W_SMDS_Mesh::Perform()
 
     fprintf(aFileId, "\n");
   }
-  
+
   fclose(aFileId);
 
   return aResult;
index 54edf6a..420b149 100644 (file)
@@ -444,6 +444,9 @@ Driver_Mesh::Status DriverGMF_Read::Perform()
     }
   }
 
+  myMesh->Modified();
+  myMesh->CompactMesh();
+
   return status;
 }
 
index a11ba48..a31488e 100644 (file)
@@ -574,3 +574,21 @@ void DriverMED_Family::Split (DriverMED_FamilyPtr by,
     common->myType = myType;
   }
 }
+
+//================================================================================
+/*!
+ * \brief Return a number of elements of a given type
+ */
+//================================================================================
+
+size_t DriverMED_Family::NbElements( SMDSAbs_ElementType theType ) const
+{
+  if ( myTypes.size() < 2 )
+    return myElements.size();
+
+  int nb = 0;
+  for ( ElementsSet::iterator e = myElements.begin(); e != myElements.end(); ++e )
+    nb += ( theType == (*e)->GetType() );
+
+  return nb;
+}
index c71ea72..97157a2 100644 (file)
@@ -119,9 +119,11 @@ class MESHDRIVERMED_EXPORT DriverMED_Family
 
   bool MemberOf(std::string theGroupName) const;
 
-  int GetGroupAttributVal() const;
+  int  GetGroupAttributVal() const;
   void SetGroupAttributVal( int theValue);
 
+  size_t NbElements( SMDSAbs_ElementType ) const;
+
  private:
   //! Initialize the tool by SMESHDS_GroupBase
   void Init (SMESHDS_GroupBase* group);
index 0003169..14a648c 100644 (file)
@@ -273,7 +273,7 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform()
             if ( anIsElemNum && !aBallInfo->myElemNum->empty() )
               maxID = *std::max_element( aBallInfo->myElemNum->begin(),
                                          aBallInfo->myElemNum->end() );
-            myMesh->getGrid()->AllocateDiameters( maxID ); // performance optimization
+            myMesh->GetGrid()->AllocateDiameters( maxID ); // performance optimization
 
             // create balls
             SMDS_MeshElement* anElement;
@@ -1038,8 +1038,6 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform()
     aResult = addMessage( "Unknown exception", /*isFatal=*/true );
   }
 #endif
-  if (myMesh)
-    myMesh->compactMesh();
 
   // Mantis issue 0020483
   if (aResult == DRS_OK && isDescConn) {
@@ -1137,6 +1135,14 @@ void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup)
 
   if (( famVecPtr = myGroups2FamiliesMap.ChangeSeek( aGroupName )))
   {
+    size_t groupSize = 0;
+    for ( size_t i = 0; i < famVecPtr->size(); ++i )
+    {
+      DriverMED_FamilyPtr aFamily = (*famVecPtr)[i];
+      groupSize += aFamily->NbElements( theGroup->GetType() );
+    }
+    theGroup->SMDSGroup().Reserve( groupSize );
+
     for ( size_t i = 0; i < famVecPtr->size(); ++i )
     {
       DriverMED_FamilyPtr aFamily = (*famVecPtr)[i];
index 57e8edf..8317ae9 100644 (file)
@@ -33,7 +33,6 @@
 #include "MED_Wrapper.hxx"
 #include "SMDS_IteratorOnIterators.hxx"
 #include "SMDS_MeshElement.hxx"
-#include "SMDS_PolyhedralVolumeOfNodes.hxx"
 #include "SMDS_SetIterator.hxx"
 #include "SMESHDS_Mesh.hxx"
 
@@ -101,7 +100,7 @@ bool DriverMED_W_Field::Set(SMESHDS_Mesh *      mesh,
     for ( int iG = 0; iG < SMDSEntity_Last; ++iG )
     {
       SMDSAbs_EntityType  geom = (SMDSAbs_EntityType) iG;
-      SMDSAbs_ElementType t = SMDS_MeshCell::toSmdsType( geom );
+      SMDSAbs_ElementType    t = SMDS_MeshCell::ElemType( geom );
       if ( t != _elemType ) continue;
 
       nbElems = mesh->GetMeshInfo().NbElements( geom );
index 75ebf66..c33517c 100644 (file)
@@ -31,9 +31,7 @@
 #include "MED_Factory.hxx"
 #include "MED_Utilities.hxx"
 #include "SMDS_IteratorOnIterators.hxx"
-#include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
-#include "SMDS_PolyhedralVolumeOfNodes.hxx"
 #include "SMDS_SetIterator.hxx"
 #include "SMESHDS_Mesh.hxx"
 
@@ -360,10 +358,6 @@ namespace
 Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
 {
   Status aResult = DRS_OK;
-  if (myMesh->hasConstructionEdges() || myMesh->hasConstructionFaces()) {
-    INFOS("SMDS_MESH with hasConstructionEdges() or hasConstructionFaces() do not supports!!!");
-    return DRS_FAIL;
-  }
   try {
     //MESSAGE("Perform - myFile : "<<myFile);
 
@@ -408,7 +402,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
           const SMDS_MeshNode* aNode = aNodesIter->next();
           aBounds[0] = min(aBounds[0],aNode->X());
           aBounds[1] = max(aBounds[1],aNode->X());
-          
+
           aBounds[2] = min(aBounds[2],aNode->Y());
           aBounds[3] = max(aBounds[3],aNode->Y());
 
@@ -454,7 +448,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
         }
       }
 
-      SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator(/*idInceasingOrder=*/true);
+      SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
       switch ( aSpaceDimension ) {
       case 3:
         aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYZGetCoord,aXYZName));
@@ -857,7 +851,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
 
       // Treat POLYEDREs
       // ----------------
-      else if (aElemTypeData->_geomType == ePOLYEDRE )
+      else if ( aElemTypeData->_geomType == ePOLYEDRE )
       {
         elemIterator = myMesh->elementGeomIterator( SMDSGeom_POLYHEDRA );
 
@@ -865,10 +859,8 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
           // Count nb of nodes
           while ( elemIterator->more() ) {
             const SMDS_MeshElement*  anElem = elemIterator->next();
-            const SMDS_VtkVolume *aPolyedre = dynamic_cast<const SMDS_VtkVolume*>(anElem);
-            if ( !aPolyedre ) continue;
-            nbPolyhedronNodes += aPolyedre->NbNodes();
-            nbPolyhedronFaces += aPolyedre->NbFaces();
+            nbPolyhedronNodes += anElem->NbNodes();
+            nbPolyhedronFaces += anElem->NbFaces();
             if ( ++iElem == aElemTypeData->_nbElems )
               break;
           }
@@ -893,8 +885,8 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
           TInt iFace = 0, iNode = 0;
           while ( elemIterator->more() )
           {
-            const SMDS_MeshElement*  anElem = elemIterator->next();
-            const SMDS_VtkVolume *aPolyedre = dynamic_cast<const SMDS_VtkVolume*>(anElem);
+            const SMDS_MeshElement* anElem = elemIterator->next();
+            const SMDS_MeshVolume *aPolyedre = myMesh->DownCast< SMDS_MeshVolume >( anElem );
             if ( !aPolyedre ) continue;
             // index
             TInt aNbFaces = aPolyedre->NbFaces();
index a9539b9..9c24099 100644 (file)
@@ -40,6 +40,7 @@
 class SMESHDS_Mesh;
 class SMESHDS_GroupBase;
 class SMESHDS_SubMesh;
+class SMDS_MeshElement;
 
 class MESHDRIVERMED_EXPORT DriverMED_W_SMESHDS_Mesh: public Driver_SMESHDS_Mesh
 {
index ae7e48c..f1e1ea6 100644 (file)
@@ -142,6 +142,9 @@ Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::Perform()
   else
     aResult = readBinary( file );
 
+  myMesh->Modified();
+  myMesh->CompactMesh();
+
   return aResult;
 }
 
index 27576a6..10f7567 100644 (file)
@@ -93,11 +93,11 @@ namespace
 
 DriverUNV_R_SMDS_Mesh::~DriverUNV_R_SMDS_Mesh()
 {
-  if (myGroup != 0) 
-    delete myGroup;
+  TGroupNamesMap::iterator grp2name = myGroupNames.begin();
+  for ( ; grp2name != myGroupNames.end(); ++grp2name )
+    delete grp2name->first;
 }
 
-
 Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
 {
   Kernel_Utils::Localizer loc;
@@ -137,7 +137,7 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
         }
       }
       // Move nodes to SI unit system
-      const double lenFactor = aUnitsRecord.factors[ UNV164::LENGTH_FACTOR ]; 
+      const double lenFactor = aUnitsRecord.factors[ UNV164::LENGTH_FACTOR ];
       if ( lenFactor != 1. )
       {
         TDataSet::iterator nodeIter = aDataSet2411.begin(), nodeEnd;
@@ -187,23 +187,23 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
         else if(IsFace(aRec.fe_descriptor_id)) {
           //MESSAGE("add face " << aRec.label);
           switch(aRec.fe_descriptor_id){
-          case 41: // Plane Stress Linear Triangle      
-          case 51: // Plane Strain Linear Triangle      
-          case 61: // Plate Linear Triangle             
-          case 74: // Membrane Linear Triangle          
-          case 81: // Axisymetric Solid Linear Triangle 
-          case 91: // Thin Shell Linear Triangle        
+          case 41: // Plane Stress Linear Triangle
+          case 51: // Plane Strain Linear Triangle
+          case 61: // Plate Linear Triangle
+          case 74: // Membrane Linear Triangle
+          case 81: // Axisymetric Solid Linear Triangle
+          case 91: // Thin Shell Linear Triangle
             anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
                                               aRec.node_labels[1],
                                               aRec.node_labels[2],
                                               aRec.label);
             break;
 
-          case 42: //  Plane Stress Parabolic Triangle       
-          case 52: //  Plane Strain Parabolic Triangle       
-          case 62: //  Plate Parabolic Triangle              
-          case 72: //  Membrane Parabolic Triangle           
-          case 82: //  Axisymetric Solid Parabolic Triangle  
+          case 42: //  Plane Stress Parabolic Triangle
+          case 52: //  Plane Strain Parabolic Triangle
+          case 62: //  Plate Parabolic Triangle
+          case 72: //  Membrane Parabolic Triangle
+          case 82: //  Axisymetric Solid Parabolic Triangle
           case 92: //  Thin Shell Parabolic Triangle
             if ( aRec.node_labels.size() == 7 )
               anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
@@ -224,12 +224,12 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
                                                 aRec.label);
             break;
 
-          case 44: // Plane Stress Linear Quadrilateral     
-          case 54: // Plane Strain Linear Quadrilateral     
-          case 64: // Plate Linear Quadrilateral            
-          case 71: // Membrane Linear Quadrilateral         
+          case 44: // Plane Stress Linear Quadrilateral
+          case 54: // Plane Strain Linear Quadrilateral
+          case 64: // Plate Linear Quadrilateral
+          case 71: // Membrane Linear Quadrilateral
           case 84: // Axisymetric Solid Linear Quadrilateral
-          case 94: // Thin Shell Linear Quadrilateral       
+          case 94: // Thin Shell Linear Quadrilateral
             anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
                                               aRec.node_labels[1],
                                               aRec.node_labels[2],
@@ -237,12 +237,12 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
                                               aRec.label);
             break;
 
-          case 45: // Plane Stress Parabolic Quadrilateral      
-          case 55: // Plane Strain Parabolic Quadrilateral      
-          case 65: // Plate Parabolic Quadrilateral             
-          case 75: // Membrane Parabolic Quadrilateral          
-          case 85: // Axisymetric Solid Parabolic Quadrilateral 
-          case 95: // Thin Shell Parabolic Quadrilateral        
+          case 45: // Plane Stress Parabolic Quadrilateral
+          case 55: // Plane Strain Parabolic Quadrilateral
+          case 65: // Plate Parabolic Quadrilateral
+          case 75: // Membrane Parabolic Quadrilateral
+          case 85: // Axisymetric Solid Parabolic Quadrilateral
+          case 95: // Thin Shell Parabolic Quadrilateral
             if ( aRec.node_labels.size() == 9 )
               anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
                                                 aRec.node_labels[2],
@@ -295,7 +295,7 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
                                                 aRec.node_labels[7],
                                                 aRec.label);
             break;
-            
+
           case 112: // Solid Linear Prism - PRISM6
             anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
                                                 aRec.node_labels[2],
@@ -305,7 +305,7 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
                                                 aRec.node_labels[4],
                                                 aRec.label);
             break;
-            
+
           case 113: // Solid Quadratic Prism - PRISM15
             anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
                                                 aRec.node_labels[4],
@@ -328,7 +328,7 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
                                                 aRec.node_labels[7],
                                                 aRec.label);
             break;
-            
+
           case 115: // Solid Linear Brick - HEX8
             anElement = myMesh->AddVolumeWithID(aRec.node_labels[0],
                                                 aRec.node_labels[3],
@@ -396,101 +396,63 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
       }
     }
     {
-      using namespace UNV2417;      
+      using namespace UNV2417;
       TDataSet aDataSet2417;
       UNV2417::Read(in_stream,aDataSet2417);
       if(MYDEBUG) MESSAGE("Perform - aDataSet2417.size() = "<<aDataSet2417.size());
-      if  (aDataSet2417.size() > 0) {
-        myGroup = new SMDS_MeshGroup(myMesh);
+      if (aDataSet2417.size() > 0)
+      {
         TDataSet::const_iterator anIter = aDataSet2417.begin();
-        for(; anIter != aDataSet2417.end(); anIter++){
-          const TGroupId& aLabel = anIter->first;
+        for ( ; anIter != aDataSet2417.end(); anIter++ )
+        {
           const TRecord& aRec = anIter->second;
-
-          int aNodesNb = aRec.NodeList.size();
-          int aElementsNb = aRec.ElementList.size();
+          int        aNodesNb = aRec.NodeList.size();
+          int     aElementsNb = aRec.ElementList.size();
 
           bool useSuffix = ((aNodesNb > 0) && (aElementsNb > 0));
-          int i;
-          if (aNodesNb > 0) {
-            SMDS_MeshGroup* aNodesGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Node);
+          if ( aNodesNb > 0 )
+          {
+            SMDS_MeshGroup* aNodesGroup = new SMDS_MeshGroup( myMesh );
             std::string aGrName = (useSuffix) ? aRec.GroupName + "_Nodes" : aRec.GroupName;
             int i = aGrName.find( "\r" );
             if (i > 0)
               aGrName.erase (i, 2);
-            myGroupNames.insert(TGroupNamesMap::value_type(aNodesGroup, aGrName));
-            myGroupId.insert(TGroupIdMap::value_type(aNodesGroup, aLabel));
+            myGroupNames.insert( std::make_pair( aNodesGroup, aGrName ));
 
-            for (i = 0; i < aNodesNb; i++) {
-              const SMDS_MeshNode* aNode = myMesh->FindNode(aRec.NodeList[i]);
-              if (aNode)
-                aNodesGroup->Add(aNode);
-            }
+            for ( int i = 0; i < aNodesNb; i++ )
+              if ( const SMDS_MeshNode* aNode = myMesh->FindNode( aRec.NodeList[i] ))
+                aNodesGroup->Add( aNode );
           }
-          if (aElementsNb > 0){
-            SMDS_MeshGroup* aEdgesGroup = 0;
-            SMDS_MeshGroup* aFacesGroup = 0;
-            SMDS_MeshGroup* aVolumeGroup = 0;
+          if ( aElementsNb > 0 )
+          {
+            std::vector< SMDS_MeshGroup* > aGroupVec( SMDSAbs_NbElementTypes, (SMDS_MeshGroup*)0 );
+            const char* aSuffix[] = { "", "", "_Edges", "_Faces", "_Volumes", "_0D", "_Balls" };
             bool createdGroup = false;
-
-            for (i = 0; i < aElementsNb; i++) {
-              const SMDS_MeshElement* aElement = myMesh->FindElement(aRec.ElementList[i]);
-              if (aElement) {
-                switch (aElement->GetType()) {
-
-                case SMDSAbs_Edge:
-                  if (!aEdgesGroup) {
-                    aEdgesGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Edge);
-                    if (!useSuffix && createdGroup) useSuffix = true;
-                    std::string aEdgesGrName = (useSuffix) ? aRec.GroupName + "_Edges" : aRec.GroupName;
-                    int i = aEdgesGrName.find( "\r" );
-                    if (i > 0)
-                      aEdgesGrName.erase (i, 2);
-                    myGroupNames.insert(TGroupNamesMap::value_type(aEdgesGroup, aEdgesGrName));
-                    myGroupId.insert(TGroupIdMap::value_type(aEdgesGroup, aLabel));
-                    createdGroup = true;
-                  }
-                  aEdgesGroup->Add(aElement);
-                  break;
-
-                case SMDSAbs_Face:
-                  if (!aFacesGroup) {
-                    aFacesGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Face);
-                    if (!useSuffix && createdGroup) useSuffix = true;
-                    std::string aFacesGrName = (useSuffix) ? aRec.GroupName + "_Faces" : aRec.GroupName;
-                    int i = aFacesGrName.find( "\r" );
-                    if (i > 0)
-                      aFacesGrName.erase (i, 2);
-                    myGroupNames.insert(TGroupNamesMap::value_type(aFacesGroup, aFacesGrName));
-                    myGroupId.insert(TGroupIdMap::value_type(aFacesGroup, aLabel));
-                    createdGroup = true;
-                  }
-                  aFacesGroup->Add(aElement);
-                  break;
-
-                case SMDSAbs_Volume:
-                  if (!aVolumeGroup) {
-                    aVolumeGroup = (SMDS_MeshGroup*) myGroup->AddSubGroup(SMDSAbs_Volume);
-                    if (!useSuffix && createdGroup) useSuffix = true;
-                    std::string aVolumeGrName = (useSuffix) ? aRec.GroupName + "_Volumes" : aRec.GroupName;
-                    int i = aVolumeGrName.find( "\r" );
-                    if (i > 0)
-                      aVolumeGrName.erase (i, 2);
-                    myGroupNames.insert(TGroupNamesMap::value_type(aVolumeGroup, aVolumeGrName));
-                    myGroupId.insert(TGroupIdMap::value_type(aVolumeGroup, aLabel));
-                    createdGroup = true;
-                  }
-                  aVolumeGroup->Add(aElement);
-                  break;
-
-                default:;
-                }
-              } 
+            for ( int i = 0; i < aElementsNb; i++)
+            {
+              const SMDS_MeshElement* aElement = myMesh->FindElement( aRec.ElementList[i] );
+              if ( !aElement ) continue;
+
+              SMDS_MeshGroup * & aGroup = aGroupVec[ aElement->GetType() ];
+              if ( !aGroup )
+              {
+                aGroup = new SMDS_MeshGroup( myMesh );
+                if (!useSuffix && createdGroup) useSuffix = true;
+                std::string aGrName = aRec.GroupName;
+                int i = aGrName.find( "\r" );
+                if ( i > 0 )
+                  aGrName.erase (i, 2);
+                if ( useSuffix )
+                  aGrName += aSuffix[ aElement->GetType() ];
+                myGroupNames.insert( std::make_pair( aGroup, aGrName ));
+                createdGroup = true;
+              }
+              aGroup->Add(aElement);
             }
           }
         }
       }
-    } 
+    }
   }
   catch(const std::exception& exc){
     INFOS("Follow exception was cought:\n\t"<<exc.what());
@@ -499,6 +461,9 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
     INFOS("Unknown exception was cought !!!");
   }
   if (myMesh)
-    myMesh->compactMesh();
+  {
+    myMesh->Modified();
+    myMesh->CompactMesh();
+  }
   return aResult;
 }
index 4f7407d..42de629 100644 (file)
 #include <string>
 
 
-class SMDS_Mesh;
 class SMDS_MeshGroup;
 
-
-typedef std::map<SMDS_MeshGroup*, std::string> TGroupNamesMap;
-typedef std::map<SMDS_MeshGroup*, int> TGroupIdMap;
-
 typedef std::map<SMDS_MeshGroup*, std::string> TGroupNamesMap;
-typedef std::map<SMDS_MeshGroup*, int> TGroupIdMap;
 
 class MESHDRIVERUNV_EXPORT DriverUNV_R_SMDS_Mesh: public Driver_SMDS_Mesh
 {
  public:
-  DriverUNV_R_SMDS_Mesh():Driver_SMDS_Mesh(),myGroup(0) {};
+  DriverUNV_R_SMDS_Mesh():Driver_SMDS_Mesh() {};
   ~DriverUNV_R_SMDS_Mesh();
+
   virtual Status Perform();
 
-  const SMDS_MeshGroup* GetGroup()         const { return myGroup;}
-  const TGroupNamesMap& GetGroupNamesMap() const { return myGroupNames; }
-  const TGroupIdMap&    GetGroupIdMap() const { return myGroupId; }
+  TGroupNamesMap& GetGroupNamesMap() { return myGroupNames; }
 
  private:
-  SMDS_MeshGroup* myGroup;
   TGroupNamesMap myGroupNames;
-  TGroupIdMap    myGroupId;
 };
 
 #endif
index d8bca84..02ec758 100644 (file)
@@ -25,9 +25,6 @@
 #include "DriverUNV_W_SMDS_Mesh.h"
 
 #include "SMDS_Mesh.hxx"
-#include "SMDS_QuadraticEdge.hxx"
-#include "SMDS_QuadraticFaceOfNodes.hxx"
-#include "SMDS_PolyhedralVolumeOfNodes.hxx"
 #include "SMESHDS_GroupBase.hxx"
 
 #include "utilities.h"
index c286848..183c0e4 100644 (file)
@@ -25,8 +25,8 @@
 
 #include <map>
 #include <vector>
-#include <fstream>      
-#include <string>       
+#include <fstream>
+#include <string>
 
 
 namespace UNV2417{
@@ -34,9 +34,9 @@ namespace UNV2417{
   typedef std::vector<int> TListOfId; // Nodal connectivitiesList of Id
 
   struct TRecord{
-    std::string    GroupName;
-    TListOfId NodeList;
-    TListOfId ElementList;
+    std::string GroupName;
+    TListOfId   NodeList;
+    TListOfId   ElementList;
   };
 
   typedef int TGroupId; // type of element label
index a1a69ff..3f64bf4 100644 (file)
@@ -31,7 +31,6 @@
 #include "SMDS_BallElement.hxx"
 #include "SMDS_Mesh.hxx"
 #include "SMDS_MeshCell.hxx"
-#include "SMDS_PolyhedralVolumeOfNodes.hxx"
 #include "SMESHDS_Mesh.hxx"
 #include "SMESHDS_Script.hxx"
 #include "SMESH_Actor.h"
@@ -81,54 +80,6 @@ static int MYDEBUGWITHFILES = 0;
   Class       : SMESH_VisualObjDef
   Description : Base class for all mesh objects to be visuilised
 */
-
-//=================================================================================
-// function : getCellType
-// purpose  : Get type of VTK cell
-//=================================================================================
-// static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
-//                                      const bool                thePoly,
-//                                      const int                 theNbNodes )
-// {
-//   switch( theType )
-//   {
-//     case SMDSAbs_0DElement:         return VTK_VERTEX;
-
-//     case SMDSAbs_Ball:              return VTK_POLY_VERTEX;
-
-//     case SMDSAbs_Edge: 
-//       if( theNbNodes == 2 )         return VTK_LINE;
-//       else if ( theNbNodes == 3 )   return VTK_QUADRATIC_EDGE;
-//       else return VTK_EMPTY_CELL;
-
-//     case SMDSAbs_Face  :
-//       if (thePoly && theNbNodes>2 ) return VTK_POLYGON;
-//       else if ( theNbNodes == 3 )   return VTK_TRIANGLE;
-//       else if ( theNbNodes == 4 )   return VTK_QUAD;
-//       else if ( theNbNodes == 6 )   return VTK_QUADRATIC_TRIANGLE;
-//       else if ( theNbNodes == 8 )   return VTK_QUADRATIC_QUAD;
-//       else if ( theNbNodes == 9 )   return VTK_BIQUADRATIC_QUAD;
-//       else if ( theNbNodes == 7 )   return VTK_BIQUADRATIC_TRIANGLE;
-//       else return VTK_EMPTY_CELL;
-      
-//     case SMDSAbs_Volume:
-//       if (thePoly && theNbNodes>3 ) return VTK_POLYHEDRON; //VTK_CONVEX_POINT_SET;
-//       else if ( theNbNodes == 4 )   return VTK_TETRA;
-//       else if ( theNbNodes == 5 )   return VTK_PYRAMID;
-//       else if ( theNbNodes == 6 )   return VTK_WEDGE;
-//       else if ( theNbNodes == 8 )   return VTK_HEXAHEDRON;
-//       else if ( theNbNodes == 12 )  return VTK_HEXAGONAL_PRISM;
-//       else if ( theNbNodes == 10 )  return VTK_QUADRATIC_TETRA;
-//       else if ( theNbNodes == 20 )  return VTK_QUADRATIC_HEXAHEDRON;
-//       else if ( theNbNodes == 27 )  return VTK_TRIQUADRATIC_HEXAHEDRON;
-//       else if ( theNbNodes == 15 )  return VTK_QUADRATIC_WEDGE;
-//       else if ( theNbNodes == 13 )  return VTK_QUADRATIC_PYRAMID; //VTK_CONVEX_POINT_SET;
-//       else return VTK_EMPTY_CELL;
-
-//     default: return VTK_EMPTY_CELL;
-//   }
-// }
-
 //=================================================================================
 // functions : SMESH_VisualObjDef
 // purpose   : Constructor
@@ -178,7 +129,7 @@ vtkIdType SMESH_VisualObjDef::GetNodeVTKId( int theObjID )
   if( this->GetMesh() ) {
     aNode = this->GetMesh()->FindNode(theObjID);
   }
-  return aNode ? aNode->getVtkId() : -1;
+  return aNode ? aNode->GetVtkID() : -1;
 }
 
 vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID )
@@ -188,7 +139,7 @@ vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID )
     TMapOfIds::const_iterator i = myVTK2SMDSElems.find(theVTKID);
     return i == myVTK2SMDSElems.end() ? -1 : i->second;
   }
-  return this->GetMesh()->fromVtkToSmds(theVTKID);
+  return this->GetMesh()->FromVtkToSmds(theVTKID);
 }
 
 vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID )
@@ -203,7 +154,7 @@ vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID )
   if ( this->GetMesh() )
     e = this->GetMesh()->FindElement(theObjID);
 
-  return e ? e->getVtkId() : -1;
+  return e ? e->GetVtkID() : -1;
 }
 
 //=================================================================================
@@ -280,15 +231,15 @@ void SMESH_VisualObjDef::buildPrs(bool buildGrid)
   else
   {
     myLocalGrid = false;
-    if (!GetMesh()->isCompacted())
+    if (!GetMesh()->IsCompacted())
     {
       NulData(); // detach from the SMDS grid to allow immediate memory de-allocation in compactMesh()
       if ( MYDEBUG ) MESSAGE("*** buildPrs ==> compactMesh!");
-      GetMesh()->compactMesh();
+      GetMesh()->CompactMesh();
       if ( SMESHDS_Mesh* m = dynamic_cast<SMESHDS_Mesh*>( GetMesh() )) // IPAL53915
         m->GetScript()->SetModified(false); // drop IsModified set in compactMesh()
     }
-    vtkUnstructuredGrid *theGrid = GetMesh()->getGrid();
+    vtkUnstructuredGrid *theGrid = GetMesh()->GetGrid();
     updateEntitiesFlags();
     myGrid->ShallowCopy(theGrid);
     //MESSAGE(myGrid->GetReferenceCount());
@@ -395,17 +346,16 @@ void SMESH_VisualObjDef::buildElemPrs()
         if((*anIter)->GetEntityType() != SMDSEntity_Polyhedra &&
            (*anIter)->GetEntityType() != SMDSEntity_Quad_Polyhedra) {
           aCellsSize += (*anIter)->NbNodes() + 1;
-        } 
+        }
         // Special case for the VTK_POLYHEDRON:
         // itsinput cellArray is of special format.
-        //  [nCellFaces, nFace0Pts, i, j, k, nFace1Pts, i, j, k, ...]   
+        //  [nCellFaces, nFace0Pts, i, j, k, nFace1Pts, i, j, k, ...]
         else {
-          if( const SMDS_VtkVolume* ph = dynamic_cast<const SMDS_VtkVolume*>(*anIter) ) {
+          if ( const SMDS_MeshVolume* ph = SMDS_Mesh::DownCast<SMDS_MeshVolume>( *anIter )) {
             int nbFaces = ph->NbFaces();
             aCellsSize += (1 + ph->NbFaces());
-            for( int i = 1; i <= nbFaces; i++ ) {
+            for( int i = 1; i <= nbFaces; i++ )
               aCellsSize += ph->NbFaceNodes(i);
-            }
           }
         }
       }
@@ -467,16 +417,14 @@ void SMESH_VisualObjDef::buildElemPrs()
 
           if (aType == SMDSAbs_Volume && anElem->IsPoly() && aNbNodes > 3) { // POLYEDRE
             anIdList->Reset();
-            if ( const SMDS_VtkVolume* ph = dynamic_cast<const SMDS_VtkVolume*>(anElem) ) {
+            if ( const SMDS_MeshVolume* ph = SMDS_Mesh::DownCast<SMDS_MeshVolume>( anElem )) {
               int nbFaces = ph->NbFaces();
               anIdList->InsertNextId(nbFaces);
               for( int i = 1; i <= nbFaces; i++ ) {
                 anIdList->InsertNextId(ph->NbFaceNodes(i));
                 for(int j = 1; j <= ph->NbFaceNodes(i); j++) {
-                  const SMDS_MeshNode* n = ph->GetFaceNode(i,j);
-                  if(n) {
-                    anIdList->InsertNextId(mySMDS2VTKNodes[n->GetID()]);
-                  }
+                  if ( const SMDS_MeshNode* n = ph->GetFaceNode( i, j ))
+                    anIdList->InsertNextId( mySMDS2VTKNodes[ n->GetID() ]);
                 }
               }
             }
@@ -504,11 +452,8 @@ void SMESH_VisualObjDef::buildElemPrs()
         //Store diameters of the balls
         if(aScalars) {
           double aDiam = 0;
-          if(aType == SMDSAbs_Ball) {
-            if (const SMDS_BallElement* ball = dynamic_cast<const SMDS_BallElement*>(anElem) ) {
-              aDiam = ball->GetDiameter();
-            }
-          }
+          if (const SMDS_BallElement* ball = SMDS_Mesh::DownCast<SMDS_BallElement>(anElem) )
+            aDiam = ball->GetDiameter();
           aScalars->SetTuple(aCurId,&aDiam);
         }
 
@@ -573,14 +518,14 @@ bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
 
 vtkUnstructuredGrid* SMESH_VisualObjDef::GetUnstructuredGrid()
 {
-  if ( !myLocalGrid && !GetMesh()->isCompacted() )
+  if ( !myLocalGrid && !GetMesh()->IsCompacted() )
   {
-    NulData(); // detach from the SMDS grid to allow immediate memory de-allocation in compactMesh()
-    GetMesh()->compactMesh();
+    NulData(); // detach from the SMDS grid to allow immediate memory de-allocation in CompactMesh()
+    GetMesh()->CompactMesh();
     if ( SMESHDS_Mesh* m = dynamic_cast<SMESHDS_Mesh*>( GetMesh() )) // IPAL53915
-      m->GetScript()->SetModified(false); // drop IsModified set in compactMesh()
+      m->GetScript()->SetModified(false); // drop IsModified set in CompactMesh()
     updateEntitiesFlags();
-    vtkUnstructuredGrid *theGrid = GetMesh()->getGrid();
+    vtkUnstructuredGrid *theGrid = GetMesh()->GetGrid();
     myGrid->ShallowCopy(theGrid);
   }
   return myGrid;
index e46dbf8..d05091e 100644 (file)
@@ -42,96 +42,72 @@ SET(_link_LIBRARIES
 # header files / no moc processing
 SET(SMDS_HEADERS
   ObjectPool.hxx
-  SMDS_TypeOfPosition.hxx
   SMDSAbs_ElementType.hxx
+  SMDS_BallElement.hxx
+  SMDS_CellOfNodes.hxx
+  SMDS_Downward.hxx
   SMDS_EdgePosition.hxx
   SMDS_ElemIterator.hxx
+  SMDS_ElementFactory.hxx
+  SMDS_FaceOfNodes.hxx
   SMDS_FacePosition.hxx
+  SMDS_Iterator.hxx
+  SMDS_IteratorOnIterators.hxx
+  SMDS_LinearEdge.hxx
   SMDS_Mesh.hxx
   SMDS_Mesh0DElement.hxx
-  SMDS_LinearEdge.hxx
+  SMDS_MeshCell.hxx
   SMDS_MeshEdge.hxx
   SMDS_MeshElement.hxx
-  SMDS_MeshElementIDFactory.hxx
-  SMDS_MeshCell.hxx
   SMDS_MeshFace.hxx
   SMDS_MeshGroup.hxx
-  SMDS_MeshIDFactory.hxx
+  SMDS_MeshInfo.hxx
   SMDS_MeshNode.hxx
-  SMDS_MeshNodeIDFactory.hxx
   SMDS_MeshObject.hxx
   SMDS_MeshVolume.hxx
+  SMDS_PolygonalFaceOfNodes.hxx
   SMDS_Position.hxx
+  SMDS_SetIterator.hxx
   SMDS_SpacePosition.hxx
+  SMDS_StdIterator.hxx
+  SMDS_TypeOfPosition.hxx
+  SMDS_UnstructuredGrid.hxx
   SMDS_VertexPosition.hxx
-  SMDS_Iterator.hxx
-  SMDS_IteratorOfElements.hxx
-  SMDS_VolumeOfFaces.hxx
   SMDS_VolumeOfNodes.hxx
-  SMDS_VtkEdge.hxx
-  SMDS_VtkFace.hxx
-  SMDS_VtkVolume.hxx
-  SMDS_VtkCellIterator.hxx
-  SMDS_PolyhedralVolumeOfNodes.hxx
-  SMDS_FaceOfEdges.hxx
-  SMDS_FaceOfNodes.hxx
-  SMDS_PolygonalFaceOfNodes.hxx
   SMDS_VolumeTool.hxx
-  SMDS_QuadraticEdge.hxx
-  SMDS_QuadraticFaceOfNodes.hxx
-  SMDS_QuadraticVolumeOfNodes.hxx
-  SMDS_SetIterator.hxx
+  SMDS_VtkCellIterator.hxx
+  SMDS_ElementHolder.hxx
   SMESH_SMDS.hxx
-  SMDS_MeshInfo.hxx
-  SMDS_UnstructuredGrid.hxx
-  SMDS_Downward.hxx
-  SMDS_StdIterator.hxx
-  SMDS_IteratorOnIterators.hxx
-  SMDS_BallElement.hxx
-)
+  chrono.hxx
+  )
 
 # --- sources ---
 
 # sources / static
 SET(SMDS_SOURCES
-  chrono.cxx
-  SMDS_MeshObject.cxx
-  SMDS_MeshElement.cxx
-  SMDS_MeshCell.cxx
-  SMDS_Position.cxx
-  SMDS_EdgePosition.cxx
+  SMDS_BallElement.cxx
+  SMDS_Downward.cxx
+  SMDS_CellOfNodes.cxx
+  SMDS_ElementFactory.cxx
+  SMDS_FaceOfNodes.cxx
   SMDS_FacePosition.cxx
-  SMDS_SpacePosition.cxx
-  SMDS_VertexPosition.cxx
-  SMDS_MeshNode.cxx
-  SMDS_Mesh0DElement.cxx
   SMDS_LinearEdge.cxx
-  SMDS_MeshEdge.cxx
-  SMDS_MeshFace.cxx
-  SMDS_MeshVolume.cxx
-  SMDS_MeshNodeIDFactory.cxx
-  SMDS_MeshElementIDFactory.cxx
-  SMDS_MeshGroup.cxx
-  SMDS_MeshIDFactory.cxx
+  SMDS_MemoryLimit.cxx
   SMDS_Mesh.cxx
-  SMDS_IteratorOfElements.cxx
-  SMDS_VolumeOfFaces.cxx
-  SMDS_VolumeOfNodes.cxx
-  SMDS_VtkEdge.cxx
-  SMDS_VtkFace.cxx
-  SMDS_VtkVolume.cxx
-  SMDS_VtkCellIterator.cxx
-  SMDS_PolyhedralVolumeOfNodes.cxx
-  SMDS_FaceOfEdges.cxx
-  SMDS_FaceOfNodes.cxx
+  SMDS_MeshCell.cxx
+  SMDS_MeshElement.cxx
+  SMDS_MeshGroup.cxx
+  SMDS_MeshNode.cxx
+  SMDS_MeshObject.cxx
+  SMDS_MeshVolume.cxx
   SMDS_PolygonalFaceOfNodes.cxx
-  SMDS_VolumeTool.cxx
-  SMDS_QuadraticEdge.cxx
-  SMDS_QuadraticFaceOfNodes.cxx
-  SMDS_QuadraticVolumeOfNodes.cxx
+  SMDS_SpacePosition.cxx
   SMDS_UnstructuredGrid.cxx
-  SMDS_Downward.cxx
-  SMDS_BallElement.cxx 
+  SMDS_VolumeOfNodes.cxx
+  SMDS_VolumeTool.cxx
+  SMDS_VtkCellIterator.cxx
+  SMDS_ElementHolder.cxx
+  chrono.cxx
 )
 
 # bin programs
diff --git a/src/SMDS/Notes b/src/SMDS/Notes
deleted file mode 100644 (file)
index 830ffb5..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
---> Branche V6_main
-
-Problemes en cours
-==================
-- a faire
-+ en cours, OK mais perfectible
-* OK
-
-+ visualisation de groupe (type d'element): on voit tout le maillage, mais le groupe est OK
-  creation d'une structure vtkUnstructuredGrid locale : iteration un peu lourde, et pas de partage avec la structure du maillage (pas evident)
-- inversion d'un volume (tetra): exception
-- script de creation de noeuds et d'elements: OK, mais pas compatible avec version precedente (numerotation noeuds differente)
-+ affichage numeros noeuds: numeros en trop sur (O,0,0) pas systematique, trouver la condition (enlever dans vtkUnstructuredGrid ?)
-  ==> purge systematique noeuds et cellules en trop dans compactage grid.
-+ gestion du mode embedded mal faite lors d'un script python : journal commandes intempestif
-- affichage des noeuds apres changement lineaire <--> quadratique √† l'IHM : pas pris en compte, alors que maillage OK,
-  mais script OK
-  ==> cass√© apres mode embedded ou elimination noeuds en trop ?
-- extrusion elements 2D along a path : affichage apres calcul pas toujours OK (filaire)
-- branche git a ouvrir pour merge avec V5_1_4_BR tag V5_1_4rc1
-
-A tester, non pris en compte
-============================
-- engine standalone
-- polyedres (attendre vtk)
-
-
-=============================== Hypothese de refonte de l'API de SMDS
-
-n'utiliser que vtkUnstructuredGrid, ne pas avor d'objets SMDS_MeshElement mais seulement des index de vtkUnstructuredGrid.
-2987 usages de SMDS_MeshNodes
-810            SMDS_MeshElement
-...
-==> en dernier ressort, lourd
-================================================================================
-
-Essai a API SMDS a peu pres constante
-=====================================
-
-SMDS_Mesh
-  static vector<SMDS_Mesh*> _meshList;     --> retrouver un SMDS_Mesh
-  vtkUnstructuredGrid*      myGrid;
-
-  vector<SMDS_MeshNode *>   myNodes;       --> meme index que dans le pointSet de myGrid
-  vector<SMDS_MeshCell *>   myCells;       --> index = ID client, pas le meme index que dans le cellTypes de myGrid (ID vtk)
-
-
-
-SMDS_MeshElement
-  int myID;                                --> index dans la structure geree par SMDS_Mesh
-  int myMeshId;                            --> pour retrouver SMDS_Mesh* dans _meshList
-  int myShapeId;                           --> pour retrouver la subShape
-                                                         
-
-SMDS_MeshNode: SMDS_MeshElement
-  SMDS_PositionPtr myPosition;             -->  A REVOIR : objet position dans la shape geom
-  ##vector<int> myInverseElements;         -->  SUPPRIME : pour retrouver les elements, vtkCellLinks
-
-
-SMDS_MeshCell: SMDS_MeshElement            --> generique pour tous les elements (cells)
-  int myVtkID                              --> A SUPPRIMER
-
-SMDS_MeshVolume: SMDS_MeshCell
-
-SMDS_VolumeOfNodes: SMDS_MeshVolume        --> Garder temporairement, utilisation dans StdMesher et SMDS_VolumeTool
-  const SMDS_MeshNode **myNodes;           --> Couteux
-  int                 myNbNodes;           -->  ""
-
-SMDS_VolumeVtkNodes: SMDS_MeshVolume       --> Utiliser systematiquement dans SMDS,
-                                           --> IMPLEMENTER.
-
-
-SMDS_MeshElementIDFactory: SMDS_MeshNodeIDFactory
-  vector<int> myIDElements; // index = ID client, value = ID vtk  --> A SUPPRIMER, ne sert que dans SMDS_MeshElementIDFactory
-  vector<int> myVtkIndex;   // index = ID vtk, value = ID client  --> A REPORTER dans SMDS_Mesh
-
-
-
-
-========= TODO ============
-
-enlever vtkId de SMDS_MeshCell, utiliser SMDS_MeshElementIDFactory.
-
-ajouter ID dans SMDS_Mesh::createTriangle 
-verifier ID dans SMDS_Mesh::Find*OrCreate
-
-===================================================
-occupation memoire cube 100*100*100 sans affichage
-NOTES:
-- sur Debian Sarge 64 bits, les mesures malloc_stat() semblent coherentes
-  avec une mesure externe globale(recherche du passage en swap du process).
-- sur Ubuntu 9.10 64 bits, les mesures malloc_stat() donnent des resultats bizarres (surestimation ?),
-  mais la mesure avec l'outil KDE de surveillance systeme est OK avec la recherche du swap.
-
-
-Reference : V513 Debian Sarge 64 bits: --> 463 - 33 = 430 Mo
--------------------------------------
-Total (incl. mmap):
-system bytes     =   43757568
-in use bytes     =   32909584 = 33M
-max mmap regions =         41
-max mmap bytes   =   16371712
-----
-Total (incl. mmap):
-system bytes     =  464670720
-in use bytes     =  463105120 = 463M
-max mmap regions =         47
-max mmap bytes   =   28188672
-
-Debian Sarge 64 bits, vtkUnstructuredGrid nodes et hexa, 4 janvier 2010 --> 512 - 41 = 471M
------------------------------------
-
-Total (incl. mmap):
-system bytes     =   52133888
-in use bytes     =   41340320 : 41M
-max mmap regions =         72
-max mmap bytes   =   24625152
-----
-Total (incl. mmap):
-system bytes     =  520560640
-in use bytes     =  518735584 : 512M
-max mmap regions =         88
-max mmap bytes   =  198385664
-
-idem avec pool SMDS_MeshNodes --> 483 -33 = 450M
------------------------------
-Total (incl. mmap):
-system bytes     =   43696128
-in use bytes     =   32915184 : 33M 
-max mmap regions =         41
-max mmap bytes   =   16371712
-----
-Total (incl. mmap):
-system bytes     =  484806656
-in use bytes     =  482980992 : 483M
-max mmap regions =         58
-max mmap bytes   =  184557568
-
-idem ci-dessus + pool SMDS_VolumeVtkNodes --> 475 -33 = 442M (git: add ObjectPool.hxx)
------------------------------------------
-
-Total (incl. mmap):
-system bytes     =   43200512
-in use bytes     =   32908576 : 33M
-max mmap regions =         41
-max mmap bytes   =   16371712
-----
-Total (incl. mmap):
-system bytes     =  478068736
-in use bytes     =  475144400 : 475M
-max mmap regions =         59
-max mmap bytes   =  184692736
-
-remplacement SMDS_PositionPtr: (boost::shared_ptr<SMDS_Position> --> SMDS_Position*) --> 436 - 35 = 401M (git SMDS_Position)
-------------------------------------------------------------------------------------
-Total (incl. mmap):
-system bytes     =   45408256
-in use bytes     =   35097680 : 35M
-max mmap regions =         47
-max mmap bytes   =   18116608
-----
-Total (incl. mmap):
-system bytes     =  438935552
-in use bytes     =  436116560 : 436M
-max mmap regions =         65
-max mmap bytes   =  186437632
-
-simplification SMDS_SpacePosition (pas de double[3]) --> 418 -33 = 385M (git SMDS_SpacePosition)
-----------------------------------------------------
-Total (incl. mmap):
-system bytes     =   42582016
-in use bytes     =   32883552 : 33M
-max mmap regions =         41
-max mmap bytes   =   16371712
-----
-Total (incl. mmap):
-system bytes     =  421728256
-in use bytes     =  418378000 : 418M
-max mmap regions =         58
-max mmap bytes   =  183640064
-
-sizeof(SMDS_MeshElement) 16
-sizeof(SMDS_MeshNode) 24
-sizeof(SMDS_MeshCell) 24
-sizeof(SMDS_VolumeVtkNodes) 24
-sizeof(SMDS_Position) 16
-sizeof(SMDS_SpacePosition) 16
-
-impact d'un int en plus dans SMDS_MeshElement --> 426 - 33 = 393M
----------------------------------------------
-
-sizeof(SMDS_MeshElement) 24
-sizeof(SMDS_MeshNode) 32       --> on retrouve bien les 8M
-sizeof(SMDS_MeshCell) 24
-sizeof(SMDS_VolumeVtkNodes) 24
-sizeof(SMDS_Position) 16
-sizeof(SMDS_SpacePosition) 16
-
-Total (incl. mmap):
-system bytes     =   43192320
-in use bytes     =   32681088 : 33M
-max mmap regions =         41
-max mmap bytes   =   16371712
-----
-Total (incl. mmap):
-system bytes     =  429334528
-in use bytes     =  426424576 : 426M
-max mmap regions =         59
-max mmap bytes   =  184692736
-
-remplacement std::set par std::vector dans SMESHDS_SubMesh --> 347 - 35 = 312M
-----------------------------------------------------------
-sizeof(SMDS_MeshElement) 24
-sizeof(SMDS_MeshNode) 32
-sizeof(SMDS_MeshCell) 24
-sizeof(SMDS_VolumeVtkNodes) 24
-sizeof(SMDS_Position) 16
-sizeof(SMDS_SpacePosition) 16
-
-Total (incl. mmap):
-system bytes     =   45404160
-in use bytes     =   35132160 --> 35M
-max mmap regions =         49
-max mmap bytes   =   17723392
-----
-Total (incl. mmap):
-system bytes     =  349831168
-in use bytes     =  346885424 --> 347M
-max mmap regions =         73
-max mmap bytes   =  204148736
-
-Ce resultat est coherent avec une recherche de swap sur une machine a 8Go de memoire:
-Cube a 270**3 mailles (~20M mailles) --> 6.2 Go (idem Debian Sarge et Ubuntu 9.10, 64 bits)
-Le meme avec V5.1.3 --> 14 Go (swap)
-
index ef514b3..d7eea28 100644 (file)
@@ -28,9 +28,9 @@
 namespace
 {
   // assure deallocation of memory of a vector
-  template<class Y> void clearVector(std::vector<Y>& v )
+  template<class Y> void clearVector(& v )
   {
-    std::vector<Y> emptyVec; v.swap( emptyVec );
+    Y emptyVec; v.swap( emptyVec );
   }
 }
 
index fd38596..7a10f79 100644 (file)
 
 #include "SMDS_BallElement.hxx"
 
-#include "SMDS_ElemIterator.hxx"
 #include "SMDS_Mesh.hxx"
 #include "SMDS_MeshNode.hxx"
-#include "SMDS_VtkCellIterator.hxx"
 
-SMDS_BallElement::SMDS_BallElement()
+void SMDS_BallElement::init(const SMDS_MeshNode * node, double diameter )
 {
-  SMDS_MeshCell::init();
-}
-
-SMDS_BallElement::SMDS_BallElement (const SMDS_MeshNode * node, double diameter)
-{
-  init( node->getVtkId(), diameter, SMDS_Mesh::_meshList[ node->getMeshId() ] );
-}
-
-SMDS_BallElement::SMDS_BallElement(vtkIdType nodeId, double diameter, SMDS_Mesh* mesh)
-{
-  init( nodeId, diameter, mesh );
-}
-
-void SMDS_BallElement::init(vtkIdType nodeId, double diameter, SMDS_Mesh* mesh)
-{
-  SMDS_MeshCell::init();
-  myMeshId = mesh->getMeshId();
-  myVtkID = mesh->getGrid()->InsertNextLinkedCell( GetVtkType(), 1, &nodeId );
-  mesh->getGrid()->SetBallDiameter( myVtkID, diameter );
-  mesh->setMyModified();
+  int nodeVtkID = node->GetVtkID();
+  int vtkID = getGrid()->InsertNextLinkedCell( toVtkType( SMDSEntity_Ball ), 1, &nodeVtkID );
+  setVtkID( vtkID );
+  getGrid()->SetBallDiameter( GetVtkID(), diameter );
 }
 
 double SMDS_BallElement::GetDiameter() const
 {
-  return SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetBallDiameter( myVtkID );
+  return getGrid()->GetBallDiameter( GetVtkID() );
 }
 
 void SMDS_BallElement::SetDiameter(double diameter)
 {
-  SMDS_Mesh::_meshList[myMeshId]->getGrid()->SetBallDiameter( myVtkID, diameter );
-}
-
-bool SMDS_BallElement::ChangeNode (const SMDS_MeshNode * node)
-{
-  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
-  vtkIdType npts = 0;
-  vtkIdType* pts = 0;
-  grid->GetCellPoints(myVtkID, npts, pts);
-  pts[0] = node->getVtkId();
-  SMDS_Mesh::_meshList[myMeshId]->setMyModified();
-  return true;
-}
-
-void SMDS_BallElement::Print (std::ostream & OS) const
-{
-  OS << "ball<" << GetID() << "> : ";
+  getGrid()->SetBallDiameter( GetVtkID(), diameter );
+  GetMesh()->setMyModified();
 }
-
-const SMDS_MeshNode* SMDS_BallElement::GetNode (const int ind) const
-{
-  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
-  vtkIdType npts, *pts;
-  grid->GetCellPoints( myVtkID, npts, pts );
-  return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ 0 ]);
-}
-
-SMDS_ElemIteratorPtr SMDS_BallElement::elementsIterator (SMDSAbs_ElementType type) const
-{
-  switch (type)
-  {
-    case SMDSAbs_Node:
-      return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
-    default:
-      ;
-      return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL);
-  }
-}
-
index c62034d..4e7c634 100644 (file)
 #include "SMESH_SMDS.hxx"
 #include "SMDS_MeshCell.hxx"
 
-#include <iostream>
-
+/*!
+ * \brief Ball element. This type is not allocated.
+ *        It is only used as function argument type to provide more clear semantic
+ *        and to provide API specific to ball element
+ */
 class SMDS_EXPORT SMDS_BallElement: public SMDS_MeshCell
 {
+  void init(const SMDS_MeshNode * node, double diameter);
+
+  friend class SMDS_Mesh;
+
  public:
-  SMDS_BallElement();
-  SMDS_BallElement (const SMDS_MeshNode * node, double diameter);
-  SMDS_BallElement(vtkIdType nodeId, double diameter, SMDS_Mesh* mesh);
-  void init(vtkIdType nodeId, double diameter, SMDS_Mesh* mesh);
+
   double GetDiameter() const;
-  void SetDiameter(double diameter);
-  bool ChangeNode (const SMDS_MeshNode * node);
-
-  virtual bool ChangeNodes(const SMDS_MeshNode* nodes[],
-                           const int            nbNodes) { return ChangeNode( nodes[0] ); }
-  virtual void Print (std::ostream & OS) const;
-
-  virtual SMDSAbs_ElementType  GetType()       const { return SMDSAbs_Ball; }
-  virtual vtkIdType            GetVtkType()    const { return VTK_POLY_VERTEX; }
-  virtual SMDSAbs_EntityType   GetEntityType() const { return SMDSEntity_Ball; }
-  virtual SMDSAbs_GeometryType GetGeomType()   const { return SMDSGeom_BALL; }
-  virtual int NbNodes() const { return 1; }
-  virtual int NbEdges() const { return 0; }
-  virtual int NbFaces() const { return 0; }
-  virtual const SMDS_MeshNode* GetNode (const int ind) const;
-
- protected:
-  SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const;
+  void   SetDiameter(double diameter);
+
+  static SMDSAbs_ElementType Type() { return SMDSAbs_Ball; }
 };
 
 #endif
diff --git a/src/SMDS/SMDS_CellOfNodes.cxx b/src/SMDS/SMDS_CellOfNodes.cxx
new file mode 100644 (file)
index 0000000..bea007f
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SMESH SMDS : implementation of Salome mesh data structure
+//
+
+#include "SMDS_CellOfNodes.hxx"
+
+SMDS_CellOfNodes::SMDS_CellOfNodes( int id, int shapeID )
+  : myID( id )
+{
+  setShapeID( shapeID );
+}
+
+void SMDS_CellOfNodes::setID(const int id)
+{
+  myID = id;
+}
+
+int SMDS_CellOfNodes::GetID() const
+{
+  return myID;
+}
+
+void SMDS_CellOfNodes::setShapeID( const int shapeID )
+{
+  myShapeID = ( shapeID << BITS_SHIFT ) | ( myShapeID & BIT_IS_MARKED );
+}
+
+int SMDS_CellOfNodes::GetShapeID() const
+{
+  return myShapeID >> BITS_SHIFT;
+}
+
+void SMDS_CellOfNodes::setIsMarked( bool is ) const
+{
+  const_cast< SMDS_CellOfNodes* >( this )->myShapeID = ( myShapeID & ~BIT_IS_MARKED ) | is;
+}
+
+bool SMDS_CellOfNodes::isMarked() const
+{
+  return myShapeID & BIT_IS_MARKED;
+}
diff --git a/src/SMDS/SMDS_CellOfNodes.hxx b/src/SMDS/SMDS_CellOfNodes.hxx
new file mode 100644 (file)
index 0000000..4880d07
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  SMESH SMDS : implementation of Salome mesh data structure
+//  File   : SMDS_CellOfNodes.hxx
+//  Module : SMESH
+//
+#ifndef _SMDS_CellOfNodes_HeaderFile
+#define _SMDS_CellOfNodes_HeaderFile
+
+#include "SMESH_SMDS.hxx"
+        
+#include "SMDS_MeshElement.hxx"
+
+// ============================================================
+/*!
+ * \brief Base class for elements of not contained in the mesh
+ */
+// ============================================================
+
+
+class SMDS_EXPORT SMDS_CellOfNodes : public SMDS_MeshElement
+{
+public:
+
+  virtual int GetID() const;
+  virtual int GetShapeID() const;
+
+  virtual void setIsMarked( bool is ) const;
+  virtual bool isMarked() const;
+
+  virtual VTKCellType GetVtkType() const { return VTK_EMPTY_CELL; }
+
+ protected:
+
+  SMDS_CellOfNodes( int id = -1, int shapeID = 0);
+
+  virtual void setID( const int id);
+  virtual void setShapeID( const int shapeID );
+
+  int  myID;
+  int  myShapeID;
+
+  enum Bits { // use the 1st right bit of myShapeId to set/unset a mark
+    BIT_IS_MARKED = 1,
+    BITS_SHIFT = 1
+  };
+};
+#endif
index c4ead4d..1955fa8 100644 (file)
@@ -1145,7 +1145,7 @@ void SMDS_DownTetra::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& o
       return;
     }
   }
-  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->FromVtkToSmds(_vtkCellIds[cellId]));
   MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
   MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
 }
@@ -1253,7 +1253,7 @@ void SMDS_DownQuadTetra::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType
       return;
     }
   }
-  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->FromVtkToSmds(_vtkCellIds[cellId]));
   MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
   MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
 }
@@ -1387,7 +1387,7 @@ void SMDS_DownPyramid::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>&
       return;
     }
   }
-  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->FromVtkToSmds(_vtkCellIds[cellId]));
   MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
   MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
 }
@@ -1531,7 +1531,7 @@ void SMDS_DownQuadPyramid::getOrderedNodesOfFace(int cellId, std::vector<vtkIdTy
       return;
     }
   }
-  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->FromVtkToSmds(_vtkCellIds[cellId]));
   MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]);
   MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
 }
@@ -1694,7 +1694,7 @@ void SMDS_DownPenta::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& o
       return;
     }
   }
-  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->FromVtkToSmds(_vtkCellIds[cellId]));
   MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
   MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
 }
@@ -1845,7 +1845,7 @@ void SMDS_DownQuadPenta::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType
       return;
     }
   }
-  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->FromVtkToSmds(_vtkCellIds[cellId]));
   MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
   MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
 }
@@ -2000,7 +2000,7 @@ void SMDS_DownHexa::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& or
       return;
     }
   }
-  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->FromVtkToSmds(_vtkCellIds[cellId]));
   MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]);
   MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
   MESSAGE(nodes[4] << " " << nodes[5] << " " << nodes[6] << " " << nodes[7]);
@@ -2132,7 +2132,7 @@ void SMDS_DownQuadHexa::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>
       return;
     }
   }
-  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->FromVtkToSmds(_vtkCellIds[cellId]));
   MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]);
   MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
 }
diff --git a/src/SMDS/SMDS_EdgePosition.cxx b/src/SMDS/SMDS_EdgePosition.cxx
deleted file mode 100644 (file)
index 9ac728d..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-//  SMESH SMDS : implementation of Salome mesh data structure
-//  File   : SMDS_EdgePosition.cxx
-//  Author : Jean-Michel BOULCOURT
-//  Module : SMESH
-//
-#include "SMDS_EdgePosition.hxx"
-
-#include "utilities.h"
-
-using namespace std;
-
-//=======================================================================
-//function : SMDS_EdgePosition
-//purpose  : 
-//=======================================================================
-
-SMDS_EdgePosition::SMDS_EdgePosition(const double aUParam): myUParameter(aUParam)
-{
-  //MESSAGE("********************************* SMDS_EdgePosition " << myUParameter);
-}
-
-/**
-*/
-SMDS_TypeOfPosition SMDS_EdgePosition::GetTypeOfPosition() const
-{
-  //MESSAGE("###################################### SMDS_EdgePosition::GetTypeOfPosition");
-        return SMDS_TOP_EDGE;
-}
-
-void SMDS_EdgePosition::SetUParameter(double aUparam)
-{
-  //MESSAGE("############################### SMDS_EdgePosition::SetUParameter " << aUparam);
-        myUParameter = aUparam;
-}
-
-//=======================================================================
-//function : GetUParameter
-//purpose  : 
-//=======================================================================
-
-double SMDS_EdgePosition::GetUParameter() const 
-{
-  //MESSAGE("########################## SMDS_EdgePosition::GetUParameter " << myUParameter);
-        return myUParameter;
-}
index f0870e9..e2c9cf1 100644 (file)
 
 #include "SMDS_Position.hxx"
 
-class SMDS_EXPORT SMDS_EdgePosition:public SMDS_Position
+class SMDS_EXPORT SMDS_EdgePosition : public SMDS_Position
 {
 
-  public:
-        SMDS_EdgePosition(const double aUParam=0);
-        SMDS_TypeOfPosition GetTypeOfPosition() const;
-        void SetUParameter(double aUparam);
-        double GetUParameter() const;
+ public:
+  SMDS_EdgePosition(const double aUParam=0) : myUParameter( aUParam ) {}
+  virtual SMDS_TypeOfPosition GetTypeOfPosition() const { return SMDS_TOP_EDGE; }
+  virtual void   SetUParameter(double aUparam) { myUParameter = aUparam; }
+  virtual double GetUParameter() const { return myUParameter; }
+  virtual const double* GetParameters() const { return &myUParameter; }
 
 private:
+ private:
 
-        double myUParameter;
+  double myUParameter;
 
 };
 
diff --git a/src/SMDS/SMDS_ElementFactory.cxx b/src/SMDS/SMDS_ElementFactory.cxx
new file mode 100644 (file)
index 0000000..a6d61e8
--- /dev/null
@@ -0,0 +1,880 @@
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : SMDS_ElementFactory.cxx
+//  Module : SMESH
+//
+
+#include "SMDS_ElementFactory.hxx"
+
+#include "ObjectPool.hxx"
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_FacePosition.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_SpacePosition.hxx"
+#include "SMDS_VertexPosition.hxx"
+
+namespace
+{
+  // nb of elements allocated by SMDS_ElementChunk at once
+  const int theChunkSize = 1024;
+
+  const int theDefaultShapeDim = 3;
+
+  // classes allowing to modify parameters of SMDS_Position stored in SMDS_ElementFactory
+
+  struct _EdgePosition : public SMDS_EdgePosition
+  {
+    TParam* myUParameter;
+
+    _EdgePosition( TParam* aUParam ) : myUParameter( aUParam )
+    { SMDS_EdgePosition::SetUParameter( aUParam[0]); }
+    virtual void   SetUParameter(double aUparam)
+    { *myUParameter = (TParam) aUparam; SMDS_EdgePosition::SetUParameter( aUparam ); }
+  };
+
+  struct _FacePosition : public SMDS_FacePosition
+  {
+    TParam* myParameter;
+
+    _FacePosition(TParam* aParam) : myParameter( aParam )
+    { SMDS_FacePosition::SetParameters( aParam[0], aParam[1] ); }
+    virtual void SetUParameter(double aUparam)
+    { myParameter[0] = (TParam) aUparam; SMDS_FacePosition::SetUParameter( aUparam ); }
+    virtual void SetVParameter(double aVparam)
+    { myParameter[1] = (TParam) aVparam; SMDS_FacePosition::SetVParameter( aVparam ); }
+    virtual void SetParameters(double aU, double aV)
+    { myParameter[0] = aU; myParameter[1] = aV; SMDS_FacePosition::SetParameters( aU, aV ); }
+  };
+}
+
+//================================================================================
+/*!
+ * \brief Create a factory of cells or nodes in a given mesh
+ */
+//================================================================================
+
+SMDS_ElementFactory::SMDS_ElementFactory( SMDS_Mesh* mesh, const bool isNodal )
+  : myIsNodal( isNodal ), myMesh( mesh ), myNbUsedElements( 0 )
+{
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+SMDS_ElementFactory::~SMDS_ElementFactory()
+{
+  myChunksWithUnused.clear();
+  myChunks.clear();
+}
+
+//================================================================================
+/*!
+ * \brief Return a number of elements in a chunk
+ *  \return int - chunk size
+ */
+//================================================================================
+
+int SMDS_ElementFactory::ChunkSize()
+{
+  return theChunkSize;
+}
+
+//================================================================================
+/*!
+ * \brief Return minimal ID of a non-used element
+ *  \return int - minimal element ID
+ */
+//================================================================================
+
+int SMDS_ElementFactory::GetFreeID()
+{
+  if ( myChunksWithUnused.empty() )
+  {
+    int id0 = myChunks.size() * theChunkSize + 1;
+    myChunks.push_back( new SMDS_ElementChunk( this, id0 ));
+  }
+  SMDS_ElementChunk * chunk = (*myChunksWithUnused.begin());
+  return chunk->GetUnusedID();
+}
+
+//================================================================================
+/*!
+ * \brief Return maximal ID of an used element
+ *  \return int - element ID
+ */
+//================================================================================
+
+int SMDS_ElementFactory::GetMaxID()
+{
+  int id = 0;
+  TIndexRanges usedRanges;
+  for ( int i = myChunks.size() - 1; i >= 0; --i )
+    if ( myChunks[i].GetUsedRanges().GetIndices( true, usedRanges ))
+    {
+      int index = usedRanges.back().second-1;
+      id = myChunks[i].Get1stID() + index;
+      break;
+    }
+  return id;
+}
+
+//================================================================================
+/*!
+ * \brief Return minimal ID of an used element
+ *  \return int - element ID
+ */
+//================================================================================
+
+int SMDS_ElementFactory::GetMinID()
+{
+  int id = 0;
+  TIndexRanges usedRanges;
+  for ( size_t i = 0; i < myChunks.size(); ++i )
+    if ( myChunks[i].GetUsedRanges().GetIndices( true, usedRanges ))
+    {
+      int index = usedRanges[0].first;
+      id = myChunks[i].Get1stID() + index;
+      break;
+    }
+  return id;
+}
+
+//================================================================================
+/*!
+ * \brief Return an element by ID. NULL if the element with the given ID is already used
+ *  \param [in] id - element ID
+ *  \return SMDS_MeshElement* - element pointer
+ */
+//================================================================================
+
+SMDS_MeshElement* SMDS_ElementFactory::NewElement( const int id )
+{
+  int iChunk = ( id - 1 ) / theChunkSize;
+  int index  = ( id - 1 ) % theChunkSize;
+  while ((int) myChunks.size() <= iChunk )
+  {
+    int id0 = myChunks.size() * theChunkSize + 1;
+    myChunks.push_back( new SMDS_ElementChunk( this, id0 ));
+  }
+  SMDS_MeshElement* e = myChunks[iChunk].Element( index );
+  if ( !e->IsNull() )
+    return 0; // element with given ID already exists
+
+  myChunks[iChunk].UseElement( index );
+  ++myNbUsedElements;
+
+  e->myHolder = & myChunks[iChunk];
+
+  myMesh->setMyModified();
+
+  return e;
+}
+
+//================================================================================
+/*!
+ * \brief Return an used element by ID. NULL if the element with the given ID is not yet used
+ *  \param [in] id - element ID
+ *  \return const SMDS_MeshElement* - element pointer
+ */
+//================================================================================
+
+const SMDS_MeshElement* SMDS_ElementFactory::FindElement( const int id ) const
+{
+  if ( id > 0 )
+  {
+    int iChunk = ( id - 1 ) / theChunkSize;
+    int index  = ( id - 1 ) % theChunkSize;
+    if ( iChunk < (int) myChunks.size() )
+    {
+      const SMDS_MeshElement* e = myChunks[iChunk].Element( index );
+      return e->IsNull() ? 0 : e;
+    }
+  }
+  return 0;
+}
+
+//================================================================================
+/*!
+ * \brief Return an SMDS ID by a Vtk one
+ *  \param [inout] vtkID - Vtk ID
+ *  \return int - SMDS ID
+ */
+//================================================================================
+
+int SMDS_ElementFactory::FromVtkToSmds( vtkIdType vtkID )
+{
+  if ( vtkID >= 0 && vtkID < (vtkIdType)mySmdsIDs.size() )
+    return mySmdsIDs[vtkID] + 1;
+  return vtkID + 1;
+}
+
+//================================================================================
+/*!
+ * \brief Mark the element as non-used
+ *  \param [in] e - element
+ */
+//================================================================================
+
+void SMDS_ElementFactory::Free( const SMDS_MeshElement* e )
+{
+  if ( !myVtkIDs.empty() )
+  {
+    size_t    id = e->GetID() - 1;
+    size_t vtkID = e->GetVtkID();
+    if ( id < myVtkIDs.size() )
+      myVtkIDs[ id ] = -1;
+    if ( vtkID < mySmdsIDs.size() )
+      mySmdsIDs[ vtkID ] = -1;
+  }
+  e->myHolder->Free( e );
+  const_cast< SMDS_MeshElement*>( e )->myHolder = 0;
+  --myNbUsedElements;
+
+  myMesh->setMyModified();
+}
+
+//================================================================================
+/*!
+ * \brief De-allocate all elements
+ */
+//================================================================================
+
+void SMDS_ElementFactory::Clear()
+{
+  myChunksWithUnused.clear();
+  clearVector( myChunks );
+  clearVector( myVtkIDs );
+  clearVector( mySmdsIDs );
+  myNbUsedElements = 0;
+}
+
+//================================================================================
+/*!
+ * \brief Remove unused elements located not at the end of the last chunk.
+ *        Minimize allocated memory
+ *  \param [out] theVtkIDsNewToOld - theVtkIDsNewToOld[ new VtkID ] = old VtkID
+ */
+//================================================================================
+
+void SMDS_ElementFactory::Compact( std::vector<int>& theVtkIDsNewToOld )
+{
+  int  newNbCells = NbUsedElements();
+  int   maxCellID = GetMaxID();
+  int newNbChunks = newNbCells / theChunkSize + bool ( newNbCells % theChunkSize );
+
+  theVtkIDsNewToOld.resize( newNbCells );
+
+  if ( newNbCells == 0 ) // empty mesh
+  {
+    clearVector( myChunks );
+  }
+  else if ( newNbCells == maxCellID ) // no holes
+  {
+    int newID, minLastID = std::min( myVtkIDs.size(), theVtkIDsNewToOld.size() );
+    for ( newID = 0; newID < minLastID; ++newID )
+      theVtkIDsNewToOld[ newID ] = myVtkIDs[ newID ];
+    for ( ; newID < newNbCells; ++newID )
+      theVtkIDsNewToOld[ newID ] = newID;
+  }
+  else // there are holes in SMDS IDs
+  {
+    int newVtkID = 0; // same as new smds ID (-1)
+    for ( int oldID = 1; oldID <= maxCellID; ++oldID ) // smds IDs
+    {
+      const SMDS_MeshElement* oldElem = FindElement( oldID );
+      if ( !oldElem ) continue;
+      theVtkIDsNewToOld[ newVtkID++ ] = oldElem->GetVtkID(); // now newVtkID == new smds ID
+      if ( oldID != newVtkID )
+      {
+        const SMDS_MeshElement* newElem = FindElement( newVtkID );
+        if ( !newElem )
+          newElem = NewElement( newVtkID );
+        if ( int shapeID = oldElem->GetShapeID() )
+          const_cast< SMDS_MeshElement* >( newElem )->setShapeID( shapeID );
+        if ( oldID > newNbCells )
+          Free( oldElem );
+      }
+    }
+  }
+  myChunks.resize( newNbChunks );
+
+  myChunksWithUnused.clear();
+  if ( !myChunks.empty() && myChunks.back().GetUsedRanges().Size() > 1 )
+    myChunksWithUnused.insert( & myChunks.back() );
+
+  for ( size_t i = 0; i < myChunks.size(); ++i )
+    myChunks[i].Compact();
+
+  clearVector( myVtkIDs );
+  clearVector( mySmdsIDs );
+}
+
+
+//================================================================================
+/*!
+ * \brief Return true if Compact() will change IDs of elements
+ */
+//================================================================================
+
+bool SMDS_ElementFactory::CompactChangePointers()
+{
+  // there can be VTK_EMPTY_CELL's in the VTK grid as well as "holes" in SMDS numeration
+  return ( NbUsedElements() != GetMaxID() );
+}
+
+//================================================================================
+/*!
+ * \brief Create a factory of nodes in a given mesh
+ */
+//================================================================================
+
+SMDS_NodeFactory::SMDS_NodeFactory( SMDS_Mesh* mesh )
+  : SMDS_ElementFactory( mesh, /*isNodal=*/true )
+{
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+SMDS_NodeFactory::~SMDS_NodeFactory()
+{
+  Clear();
+}
+
+//================================================================================
+/*!
+ * \brief Remove unused nodes located not at the end of the last chunk.
+ *        Minimize allocated memory
+ *  \param [out] theVtkIDsOldToNew - vector storing change of vtk IDs
+ */
+//================================================================================
+
+void SMDS_NodeFactory::Compact( std::vector<int>& theVtkIDsOldToNew )
+{
+  // IDs of VTK nodes always correspond to SMDS IDs but there can be "holes"
+  // in the chunks. So we remove holes and report relocation in theVtkIDsOldToNew:
+  // theVtkIDsOldToNew[ old VtkID ] = new VtkID
+
+  int  oldNbNodes = myMesh->GetGrid()->GetNumberOfPoints();
+  int  newNbNodes = NbUsedElements();
+  int newNbChunks = newNbNodes / theChunkSize + bool ( newNbNodes % theChunkSize );
+  int   maxNodeID = GetMaxID();
+
+  theVtkIDsOldToNew.resize( oldNbNodes, -1 );
+
+  if ( newNbNodes == 0 ) // empty mesh
+  {
+    clearVector( myChunks );
+  }
+  else if ( maxNodeID > newNbNodes ) // there are holes
+  {
+    size_t newID = 0;
+    for ( size_t oldID = 0; oldID < theVtkIDsOldToNew.size(); ++oldID )
+    {
+      const SMDS_MeshElement* oldNode = FindNode( oldID+1 );
+      if ( !oldNode )
+        continue;
+      theVtkIDsOldToNew[ oldID ] = newID;
+      if ( oldID != newID )
+      {
+        const SMDS_MeshElement* newNode = FindElement( newID+1 );
+        if ( !newNode )
+          newNode = NewElement( newID+1 );
+        int  shapeID = oldNode->GetShapeID();
+        int shapeDim = GetShapeDim( shapeID );
+        int   iChunk = newID / theChunkSize;
+        myChunks[ iChunk ].SetShapeID( newNode, shapeID );
+        if ( shapeDim == 2 || shapeDim == 1 )
+        {
+          int iChunkOld = oldID / theChunkSize;
+          TParam* oldPos = myChunks[ iChunkOld ].GetPositionPtr( oldNode );
+          TParam* newPos = myChunks[ iChunk    ].GetPositionPtr( newNode, /*allocate=*/true );
+          if ( oldPos )
+          {
+            newPos[0] = oldPos[0];
+            newPos[1] = oldPos[1];
+          }
+        }
+        if ( oldNode->GetID() > newNbNodes )
+          Free( oldNode );
+      }
+      ++newID;
+    }
+  }
+  else // no holes
+  {
+    for ( int i = 0; i < newNbNodes; ++i )
+      theVtkIDsOldToNew[ i ] = i;
+  }
+  myChunks.resize( newNbChunks );
+
+  myChunksWithUnused.clear();
+  if ( !myChunks.empty() && myChunks.back().GetUsedRanges().Size() > 1 )
+    myChunksWithUnused.insert( & myChunks.back() );
+
+  for ( size_t i = 0; i < myChunks.size(); ++i )
+    myChunks[i].Compact();
+
+  ASSERT( newNbNodes == GetMaxID() );
+  ASSERT( newNbNodes == NbUsedElements() );
+}
+
+//================================================================================
+/*!
+ * \brief Return true if Compact() will change IDs of elements
+ */
+//================================================================================
+
+bool SMDS_NodeFactory::CompactChangePointers()
+{
+  // IDs of VTK nodes always correspond to SMDS IDs but there can be "holes" in SMDS numeration
+  return ( NbUsedElements() != GetMaxID() );
+}
+
+//================================================================================
+/*!
+ * \brief De-allocate all nodes
+ */
+//================================================================================
+
+void SMDS_NodeFactory::Clear()
+{
+  SMDS_ElementFactory::Clear();
+}
+
+//================================================================================
+/*!
+ * \brief Set a total number of sub-shapes in the main shape
+ */
+//================================================================================
+
+void SMDS_NodeFactory::SetNbShapes( size_t nbShapes )
+{
+  clearVector( myShapeDim );
+  myShapeDim.resize( nbShapes+1, theDefaultShapeDim );
+}
+
+//================================================================================
+/*!
+ * \brief Return a dimension of a shape
+ */
+//================================================================================
+
+int SMDS_NodeFactory::GetShapeDim( int shapeID ) const
+{
+  return shapeID < (int)myShapeDim.size() ? myShapeDim[ shapeID ] : theDefaultShapeDim;
+}
+
+//================================================================================
+/*!
+ * \brief Set a dimension of a shape
+ */
+//================================================================================
+
+void SMDS_NodeFactory::SetShapeDim( int shapeID, int dim )
+{
+  if ( shapeID >= (int)myShapeDim.size() )
+    myShapeDim.resize( shapeID + 10, theDefaultShapeDim );
+  myShapeDim[ shapeID ] = dim;
+}
+
+//================================================================================
+/*!
+ * \brief SMDS_ElementChunk constructor
+ *  \param [in] factory - the factory
+ *  \param [in] id0 - ID of the 1st element
+ */
+//================================================================================
+
+SMDS_ElementChunk::SMDS_ElementChunk( SMDS_ElementFactory* factory, int id0 ):
+  myFactory( factory ),
+  my1stID( id0 ),
+  myMinSubID( std::numeric_limits<int>::max() ),
+  myMaxSubID( 0 )
+{
+  if ( !myFactory )
+    return;
+  if ( myFactory->myIsNodal )
+    myElements = new SMDS_MeshNode[ theChunkSize ];
+  else
+    myElements = new SMDS_MeshCell[ theChunkSize ];
+
+  myUsedRanges.mySet.reserve(2);
+  mySubIDRanges.mySet.insert( _ShapeIDRange( 0, 0 ));
+  myUsedRanges.mySet.insert( _UsedRange( 0, false ));
+  myFactory->myChunksWithUnused.insert( this );
+}
+
+//================================================================================
+/*!
+ * \brief SMDS_ElementChunk destructor
+ */
+//================================================================================
+
+SMDS_ElementChunk::~SMDS_ElementChunk()
+{
+  delete [] myElements;
+  myFactory->myChunksWithUnused.erase( this );
+}
+
+//================================================================================
+/*!
+ * \brief Mark an element as used
+ */
+//================================================================================
+
+void SMDS_ElementChunk::UseElement( const int index )
+{
+  myUsedRanges.SetValue( index, true );
+  if ( myUsedRanges.Size() == 1 ) // all elements used
+    myFactory->myChunksWithUnused.erase( this );
+}
+
+//================================================================================
+/*!
+ * \brief Return ID of the first non-used element
+ */
+//================================================================================
+
+int SMDS_ElementChunk::GetUnusedID() const
+{
+  TUsedRangeSet::set_iterator r = myUsedRanges.mySet.begin();
+  for ( ; r != myUsedRanges.mySet.end(); ++r )
+    if ( !IsUsed( *r ))
+      break;
+
+  return my1stID + r->my1st;
+}
+
+//================================================================================
+/*!
+ * \brief Mark an element as non-used
+ */
+//================================================================================
+
+void SMDS_ElementChunk::Free( const SMDS_MeshElement* e )
+{
+  bool hasHoles = ( myUsedRanges.Size() > 1 );
+  myUsedRanges.SetValue( Index( e ), false );
+  SetShapeID( e, 0 ); // sub-mesh must do it?
+  SetIsMarked( e, false );
+  if ( !hasHoles )
+    myFactory->myChunksWithUnused.insert( this );
+
+  if ( myUsedRanges.Size() == 1 )
+  {
+    clearVector( myMarkedSet );
+    clearVector( myPositions );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Return an SMDS ID of an element
+ */
+//================================================================================
+
+int SMDS_ElementChunk::GetID( const SMDS_MeshElement* e ) const
+{
+  return my1stID + Index( e );
+}
+
+//================================================================================
+/*!
+ * \brief Set a Vtk ID of an element
+ */
+//================================================================================
+
+void SMDS_ElementChunk::SetVTKID( const SMDS_MeshElement* e, const vtkIdType vtkID )
+{
+  if ( e->GetID() - 1 != vtkID )
+  {
+    if ((int) myFactory->myVtkIDs.size() <= e->GetID() - 1 )
+    {
+      size_t i = myFactory->myVtkIDs.size();
+      myFactory->myVtkIDs.resize( e->GetID() + 100 );
+      for ( ; i < myFactory->myVtkIDs.size(); ++i )
+        myFactory->myVtkIDs[i] = i;
+    }
+    myFactory->myVtkIDs[ e->GetID() - 1 ] = vtkID;
+
+    if ((vtkIdType) myFactory->mySmdsIDs.size() <= vtkID )
+    {
+      size_t i = myFactory->mySmdsIDs.size();
+      myFactory->mySmdsIDs.resize( vtkID + 100 );
+      for ( ; i < myFactory->mySmdsIDs.size(); ++i )
+        myFactory->mySmdsIDs[i] = i;
+    }
+    myFactory->mySmdsIDs[ vtkID ] = e->GetID() - 1;
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Return a Vtk ID of an element
+ */
+//================================================================================
+
+int SMDS_ElementChunk::GetVtkID( const SMDS_MeshElement* e ) const
+{
+  size_t dfltVtkID = e->GetID() - 1;
+  return ( dfltVtkID < myFactory->myVtkIDs.size() ) ? myFactory->myVtkIDs[ dfltVtkID ] : dfltVtkID;
+}
+
+//================================================================================
+/*!
+ * \brief Return ID of a shape an element is assigned to
+ */
+//================================================================================
+
+int SMDS_ElementChunk::GetShapeID( const SMDS_MeshElement* e ) const
+{
+  return mySubIDRanges.GetValue( Index( e ));
+}
+
+//================================================================================
+/*!
+ * \brief Set ID of a shape an element is assigned to
+ */
+//================================================================================
+
+void SMDS_ElementChunk::SetShapeID( const SMDS_MeshElement* e, int shapeID ) const
+{
+  const size_t nbRanges = mySubIDRanges.Size();
+
+  SMDS_ElementChunk* me = const_cast<SMDS_ElementChunk*>( this );
+  int oldShapeID = me->mySubIDRanges.SetValue( Index( e ), shapeID );
+  if ( oldShapeID == shapeID ) return;
+
+  if ( const SMDS_MeshNode* n = dynamic_cast< const SMDS_MeshNode* >( e ))
+    if ( TParam* uv = me->GetPositionPtr( n ))
+    {
+      uv[0] = 0.;
+      uv[1] = 0.;
+    }
+  // update min/max
+  if (( nbRanges > mySubIDRanges.Size() ) &&
+      ( myMinSubID == oldShapeID || myMaxSubID == oldShapeID ))
+  {
+    me->myMinSubID = ( std::numeric_limits<int>::max() );
+    me->myMaxSubID = 0;
+    TSubIDRangeSet::set_iterator it;
+    for ( it = mySubIDRanges.mySet.begin(); it < mySubIDRanges.mySet.end(); ++it )
+      if ( it->myValue > 0 )
+      {
+        me->myMinSubID = std::min( myMinSubID, it->myValue );
+        me->myMaxSubID = std::max( myMaxSubID, it->myValue );
+      }
+  }
+  else if ( shapeID > 0 )
+  {
+    me->myMinSubID = std::min( myMinSubID, shapeID );
+    me->myMaxSubID = std::max( myMaxSubID, shapeID );
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Set isMarked flag of an element
+ */
+//================================================================================
+
+bool SMDS_ElementChunk::IsMarked( const SMDS_MeshElement* e ) const
+{
+  return ( !myMarkedSet.empty() && myMarkedSet[ Index( e )]);
+}
+
+//================================================================================
+/*!
+ * \brief Return isMarked flag of an element
+ */
+//================================================================================
+
+void SMDS_ElementChunk::SetIsMarked( const SMDS_MeshElement* e, bool is )
+{
+  if ( !is && myMarkedSet.empty() ) return;
+  if ( myMarkedSet.empty() ) myMarkedSet.resize( theChunkSize, false );
+  myMarkedSet[ Index( e )] = is;
+}
+
+//================================================================================
+/*!
+ * \brief Return SMDS_Position of a node on a shape
+ */
+//================================================================================
+
+SMDS_PositionPtr SMDS_ElementChunk::GetPosition( const SMDS_MeshNode* n ) const
+{
+  int  shapeID = GetShapeID( n );
+  int shapeDim = static_cast< SMDS_NodeFactory* >( myFactory )->GetShapeDim( shapeID );
+
+  SMDS_ElementChunk* me = const_cast< SMDS_ElementChunk* >( this );
+
+  switch ( shapeDim ) {
+  case 2:
+  {
+    return SMDS_PositionPtr( new _FacePosition( me->GetPositionPtr( n )));
+  }
+  case 1:
+  {
+    return SMDS_PositionPtr( new _EdgePosition( me->GetPositionPtr( n )));
+  }
+  case 0:
+    return SMDS_VertexPosition::StaticPosition();
+  }
+
+  return SMDS_SpacePosition::originSpacePosition();
+}
+
+//================================================================================
+/*!
+ * \brief Set SMDS_Position of a node on a shape
+ */
+//================================================================================
+
+void SMDS_ElementChunk::SetPosition( const SMDS_MeshNode* n, const SMDS_PositionPtr& pos, int shapeID )
+{
+  int shapeDim = pos ? pos->GetDim() : theDefaultShapeDim;
+  if ( shapeID < 1 )
+  {
+    if ( shapeDim == theDefaultShapeDim )
+      return;
+    shapeID = GetShapeID( n );
+    if ( shapeID < 1 )
+      throw SALOME_Exception("SetPosition() No shape ID provided");
+  }
+
+  static_cast< SMDS_NodeFactory* >( myFactory )->SetShapeDim( shapeID, shapeDim );
+
+  switch ( shapeDim ) {
+  case 2:
+  {
+    TParam* uv = GetPositionPtr( n, /*allocate=*/true );
+    uv[0] = (TParam) pos->GetParameters()[0];
+    uv[1] = (TParam) pos->GetParameters()[1];
+    break;
+  }
+  case 1:
+  {
+    GetPositionPtr( n, /*allocate=*/true )[0] = (TParam) pos->GetParameters()[0];
+    break;
+  }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Return pointer to on-shape-parameters of a node
+ */
+//================================================================================
+
+TParam* SMDS_ElementChunk::GetPositionPtr( const SMDS_MeshElement* n, bool allocate )
+{
+  if ( myPositions.empty() && !allocate )
+    return 0;
+
+  myPositions.resize( theChunkSize * 2 );
+  return myPositions.data() + 2 * Index( n );
+}
+
+//================================================================================
+/*!
+ * \brief Minimize allocated memory
+ */
+//================================================================================
+
+void SMDS_ElementChunk::Compact()
+{
+  mySubIDRanges.mySet.shrink_to_fit();
+  if ( myUsedRanges.mySet.capacity() > 2 )
+    myUsedRanges.mySet.shrink_to_fit();
+
+  clearVector( myMarkedSet );
+
+  if ( !myPositions.empty() )
+  {
+    // look for the last position that must be kept
+    TSubIDRangeSet::set_t::reverse_iterator it;
+    for ( it = mySubIDRanges.mySet.rbegin(); it != mySubIDRanges.mySet.rend(); ++it )
+    {
+      int shapeDim = static_cast< SMDS_NodeFactory* >( myFactory )->GetShapeDim( it->myValue );
+      if ( shapeDim == 1 || shapeDim == 2 )
+        break;
+    }
+    if ( it == mySubIDRanges.mySet.rend() )
+    {
+      clearVector( myPositions );
+    }
+    else if ( it != mySubIDRanges.mySet.rbegin() )
+    {
+      int nbNodes = (it-1)->my1st;
+      myPositions.resize( nbNodes * 2 );
+      std::vector<TParam> newPos( myPositions.begin(), myPositions.end() );
+      myPositions.swap( newPos );
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Print some data for debug purposes
+ */
+//================================================================================
+
+void SMDS_ElementChunk::Dump() const
+{
+  std::cout << "1stID: " << my1stID << std::endl;
+
+  std::cout << "SubID min/max: " << myMinSubID << ", " << myMaxSubID << std::endl;
+  std::cout << "SubIDRanges: " << mySubIDRanges.Size() << " ";
+  {
+    TSubIDRangeSet::set_iterator i = mySubIDRanges.mySet.begin();
+    for ( int cnt = 0; i != mySubIDRanges.mySet.end(); ++i, ++cnt )
+      std::cout << "|" << cnt << " - (" << i->my1st << ", " << i->myValue << ") ";
+    std::cout << std::endl;
+  }
+  {
+    std::cout << "UsedRanges: " << myUsedRanges.Size() << " ";
+    TUsedRangeSet::set_iterator i = myUsedRanges.mySet.begin();
+    for ( int cnt = 0; i != myUsedRanges.mySet.end(); ++i, ++cnt )
+      std::cout << cnt << " - (" << i->my1st << ", " << i->myValue << ") ";
+    std::cout << std::endl;
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Compare SMDS_ElementChunk's
+ */
+//================================================================================
+
+bool _ChunkCompare::operator () (const SMDS_ElementChunk* e1, const SMDS_ElementChunk* e2) const
+{
+  return e1->Get1stID() < e2->Get1stID();
+}
+
diff --git a/src/SMDS/SMDS_ElementFactory.hxx b/src/SMDS/SMDS_ElementFactory.hxx
new file mode 100644 (file)
index 0000000..b25b635
--- /dev/null
@@ -0,0 +1,559 @@
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : SMDS_ElementFactory.hxx
+//  Module : SMESH
+//
+#ifndef _SMDS_ElementFactory_HeaderFile
+#define _SMDS_ElementFactory_HeaderFile
+
+#include "SMDS_MeshCell.hxx"
+#include "SMDS_Position.hxx"
+
+#include <Utils_SALOME_Exception.hxx>
+
+#include <boost/container/flat_set.hpp>
+#include <boost/dynamic_bitset.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include <set>
+
+#include <vtkType.h>
+
+class SMDS_ElementChunk;
+class SMDS_Mesh;
+class SMDS_MeshCell;
+class SMDS_MeshNode;
+
+struct _ChunkCompare {
+  bool operator () (const SMDS_ElementChunk* c1, const SMDS_ElementChunk* c2) const;
+};
+typedef boost::ptr_vector<SMDS_ElementChunk>       TChunkVector;
+typedef std::set<SMDS_ElementChunk*,_ChunkCompare> TChunkPtrSet;
+
+//------------------------------------------------------------------------------------
+/*!
+ * \brief Allocate SMDS_MeshElement's (SMDS_MeshCell's or SMDS_MeshNode's )
+ *        and bind some attributes to elements:
+ *        element ID, element VTK ID, sub-mesh ID, position on shape.
+ *
+ * Elements are allocated by chunks, so there are used and non-used elements
+ */
+class SMDS_ElementFactory
+{
+protected:
+  bool                     myIsNodal;          // what to allocate: nodes or cells
+  SMDS_Mesh*               myMesh;
+  TChunkVector             myChunks;           // array of chunks of elements
+  TChunkPtrSet             myChunksWithUnused; // sorted chunks having unused elements
+  std::vector< vtkIdType > myVtkIDs;           // myVtkIDs[ smdsID-1 ] == vtkID
+  std::vector< int >       mySmdsIDs;          // mySmdsIDs[ vtkID ] == smdsID - 1
+  int                      myNbUsedElements;   // counter of elements
+
+  friend class SMDS_ElementChunk;
+
+public:
+
+  SMDS_ElementFactory( SMDS_Mesh* mesh, const bool isNodal=false );
+  virtual ~SMDS_ElementFactory();
+
+  //! Return minimal ID of a non-used element
+  int GetFreeID();
+
+  //! Return maximal ID of an used element
+  int GetMaxID();
+
+  //! Return minimal ID of an used element
+  int GetMinID();
+
+  //! Return an element by ID. NULL if the element with the given ID is already used
+  SMDS_MeshElement* NewElement( const int id );
+
+  //! Return a SMDS_MeshCell by ID. NULL if the cell with the given ID is already used
+  SMDS_MeshCell* NewCell( const int id ) { return static_cast<SMDS_MeshCell*>( NewElement( id )); }
+
+  //! Return an used element by ID. NULL if the element with the given ID is not yet used
+  const SMDS_MeshElement* FindElement( const int id ) const;
+
+  //! Return a number of used elements
+  int NbUsedElements() const { return myNbUsedElements; }
+
+  //! Return an iterator on all element filtered using a given filter.
+  //  nbElemsToReturn is used to optimize by stopping the iteration as soon as
+  //  all elements satisfying filtering condition encountered.
+  template< class ElemIterator >
+  boost::shared_ptr< ElemIterator > GetIterator( SMDS_MeshElement::Filter* filter,
+                                                 size_t nbElemsToReturn = -1 );
+
+  //! Return an iterator on all element assigned to a given shape.
+  //  nbElemsToReturn is used to optimize by stopping the iteration as soon as
+  //  all elements assigned to the shape encountered.
+  template< class ElemIterator >
+  boost::shared_ptr< ElemIterator > GetShapeIterator( int shapeID, size_t nbElemsToReturn );
+
+  //! Mark the element as non-used
+  void Free( const SMDS_MeshElement* );
+
+  //! Return an SMDS ID by a Vtk one
+  int FromVtkToSmds( vtkIdType vtkID );
+
+  //! De-allocate all elements
+  virtual void Clear();
+
+  //! Remove unused elements located not at the end of the last chunk.
+  //  Minimize allocated memory
+  virtual void Compact(std::vector<int>& idCellsOldToNew);
+
+  //! Return true if Compact() will change IDs of elements
+  virtual bool CompactChangePointers();
+
+  //! Return a number of elements in a chunk
+  static int ChunkSize();
+};
+
+//------------------------------------------------------------------------------------
+/*!
+ * \brief Allocate SMDS_MeshNode's
+ */
+class SMDS_NodeFactory : public SMDS_ElementFactory
+{
+  std::vector<char> myShapeDim; // dimension of shapes
+
+public:
+
+  SMDS_NodeFactory( SMDS_Mesh* mesh );
+  ~SMDS_NodeFactory();
+
+  //! Return a SMDS_MeshNode by ID. NULL if the node with the given ID is already used
+  SMDS_MeshNode* NewNode( int id ) { return (SMDS_MeshNode*) NewElement(id); }
+
+  //! Return an used node by ID. NULL if the node with the given ID is not yet used
+  const SMDS_MeshNode* FindNode( int id ) { return (const SMDS_MeshNode*) FindElement(id); }
+
+  //! Set a total number of sub-shapes in the main shape
+  void SetNbShapes( size_t nbShapes );
+
+  //! Return a dimension of a shape
+  int  GetShapeDim( int shapeID ) const;
+
+  //! Set a dimension of a shape
+  void SetShapeDim( int shapeID, int dim );
+
+  //! De-allocate all nodes
+  virtual void Clear();
+
+  //! Remove unused nodes located not at the end of the last chunk.
+  //  Minimize allocated memory
+  virtual void Compact(std::vector<int>& idNodesOldToNew);
+
+  //! Return true if Compact() will change IDs of node
+  virtual bool CompactChangePointers();
+};
+
+//------------------------------------------------------------------------------------
+/*!
+ * \brief Range of elements in a chunk having the same attribute value
+ */
+template< typename ATTR>
+struct _Range
+{
+  typedef ATTR attr_t;
+
+  attr_t myValue; // common attribute value
+  int    my1st;   // index in the chunk of the 1st element 
+  _Range( int i0 = 0, attr_t v = 0 ): myValue( v ), my1st( i0 ) {}
+
+  bool operator < (const _Range& other) const { return my1st < other.my1st; }
+};
+
+typedef std::vector< std::pair< int, int > > TIndexRanges;
+
+//------------------------------------------------------------------------------------
+/*!
+ * \brief Sorted set of ranges
+ */
+template< class RANGE >
+struct _RangeSet
+{
+  typedef typename RANGE::attr_t              attr_t;
+  typedef boost::container::flat_set< RANGE > set_t;
+  typedef typename set_t::const_iterator      set_iterator;
+
+  set_t mySet;
+
+  _RangeSet() { mySet.insert( RANGE( 0, 0 )); }
+
+  /*!
+   * \brief Return a number of ranges
+   */
+  size_t Size() const { return mySet.size(); }
+
+  /*!
+   * \brief Return a mutable _Range::my1st of a range pointed by an iterator
+   */
+  int&   First( set_iterator rangePtr ) { return const_cast< int& >( rangePtr->my1st ); }
+
+  /*!
+   * \brief Return a number of elements in a range pointed by an iterator
+   */
+  size_t Size( set_iterator rangePtr ) const
+  {
+    int next1st =
+      ( rangePtr + 1 == mySet.end() ) ? SMDS_ElementFactory::ChunkSize() : ( rangePtr + 1 )->my1st;
+    return next1st - rangePtr->my1st;
+  }
+
+  /*!
+   * \brief Return ranges of indices (from,to) of elements having a given value
+   */
+  bool GetIndices( const attr_t theValue, TIndexRanges & theIndices,
+                   const attr_t* theMinValue = 0, const attr_t* theMaxValue = 0) const
+  {
+    bool isFound = false;
+
+    if ( sizeof( attr_t ) == sizeof( int ) && theMinValue )
+      if ( theValue < *theMinValue || theValue > *theMaxValue )
+        return isFound;
+
+    for ( set_iterator it = mySet.begin(); it < mySet.end(); ++it )
+    {
+      if ( it->myValue == theValue )
+      {
+        theIndices.push_back( std::make_pair( it->my1st, it->my1st + Size( it )));
+        isFound = true;
+        ++it; // the next range value differs from theValue
+      }
+    }
+    return isFound;
+  }
+
+  /*!
+   * \brief Return value of an element attribute
+   *  \param [in] theIndex - element index
+   *  \return attr_t - attribute value
+   */
+  attr_t GetValue( int theIndex ) const
+  {
+    set_iterator r = mySet.upper_bound( theIndex ) - 1;
+    return r->myValue;
+  }
+
+  /*!
+   * \brief Change value of an element attribute
+   *  \param [in] theIndex - element index
+   *  \param [in] theValue - attribute value
+   *  \return attr_t - previous value
+   */
+  attr_t SetValue( int theIndex, attr_t theValue )
+  {
+    set_iterator rNext = mySet.upper_bound( theIndex );
+    set_iterator     r = rNext - 1;
+    int          rSize = Size( r ); // range size
+    attr_t      rValue = r->myValue;
+    if ( rValue == theValue )
+      return rValue; // it happens while compacting
+
+    if ( r->my1st == theIndex ) // theIndex is the first in the range
+    {
+      bool joinPrev = // can join theIndex to the previous range
+        ( r->my1st > 0 && ( r-1 )->myValue == theValue );
+
+      if ( rSize == 1 )
+      {
+        bool joinNext = // can join to the next range
+          ( rNext != mySet.end() && rNext->myValue == theValue );
+
+        if ( joinPrev )
+        {
+          if ( joinNext ) // && joinPrev
+          {
+            mySet.erase( r, r + 2 );
+          }
+          else // joinPrev && !joinNext
+          {
+            mySet.erase( r );
+          }
+        }
+        else
+        {
+          if ( joinNext ) // && !joinPrev
+          {
+            r = mySet.erase( r ); // then r points to the next range
+            First( r )--;
+          }
+          else // !joinPrev && !joinNext
+          {
+            const_cast< attr_t & >( r->myValue ) = theValue;
+          }
+        }
+      }
+      else // if rSize > 1
+      {
+        if ( joinPrev )
+        {
+          First( r )++;
+        }
+        else
+        {
+          r = mySet.insert( r, RANGE( theIndex + 1, rValue )) - 1;
+          const_cast< attr_t & >( r->myValue ) = theValue;
+        }
+      }
+    }
+    else if ( r->my1st + rSize - 1 == theIndex ) // theIndex is last in the range
+    {
+      if ( rNext != mySet.end() && rNext->myValue == theValue ) // join to the next
+      {
+        First( rNext )--;
+      }
+      else
+      {
+        mySet.insert( r, RANGE( theIndex, theValue ));
+      }
+    }
+    else // theIndex in the middle of the range
+    {
+      r = mySet.insert( r, RANGE( theIndex,     theValue ));
+      r = mySet.insert( r, RANGE( theIndex + 1, rValue ));
+    }
+    return rValue;
+  }
+}; // struct _RangeSet
+
+
+typedef _Range< int >  _ShapeIDRange; // sub-mesh ID range
+typedef _Range< bool > _UsedRange;    // range of used elements
+
+typedef _RangeSet< _ShapeIDRange > TSubIDRangeSet;
+typedef _RangeSet< _UsedRange >    TUsedRangeSet;
+typedef boost::dynamic_bitset<>    TBitSet;
+typedef float                       TParam;
+
+//------------------------------------------------------------------------------------
+/*!
+ * \brief Allocate SMDS_MeshElement's (SMDS_MeshCell's or SMDS_MeshNode's )
+ *        and bind some attributes to elements:
+ *        element ID, sub-shape ID, isMarked flag, parameters on shape
+ */
+class SMDS_ElementChunk
+{
+  SMDS_ElementFactory* myFactory;     // holder of this chunk
+  SMDS_MeshElement*    myElements;    // array of elements
+  int                  my1stID;       // ID of myElements[0]
+  TBitSet              myMarkedSet;   // mark some elements
+  TUsedRangeSet        myUsedRanges;  // ranges of used/unused elements
+  TSubIDRangeSet       mySubIDRanges; // ranges of elements on the same sub-shape
+  int                  myMinSubID;    // min sub-shape ID
+  int                  myMaxSubID;    // max sub-shape ID
+  std::vector<TParam>  myPositions;   // UV parameters on shape: 2*param_t per an element
+
+public:
+
+  SMDS_ElementChunk( SMDS_ElementFactory* factory = 0, int id0 = 0 );
+  ~SMDS_ElementChunk();
+
+  //! Return an element by an index [0,ChunkSize()]
+  SMDS_MeshElement* Element(int index) { return & myElements[index]; }
+
+  //! Return an element by an index [0,ChunkSize()]
+  const SMDS_MeshElement* Element(int index) const { return & myElements[index]; }
+
+  //! Return ID of the first non-used element
+  int  GetUnusedID() const;
+
+  //! Mark an element as used
+  void UseElement( const int index );
+
+  //! Mark an element as non-used
+  void Free( const SMDS_MeshElement* e );
+
+  //! Check if a given range holds used or non-used elements
+  static bool IsUsed( const _UsedRange& r ) { return r.myValue; }
+
+  //! Return index of an element in the chunk
+  int Index( const SMDS_MeshElement* e ) const { return e - myElements; }
+
+  //! Return ID of the 1st element in the chunk
+  int Get1stID() const { return my1stID; }
+
+  //! Return pointer to on-shape-parameters of a node
+  TParam* GetPositionPtr( const SMDS_MeshElement* node, bool allocate=false );
+
+  //! Return ranges of used/non-used elements
+  const TUsedRangeSet&  GetUsedRanges() const { return myUsedRanges; }
+  const TUsedRangeSet&  GetUsedRangesMinMax( bool& min, bool& max ) const
+  { min = false; max = true; return myUsedRanges; }
+
+  //! Return ranges of elements assigned to sub-shapes and min/max of sub-shape IDs
+  const TSubIDRangeSet& GetSubIDRangesMinMax( int& min, int& max ) const
+  { min = myMinSubID; max = myMaxSubID; return mySubIDRanges; }
+
+  //! Minimize allocated memory
+  void Compact();
+
+  //! Print some data
+  void Dump() const; // debug
+
+
+  // Methods called by SMDS_MeshElement
+
+  int  GetID( const SMDS_MeshElement* e ) const;
+
+  int  GetVtkID( const SMDS_MeshElement* e ) const;
+  void SetVTKID( const SMDS_MeshElement* e, const vtkIdType id );
+
+  int  GetShapeID( const SMDS_MeshElement* e ) const;
+  void SetShapeID( const SMDS_MeshElement* e, int shapeID ) const;
+
+  bool IsMarked   ( const SMDS_MeshElement* e ) const;
+  void SetIsMarked( const SMDS_MeshElement* e, bool is );
+
+  SMDS_PositionPtr GetPosition( const SMDS_MeshNode* n ) const;
+  void SetPosition( const SMDS_MeshNode* n, const SMDS_PositionPtr& pos, int shapeID );
+
+  SMDS_Mesh* GetMesh() { return myFactory->myMesh; }
+};
+
+//------------------------------------------------------------------------------------
+/*!
+ * \brief Iterator on elements in chunks
+ */
+template< class ELEM_ITERATOR, class RANGE_SET >
+struct _ChunkIterator : public ELEM_ITERATOR
+{
+  typedef typename ELEM_ITERATOR::value_type    element_type;
+  typedef SMDS_MeshElement::Filter*             filter_ptr;
+  typedef typename RANGE_SET::attr_t            attr_type;
+  typedef const RANGE_SET& (SMDS_ElementChunk::*get_rangeset_fun)(attr_type&, attr_type&) const;
+
+  const SMDS_MeshElement* myElement;
+  TIndexRanges            myRanges;
+  int                     myRangeIndex;
+  const TChunkVector&     myChunks;
+  int                     myChunkIndex;
+  get_rangeset_fun        myGetRangeSetFun;
+  attr_type               myValue;
+  attr_type               myMinValue;
+  attr_type               myMaxValue;
+  filter_ptr              myFilter;
+  size_t                  myNbElemsToReturn;
+  size_t                  myNbReturned;
+
+  _ChunkIterator( const TChunkVector &      theChunks,
+                  get_rangeset_fun          theGetRangeSetFun,
+                  attr_type                 theAttrValue,
+                  SMDS_MeshElement::Filter* theFilter,
+                  size_t                    theNbElemsToReturn = -1):
+    myElement( 0 ),
+    myRangeIndex( 0 ),
+    myChunks( theChunks ),
+    myChunkIndex( -1 ),
+    myGetRangeSetFun( theGetRangeSetFun ),
+    myValue( theAttrValue ),
+    myFilter( theFilter ),
+    myNbElemsToReturn( theNbElemsToReturn ),
+    myNbReturned( 0 )
+  {
+    next();
+  }
+  ~_ChunkIterator()
+  {
+    delete myFilter;
+  }
+
+  virtual bool more()
+  {
+    return myElement;
+  }
+
+  virtual element_type next()
+  {
+    element_type result = (element_type) myElement;
+    myNbReturned += bool( result );
+
+    myElement = 0;
+    if ( myNbReturned < myNbElemsToReturn )
+      while ( ! nextInRange() )
+      {
+        if ( ++myRangeIndex >= (int)myRanges.size() )
+        {
+          myRanges.clear();
+          myRangeIndex = 0;
+          while ( ++myChunkIndex < (int)myChunks.size() &&
+                  !getRangeSet().GetIndices( myValue, myRanges, &myMinValue, &myMaxValue ))
+            ;
+          if ( myChunkIndex >= (int)myChunks.size() )
+            break;
+        }
+      }
+    return result;
+  }
+
+  bool nextInRange()
+  {
+    if ( myRangeIndex < (int)myRanges.size() )
+    {
+      std::pair< int, int > & range = myRanges[ myRangeIndex ];
+      while ( range.first < range.second && !myElement )
+      {
+        myElement = myChunks[ myChunkIndex ].Element( range.first++ );
+        if ( !(*myFilter)( myElement ))
+          myElement = 0;
+      }
+    }
+    return myElement;
+  }
+
+  const RANGE_SET& getRangeSet()
+  {
+    return ( myChunks[  myChunkIndex ].*myGetRangeSetFun )( myMinValue, myMaxValue );
+  }
+}; // struct _ChunkIterator
+
+
+template< class ElemIterator >
+boost::shared_ptr< ElemIterator >
+SMDS_ElementFactory::GetIterator( SMDS_MeshElement::Filter* filter,
+                                  size_t                    nbElemsToReturn )
+{
+  typedef _ChunkIterator< ElemIterator, TUsedRangeSet > TChuckIterator;
+  return boost::make_shared< TChuckIterator >( myChunks,
+                                               & SMDS_ElementChunk::GetUsedRangesMinMax,
+                                               /*isUsed=*/true,
+                                               filter,
+                                               nbElemsToReturn );
+}
+
+template< class ElemIterator >
+boost::shared_ptr< ElemIterator >
+SMDS_ElementFactory::GetShapeIterator( int shapeID, size_t nbElemsToReturn )
+{
+  typedef _ChunkIterator< ElemIterator, TSubIDRangeSet > TChuckIterator;
+  return boost::make_shared< TChuckIterator >( myChunks,
+                                               & SMDS_ElementChunk::GetSubIDRangesMinMax,
+                                               /*shapeID=*/shapeID,
+                                               new SMDS_MeshElement::NonNullFilter(),
+                                               nbElemsToReturn );
+}
+
+#endif
diff --git a/src/SMDS/SMDS_ElementHolder.cxx b/src/SMDS/SMDS_ElementHolder.cxx
new file mode 100644 (file)
index 0000000..0913590
--- /dev/null
@@ -0,0 +1,122 @@
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : SMDS_ElementHolder.cxx
+//  Module : SMESH
+//
+
+#include "SMDS_ElementHolder.hxx"
+
+#include "ObjectPool.hxx"
+#include "SMDS_CellOfNodes.hxx"
+#include "SMDS_Mesh.hxx"
+
+//=======================================================================
+//function : SMDS_ElementHolder
+//purpose  : register self in the mesh
+//=======================================================================
+
+SMDS_ElementHolder::SMDS_ElementHolder( const SMDS_Mesh* mesh )
+  : myMesh( const_cast< SMDS_Mesh* >( mesh ))
+{
+  myPtrInMesh = myMesh->myElemHolders.insert( this ).first;
+}
+
+//=======================================================================
+//function : ~SMDS_ElementHolder
+//purpose  : un-register self from the mesh
+//=======================================================================
+
+SMDS_ElementHolder::~SMDS_ElementHolder()
+{
+  myMesh->myElemHolders.erase( myPtrInMesh );
+}
+
+//=======================================================================
+//function : beforeCompacting
+//purpose  : store vtkIDs of elements
+//=======================================================================
+
+void SMDS_ElementHolder::beforeCompacting()
+{
+  int i = 0;
+  for ( SMDS_ElemIteratorPtr it = getElements(); it->more(); ++i )
+  {
+    const SMDS_MeshElement* e = it->next();
+    if ( !e ) continue;
+    if ( e->IsNull() && !dynamic_cast<const SMDS_CellOfNodes*>( e ))
+      continue; // removed element
+    myIsNode.push_back( e->GetType() == SMDSAbs_Node );
+    if ( myMesh->Contains( e ))
+    {
+      myVtkIDs.push_back( e->GetVtkID() );
+    }
+    else
+    {
+      myExternalElems.push_back( e );
+      myVtkIDs.push_back( -1 * (int)myExternalElems.size() );
+    }
+  }
+}
+
+//=======================================================================
+//function : restoreElements
+//purpose  : restore pointers to elements
+//=======================================================================
+
+void SMDS_ElementHolder::restoreElements( const std::vector<int>& idNodesOldToNew,
+                                          const std::vector<int>& idCellsOldToNew )
+{
+  tmpClear();
+
+  const SMDS_MeshElement* elem;
+
+  std::vector< bool >::iterator isNode = myIsNode.begin();
+  for ( size_t i = 0; i < myVtkIDs.size(); ++i, ++isNode )
+  {
+    int vtkID = myVtkIDs[i];
+    if ( vtkID < 0 )
+    {
+      elem = myExternalElems[ (-vtkID)-1 ];
+    }
+    else if ( *isNode )
+    {
+      if ( vtkID < (int)idNodesOldToNew.size() )
+        elem = myMesh->FindNodeVtk( idNodesOldToNew[ vtkID ]);
+      else
+        elem = myMesh->FindNodeVtk( vtkID );
+    }
+    else
+    {
+      if ( vtkID < (int)idCellsOldToNew.size() )
+        elem = myMesh->FindElementVtk( idCellsOldToNew[ vtkID ]);
+      else
+        elem = myMesh->FindElementVtk( vtkID );
+    }
+    if ( elem )
+      add( elem );
+  }
+  clearVector( myExternalElems );
+  clearVector( myVtkIDs );
+  clearVector( myIsNode );
+
+  compact();
+}
diff --git a/src/SMDS/SMDS_ElementHolder.hxx b/src/SMDS/SMDS_ElementHolder.hxx
new file mode 100644 (file)
index 0000000..f05774b
--- /dev/null
@@ -0,0 +1,93 @@
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  File   : SMDS_ElementHolder.hxx
+//  Module : SMESH
+//
+#ifndef _SMDS_ElementHolder_HeaderFile
+#define _SMDS_ElementHolder_HeaderFile
+
+#include "SMESH_SMDS.hxx"
+
+#include "SMDS_ElemIterator.hxx"
+
+#include <vector>
+#include <set>
+
+class SMDS_Mesh;
+class SMDS_MeshElement;
+
+//------------------------------------------------------------------------------------
+/*!
+ * \brief Base class of object holding SMDS_MeshElement pointers.
+ *        Registering such an object in SMDS_Mesh assures that the
+ *        pointers remain valid after compacting the mesh
+ */
+class SMDS_EXPORT SMDS_ElementHolder
+{
+ public:
+
+  //! register self in the mesh
+  SMDS_ElementHolder( const SMDS_Mesh* mesh );
+
+  //! un-register self from the mesh
+  virtual ~SMDS_ElementHolder();
+
+
+ protected:
+
+  //!< the descendant object return its elements just before the mesh compacting
+  virtual SMDS_ElemIteratorPtr getElements() = 0;
+
+  //!< the descendant object temporary remove its elements
+  virtual void tmpClear() = 0;
+
+  //!< the descendant object re-add its elements after the mesh compacting
+  virtual void add( const SMDS_MeshElement* element ) = 0;
+
+  //!< the descendant squeeze its element storage after re-adding elements
+  virtual void compact() = 0;
+
+  //!< allow the descendant treat its elements before mesh clearing
+  virtual void clear() {}
+
+  SMDS_Mesh* myMesh;
+
+
+ private: // methods called by SMDS_Mesh
+
+  friend class SMDS_Mesh;
+
+  //! store vtkIDs of elements
+  void beforeCompacting();
+
+  //! restore pointers to elements
+  void restoreElements( const std::vector<int>& idNodessOldToNew,
+                        const std::vector<int>& idCellsOldToNew );
+
+
+  std::vector<const SMDS_MeshElement*>      myExternalElems; //!< elements not contained in the mesh
+  std::vector< int >                        myVtkIDs;        //!< vtk IDs of elements
+  std::vector< bool >                       myIsNode;
+  std::set< SMDS_ElementHolder* >::iterator myPtrInMesh;
+};
+
+#endif
diff --git a/src/SMDS/SMDS_FaceOfEdges.cxx b/src/SMDS/SMDS_FaceOfEdges.cxx
deleted file mode 100644 (file)
index 67ff4f6..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-//  SMESH SMDS : implementation of Salome mesh data structure
-//
-#ifdef _MSC_VER
-#pragma warning(disable:4786)
-#endif
-
-#include "SMDS_FaceOfEdges.hxx"
-#include "SMDS_IteratorOfElements.hxx"
-#include "SMDS_MeshNode.hxx"
-#include "utilities.h"
-
-using namespace std;
-
-//=======================================================================
-//function : NbEdges
-//purpose  : 
-//=======================================================================
-
-int SMDS_FaceOfEdges::NbEdges() const
-{
-        return myNbEdges;
-}
-
-int SMDS_FaceOfEdges::NbFaces() const
-{
-        return 1;
-}
-//=======================================================================
-//function : Print
-//purpose  : 
-//=======================================================================
-
-void SMDS_FaceOfEdges::Print(ostream & OS) const
-{
-        OS << "face <" << GetID() << " > : ";
-        int i;
-        for (i = 0; i < NbEdges() - 1; i++) OS << myEdges[i] << ",";
-        OS << myEdges[i] << ") " << endl;
-}
-
-SMDSAbs_ElementType SMDS_FaceOfEdges::GetType() const
-{
-        return SMDSAbs_Face;
-}
-
-//=======================================================================
-//function : elementsIterator
-//purpose  : 
-//=======================================================================
-
-class SMDS_FaceOfEdges_MyIterator:public SMDS_ElemIterator
-{
-  const SMDS_MeshEdge* const *mySet;
-  int myLength;
-  int index;
- public:
-  SMDS_FaceOfEdges_MyIterator(const SMDS_MeshEdge* const *s, int l):
-    mySet(s),myLength(l),index(0) {}
-
-  bool more()
-  {
-    return index<myLength;
-  }
-
-  const SMDS_MeshElement* next()
-  {
-    index++;
-    return mySet[index-1];
-  }     
-};
-
-SMDS_ElemIteratorPtr SMDS_FaceOfEdges::elementsIterator
-                         (SMDSAbs_ElementType type) const
-{
-  switch(type)
-  {
-  case SMDSAbs_Face:
-    return SMDS_MeshElement::elementsIterator(SMDSAbs_Face);
-  case SMDSAbs_Edge:
-    return SMDS_ElemIteratorPtr(new SMDS_FaceOfEdges_MyIterator(myEdges,myNbEdges));
-  default:
-    return SMDS_ElemIteratorPtr
-      (new SMDS_IteratorOfElements
-       (this,type, SMDS_ElemIteratorPtr
-        (new SMDS_FaceOfEdges_MyIterator(myEdges,myNbEdges))));
-  }
-}
-
-SMDS_FaceOfEdges::SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1,
-                                   const SMDS_MeshEdge* edge2,
-                                   const SMDS_MeshEdge* edge3)
-{
-  //MESSAGE("****************************************************** SMDS_FaceOfEdges");
-        myNbEdges = 3;
-        myEdges[0]=edge1;
-        myEdges[1]=edge2;
-        myEdges[2]=edge3;
-        myEdges[3]=0;
-}
-
-SMDS_FaceOfEdges::SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1,
-                                   const SMDS_MeshEdge* edge2,
-                                   const SMDS_MeshEdge* edge3,
-                                   const SMDS_MeshEdge* edge4)
-{
-  //MESSAGE("****************************************************** SMDS_FaceOfEdges");
-        myNbEdges = 4;
-        myEdges[0]=edge1;
-        myEdges[1]=edge2;
-        myEdges[2]=edge3;
-        myEdges[3]=edge4;       
-}
-
-/*bool operator<(const SMDS_FaceOfEdges& f1, const SMDS_FaceOfEdges& f2)
-{
-        set<SMDS_MeshNode> set1,set2;
-        SMDS_ElemIteratorPtr it;
-        const SMDS_MeshNode * n;
-
-        it=f1.nodesIterator();
-
-        while(it->more())
-        {
-                n=static_cast<const SMDS_MeshNode *>(it->next());
-                set1.insert(*n);
-        }
-
-        delete it;
-        it=f2.nodesIterator();
-        
-        while(it->more())
-        {       
-                n=static_cast<const SMDS_MeshNode *>(it->next());
-                set2.insert(*n);
-        }
-
-        delete it;
-        return set1<set2;       
-
-}*/
-
-
-int SMDS_FaceOfEdges::NbNodes() const
-{
-  return myEdges[0]->NbNodes() + myEdges[1]->NbNodes() + myEdges[2]->NbNodes() +
-    ( myNbEdges == 4 ? myEdges[3]->NbNodes() : 0 ) - myNbEdges;
-}
-
-/*!
- * \brief Return node by its index
- * \param ind - node index
- * \retval const SMDS_MeshNode* - the node
- */
-const SMDS_MeshNode* SMDS_FaceOfEdges::GetNode(const int ind) const
-{
-  int index = ind;
-  for ( int i = 0; i < myNbEdges; ++i ) {
-    if ( index >= myEdges[ i ]->NbNodes() )
-      index -= myEdges[ i ]->NbNodes();
-    else
-      return myEdges[ i ]->GetNode( index );
-  }
-  return 0;
-}
-
-SMDSAbs_EntityType SMDS_FaceOfEdges::GetEntityType() const
-{
-  return myNbEdges == 3 ? SMDSEntity_Triangle : SMDSEntity_Quadrangle;
-}
-
-SMDSAbs_GeometryType SMDS_FaceOfEdges::GetGeomType() const
-{
-  return myNbEdges == 3 ? SMDSGeom_TRIANGLE : SMDSGeom_QUADRANGLE;
-}
diff --git a/src/SMDS/SMDS_FaceOfEdges.hxx b/src/SMDS/SMDS_FaceOfEdges.hxx
deleted file mode 100644 (file)
index 8bfc1d3..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-//  SMESH SMDS : implementation of Salome mesh data structure
-//
-#ifndef _SMDS_FaceOfEdges_HeaderFile
-#define _SMDS_FaceOfEdges_HeaderFile
-
-#include "SMESH_SMDS.hxx"
-
-#include "SMDS_MeshFace.hxx"
-#include "SMDS_MeshEdge.hxx"
-#include "SMDS_Iterator.hxx"
-
-#include <iostream>
-
-
-class SMDS_EXPORT SMDS_FaceOfEdges:public SMDS_MeshFace
-{
-  public:
-        void Print(std::ostream & OS) const;
-        SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1,
-                         const SMDS_MeshEdge* edge2,
-                         const SMDS_MeshEdge* edge3);
-        SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1,
-                         const SMDS_MeshEdge* edge2,
-                         const SMDS_MeshEdge* edge3,
-                         const SMDS_MeshEdge* edge4);
-                
-        virtual SMDSAbs_ElementType  GetType() const;
-        virtual SMDSAbs_EntityType   GetEntityType() const;
-        virtual SMDSAbs_GeometryType GetGeomType() const;
-        virtual bool ChangeNodes(const SMDS_MeshNode* nodes[],
-                                 const int            nbNodes) {return false;}
-        virtual int NbNodes() const;
-        virtual int NbEdges() const;
-        virtual int NbFaces() const;
-        virtual const SMDS_MeshNode* GetNode(const int ind) const;
-
-  protected:
-        virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const;
-
-  private:
-        const SMDS_MeshEdge* myEdges[4];
-        int                  myNbEdges;
-
-};
-
-#endif
index dfd3b73..0b7f9ac 100644 (file)
 #pragma warning(disable:4786)
 #endif
 
-#include "SMDS_SetIterator.hxx"
 #include "SMDS_FaceOfNodes.hxx"
-#include "SMDS_IteratorOfElements.hxx"
+
+#include "SMDS_SetIterator.hxx"
 #include "SMDS_MeshNode.hxx"
 #include "SMDS_Mesh.hxx"
 
-#include "utilities.h"
+#include <utilities.h>
 
-using namespace std;
+#include <boost/make_shared.hpp>
 
 //=======================================================================
 //function : NbEdges
@@ -43,17 +43,25 @@ using namespace std;
 
 int SMDS_FaceOfNodes::NbEdges() const
 {
-        return NbNodes();
+  return NbNodes();
 }
 
 int SMDS_FaceOfNodes::NbFaces() const
 {
-        return 1;
+  return 1;
 }
 
 int SMDS_FaceOfNodes::NbNodes() const
 {
-        return myNbNodes;
+  return myNbNodes;
+}
+
+int SMDS_FaceOfNodes::GetNodeIndex( const SMDS_MeshNode* node ) const
+{
+  for ( int i = 0; i < myNbNodes; ++i )
+    if ( myNodes[i] == node )
+      return i;
+  return -1;
 }
 
 //=======================================================================
@@ -63,81 +71,31 @@ int SMDS_FaceOfNodes::NbNodes() const
 
 void SMDS_FaceOfNodes::Print(ostream & OS) const
 {
-        OS << "face <" << GetID() << " > : ";
-        int i;
-        for (i = 0; i < NbNodes() - 1; i++) OS << myNodes[i] << ",";
-        OS << myNodes[i] << ") " << endl;
+  OS << "face <" << GetID() << " > : ";
+  int i;
+  for (i = 0; i < NbNodes() - 1; i++) OS << myNodes[i] << ",";
+  OS << myNodes[i] << ") " << endl;
 }
 
-//=======================================================================
-//function : elementsIterator
-//purpose  : 
-//=======================================================================
-
-class SMDS_FaceOfNodes_MyIterator:public SMDS_NodeArrayElemIterator
+SMDS_ElemIteratorPtr SMDS_FaceOfNodes::nodesIterator() const
 {
- public:
-  SMDS_FaceOfNodes_MyIterator(const SMDS_MeshNode* const *s, int l):
-    SMDS_NodeArrayElemIterator( s, & s[ l ] ) {}
-};
-
-/// ===================================================================
-/*!
- * \brief Iterator on edges of face
- */
-/// ===================================================================
+  return boost::make_shared< SMDS_NodeArrayElemIterator >( &myNodes[0], &myNodes[0] + NbNodes() );
+}
 
-class _MyEdgeIterator : public SMDS_ElemIterator
-{
-  vector< const SMDS_MeshElement* > myElems;
-  size_t                            myIndex;
-public:
-  _MyEdgeIterator(const SMDS_FaceOfNodes* face):myIndex(0) {
-    myElems.reserve( face->NbNodes() );
-    for ( int i = 0; i < face->NbNodes(); ++i ) {
-      const SMDS_MeshElement* edge =
-        SMDS_Mesh::FindEdge( face->GetNode( i ), face->GetNodeWrap( i + 1 ));
-      if ( edge )
-        myElems.push_back( edge );
-    }
-  }
-  /// Return true if and only if there are other object in this iterator
-  virtual bool more() { return myIndex < myElems.size(); }
-
-  /// Return the current object and step to the next one
-  virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; }
-};
-
-SMDS_ElemIteratorPtr SMDS_FaceOfNodes::elementsIterator( SMDSAbs_ElementType type ) const
+SMDS_NodeIteratorPtr SMDS_FaceOfNodes::nodeIterator() const
 {
-  switch(type)
-  {
-  case SMDSAbs_Face:
-    return SMDS_MeshElement::elementsIterator(SMDSAbs_Face);
-  case SMDSAbs_Node:
-    return SMDS_ElemIteratorPtr(new SMDS_FaceOfNodes_MyIterator(myNodes,myNbNodes));
-  case SMDSAbs_Edge:
-    return SMDS_ElemIteratorPtr(new _MyEdgeIterator( this ));
-    break;
-  default:
-    return SMDS_ElemIteratorPtr
-      (new SMDS_IteratorOfElements
-       (this,type,SMDS_ElemIteratorPtr
-        (new SMDS_FaceOfNodes_MyIterator(myNodes,myNbNodes))));
-  }
-  return SMDS_ElemIteratorPtr();
+  return boost::make_shared< SMDS_NodeArrayIterator >( &myNodes[0], &myNodes[0] + NbNodes() );
 }
 
 SMDS_FaceOfNodes::SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
                                    const SMDS_MeshNode* node2,
                                    const SMDS_MeshNode* node3)
 {
-  //MESSAGE("******************************************************* SMDS_FaceOfNodes");
-        myNbNodes = 3;
-        myNodes[0]=node1;
-        myNodes[1]=node2;
-        myNodes[2]=node3;
-        myNodes[3]=0;
+  myNbNodes = 3;
+  myNodes[0]=node1;
+  myNodes[1]=node2;
+  myNodes[2]=node3;
+  myNodes[3]=0;
 }
 
 SMDS_FaceOfNodes::SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
@@ -145,12 +103,11 @@ SMDS_FaceOfNodes::SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
                                    const SMDS_MeshNode* node3,
                                    const SMDS_MeshNode* node4)
 {
-  //MESSAGE("******************************************************* SMDS_FaceOfNodes");
-        myNbNodes = 4;
-        myNodes[0]=node1;
-        myNodes[1]=node2;
-        myNodes[2]=node3;
-        myNodes[3]=node4;       
+  myNbNodes = 4;
+  myNodes[0]=node1;
+  myNodes[1]=node2;
+  myNodes[2]=node3;
+  myNodes[3]=node4;       
 }
 bool SMDS_FaceOfNodes::ChangeNodes(const SMDS_MeshNode* nodes[],
                                    const int            nbNodes)
index fec0b09..7e25a90 100644 (file)
 
 #include "SMESH_SMDS.hxx"
 
-#include "SMDS_MeshFace.hxx"
-#include "SMDS_MeshNode.hxx"
-#include "SMDS_Iterator.hxx"
+#include "SMDS_CellOfNodes.hxx"
 
-#include <iostream>
-
-class SMDS_EXPORT SMDS_FaceOfNodes:public SMDS_MeshFace
+class SMDS_EXPORT SMDS_FaceOfNodes: public SMDS_CellOfNodes
 {
-  public:
-        void Print(std::ostream & OS) const;
-        SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
-                         const SMDS_MeshNode* node2,
-                         const SMDS_MeshNode* node3);
-        SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
-                         const SMDS_MeshNode* node2,
-                         const SMDS_MeshNode* node3,
-                         const SMDS_MeshNode* node4);
-        bool ChangeNodes(const SMDS_MeshNode* nodes[],
-                         const int            nbNodes);
-        int NbEdges() const;
-        int NbFaces() const;
-        int NbNodes() const;
+ public:
+  void Print(std::ostream & OS) const;
+  SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
+                   const SMDS_MeshNode* node2,
+                   const SMDS_MeshNode* node3);
+  SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
+                   const SMDS_MeshNode* node2,
+                   const SMDS_MeshNode* node3,
+                   const SMDS_MeshNode* node4);
+  virtual bool ChangeNodes(const SMDS_MeshNode* nodes[],
+                           const int            nbNodes);
+  virtual int  NbEdges() const;
+  virtual int  NbFaces() const;
+  virtual int  NbNodes() const;
+
+  virtual int  NbCornerNodes() const { return NbNodes(); }
+  virtual int  GetNodeIndex( const SMDS_MeshNode* node ) const;
+
+  virtual bool IsPoly() const { return false; }
+  virtual bool IsQuadratic() const  { return false; }
+
+  virtual SMDS_ElemIteratorPtr nodesIterator() const;
+  virtual SMDS_NodeIteratorPtr nodeIterator() const;
 
-  /*!
-   * \brief Return node by its index
-    * \param ind - node index
-    * \retval const SMDS_MeshNode* - the node
-   */
   virtual const SMDS_MeshNode* GetNode(const int ind) const;
 
+  virtual SMDSAbs_ElementType  GetType() const { return SMDSAbs_Face; }
   virtual SMDSAbs_EntityType   GetEntityType() const;
   virtual SMDSAbs_GeometryType GetGeomType() const;
 
-  protected:
-        SMDS_ElemIteratorPtr
-                elementsIterator(SMDSAbs_ElementType type) const;
-
-  private:
-        const SMDS_MeshNode* myNodes[4];
-        int                  myNbNodes;
+ private:
+  const SMDS_MeshNode* myNodes[4];
+  int                  myNbNodes;
 
 };
 
index ae12dc3..3eb3c16 100644 (file)
 //  Module : SMESH
 //
 #include "SMDS_FacePosition.hxx"
-
-#include "utilities.h"
-
-using namespace std;
+#include "SMDS_EdgePosition.hxx"
 
 //=======================================================================
 //function : SMDS_FacePosition
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 SMDS_FacePosition::SMDS_FacePosition(const double aUParam,
                                      const double aVParam)
-   : myUParameter(aUParam),myVParameter(aVParam)
 {
-  //MESSAGE("******************************************************** SMDS_FacePosition");
+  SetParameters( aUParam,aVParam );
 }
 
-/**
-*/
+//=======================================================================
+//function : GetTypeOfPosition
+//purpose  :
+//=======================================================================
+
 SMDS_TypeOfPosition SMDS_FacePosition::GetTypeOfPosition() const
 {
-        return SMDS_TOP_FACE;
+  return SMDS_TOP_FACE;
 }
 
 void SMDS_FacePosition::SetUParameter(double aUparam)
 {
-        myUParameter = aUparam;
+  myParameter[0] = aUparam;
 }
 
 //=======================================================================
 //function : SetVParameter
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SMDS_FacePosition::SetVParameter(double aVparam)
 {
-        myVParameter = aVparam;
+  myParameter[1] = aVparam;
 }
 
 //=======================================================================
 //function : GetUParameter
-//purpose  : 
+//purpose  :
 //=======================================================================
 
-double SMDS_FacePosition::GetUParameter() const 
+double SMDS_FacePosition::GetUParameter() const
 {
-        return myUParameter;
+  return myParameter[0];
 }
 
 //=======================================================================
 //function : GetVParameter
-//purpose  : 
+//purpose  :
 //=======================================================================
 
-double SMDS_FacePosition::GetVParameter() const 
+double SMDS_FacePosition::GetVParameter() const
 {
-        return myVParameter;
+  return myParameter[1];
 }
 
 //=======================================================================
@@ -92,6 +91,6 @@ double SMDS_FacePosition::GetVParameter() const
 
 void SMDS_FacePosition::SetParameters(double aUparam, double aVparam)
 {
-  myUParameter = aUparam;
-  myVParameter = aVparam;
+  myParameter[0] = aUparam;
+  myParameter[1] = aVparam;
 }
index 4501588..a36e300 100644 (file)
 
 class SMDS_EXPORT SMDS_FacePosition:public SMDS_Position
 {
+ public:
+  SMDS_FacePosition(double aUParam=0, double aVParam=0);
+  SMDS_TypeOfPosition GetTypeOfPosition() const;
+  virtual void SetUParameter(double aUparam);
+  virtual void SetVParameter(double aVparam);
+  virtual void SetParameters(double aUparam, double aVparam);
+  virtual double GetUParameter() const;
+  virtual double GetVParameter() const;
+  virtual const double* GetParameters() const { return &myParameter[0]; }
 
-  public:
-        SMDS_FacePosition(double aUParam=0, double aVParam=0);
-        SMDS_TypeOfPosition GetTypeOfPosition() const;
-        void SetUParameter(double aUparam);
-        void SetVParameter(double aVparam);
-        void SetParameters(double aUparam, double aVparam);
-        double GetUParameter() const;
-        double GetVParameter() const;
-
-  private:
-        double myUParameter;
-        double myVParameter;
+ private:
+  double myParameter[2];
 };
 #endif
index f20d706..5613249 100644 (file)
 #ifndef _SMDS_Iterator_HeaderFile
 #define _SMDS_Iterator_HeaderFile
 
-#include "SMESH_SMDS.hxx"
-
 ///////////////////////////////////////////////////////////////////////////////
 ///Abstract class for iterators
 ///@author Jerome Robert
 ///////////////////////////////////////////////////////////////////////////////
 template<typename VALUE> class SMDS_Iterator
 {
-  public:
-        /// Return true if and only if there are other object in this iterator
-          virtual bool more()=0;
-        
-        /// Return the current object and step to the next one
-          virtual VALUE next()=0;
+public:
+
+  typedef VALUE value_type;
+
+  /// Return true if and only if there are other object in this iterator
+  virtual bool more()=0;
+
+  /// Return the current object and step to the next one
+  virtual VALUE next()=0;
         
-        /// Delete the current element and step to the next one
-        virtual void remove(){}
+  /// Delete the current element and step to the next one
+  virtual void remove(){}
         
-        /// Provide virtual destructor just for case if some derived iterator
-        /// must have a destructor
-        virtual ~SMDS_Iterator(){}
+  /// Provide virtual destructor just for case if some derived iterator
+  /// must have a destructor
+  virtual ~SMDS_Iterator(){}
 };
 
 #endif
diff --git a/src/SMDS/SMDS_IteratorOfElements.cxx b/src/SMDS/SMDS_IteratorOfElements.cxx
deleted file mode 100644 (file)
index 3d125fc..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-//  SMESH SMDS : implementation of Salome mesh data structure
-//
-#ifdef _MSC_VER
-#pragma warning(disable:4786)
-#endif
-
-#include "SMDS_IteratorOfElements.hxx"
-
-bool SMDS_IteratorOfElements::subMore()
-{
-        if((t2Iterator.get()==NULL)||(!t2Iterator->more()))
-        {
-                if(t1Iterator->more())
-                {
-                        t2Iterator=t1Iterator->next()->elementsIterator(myType);
-                        return subMore();
-                }
-                else return false;
-        }
-        else return true;
-}
-
-const SMDS_MeshElement * SMDS_IteratorOfElements::subNext()
-{
-        if((t2Iterator.get()==NULL)||(!t2Iterator->more()))
-                if(t1Iterator->more())
-                        t2Iterator=t1Iterator->next()->elementsIterator(myType);
-        return t2Iterator->next();
-}
-
-/////////////////////////////////////////////////////////////////////////////
-/// Create an iterator which look for elements of type type which are linked 
-/// to the element element. it is the iterator to get connectivity of element
-//////////////////////////////////////////////////////////////////////////////
-SMDS_IteratorOfElements::SMDS_IteratorOfElements(const SMDS_MeshElement *    element,
-                                                 SMDSAbs_ElementType         type,
-                                                 const SMDS_ElemIteratorPtr& it)
-  : t1Iterator(it),
-    t2Iterator(SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL)),
-    myType(type), myElement(element),
-    myProxyElement(NULL)
-{
-  while(subMore())
-    alreadyReturnedElements.insert(subNext());
-  itAlreadyReturned= alreadyReturnedElements.begin();
-  switch(myElement->GetType())
-  {
-  case SMDSAbs_Node:
-  case SMDSAbs_Edge: myReverseIteration=true; break;
-  case SMDSAbs_Face: myReverseIteration=(type==SMDSAbs_Volume); break;
-  default: myReverseIteration=false;
-  }
-}
-
-bool SMDS_IteratorOfElements::more()
-{
-        if(myProxyElement==NULL)
-        {
-                while(itAlreadyReturned!=alreadyReturnedElements.end())
-                {
-                        myProxyElement=*itAlreadyReturned;
-                        itAlreadyReturned++;    
-
-                        if(myReverseIteration)
-                        {
-                                SMDS_ElemIteratorPtr it=
-                                        myProxyElement->elementsIterator(myElement->GetType());
-                                while(it->more())
-                                {                               
-                                        if(it->next()==myElement) return true;
-                                }
-                        }
-                        else return true;
-                }
-                myProxyElement=NULL;
-                return false;
-        }
-        else return true;
-}
-
-const SMDS_MeshElement * SMDS_IteratorOfElements::next()
-{
-        more();
-        const SMDS_MeshElement *e=myProxyElement;
-        myProxyElement=NULL;
-        return e;
-}
diff --git a/src/SMDS/SMDS_IteratorOfElements.hxx b/src/SMDS/SMDS_IteratorOfElements.hxx
deleted file mode 100644 (file)
index f2d73d8..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-
-//  SMESH SMDS : implementation of Salome mesh data structure
-//
-#include "SMESH_SMDS.hxx"
-
-#include "SMDS_Iterator.hxx"
-#include "SMDS_MeshElement.hxx"
-#include <set>
-
-
-class SMDS_EXPORT SMDS_IteratorOfElements:public SMDS_ElemIterator
-{
-  public:
-/////////////////////////////////////////////////////////////////////////////
-/// Create an iterator which look for elements of type type which are linked 
-/// to the element element. it is the iterator to get connectivity of element
-//////////////////////////////////////////////////////////////////////////////
-        SMDS_IteratorOfElements(const SMDS_MeshElement * element,
-                                SMDSAbs_ElementType type,
-                                const SMDS_ElemIteratorPtr& it);
-        bool more();
-        const SMDS_MeshElement * next();
-
-  private:
-        SMDS_ElemIteratorPtr t1Iterator;
-        SMDS_ElemIteratorPtr t2Iterator;
-        SMDSAbs_ElementType myType;     
-        const SMDS_MeshElement * myElement;             
-        const SMDS_MeshElement * myProxyElement;
-        bool myReverseIteration;
-
-        std::set<const SMDS_MeshElement*> alreadyReturnedElements;
-        std::set<const SMDS_MeshElement*>::iterator itAlreadyReturned;  
-        bool subMore();
-        const SMDS_MeshElement * subNext();
-};
index 8b87a9a..1d58368 100644 (file)
 #endif
 
 #include "SMDS_LinearEdge.hxx"
-#include "SMDS_IteratorOfElements.hxx"
 #include "SMDS_MeshNode.hxx"
-#include "utilities.h"
+#include "SMDS_SetIterator.hxx"
 
-using namespace std;
+#include <boost/make_shared.hpp>
 
 //=======================================================================
 //function : SMDS_LinearEdge
@@ -42,22 +41,10 @@ using namespace std;
 SMDS_LinearEdge::SMDS_LinearEdge(const SMDS_MeshNode * node1,
                                  const SMDS_MeshNode * node2)
 {
-  //MESSAGE("SMDS_LinearEdge " << GetID());
   myNodes[0] = node1;
   myNodes[1] = node2;
 }
 
-//=======================================================================
-//function : Print
-//purpose  : 
-//=======================================================================
-
-void SMDS_LinearEdge::Print(ostream & OS) const
-{
-  OS << "edge <" << GetID() << "> : (" << myNodes[0] << " , " << myNodes[1]
-      << ") " << endl;
-}
-
 int SMDS_LinearEdge::NbNodes() const
 {
   return 2;
@@ -68,75 +55,29 @@ int SMDS_LinearEdge::NbEdges() const
   return 1;
 }
 
-class SMDS_LinearEdge_MyNodeIterator: public SMDS_ElemIterator
+int SMDS_LinearEdge::NbFaces() const
 {
-  const SMDS_MeshNode * const * myNodes;
-  int myIndex;
-public:
-  SMDS_LinearEdge_MyNodeIterator(const SMDS_MeshNode * const * nodes) :
-    myNodes(nodes), myIndex(0)
-  {
-  }
-
-  bool more()
-  {
-    return myIndex < 2;
-  }
-
-  const SMDS_MeshElement* next()
-  {
-    myIndex++;
-    return myNodes[myIndex - 1];
-  }
-};
+  return 0;
+}
 
-SMDS_ElemIteratorPtr SMDS_LinearEdge::elementsIterator(SMDSAbs_ElementType type) const
+int SMDS_LinearEdge::GetNodeIndex( const SMDS_MeshNode* node ) const
 {
-  switch (type)
-  {
-    case SMDSAbs_Edge:
-      return SMDS_MeshElement::elementsIterator(SMDSAbs_Edge);
-    case SMDSAbs_Node:
-      return SMDS_ElemIteratorPtr(new SMDS_LinearEdge_MyNodeIterator(myNodes));
-    default:
-      return SMDS_ElemIteratorPtr
-        (new SMDS_IteratorOfElements(this,
-                                     type,
-                                     SMDS_ElemIteratorPtr
-                                     (new SMDS_LinearEdge_MyNodeIterator(myNodes))));
-  }
+  if ( node == myNodes[0] ) return 0;
+  if ( node == myNodes[1] ) return 1;
+  return -1;
 }
 
-bool operator<(const SMDS_LinearEdge & e1, const SMDS_LinearEdge & e2)
+SMDS_ElemIteratorPtr SMDS_LinearEdge::nodesIterator() const
 {
-  int id11 = e1.myNodes[0]->getVtkId();
-  int id21 = e2.myNodes[0]->getVtkId();
-  int id12 = e1.myNodes[1]->getVtkId();
-  int id22 = e2.myNodes[1]->getVtkId();
-  int tmp;
-
-  if (id11 >= id12)
-    {
-      tmp = id11;
-      id11 = id12;
-      id12 = tmp;
-    }
-  if (id21 >= id22)
-    {
-      tmp = id21;
-      id21 = id22;
-      id22 = tmp;
-    }
+  return boost::make_shared< SMDS_NodeArrayElemIterator >( &myNodes[0], &myNodes[0] + NbNodes() );
+}
 
-  if (id11 < id21)
-    return true;
-  else if (id11 == id21)
-    return (id21 < id22);
-  else
-    return false;
+SMDS_NodeIteratorPtr SMDS_LinearEdge::nodeIterator() const
+{
+  return boost::make_shared< SMDS_NodeArrayIterator >( &myNodes[0], &myNodes[0] + NbNodes() );
 }
 
-/*!
+/*
  * \brief Return node by its index
  * \param ind - node index
  * \retval const SMDS_MeshNode* - the node
@@ -151,10 +92,9 @@ const SMDS_MeshNode* SMDS_LinearEdge::GetNode(const int ind) const
 //purpose  : 
 //=======================================================================
 
-bool SMDS_LinearEdge::ChangeNodes(const SMDS_MeshNode * node1,
-                                  const SMDS_MeshNode * node2)
+bool SMDS_LinearEdge::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
 {
-  myNodes[0] = node1;
-  myNodes[1] = node2;
-  return true;
+  myNodes[0] = nodes[0];
+  myNodes[1] = nodes[1];
+  return nbNodes == 2;
 }
index 1ac80ee..75d984e 100644 (file)
 
 #include "SMESH_SMDS.hxx"
 
-#include "SMDS_MeshEdge.hxx"
-#include <iostream>
+#include "SMDS_CellOfNodes.hxx"
 
-class SMDS_EXPORT SMDS_LinearEdge: public SMDS_MeshEdge
+class SMDS_EXPORT SMDS_LinearEdge: public SMDS_CellOfNodes
 {
-
 public:
   SMDS_LinearEdge(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2);
-  bool ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2);
-  void Print(std::ostream & OS) const;
 
-  virtual SMDSAbs_EntityType GetEntityType() const
-  {
-    return SMDSEntity_Edge;
-  }
-  virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
-  {
-    return false;
-  }
-  int NbNodes() const;
-  int NbEdges() const;
-  friend bool operator<(const SMDS_LinearEdge& e1, const SMDS_LinearEdge& e2);
+  virtual SMDSAbs_ElementType  GetType()       const { return SMDSAbs_Edge; }
+  virtual SMDSAbs_GeometryType GetGeomType()   const { return SMDSGeom_EDGE; }
+  virtual SMDSAbs_EntityType   GetEntityType() const { return SMDSEntity_Edge; }
+  virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes);
+  virtual int  NbNodes() const;
+  virtual int  NbEdges() const;
+  virtual int  NbFaces() const;
 
-  /*!
-   * \brief Return node by its index
-   * \param ind - node index
-   * \retval const SMDS_MeshNode* - the node
-   */
-  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+  virtual int  NbCornerNodes() const { return NbNodes(); }
+  virtual int  GetNodeIndex( const SMDS_MeshNode* node ) const;
 
-protected:
-  SMDS_ElemIteratorPtr
-  elementsIterator(SMDSAbs_ElementType type) const;
+  virtual bool IsPoly() const { return false; }
+  virtual bool IsQuadratic() const  { return false; }
+
+  virtual SMDS_ElemIteratorPtr nodesIterator() const;
+  virtual SMDS_NodeIteratorPtr nodeIterator() const;
+
+  virtual const SMDS_MeshNode* GetNode(const int ind) const;
 
 protected:
-  const SMDS_MeshNode* myNodes[3];
+  const SMDS_MeshNode* myNodes[2];
 
 };
 #endif
index 40caa2c..1d7ba14 100644 (file)
 #pragma warning(disable:4786)
 #endif
 
-#include "SMDS_FaceOfEdges.hxx"
-#include "SMDS_FaceOfNodes.hxx"
 #include "SMDS_Mesh.hxx"
-#include "SMDS_PolygonalFaceOfNodes.hxx"
-#include "SMDS_PolyhedralVolumeOfNodes.hxx"
-#include "SMDS_QuadraticEdge.hxx"
-#include "SMDS_QuadraticFaceOfNodes.hxx"
-#include "SMDS_QuadraticVolumeOfNodes.hxx"
+
+#include "SMDS_ElementFactory.hxx"
+#include "SMDS_ElementHolder.hxx"
 #include "SMDS_SetIterator.hxx"
 #include "SMDS_SpacePosition.hxx"
 #include "SMDS_UnstructuredGrid.hxx"
-#include "SMDS_VolumeOfFaces.hxx"
-#include "SMDS_VolumeOfNodes.hxx"
 
-#include "utilities.h"
+#include <utilities.h>
 
 #include <vtkUnstructuredGrid.h>
-#include <vtkUnstructuredGridWriter.h>
-#include <vtkUnsignedCharArray.h>
+//#include <vtkUnstructuredGridWriter.h>
 #include <vtkCell.h>
+#include <vtkUnsignedCharArray.h>
 #include <vtkCellLinks.h>
 #include <vtkIdList.h>
 
 #include <algorithm>
-#include <map>
 #include <iostream>
 #include <fstream>
-#include <iterator>
-using namespace std;
+
+#include <boost/make_shared.hpp>
 
 #if !defined WIN32 && !defined __APPLE__
 #include <sys/sysinfo.h>
@@ -63,9 +56,9 @@ using namespace std;
 // number of added entities to check memory after
 #define CHECKMEMORY_INTERVAL 100000
 
-vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
-int SMDS_Mesh::chunkSize = 1024;
+#define MYASSERT(val) if (!(val)) throw SALOME_Exception(LOCALIZED("assertion not verified"));
 
+int SMDS_Mesh::chunkSize = 1024;
 
 //================================================================================
 /*!
@@ -77,6 +70,7 @@ int SMDS_Mesh::chunkSize = 1024;
 
 int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
 {
+  return -1;
 #if !defined WIN32 && !defined __APPLE__
   struct sysinfo si;
   int err = sysinfo( &si );
@@ -87,13 +81,16 @@ int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
 
   static int limit = -1;
   if ( limit < 0 ) {
-    int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
-    if (status >= 0 ) {
-      limit = WEXITSTATUS(status);
-    }
-    else {
-      double factor = ( si.totalswap == 0 ) ? 0.1 : 0.2;
-      limit = int(( factor * si.totalram * si.mem_unit ) / Mbyte );
+    if ( si.totalswap == 0 )
+    {
+      int status = system("SMDS_MemoryLimit"); // it returns lower limit of free RAM
+      if (status >= 0 ) {
+        limit = WEXITSTATUS(status);
+      }
+      else {
+        double factor = ( si.totalswap == 0 ) ? 0.1 : 0.2;
+        limit = int(( factor * si.totalram * si.mem_unit ) / Mbyte );
+      }
     }
     if ( limit < 20 )
       limit = 20;
@@ -106,7 +103,6 @@ int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
   int freeMb =
     ( si.freeram  * si.mem_unit ) / Mbyte +
     ( si.freeswap * si.mem_unit ) / Mbyte;
-  //cout << "freeMb = " << freeMb << " limit = " << limit << endl;
 
   if ( freeMb > limit )
     return freeMb - limit;
@@ -125,29 +121,12 @@ int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
 /// Create a new mesh object
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_Mesh::SMDS_Mesh():
-  myNodePool(0), myVolumePool(0), myFacePool(0), myEdgePool(0), myBallPool(0),
+  myNodeFactory( new SMDS_NodeFactory( this )),
+  myCellFactory( new SMDS_ElementFactory( this )),
   myParent(NULL),
-  myNodeIDFactory(new SMDS_MeshNodeIDFactory()),
-  myElementIDFactory(new SMDS_MeshElementIDFactory()),
   myModified(false), myModifTime(0), myCompactTime(0),
-  myHasConstructionEdges(false), myHasConstructionFaces(false),
-  myHasInverseElements(true),
   xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0)
 {
-  myMeshId = _meshList.size();         // --- index of the mesh to push back in the vector
-  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);
-  myBallPool = new ObjectPool<SMDS_BallElement>(SMDS_Mesh::chunkSize);
-
-  myNodes.clear();
-  myCells.clear();
-  //myCellIdSmdsToVtk.clear();
-  myCellIdVtkToSmds.clear();
   myGrid = SMDS_UnstructuredGrid::New();
   myGrid->setSMDS_mesh(this);
   myGrid->Initialize();
@@ -156,22 +135,13 @@ SMDS_Mesh::SMDS_Mesh():
   // bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion"
   // Use double type for storing coordinates of nodes instead of float.
   points->SetDataType(VTK_DOUBLE);
-  points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/);
+  points->SetNumberOfPoints( 0 );
   myGrid->SetPoints( points );
   points->Delete();
-  //myGrid->BuildLinks();
   this->Modified();
 
   // initialize static maps in SMDS_MeshCell, to be thread-safe
-  if ( myMeshId == 0 )
-  {
-    SMDS_MeshCell::toVtkType( SMDSEntity_Node );
-    SMDS_MeshCell::toVtkOrder( SMDSEntity_Node );
-    SMDS_MeshCell::reverseSmdsOrder( SMDSEntity_Node );
-    SMDS_MeshCell::interlacedSmdsOrder( SMDSEntity_Node );
-    SMDS_MeshCell::toSmdsType( VTK_VERTEX );
-    SMDS_MeshCell::fromVtkOrder( SMDSEntity_Node );
-  }
+  SMDS_MeshCell::InitStaticMembers();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -180,15 +150,9 @@ SMDS_Mesh::SMDS_Mesh():
 /// (2003-09-08) of SMESH
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent):
-  myNodePool(parent->myNodePool),
-  myVolumePool(parent->myVolumePool),
-  myFacePool(parent->myFacePool),
-  myEdgePool(parent->myEdgePool),
-  myBallPool(parent->myBallPool),
-  myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
-  myElementIDFactory(parent->myElementIDFactory),
-  myHasConstructionEdges(false), myHasConstructionFaces(false),
-  myHasInverseElements(true)
+  myNodeFactory( new SMDS_NodeFactory( this )),
+  myCellFactory( new SMDS_ElementFactory( this )),
+  myParent(parent)
 {
 }
 
@@ -211,7 +175,7 @@ SMDS_Mesh *SMDS_Mesh::AddSubMesh()
 
 SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
 {
-  return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
+  return SMDS_Mesh::AddNodeWithID( x,y,z, myNodeFactory->GetFreeID() );
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -219,33 +183,18 @@ 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, int ID )
 {
   // find the MeshNode corresponding to ID
-  const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
-  if(!node){
-    if (ID < 1)
-      {
-        MESSAGE("=============>  Bad Node Id: " << ID);
-        ID = myNodeIDFactory->GetFreeID();
-      }
-    myNodeIDFactory->adjustMaxId(ID);
-    SMDS_MeshNode * node = myNodePool->getNew();
-    node->init(ID, myMeshId, 0, x, y, z);
-
-    if (ID >= (int)myNodes.size())
-    {
-        myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
-//         MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
-    }
-    myNodes[ID] = node;
-    myNodeIDFactory->BindID(ID,node);
+  SMDS_MeshNode *node = myNodeFactory->NewNode( ID );
+  if ( node )
+  {
+    node->init( x, y, z );
     myInfo.myNbNodes++;
     myModified = true;
     this->adjustBoundingBox(x, y, z);
-    return node;
-  }else
-    return NULL;
+  }
+  return node;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -254,7 +203,7 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
 {
-  SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
+  const SMDS_MeshNode * node = myNodeFactory->FindNode(idnode);
   if (!node) return NULL;
   return SMDS_Mesh::Add0DElementWithID(node, ID);
 }
@@ -265,7 +214,7 @@ SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(int idnode, int ID)
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_Mesh0DElement* SMDS_Mesh::Add0DElement(const SMDS_MeshNode * node)
 {
-  return SMDS_Mesh::Add0DElementWithID(node, myElementIDFactory->GetFreeID());
+  return SMDS_Mesh::Add0DElementWithID( node, myCellFactory->GetFreeID() );
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -280,30 +229,26 @@ SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int I
   if (!n) return 0;
 
   if (Nb0DElements() % 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;
+
+  if ( SMDS_MeshCell * cell = myCellFactory->NewCell( ID ))
+  {
+    cell->init( SMDSEntity_0D, /*nbNodes=*/1, n );
     myInfo.myNb0DElements++;
-    return el0d;
+    return static_cast< SMDS_Mesh0DElement*> ( cell );
   }
 
-  delete el0d;
-  return NULL;
+  return 0;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 /// 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( int idnode, double diameter, int ID )
 {
-  SMDS_MeshNode * node = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode);
+  const SMDS_MeshNode * node = myNodeFactory->FindNode( idnode );
   if (!node) return NULL;
-  return SMDS_Mesh::AddBallWithID(node, diameter, ID);
+  return SMDS_Mesh::AddBallWithID( node, diameter, ID );
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -312,7 +257,7 @@ SMDS_BallElement* SMDS_Mesh::AddBallWithID(int idnode, double diameter, int ID)
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_BallElement* SMDS_Mesh::AddBall(const SMDS_MeshNode * node, double diameter)
 {
-  return SMDS_Mesh::AddBallWithID(node, diameter, myElementIDFactory->GetFreeID());
+  return SMDS_Mesh::AddBallWithID(node, diameter, myCellFactory->GetFreeID());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -329,17 +274,12 @@ SMDS_BallElement* SMDS_Mesh::AddBallWithID(const SMDS_MeshNode * n, double diame
 
   if (NbBalls() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
 
-  SMDS_BallElement *ball = myBallPool->getNew();
-  ball->init(n->getVtkId(), diameter, this);
-  if (!this->registerElement(ID,ball))
+  SMDS_BallElement* ball = static_cast< SMDS_BallElement*>( myCellFactory->NewElement( ID ));
+  if ( ball )
   {
-    this->myGrid->GetCellTypesArray()->SetValue(ball->getVtkId(), VTK_EMPTY_CELL);
-    myBallPool->destroy(ball);
-    return 0;
+    ball->init( n, diameter );
+    myInfo.myNbBalls++;
   }
-  adjustmyCellsCapacity(ID);
-  myCells[ID] = ball;
-  myInfo.myNbBalls++;
   return ball;
 }
 
@@ -350,8 +290,8 @@ SMDS_BallElement* SMDS_Mesh::AddBallWithID(const SMDS_MeshNode * n, double diame
 
 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);
+  const SMDS_MeshNode * node1 = myNodeFactory->FindNode(idnode1);
+  const SMDS_MeshNode * node2 = myNodeFactory->FindNode(idnode2);
   if(!node1 || !node2) return NULL;
   return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
 }
@@ -364,7 +304,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)
 {
-  return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
+  return SMDS_Mesh::AddEdgeWithID(node1, node2, myCellFactory->GetFreeID());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -378,36 +318,17 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
 
 SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n2,
-                                        int ID)
+                                        int                   ID)
 {
   if ( !n1 || !n2 ) return 0;
-  SMDS_MeshEdge * edge = 0;
-
-  // --- retrieve nodes ID
-  vector<vtkIdType> nodeIds;
-  nodeIds.clear();
-  nodeIds.push_back(n1->getVtkId());
-  nodeIds.push_back(n2->getVtkId());
-
-  SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
-  edgevtk->init(nodeIds, this);
-  if (!this->registerElement(ID,edgevtk))
-    {
-      this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
-      myEdgePool->destroy(edgevtk);
-      return 0;
-    }
-  edge = edgevtk;
-  adjustmyCellsCapacity(ID);
-  myCells[ID] = edge;
-  myInfo.myNbEdges++;
 
-//  if (edge && !registerElement(ID, edge))
-//  {
-//    RemoveElement(edge, false);
-//    edge = NULL;
-//  }
-  return edge;
+  if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
+  {
+    cell->init( SMDSEntity_Edge, /*nbNodes=*/2, n1, n2 );
+    myInfo.myNbEdges++;
+    return static_cast<SMDS_MeshEdge*>( cell );
+  }
+  return 0;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -419,7 +340,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
                                   const SMDS_MeshNode * n2,
                                   const SMDS_MeshNode * n3)
 {
-  return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
+  return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myCellFactory->GetFreeID());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -428,9 +349,9 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
 
 SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
 {
-  SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
-  SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
-  SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
+  const SMDS_MeshNode * node1 = myNodeFactory->FindNode(idnode1);
+  const SMDS_MeshNode * node2 = myNodeFactory->FindNode(idnode2);
+  const SMDS_MeshNode * node3 = myNodeFactory->FindNode(idnode3);
   if(!node1 || !node2 || !node3) return NULL;
   return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);
 }
@@ -444,14 +365,16 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n3,
                                         int ID)
 {
-  //MESSAGE("AddFaceWithID " << ID)
-  SMDS_MeshFace * face=createTriangle(n1, n2, n3, ID);
+  if ( !n1 || !n2 || !n3 ) return 0;
+  if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
 
-//  if (face && !registerElement(ID, face)) {
-//    RemoveElement(face, false);
-//    face = NULL;
-//  }
-  return face;
+  if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
+  {
+    cell->init( SMDSEntity_Triangle, /*nbNodes=*/3, n1, n2, n3 );
+    myInfo.myNbTriangles++;
+    return static_cast<SMDS_MeshFace*>( cell );
+  }
+  return 0;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -464,7 +387,7 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
                                   const SMDS_MeshNode * n3,
                                   const SMDS_MeshNode * n4)
 {
-  return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
+  return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myCellFactory->GetFreeID());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -477,12 +400,12 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1,
                                         int idnode4,
                                         int ID)
 {
-  SMDS_MeshNode *node1, *node2, *node3, *node4;
-  node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
-  node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
-  node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
-  node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
-  if(!node1 || !node2 || !node3 || !node4) return NULL;
+  const SMDS_MeshNode *node1, *node2, *node3, *node4;
+  node1 = myNodeFactory->FindNode(idnode1);
+  node2 = myNodeFactory->FindNode(idnode2);
+  node3 = myNodeFactory->FindNode(idnode3);
+  node4 = myNodeFactory->FindNode(idnode4);
+  if ( !node1 || !node2 || !node3 || !node4 ) return NULL;
   return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);
 }
 
@@ -496,100 +419,16 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n4,
                                         int ID)
 {
-  //MESSAGE("AddFaceWithID " << ID);
-  SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
-
-//  if (face && !registerElement(ID, face)) {
-//    RemoveElement(face, false);
-//    face = NULL;
-//  }
-  return face;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// Add a triangle defined by its edges. An ID is automatically assigned to the
-/// Created face
-///////////////////////////////////////////////////////////////////////////////
-
-SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
-                                  const SMDS_MeshEdge * e2,
-                                  const SMDS_MeshEdge * e3)
-{
-  if (!hasConstructionEdges())
-    return NULL;
-     //MESSAGE("AddFaceWithID");
- return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// Add a triangle defined by its edges
-///////////////////////////////////////////////////////////////////////////////
-
-SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
-                                        const SMDS_MeshEdge * e2,
-                                        const SMDS_MeshEdge * e3,
-                                        int ID)
-{
-  if (!hasConstructionEdges())
-    return NULL;
-  if ( !e1 || !e2 || !e3 ) return 0;
-
-  if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-
-  SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
-  adjustmyCellsCapacity(ID);
-  myCells[ID] = face;
-  myInfo.myNbTriangles++;
-
-  if (!registerElement(ID, face)) {
-    registerElement(myElementIDFactory->GetFreeID(), face);
-    //RemoveElement(face, false);
-    //face = NULL;
-  }
-  return face;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// Add a quadrangle defined by its edges. An ID is automatically assigned to the
-/// Created face
-///////////////////////////////////////////////////////////////////////////////
-
-SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
-                                  const SMDS_MeshEdge * e2,
-                                  const SMDS_MeshEdge * e3,
-                                  const SMDS_MeshEdge * e4)
-{
-  if (!hasConstructionEdges())
-    return NULL;
- return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// Add a quadrangle defined by its edges
-///////////////////////////////////////////////////////////////////////////////
-
-SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
-                                        const SMDS_MeshEdge * e2,
-                                        const SMDS_MeshEdge * e3,
-                                        const SMDS_MeshEdge * e4,
-                                        int ID)
-{
-  if (!hasConstructionEdges())
-    return NULL;
-  if ( !e1 || !e2 || !e3 || !e4 ) return 0;
+  if ( !n1 || !n2 || !n3 || !n4 ) return 0;
   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-  SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
-  adjustmyCellsCapacity(ID);
-  myCells[ID] = face;
-  myInfo.myNbQuadrangles++;
 
-  if (!registerElement(ID, face))
+  if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
   {
-    registerElement(myElementIDFactory->GetFreeID(), face);
-    //RemoveElement(face, false);
-    //face = NULL;
+    cell->init( SMDSEntity_Quadrangle, /*nbNodes=*/4, n1, n2, n3, n4 );
+    myInfo.myNbQuadrangles++;
+    return static_cast<SMDS_MeshFace*>( cell );
   }
-  return face;
+  return 0;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -602,10 +441,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
                                       const SMDS_MeshNode * n3,
                                       const SMDS_MeshNode * n4)
 {
-  int ID = myElementIDFactory->GetFreeID();
-  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
-  if(v==NULL) myElementIDFactory->ReleaseID(ID);
-  return v;
+  return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, myCellFactory->GetFreeID() );
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -621,11 +457,11 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
                                              int idnode4,
                                              int ID)
 {
-  SMDS_MeshNode *node1, *node2, *node3, *node4;
-  node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
-  node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
-  node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
-  node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
+  const SMDS_MeshNode *node1, *node2, *node3, *node4;
+  node1 = myNodeFactory->FindNode(idnode1);
+  node2 = myNodeFactory->FindNode(idnode2);
+  node3 = myNodeFactory->FindNode(idnode3);
+  node4 = myNodeFactory->FindNode(idnode4);
   if(!node1 || !node2 || !node3 || !node4) return NULL;
   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
 }
@@ -642,49 +478,16 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n4,
                                             int ID)
 {
-  SMDS_MeshVolume* volume = 0;
-  if ( !n1 || !n2 || !n3 || !n4) return volume;
+  if ( !n1 || !n2 || !n3 || !n4 ) return 0;
   if ( NbVolumes() % 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);
-    adjustmyCellsCapacity(ID);
-    myCells[ID] = volume;
-    myInfo.myNbTetras++;
-  }
-  else if(hasConstructionEdges()) {
-    return NULL;
-  }
-  else {
-    // --- retrieve nodes ID
-    myNodeIds.resize(4);
-    myNodeIds[0] = n1->getVtkId();
-    myNodeIds[1] = n3->getVtkId(); // order SMDS-->VTK
-    myNodeIds[2] = n2->getVtkId();
-    myNodeIds[3] = n4->getVtkId();
-
-    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
-    volvtk->init(myNodeIds, this);
-    if (!this->registerElement(ID,volvtk))
-    {
-      this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
-      myVolumePool->destroy(volvtk);
-      return 0;
-    }
-    volume = volvtk;
-    adjustmyCellsCapacity(ID);
-    myCells[ID] = volume;
+
+  if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
+  {
+    cell->init( SMDSEntity_Tetra, /*nbNodes=*/4, n1, n2, n3, n4 );
     myInfo.myNbTetras++;
+    return static_cast<SMDS_MeshVolume*>( cell );
   }
-
-  //  if (!registerElement(ID, volume)) {
-  //    RemoveElement(volume, false);
-  //    volume = NULL;
-  //  }
-  return volume;
+  return 0;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -699,10 +502,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
                                       const SMDS_MeshNode * n4,
                                       const SMDS_MeshNode * n5)
 {
-  int ID = myElementIDFactory->GetFreeID();
-  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
-  if(v==NULL) myElementIDFactory->ReleaseID(ID);
-  return v;
+  return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, myCellFactory->GetFreeID() );
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -720,12 +520,12 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
                                              int idnode5,
                                              int ID)
 {
-  SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
-  node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
-  node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
-  node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
-  node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
-  node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
+  const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
+  node1 = myNodeFactory->FindNode(idnode1);
+  node2 = myNodeFactory->FindNode(idnode2);
+  node3 = myNodeFactory->FindNode(idnode3);
+  node4 = myNodeFactory->FindNode(idnode4);
+  node5 = myNodeFactory->FindNode(idnode5);
   if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
 }
@@ -744,50 +544,16 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n5,
                                             int ID)
 {
-  SMDS_MeshVolume* volume = 0;
-  if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
+  if ( !n1 || !n2 || !n3 || !n4 || !n5 ) return 0;
   if ( NbVolumes() % 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);
-    adjustmyCellsCapacity(ID);
-    myCells[ID] = volume;
-    myInfo.myNbPyramids++;
-  }
-  else if(hasConstructionEdges()) {
-    return NULL;
-  }
-  else {
-    // --- retrieve nodes ID
-    myNodeIds.resize(5);
-    myNodeIds[0] = n1->getVtkId();
-    myNodeIds[1] = n4->getVtkId();
-    myNodeIds[2] = n3->getVtkId();
-    myNodeIds[3] = n2->getVtkId();
-    myNodeIds[4] = n5->getVtkId();
-
-    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
-    volvtk->init(myNodeIds, this);
-    if (!this->registerElement(ID,volvtk))
-    {
-      this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
-      myVolumePool->destroy(volvtk);
-      return 0;
-    }
-    volume = volvtk;
-    adjustmyCellsCapacity(ID);
-    myCells[ID] = volume;
+
+  if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
+  {
+    cell->init( SMDSEntity_Pyramid, /*nbNodes=*/5, n1, n2, n3, n4, n5 );
     myInfo.myNbPyramids++;
+    return static_cast<SMDS_MeshVolume*>( cell );
   }
-
-  //  if (!registerElement(ID, volume)) {
-  //    RemoveElement(volume, false);
-  //    volume = NULL;
-  //  }
-  return volume;
+  return 0;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -803,10 +569,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
                                       const SMDS_MeshNode * n5,
                                       const SMDS_MeshNode * n6)
 {
-  int ID = myElementIDFactory->GetFreeID();
-  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
-  if(v==NULL) myElementIDFactory->ReleaseID(ID);
-  return v;
+  int ID = myCellFactory->GetFreeID();
+  return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -825,14 +589,13 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
                                              int idnode6,
                                              int ID)
 {
-  SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
-  node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
-  node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
-  node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
-  node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
-  node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
-  node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
-  if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
+  const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
+  node1 = myNodeFactory->FindNode(idnode1);
+  node2 = myNodeFactory->FindNode(idnode2);
+  node3 = myNodeFactory->FindNode(idnode3);
+  node4 = myNodeFactory->FindNode(idnode4);
+  node5 = myNodeFactory->FindNode(idnode5);
+  node6 = myNodeFactory->FindNode(idnode6);
   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
 }
 
@@ -851,52 +614,16 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n6,
                                             int ID)
 {
-  SMDS_MeshVolume* volume = 0;
-  if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
+  if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 ) return 0;
   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-  if(hasConstructionFaces()) {
-    SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
-    SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
-    SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
-    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);
-    adjustmyCellsCapacity(ID);
-    myCells[ID] = volume;
-    myInfo.myNbPrisms++;
-  }
-  else if(hasConstructionEdges()) {
-    return NULL;
-  }
-  else {
-    // --- retrieve nodes ID
-    myNodeIds.resize(6);
-    myNodeIds[0] = n1->getVtkId();
-    myNodeIds[1] = n2->getVtkId();
-    myNodeIds[2] = n3->getVtkId();
-    myNodeIds[3] = n4->getVtkId();
-    myNodeIds[4] = n5->getVtkId();
-    myNodeIds[5] = n6->getVtkId();
-
-    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
-    volvtk->init(myNodeIds, this);
-    if (!this->registerElement(ID,volvtk))
-    {
-      this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
-      myVolumePool->destroy(volvtk);
-      return 0;
-    }
-    volume = volvtk;
-    adjustmyCellsCapacity(ID);
-    myCells[ID] = volume;
+
+  if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
+  {
+    cell->init( SMDSEntity_Penta, /*nbNodes=*/6, n1, n2, n3, n4, n5, n6 );
     myInfo.myNbPrisms++;
+    return static_cast<SMDS_MeshVolume*>( cell );
   }
-
-  //  if (!registerElement(ID, volume)) {
-  //    RemoveElement(volume, false);
-  //    volume = NULL;
-  //  }
-  return volume;
+  return 0;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -917,12 +644,9 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
                                       const SMDS_MeshNode * n11,
                                       const SMDS_MeshNode * n12)
 {
-  int ID = myElementIDFactory->GetFreeID();
-  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6,
-                                                   n7, n8, n9, n10, n11, n12,
-                                                   ID);
-  if(v==NULL) myElementIDFactory->ReleaseID(ID);
-  return v;
+  return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6,
+                                    n7, n8, n9, n10, n11, n12,
+                                    myCellFactory->GetFreeID() );
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -946,18 +670,18 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
                                              int idnode12,
                                              int ID)
 {
-  SMDS_MeshNode *node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
-  SMDS_MeshNode *node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
-  SMDS_MeshNode *node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
-  SMDS_MeshNode *node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
-  SMDS_MeshNode *node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
-  SMDS_MeshNode *node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
-  SMDS_MeshNode *node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
-  SMDS_MeshNode *node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
-  SMDS_MeshNode *node9 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode9);
-  SMDS_MeshNode *node10 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode10);
-  SMDS_MeshNode *node11 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode11);
-  SMDS_MeshNode *node12 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode12);
+  const SMDS_MeshNode *node1 = myNodeFactory->FindNode(idnode1);
+  const SMDS_MeshNode *node2 = myNodeFactory->FindNode(idnode2);
+  const SMDS_MeshNode *node3 = myNodeFactory->FindNode(idnode3);
+  const SMDS_MeshNode *node4 = myNodeFactory->FindNode(idnode4);
+  const SMDS_MeshNode *node5 = myNodeFactory->FindNode(idnode5);
+  const SMDS_MeshNode *node6 = myNodeFactory->FindNode(idnode6);
+  const SMDS_MeshNode *node7 = myNodeFactory->FindNode(idnode7);
+  const SMDS_MeshNode *node8 = myNodeFactory->FindNode(idnode8);
+  const SMDS_MeshNode *node9 = myNodeFactory->FindNode(idnode9);
+  const SMDS_MeshNode *node10 = myNodeFactory->FindNode(idnode10);
+  const SMDS_MeshNode *node11 = myNodeFactory->FindNode(idnode11);
+  const SMDS_MeshNode *node12 = myNodeFactory->FindNode(idnode12);
   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
                                     node7, node8, node9, node10, node11, node12,
                                     ID);
@@ -988,44 +712,15 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
      !n7 || !n8 || !n9 || !n10 || !n11 || !n12 )
     return volume;
   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-  if(hasConstructionFaces()) {
-    return NULL;
-  }
-  else if(hasConstructionEdges()) {
-    return NULL;
-  }
-  else {
-    // --- retrieve nodes ID
-    myNodeIds.resize(12);
-    myNodeIds[0] = n1->getVtkId();
-    myNodeIds[1] = n6->getVtkId();
-    myNodeIds[2] = n5->getVtkId();
-    myNodeIds[3] = n4->getVtkId();
-    myNodeIds[4] = n3->getVtkId();
-    myNodeIds[5] = n2->getVtkId();
-
-    myNodeIds[6] = n7->getVtkId();
-    myNodeIds[7] = n12->getVtkId();
-    myNodeIds[8] = n11->getVtkId();
-    myNodeIds[9] = n10->getVtkId();
-    myNodeIds[10] = n9->getVtkId();
-    myNodeIds[11] = n8->getVtkId();
-
-    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
-    volvtk->init(myNodeIds, this);
-    if (!this->registerElement(ID,volvtk))
-    {
-      this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
-      myVolumePool->destroy(volvtk);
-      return 0;
-    }
-    volume = volvtk;
-    adjustmyCellsCapacity(ID);
-    myCells[ID] = volume;
+
+  if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
+  {
+    cell->init( SMDSEntity_Hexagonal_Prism,
+                /*nbNodes=*/12, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12 );
     myInfo.myNbHexPrism++;
+    return static_cast<SMDS_MeshVolume*>( cell );
   }
-
-  return volume;
+  return 0;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1043,10 +738,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
                                       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);
-  if(v==NULL) myElementIDFactory->ReleaseID(ID);
-  return v;
+  int ID = myCellFactory->GetFreeID();
+  return SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1067,17 +760,15 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
                                              int idnode8,
                                              int ID)
 {
-  SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
-  node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
-  node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
-  node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
-  node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
-  node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
-  node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
-  node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
-  node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
-  if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
-    return NULL;
+  const SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
+  node1 = myNodeFactory->FindNode(idnode1);
+  node2 = myNodeFactory->FindNode(idnode2);
+  node3 = myNodeFactory->FindNode(idnode3);
+  node4 = myNodeFactory->FindNode(idnode4);
+  node5 = myNodeFactory->FindNode(idnode5);
+  node6 = myNodeFactory->FindNode(idnode6);
+  node7 = myNodeFactory->FindNode(idnode7);
+  node8 = myNodeFactory->FindNode(idnode8);
   return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
                                     node7, node8, ID);
 }
@@ -1103,203 +794,28 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
   SMDS_MeshVolume* volume = 0;
   if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-  if(hasConstructionFaces()) {
-    SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
-    SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
-    SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
-    SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
-    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);
-    adjustmyCellsCapacity(ID);
-    myCells[ID] = volume;
-    myInfo.myNbHexas++;
-  }
-  else if(hasConstructionEdges()) {
-    return NULL;
-  }
-  else {
-    // --- retrieve nodes ID
-    myNodeIds.resize(8);
-    myNodeIds[0] = n1->getVtkId();
-    myNodeIds[1] = n4->getVtkId();
-    myNodeIds[2] = n3->getVtkId();
-    myNodeIds[3] = n2->getVtkId();
-    myNodeIds[4] = n5->getVtkId();
-    myNodeIds[5] = n8->getVtkId();
-    myNodeIds[6] = n7->getVtkId();
-    myNodeIds[7] = n6->getVtkId();
-
-    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
-    volvtk->init(myNodeIds, this);
-    if (!this->registerElement(ID,volvtk))
-    {
-      this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
-      myVolumePool->destroy(volvtk);
-      return 0;
-    }
-    volume = volvtk;
-    adjustmyCellsCapacity(ID);
-    myCells[ID] = volume;
-    myInfo.myNbHexas++;
-  }
-
-  //  if (!registerElement(ID, volume)) {
-  //    RemoveElement(volume, false);
-  //    volume = NULL;
-  //  }
-  return volume;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-///Create a new tetrahedron defined by its faces and add it to the mesh.
-///@return The created tetrahedron
-///////////////////////////////////////////////////////////////////////////////
-
-SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
-                                      const SMDS_MeshFace * f2,
-                                      const SMDS_MeshFace * f3,
-                                      const SMDS_MeshFace * f4)
-{
-  if (!hasConstructionFaces())
-    return NULL;
-  return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-///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
-///////////////////////////////////////////////////////////////////////////////
-
-SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
-                                            const SMDS_MeshFace * f2,
-                                            const SMDS_MeshFace * f3,
-                                            const SMDS_MeshFace * f4,
-                                            int ID)
-{
-  if (!hasConstructionFaces())
-    return NULL;
-  if ( !f1 || !f2 || !f3 || !f4) return 0;
-  if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-  SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
-  adjustmyCellsCapacity(ID);
-  myCells[ID] = volume;
-  myInfo.myNbTetras++;
-
-  if (!registerElement(ID, volume)) {
-    registerElement(myElementIDFactory->GetFreeID(), volume);
-    //RemoveElement(volume, false);
-    //volume = NULL;
-  }
-  return volume;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-///Create a new pyramid defined by its faces and add it to the mesh.
-///@return The created pyramid
-///////////////////////////////////////////////////////////////////////////////
-
-SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
-                                      const SMDS_MeshFace * f2,
-                                      const SMDS_MeshFace * f3,
-                                      const SMDS_MeshFace * f4,
-                                      const SMDS_MeshFace * f5)
-{
- if (!hasConstructionFaces())
-    return NULL;
-  return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-///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
-///////////////////////////////////////////////////////////////////////////////
-
-SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
-                                            const SMDS_MeshFace * f2,
-                                            const SMDS_MeshFace * f3,
-                                            const SMDS_MeshFace * f4,
-                                            const SMDS_MeshFace * f5,
-                                            int ID)
-{
-  if (!hasConstructionFaces())
-    return NULL;
-  if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
-  if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-  SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
-  adjustmyCellsCapacity(ID);
-  myCells[ID] = volume;
-  myInfo.myNbPyramids++;
-
-  if (!registerElement(ID, volume)) {
-    registerElement(myElementIDFactory->GetFreeID(), volume);
-    //RemoveElement(volume, false);
-    //volume = NULL;
-  }
-  return volume;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-///Create a new prism defined by its faces and add it to the mesh.
-///@return The created prism
-///////////////////////////////////////////////////////////////////////////////
-
-SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
-                                      const SMDS_MeshFace * f2,
-                                      const SMDS_MeshFace * f3,
-                                      const SMDS_MeshFace * f4,
-                                      const SMDS_MeshFace * f5,
-                                      const SMDS_MeshFace * f6)
-{
- if (!hasConstructionFaces())
-    return NULL;
-  return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-///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
-///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
-                                            const SMDS_MeshFace * f2,
-                                            const SMDS_MeshFace * f3,
-                                            const SMDS_MeshFace * f4,
-                                            const SMDS_MeshFace * f5,
-                                            const SMDS_MeshFace * f6,
-                                            int ID)
-{
-  if (!hasConstructionFaces())
-    return NULL;
-  if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
-  if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-  SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
-  adjustmyCellsCapacity(ID);
-  myCells[ID] = volume;
-  myInfo.myNbPrisms++;
-
-  if (!registerElement(ID, volume)) {
-    registerElement(myElementIDFactory->GetFreeID(), volume);
-    //RemoveElement(volume, false);
-    //volume = NULL;
+  if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
+  {
+    cell->init( SMDSEntity_Hexa,
+                /*nbNodes=*/8, n1, n2, n3, n4, n5, n6, n7, n8 );
+    myInfo.myNbHexas++;
+    return static_cast<SMDS_MeshVolume*>( cell );
   }
-  return volume;
+  return 0;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 /// Add a polygon defined by its nodes IDs
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const vector<int> & nodes_ids,
-                                                  const int           ID)
+SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const std::vector<int> & nodes_ids,
+                                                  const int               ID)
 {
   int nbNodes = nodes_ids.size();
-  vector<const SMDS_MeshNode*> nodes (nbNodes);
+  std::vector<const SMDS_MeshNode*> nodes (nbNodes);
   for (int i = 0; i < nbNodes; i++) {
-    nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
+    nodes[i] = myNodeFactory->FindNode( nodes_ids[i] );
     if (!nodes[i]) return NULL;
   }
   return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
@@ -1310,38 +826,18 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (const vector<int> & nodes_ids,
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshFace*
-SMDS_Mesh::AddPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
-                                   const int                            ID)
+SMDS_Mesh::AddPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*> & nodes,
+                                   const int                                 ID)
 {
-  SMDS_MeshFace * face;
-
   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-  if (hasConstructionEdges())
-  {
-    return NULL;
-  }
-  else
-  {
-    myNodeIds.resize( nodes.size() );
-    for ( size_t i = 0; i < nodes.size(); ++i )
-      myNodeIds[i] = nodes[i]->getVtkId();
-
-    SMDS_VtkFace *facevtk = myFacePool->getNew();
-    facevtk->initPoly(myNodeIds, this);
-    if (!this->registerElement(ID,facevtk))
-    {
-      this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
-      myFacePool->destroy(facevtk);
-      return 0;
-    }
-    face = facevtk;
 
-    adjustmyCellsCapacity(ID);
-    myCells[ID] = face;
+  if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
+  {
+    cell->init( SMDSEntity_Polygon, nodes );
     myInfo.myNbPolygons++;
+    return static_cast<SMDS_MeshFace*>( cell );
   }
-
-  return face;
+  return 0;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1349,21 +845,21 @@ SMDS_Mesh::AddPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
 /// An ID is automatically affected to the created face.
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const vector<const SMDS_MeshNode*> & nodes)
+SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (const std::vector<const SMDS_MeshNode*> & nodes)
 {
-  return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
+  return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myCellFactory->GetFreeID());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 /// Add a quadratic polygon defined by its nodes IDs
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const vector<int> & nodes_ids,
-                                                      const int           ID)
+SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<int> & nodes_ids,
+                                                      const int                ID)
 {
-  vector<const SMDS_MeshNode*> nodes( nodes_ids.size() );
+  std::vector<const SMDS_MeshNode*> nodes( nodes_ids.size() );
   for ( size_t i = 0; i < nodes.size(); i++) {
-    nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
+    nodes[i] = myNodeFactory->FindNode(nodes_ids[i]);
     if (!nodes[i]) return NULL;
   }
   return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, ID);
@@ -1374,36 +870,17 @@ SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFaceWithID (const vector<int> & nodes_
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshFace*
-SMDS_Mesh::AddQuadPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & nodes,
-                                       const int                            ID)
+SMDS_Mesh::AddQuadPolygonalFaceWithID (const std::vector<const SMDS_MeshNode*> & nodes,
+                                       const int                                 ID)
 {
-  SMDS_MeshFace * face;
-
   if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-  if (hasConstructionEdges())
-  {
-    return NULL;
-  }
-  else
+  if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
   {
-    myNodeIds.resize( nodes.size() );
-    for ( size_t i = 0; i < nodes.size(); ++i )
-      myNodeIds[i] = nodes[i]->getVtkId();
-
-    SMDS_VtkFace *facevtk = myFacePool->getNew();
-    facevtk->initQuadPoly(myNodeIds, this);
-    if (!this->registerElement(ID,facevtk))
-    {
-      this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
-      myFacePool->destroy(facevtk);
-      return 0;
-    }
-    face = facevtk;
-    adjustmyCellsCapacity(ID);
-    myCells[ID] = face;
+    cell->init( SMDSEntity_Quad_Polygon, nodes );
     myInfo.myNbQuadPolygons++;
+    return static_cast<SMDS_MeshFace*>( cell );
   }
-  return face;
+  return 0;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1411,9 +888,9 @@ SMDS_Mesh::AddQuadPolygonalFaceWithID (const vector<const SMDS_MeshNode*> & node
 /// An ID is automatically affected to the created face.
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFace (const vector<const SMDS_MeshNode*> & nodes)
+SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFace (const std::vector<const SMDS_MeshNode*> & nodes)
 {
-  return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
+  return SMDS_Mesh::AddQuadPolygonalFaceWithID(nodes, myCellFactory->GetFreeID());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1423,15 +900,14 @@ SMDS_MeshFace* SMDS_Mesh::AddQuadPolygonalFace (const vector<const SMDS_MeshNode
 /// or if input nodes are not found.
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
-                             (const vector<int> & nodes_ids,
-                              const vector<int> & quantities,
-                              const int           ID)
+SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID (const std::vector<int> & nodes_ids,
+                                                        const std::vector<int> & quantities,
+                                                        const int                ID)
 {
   int nbNodes = nodes_ids.size();
-  vector<const SMDS_MeshNode*> nodes (nbNodes);
+  std::vector<const SMDS_MeshNode*> nodes (nbNodes);
   for (int i = 0; i < nbNodes; i++) {
-    nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
+    nodes[i] = myNodeFactory->FindNode(nodes_ids[i]);
     if (!nodes[i]) return NULL;
   }
   return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
@@ -1444,57 +920,22 @@ SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume*
-SMDS_Mesh::AddPolyhedralVolumeWithID (const vector<const SMDS_MeshNode*>& nodes,
-                                      const vector<int>                 & quantities,
+SMDS_Mesh::AddPolyhedralVolumeWithID (const std::vector<const SMDS_MeshNode*>& nodes,
+                                      const std::vector<int>                 & quantities,
                                       const int                           ID)
 {
-  SMDS_MeshVolume* volume = 0;
   if ( nodes.empty() || quantities.empty() )
     return NULL;
   if ( NbVolumes() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-  if (hasConstructionFaces())
-  {
-    return NULL;
-  }
-  else if (hasConstructionEdges())
-  {
-    return NULL;
-  }
-  else
+
+  if ( SMDS_MeshCell* cell = myCellFactory->NewCell( ID ))
   {
-    //#ifdef VTK_HAVE_POLYHEDRON
-    myNodeIds.resize( nodes.size() );
-    for ( size_t i = 0; i < nodes.size(); ++i )
-      myNodeIds[i] = nodes[i]->getVtkId();
-
-    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
-    volvtk->initPoly(myNodeIds, quantities, this);
-    if (!this->registerElement(ID, volvtk))
-    {
-      this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
-      myVolumePool->destroy(volvtk);
-      return 0;
-    }
-    volume = volvtk;
-    //#else
-    //      for ( int i = 0; i < nodes.size(); ++i )
-    //      if ( !nodes[ i ] ) return 0;
-    //      volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
-    //#endif
-    adjustmyCellsCapacity(ID);
-    myCells[ID] = volume;
+    SMDS_MeshVolume* volume = static_cast<SMDS_MeshVolume*>( cell );
+    volume->init( nodes, quantities );
     myInfo.myNbPolyhedrons++;
+    return volume;
   }
-
-  //#ifndef VTK_HAVE_POLYHEDRON
-  //  if (!registerElement(ID, volume))
-  //    {
-  //      registerElement(myElementIDFactory->GetFreeID(), volume);
-  //      //RemoveElement(volume, false);
-  //      //volume = NULL;
-  //    }
-  //#endif
-  return volume;
+  return 0;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1503,160 +944,31 @@ SMDS_Mesh::AddPolyhedralVolumeWithID (const vector<const SMDS_MeshNode*>& nodes,
 ///////////////////////////////////////////////////////////////////////////////
 
 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
-                            (const vector<const SMDS_MeshNode*> & nodes,
                            const vector<int>                  & quantities)
+(const std::vector<const SMDS_MeshNode*> & nodes,
const std::vector<int>                  & quantities)
 {
-  int ID = myElementIDFactory->GetFreeID();
-  SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
-  if (v == NULL) myElementIDFactory->ReleaseID(ID);
-  return v;
+  int ID = myCellFactory->GetFreeID();
+  return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
 }
 
 SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
 {
-  int ID = myElementIDFactory->GetFreeID();
-  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeFromVtkIdsWithID(vtkNodeIds, ID);
-  if (v == NULL) myElementIDFactory->ReleaseID(ID);
-  return v;
-}
-
-SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
-{
-  SMDS_VtkVolume *volvtk = myVolumePool->getNew();
-  volvtk->init(vtkNodeIds, this);
-  if (!this->registerElement(ID,volvtk))
-    {
-      this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
-      myVolumePool->destroy(volvtk);
-      return 0;
-    }
-  adjustmyCellsCapacity(ID);
-  myCells[ID] = volvtk;
-  vtkIdType aVtkType = volvtk->GetVtkType();
-  switch (aVtkType)
-  {
-    case VTK_TETRA:
-      myInfo.myNbTetras++;
-      break;
-    case VTK_PYRAMID:
-      myInfo.myNbPyramids++;
-      break;
-    case VTK_WEDGE:
-      myInfo.myNbPrisms++;
-      break;
-    case VTK_HEXAHEDRON:
-      myInfo.myNbHexas++;
-      break;
-    case VTK_QUADRATIC_TETRA:
-      myInfo.myNbQuadTetras++;
-      break;
-    case VTK_QUADRATIC_PYRAMID:
-      myInfo.myNbQuadPyramids++;
-      break;
-    case VTK_QUADRATIC_WEDGE:
-      myInfo.myNbQuadPrisms++;
-      break;
-    case VTK_BIQUADRATIC_QUADRATIC_WEDGE:
-      myInfo.myNbBiQuadPrisms++;
-      break;
-    case VTK_QUADRATIC_HEXAHEDRON:
-      myInfo.myNbQuadHexas++;
-      break;
-    case VTK_TRIQUADRATIC_HEXAHEDRON:
-      myInfo.myNbTriQuadHexas++;
-      break;
-//#ifdef VTK_HAVE_POLYHEDRON
-    case VTK_POLYHEDRON:
-      myInfo.myNbPolyhedrons++;
-      break;
-//#endif
-    default:
-      myInfo.myNbPolyhedrons++;
-      break;
-  }
-  return volvtk;
+  SMDS_MeshCell*   cell = myCellFactory->NewCell( myCellFactory->GetFreeID() );
+  SMDS_MeshVolume * vol = static_cast<SMDS_MeshVolume*>( cell );
+  vol->init( vtkNodeIds );
+  myInfo.add( cell );
+  return vol;
 }
 
 SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIds(const std::vector<vtkIdType>& vtkNodeIds)
 {
-  int ID = myElementIDFactory->GetFreeID();
-  SMDS_MeshFace * f = SMDS_Mesh::AddFaceFromVtkIdsWithID(vtkNodeIds, ID);
-  if (f == NULL) myElementIDFactory->ReleaseID(ID);
+  SMDS_MeshCell* cell = myCellFactory->NewCell( myCellFactory->GetFreeID() );
+  SMDS_MeshFace *   f = static_cast<SMDS_MeshFace*>( cell );
+  f->init( vtkNodeIds );
+  myInfo.add( cell );
   return f;
 }
 
-SMDS_MeshFace* SMDS_Mesh::AddFaceFromVtkIdsWithID(const std::vector<vtkIdType>& vtkNodeIds, const int ID)
-{
-  SMDS_VtkFace *facevtk = myFacePool->getNew();
-  facevtk->init(vtkNodeIds, this);
-  if (!this->registerElement(ID,facevtk))
-    {
-      this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
-      myFacePool->destroy(facevtk);
-      return 0;
-    }
-  adjustmyCellsCapacity(ID);
-  myCells[ID] = facevtk;
-  vtkIdType aVtkType = facevtk->GetVtkType();
-  switch (aVtkType)
-  {
-    case VTK_TRIANGLE:
-      myInfo.myNbTriangles++;
-      break;
-    case VTK_QUAD:
-      myInfo.myNbQuadrangles++;
-      break;
-    case VTK_QUADRATIC_TRIANGLE:
-      myInfo.myNbQuadTriangles++;
-      break;
-    case VTK_QUADRATIC_QUAD:
-      myInfo.myNbQuadQuadrangles++;
-      break;
-    case VTK_BIQUADRATIC_QUAD:
-      myInfo.myNbBiQuadQuadrangles++;
-      break;
-    case VTK_BIQUADRATIC_TRIANGLE:
-      myInfo.myNbBiQuadTriangles++;
-      break;
-    case VTK_POLYGON:
-      myInfo.myNbPolygons++;
-      break;
-     default:
-      myInfo.myNbPolygons++;
-  }
-  return facevtk;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// Registers element with the given ID, maintains inverse connections
-///////////////////////////////////////////////////////////////////////////////
-bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
-{
-  if ((ID >=0) && (ID < (int)myCells.size()) && myCells[ID]) // --- already bound
-  {
-    MESSAGE(" ------------------ already bound "<< ID << " " << myCells[ID]->getVtkId());
-    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 (vtkId >= (int)myCellIdVtkToSmds.size()) // --- resize local vector
-  {
-    myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1);
-  }
-  myCellIdVtkToSmds[vtkId] = ID;
-
-  myElementIDFactory->updateMinMax(ID);
-  return true;
-}
-
 //=======================================================================
 //function : MoveNode
 //purpose  : 
@@ -1673,11 +985,7 @@ void SMDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
 ///////////////////////////////////////////////////////////////////////////////
 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
 {
-  if (ID < 1 || ID >= (int)myNodes.size())
-  {
-    return 0;
-  }
-  return (const SMDS_MeshNode *)myNodes[ID];
+  return myNodeFactory->FindNode( ID );
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1685,117 +993,12 @@ const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
 ///////////////////////////////////////////////////////////////////////////////
 const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const
 {
-  // TODO if needed use mesh->nodeIdFromVtkToSmds
-  if ( vtkId < 0 || vtkId+1 >= (int) myNodes.size() )
-  {
-    MESSAGE("------------------------------------------------------------------------- ");
-    MESSAGE("---------------------------- bad VTK ID " << vtkId << " " << myNodes.size());
-    MESSAGE("------------------------------------------------------------------------- ");
-    return 0;
-  }
-  return (const SMDS_MeshNode *)myNodes[vtkId+1];
+  return myNodeFactory->FindNode( vtkId + 1 );
 }
 
-//////////////////////////////////////////////////////////////////////////////
-///Create a triangle and add it to the current mesh. This method does 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,
-                                          int ID)
+const SMDS_MeshElement * SMDS_Mesh::FindElementVtk(int IDelem) const
 {
-  if ( !node1 || !node2 || !node3) return 0;
-  if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-  if(hasConstructionEdges())
-  {
-    SMDS_MeshEdge *edge1, *edge2, *edge3;
-    edge1=FindEdgeOrCreate(node1,node2);
-    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);
-    adjustmyCellsCapacity(ID);
-    myCells[ID] = face;
-    myInfo.myNbTriangles++;
-    return face;
-  }
-  else
-  {
-    // --- retrieve nodes ID
-    myNodeIds.resize(3);
-    myNodeIds[0] = node1->getVtkId();
-    myNodeIds[1] = node2->getVtkId();
-    myNodeIds[2] = node3->getVtkId();
-
-    SMDS_MeshFace * face = 0;
-    SMDS_VtkFace *facevtk = myFacePool->getNew();
-    facevtk->init(myNodeIds, this); // put in vtkUnstructuredGrid
-    if (!this->registerElement(ID,facevtk))
-    {
-      this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
-      myFacePool->destroy(facevtk);
-      return 0;
-    }
-    face = facevtk;
-    adjustmyCellsCapacity(ID);
-    myCells[ID] = face;
-    myInfo.myNbTriangles++;
-    return face;
-  }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-///Create a quadrangle and add it to the current mesh. This method does not bind
-///an 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,
-                                            int ID)
-{
-  if ( !node1 || !node2 || !node3 || !node4 ) return 0;
-  if ( NbFaces() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-  if(hasConstructionEdges())
-  {
-    SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
-    edge1=FindEdgeOrCreate(node1,node2);
-    edge2=FindEdgeOrCreate(node2,node3);
-    edge3=FindEdgeOrCreate(node3,node4);
-    edge4=FindEdgeOrCreate(node4,node1);
-
-    SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
-    adjustmyCellsCapacity(ID);
-    myCells[ID] = face;
-    myInfo.myNbQuadrangles++;
-    return face;
-  }
-  else
-  {
-    // --- retrieve nodes ID
-    myNodeIds.resize(4);
-    myNodeIds[0] = node1->getVtkId();
-    myNodeIds[1] = node2->getVtkId();
-    myNodeIds[2] = node3->getVtkId();
-    myNodeIds[3] = node4->getVtkId();
-
-    SMDS_MeshFace * face = 0;
-    SMDS_VtkFace *facevtk = myFacePool->getNew();
-    facevtk->init(myNodeIds, this);
-    if (!this->registerElement(ID,facevtk))
-    {
-      this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
-      myFacePool->destroy(facevtk);
-      return 0;
-    }
-    face = facevtk;
-    adjustmyCellsCapacity(ID);
-    myCells[ID] = face;
-    myInfo.myNbQuadrangles++;
-    return face;
-  }
+  return myCellFactory->FindElement( FromVtkToSmds( IDelem ));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1807,42 +1010,6 @@ void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
   RemoveElement(node, true);
 }
 
-///////////////////////////////////////////////////////////////////////////////
-/// Remove an edge and all the elements which own this edge
-///////////////////////////////////////////////////////////////////////////////
-
-void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
-{
-  RemoveElement(elem0d,true);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// Remove an edge and all the elements which own this edge
-///////////////////////////////////////////////////////////////////////////////
-
-void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
-{
-  RemoveElement(edge,true);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// Remove an face and all the elements which own this face
-///////////////////////////////////////////////////////////////////////////////
-
-void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
-{
-  RemoveElement(face, true);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// Remove a volume
-///////////////////////////////////////////////////////////////////////////////
-
-void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
-{
-  RemoveElement(volume, true);
-}
-
 //=======================================================================
 //function : RemoveFromParent
 //purpose  :
@@ -1863,7 +1030,7 @@ bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
 {
   bool found = false;
 
-  list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
+  std::list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
   for (; itmsh!=myChildren.end() && !found; itmsh++)
   {
     SMDS_Mesh * submesh = *itmsh;
@@ -1886,28 +1053,27 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
                                    const SMDS_MeshNode    * nodes[],
                                    const int                nbnodes)
 {
-  // keep current nodes of elem
-  set<const SMDS_MeshNode*> oldNodes( element->begin_nodes(), element->end_nodes() );
+  // keep current nodes of element
+  std::set<const SMDS_MeshNode*> oldNodes( element->begin_nodes(), element->end_nodes() );
 
   // change nodes
   bool Ok = false;
-  SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element);
-  if (cell)
-  {
-    Ok = cell->vtkOrder(nodes, nbnodes);
+  if ( SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element))
     Ok = cell->ChangeNodes(nodes, nbnodes);
-  }
 
-  if ( Ok ) { // update InverseElements
+  if ( Ok )
+    setMyModified();
 
-    set<const SMDS_MeshNode*>::iterator it;
+  if ( Ok && GetGrid()->HasLinks() ) // update InverseElements
+  {
+    std::set<const SMDS_MeshNode*>::iterator it;
 
     // AddInverseElement to new nodes
     for ( int i = 0; i < nbnodes; i++ ) {
       it = oldNodes.find( nodes[i] );
       if ( it == oldNodes.end() )
         // new node
-        const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( cell );
+        const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( element );
       else
         // remove from oldNodes a node that remains in elem
         oldNodes.erase( it );
@@ -1916,84 +1082,13 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
     for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
     {
       SMDS_MeshNode * n = const_cast<SMDS_MeshNode *>( *it );
-      n->RemoveInverseElement( cell );
+      n->RemoveInverseElement( element );
     }
   }
 
   return Ok;
 }
 
-//=======================================================================
-//function : ChangePolyhedronNodes
-//purpose  : to change nodes of polyhedral volume
-//=======================================================================
-bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement *            elem,
-                                       const vector<const SMDS_MeshNode*>& nodes,
-                                       const vector<int>                 & quantities)
-{
-  if (elem->GetType() != SMDSAbs_Volume) {
-    MESSAGE("WRONG ELEM TYPE");
-    return false;
-  }
-
-  const SMDS_VtkVolume* vol = dynamic_cast<const SMDS_VtkVolume*>(elem);
-  if (!vol) {
-    return false;
-  }
-
-  // keep current nodes of elem
-  set<const SMDS_MeshElement*> oldNodes;
-  SMDS_ElemIteratorPtr itn = elem->nodesIterator();
-  while (itn->more()) {
-    oldNodes.insert(itn->next());
-  }
-
-  // change nodes
-  // TODO remove this function
-  //bool Ok = const_cast<SMDS_VtkVolume*>(vol)->ChangeNodes(nodes, quantities);
-  bool Ok = false;
-  if (!Ok) {
-    return false;
-  }
-
-  // update InverseElements
-
-  // AddInverseElement to new nodes
-  int nbnodes = nodes.size();
-  set<const SMDS_MeshElement*>::iterator it;
-  for (int i = 0; i < nbnodes; i++) {
-    it = oldNodes.find(nodes[i]);
-    if (it == oldNodes.end()) {
-      // new node
-      const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
-    } else {
-      // remove from oldNodes a node that remains in elem
-      oldNodes.erase(it);
-    }
-  }
-
-  // RemoveInverseElement from the nodes removed from elem
-  for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
-    SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
-      (const_cast<SMDS_MeshElement *>( *it ));
-    n->RemoveInverseElement(elem);
-  }
-
-  return Ok;
-}
-
-
-//=======================================================================
-//function : 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;
@@ -2008,18 +1103,6 @@ const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
   return toReturn;
 }
 
-//=======================================================================
-//function : FindBall
-//purpose  :
-//=======================================================================
-
-const SMDS_BallElement* SMDS_Mesh::FindBall(int idnode) const
-{
-  const SMDS_MeshNode * node = FindNode(idnode);
-  if(node == NULL) return NULL;
-  return FindBall(node);
-}
-
 const SMDS_BallElement* SMDS_Mesh::FindBall(const SMDS_MeshNode * node)
 {
   if (!node) return 0;
@@ -2033,49 +1116,12 @@ const SMDS_BallElement* SMDS_Mesh::FindBall(const SMDS_MeshNode * node)
   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  :
-//=======================================================================
-
-const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
-{
-  const SMDS_MeshNode * node1=FindNode(idnode1);
-  const SMDS_MeshNode * node2=FindNode(idnode2);
-  if((node1==NULL)||(node2==NULL)) return NULL;
-  return FindEdge(node1,node2);
-}
-
-//#include "Profiler.h"
 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
                                          const SMDS_MeshNode * node2)
 {
   if ( !node1 ) return 0;
   const SMDS_MeshEdge * toReturn=NULL;
-  //PROFILER_Init();
-  //PROFILER_Set();
   SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
-  //PROFILER_Get(0);
-  //PROFILER_Set();
   while(it1->more()) {
     const SMDS_MeshElement * e = it1->next();
     if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
@@ -2083,60 +1129,9 @@ const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
       break;
     }
   }
-  //PROFILER_Get(1);
   return toReturn;
 }
 
-
-//=======================================================================
-//function : FindEdgeOrCreate
-//purpose  :
-//=======================================================================
-
-SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
-                                           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 ( NbEdges() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-    int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
-    adjustmyCellsCapacity(ID);
-    myNodeIds.resize(2);
-    myNodeIds[0] = node1->getVtkId();
-    myNodeIds[1] = node2->getVtkId();
-
-    SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
-    edgevtk->init(myNodeIds, this);
-    if (!this->registerElement(ID,edgevtk))
-    {
-      this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
-      myEdgePool->destroy(edgevtk);
-      return 0;
-    }
-    toReturn = edgevtk;
-    myCells[ID] = toReturn;
-    myInfo.myNbEdges++;
-  }
-  return toReturn;
-}
-
-
-//=======================================================================
-//function : FindEdge
-//purpose  :
-//=======================================================================
-
-const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
-                                         int idnode3) const
-{
-  const SMDS_MeshNode * node1=FindNode(idnode1);
-  const SMDS_MeshNode * node2=FindNode(idnode2);
-  const SMDS_MeshNode * node3=FindNode(idnode3);
-  return FindEdge(node1,node2,node3);
-}
-
 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
                                          const SMDS_MeshNode * node2,
                                          const SMDS_MeshNode * node3)
@@ -2164,21 +1159,11 @@ const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
   return 0;
 }
 
-
 //=======================================================================
 //function : FindFace
 //purpose  :
 //=======================================================================
 
-const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
-        int idnode3) const
-{
-  const SMDS_MeshNode * node1=FindNode(idnode1);
-  const SMDS_MeshNode * node2=FindNode(idnode2);
-  const SMDS_MeshNode * node3=FindNode(idnode3);
-  return FindFace(node1, node2, node3);
-}
-
 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
                                          const SMDS_MeshNode *node2,
                                          const SMDS_MeshNode *node3)
@@ -2206,35 +1191,11 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
   return 0;
 }
 
-SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
-                                           const SMDS_MeshNode *node2,
-                                           const SMDS_MeshNode *node3)
-{
-  SMDS_MeshFace * toReturn=NULL;
-  toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
-  if(toReturn==NULL) {
-    int ID = myElementIDFactory->GetFreeID();
-    toReturn = createTriangle(node1,node2,node3, ID);
-  }
-  return toReturn;
-}
-
-
 //=======================================================================
 //function : FindFace
 //purpose  :
 //=======================================================================
 
-const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
-                                         int idnode3, int idnode4) const
-{
-  const SMDS_MeshNode * node1=FindNode(idnode1);
-  const SMDS_MeshNode * node2=FindNode(idnode2);
-  const SMDS_MeshNode * node3=FindNode(idnode3);
-  const SMDS_MeshNode * node4=FindNode(idnode4);
-  return FindFace(node1, node2, node3, node4);
-}
-
 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
                                          const SMDS_MeshNode *node2,
                                          const SMDS_MeshNode *node3,
@@ -2264,39 +1225,11 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
   return 0;
 }
 
-SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
-                                           const SMDS_MeshNode *node2,
-                                           const SMDS_MeshNode *node3,
-                                           const SMDS_MeshNode *node4)
-{
-  SMDS_MeshFace * toReturn=NULL;
-  toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
-  if(toReturn==NULL) {
-    int ID = myElementIDFactory->GetFreeID();
-    toReturn=createQuadrangle(node1,node2,node3,node4,ID);
-  }
-  return toReturn;
-}
-
-
 //=======================================================================
 //function : FindFace
 //purpose  :quadratic triangle
 //=======================================================================
 
-const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
-                                         int idnode3, int idnode4,
-                                         int idnode5, int idnode6) const
-{
-  const SMDS_MeshNode * node1 = FindNode(idnode1);
-  const SMDS_MeshNode * node2 = FindNode(idnode2);
-  const SMDS_MeshNode * node3 = FindNode(idnode3);
-  const SMDS_MeshNode * node4 = FindNode(idnode4);
-  const SMDS_MeshNode * node5 = FindNode(idnode5);
-  const SMDS_MeshNode * node6 = FindNode(idnode6);
-  return FindFace(node1, node2, node3, node4, node5, node6);
-}
-
 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
                                          const SMDS_MeshNode *node2,
                                          const SMDS_MeshNode *node3,
@@ -2336,22 +1269,6 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
 //purpose  : quadratic quadrangle
 //=======================================================================
 
-const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
-                                         int idnode3, int idnode4,
-                                         int idnode5, int idnode6,
-                                         int idnode7, int idnode8) const
-{
-  const SMDS_MeshNode * node1 = FindNode(idnode1);
-  const SMDS_MeshNode * node2 = FindNode(idnode2);
-  const SMDS_MeshNode * node3 = FindNode(idnode3);
-  const SMDS_MeshNode * node4 = FindNode(idnode4);
-  const SMDS_MeshNode * node5 = FindNode(idnode5);
-  const SMDS_MeshNode * node6 = FindNode(idnode6);
-  const SMDS_MeshNode * node7 = FindNode(idnode7);
-  const SMDS_MeshNode * node8 = FindNode(idnode8);
-  return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
-}
-
 const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
                                          const SMDS_MeshNode *node2,
                                          const SMDS_MeshNode *node3,
@@ -2397,11 +1314,7 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
 
 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
 {
-  if ( IDelem <= 0 || IDelem >= (int)myCells.size() )
-  {
-    return 0;
-  }
-  return myCells[IDelem];
+  return myCellFactory->FindElement( IDelem );
 }
 
 //=======================================================================
@@ -2409,19 +1322,8 @@ const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
 //purpose  : find polygon
 //=======================================================================
 
-const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<int>& nodes_ids) const
-{
-  int nbnodes = nodes_ids.size();
-  vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
-  for (int inode = 0; inode < nbnodes; inode++) {
-    const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
-    if (node == NULL) return NULL;
-    poly_nodes[inode] = node;
-  }
-  return FindFace(poly_nodes);
-}
 
-const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<const SMDS_MeshNode *>& nodes)
+const SMDS_MeshFace* SMDS_Mesh::FindFace (const std::vector<const SMDS_MeshNode *>& nodes)
 {
   return (const SMDS_MeshFace*) FindElement( nodes, SMDSAbs_Face );
 }
@@ -2437,7 +1339,7 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace (const vector<const SMDS_MeshNode *>& n
  */
 //================================================================================
 
-const SMDS_MeshElement* SMDS_Mesh::FindElement (const vector<const SMDS_MeshNode *>& nodes,
+const SMDS_MeshElement* SMDS_Mesh::FindElement (const std::vector<const SMDS_MeshNode *>& nodes,
                                                 const SMDSAbs_ElementType            type,
                                                 const bool                           noMedium)
 {
@@ -2507,110 +1409,6 @@ int SMDS_Mesh::GetElementsByNodes(const std::vector<const SMDS_MeshNode *>& node
   return foundElems.size();
 }
 
-//=======================================================================
-//function : DumpNodes
-//purpose  :
-//=======================================================================
-
-void SMDS_Mesh::DumpNodes() const
-{
-  SMDS_NodeIteratorPtr itnode=nodesIterator();
-  while(itnode->more()) ; //MESSAGE(itnode->next());
-}
-
-//=======================================================================
-//function : Dump0DElements
-//purpose  :
-//=======================================================================
-void SMDS_Mesh::Dump0DElements() const
-{
-  SMDS_ElemIteratorPtr it0d = elementsIterator(SMDSAbs_0DElement);
-  while(it0d->more()) ; //MESSAGE(it0d->next());
-}
-
-//=======================================================================
-//function : DumpEdges
-//purpose  :
-//=======================================================================
-
-void SMDS_Mesh::DumpEdges() const
-{
-  SMDS_EdgeIteratorPtr itedge=edgesIterator();
-  while(itedge->more()) ; //MESSAGE(itedge->next());
-}
-
-//=======================================================================
-//function : DumpFaces
-//purpose  :
-//=======================================================================
-
-void SMDS_Mesh::DumpFaces() const
-{
-  SMDS_FaceIteratorPtr itface=facesIterator();
-  while(itface->more()) ; //MESSAGE(itface->next());
-}
-
-//=======================================================================
-//function : DumpVolumes
-//purpose  :
-//=======================================================================
-
-void SMDS_Mesh::DumpVolumes() const
-{
-  SMDS_VolumeIteratorPtr itvol=volumesIterator();
-  while(itvol->more()) ; //MESSAGE(itvol->next());
-}
-
-//=======================================================================
-//function : DebugStats
-//purpose  :
-//=======================================================================
-
-void SMDS_Mesh::DebugStats() const
-{
-  MESSAGE("Debug stats of mesh : ");
-
-  MESSAGE("===== NODES ====="<<NbNodes());
-  MESSAGE("===== 0DELEMS ====="<<Nb0DElements());
-  MESSAGE("===== EDGES ====="<<NbEdges());
-  MESSAGE("===== FACES ====="<<NbFaces());
-  MESSAGE("===== VOLUMES ====="<<NbVolumes());
-
-  MESSAGE("End Debug stats of mesh ");
-
-  //#ifdef DEB
-
-  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);
-    }
-  }
-
-  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);;
-
-  //#endif
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 /// Return the number of nodes
 ///////////////////////////////////////////////////////////////////////////////
@@ -2681,91 +1479,35 @@ int SMDS_Mesh::NbSubMesh() const
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_Mesh::~SMDS_Mesh()
 {
-  list<SMDS_Mesh*>::iterator itc=myChildren.begin();
+  std::list<SMDS_Mesh*>::iterator itc=myChildren.begin();
   while(itc!=myChildren.end())
   {
     delete *itc;
     itc++;
   }
 
-  if(myParent==NULL)
-  {
-    delete myNodeIDFactory;
-    delete myElementIDFactory;
-  }
-  else
-  {
-    SMDS_ElemIteratorPtr eIt = elementsIterator();
-    while ( eIt->more() )
-      {
-        const SMDS_MeshElement *elem = eIt->next();
-        myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
-      }
-    SMDS_NodeIteratorPtr itn = nodesIterator();
-    while (itn->more())
-      {
-        const SMDS_MeshNode *node = itn->next();
-        ((SMDS_MeshNode*)node)->SetPosition(SMDS_SpacePosition::originSpacePosition());
-        myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
-      }
-  }
-  myGrid->Delete();
+  delete myNodeFactory;
+  delete myCellFactory;
 
-  delete myNodePool;
-  delete myVolumePool;
-  delete myFacePool;
-  delete myEdgePool;
-  delete myBallPool;
+  myGrid->Delete();
 }
 
-//================================================================================
-/*!
- * \brief Clear all data
- */
-//================================================================================
-
-void SMDS_Mesh::Clear()
-{
-  if (myParent!=NULL)
-  {
-    SMDS_ElemIteratorPtr eIt = elementsIterator();
-    while ( eIt->more() )
-    {
-      const SMDS_MeshElement *elem = eIt->next();
-      myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
-    }
-    SMDS_NodeIteratorPtr itn = nodesIterator();
-    while (itn->more())
-    {
-      const SMDS_MeshNode *node = itn->next();
-      myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
-    }
-  }
-  else
-  {
-    myNodeIDFactory->Clear();
-    myElementIDFactory->Clear();
-  }
-
-  myVolumePool->clear();
-  myFacePool->clear();
-  myEdgePool->clear();
-  myBallPool->clear();
+//================================================================================
+/*!
+ * \brief Clear all data
+ */
+//================================================================================
 
-  clearVector( myCells );
-  clearVector( myCellIdVtkToSmds );
+void SMDS_Mesh::Clear()
+{
+  std::set< SMDS_ElementHolder* >::iterator holder = myElemHolders.begin();
+  for ( ; holder != myElemHolders.end(); ++holder )
+    (*holder)->clear();
 
-  SMDS_NodeIteratorPtr itn = nodesIterator();
-  while (itn->more())
-  {
-    SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next());
-    node->SetPosition(SMDS_SpacePosition::originSpacePosition());
-    //myNodePool->destroy(node);
-  }
-  myNodePool->clear();
-  clearVector( myNodes );
+  myNodeFactory->Clear();
+  myCellFactory->Clear();
 
-  list<SMDS_Mesh*>::iterator itc=myChildren.begin();
+  std::list<SMDS_Mesh*>::iterator itc=myChildren.begin();
   while(itc!=myChildren.end())
     (*itc)->Clear();
 
@@ -2790,181 +1532,28 @@ void SMDS_Mesh::Clear()
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Return true if this mesh create faces with edges.
-/// A false returned value mean that faces are created with nodes. A concequence
-/// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
-///////////////////////////////////////////////////////////////////////////////
-bool SMDS_Mesh::hasConstructionEdges()
-{
-  return myHasConstructionEdges;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// Return true if this mesh create volumes with faces
-/// A false returned value mean that volumes are created with nodes or edges.
-/// (see hasConstructionEdges)
-/// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
-/// unavailable.
-///////////////////////////////////////////////////////////////////////////////
-bool SMDS_Mesh::hasConstructionFaces()
-{
-  return myHasConstructionFaces;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// Return true if nodes are linked to the finit elements, they are belonging to.
-/// Currently, It always return true.
-///////////////////////////////////////////////////////////////////////////////
-bool SMDS_Mesh::hasInverseElements()
-{
-  return myHasInverseElements;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// Make this mesh creating construction edges (see hasConstructionEdges)
-/// @param b true to have construction edges, else false.
-///////////////////////////////////////////////////////////////////////////////
-void SMDS_Mesh::setConstructionEdges(bool b)
-{
-  myHasConstructionEdges=b;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// Make this mesh creating construction faces (see hasConstructionFaces)
-/// @param b true to have construction faces, else false.
-///////////////////////////////////////////////////////////////////////////////
-void SMDS_Mesh::setConstructionFaces(bool b)
-{
-  myHasConstructionFaces=b;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-/// Make this mesh creating link from nodes to elements (see hasInverseElements)
-/// @param b true to link nodes to elements, else false.
-///////////////////////////////////////////////////////////////////////////////
-void SMDS_Mesh::setInverseElements(bool b)
-{
-  if(!b) MESSAGE("Error : inverseElement=false not implemented");
-  myHasInverseElements=b;
-}
-
-namespace {
-
-  //================================================================================
-  /*!
-   * \brief Iterator on elements in id increasing order
-   */
-  //================================================================================
-
-  template <typename ELEM=const SMDS_MeshElement*>
-  class IdSortedIterator : public SMDS_Iterator<ELEM>
-  {
-    SMDS_MeshElementIDFactory&       myIDFact;
-    int                              myID, myMaxID, myNbFound, myTotalNb;
-    SMDSAbs_ElementType              myType;
-    ELEM                             myElem;
-
-  public:
-    IdSortedIterator(const SMDS_MeshElementIDFactory& fact,
-                     const SMDSAbs_ElementType        type, // SMDSAbs_All NOT allowed!!! 
-                     const int                        totalNb)
-      :myIDFact( const_cast<SMDS_MeshElementIDFactory&>(fact) ),
-       myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ),
-       myType( type ),
-       myElem(0)
-    {
-      next();
-    }
-    bool more()
-    {
-      return myElem;
-    }
-    ELEM next()
-    {
-      ELEM current = myElem;
-
-      for ( myElem = 0;  !myElem && myNbFound < myTotalNb && myID <= myMaxID; ++myID )
-        if ((myElem = (ELEM) myIDFact.MeshElement( myID ))
-            && myElem->GetType() != myType )
-          myElem = 0;
-
-      myNbFound += bool(myElem);
-
-      return current;
-    }
-  };
-
-  //================================================================================
-  /*!
-   * \brief Iterator on vector of elements, possibly being resized while iteration
-   */
-  //================================================================================
-
-  template<typename RETURN_VALUE,
-           typename VECTOR_VALUE=SMDS_MeshCell*,
-           typename VALUE_FILTER=SMDS::NonNullFilter<VECTOR_VALUE> >
-  class ElemVecIterator: public SMDS_Iterator<RETURN_VALUE>
-  {
-    const std::vector<VECTOR_VALUE>& _vector;
-    size_t                           _index;
-    bool                             _more;
-    VALUE_FILTER                     _filter;
-  public:
-    ElemVecIterator(const std::vector<VECTOR_VALUE>& vec,
-                    const VALUE_FILTER&              filter=VALUE_FILTER() )
-      :_vector( vec ), _index(0), _more( !vec.empty() ), _filter( filter )
-    {
-      if ( _more && !_filter( _vector[ _index ]))
-        next();
-    }
-    virtual bool more()
-    {
-      return _more;
-    }
-    virtual RETURN_VALUE next()
-    {
-      if ( !_more ) return NULL;
-      VECTOR_VALUE current = _vector[ _index ];
-      _more = 0;
-      while ( !_more && ++_index < _vector.size() )
-        _more = _filter( _vector[ _index ]);
-      return (RETURN_VALUE) current;
-    }
-  };
-}
-
-///////////////////////////////////////////////////////////////////////////////
 /// Return an iterator on nodes of the current mesh factory
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
+SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
 {
-  // naturally always sorted by ID
-  typedef ElemVecIterator<const SMDS_MeshNode*, SMDS_MeshNode*> TIterator;
-  return SMDS_NodeIteratorPtr( new TIterator(myNodes));
+  return myNodeFactory->GetIterator< SMDS_NodeIterator >( new SMDS_MeshElement::NonNullFilter );
 }
 
 SMDS_ElemIteratorPtr SMDS_Mesh::elementGeomIterator(SMDSAbs_GeometryType type) const
 {
-  // naturally always sorted by ID
-  typedef ElemVecIterator
-    < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::GeomFilter > TIterator;
-  return SMDS_ElemIteratorPtr
-    (new TIterator(myCells, SMDS_MeshElement::GeomFilter( type )));
+  return myCellFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::GeomFilter( type ),
+                                                          myInfo.NbElements( type ));
 }
 
 SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) const
 {
   if ( type == SMDSEntity_Node )
   {
-    typedef ElemVecIterator<const SMDS_MeshElement*, SMDS_MeshNode*> TIterator;
-    return SMDS_ElemIteratorPtr( new TIterator(myNodes));
+    return myNodeFactory->GetIterator< SMDS_ElemIterator >( new SMDS_MeshElement::NonNullFilter );
   }
-  // naturally always sorted by ID
-  typedef ElemVecIterator
-    < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::EntityFilter > TIterator;
-  return SMDS_ElemIteratorPtr
-    (new TIterator(myCells, SMDS_MeshElement::EntityFilter( type )));
+  return myCellFactory->GetIterator<SMDS_ElemIterator>( new SMDS_MeshElement::EntityFilter( type ),
+                                                        myInfo.NbElements( type ));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -2972,20 +1561,18 @@ SMDS_ElemIteratorPtr SMDS_Mesh::elementEntityIterator(SMDSAbs_EntityType type) c
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
 {
-  // naturally always sorted by ID
+  typedef SMDS_ElemIterator TIterator;
   switch ( type ) {
 
   case SMDSAbs_All:
-    return SMDS_ElemIteratorPtr (new ElemVecIterator<const SMDS_MeshElement*>(myCells));
+    return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter );
 
   case SMDSAbs_Node:
-    return SMDS_ElemIteratorPtr
-      ( new ElemVecIterator<const SMDS_MeshElement*, SMDS_MeshNode*>( myNodes ));
+    return myNodeFactory->GetIterator< TIterator >( new SMDS_MeshElement::NonNullFilter );
 
   default:
-    typedef ElemVecIterator
-      < const SMDS_MeshElement*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
-    return SMDS_ElemIteratorPtr (new TIterator(myCells, SMDS_MeshElement::TypeFilter( type )));
+    return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( type ),
+                                                    myInfo.NbElements( type ));
   }
   return SMDS_ElemIteratorPtr();
 }
@@ -2994,118 +1581,113 @@ SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
 ///Return an iterator on edges of the current mesh.
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const
+SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
 {
-  // naturally always sorted by ID
-  typedef ElemVecIterator
-    < const SMDS_MeshEdge*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
-  return SMDS_EdgeIteratorPtr
-    (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Edge )));
+  typedef SMDS_EdgeIterator TIterator;
+  return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Edge ),
+                                                  myInfo.NbEdges());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 ///Return an iterator on faces of the current mesh.
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const
+SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
 {
-  // naturally always sorted by ID
-  typedef ElemVecIterator
-    < const SMDS_MeshFace*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
-  return SMDS_FaceIteratorPtr
-    (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Face )));
+  typedef SMDS_FaceIterator TIterator;
+  return myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Face ),
+                                                  myInfo.NbFaces());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 ///Return an iterator on volumes of the current mesh.
 ///////////////////////////////////////////////////////////////////////////////
 
-SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const
+SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
+{
+  typedef SMDS_VolumeIterator TIterator;
+  return
+    myCellFactory->GetIterator< TIterator >( new SMDS_MeshElement::TypeFilter( SMDSAbs_Volume ),
+                                             myInfo.NbVolumes());
+}
+
+SMDS_NodeIteratorPtr SMDS_Mesh::shapeNodesIterator(int shapeID, size_t nbElemsToReturn) const
+{
+  return myNodeFactory->GetShapeIterator< SMDS_NodeIterator >( shapeID, nbElemsToReturn );
+}
+
+SMDS_ElemIteratorPtr SMDS_Mesh::shapeElementsIterator(int shapeID, size_t nbElemsToReturn) const
 {
-  // naturally always sorted by ID
-  typedef ElemVecIterator
-    < const SMDS_MeshVolume*, SMDS_MeshCell*, SMDS_MeshElement::TypeFilter > TIterator;
-  return SMDS_VolumeIteratorPtr
-    (new TIterator(myCells, SMDS_MeshElement::TypeFilter( SMDSAbs_Volume )));
+  return myCellFactory->GetShapeIterator< SMDS_ElemIterator >( shapeID, nbElemsToReturn );
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 /// Do intersection of sets (more than 2)
 ///////////////////////////////////////////////////////////////////////////////
-static set<const SMDS_MeshElement*> * intersectionOfSets(
-        set<const SMDS_MeshElement*> vs[], int numberOfSets)
+static std::set<const SMDS_MeshElement*> *
+intersectionOfSets( std::set<const SMDS_MeshElement*> vs[], int numberOfSets )
 {
-        set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
-        set<const SMDS_MeshElement*>* rsetB;
+  std::set<const SMDS_MeshElement*>* rsetA = new std::set<const SMDS_MeshElement*>(vs[0]);
+  std::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 std::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 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)
+static std::set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
 {
   int numberOfSets=element->NbNodes();
-  set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
+  std::set<const SMDS_MeshElement*> *initSet = new std::set<const SMDS_MeshElement*>[numberOfSets];
 
-  SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
+  SMDS_NodeIteratorPtr itNodes = element->nodeIterator();
 
   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();
-
-    while ( itFe->more() )
-    {
-      const SMDS_MeshElement* elem = itFe->next();
-      MYASSERT(elem);
-      initSet[i].insert(elem);
-    }
-
+    const SMDS_MeshNode *   n = itNodes->next();
+    for ( SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); itFe->more(); )
+      initSet[i].insert( itFe->next() );
     i++;
   }
-  set<const SMDS_MeshElement*> *retSet = intersectionOfSets( initSet, numberOfSets );
+  std::set<const SMDS_MeshElement*> *retSet = intersectionOfSets( initSet, numberOfSets );
   delete [] initSet;
   return retSet;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Return the list of nodes used only by the given elements
+/// Return the std::list of nodes used only by the given elements
 ///////////////////////////////////////////////////////////////////////////////
-static set<const SMDS_MeshElement*> * getExclusiveNodes(set<const SMDS_MeshElement*>& elements)
+static
+std::set<const SMDS_MeshElement*> *getExclusiveNodes(std::set<const SMDS_MeshElement*>& elements)
 {
-  set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
-  set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
+  std::set<const SMDS_MeshElement*> *           toReturn = new std::set<const SMDS_MeshElement*>();
+  std::set<const SMDS_MeshElement*>::iterator itElements = elements.begin();
 
-  while(itElements!=elements.end())
+  while( itElements != elements.end() )
   {
-    SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
+    SMDS_NodeIteratorPtr itNodes = (*itElements)->nodeIterator();
     itElements++;
 
-    while(itNodes->more())
+    while( itNodes->more() )
     {
-      const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
+      const SMDS_MeshNode *   n = 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);
+      std::set<const SMDS_MeshElement*> s;
+      while ( itFe->more() )
+        s.insert( itFe->next() );
+      if ( s == elements ) toReturn->insert(n);
     }
   }
   return toReturn;
@@ -3117,14 +1699,14 @@ static set<const SMDS_MeshElement*> * getExclusiveNodes(set<const SMDS_MeshEleme
 ///@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)
+void SMDS_Mesh::addChildrenWithNodes(std::set<const SMDS_MeshElement*>& setOfChildren,
+                                     const SMDS_MeshElement *           element,
+                                     std::set<const SMDS_MeshElement*>& nodes)
 {
   switch(element->GetType())
   {
   case SMDSAbs_Node:
-    MESSAGE("Internal Error: This should not happen");
+    throw SALOME_Exception("Internal Error: This should not happen");
     break;
   case SMDSAbs_0DElement:
   case SMDSAbs_Ball:
@@ -3156,28 +1738,8 @@ void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren
         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);
-    }
-  }
   case SMDSAbs_NbElementTypes:
   case SMDSAbs_All: break;
   }
@@ -3188,10 +1750,10 @@ 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;
+  std::vector<const SMDS_MeshElement *> removedElems;
+  std::vector<const SMDS_MeshElement *> removedNodes;
   RemoveElement( elem, removedElems, removedNodes, removenodes );
 }
 
@@ -3201,169 +1763,91 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
 ///@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,
-                              list<const SMDS_MeshElement *>& removedElems,
-                              list<const SMDS_MeshElement *>& removedNodes,
-                              bool                            removenodes)
+void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *               elem,
+                              std::vector<const SMDS_MeshElement *>& removedElems,
+                              std::vector<const SMDS_MeshElement *>& removedNodes,
+                              bool                                   removenodes)
 {
   // get finite elements built on elem
-  set<const SMDS_MeshElement*> * s1;
+  std::set<const SMDS_MeshElement*> * s1;
   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*> ();
-      s1->insert(elem);
-    }
+          ||  (elem->GetType() == SMDSAbs_Ball)
+          ||  (elem->GetType() == SMDSAbs_Edge)
+          ||  (elem->GetType() == SMDSAbs_Face)
+          ||  (elem->GetType() == SMDSAbs_Volume) )
+  {
+    s1 = new std::set<const SMDS_MeshElement*> ();
+    s1->insert(elem);
+  }
   else
     s1 = getFinitElements(elem);
 
   // get exclusive nodes (which would become free afterwards)
-  set<const SMDS_MeshElement*> * s2;
+  std::set<const SMDS_MeshElement*> * s2;
   if (elem->GetType() == SMDSAbs_Node) // a node is removed
-    {
-      // do not remove nodes except elem
-      s2 = new set<const SMDS_MeshElement*> ();
-      s2->insert(elem);
-      removenodes = true;
-    }
+  {
+    // do not remove nodes except elem
+    s2 = new std::set<const SMDS_MeshElement*> ();
+    s2->insert(elem);
+    removenodes = true;
+  }
   else
     s2 = getExclusiveNodes(*s1);
 
   // form the set of finite and construction elements to remove
-  set<const SMDS_MeshElement*> s3;
-  set<const SMDS_MeshElement*>::iterator it = s1->begin();
+  std::set<const SMDS_MeshElement*> s3;
+  std::set<const SMDS_MeshElement*>::iterator it = s1->begin();
   while (it != s1->end())
-    {
-      addChildrenWithNodes(s3, *it, *s2);
-      s3.insert(*it);
-      it++;
-    }
+  {
+    addChildrenWithNodes(s3, *it, *s2);
+    s3.insert(*it);
+    it++;
+  }
   if (elem->GetType() != SMDSAbs_Node)
     s3.insert(elem);
 
   // remove finite and construction elements
-  it = s3.begin();
-  while (it != s3.end())
+  for( it = s3.begin();it != s3.end(); ++it )
+  {
+    // Remove element from <InverseElements> of its nodes
+    SMDS_NodeIteratorPtr itn = (*it)->nodeIterator();
+    while (itn->more())
     {
-      // Remove element from <InverseElements> of its nodes
-      SMDS_ElemIteratorPtr itn = (*it)->nodesIterator();
-      while (itn->more())
-      {
-        SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (itn->next()));
-        n->RemoveInverseElement((*it));
-      }
-      int IdToRemove = (*it)->GetID();
-      int vtkid = (*it)->getVtkId();
-      switch ((*it)->GetType())
-      {
-        case SMDSAbs_Node:
-          MYASSERT("Internal Error: This should not happen");
-          break;
-        case SMDSAbs_0DElement:
-          if (IdToRemove >= 0)
-            {
-              myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
-              myInfo.remove(*it);
-            }
-          removedElems.push_back((*it));
-          myElementIDFactory->ReleaseID(IdToRemove, vtkid);
-          delete (*it);
-          break;
-        case SMDSAbs_Edge:
-          if (IdToRemove >= 0)
-            {
-              myCells[IdToRemove] = 0;
-              myInfo.RemoveEdge(*it);
-            }
-          removedElems.push_back((*it));
-          myElementIDFactory->ReleaseID(IdToRemove, vtkid);
-          if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
-            myEdgePool->destroy((SMDS_VtkEdge*) vtkElem);
-          else {
-            ((SMDS_MeshElement*) *it)->init( 0, -1, -1 ); // avoid reuse
-            delete (*it);
-          }
-          break;
-        case SMDSAbs_Face:
-          if (IdToRemove >= 0)
-            {
-              myCells[IdToRemove] = 0;
-              myInfo.RemoveFace(*it);
-            }
-          removedElems.push_back((*it));
-          myElementIDFactory->ReleaseID(IdToRemove, vtkid);
-          if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
-            myFacePool->destroy((SMDS_VtkFace*) vtkElem);
-          else {
-            ((SMDS_MeshElement*) *it)->init( 0, -1, -1 ); // avoid reuse
-            delete (*it);
-          }
-          break;
-        case SMDSAbs_Volume:
-          if (IdToRemove >= 0)
-            {
-              myCells[IdToRemove] = 0;
-              myInfo.RemoveVolume(*it);
-            }
-          removedElems.push_back((*it));
-          myElementIDFactory->ReleaseID(IdToRemove, vtkid);
-          if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
-            myVolumePool->destroy((SMDS_VtkVolume*) vtkElem);
-          else {
-            ((SMDS_MeshElement*) *it)->init( 0, -1, -1 ); // avoid reuse
-            delete (*it);
-          }
-          break;
-        case SMDSAbs_Ball:
-          if (IdToRemove >= 0)
-            {
-              myCells[IdToRemove] = 0;
-              myInfo.remove(*it);
-            }
-          removedElems.push_back((*it));
-          myElementIDFactory->ReleaseID(IdToRemove, vtkid);
-          if (const SMDS_BallElement* vtkElem = dynamic_cast<const SMDS_BallElement*>(*it))
-            myBallPool->destroy(const_cast<SMDS_BallElement*>( vtkElem ));
-          else {
-            ((SMDS_MeshElement*) *it)->init( 0, -1, -1 ); // avoid reuse
-            delete (*it);
-          }
-          break;
+      SMDS_MeshNode * n = const_cast<SMDS_MeshNode *> (itn->next());
+      n->RemoveInverseElement((*it));
+    }
 
-        case SMDSAbs_All: // avoid compilation warning
-        case SMDSAbs_NbElementTypes: break;
-      }
-      if (vtkid >= 0)
-      {
-        this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
-      }
-      it++;
+    int vtkid = (*it)->GetVtkID();
+
+    switch ((*it)->GetType()) {
+    case SMDSAbs_Node:
+      throw SALOME_Exception(LOCALIZED("Internal Error: This should not happen"));
+      break;
+    case SMDSAbs_Edge:      myInfo.RemoveEdge(*it);   break;
+    case SMDSAbs_Face:      myInfo.RemoveFace(*it);   break;
+    case SMDSAbs_Volume:    myInfo.RemoveVolume(*it); break;
+    case SMDSAbs_Ball:      myInfo.myNbBalls--;       break;
+    case SMDSAbs_0DElement: myInfo.myNb0DElements--;  break;
+    case SMDSAbs_All: // avoid compilation warning
+    case SMDSAbs_NbElementTypes: break;
+    }
+
+    myCellFactory->Free( static_cast< const SMDS_MeshCell*>( *it ));
+
+    if (vtkid >= 0)
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
     }
+  }
 
   // remove exclusive (free) nodes
   if (removenodes)
   {
-    it = s2->begin();
-    while (it != s2->end())
+    for ( it = s2->begin(); it != s2->end(); ++it )
     {
-      int IdToRemove = (*it)->GetID();
-      if (IdToRemove >= 0)
-      {
-        myNodes[IdToRemove] = 0;
-        myInfo.myNbNodes--;
-      }
-      myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId());
+      myInfo.myNbNodes--;
+      myNodeFactory->Free( (*it) );
       removedNodes.push_back((*it));
-      if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
-      {
-        ((SMDS_MeshNode*)vtkElem)->SetPosition(SMDS_SpacePosition::originSpacePosition());
-        myNodePool->destroy((SMDS_MeshNode*) vtkElem);
-      }
-     &nbs