Salome HOME
IPAL54382: TC8.5.0: SMESH: Regression in mesh visualization (body fitting)
[modules/smesh.git] / src / OBJECT / SMESH_Object.cxx
index 6621177cc32ed4f904eacaeaba8602d65d28dce2..1599efe5e602e4a12ca67ff0926f837cf8c71b20 100644 (file)
@@ -1,53 +1,61 @@
-//  SMESH OBJECT : interactive object for SMESH visualization
+// 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.
 //
-//  Copyright (C) 2003  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 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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+// 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 OBJECT : interactive object for SMESH visualization
 //  File   : SMESH_Grid.cxx
 //  Author : Nicolas REJNERI
 //  Module : SMESH
+//
+#include "SMESH_ObjectDef.h"
+#include "SMESH_ActorUtils.h"
 
-#include "SMESH_Object.h"
+#include "SMDS_BallElement.hxx"
 #include "SMDS_Mesh.hxx"
-#include "SALOME_ExtractUnstructuredGrid.h"
+#include "SMDS_MeshCell.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESHDS_Script.hxx"
 #include "SMESH_Actor.h"
+#include "SMESH_ControlsDef.hxx"
+
+#include <SalomeApp_Application.h>
+#include <VTKViewer_ExtractUnstructuredGrid.h>
+#include <VTKViewer_CellLocationsArray.h>
 
+#include CORBA_SERVER_HEADER(SMESH_Gen)
 #include CORBA_SERVER_HEADER(SALOME_Exception)
 
 #include <vtkCell.h>
 #include <vtkIdList.h>
-#include <vtkIntArray.h>
 #include <vtkCellArray.h>
 #include <vtkUnsignedCharArray.h>
-
+#include <vtkCellData.h>
 #include <vtkUnstructuredGrid.h>
-#include <vtkUnstructuredGridWriter.h>
-#include <vtkUnstructuredGridReader.h>
 
 #include <memory>
-#include <sstream>     
+#include <sstream>      
 #include <stdexcept>
 #include <set>
 
-#include "utilities.h"
+#include <utilities.h>
 
 using namespace std;
 
@@ -61,252 +69,33 @@ using namespace std;
 
 #ifdef _DEBUG_
 static int MYDEBUG = 0;
-static int MYDEBUGWITHFILES = 0;
+static int MYDEBUGWITHFILES = 0;//1;
 #else
 static int MYDEBUG = 0;
 static int MYDEBUGWITHFILES = 0;
 #endif
 
 
-void WriteUnstructuredGrid(vtkUnstructuredGrid* theGrid, const char* theFileName){
-  vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
-  aWriter->SetFileName(theFileName);
-  aWriter->SetInput(theGrid);
-  if(theGrid->GetNumberOfCells()){
-    aWriter->Write();
-  }
-  aWriter->Delete();
-}
-
-
-namespace{
-
-  inline const SMDS_MeshNode* FindNode(const SMDS_Mesh* theMesh, int theId){
-    if(const SMDS_MeshNode* anElem = theMesh->FindNode(theId)) return anElem;
-    EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
-  }
-
-
-  inline const SMDS_MeshElement* FindElement(const SMDS_Mesh* theMesh, int theId){
-    if(const SMDS_MeshElement* anElem = theMesh->FindElement(theId)) return anElem;
-    EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot find a SMDS_MeshElement for ID = "<<theId);
-  }
-
-
-  inline void AddNodesWithID(SMDS_Mesh* theMesh, 
-                            SMESH::log_array_var& theSeq,
-                            CORBA::Long theId)
-  {
-    const SMESH::double_array& aCoords = theSeq[theId].coords;
-    const SMESH::long_array& anIndexes = theSeq[theId].indexes;
-    CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(3*aNbElems != aCoords.length())
-      EXCEPTION(runtime_error,"AddNodesWithID - 3*aNbElems != aCoords.length()");
-    for(CORBA::Long aCoordId = 0; anElemId < aNbElems; anElemId++, aCoordId+=3){
-      SMDS_MeshElement* anElem = theMesh->AddNodeWithID(aCoords[aCoordId],
-                                                       aCoords[aCoordId+1],
-                                                       aCoords[aCoordId+2],
-                                                       anIndexes[anElemId]);
-      if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddNodeWithID for ID = "<<anElemId);
-    }
-  }
-
-
-  inline void AddEdgesWithID(SMDS_Mesh* theMesh, 
-                            SMESH::log_array_var& theSeq,
-                            CORBA::Long theId)
-  {
-    const SMESH::double_array& aCoords = theSeq[theId].coords;
-    const SMESH::long_array& anIndexes = theSeq[theId].indexes;
-    CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(3*aNbElems != anIndexes.length())
-      EXCEPTION(runtime_error,"AddEdgeWithID - 3*aNbElems != aCoords.length()");
-    for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=3){
-      SMDS_MeshElement* anElem = theMesh->AddEdgeWithID(anIndexes[anIndexId+1],
-                                                       anIndexes[anIndexId+2],
-                                                       anIndexes[anIndexId]);
-      if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<<anElemId);
-    }
-  }
-
-
-  inline void AddTriasWithID(SMDS_Mesh* theMesh, 
-                            SMESH::log_array_var& theSeq,
-                            CORBA::Long theId)
-  {
-    const SMESH::double_array& aCoords = theSeq[theId].coords;
-    const SMESH::long_array& anIndexes = theSeq[theId].indexes;
-    CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(4*aNbElems != anIndexes.length())
-      EXCEPTION(runtime_error,"AddEdgeWithID - 4*aNbElems != anIndexes.length()");
-    for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=4){
-      SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
-                                                       anIndexes[anIndexId+2],
-                                                       anIndexes[anIndexId+3],
-                                                       anIndexes[anIndexId]);
-      if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
-    }
-  }
-
-
-  inline void AddQuadsWithID(SMDS_Mesh* theMesh, 
-                            SMESH::log_array_var theSeq,
-                            CORBA::Long theId)
-  {
-    const SMESH::double_array& aCoords = theSeq[theId].coords;
-    const SMESH::long_array& anIndexes = theSeq[theId].indexes;
-    CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(5*aNbElems != anIndexes.length())
-      EXCEPTION(runtime_error,"AddEdgeWithID - 4*aNbElems != anIndexes.length()");
-    for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){
-      SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
-                                                       anIndexes[anIndexId+2],
-                                                       anIndexes[anIndexId+3],
-                                                       anIndexes[anIndexId+4],
-                                                       anIndexes[anIndexId]);
-      if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
-    }
-  }
-
-
-  inline void AddTetrasWithID(SMDS_Mesh* theMesh, 
-                             SMESH::log_array_var& theSeq,
-                             CORBA::Long theId)
-  {
-    const SMESH::double_array& aCoords = theSeq[theId].coords;
-    const SMESH::long_array& anIndexes = theSeq[theId].indexes;
-    CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(5*aNbElems != anIndexes.length())
-      EXCEPTION(runtime_error,"AddEdgeWithID - 5*aNbElems != anIndexes.length()");
-    for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){
-      SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
-                                                         anIndexes[anIndexId+2],
-                                                         anIndexes[anIndexId+3],
-                                                         anIndexes[anIndexId+4],
-                                                         anIndexes[anIndexId]);
-      if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
-    }
-  }
-
-
-  inline void AddPiramidsWithID(SMDS_Mesh* theMesh, 
-                               SMESH::log_array_var& theSeq,
-                               CORBA::Long theId)
-  {
-    const SMESH::double_array& aCoords = theSeq[theId].coords;
-    const SMESH::long_array& anIndexes = theSeq[theId].indexes;
-    CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(6*aNbElems != anIndexes.length())
-      EXCEPTION(runtime_error,"AddEdgeWithID - 6*aNbElems != anIndexes.length()");
-    for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=6){
-      SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
-                                                         anIndexes[anIndexId+2],
-                                                         anIndexes[anIndexId+3],
-                                                         anIndexes[anIndexId+4],
-                                                         anIndexes[anIndexId+5],
-                                                         anIndexes[anIndexId]);
-      if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
-    }
-  }
-
-
-  inline void AddPrismsWithID(SMDS_Mesh* theMesh, 
-                             SMESH::log_array_var& theSeq,
-                             CORBA::Long theId)
-  {
-    const SMESH::double_array& aCoords = theSeq[theId].coords;
-    const SMESH::long_array& anIndexes = theSeq[theId].indexes;
-    CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(7*aNbElems != anIndexes.length())
-      EXCEPTION(runtime_error,"AddEdgeWithID - 7*aNbElems != anIndexes.length()");
-    for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=7){
-      SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
-                                                         anIndexes[anIndexId+2],
-                                                         anIndexes[anIndexId+3],
-                                                         anIndexes[anIndexId+4],
-                                                         anIndexes[anIndexId+5],
-                                                         anIndexes[anIndexId+6],
-                                                         anIndexes[anIndexId]);
-      if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
-    }
-  }
-
-
-  inline void AddHexasWithID(SMDS_Mesh* theMesh, 
-                            SMESH::log_array_var& theSeq,
-                            CORBA::Long theId)
-  {
-    const SMESH::double_array& aCoords = theSeq[theId].coords;
-    const SMESH::long_array& anIndexes = theSeq[theId].indexes;
-    CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
-    if(9*aNbElems != anIndexes.length())
-      EXCEPTION(runtime_error,"AddEdgeWithID - 9*aNbElems != anIndexes.length()");
-    for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=9){
-      SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
-                                                         anIndexes[anIndexId+2],
-                                                         anIndexes[anIndexId+3],
-                                                         anIndexes[anIndexId+4],
-                                                         anIndexes[anIndexId+5],
-                                                         anIndexes[anIndexId+6],
-                                                         anIndexes[anIndexId+7],
-                                                         anIndexes[anIndexId+8],
-                                                         anIndexes[anIndexId]);
-      if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
-    }
-  }
-
-
-}
 /*
-  Class       : SMESH_VisualObj
+  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 SMESH::ElementType theType,
-                                     const int theNbNodes )
-{
-  switch( theType )
-  {
-    case SMESH::EDGE: return theNbNodes == 2 ? VTK_LINE : VTK_EMPTY_CELL;
-
-    case SMESH::FACE  : if      ( theNbNodes == 3 ) return VTK_TRIANGLE;
-                        else if ( theNbNodes == 4 ) return VTK_QUAD;
-                        else                        return VTK_EMPTY_CELL;
-
-    case SMESH::VOLUME: 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                        return VTK_EMPTY_CELL;
-
-    default: return VTK_EMPTY_CELL;
-  }
-}
-
 //=================================================================================
-// functions : SMESH_VisualObj
+// functions : SMESH_VisualObjDef
 // purpose   : Constructor
 //=================================================================================
-SMESH_VisualObj::SMESH_VisualObj()
+SMESH_VisualObjDef::SMESH_VisualObjDef()
 {
+  if ( MYDEBUG ) MESSAGE("-------------------------------SMESH_VisualObjDef::SMESH_VisualObjDef");
   myGrid = vtkUnstructuredGrid::New();
+  myLocalGrid = false;
+  ClearEntitiesFlags();
+  SMESH::GetEntitiesFromObject(NULL);
 }
-SMESH_VisualObj::~SMESH_VisualObj()
+SMESH_VisualObjDef::~SMESH_VisualObjDef()
 {
-  if ( MYDEBUG )
-    MESSAGE( "~SMESH_MeshObj - myGrid->GetReferenceCount() = " << myGrid->GetReferenceCount() );
+  if ( MYDEBUG ) MESSAGE("--------------------------------SMESH_VisualObjDef::~SMESH_VisualObjDef");
+  if ( MYDEBUG ) MESSAGE( "myGrid->GetReferenceCount() = " << myGrid->GetReferenceCount() );
   myGrid->Delete();
 }
 
@@ -314,39 +103,77 @@ SMESH_VisualObj::~SMESH_VisualObj()
 // functions : GetNodeObjId, GetNodeVTKId, GetElemObjId, GetElemVTKId
 // purpose   : Methods for retrieving VTK IDs by SMDS IDs and  vice versa
 //=================================================================================
-vtkIdType SMESH_VisualObj::GetNodeObjId( int theVTKID )
+vtkIdType SMESH_VisualObjDef::GetNodeObjId( int theVTKID )
 {
-  return myVTK2SMDSNodes.find(theVTKID) == myVTK2SMDSNodes.end() ? -1 : myVTK2SMDSNodes[theVTKID];
+  if (myLocalGrid)
+  {
+    TMapOfIds::const_iterator i = myVTK2SMDSNodes.find(theVTKID);
+    return i == myVTK2SMDSNodes.end() ? -1 : i->second;
+  }
+  const SMDS_MeshNode* aNode = 0;
+  if( this->GetMesh() )
+    aNode = this->GetMesh()->FindNodeVtk( theVTKID );
+
+  return aNode ? aNode->GetID() : -1;
 }
 
-vtkIdType SMESH_VisualObj::GetNodeVTKId( int theObjID )
+vtkIdType SMESH_VisualObjDef::GetNodeVTKId( int theObjID )
 {
-  return mySMDS2VTKNodes.find(theObjID) == mySMDS2VTKNodes.end() ? -1 : mySMDS2VTKNodes[theObjID];
+  if (myLocalGrid)
+  {
+    TMapOfIds::const_iterator i = mySMDS2VTKNodes.find(theObjID);
+    return i == mySMDS2VTKNodes.end() ? -1 : i->second;
+  }
+
+  const SMDS_MeshNode* aNode = 0;
+  if( this->GetMesh() ) {
+    aNode = this->GetMesh()->FindNode(theObjID);
+  }
+  return aNode ? aNode->GetVtkID() : -1;
 }
 
-vtkIdType SMESH_VisualObj::GetElemObjId( int theVTKID )
+vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID )
 {
-  return myVTK2SMDSElems.find(theVTKID) == myVTK2SMDSElems.end() ? -1 : myVTK2SMDSElems[theVTKID];
+  if (myLocalGrid)
+  {
+    TMapOfIds::const_iterator i = myVTK2SMDSElems.find(theVTKID);
+    return i == myVTK2SMDSElems.end() ? -1 : i->second;
+  }
+  return this->GetMesh()->FromVtkToSmds(theVTKID);
 }
 
-vtkIdType SMESH_VisualObj::GetElemVTKId( int theObjID )
+vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID )
 {
-  return mySMDS2VTKElems.find(theObjID) == mySMDS2VTKElems.end() ? -1 : mySMDS2VTKElems[theObjID];
+  if (myLocalGrid)
+  {
+    TMapOfIds::const_iterator i = mySMDS2VTKElems.find(theObjID);
+    return i == mySMDS2VTKElems.end() ? -1 : i->second;
+  }
+
+  const SMDS_MeshElement* e = 0;
+  if ( this->GetMesh() )
+    e = this->GetMesh()->FindElement(theObjID);
+
+  return e ? e->GetVtkID() : -1;
 }
 
 //=================================================================================
-// function : SMESH_VisualObj::createPoints
+// function : SMESH_VisualObjDef::createPoints
 // purpose  : Create points from nodes
 //=================================================================================
-void SMESH_VisualObj::createPoints( vtkPoints* thePoints )
+/*! fills a vtkPoints structure for a submesh.
+ *  fills a std::list of SMDS_MeshElements*, then extract the points.
+ *  fills also conversion id maps between SMDS and VTK.
+ */
+void SMESH_VisualObjDef::createPoints( vtkPoints* thePoints )
 {
   if ( thePoints == 0 )
     return;
 
   TEntityList aNodes;
-  vtkIdType nbNodes = GetEntities( SMESH::NODE, aNodes );
+  vtkIdType nbNodes = GetEntities( SMDSAbs_Node, aNodes );
   thePoints->SetNumberOfPoints( nbNodes );
-  
+
   int nbPoints = 0;
 
   TEntityList::const_iterator anIter;
@@ -357,8 +184,8 @@ void SMESH_VisualObj::createPoints( vtkPoints* thePoints )
     {
       thePoints->SetPoint( nbPoints, aNode->X(), aNode->Y(), aNode->Z() );
       int anId = aNode->GetID();
-      mySMDS2VTKNodes.insert( TMapOfIds::value_type( anId, nbPoints ) );
-      myVTK2SMDSNodes.insert( TMapOfIds::value_type( nbPoints, anId ) );
+      mySMDS2VTKNodes.insert( mySMDS2VTKNodes.end(), std::make_pair( anId, nbPoints ));
+      myVTK2SMDSNodes.insert( myVTK2SMDSNodes.end(), std::make_pair( nbPoints, anId ));
       nbPoints++;
     }
   }
@@ -371,111 +198,143 @@ void SMESH_VisualObj::createPoints( vtkPoints* thePoints )
 // function : buildPrs
 // purpose  : create VTK cells( fill unstructured grid )
 //=================================================================================
-void SMESH_VisualObj::buildPrs()
+void SMESH_VisualObjDef::buildPrs(bool buildGrid)
 {
-  try
-  {
-    mySMDS2VTKNodes.clear();
-    myVTK2SMDSNodes.clear();
-    mySMDS2VTKElems.clear();
-    myVTK2SMDSElems.clear();
-    
-    if ( IsNodePrs() )
-      buildNodePrs();
-    else
-      buildElemPrs();
-  }
-  catch( const std::exception& exc )
+  if ( MYDEBUG ) MESSAGE("---------------------------SMESH_VisualObjDef::buildPrs " << buildGrid);
+  if (buildGrid)
   {
-    INFOS("Follow exception was cought:\n\t"<<exc.what());
+    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;
+    }
   }
-  catch(...)
+  else
   {
-    INFOS("Unknown exception was cought !!!");
+    myLocalGrid = false;
+    if (!GetMesh()->IsCompacted())
+    {
+      NulData(); // detach from the SMDS grid to allow immediate memory de-allocation in compactMesh()
+      if ( MYDEBUG ) MESSAGE("*** buildPrs ==> 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();
+    updateEntitiesFlags();
+    myGrid->ShallowCopy(theGrid);
+    //MESSAGE(myGrid->GetReferenceCount());
+    //MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->GetNumberOfCells() );
+    //MESSAGE( "Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints() );
+    if( MYDEBUGWITHFILES ) {
+      SMESH::WriteUnstructuredGrid( myGrid,"myPrs.vtu" );
+    }
   }
-  
-  if( MYDEBUG ) MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->GetNumberOfCells() );
-  if( MYDEBUGWITHFILES ) WriteUnstructuredGrid( myGrid,"/tmp/buildPrs" );
 }
 
 //=================================================================================
 // function : buildNodePrs
 // purpose  : create VTK cells for nodes
 //=================================================================================
-void SMESH_VisualObj::buildNodePrs()
+
+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
   vtkPoints* aPoints = vtkPoints::New();
   createPoints( aPoints );
-  int nbPoints = aPoints->GetNumberOfPoints();
+  SMDS_Mesh::CheckMemory();
   myGrid->SetPoints( aPoints );
   aPoints->Delete();
 
-  myGrid->SetCells( 0, 0, 0 );
-
-  // Create cells
-  /*
-  vtkIdList *anIdList = vtkIdList::New();
-  anIdList->SetNumberOfIds( 1 );
+  myGrid->SetCells( 0, 0, 0, 0, 0 );
+}
 
-  vtkCellArray *aCells = vtkCellArray::New();
-  aCells->Allocate( 2 * nbPoints, 0 );
+//=================================================================================
+// function : buildElemPrs
+// purpose  : Create VTK cells for elements
+//=================================================================================
 
-  vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
-  aCellTypesArray->SetNumberOfComponents( 1 );
-  aCellTypesArray->Allocate( nbPoints );
+namespace{
+  typedef std::vector<const SMDS_MeshElement*> TConnect;
 
-  for( vtkIdType aCellId = 0; aCellId < nbPoints; aCellId++ )
+  int GetConnect(const SMDS_ElemIteratorPtr& theNodesIter, 
+                 TConnect& theConnect)
   {
-    anIdList->SetId( 0, aCellId );
-    aCells->InsertNextCell( anIdList );
-    aCellTypesArray->InsertNextValue( VTK_VERTEX );
+    theConnect.clear();
+    for(; theNodesIter->more();)
+      theConnect.push_back(theNodesIter->next());
+    return theConnect.size();
+  }
+  
+  inline 
+  void SetId(vtkIdList *theIdList, 
+             const SMESH_VisualObjDef::TMapOfIds& theSMDS2VTKNodes, 
+             const TConnect& theConnect, 
+             int thePosition,
+             int theId)
+  {
+    theIdList->SetId(thePosition,theSMDS2VTKNodes.find(theConnect[theId]->GetID())->second);
   }
 
-  vtkIntArray* aCellLocationsArray = vtkIntArray::New();
-  aCellLocationsArray->SetNumberOfComponents( 1 );
-  aCellLocationsArray->SetNumberOfTuples( nbPoints );
-
-  aCells->InitTraversal();
-  for( vtkIdType i = 0, *pts, npts; aCells->GetNextCell( npts, pts ); i++ )
-    aCellLocationsArray->SetValue( i, aCells->GetTraversalLocation( npts ) );
-
-  myGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells );
-
-  aCellLocationsArray->Delete();
-  aCellTypesArray->Delete();
-  aCells->Delete();
-  anIdList->Delete(); 
-  */
 }
 
-//=================================================================================
-// function : buildElemPrs
-// purpose  : Create VTK cells for elements
-//=================================================================================
-void SMESH_VisualObj::buildElemPrs()
+
+void SMESH_VisualObjDef::buildElemPrs()
 {
   // Create points
-  
+
   vtkPoints* aPoints = vtkPoints::New();
   createPoints( aPoints );
   myGrid->SetPoints( aPoints );
   aPoints->Delete();
-    
+
   if ( MYDEBUG )
     MESSAGE("Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints());
 
   // Calculate cells size
 
-  static SMESH::ElementType aTypes[ 3 ] = { SMESH::EDGE, SMESH::FACE, SMESH::VOLUME };
+  const int nbTypes = 5;
+  static SMDSAbs_ElementType aTypes[ nbTypes ] =
+    { SMDSAbs_Edge, SMDSAbs_Face, SMDSAbs_Volume, SMDSAbs_Ball, SMDSAbs_0DElement };
 
   // get entity data
-  map< int, int >         nbEnts;
-  map< int, TEntityList > anEnts;
+  map<SMDSAbs_ElementType,int> nbEnts;
+  map<SMDSAbs_ElementType,TEntityList> anEnts;
 
-  for ( int i = 0; i <= 2; 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
 
-  vtkIdType aCellsSize =  3 * nbEnts[ SMESH::EDGE ];
+  vtkIdType aCellsSize =  2 * nbEnts[ SMDSAbs_0DElement ] + 3 * nbEnts[ SMDSAbs_Edge ];
+  aCellsSize += 2 * nbEnts[ SMDSAbs_Ball ];
 
   for ( int i = 1; i <= 2; i++ ) // iterate through faces and volumes
   {
@@ -483,87 +342,158 @@ void SMESH_VisualObj::buildElemPrs()
     {
       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_MeshVolume* ph = SMDS_Mesh::DownCast<SMDS_MeshVolume>( *anIter )) {
+            int nbFaces = ph->NbFaces();
+            aCellsSize += (1 + ph->NbFaces());
+            for( int i = 1; i <= nbFaces; i++ )
+              aCellsSize += ph->NbFaceNodes(i);
+          }
+        }
+      }
     }
   }
-
-  vtkIdType aNbCells = nbEnts[ SMESH::EDGE ] + nbEnts[ SMESH::FACE ] + nbEnts[ SMESH::VOLUME ];
-  
   if ( MYDEBUG )
     MESSAGE( "Update - aNbCells = "<<aNbCells<<"; aCellsSize = "<<aCellsSize );
 
   // Create cells
-  
+
   vtkCellArray* aConnectivity = vtkCellArray::New();
   aConnectivity->Allocate( aCellsSize, 0 );
-  
+
+  SMDS_Mesh::CheckMemory(); // PAL16631
+
   vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
   aCellTypesArray->SetNumberOfComponents( 1 );
   aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
-  
+
+  SMDS_Mesh::CheckMemory(); // PAL16631
+
   vtkIdList *anIdList = vtkIdList::New();
   vtkIdType iElem = 0;
-  
-  for ( int i = 0; i <= 2; i++ ) // iterate through edges, faces and volumes
+
+  TConnect aConnect;
+  aConnect.reserve(VTK_CELL_SIZE);
+
+  SMDS_Mesh::CheckMemory(); // PAL16631
+  bool hasBalls = nbEnts[ SMDSAbs_Ball ] > 0;
+  vtkDataArray* aScalars = 0;
+  if(hasBalls) {
+    aScalars = vtkDataArray::CreateDataArray(VTK_DOUBLE);
+    aScalars->SetNumberOfComponents(1);
+    aScalars->SetNumberOfTuples(aNbCells);
+  }
+  for ( int i = 0; i < nbTypes; i++ ) // iterate through all types of elements
   {
-    if( nbEnts[ aTypes[ i ] ] > 0 )
-    {
-      const TEntityList& aList = anEnts[ aTypes[ i ] ];
+    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 = SMDS_MeshCell::toVtkType( anElem->GetEntityType() );
 
         int anId = anElem->GetID();
 
-        mySMDS2VTKElems.insert( TMapOfIds::value_type( anId, iElem ) );
-        myVTK2SMDSElems.insert( TMapOfIds::value_type( iElem, anId ) );
+        mySMDS2VTKElems.insert( mySMDS2VTKElems.end(), std::make_pair( anId, iElem ));
+        myVTK2SMDSElems.insert( myVTK2SMDSElems.end(), std::make_pair( iElem, anId ));
 
         SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
-        for( vtkIdType aNodeId = 0; aNodesIter->more(); aNodeId++ )
         {
-          const SMDS_MeshElement* aNode = aNodesIter->next();
-          anIdList->SetId( aNodeId, mySMDS2VTKNodes[aNode->GetID()] );
+          // Convert connectivities from SMDS to VTK
+
+          if (aType == SMDSAbs_Volume && anElem->IsPoly() && aNbNodes > 3) { // POLYEDRE
+            anIdList->Reset();
+            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++) {
+                  if ( const SMDS_MeshNode* n = ph->GetFaceNode( i, j ))
+                    anIdList->InsertNextId( mySMDS2VTKNodes[ n->GetID() ]);
+                }
+              }
+            }
+          }
+          else {
+            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()] );
+              }
+            }
+          }
+        }
+        vtkIdType aCurId = aConnectivity->InsertNextCell( anIdList );
+        aCellTypesArray->InsertNextValue( vtkElemType );
+        
+        //Store diameters of the balls
+        if(aScalars) {
+          double aDiam = 0;
+          if (const SMDS_BallElement* ball = SMDS_Mesh::DownCast<SMDS_BallElement>(anElem) )
+            aDiam = ball->GetDiameter();
+          aScalars->SetTuple(aCurId,&aDiam);
         }
-
-        aConnectivity->InsertNextCell( anIdList );
-        aCellTypesArray->InsertNextValue( getCellType( aTypes[ i ], aNbNodes ) );
 
         iElem++;
       }
     }
+    SMDS_Mesh::CheckMemory(); // PAL16631
   }
 
   // Insert cells in grid
-  
-  vtkIntArray* aCellLocationsArray = vtkIntArray::New();
+
+  VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
   aCellLocationsArray->SetNumberOfComponents( 1 );
   aCellLocationsArray->SetNumberOfTuples( aNbCells );
-  
+
+  SMDS_Mesh::CheckMemory(); // PAL16631
+
   aConnectivity->InitTraversal();
   for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
     aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
 
   myGrid->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
-  
+  myGrid->GetCellData()->SetScalars(aScalars);
+
   aCellLocationsArray->Delete();
   aCellTypesArray->Delete();
   aConnectivity->Delete();
   anIdList->Delete();
+
+  SMDS_Mesh::CheckMemory(); // PAL16631
 }
 
 //=================================================================================
 // function : GetEdgeNodes
-// purpose  : Retrieve ids of nodes from edge of elements ( edge is numbered from 1 )
+// purpose  : Retrieve ids of nodes from edge of elements ( edge is numbered from 0 )
 //=================================================================================
-bool SMESH_VisualObj::GetEdgeNodes( const int theElemId,
-                                    const int theEdgeNum,
-                                    int&      theNodeId1,
-                                    int&      theNodeId2 ) const
+bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
+                                       const int theEdgeNum,
+                                       int&      theNodeId1,
+                                       int&      theNodeId2 ) const
 {
   const SMDS_Mesh* aMesh = GetMesh();
   if ( aMesh == 0 )
@@ -573,29 +503,115 @@ bool SMESH_VisualObj::GetEdgeNodes( const int theElemId,
   if ( anElem == 0 )
     return false;
     
-  int nbNodes = anElem->NbNodes();
+  int nbNodes = anElem->NbCornerNodes();
 
-  if ( theEdgeNum < 1 || theEdgeNum > 4 || nbNodes != 3 && nbNodes != 4 || theEdgeNum > nbNodes )
+  if (( theEdgeNum < 0 || theEdgeNum > 3 ) ||
+      ( nbNodes != 3 && nbNodes != 4 ) ||
+      ( theEdgeNum >= nbNodes ))
     return false;
 
-  int anIds[ nbNodes ];
-  SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
-  int i = 0;
-  while( anIter->more() )
-    anIds[ i++ ] = anIter->next()->GetID();
+  theNodeId1 = anElem->GetNode(  theEdgeNum                 )->GetID();
+  theNodeId2 = anElem->GetNode(( theEdgeNum + 1 ) % nbNodes )->GetID();
+
+  return true;
+}
 
-  if ( nbNodes != theEdgeNum )
+vtkUnstructuredGrid* SMESH_VisualObjDef::GetUnstructuredGrid()
+{
+  if ( !myLocalGrid && ( !GetMesh()->IsCompacted() || // !IsCompacted() is needed ???
+                         GetMesh()->GetGrid()->GetMTime() > myGrid->GetMTime() ))
   {
-    theNodeId1 = anIds[ theEdgeNum - 1 ];
-    theNodeId2 = anIds[ theEdgeNum ];
+    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()
+    updateEntitiesFlags();
+    vtkUnstructuredGrid *theGrid = GetMesh()->GetGrid();
+    myGrid->ShallowCopy(theGrid);
   }
-  else
-  {
-    theNodeId1 = anIds[ nbNodes - 1 ];
-    theNodeId2 = anIds[ 0 ];
+  return myGrid;
+}
+
+
+//=================================================================================
+// function : IsValid
+// purpose  : Return true if there are some entities
+//=================================================================================
+bool SMESH_VisualObjDef::IsValid() const
+{
+  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;
   }
 
-  return 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;
 }
 
 /*
@@ -607,14 +623,12 @@ bool SMESH_VisualObj::GetEdgeNodes( const int theElemId,
 // function : SMESH_MeshObj
 // purpose  : Constructor
 //=================================================================================
-SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh)
+SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh):
+  myClient(SalomeApp_Application::orb(),theMesh)
 {
+        myEmptyGrid = 0;
   if ( MYDEBUG ) 
-    MESSAGE("SMESH_MeshObj - theMesh->_is_nil() = "<<theMesh->_is_nil());
-    
-  myMeshServer = SMESH::SMESH_Mesh::_duplicate( theMesh );
-  myMeshServer->Register();
-  myMesh = new SMDS_Mesh();
+    MESSAGE("SMESH_MeshObj - this = "<<this<<"; theMesh->_is_nil() = "<<theMesh->_is_nil());
 }
 
 //=================================================================================
@@ -623,132 +637,60 @@ SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh)
 //=================================================================================
 SMESH_MeshObj::~SMESH_MeshObj()
 {
-  myMeshServer->Destroy();
-  delete myMesh;
+  if ( MYDEBUG ) 
+    MESSAGE("SMESH_MeshObj - this = "<<this<<"\n");
+  if ( myEmptyGrid )
+    myEmptyGrid->Delete();
 }
 
 //=================================================================================
 // function : Update
 // purpose  : Update mesh and fill grid with new values if necessary 
 //=================================================================================
-void SMESH_MeshObj::Update( int theIsClear )
+bool SMESH_MeshObj::Update( int theIsClear )
 {
   // Update SMDS_Mesh on client part
-  
-  try
-  {
-    SMESH::log_array_var aSeq = myMeshServer->GetLog( theIsClear );
-    CORBA::Long aLength = aSeq->length();
-    
-    if( MYDEBUG ) MESSAGE( "Update: length of the script is "<<aLength );
-    
-    if( !aLength )
-      return;
-      
-    for ( CORBA::Long anId = 0; anId < aLength; anId++)
-    {
-      const SMESH::double_array& aCoords = aSeq[anId].coords;
-      const SMESH::long_array& anIndexes = aSeq[anId].indexes;
-      CORBA::Long anElemId = 0, aNbElems = aSeq[anId].number;
-      SMDS_MeshElement* anElem = NULL;
-      CORBA::Long aCommand = aSeq[anId].commandType;
-      
-      switch(aCommand)
-      {
-        case SMESH::ADD_NODE       : AddNodesWithID   ( myMesh, aSeq, anId ); break;
-        case SMESH::ADD_EDGE       : AddEdgesWithID   ( myMesh, aSeq, anId ); break;
-        case SMESH::ADD_TRIANGLE   : AddTriasWithID   ( myMesh, aSeq, anId ); break;
-        case SMESH::ADD_QUADRANGLE : AddQuadsWithID   ( myMesh, aSeq, anId ); break;
-        case SMESH::ADD_TETRAHEDRON: AddTetrasWithID  ( myMesh, aSeq, anId ); break;
-        case SMESH::ADD_PYRAMID    : AddPiramidsWithID( myMesh, aSeq, anId ); break;
-        case SMESH::ADD_PRISM      : AddPrismsWithID  ( myMesh, aSeq, anId ); break;
-        case SMESH::ADD_HEXAHEDRON : AddHexasWithID   ( myMesh, aSeq, anId ); break;
-        
-        case SMESH::REMOVE_NODE:
-          for( ; anElemId < aNbElems; anElemId++ )
-            myMesh->RemoveNode( FindNode( myMesh, anIndexes[anElemId] ) );
-        break;
-        
-        case SMESH::REMOVE_ELEMENT:
-          for( ; anElemId < aNbElems; anElemId++ )
-            myMesh->RemoveElement( FindElement( myMesh, anIndexes[anElemId] ) );
-        break;
-
-        case SMESH::MOVE_NODE:
-          for(CORBA::Long aCoordId=0; anElemId < aNbElems; anElemId++, aCoordId+=3)
-          {
-            SMDS_MeshNode* node =
-              const_cast<SMDS_MeshNode*>( FindNode( myMesh, anIndexes[anElemId] ));
-            node->setXYZ( aCoords[aCoordId], aCoords[aCoordId+1], aCoords[aCoordId+2] );
-          }
-        break;
-
-        case SMESH::CHANGE_ELEMENT_NODES:
-          for ( CORBA::Long i = 0; anElemId < aNbElems; anElemId++ )
-          {
-            // find element
-            const SMDS_MeshElement* elem = FindElement( myMesh, anIndexes[i++] );
-            // nb nodes
-            int nbNodes = anIndexes[i++];
-            // nodes
-            ASSERT( nbNodes < 9 );
-            const SMDS_MeshNode* aNodes[ 8 ];
-            for ( int iNode = 0; iNode < nbNodes; iNode++ )
-              aNodes[ iNode ] = FindNode( myMesh, anIndexes[i++] );
-            // change
-            myMesh->ChangeElementNodes( elem, aNodes, nbNodes );
-          }
-          break;
-
-        case SMESH::RENUMBER:
-          for(CORBA::Long i=0; anElemId < aNbElems; anElemId++, i+=3)
-          {
-            myMesh->Renumber( anIndexes[i], anIndexes[i+1], anIndexes[i+2] );
-          }
-          break;
-          
-        default:;
-      }
-    }
-  }
-  catch ( SALOME::SALOME_Exception& exc )
-  {
-    INFOS("Following exception was cought:\n\t"<<exc.details.text);
-  }
-  catch( const std::exception& exc)
-  {
-    INFOS("Following exception was cought:\n\t"<<exc.what());
+  if ( MYDEBUG ) MESSAGE("SMESH_MeshObj::Update " << this);
+  if ( myClient.Update(theIsClear) || GetUnstructuredGrid()->GetNumberOfPoints()==0) {
+    if ( MYDEBUG ) MESSAGE("buildPrs");
+    buildPrs();  // Fill unstructured grid
+    return true;
   }
-  catch(...)
-  {
-    INFOS("Unknown exception was cought !!!");
-  }
-  
-  if ( MYDEBUG )
+  return false;
+}
+
+bool SMESH_MeshObj::NulData()
+{
+  if ( MYDEBUG ) MESSAGE ("SMESH_MeshObj::NulData() =============================================");
+  if (!myEmptyGrid)
   {
-    MESSAGE("Update - myMesh->NbNodes() = "<<myMesh->NbNodes());
-    MESSAGE("Update - myMesh->NbEdges() = "<<myMesh->NbEdges());
-    MESSAGE("Update - myMesh->NbFaces() = "<<myMesh->NbFaces());
-    MESSAGE("Update - myMesh->NbVolumes() = "<<myMesh->NbVolumes());
+    myEmptyGrid = SMDS_UnstructuredGrid::New();
+    myEmptyGrid->Initialize();
+    myEmptyGrid->Allocate();
+    vtkPoints* points = vtkPoints::New();
+    points->SetNumberOfPoints(0);
+    myEmptyGrid->SetPoints( points );
+    points->Delete();
+    //myEmptyGrid->BuildLinks();
   }
-
-  // Fill unstructured grid
-  buildPrs();
+  myGrid->ShallowCopy(myEmptyGrid);
+  return true;
 }
-
 //=================================================================================
 // function : GetElemDimension
 // purpose  : Get dimension of element
 //=================================================================================
 int SMESH_MeshObj::GetElemDimension( const int theObjId )
 {
-  const SMDS_MeshElement* anElem = myMesh->FindElement( theObjId );
+  const SMDS_MeshElement* anElem = myClient->FindElement( theObjId );
   if ( anElem == 0 )
     return 0;
 
   int aType = anElem->GetType();
   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;
@@ -760,28 +702,37 @@ int SMESH_MeshObj::GetElemDimension( const int theObjId )
 // function : GetEntities
 // purpose  : Get entities of specified type. Return number of entities
 //=================================================================================
-int SMESH_MeshObj::GetNbEntities( const SMESH::ElementType theType) const
+int SMESH_MeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const
 {
   switch ( theType )
   {
-    case SMESH::NODE:
+    case SMDSAbs_Node:
+    {
+      return myClient->NbNodes();
+    }
+    break;
+    case SMDSAbs_0DElement:
+    {
+      return myClient->Nb0DElements();
+    }
+    case SMDSAbs_Ball:
     {
-      return myMesh->NbNodes();
+      return myClient->NbBalls();
     }
     break;
-    case SMESH::EDGE:
+    case SMDSAbs_Edge:
     {
-      return myMesh->NbEdges();
+      return myClient->NbEdges();
     }
     break;
-    case SMESH::FACE:
+    case SMDSAbs_Face:
     {
-      return myMesh->NbFaces();
+      return myClient->NbFaces();
     }
     break;
-    case SMESH::VOLUME:
+    case SMDSAbs_Volume:
     {
-      return myMesh->NbVolumes();
+      return myClient->NbVolumes();
     }
     break;
     default:
@@ -790,33 +741,45 @@ int SMESH_MeshObj::GetNbEntities( const SMESH::ElementType theType) const
   }
 }
 
-int SMESH_MeshObj::GetEntities( const SMESH::ElementType theType, TEntityList& theObjs ) const
+int SMESH_MeshObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& theObjs ) const
 {
   theObjs.clear();
 
   switch ( theType )
   {
-    case SMESH::NODE:
+    case SMDSAbs_Node:
+    {
+      SMDS_NodeIteratorPtr anIter = myClient->nodesIterator();
+      while ( anIter->more() ) theObjs.push_back( anIter->next() );
+    }
+    break;
+    case SMDSAbs_0DElement:
+    {
+      SMDS_ElemIteratorPtr anIter = myClient->elementsIterator(SMDSAbs_0DElement);
+      while ( anIter->more() ) theObjs.push_back( anIter->next() );
+    }
+    break;
+    case SMDSAbs_Ball:
     {
-      SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator();
+      SMDS_ElemIteratorPtr anIter = myClient->elementGeomIterator(SMDSGeom_BALL);
       while ( anIter->more() ) theObjs.push_back( anIter->next() );
     }
     break;
-    case SMESH::EDGE:
+    case SMDSAbs_Edge:
     {
-      SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
+      SMDS_EdgeIteratorPtr anIter = myClient->edgesIterator();
       while ( anIter->more() ) theObjs.push_back( anIter->next() );
     }
     break;
-    case SMESH::FACE:
+    case SMDSAbs_Face:
     {
-      SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
+      SMDS_FaceIteratorPtr anIter = myClient->facesIterator();
       while ( anIter->more() ) theObjs.push_back( anIter->next() );
     }
     break;
-    case SMESH::VOLUME:
+    case SMDSAbs_Volume:
     {
-      SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
+      SMDS_VolumeIteratorPtr anIter = myClient->volumesIterator();
       while ( anIter->more() ) theObjs.push_back( anIter->next() );
     }
     break;
@@ -842,7 +805,7 @@ void SMESH_MeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor
 //=================================================================================
 bool SMESH_MeshObj::IsNodePrs() const
 {
-  return myMesh->NbEdges() == 0 &&myMesh->NbFaces() == 0 &&myMesh->NbVolumes() == 0 ;
+  return myClient->Nb0DElements() + myClient->NbEdges() + myClient->NbFaces() + myClient->NbVolumes() + myClient->NbBalls() == 0 ;
 }
 
 
@@ -879,6 +842,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() );
@@ -888,10 +852,12 @@ void SMESH_SubMeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunc
 // function : Update
 // purpose  : Update mesh object and fill grid with new values 
 //=================================================================================
-void SMESH_SubMeshObj::Update( int theIsClear )
+bool SMESH_SubMeshObj::Update( int theIsClear )
 {
-  myMeshObj->Update( theIsClear );
-  buildPrs();
+  if ( MYDEBUG ) MESSAGE("SMESH_SubMeshObj::Update " << this)
+  bool changed = myMeshObj->Update( theIsClear );
+  buildPrs(true);
+  return changed;
 }
 
 
@@ -916,7 +882,7 @@ SMESH_GroupObj::SMESH_GroupObj( SMESH::SMESH_GroupBase_ptr theGroup,
 SMESH_GroupObj::~SMESH_GroupObj()
 {
   if ( MYDEBUG ) MESSAGE("~SMESH_GroupObj");
-  myGroupServer->Destroy();
+  myGroupServer->UnRegister();
 }
 
 //=================================================================================
@@ -928,6 +894,15 @@ bool SMESH_GroupObj::IsNodePrs() const
   return myGroupServer->GetType() == SMESH::NODE;
 }
 
+//=================================================================================
+// function : GetElementType
+// purpose  : Return type of elements of group
+//=================================================================================
+SMDSAbs_ElementType SMESH_GroupObj::GetElementType() const
+{
+  return SMDSAbs_ElementType(myGroupServer->GetType());
+}
+
 //=================================================================================
 // function : getNodesFromElems
 // purpose  : Retrieve nodes from elements
@@ -964,14 +939,14 @@ static int getNodesFromElems( SMESH::long_array_var&              theElemIds,
 // function : getPointers
 // purpose  : Get std::list<const SMDS_MeshElement*> from list of IDs
 //=================================================================================
-static int getPointers( const SMESH::ElementType            theRequestType,
+static int getPointers( const SMDSAbs_ElementType           theRequestType,
                         SMESH::long_array_var&              theElemIds,
                         const SMDS_Mesh*                    theMesh,
                         std::list<const SMDS_MeshElement*>& theResList )
 {
   for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ )
   {
-    const SMDS_MeshElement* anElem = theRequestType == SMESH::NODE
+    const SMDS_MeshElement* anElem = theRequestType == SMDSAbs_Node
       ? theMesh->FindNode( theElemIds[ i ] ) : theMesh->FindElement( theElemIds[ i ] );
 
     if ( anElem != 0 )
@@ -986,32 +961,40 @@ static int getPointers( const SMESH::ElementType            theRequestType,
 // function : GetEntities
 // purpose  : Get entities of specified type. Return number of entities
 //=================================================================================
-int SMESH_GroupObj::GetNbEntities( const SMESH::ElementType theType) const
+int SMESH_GroupObj::GetNbEntities( const SMDSAbs_ElementType theType) const
 {
-  if(myGroupServer->GetType() == theType){
+  if(SMDSAbs_ElementType(myGroupServer->GetType()) == theType) {
     return myGroupServer->Size();
   }
+  if ( theType == SMDSAbs_Node ) {
+    return myGroupServer->GetNumberOfNodes();
+  }
   return 0;
 }
 
-int SMESH_GroupObj::GetEntities( const SMESH::ElementType theType, TEntityList& theResList ) const
+int SMESH_GroupObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& theResList ) const
 {
   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::ElementType aGrpType = myGroupServer->GetType();
   SMESH::long_array_var anIds = myGroupServer->GetListOfID();
+  if ( anIds->length() == 0 )
+    return 0;
 
   if ( aGrpType == theType )
     return getPointers( theType, anIds, aMesh, theResList );
-  else if ( theType == SMESH::NODE )
+  else if ( theType == SMDSAbs_Node )
     return getNodesFromElems( anIds, aMesh, theResList );
   else
     return 0;
-}    
+}
 
 
 
@@ -1037,27 +1020,30 @@ SMESH_subMeshObj::SMESH_subMeshObj( SMESH::SMESH_subMesh_ptr theSubMesh,
 SMESH_subMeshObj::~SMESH_subMeshObj()
 {
   if ( MYDEBUG ) MESSAGE( "~SMESH_subMeshObj" );
-  mySubMeshServer->Destroy();
+  mySubMeshServer->UnRegister();
 }
 
 //=================================================================================
 // function : GetEntities
 // purpose  : Get entities of specified type. Return number of entities
 //=================================================================================
-int SMESH_subMeshObj::GetNbEntities( const SMESH::ElementType theType) const
+int SMESH_subMeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const
 {
   switch ( theType )
   {
-    case SMESH::NODE:
+    case SMDSAbs_Node:
     {
-      return mySubMeshServer->GetNumberOfNodes( false );
+      return mySubMeshServer->GetNumberOfNodes( /*all=*/true );
     }
     break;
-    case SMESH::EDGE:
-    case SMESH::FACE:
-    case SMESH::VOLUME:
+    case SMDSAbs_Ball:
+    case SMDSAbs_0DElement:
+    case SMDSAbs_Edge:
+    case SMDSAbs_Face:
+    case SMDSAbs_Volume:
     {
-      SMESH::long_array_var anIds = mySubMeshServer->GetElementsByType( theType );
+      SMESH::long_array_var anIds = 
+        mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
       return anIds->length();
     }
     default:
@@ -1066,7 +1052,7 @@ int SMESH_subMeshObj::GetNbEntities( const SMESH::ElementType theType) const
   }
 }
 
-int SMESH_subMeshObj::GetEntities( const SMESH::ElementType theType, TEntityList& theResList ) const
+int SMESH_subMeshObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& theResList ) const
 {
   theResList.clear();
 
@@ -1078,22 +1064,23 @@ int SMESH_subMeshObj::GetEntities( const SMESH::ElementType theType, TEntityList
 
   if ( isNodal )
   {
-    if ( theType == SMESH::NODE )
+    if ( theType == SMDSAbs_Node )
     {
       SMESH::long_array_var anIds = mySubMeshServer->GetNodesId();
-      return getPointers( SMESH::NODE, anIds, aMesh, theResList );
+      return getPointers( SMDSAbs_Node, anIds, aMesh, theResList );
     }
   }
   else
   {
-    if ( theType == SMESH::NODE )
+    if ( theType == SMDSAbs_Node )
     {
       SMESH::long_array_var anIds = mySubMeshServer->GetElementsId();
       return getNodesFromElems( anIds, aMesh, theResList );
     }
     else
     {
-      SMESH::long_array_var anIds = mySubMeshServer->GetElementsByType( theType );
+      SMESH::long_array_var anIds = 
+        mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
       return getPointers( theType, anIds, aMesh, theResList );
     }
   }
@@ -1109,15 +1096,3 @@ bool SMESH_subMeshObj::IsNodePrs() const
 {
   return mySubMeshServer->GetNumberOfElements() == 0;
 }
-
-
-
-
-
-
-
-
-
-
-
-