Salome HOME
0020082: EDF 869 GEOM : Edges Orientation indicator/reverse
[modules/smesh.git] / src / OBJECT / SMESH_Object.cxx
index ca0e7418ef165dd24c7bd0258e2cdca02fa0c847..c286fcc7e355a6cd072640e7294cdc03c3d044c5 100644 (file)
@@ -1,34 +1,34 @@
-//  SMESH OBJECT : interactive object for SMESH visualization
+//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
-//  Copyright (C) 2003  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 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.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 "SMDS_Mesh.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
 #include "SMESH_Actor.h"
 #include "SMESH_ControlsDef.hxx"
 #include "SalomeApp_Application.h"
@@ -111,7 +111,10 @@ static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
       else if ( theNbNodes == 20 )  {
         return VTK_QUADRATIC_HEXAHEDRON;
       }
-      else if ( theNbNodes==13 || theNbNodes==15 )  {
+      else if ( theNbNodes == 15 )  {
+        return VTK_QUADRATIC_WEDGE;
+      }
+      else if ( theNbNodes==13 )  {
         return VTK_CONVEX_POINT_SET;
       }
       else return VTK_EMPTY_CELL;
@@ -141,22 +144,26 @@ SMESH_VisualObjDef::~SMESH_VisualObjDef()
 //=================================================================================
 vtkIdType SMESH_VisualObjDef::GetNodeObjId( int theVTKID )
 {
-  return myVTK2SMDSNodes.find(theVTKID) == myVTK2SMDSNodes.end() ? -1 : myVTK2SMDSNodes[theVTKID];
+  TMapOfIds::const_iterator i = myVTK2SMDSNodes.find(theVTKID);
+  return i == myVTK2SMDSNodes.end() ? -1 : i->second;
 }
 
 vtkIdType SMESH_VisualObjDef::GetNodeVTKId( int theObjID )
 {
-  return mySMDS2VTKNodes.find(theObjID) == mySMDS2VTKNodes.end() ? -1 : mySMDS2VTKNodes[theObjID];
+  TMapOfIds::const_iterator i = mySMDS2VTKNodes.find(theObjID);
+  return i == mySMDS2VTKNodes.end() ? -1 : i->second;
 }
 
 vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID )
 {
-  return myVTK2SMDSElems.find(theVTKID) == myVTK2SMDSElems.end() ? -1 : myVTK2SMDSElems[theVTKID];
+  TMapOfIds::const_iterator i = myVTK2SMDSElems.find(theVTKID);
+  return i == myVTK2SMDSElems.end() ? -1 : i->second;
 }
 
 vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID )
 {
-  return mySMDS2VTKElems.find(theObjID) == mySMDS2VTKElems.end() ? -1 : mySMDS2VTKElems[theObjID];
+  TMapOfIds::const_iterator i = mySMDS2VTKElems.find(theObjID);
+  return i == mySMDS2VTKElems.end() ? -1 : i->second;
 }
 
 //=================================================================================
@@ -198,7 +205,7 @@ void SMESH_VisualObjDef::createPoints( vtkPoints* thePoints )
 //=================================================================================
 void SMESH_VisualObjDef::buildPrs()
 {
-  try
+  try 
   {
     mySMDS2VTKNodes.clear();
     myVTK2SMDSNodes.clear();
@@ -210,13 +217,16 @@ void SMESH_VisualObjDef::buildPrs()
     else
       buildElemPrs();
   }
-  catch( const std::exception& exc )
-  {
-    INFOS("Follow exception was cought:\n\t"<<exc.what());
-  }
   catch(...)
   {
-    INFOS("Unknown exception was cought !!!");
+    mySMDS2VTKNodes.clear();
+    myVTK2SMDSNodes.clear();
+    mySMDS2VTKElems.clear();
+    myVTK2SMDSElems.clear();
+
+    myGrid->SetPoints( 0 );
+    myGrid->SetCells( 0, 0, 0 );
+    throw;
   }
   
   if( MYDEBUG ) MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->GetNumberOfCells() );
@@ -229,8 +239,12 @@ void SMESH_VisualObjDef::buildPrs()
 //=================================================================================
 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 );
+  SMDS_Mesh::CheckMemory();
   myGrid->SetPoints( aPoints );
   aPoints->Delete();
 
@@ -290,6 +304,10 @@ void SMESH_VisualObjDef::buildElemPrs()
   for ( int i = 0; i <= 2; 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 ];
 
   for ( int i = 1; i <= 2; i++ ) // iterate through faces and volumes
@@ -313,16 +331,22 @@ void SMESH_VisualObjDef::buildElemPrs()
   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;
 
   TConnect aConnect;
   aConnect.reserve(VTK_CELL_SIZE);
 
+  SMDS_Mesh::CheckMemory(); // PAL16631
+
   for ( int i = 0; i <= 2; i++ ) // iterate through edges, faces and volumes
   {
     if( nbEnts[ aTypes[ i ] ] > 0 )
@@ -345,15 +369,21 @@ void SMESH_VisualObjDef::buildElemPrs()
         SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
        switch(aType){
        case SMDSAbs_Volume:{
+          aConnect.clear();
          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++) {
+
+            if ( const SMDS_PolyhedralVolumeOfNodes* ph =
+                 dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem))
+            {
+              aNbNodes = GetConnect(ph->uniqueNodesIterator(),aConnect);
+              anIdList->SetNumberOfIds( aNbNodes );
+            }
+           for (int k = 0; k < aNbNodes; k++)
              aConnectivities.push_back(k);
-           }
 
-         } else if (aNbNodes == 4) {
+          } else if (aNbNodes == 4) {
            static int anIds[] = {0,2,1,3};
            for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
 
@@ -380,7 +410,8 @@ void SMESH_VisualObjDef::buildElemPrs()
            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,2,1,3,5,4,8,7,6,11,10,9,12,14,13};
+            static int anIds[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
            for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
            //for (int k = 0; k < aNbNodes; k++) {
             //  int nn = aConnectivities[k];
@@ -395,6 +426,9 @@ void SMESH_VisualObjDef::buildElemPrs()
           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]);
@@ -414,6 +448,7 @@ void SMESH_VisualObjDef::buildElemPrs()
         iElem++;
       }
     }
+    SMDS_Mesh::CheckMemory(); // PAL16631
   }
 
   // Insert cells in grid
@@ -422,6 +457,8 @@ void SMESH_VisualObjDef::buildElemPrs()
   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 ) );
@@ -432,6 +469,8 @@ void SMESH_VisualObjDef::buildElemPrs()
   aCellTypesArray->Delete();
   aConnectivity->Delete();
   anIdList->Delete();
+
+  SMDS_Mesh::CheckMemory(); // PAL16631
 }
 
 //=================================================================================
@@ -456,7 +495,7 @@ bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
   if ( theEdgeNum < 0 || theEdgeNum > 3 || nbNodes != 3 && nbNodes != 4 || theEdgeNum > nbNodes )
     return false;
 
-  int anIds[ nbNodes ];
+  vector<int> anIds( nbNodes );
   SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
   int i = 0;
   while( anIter->more() )
@@ -506,11 +545,14 @@ SMESH_MeshObj::~SMESH_MeshObj()
 // 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
-  if ( myClient.Update(theIsClear) )
+  if ( myClient.Update(theIsClear) || GetUnstructuredGrid()->GetNumberOfPoints()==0) {
     buildPrs();  // Fill unstructured grid
+    return true;
+  }
+  return false;
 }
 
 //=================================================================================
@@ -665,10 +707,11 @@ 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 );
+  bool changed = myMeshObj->Update( theIsClear );
   buildPrs();
+  return changed;
 }
 
 
@@ -705,6 +748,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