Salome HOME
Merge from V5_1_4_BR 07/05/2010
[modules/smesh.git] / src / OBJECT / SMESH_Object.cxx
index 30544754989fdeb7b411fab88f64a64c9c5edfbb..eb43a6b5f89828f48ffedb925249431b046ce7d3 100644 (file)
@@ -1,4 +1,4 @@
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//  Copyright (C) 2007-2010  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
@@ -19,6 +19,7 @@
 //
 //  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
@@ -46,7 +47,7 @@
 #include <vtkUnstructuredGrid.h>
 
 #include <memory>
-#include <sstream>     
+#include <sstream>      
 #include <stdexcept>
 #include <set>
 
@@ -81,11 +82,14 @@ static int MYDEBUGWITHFILES = 0;
 // purpose  : Get type of VTK cell
 //=================================================================================
 static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
-                                    const bool thePoly,
+                                     const bool thePoly,
                                      const int theNbNodes )
 {
   switch( theType )
   {
+    case SMDSAbs_0DElement: 
+      return VTK_VERTEX;
+
     case SMDSAbs_Edge: 
       if( theNbNodes == 2 )         return VTK_LINE;
       else if ( theNbNodes == 3 )   return VTK_QUADRATIC_EDGE;
@@ -260,7 +264,7 @@ namespace{
   typedef std::vector<const SMDS_MeshElement*> TConnect;
 
   int GetConnect(const SMDS_ElemIteratorPtr& theNodesIter, 
-                TConnect& theConnect)
+                 TConnect& theConnect)
   {
     theConnect.clear();
     for(; theNodesIter->more();)
@@ -270,10 +274,10 @@ namespace{
   
   inline 
   void SetId(vtkIdList *theIdList, 
-            const SMESH_VisualObjDef::TMapOfIds& theSMDS2VTKNodes, 
-            const TConnect& theConnect, 
-            int thePosition,
-            int theId)
+             const SMESH_VisualObjDef::TMapOfIds& theSMDS2VTKNodes, 
+             const TConnect& theConnect, 
+             int thePosition,
+             int theId)
   {
     theIdList->SetId(thePosition,theSMDS2VTKNodes.find(theConnect[theId]->GetID())->second);
   }
@@ -295,22 +299,23 @@ void SMESH_VisualObjDef::buildElemPrs()
 
   // Calculate cells size
 
-  static SMDSAbs_ElementType aTypes[ 3 ] = { SMDSAbs_Edge, SMDSAbs_Face, SMDSAbs_Volume };
+  static SMDSAbs_ElementType aTypes[ 4 ] =
+    { SMDSAbs_0DElement, SMDSAbs_Edge, SMDSAbs_Face, SMDSAbs_Volume };
 
   // get entity data
   map<SMDSAbs_ElementType,int> nbEnts;
   map<SMDSAbs_ElementType,TEntityList> anEnts;
 
-  for ( int i = 0; i <= 2; i++ )
+  for ( int i = 0; i <= 3; i++ )
     nbEnts[ aTypes[ i ] ] = GetEntities( aTypes[ i ], anEnts[ 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[ SMDSAbs_Edge ];
+  vtkIdType aCellsSize =  2 * nbEnts[ SMDSAbs_0DElement ] + 3 * nbEnts[ SMDSAbs_Edge ];
 
-  for ( int i = 1; i <= 2; i++ ) // iterate through faces and volumes
+  for ( int i = 2; i <= 3; i++ ) // iterate through faces and volumes
   {
     if ( nbEnts[ aTypes[ i ] ] )
     {
@@ -321,22 +326,23 @@ void SMESH_VisualObjDef::buildElemPrs()
     }
   }
 
-  vtkIdType aNbCells = nbEnts[ SMDSAbs_Edge ] + nbEnts[ SMDSAbs_Face ] + nbEnts[ SMDSAbs_Volume ];
+  vtkIdType aNbCells = nbEnts[ SMDSAbs_0DElement ] + nbEnts[ SMDSAbs_Edge ] +
+                       nbEnts[ SMDSAbs_Face ] + nbEnts[ SMDSAbs_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();
@@ -347,9 +353,9 @@ void SMESH_VisualObjDef::buildElemPrs()
 
   SMDS_Mesh::CheckMemory(); // PAL16631
 
-  for ( int i = 0; i <= 2; i++ ) // iterate through edges, faces and volumes
+  for ( int i = 0; i <= 3; i++ ) // iterate through 0d elements, edges, faces and volumes
   {
-    if( nbEnts[ aTypes[ i ] ] > 0 )
+    if ( nbEnts[ aTypes[ i ] ] > 0 )
     {
       const SMDSAbs_ElementType& aType = aTypes[ i ];
       const TEntityList& aList = anEnts[ aType ];
@@ -357,7 +363,7 @@ void SMESH_VisualObjDef::buildElemPrs()
       for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
       {
         const SMDS_MeshElement* anElem = *anIter;
-        
+
         vtkIdType aNbNodes = anElem->NbNodes();
         anIdList->SetNumberOfIds( aNbNodes );
 
@@ -367,12 +373,12 @@ void SMESH_VisualObjDef::buildElemPrs()
         myVTK2SMDSElems.insert( TMapOfIds::value_type( iElem, anId ) );
 
         SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
-       switch(aType){
-       case SMDSAbs_Volume:{
+        switch (aType) {
+        case SMDSAbs_Volume:{
           aConnect.clear();
-         std::vector<int> aConnectivities;
-         // Convertions connectivities from SMDS to VTK
-         if (anElem->IsPoly() && aNbNodes > 3) { // POLYEDRE
+          std::vector<int> aConnectivities;
+          // Convertions connectivities from SMDS to VTK
+          if (anElem->IsPoly() && aNbNodes > 3) { // POLYEDRE
 
             if ( const SMDS_PolyhedralVolumeOfNodes* ph =
                  dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem))
@@ -380,67 +386,67 @@ void SMESH_VisualObjDef::buildElemPrs()
               aNbNodes = GetConnect(ph->uniqueNodesIterator(),aConnect);
               anIdList->SetNumberOfIds( aNbNodes );
             }
-           for (int k = 0; k < aNbNodes; k++)
-             aConnectivities.push_back(k);
+            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]);
+            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 == 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 == 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]);
+            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]);
-         }
+            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]);
-         }
+            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++) {
+            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]);
-         }
+            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()] );
-         }
-       }
+          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( aType, anElem->IsPoly(), aNbNodes ) );
@@ -478,9 +484,9 @@ void SMESH_VisualObjDef::buildElemPrs()
 // purpose  : Retrieve ids of nodes from edge of elements ( edge is numbered from 1 )
 //=================================================================================
 bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
-                                      const int theEdgeNum,
-                                      int&      theNodeId1,
-                                      int&      theNodeId2 ) const
+                                       const int theEdgeNum,
+                                       int&      theNodeId1,
+                                       int&      theNodeId2 ) const
 {
   const SMDS_Mesh* aMesh = GetMesh();
   if ( aMesh == 0 )
@@ -515,6 +521,19 @@ bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
   return true;
 }
 
+//=================================================================================
+// function : IsValid
+// purpose  : Return true if there are some entities
+//=================================================================================
+bool SMESH_VisualObjDef::IsValid() const
+{
+  return GetNbEntities(SMDSAbs_Node) > 0      || 
+         GetNbEntities(SMDSAbs_0DElement) > 0 || 
+         GetNbEntities(SMDSAbs_Edge) > 0      || 
+         GetNbEntities(SMDSAbs_Face) > 0      ||
+         GetNbEntities(SMDSAbs_Volume) > 0 ;
+}
+
 /*
   Class       : SMESH_MeshObj
   Description : Class for visualisation of mesh
@@ -568,6 +587,7 @@ int SMESH_MeshObj::GetElemDimension( const int theObjId )
   int aType = anElem->GetType();
   switch ( aType )
   {
+    case SMDSAbs_0DElement : return 0;
     case SMDSAbs_Edge  : return 1;
     case SMDSAbs_Face  : return 2;
     case SMDSAbs_Volume: return 3;
@@ -588,6 +608,11 @@ int SMESH_MeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const
       return myClient->NbNodes();
     }
     break;
+    case SMDSAbs_0DElement:
+    {
+      return myClient->Nb0DElements();
+    }
+    break;
     case SMDSAbs_Edge:
     {
       return myClient->NbEdges();
@@ -621,6 +646,12 @@ int SMESH_MeshObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList&
       while ( anIter->more() ) theObjs.push_back( anIter->next() );
     }
     break;
+    case SMDSAbs_0DElement:
+    {
+      SMDS_0DElementIteratorPtr anIter = myClient->elements0dIterator();
+      while ( anIter->more() ) theObjs.push_back( anIter->next() );
+    }
+    break;
     case SMDSAbs_Edge:
     {
       SMDS_EdgeIteratorPtr anIter = myClient->edgesIterator();
@@ -661,7 +692,7 @@ void SMESH_MeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor
 //=================================================================================
 bool SMESH_MeshObj::IsNodePrs() const
 {
-  return myClient->NbEdges() == 0 &&myClient->NbFaces() == 0 && myClient->NbVolumes() == 0 ;
+  return myClient->Nb0DElements() == 0 && myClient->NbEdges() == 0 && myClient->NbFaces() == 0 && myClient->NbVolumes() == 0 ;
 }
 
 
@@ -748,6 +779,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
@@ -873,12 +913,13 @@ int SMESH_subMeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const
       return mySubMeshServer->GetNumberOfNodes( false );
     }
     break;
+    case SMDSAbs_0DElement:
     case SMDSAbs_Edge:
     case SMDSAbs_Face:
     case SMDSAbs_Volume:
     {
       SMESH::long_array_var anIds = 
-       mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
+        mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
       return anIds->length();
     }
     default:
@@ -915,7 +956,7 @@ int SMESH_subMeshObj::GetEntities( const SMDSAbs_ElementType theType, TEntityLis
     else
     {
       SMESH::long_array_var anIds = 
-       mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
+        mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
       return getPointers( theType, anIds, aMesh, theResList );
     }
   }