Salome HOME
PR: synchro V6_main tag mergeto_V7_main_11Feb13
[modules/smesh.git] / src / OBJECT / SMESH_Object.cxx
index 31a21fef1d800a3fc50d7ebf07abc98ce20ff803..96b25c9b99e95134faa13b0e26c0c82c2516fff8 100644 (file)
@@ -1,23 +1,23 @@
-//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2012  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
+// 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.
+// 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.
 //
-//  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.
+// 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
+// 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
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 //  SMESH OBJECT : interactive object for SMESH visualization
@@ -65,7 +65,7 @@ using namespace std;
 
 #ifdef _DEBUG_
 static int MYDEBUG = 1;
-static int MYDEBUGWITHFILES = 1;
+static int MYDEBUGWITHFILES = 0;//1;
 #else
 static int MYDEBUG = 0;
 static int MYDEBUGWITHFILES = 0;
@@ -82,13 +82,14 @@ static int MYDEBUGWITHFILES = 0;
 // purpose  : Get type of VTK cell
 //=================================================================================
 static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
-                                     const bool thePoly,
-                                     const int theNbNodes )
+                                     const bool                thePoly,
+                                     const int                 theNbNodes )
 {
   switch( theType )
   {
-    case SMDSAbs_0DElement: 
-      return VTK_VERTEX;
+    case SMDSAbs_0DElement:         return VTK_VERTEX;
+
+    case SMDSAbs_Ball:              return VTK_POLY_VERTEX;
 
     case SMDSAbs_Edge: 
       if( theNbNodes == 2 )         return VTK_LINE;
@@ -101,26 +102,21 @@ static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
       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 return VTK_EMPTY_CELL;
       
     case SMDSAbs_Volume:
-      if (thePoly && theNbNodes>3 ) return VTK_CONVEX_POINT_SET;
+      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 == 10 )  {
-        return VTK_QUADRATIC_TETRA;
-      }
-      else if ( theNbNodes == 20 )  {
-        return VTK_QUADRATIC_HEXAHEDRON;
-      }
-      else if ( theNbNodes == 15 )  {
-        return VTK_QUADRATIC_WEDGE;
-      }
-      else if ( theNbNodes==13 )  {
-        return VTK_QUADRATIC_PYRAMID; //VTK_CONVEX_POINT_SET;
-      }
+      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;
@@ -136,6 +132,8 @@ SMESH_VisualObjDef::SMESH_VisualObjDef()
   MESSAGE("---------------------------------------------SMESH_VisualObjDef::SMESH_VisualObjDef");
   myGrid = vtkUnstructuredGrid::New();
   myLocalGrid = false;
+  ClearEntitiesFlags();
+  SMESH::GetEntitiesFromObject(NULL);
 }
 SMESH_VisualObjDef::~SMESH_VisualObjDef()
 {
@@ -151,41 +149,46 @@ SMESH_VisualObjDef::~SMESH_VisualObjDef()
 //=================================================================================
 vtkIdType SMESH_VisualObjDef::GetNodeObjId( int theVTKID )
 {
-       if (myLocalGrid)
-       {
-               TMapOfIds::const_iterator i = myVTK2SMDSNodes.find(theVTKID);
-               return i == myVTK2SMDSNodes.end() ? -1 : i->second;
-       }
+        if (myLocalGrid)
+        {
+                TMapOfIds::const_iterator i = myVTK2SMDSNodes.find(theVTKID);
+                return i == myVTK2SMDSNodes.end() ? -1 : i->second;
+        }
   return this->GetMesh()->FindNodeVtk(theVTKID)->GetID();
 }
 
 vtkIdType SMESH_VisualObjDef::GetNodeVTKId( int theObjID )
 {
-       if (myLocalGrid)
-       {
-               TMapOfIds::const_iterator i = mySMDS2VTKNodes.find(theObjID);
+        if (myLocalGrid)
+        {
+                TMapOfIds::const_iterator i = mySMDS2VTKNodes.find(theObjID);
     return i == mySMDS2VTKNodes.end() ? -1 : i->second;
-       }
-  return this->GetMesh()->FindNode(theObjID)->getVtkId();
+        }
+
+        const SMDS_MeshNode* aNode = 0;
+        if( this->GetMesh() ) {
+          aNode = this->GetMesh()->FindNode(theObjID);
+        }
+        return aNode ? aNode->getVtkId() : -1;
 }
 
 vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID )
 {
-       if (myLocalGrid)
-       {
-               TMapOfIds::const_iterator i = myVTK2SMDSElems.find(theVTKID);
-               return i == myVTK2SMDSElems.end() ? -1 : i->second;
-       }
+        if (myLocalGrid)
+        {
+                TMapOfIds::const_iterator i = myVTK2SMDSElems.find(theVTKID);
+                return i == myVTK2SMDSElems.end() ? -1 : i->second;
+        }
   return this->GetMesh()->fromVtkToSmds(theVTKID);
 }
 
 vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID )
 {
-       if (myLocalGrid)
-       {
-               TMapOfIds::const_iterator i = mySMDS2VTKElems.find(theObjID);
-               return i == mySMDS2VTKElems.end() ? -1 : i->second;
-       }
+        if (myLocalGrid)
+        {
+                TMapOfIds::const_iterator i = mySMDS2VTKElems.find(theObjID);
+                return i == mySMDS2VTKElems.end() ? -1 : i->second;
+        }
   return this->GetMesh()->FindElement(theObjID)->getVtkId();
   //return this->GetMesh()->fromSmdsToVtk(theObjID);
 }
@@ -236,45 +239,46 @@ void SMESH_VisualObjDef::buildPrs(bool buildGrid)
   MESSAGE("----------------------------------------------------------SMESH_VisualObjDef::buildPrs " << buildGrid);
   if (buildGrid)
   {
-       myLocalGrid = true;
-       try
-       {
-               mySMDS2VTKNodes.clear();
-               myVTK2SMDSNodes.clear();
-               mySMDS2VTKElems.clear();
-               myVTK2SMDSElems.clear();
-
-               if ( IsNodePrs() )
-                       buildNodePrs();
-               else
-                       buildElemPrs();
-       }
-       catch(...)
-       {
-               mySMDS2VTKNodes.clear();
-               myVTK2SMDSNodes.clear();
-               mySMDS2VTKElems.clear();
-               myVTK2SMDSElems.clear();
-
-               myGrid->SetPoints( 0 );
-               myGrid->SetCells( 0, 0, 0, 0, 0 );
-               throw;
-       }
+        myLocalGrid = true;
+        try
+        {
+                mySMDS2VTKNodes.clear();
+                myVTK2SMDSNodes.clear();
+                mySMDS2VTKElems.clear();
+                myVTK2SMDSElems.clear();
+
+                if ( IsNodePrs() )
+                        buildNodePrs();
+                else
+                        buildElemPrs();
+        }
+        catch(...)
+        {
+                mySMDS2VTKNodes.clear();
+                myVTK2SMDSNodes.clear();
+                mySMDS2VTKElems.clear();
+                myVTK2SMDSElems.clear();
+
+                myGrid->SetPoints( 0 );
+                myGrid->SetCells( 0, 0, 0, 0, 0 );
+                throw;
+        }
   }
   else
   {
-       myLocalGrid = false;
-       if (!GetMesh()->isCompacted())
-         {
-           MESSAGE("*** buildPrs ==> compactMesh!");
-           GetMesh()->compactMesh();
-         }
-       vtkUnstructuredGrid *theGrid = GetMesh()->getGrid();
-       myGrid->ShallowCopy(theGrid);
-       //MESSAGE(myGrid->GetReferenceCount());
-       //MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->GetNumberOfCells() );
-       //MESSAGE( "Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints() );
-       if( MYDEBUGWITHFILES ) SMESH::WriteUnstructuredGrid( myGrid,"buildPrs.vtu" );
+        myLocalGrid = false;
+        if (!GetMesh()->isCompacted())
+          {
+            MESSAGE("*** buildPrs ==> compactMesh!");
+            GetMesh()->compactMesh();
+          }
+        vtkUnstructuredGrid *theGrid = GetMesh()->getGrid();
+        updateEntitiesFlags();
+        myGrid->ShallowCopy(theGrid);
+        //MESSAGE(myGrid->GetReferenceCount());
+        //MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->GetNumberOfCells() );
+        //MESSAGE( "Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints() );
+        if( MYDEBUGWITHFILES ) SMESH::WriteUnstructuredGrid( myGrid,"buildPrs.vtu" );
   }
 }
 
@@ -287,10 +291,10 @@ void SMESH_VisualObjDef::buildNodePrs()
 {
   // PAL16631: without swap, bad_alloc is not thrown but hung up and crash instead,
   // so check remaining memory size for safety
-  // SMDS_Mesh::CheckMemory(); // PAL16631
+  SMDS_Mesh::CheckMemory(); // PAL16631
   vtkPoints* aPoints = vtkPoints::New();
   createPoints( aPoints );
-  // SMDS_Mesh::CheckMemory();
+  SMDS_Mesh::CheckMemory();
   myGrid->SetPoints( aPoints );
   aPoints->Delete();
 
@@ -341,36 +345,54 @@ void SMESH_VisualObjDef::buildElemPrs()
 
   // Calculate cells size
 
-  static SMDSAbs_ElementType aTypes[ 4 ] =
-    { SMDSAbs_0DElement, SMDSAbs_Edge, SMDSAbs_Face, SMDSAbs_Volume };
+  const int nbTypes = 5;
+  static SMDSAbs_ElementType aTypes[ nbTypes ] =
+    { SMDSAbs_Edge, SMDSAbs_Face, SMDSAbs_Volume, SMDSAbs_Ball, SMDSAbs_0DElement };
 
   // get entity data
   map<SMDSAbs_ElementType,int> nbEnts;
   map<SMDSAbs_ElementType,TEntityList> anEnts;
 
-  for ( int i = 0; i <= 3; i++ )
-    nbEnts[ aTypes[ i ] ] = GetEntities( aTypes[ i ], anEnts[ aTypes[ i ] ] );
+  vtkIdType aNbCells = 0;
 
+  for ( int i = 0; i < nbTypes; i++ )
+  {
+    nbEnts[ aTypes[ i ] ] = GetEntities( aTypes[ i ], anEnts[ aTypes[ i ] ] );
+    aNbCells += nbEnts[ aTypes [ i ]];
+  }
   // PAL16631: without swap, bad_alloc is not thrown but hung up and crash instead,
   // so check remaining memory size for safety
-  // SMDS_Mesh::CheckMemory(); // PAL16631
+  SMDS_Mesh::CheckMemory(); // PAL16631
 
   vtkIdType aCellsSize =  2 * nbEnts[ SMDSAbs_0DElement ] + 3 * nbEnts[ SMDSAbs_Edge ];
+  aCellsSize += 2 * nbEnts[ SMDSAbs_Ball ];
 
-  for ( int i = 2; i <= 3; i++ ) // iterate through faces and volumes
+  for ( int i = 1; i <= 2; i++ ) // iterate through faces and volumes
   {
     if ( nbEnts[ aTypes[ i ] ] )
     {
       const TEntityList& aList = anEnts[ aTypes[ i ] ];
       TEntityList::const_iterator anIter;
-      for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
-        aCellsSize += (*anIter)->NbNodes() + 1;
+      for ( anIter = aList.begin(); anIter != aList.end(); ++anIter ) {
+        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, ...]   
+        else {
+          if( const SMDS_VtkVolume* ph = dynamic_cast<const SMDS_VtkVolume*>(*anIter) ) {
+            int nbFaces = ph->NbFaces();
+            aCellsSize += (1 + ph->NbFaces());
+            for( int i = 1; i <= nbFaces; i++ ) {
+              aCellsSize += ph->NbFaceNodes(i);
+            }
+          }
+        }
+      }
     }
   }
-
-  vtkIdType aNbCells = nbEnts[ SMDSAbs_0DElement ] + nbEnts[ SMDSAbs_Edge ] +
-                       nbEnts[ SMDSAbs_Face ] + nbEnts[ SMDSAbs_Volume ];
-
   if ( MYDEBUG )
     MESSAGE( "Update - aNbCells = "<<aNbCells<<"; aCellsSize = "<<aCellsSize );
 
@@ -379,13 +401,13 @@ void SMESH_VisualObjDef::buildElemPrs()
   vtkCellArray* aConnectivity = vtkCellArray::New();
   aConnectivity->Allocate( aCellsSize, 0 );
 
-  // SMDS_Mesh::CheckMemory(); // PAL16631
+  SMDS_Mesh::CheckMemory(); // PAL16631
 
   vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
   aCellTypesArray->SetNumberOfComponents( 1 );
   aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
 
-  // SMDS_Mesh::CheckMemory(); // PAL16631
+  SMDS_Mesh::CheckMemory(); // PAL16631
 
   vtkIdList *anIdList = vtkIdList::New();
   vtkIdType iElem = 0;
@@ -393,110 +415,72 @@ void SMESH_VisualObjDef::buildElemPrs()
   TConnect aConnect;
   aConnect.reserve(VTK_CELL_SIZE);
 
-  // SMDS_Mesh::CheckMemory(); // PAL16631
+  SMDS_Mesh::CheckMemory(); // PAL16631
 
-  for ( int i = 0; i <= 3; i++ ) // iterate through 0d elements, edges, faces and volumes
+  for ( int i = 0; i < nbTypes; i++ ) // iterate through all types of elements
   {
-    if ( nbEnts[ aTypes[ i ] ] > 0 )
-    {
+    if ( nbEnts[ aTypes[ i ] ] > 0 ) {
+      
       const SMDSAbs_ElementType& aType = aTypes[ i ];
       const TEntityList& aList = anEnts[ aType ];
       TEntityList::const_iterator anIter;
       for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
       {
         const SMDS_MeshElement* anElem = *anIter;
-
+        
         vtkIdType aNbNodes = anElem->NbNodes();
         anIdList->SetNumberOfIds( aNbNodes );
-
+        const vtkIdType vtkElemType = getCellType( aType, anElem->IsPoly(), aNbNodes );
+        
         int anId = anElem->GetID();
-
+        
         mySMDS2VTKElems.insert( TMapOfIds::value_type( anId, iElem ) );
         myVTK2SMDSElems.insert( TMapOfIds::value_type( iElem, anId ) );
-
+        
         SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
-        switch (aType) {
-        case SMDSAbs_Volume:{
-          aConnect.clear();
-          std::vector<int> aConnectivities;
+        {
           // Convertions connectivities from SMDS to VTK
-          if (anElem->IsPoly() && aNbNodes > 3) { // POLYEDRE
 
-            if ( const SMDS_VtkVolume* ph =
-                 dynamic_cast<const SMDS_VtkVolume*> (anElem))
-            {
-              aNbNodes = GetConnect(ph->uniqueNodesIterator(),aConnect);
-              anIdList->SetNumberOfIds( aNbNodes );
+          if (aType == SMDSAbs_Volume && anElem->IsPoly() && aNbNodes > 3) { // POLYEDRE
+            anIdList->Reset();
+            if ( const SMDS_VtkVolume* ph = dynamic_cast<const SMDS_VtkVolume*>(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()]);
+                  }
+                }
+              }
             }
-            for (int k = 0; k < aNbNodes; k++)
-              aConnectivities.push_back(k);
-
-          } else if (aNbNodes == 4) {
-            static int anIds[] = {0,2,1,3};
-            for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
-
-          } else if (aNbNodes == 5) {
-            static int anIds[] = {0,3,2,1,4};
-            for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
-
-          } else if (aNbNodes == 6) {
-            static int anIds[] = {0,1,2,3,4,5};
-            for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
-
-          }
-          else if (aNbNodes == 8) {
-            static int anIds[] = {0,3,2,1,4,7,6,5};
-            for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
-
-          }
-          else if (aNbNodes == 10) {
-            static int anIds[] = {0,2,1,3,6,5,4,7,9,8};
-            for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
-          }
-          else if (aNbNodes == 13) {
-            static int anIds[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
-            for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
-          }
-          else if (aNbNodes == 15) {
-            //static int anIds[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13};
-            static int anIds[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
-            for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
-            //for (int k = 0; k < aNbNodes; k++) {
-            //  int nn = aConnectivities[k];
-            //  const SMDS_MeshNode* N = static_cast<const SMDS_MeshNode*> (aConnect[nn]);
-            //  cout<<"k="<<k<<"  N("<<N->X()<<","<<N->Y()<<","<<N->Z()<<")"<<endl;
-            //}
-          }
-          else if (aNbNodes == 20) {
-            static int anIds[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
-            for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
           }
           else {
-          }
-
-          if ( aConnect.empty() )
-            GetConnect(aNodesIter,aConnect);
-
-          if (aConnectivities.size() > 0) {
-            for (vtkIdType aNodeId = 0; aNodeId < aNbNodes; aNodeId++)
-              SetId(anIdList,mySMDS2VTKNodes,aConnect,aNodeId,aConnectivities[aNodeId]);
-          }
-          break;
-        }
-        default:
-          for( vtkIdType aNodeId = 0; aNodesIter->more(); aNodeId++ ){
-            const SMDS_MeshElement* aNode = aNodesIter->next();
-            anIdList->SetId( aNodeId, mySMDS2VTKNodes[aNode->GetID()] );
+            const std::vector<int>& aConnectivities =
+              SMDS_MeshCell::toVtkOrder( VTKCellType( vtkElemType ));
+            if (aConnectivities.size() > 0) {
+              aConnect.clear();
+              GetConnect(aNodesIter,aConnect);
+              for (vtkIdType aNodeId = 0; aNodeId < aNbNodes; aNodeId++)
+                SetId(anIdList,mySMDS2VTKNodes,aConnect,aNodeId,aConnectivities[aNodeId]);
+            }
+            else {
+              for( vtkIdType aNodeId = 0; aNodesIter->more(); aNodeId++ ){
+                const SMDS_MeshElement* aNode = aNodesIter->next();
+                anIdList->SetId( aNodeId, mySMDS2VTKNodes[aNode->GetID()] );
+              }
+            }
           }
         }
-
         aConnectivity->InsertNextCell( anIdList );
-        aCellTypesArray->InsertNextValue( getCellType( aType, anElem->IsPoly(), aNbNodes ) );
+        aCellTypesArray->InsertNextValue( vtkElemType );
 
         iElem++;
       }
     }
-    // SMDS_Mesh::CheckMemory(); // PAL16631
+    SMDS_Mesh::CheckMemory(); // PAL16631
   }
 
   // Insert cells in grid
@@ -505,7 +489,7 @@ void SMESH_VisualObjDef::buildElemPrs()
   aCellLocationsArray->SetNumberOfComponents( 1 );
   aCellLocationsArray->SetNumberOfTuples( aNbCells );
 
-  // SMDS_Mesh::CheckMemory(); // PAL16631
+  SMDS_Mesh::CheckMemory(); // PAL16631
 
   aConnectivity->InitTraversal();
   for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
@@ -518,7 +502,7 @@ void SMESH_VisualObjDef::buildElemPrs()
   aConnectivity->Delete();
   anIdList->Delete();
 
-  // SMDS_Mesh::CheckMemory(); // PAL16631
+  SMDS_Mesh::CheckMemory(); // PAL16631
 }
 
 //=================================================================================
@@ -565,8 +549,14 @@ bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
 
 vtkUnstructuredGrid* SMESH_VisualObjDef::GetUnstructuredGrid()
 {
-       //MESSAGE("SMESH_VisualObjDef::GetUnstructuredGrid " << myGrid);
-       return myGrid;
+  if ( !myLocalGrid && !GetMesh()->isCompacted() )
+  {
+    GetMesh()->compactMesh();
+        updateEntitiesFlags();
+    vtkUnstructuredGrid *theGrid = GetMesh()->getGrid();
+    myGrid->ShallowCopy(theGrid);
+  }
+  return myGrid;
 }
 
 
@@ -576,12 +566,72 @@ vtkUnstructuredGrid* SMESH_VisualObjDef::GetUnstructuredGrid()
 //=================================================================================
 bool SMESH_VisualObjDef::IsValid() const
 {
-       //MESSAGE("SMESH_VisualObjDef::IsValid");
-  return GetNbEntities(SMDSAbs_Node) > 0      || 
-         GetNbEntities(SMDSAbs_0DElement) > 0 || 
-         GetNbEntities(SMDSAbs_Edge) > 0      || 
-         GetNbEntities(SMDSAbs_Face) > 0      ||
-         GetNbEntities(SMDSAbs_Volume) > 0 ;
+        //MESSAGE("SMESH_VisualObjDef::IsValid");
+  return ( GetNbEntities(SMDSAbs_0DElement) > 0 || 
+           GetNbEntities(SMDSAbs_Ball     ) > 0 || 
+           GetNbEntities(SMDSAbs_Edge     ) > 0 || 
+           GetNbEntities(SMDSAbs_Face     ) > 0 ||
+           GetNbEntities(SMDSAbs_Volume   ) > 0 ||
+           GetNbEntities(SMDSAbs_Node     ) > 0 );
+}
+
+//=================================================================================
+// function : updateEntitiesFlags
+// purpose  : Update entities flags
+//=================================================================================
+void SMESH_VisualObjDef::updateEntitiesFlags() {
+
+        unsigned int tmp = myEntitiesState;
+        ClearEntitiesFlags();
+
+        map<SMDSAbs_ElementType,int> entities = SMESH::GetEntitiesFromObject(this);
+        
+
+        if( myEntitiesCache[SMDSAbs_0DElement] != 0 ||  myEntitiesCache[SMDSAbs_0DElement] >= entities[SMDSAbs_0DElement] )
+                myEntitiesState &= ~SMESH_Actor::e0DElements;
+
+        if( myEntitiesCache[SMDSAbs_Ball] != 0 ||  myEntitiesCache[SMDSAbs_Ball] >= entities[SMDSAbs_Ball] )
+                myEntitiesState &= ~SMESH_Actor::eBallElem;
+
+        if( myEntitiesCache[SMDSAbs_Edge] != 0 || myEntitiesCache[SMDSAbs_Edge] >= entities[SMDSAbs_Edge] )
+                myEntitiesState &= ~SMESH_Actor::eEdges; 
+
+        if( myEntitiesCache[SMDSAbs_Face] != 0 || myEntitiesCache[SMDSAbs_Face] >= entities[SMDSAbs_Face] )
+                myEntitiesState &= ~SMESH_Actor::eFaces; 
+
+        if( myEntitiesCache[SMDSAbs_Volume] != 0 || myEntitiesCache[SMDSAbs_Volume] >= entities[SMDSAbs_Volume] )
+                myEntitiesState &= ~SMESH_Actor::eVolumes;
+
+        if( tmp != myEntitiesState ) {
+                myEntitiesFlag = true;
+        }
+        
+        myEntitiesCache = entities;
+}
+
+//=================================================================================
+// function : ClearEntitiesFlags
+// purpose  : Clear the entities flags
+//=================================================================================
+void SMESH_VisualObjDef::ClearEntitiesFlags() {
+        myEntitiesState = SMESH_Actor::eAllEntity;
+        myEntitiesFlag = false;
+}
+
+//=================================================================================
+// function : GetEntitiesFlag
+// purpose  : Return the entities flag
+//=================================================================================
+bool SMESH_VisualObjDef::GetEntitiesFlag() {
+        return myEntitiesFlag;
+}
+
+//=================================================================================
+// function : GetEntitiesState
+// purpose  : Return the entities state
+//=================================================================================
+unsigned int SMESH_VisualObjDef::GetEntitiesState() {
+        return myEntitiesState;
 }
 
 /*
@@ -596,7 +646,7 @@ bool SMESH_VisualObjDef::IsValid() const
 SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh):
   myClient(SalomeApp_Application::orb(),theMesh)
 {
-       myEmptyGrid = 0;
+        myEmptyGrid = 0;
   if ( MYDEBUG ) 
     MESSAGE("SMESH_MeshObj - this = "<<this<<"; theMesh->_is_nil() = "<<theMesh->_is_nil());
 }
@@ -609,6 +659,8 @@ SMESH_MeshObj::~SMESH_MeshObj()
 {
   if ( MYDEBUG ) 
     MESSAGE("SMESH_MeshObj - this = "<<this<<"\n");
+  if ( myEmptyGrid )
+    myEmptyGrid->Delete();
 }
 
 //=================================================================================
@@ -629,20 +681,20 @@ bool SMESH_MeshObj::Update( int theIsClear )
 
 bool SMESH_MeshObj::NulData()
 {
-       MESSAGE ("SMESH_MeshObj::NulData() ==================================================================================");
-       if (!myEmptyGrid)
-       {
-         myEmptyGrid = SMDS_UnstructuredGrid::New();
-         myEmptyGrid->Initialize();
-         myEmptyGrid->Allocate();
-         vtkPoints* points = vtkPoints::New();
-         points->SetNumberOfPoints(0);
-         myEmptyGrid->SetPoints( points );
-         points->Delete();
-         myEmptyGrid->BuildLinks();
-       }
-       myGrid->ShallowCopy(myEmptyGrid);
-       return true;
+        MESSAGE ("SMESH_MeshObj::NulData() ==================================================================================");
+        if (!myEmptyGrid)
+        {
+          myEmptyGrid = SMDS_UnstructuredGrid::New();
+          myEmptyGrid->Initialize();
+          myEmptyGrid->Allocate();
+          vtkPoints* points = vtkPoints::New();
+          points->SetNumberOfPoints(0);
+          myEmptyGrid->SetPoints( points );
+          points->Delete();
+          myEmptyGrid->BuildLinks();
+        }
+        myGrid->ShallowCopy(myEmptyGrid);
+        return true;
 }
 //=================================================================================
 // function : GetElemDimension
@@ -658,6 +710,7 @@ int SMESH_MeshObj::GetElemDimension( const int theObjId )
   switch ( aType )
   {
     case SMDSAbs_0DElement : return 0;
+    case SMDSAbs_Ball : return 0;
     case SMDSAbs_Edge  : return 1;
     case SMDSAbs_Face  : return 2;
     case SMDSAbs_Volume: return 3;
@@ -682,6 +735,10 @@ int SMESH_MeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const
     {
       return myClient->Nb0DElements();
     }
+    case SMDSAbs_Ball:
+    {
+      return myClient->NbBalls();
+    }
     break;
     case SMDSAbs_Edge:
     {
@@ -718,7 +775,13 @@ int SMESH_MeshObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList&
     break;
     case SMDSAbs_0DElement:
     {
-      SMDS_0DElementIteratorPtr anIter = myClient->elements0dIterator();
+      SMDS_ElemIteratorPtr anIter = myClient->elementsIterator(SMDSAbs_0DElement);
+      while ( anIter->more() ) theObjs.push_back( anIter->next() );
+    }
+    break;
+    case SMDSAbs_Ball:
+    {
+      SMDS_ElemIteratorPtr anIter = myClient->elementGeomIterator(SMDSGeom_BALL);
       while ( anIter->more() ) theObjs.push_back( anIter->next() );
     }
     break;
@@ -762,7 +825,7 @@ void SMESH_MeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor
 //=================================================================================
 bool SMESH_MeshObj::IsNodePrs() const
 {
-  return myClient->Nb0DElements() == 0 && myClient->NbEdges() == 0 && myClient->NbFaces() == 0 && myClient->NbVolumes() == 0 ;
+  return myClient->Nb0DElements() + myClient->NbEdges() + myClient->NbFaces() + myClient->NbVolumes() + myClient->NbBalls() == 0 ;
 }
 
 
@@ -799,6 +862,7 @@ int SMESH_SubMeshObj::GetElemDimension( const int theObjId )
 // function : UpdateFunctor
 // purpose  : Update functor in accordance with current mesh
 //=================================================================================
+
 void SMESH_SubMeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor )
 {
   theFunctor->SetMesh( myMeshObj->GetMesh() );
@@ -810,7 +874,7 @@ void SMESH_SubMeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunc
 //=================================================================================
 bool SMESH_SubMeshObj::Update( int theIsClear )
 {
-       MESSAGE("SMESH_SubMeshObj::Update " << this)
+  MESSAGE("SMESH_SubMeshObj::Update " << this)
   bool changed = myMeshObj->Update( theIsClear );
   buildPrs(true);
   return changed;
@@ -838,7 +902,7 @@ SMESH_GroupObj::SMESH_GroupObj( SMESH::SMESH_GroupBase_ptr theGroup,
 SMESH_GroupObj::~SMESH_GroupObj()
 {
   if ( MYDEBUG ) MESSAGE("~SMESH_GroupObj");
-  myGroupServer->Destroy();
+  myGroupServer->UnRegister();
 }
 
 //=================================================================================
@@ -919,9 +983,12 @@ static int getPointers( const SMDSAbs_ElementType            theRequestType,
 //=================================================================================
 int SMESH_GroupObj::GetNbEntities( const SMDSAbs_ElementType theType) const
 {
-  if(SMDSAbs_ElementType(myGroupServer->GetType()) == theType){
+  if(SMDSAbs_ElementType(myGroupServer->GetType()) == theType) {
     return myGroupServer->Size();
   }
+  if ( theType == SMDSAbs_Node ) {
+    return myGroupServer->GetNumberOfNodes();
+  }
   return 0;
 }
 
@@ -930,11 +997,16 @@ int SMESH_GroupObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList&
   theResList.clear();
   SMDS_Mesh* aMesh = myMeshObj->GetMesh();
   
-  if ( myGroupServer->Size() == 0 || aMesh == 0 )
+  if ( aMesh == 0 )
     return 0;
 
   SMDSAbs_ElementType aGrpType = SMDSAbs_ElementType(myGroupServer->GetType());
+  if ( aGrpType != theType && theType != SMDSAbs_Node )
+    return 0;
+
   SMESH::long_array_var anIds = myGroupServer->GetListOfID();
+  if ( anIds->length() == 0 )
+    return 0;
 
   if ( aGrpType == theType )
     return getPointers( theType, anIds, aMesh, theResList );
@@ -942,7 +1014,7 @@ int SMESH_GroupObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList&
     return getNodesFromElems( anIds, aMesh, theResList );
   else
     return 0;
-}    
+}
 
 
 
@@ -968,7 +1040,7 @@ SMESH_subMeshObj::SMESH_subMeshObj( SMESH::SMESH_subMesh_ptr theSubMesh,
 SMESH_subMeshObj::~SMESH_subMeshObj()
 {
   if ( MYDEBUG ) MESSAGE( "~SMESH_subMeshObj" );
-  mySubMeshServer->Destroy();
+  mySubMeshServer->UnRegister();
 }
 
 //=================================================================================
@@ -981,9 +1053,10 @@ int SMESH_subMeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const
   {
     case SMDSAbs_Node:
     {
-      return mySubMeshServer->GetNumberOfNodes( false );
+      return mySubMeshServer->GetNumberOfNodes( /*all=*/true );
     }
     break;
+    case SMDSAbs_Ball:
     case SMDSAbs_0DElement:
     case SMDSAbs_Edge:
     case SMDSAbs_Face: