Salome HOME
PAL10237. Add hypothesis "AutomaticLength" and 2 hypotheses-set's:
[modules/smesh.git] / src / OBJECT / SMESH_Object.cxx
index 6621177cc32ed4f904eacaeaba8602d65d28dce2..885ee3de35b4b66aed1a34dcc8e1166956a27870 100644 (file)
 //  Author : Nicolas REJNERI
 //  Module : SMESH
 
-#include "SMESH_Object.h"
+#include "SMESH_ObjectDef.h"
+#include "SMESH_ActorUtils.h"
+
 #include "SMDS_Mesh.hxx"
-#include "SALOME_ExtractUnstructuredGrid.h"
 #include "SMESH_Actor.h"
+#include "SMESH_ControlsDef.hxx"
+#include <VTKViewer_ExtractUnstructuredGrid.h>
 
 #include CORBA_SERVER_HEADER(SALOME_Exception)
 
@@ -39,8 +42,6 @@
 #include <vtkUnsignedCharArray.h>
 
 #include <vtkUnstructuredGrid.h>
-#include <vtkUnstructuredGridWriter.h>
-#include <vtkUnstructuredGridReader.h>
 
 #include <memory>
 #include <sstream>     
@@ -68,17 +69,6 @@ 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){
@@ -117,7 +107,6 @@ namespace{
                             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())
@@ -136,7 +125,6 @@ namespace{
                             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())
@@ -156,7 +144,6 @@ namespace{
                             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())
@@ -173,11 +160,34 @@ namespace{
   }
 
 
+  inline void AddPolygonsWithID(SMDS_Mesh* theMesh, 
+                                SMESH::log_array_var& theSeq,
+                                CORBA::Long theId)
+  {
+    const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+    CORBA::Long anIndexId = 0, aNbElems = theSeq[theId].number;
+
+    for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++) {
+      int aFaceId = anIndexes[anIndexId++];
+
+      int aNbNodes = anIndexes[anIndexId++];
+      std::vector<int> nodes_ids (aNbNodes);
+      for (int i = 0; i < aNbNodes; i++) {
+        nodes_ids[i] = anIndexes[anIndexId++];
+      }
+
+      SMDS_MeshElement* anElem = theMesh->AddPolygonalFaceWithID(nodes_ids, aFaceId);
+      if (!anElem)
+       EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddPolygonalFaceWithID 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())
@@ -189,7 +199,7 @@ namespace{
                                                          anIndexes[anIndexId+4],
                                                          anIndexes[anIndexId]);
       if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
+       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
     }
   }
 
@@ -198,7 +208,6 @@ namespace{
                                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())
@@ -211,7 +220,7 @@ namespace{
                                                          anIndexes[anIndexId+5],
                                                          anIndexes[anIndexId]);
       if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
+       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
     }
   }
 
@@ -220,7 +229,6 @@ namespace{
                              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())
@@ -234,7 +242,7 @@ namespace{
                                                          anIndexes[anIndexId+6],
                                                          anIndexes[anIndexId]);
       if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
+       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
     }
   }
 
@@ -243,7 +251,6 @@ namespace{
                             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())
@@ -259,14 +266,76 @@ namespace{
                                                          anIndexes[anIndexId+8],
                                                          anIndexes[anIndexId]);
       if(!anElem)
-       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
+       EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
+    }
+  }
+
+
+  inline void AddPolyhedronsWithID (SMDS_Mesh* theMesh, 
+                                    SMESH::log_array_var& theSeq,
+                                    CORBA::Long theId)
+  {
+    const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+    CORBA::Long anIndexId = 0, aNbElems = theSeq[theId].number;
+
+    for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++) {
+      int aFaceId = anIndexes[anIndexId++];
+
+      int aNbNodes = anIndexes[anIndexId++];
+      std::vector<int> nodes_ids (aNbNodes);
+      for (int i = 0; i < aNbNodes; i++) {
+        nodes_ids[i] = anIndexes[anIndexId++];
+      }
+
+      int aNbFaces = anIndexes[anIndexId++];
+      std::vector<int> quantities (aNbFaces);
+      for (int i = 0; i < aNbFaces; i++) {
+        quantities[i] = anIndexes[anIndexId++];
+      }
+
+      SMDS_MeshElement* anElem =
+        theMesh->AddPolyhedralVolumeWithID(nodes_ids, quantities, aFaceId);
+      if (!anElem)
+       EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddPolyhedralVolumeWithID for ID = "
+                  << anElemId);
+    }
+  }
+
+
+  inline void ChangePolyhedronNodes (SMDS_Mesh* theMesh, 
+                                     SMESH::log_array_var& theSeq,
+                                     CORBA::Long theId)
+  {
+    const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+    CORBA::Long iind = 0, aNbElems = theSeq[theId].number;
+
+    for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++)
+    {
+      // find element
+      const SMDS_MeshElement* elem = FindElement(theMesh, anIndexes[iind++]);
+      // nb nodes
+      int nbNodes = anIndexes[iind++];
+      // nodes
+      std::vector<const SMDS_MeshNode*> aNodes (nbNodes);
+      for (int iNode = 0; iNode < nbNodes; iNode++) {
+        aNodes[iNode] = FindNode(theMesh, anIndexes[iind++]);
+      }
+      // nb faces
+      int nbFaces = anIndexes[iind++];
+      // quantities
+      std::vector<int> quantities (nbFaces);
+      for (int iFace = 0; iFace < nbFaces; iFace++) {
+        quantities[iFace] = anIndexes[iind++];
+      }
+      // change
+      theMesh->ChangePolyhedronNodes(elem, aNodes, quantities);
     }
   }
 
 
 }
 /*
-  Class       : SMESH_VisualObj
+  Class       : SMESH_VisualObjDef
   Description : Base class for all mesh objects to be visuilised
 */
 
@@ -274,36 +343,42 @@ namespace{
 // function : getCellType
 // purpose  : Get type of VTK cell
 //=================================================================================
-static inline vtkIdType getCellType( const SMESH::ElementType theType,
+static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
+                                    const bool thePoly,
                                      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;
+    case SMDSAbs_Edge: 
+      return theNbNodes == 2 ? VTK_LINE : 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 return VTK_EMPTY_CELL;
+      
+    case SMDSAbs_Volume:
+      if (thePoly && theNbNodes>3 ) return 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 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()
 {
   myGrid = vtkUnstructuredGrid::New();
 }
-SMESH_VisualObj::~SMESH_VisualObj()
+SMESH_VisualObjDef::~SMESH_VisualObjDef()
 {
   if ( MYDEBUG )
     MESSAGE( "~SMESH_MeshObj - myGrid->GetReferenceCount() = " << myGrid->GetReferenceCount() );
@@ -314,37 +389,37 @@ 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];
 }
 
-vtkIdType SMESH_VisualObj::GetNodeVTKId( int theObjID )
+vtkIdType SMESH_VisualObjDef::GetNodeVTKId( int theObjID )
 {
   return mySMDS2VTKNodes.find(theObjID) == mySMDS2VTKNodes.end() ? -1 : mySMDS2VTKNodes[theObjID];
 }
 
-vtkIdType SMESH_VisualObj::GetElemObjId( int theVTKID )
+vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID )
 {
   return myVTK2SMDSElems.find(theVTKID) == myVTK2SMDSElems.end() ? -1 : myVTK2SMDSElems[theVTKID];
 }
 
-vtkIdType SMESH_VisualObj::GetElemVTKId( int theObjID )
+vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID )
 {
   return mySMDS2VTKElems.find(theObjID) == mySMDS2VTKElems.end() ? -1 : mySMDS2VTKElems[theObjID];
 }
 
 //=================================================================================
-// function : SMESH_VisualObj::createPoints
+// function : SMESH_VisualObjDef::createPoints
 // purpose  : Create points from nodes
 //=================================================================================
-void SMESH_VisualObj::createPoints( vtkPoints* thePoints )
+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;
@@ -371,7 +446,7 @@ void SMESH_VisualObj::createPoints( vtkPoints* thePoints )
 // function : buildPrs
 // purpose  : create VTK cells( fill unstructured grid )
 //=================================================================================
-void SMESH_VisualObj::buildPrs()
+void SMESH_VisualObjDef::buildPrs()
 {
   try
   {
@@ -395,18 +470,17 @@ void SMESH_VisualObj::buildPrs()
   }
   
   if( MYDEBUG ) MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->GetNumberOfCells() );
-  if( MYDEBUGWITHFILES ) WriteUnstructuredGrid( myGrid,"/tmp/buildPrs" );
+  if( MYDEBUGWITHFILES ) SMESH::WriteUnstructuredGrid( myGrid,"/tmp/buildPrs" );
 }
 
 //=================================================================================
 // function : buildNodePrs
 // purpose  : create VTK cells for nodes
 //=================================================================================
-void SMESH_VisualObj::buildNodePrs()
+void SMESH_VisualObjDef::buildNodePrs()
 {
   vtkPoints* aPoints = vtkPoints::New();
   createPoints( aPoints );
-  int nbPoints = aPoints->GetNumberOfPoints();
   myGrid->SetPoints( aPoints );
   aPoints->Delete();
 
@@ -414,6 +488,7 @@ void SMESH_VisualObj::buildNodePrs()
 
   // Create cells
   /*
+  int nbPoints = aPoints->GetNumberOfPoints();
   vtkIdList *anIdList = vtkIdList::New();
   anIdList->SetNumberOfIds( 1 );
 
@@ -452,7 +527,33 @@ void SMESH_VisualObj::buildNodePrs()
 // function : buildElemPrs
 // purpose  : Create VTK cells for elements
 //=================================================================================
-void SMESH_VisualObj::buildElemPrs()
+
+namespace{
+  typedef std::vector<const SMDS_MeshElement*> TConnect;
+
+  int GetConnect(const SMDS_ElemIteratorPtr& theNodesIter, 
+                TConnect& theConnect)
+  {
+    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);
+  }
+
+}
+
+
+void SMESH_VisualObjDef::buildElemPrs()
 {
   // Create points
   
@@ -466,16 +567,16 @@ void SMESH_VisualObj::buildElemPrs()
 
   // Calculate cells size
 
-  static SMESH::ElementType aTypes[ 3 ] = { SMESH::EDGE, SMESH::FACE, SMESH::VOLUME };
+  static SMDSAbs_ElementType aTypes[ 3 ] = { SMDSAbs_Edge, SMDSAbs_Face, SMDSAbs_Volume };
 
   // 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++ )
     nbEnts[ aTypes[ i ] ] = GetEntities( aTypes[ i ], anEnts[ aTypes[ i ] ] );
 
-  vtkIdType aCellsSize =  3 * nbEnts[ SMESH::EDGE ];
+  vtkIdType aCellsSize =  3 * nbEnts[ SMDSAbs_Edge ];
 
   for ( int i = 1; i <= 2; i++ ) // iterate through faces and volumes
   {
@@ -488,7 +589,7 @@ void SMESH_VisualObj::buildElemPrs()
     }
   }
 
-  vtkIdType aNbCells = nbEnts[ SMESH::EDGE ] + nbEnts[ SMESH::FACE ] + nbEnts[ SMESH::VOLUME ];
+  vtkIdType aNbCells = nbEnts[ SMDSAbs_Edge ] + nbEnts[ SMDSAbs_Face ] + nbEnts[ SMDSAbs_Volume ];
   
   if ( MYDEBUG )
     MESSAGE( "Update - aNbCells = "<<aNbCells<<"; aCellsSize = "<<aCellsSize );
@@ -504,12 +605,16 @@ void SMESH_VisualObj::buildElemPrs()
   
   vtkIdList *anIdList = vtkIdList::New();
   vtkIdType iElem = 0;
-  
+
+  TConnect aConnect;
+  aConnect.reserve(VTK_CELL_SIZE);
+
   for ( int i = 0; i <= 2; i++ ) // iterate through edges, faces and volumes
   {
     if( nbEnts[ aTypes[ i ] ] > 0 )
     {
-      const TEntityList& aList = anEnts[ aTypes[ i ] ];
+      const SMDSAbs_ElementType& aType = aTypes[ i ];
+      const TEntityList& aList = anEnts[ aType ];
       TEntityList::const_iterator anIter;
       for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
       {
@@ -524,14 +629,50 @@ void SMESH_VisualObj::buildElemPrs()
         myVTK2SMDSElems.insert( TMapOfIds::value_type( 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()] );
-        }
+       switch(aType){
+       case SMDSAbs_Volume:{
+         std::vector<int> aConnectivities;
+         GetConnect(aNodesIter,aConnect);
+         // Convertions connectivities from SMDS to VTK
+         if (anElem->IsPoly() && aNbNodes > 3) { // POLYEDRE
+           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 (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()] );
+         }
+       }
 
         aConnectivity->InsertNextCell( anIdList );
-        aCellTypesArray->InsertNextValue( getCellType( aTypes[ i ], aNbNodes ) );
+        aCellTypesArray->InsertNextValue( getCellType( aType, anElem->IsPoly(), aNbNodes ) );
 
         iElem++;
       }
@@ -560,10 +701,10 @@ void SMESH_VisualObj::buildElemPrs()
 // function : GetEdgeNodes
 // purpose  : Retrieve ids of nodes from edge of elements ( edge is numbered from 1 )
 //=================================================================================
-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 )
@@ -575,7 +716,7 @@ bool SMESH_VisualObj::GetEdgeNodes( const int theElemId,
     
   int nbNodes = anElem->NbNodes();
 
-  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 ];
@@ -584,10 +725,10 @@ bool SMESH_VisualObj::GetEdgeNodes( const int theElemId,
   while( anIter->more() )
     anIds[ i++ ] = anIter->next()->GetID();
 
-  if ( nbNodes != theEdgeNum )
+  if ( theEdgeNum < nbNodes - 1 )
   {
-    theNodeId1 = anIds[ theEdgeNum - 1 ];
-    theNodeId2 = anIds[ theEdgeNum ];
+    theNodeId1 = anIds[ theEdgeNum ];
+    theNodeId2 = anIds[ theEdgeNum + 1 ];
   }
   else
   {
@@ -644,26 +785,27 @@ void SMESH_MeshObj::Update( int theIsClear )
     
     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::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_POLYGON    : AddPolygonsWithID   ( 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::ADD_POLYHEDRON : AddPolyhedronsWithID( myMesh, aSeq, anId ); break;
+
         case SMESH::REMOVE_NODE:
           for( ; anElemId < aNbElems; anElemId++ )
             myMesh->RemoveNode( FindNode( myMesh, anIndexes[anElemId] ) );
@@ -691,8 +833,8 @@ void SMESH_MeshObj::Update( int theIsClear )
             // nb nodes
             int nbNodes = anIndexes[i++];
             // nodes
-            ASSERT( nbNodes < 9 );
-            const SMDS_MeshNode* aNodes[ 8 ];
+            //ASSERT( nbNodes < 9 );
+            const SMDS_MeshNode* aNodes[ nbNodes ];
             for ( int iNode = 0; iNode < nbNodes; iNode++ )
               aNodes[ iNode ] = FindNode( myMesh, anIndexes[i++] );
             // change
@@ -700,6 +842,9 @@ void SMESH_MeshObj::Update( int theIsClear )
           }
           break;
 
+        case SMESH::CHANGE_POLYHEDRON_NODES:
+          ChangePolyhedronNodes(myMesh, aSeq, anId);
+          break;
         case SMESH::RENUMBER:
           for(CORBA::Long i=0; anElemId < aNbElems; anElemId++, i+=3)
           {
@@ -760,26 +905,26 @@ 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 myMesh->NbNodes();
     }
     break;
-    case SMESH::EDGE:
+    case SMDSAbs_Edge:
     {
       return myMesh->NbEdges();
     }
     break;
-    case SMESH::FACE:
+    case SMDSAbs_Face:
     {
       return myMesh->NbFaces();
     }
     break;
-    case SMESH::VOLUME:
+    case SMDSAbs_Volume:
     {
       return myMesh->NbVolumes();
     }
@@ -790,31 +935,31 @@ 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 = myMesh->nodesIterator();
       while ( anIter->more() ) theObjs.push_back( anIter->next() );
     }
     break;
-    case SMESH::EDGE:
+    case SMDSAbs_Edge:
     {
       SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
       while ( anIter->more() ) theObjs.push_back( anIter->next() );
     }
     break;
-    case SMESH::FACE:
+    case SMDSAbs_Face:
     {
       SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
       while ( anIter->more() ) theObjs.push_back( anIter->next() );
     }
     break;
-    case SMESH::VOLUME:
+    case SMDSAbs_Volume:
     {
       SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
       while ( anIter->more() ) theObjs.push_back( anIter->next() );
@@ -964,14 +1109,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,15 +1131,15 @@ 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();
   }
   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();
@@ -1002,12 +1147,12 @@ int SMESH_GroupObj::GetEntities( const SMESH::ElementType theType, TEntityList&
   if ( myGroupServer->Size() == 0 || aMesh == 0 )
     return 0;
 
-  SMESH::ElementType aGrpType = myGroupServer->GetType();
+  SMDSAbs_ElementType aGrpType = SMDSAbs_ElementType(myGroupServer->GetType());
   SMESH::long_array_var anIds = myGroupServer->GetListOfID();
 
   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;
@@ -1044,20 +1189,21 @@ SMESH_subMeshObj::~SMESH_subMeshObj()
 // 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 );
     }
     break;
-    case SMESH::EDGE:
-    case SMESH::FACE:
-    case SMESH::VOLUME:
+    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 +1212,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 +1224,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 );
     }
   }