Version: 6.3.1

src/OBJECT/SMESH_Object.cxx

Go to the documentation of this file.
00001 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  SMESH OBJECT : interactive object for SMESH visualization
00024 //  File   : SMESH_Grid.cxx
00025 //  Author : Nicolas REJNERI
00026 //  Module : SMESH
00027 //
00028 #include "SMESH_ObjectDef.h"
00029 #include "SMESH_ActorUtils.h"
00030 
00031 #include "SMDS_Mesh.hxx"
00032 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
00033 #include "SMESH_Actor.h"
00034 #include "SMESH_ControlsDef.hxx"
00035 #include "SalomeApp_Application.h"
00036 #include "VTKViewer_ExtractUnstructuredGrid.h"
00037 #include "VTKViewer_CellLocationsArray.h"
00038 
00039 #include CORBA_SERVER_HEADER(SMESH_Gen)
00040 #include CORBA_SERVER_HEADER(SALOME_Exception)
00041 
00042 #include <vtkCell.h>
00043 #include <vtkIdList.h>
00044 #include <vtkCellArray.h>
00045 #include <vtkUnsignedCharArray.h>
00046 
00047 #include <vtkUnstructuredGrid.h>
00048 
00049 #include <memory>
00050 #include <sstream>      
00051 #include <stdexcept>
00052 #include <set>
00053 
00054 #include "utilities.h"
00055 
00056 using namespace std;
00057 
00058 #ifndef EXCEPTION
00059 #define EXCEPTION(TYPE, MSG) {\
00060   std::ostringstream aStream;\
00061   aStream<<__FILE__<<"["<<__LINE__<<"]::"<<MSG;\
00062   throw TYPE(aStream.str());\
00063 }
00064 #endif
00065 
00066 #ifdef _DEBUG_
00067 static int MYDEBUG = 1;
00068 static int MYDEBUGWITHFILES = 0;//1;
00069 #else
00070 static int MYDEBUG = 0;
00071 static int MYDEBUGWITHFILES = 0;
00072 #endif
00073 
00074 
00075 /*
00076   Class       : SMESH_VisualObjDef
00077   Description : Base class for all mesh objects to be visuilised
00078 */
00079 
00080 //=================================================================================
00081 // function : getCellType
00082 // purpose  : Get type of VTK cell
00083 //=================================================================================
00084 static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
00085                                      const bool thePoly,
00086                                      const int theNbNodes )
00087 {
00088   switch( theType )
00089   {
00090     case SMDSAbs_0DElement: 
00091       return VTK_VERTEX;
00092 
00093     case SMDSAbs_Edge: 
00094       if( theNbNodes == 2 )         return VTK_LINE;
00095       else if ( theNbNodes == 3 )   return VTK_QUADRATIC_EDGE;
00096       else return VTK_EMPTY_CELL;
00097 
00098     case SMDSAbs_Face  :
00099       if (thePoly && theNbNodes>2 ) return VTK_POLYGON;
00100       else if ( theNbNodes == 3 )   return VTK_TRIANGLE;
00101       else if ( theNbNodes == 4 )   return VTK_QUAD;
00102       else if ( theNbNodes == 6 )   return VTK_QUADRATIC_TRIANGLE;
00103       else if ( theNbNodes == 8 )   return VTK_QUADRATIC_QUAD;
00104       else return VTK_EMPTY_CELL;
00105       
00106     case SMDSAbs_Volume:
00107       if (thePoly && theNbNodes>3 ) return VTK_POLYHEDRON; //VTK_CONVEX_POINT_SET;
00108       else if ( theNbNodes == 4 )   return VTK_TETRA;
00109       else if ( theNbNodes == 5 )   return VTK_PYRAMID;
00110       else if ( theNbNodes == 6 )   return VTK_WEDGE;
00111       else if ( theNbNodes == 8 )   return VTK_HEXAHEDRON;
00112       else if ( theNbNodes == 10 )  {
00113         return VTK_QUADRATIC_TETRA;
00114       }
00115       else if ( theNbNodes == 20 )  {
00116         return VTK_QUADRATIC_HEXAHEDRON;
00117       }
00118       else if ( theNbNodes == 15 )  {
00119         return VTK_QUADRATIC_WEDGE;
00120       }
00121       else if ( theNbNodes==13 )  {
00122         return VTK_QUADRATIC_PYRAMID; //VTK_CONVEX_POINT_SET;
00123       }
00124       else return VTK_EMPTY_CELL;
00125 
00126     default: return VTK_EMPTY_CELL;
00127   }
00128 }
00129 
00130 //=================================================================================
00131 // functions : SMESH_VisualObjDef
00132 // purpose   : Constructor
00133 //=================================================================================
00134 SMESH_VisualObjDef::SMESH_VisualObjDef()
00135 {
00136   MESSAGE("---------------------------------------------SMESH_VisualObjDef::SMESH_VisualObjDef");
00137   myGrid = vtkUnstructuredGrid::New();
00138   myLocalGrid = false;
00139 }
00140 SMESH_VisualObjDef::~SMESH_VisualObjDef()
00141 {
00142   MESSAGE("---------------------------------------------SMESH_VisualObjDef::~SMESH_VisualObjDef");
00143   //if ( MYDEBUG )
00144     MESSAGE( "~SMESH_MeshObj - myGrid->GetReferenceCount() = " << myGrid->GetReferenceCount() );
00145   myGrid->Delete();
00146 }
00147 
00148 //=================================================================================
00149 // functions : GetNodeObjId, GetNodeVTKId, GetElemObjId, GetElemVTKId
00150 // purpose   : Methods for retrieving VTK IDs by SMDS IDs and  vice versa
00151 //=================================================================================
00152 vtkIdType SMESH_VisualObjDef::GetNodeObjId( int theVTKID )
00153 {
00154         if (myLocalGrid)
00155         {
00156                 TMapOfIds::const_iterator i = myVTK2SMDSNodes.find(theVTKID);
00157                 return i == myVTK2SMDSNodes.end() ? -1 : i->second;
00158         }
00159   return this->GetMesh()->FindNodeVtk(theVTKID)->GetID();
00160 }
00161 
00162 vtkIdType SMESH_VisualObjDef::GetNodeVTKId( int theObjID )
00163 {
00164         if (myLocalGrid)
00165         {
00166                 TMapOfIds::const_iterator i = mySMDS2VTKNodes.find(theObjID);
00167     return i == mySMDS2VTKNodes.end() ? -1 : i->second;
00168         }
00169 
00170         const SMDS_MeshNode* aNode = 0;
00171         if( this->GetMesh() ) {
00172           aNode = this->GetMesh()->FindNode(theObjID);
00173         }
00174         return aNode ? aNode->getVtkId() : -1;
00175 }
00176 
00177 vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID )
00178 {
00179         if (myLocalGrid)
00180         {
00181                 TMapOfIds::const_iterator i = myVTK2SMDSElems.find(theVTKID);
00182                 return i == myVTK2SMDSElems.end() ? -1 : i->second;
00183         }
00184   return this->GetMesh()->fromVtkToSmds(theVTKID);
00185 }
00186 
00187 vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID )
00188 {
00189         if (myLocalGrid)
00190         {
00191                 TMapOfIds::const_iterator i = mySMDS2VTKElems.find(theObjID);
00192                 return i == mySMDS2VTKElems.end() ? -1 : i->second;
00193         }
00194   return this->GetMesh()->FindElement(theObjID)->getVtkId();
00195   //return this->GetMesh()->fromSmdsToVtk(theObjID);
00196 }
00197 
00198 //=================================================================================
00199 // function : SMESH_VisualObjDef::createPoints
00200 // purpose  : Create points from nodes
00201 //=================================================================================
00206 void SMESH_VisualObjDef::createPoints( vtkPoints* thePoints )
00207 {
00208   if ( thePoints == 0 )
00209     return;
00210 
00211   TEntityList aNodes;
00212   vtkIdType nbNodes = GetEntities( SMDSAbs_Node, aNodes );
00213   thePoints->SetNumberOfPoints( nbNodes );
00214 
00215   int nbPoints = 0;
00216 
00217   TEntityList::const_iterator anIter;
00218   for ( anIter = aNodes.begin(); anIter != aNodes.end(); ++anIter )
00219   {
00220     const SMDS_MeshNode* aNode = ( const SMDS_MeshNode* )(*anIter);
00221     if ( aNode != 0 )
00222     {
00223       thePoints->SetPoint( nbPoints, aNode->X(), aNode->Y(), aNode->Z() );
00224       int anId = aNode->GetID();
00225       mySMDS2VTKNodes.insert( TMapOfIds::value_type( anId, nbPoints ) );
00226       myVTK2SMDSNodes.insert( TMapOfIds::value_type( nbPoints, anId ) );
00227       nbPoints++;
00228     }
00229   }
00230 
00231   if ( nbPoints != nbNodes )
00232     thePoints->SetNumberOfPoints( nbPoints );
00233 }
00234 
00235 //=================================================================================
00236 // function : buildPrs
00237 // purpose  : create VTK cells( fill unstructured grid )
00238 //=================================================================================
00239 void SMESH_VisualObjDef::buildPrs(bool buildGrid)
00240 {
00241   MESSAGE("----------------------------------------------------------SMESH_VisualObjDef::buildPrs " << buildGrid);
00242   if (buildGrid)
00243   {
00244         myLocalGrid = true;
00245         try
00246         {
00247                 mySMDS2VTKNodes.clear();
00248                 myVTK2SMDSNodes.clear();
00249                 mySMDS2VTKElems.clear();
00250                 myVTK2SMDSElems.clear();
00251 
00252                 if ( IsNodePrs() )
00253                         buildNodePrs();
00254                 else
00255                         buildElemPrs();
00256         }
00257         catch(...)
00258         {
00259                 mySMDS2VTKNodes.clear();
00260                 myVTK2SMDSNodes.clear();
00261                 mySMDS2VTKElems.clear();
00262                 myVTK2SMDSElems.clear();
00263 
00264                 myGrid->SetPoints( 0 );
00265                 myGrid->SetCells( 0, 0, 0, 0, 0 );
00266                 throw;
00267         }
00268   }
00269   else
00270   {
00271         myLocalGrid = false;
00272         if (!GetMesh()->isCompacted())
00273           {
00274             MESSAGE("*** buildPrs ==> compactMesh!");
00275             GetMesh()->compactMesh();
00276           }
00277         vtkUnstructuredGrid *theGrid = GetMesh()->getGrid();
00278         myGrid->ShallowCopy(theGrid);
00279         //MESSAGE(myGrid->GetReferenceCount());
00280         //MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->GetNumberOfCells() );
00281         //MESSAGE( "Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints() );
00282         if( MYDEBUGWITHFILES ) SMESH::WriteUnstructuredGrid( myGrid,"buildPrs.vtu" );
00283   }
00284 }
00285 
00286 //=================================================================================
00287 // function : buildNodePrs
00288 // purpose  : create VTK cells for nodes
00289 //=================================================================================
00290 
00291 void SMESH_VisualObjDef::buildNodePrs()
00292 {
00293   // PAL16631: without swap, bad_alloc is not thrown but hung up and crash instead,
00294   // so check remaining memory size for safety
00295   SMDS_Mesh::CheckMemory(); // PAL16631
00296   vtkPoints* aPoints = vtkPoints::New();
00297   createPoints( aPoints );
00298   SMDS_Mesh::CheckMemory();
00299   myGrid->SetPoints( aPoints );
00300   aPoints->Delete();
00301 
00302   myGrid->SetCells( 0, 0, 0, 0, 0 );
00303 }
00304 
00305 //=================================================================================
00306 // function : buildElemPrs
00307 // purpose  : Create VTK cells for elements
00308 //=================================================================================
00309 
00310 namespace{
00311   typedef std::vector<const SMDS_MeshElement*> TConnect;
00312 
00313   int GetConnect(const SMDS_ElemIteratorPtr& theNodesIter, 
00314                  TConnect& theConnect)
00315   {
00316     theConnect.clear();
00317     for(; theNodesIter->more();)
00318       theConnect.push_back(theNodesIter->next());
00319     return theConnect.size();
00320   }
00321   
00322   inline 
00323   void SetId(vtkIdList *theIdList, 
00324              const SMESH_VisualObjDef::TMapOfIds& theSMDS2VTKNodes, 
00325              const TConnect& theConnect, 
00326              int thePosition,
00327              int theId)
00328   {
00329     theIdList->SetId(thePosition,theSMDS2VTKNodes.find(theConnect[theId]->GetID())->second);
00330   }
00331 
00332 }
00333 
00334 
00335 void SMESH_VisualObjDef::buildElemPrs()
00336 {
00337   // Create points
00338 
00339   vtkPoints* aPoints = vtkPoints::New();
00340   createPoints( aPoints );
00341   myGrid->SetPoints( aPoints );
00342   aPoints->Delete();
00343 
00344   if ( MYDEBUG )
00345     MESSAGE("Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints());
00346 
00347   // Calculate cells size
00348 
00349   static SMDSAbs_ElementType aTypes[ 4 ] =
00350     { SMDSAbs_0DElement, SMDSAbs_Edge, SMDSAbs_Face, SMDSAbs_Volume };
00351 
00352   // get entity data
00353   map<SMDSAbs_ElementType,int> nbEnts;
00354   map<SMDSAbs_ElementType,TEntityList> anEnts;
00355 
00356   for ( int i = 0; i <= 3; i++ )
00357     nbEnts[ aTypes[ i ] ] = GetEntities( aTypes[ i ], anEnts[ aTypes[ i ] ] );
00358 
00359   // PAL16631: without swap, bad_alloc is not thrown but hung up and crash instead,
00360   // so check remaining memory size for safety
00361   SMDS_Mesh::CheckMemory(); // PAL16631
00362 
00363   vtkIdType aCellsSize =  2 * nbEnts[ SMDSAbs_0DElement ] + 3 * nbEnts[ SMDSAbs_Edge ];
00364 
00365   for ( int i = 2; i <= 3; i++ ) // iterate through faces and volumes
00366   {
00367     if ( nbEnts[ aTypes[ i ] ] )
00368     {
00369       const TEntityList& aList = anEnts[ aTypes[ i ] ];
00370       TEntityList::const_iterator anIter;
00371       for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
00372         aCellsSize += (*anIter)->NbNodes() + 1;
00373     }
00374   }
00375 
00376   vtkIdType aNbCells = nbEnts[ SMDSAbs_0DElement ] + nbEnts[ SMDSAbs_Edge ] +
00377                        nbEnts[ SMDSAbs_Face ] + nbEnts[ SMDSAbs_Volume ];
00378 
00379   if ( MYDEBUG )
00380     MESSAGE( "Update - aNbCells = "<<aNbCells<<"; aCellsSize = "<<aCellsSize );
00381 
00382   // Create cells
00383 
00384   vtkCellArray* aConnectivity = vtkCellArray::New();
00385   aConnectivity->Allocate( aCellsSize, 0 );
00386 
00387   SMDS_Mesh::CheckMemory(); // PAL16631
00388 
00389   vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
00390   aCellTypesArray->SetNumberOfComponents( 1 );
00391   aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
00392 
00393   SMDS_Mesh::CheckMemory(); // PAL16631
00394 
00395   vtkIdList *anIdList = vtkIdList::New();
00396   vtkIdType iElem = 0;
00397 
00398   TConnect aConnect;
00399   aConnect.reserve(VTK_CELL_SIZE);
00400 
00401   SMDS_Mesh::CheckMemory(); // PAL16631
00402 
00403   for ( int i = 0; i <= 3; i++ ) // iterate through 0d elements, edges, faces and volumes
00404   {
00405     if ( nbEnts[ aTypes[ i ] ] > 0 )
00406     {
00407       const SMDSAbs_ElementType& aType = aTypes[ i ];
00408       const TEntityList& aList = anEnts[ aType ];
00409       TEntityList::const_iterator anIter;
00410       for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
00411       {
00412         const SMDS_MeshElement* anElem = *anIter;
00413 
00414         vtkIdType aNbNodes = anElem->NbNodes();
00415         anIdList->SetNumberOfIds( aNbNodes );
00416 
00417         int anId = anElem->GetID();
00418 
00419         mySMDS2VTKElems.insert( TMapOfIds::value_type( anId, iElem ) );
00420         myVTK2SMDSElems.insert( TMapOfIds::value_type( iElem, anId ) );
00421 
00422         SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
00423         switch (aType) {
00424         case SMDSAbs_Volume:{
00425           aConnect.clear();
00426           std::vector<int> aConnectivities;
00427           // Convertions connectivities from SMDS to VTK
00428           if (anElem->IsPoly() && aNbNodes > 3) { // POLYEDRE
00429 
00430             if ( const SMDS_VtkVolume* ph =
00431                  dynamic_cast<const SMDS_VtkVolume*> (anElem))
00432             {
00433               aNbNodes = GetConnect(ph->uniqueNodesIterator(),aConnect);
00434               anIdList->SetNumberOfIds( aNbNodes );
00435             }
00436             for (int k = 0; k < aNbNodes; k++)
00437               aConnectivities.push_back(k);
00438 
00439           } else if (aNbNodes == 4) {
00440             static int anIds[] = {0,2,1,3};
00441             for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
00442 
00443           } else if (aNbNodes == 5) {
00444             static int anIds[] = {0,3,2,1,4};
00445             for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
00446 
00447           } else if (aNbNodes == 6) {
00448             static int anIds[] = {0,1,2,3,4,5};
00449             for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
00450 
00451           }
00452           else if (aNbNodes == 8) {
00453             static int anIds[] = {0,3,2,1,4,7,6,5};
00454             for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
00455 
00456           }
00457           else if (aNbNodes == 10) {
00458             static int anIds[] = {0,2,1,3,6,5,4,7,9,8};
00459             for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
00460           }
00461           else if (aNbNodes == 13) {
00462             static int anIds[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
00463             for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
00464           }
00465           else if (aNbNodes == 15) {
00466             //static int anIds[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13};
00467             static int anIds[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
00468             for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
00469             //for (int k = 0; k < aNbNodes; k++) {
00470             //  int nn = aConnectivities[k];
00471             //  const SMDS_MeshNode* N = static_cast<const SMDS_MeshNode*> (aConnect[nn]);
00472             //  cout<<"k="<<k<<"  N("<<N->X()<<","<<N->Y()<<","<<N->Z()<<")"<<endl;
00473             //}
00474           }
00475           else if (aNbNodes == 20) {
00476             static int anIds[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
00477             for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
00478           }
00479           else {
00480           }
00481 
00482           if ( aConnect.empty() )
00483             GetConnect(aNodesIter,aConnect);
00484 
00485           if (aConnectivities.size() > 0) {
00486             for (vtkIdType aNodeId = 0; aNodeId < aNbNodes; aNodeId++)
00487               SetId(anIdList,mySMDS2VTKNodes,aConnect,aNodeId,aConnectivities[aNodeId]);
00488           }
00489           break;
00490         }
00491         default:
00492           for( vtkIdType aNodeId = 0; aNodesIter->more(); aNodeId++ ){
00493             const SMDS_MeshElement* aNode = aNodesIter->next();
00494             anIdList->SetId( aNodeId, mySMDS2VTKNodes[aNode->GetID()] );
00495           }
00496         }
00497 
00498         aConnectivity->InsertNextCell( anIdList );
00499         aCellTypesArray->InsertNextValue( getCellType( aType, anElem->IsPoly(), aNbNodes ) );
00500 
00501         iElem++;
00502       }
00503     }
00504     SMDS_Mesh::CheckMemory(); // PAL16631
00505   }
00506 
00507   // Insert cells in grid
00508 
00509   VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
00510   aCellLocationsArray->SetNumberOfComponents( 1 );
00511   aCellLocationsArray->SetNumberOfTuples( aNbCells );
00512 
00513   SMDS_Mesh::CheckMemory(); // PAL16631
00514 
00515   aConnectivity->InitTraversal();
00516   for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
00517     aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
00518 
00519   myGrid->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
00520 
00521   aCellLocationsArray->Delete();
00522   aCellTypesArray->Delete();
00523   aConnectivity->Delete();
00524   anIdList->Delete();
00525 
00526   SMDS_Mesh::CheckMemory(); // PAL16631
00527 }
00528 
00529 //=================================================================================
00530 // function : GetEdgeNodes
00531 // purpose  : Retrieve ids of nodes from edge of elements ( edge is numbered from 1 )
00532 //=================================================================================
00533 bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
00534                                        const int theEdgeNum,
00535                                        int&      theNodeId1,
00536                                        int&      theNodeId2 ) const
00537 {
00538   const SMDS_Mesh* aMesh = GetMesh();
00539   if ( aMesh == 0 )
00540     return false;
00541     
00542   const SMDS_MeshElement* anElem = aMesh->FindElement( theElemId );
00543   if ( anElem == 0 )
00544     return false;
00545     
00546   int nbNodes = anElem->NbNodes();
00547 
00548   if ( theEdgeNum < 0 || theEdgeNum > 3 || (nbNodes != 3 && nbNodes != 4) || theEdgeNum > nbNodes )
00549     return false;
00550 
00551   vector<int> anIds( nbNodes );
00552   SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
00553   int i = 0;
00554   while( anIter->more() )
00555     anIds[ i++ ] = anIter->next()->GetID();
00556 
00557   if ( theEdgeNum < nbNodes - 1 )
00558   {
00559     theNodeId1 = anIds[ theEdgeNum ];
00560     theNodeId2 = anIds[ theEdgeNum + 1 ];
00561   }
00562   else
00563   {
00564     theNodeId1 = anIds[ nbNodes - 1 ];
00565     theNodeId2 = anIds[ 0 ];
00566   }
00567 
00568   return true;
00569 }
00570 
00571 vtkUnstructuredGrid* SMESH_VisualObjDef::GetUnstructuredGrid()
00572 {
00573         //MESSAGE("SMESH_VisualObjDef::GetUnstructuredGrid " << myGrid);
00574         return myGrid;
00575 }
00576 
00577 
00578 //=================================================================================
00579 // function : IsValid
00580 // purpose  : Return true if there are some entities
00581 //=================================================================================
00582 bool SMESH_VisualObjDef::IsValid() const
00583 {
00584         //MESSAGE("SMESH_VisualObjDef::IsValid");
00585   return GetNbEntities(SMDSAbs_Node) > 0      || 
00586          GetNbEntities(SMDSAbs_0DElement) > 0 || 
00587          GetNbEntities(SMDSAbs_Edge) > 0      || 
00588          GetNbEntities(SMDSAbs_Face) > 0      ||
00589          GetNbEntities(SMDSAbs_Volume) > 0 ;
00590 }
00591 
00592 /*
00593   Class       : SMESH_MeshObj
00594   Description : Class for visualisation of mesh
00595 */
00596 
00597 //=================================================================================
00598 // function : SMESH_MeshObj
00599 // purpose  : Constructor
00600 //=================================================================================
00601 SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh):
00602   myClient(SalomeApp_Application::orb(),theMesh)
00603 {
00604         myEmptyGrid = 0;
00605   if ( MYDEBUG ) 
00606     MESSAGE("SMESH_MeshObj - this = "<<this<<"; theMesh->_is_nil() = "<<theMesh->_is_nil());
00607 }
00608 
00609 //=================================================================================
00610 // function : ~SMESH_MeshObj
00611 // purpose  : Destructor
00612 //=================================================================================
00613 SMESH_MeshObj::~SMESH_MeshObj()
00614 {
00615   if ( MYDEBUG ) 
00616     MESSAGE("SMESH_MeshObj - this = "<<this<<"\n");
00617 }
00618 
00619 //=================================================================================
00620 // function : Update
00621 // purpose  : Update mesh and fill grid with new values if necessary 
00622 //=================================================================================
00623 bool SMESH_MeshObj::Update( int theIsClear )
00624 {
00625   // Update SMDS_Mesh on client part
00626   MESSAGE("SMESH_MeshObj::Update " << this);
00627   if ( myClient.Update(theIsClear) || GetUnstructuredGrid()->GetNumberOfPoints()==0) {
00628     MESSAGE("buildPrs");
00629     buildPrs();  // Fill unstructured grid
00630     return true;
00631   }
00632   return false;
00633 }
00634 
00635 bool SMESH_MeshObj::NulData()
00636 {
00637         MESSAGE ("SMESH_MeshObj::NulData() ==================================================================================");
00638         if (!myEmptyGrid)
00639         {
00640           myEmptyGrid = SMDS_UnstructuredGrid::New();
00641           myEmptyGrid->Initialize();
00642           myEmptyGrid->Allocate();
00643           vtkPoints* points = vtkPoints::New();
00644           points->SetNumberOfPoints(0);
00645           myEmptyGrid->SetPoints( points );
00646           points->Delete();
00647           myEmptyGrid->BuildLinks();
00648         }
00649         myGrid->ShallowCopy(myEmptyGrid);
00650         return true;
00651 }
00652 //=================================================================================
00653 // function : GetElemDimension
00654 // purpose  : Get dimension of element
00655 //=================================================================================
00656 int SMESH_MeshObj::GetElemDimension( const int theObjId )
00657 {
00658   const SMDS_MeshElement* anElem = myClient->FindElement( theObjId );
00659   if ( anElem == 0 )
00660     return 0;
00661 
00662   int aType = anElem->GetType();
00663   switch ( aType )
00664   {
00665     case SMDSAbs_0DElement : return 0;
00666     case SMDSAbs_Edge  : return 1;
00667     case SMDSAbs_Face  : return 2;
00668     case SMDSAbs_Volume: return 3;
00669     default            : return 0;
00670   }
00671 }
00672 
00673 //=================================================================================
00674 // function : GetEntities
00675 // purpose  : Get entities of specified type. Return number of entities
00676 //=================================================================================
00677 int SMESH_MeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const
00678 {
00679   switch ( theType )
00680   {
00681     case SMDSAbs_Node:
00682     {
00683       return myClient->NbNodes();
00684     }
00685     break;
00686     case SMDSAbs_0DElement:
00687     {
00688       return myClient->Nb0DElements();
00689     }
00690     break;
00691     case SMDSAbs_Edge:
00692     {
00693       return myClient->NbEdges();
00694     }
00695     break;
00696     case SMDSAbs_Face:
00697     {
00698       return myClient->NbFaces();
00699     }
00700     break;
00701     case SMDSAbs_Volume:
00702     {
00703       return myClient->NbVolumes();
00704     }
00705     break;
00706     default:
00707       return 0;
00708     break;
00709   }
00710 }
00711 
00712 int SMESH_MeshObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& theObjs ) const
00713 {
00714   theObjs.clear();
00715 
00716   switch ( theType )
00717   {
00718     case SMDSAbs_Node:
00719     {
00720       SMDS_NodeIteratorPtr anIter = myClient->nodesIterator();
00721       while ( anIter->more() ) theObjs.push_back( anIter->next() );
00722     }
00723     break;
00724     case SMDSAbs_0DElement:
00725     {
00726       SMDS_0DElementIteratorPtr anIter = myClient->elements0dIterator();
00727       while ( anIter->more() ) theObjs.push_back( anIter->next() );
00728     }
00729     break;
00730     case SMDSAbs_Edge:
00731     {
00732       SMDS_EdgeIteratorPtr anIter = myClient->edgesIterator();
00733       while ( anIter->more() ) theObjs.push_back( anIter->next() );
00734     }
00735     break;
00736     case SMDSAbs_Face:
00737     {
00738       SMDS_FaceIteratorPtr anIter = myClient->facesIterator();
00739       while ( anIter->more() ) theObjs.push_back( anIter->next() );
00740     }
00741     break;
00742     case SMDSAbs_Volume:
00743     {
00744       SMDS_VolumeIteratorPtr anIter = myClient->volumesIterator();
00745       while ( anIter->more() ) theObjs.push_back( anIter->next() );
00746     }
00747     break;
00748     default:
00749     break;
00750   }
00751 
00752   return theObjs.size();
00753 }
00754 
00755 //=================================================================================
00756 // function : UpdateFunctor
00757 // purpose  : Update functor in accordance with current mesh
00758 //=================================================================================
00759 void SMESH_MeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor )
00760 {
00761   theFunctor->SetMesh( GetMesh() );
00762 }
00763 
00764 //=================================================================================
00765 // function : IsNodePrs
00766 // purpose  : Return true if node presentation is used
00767 //=================================================================================
00768 bool SMESH_MeshObj::IsNodePrs() const
00769 {
00770   return myClient->Nb0DElements() == 0 && myClient->NbEdges() == 0 && myClient->NbFaces() == 0 && myClient->NbVolumes() == 0 ;
00771 }
00772 
00773 
00774 /*
00775   Class       : SMESH_SubMeshObj
00776   Description : Base class for visualisation of submeshes and groups
00777 */
00778 
00779 //=================================================================================
00780 // function : SMESH_SubMeshObj
00781 // purpose  : Constructor
00782 //=================================================================================
00783 SMESH_SubMeshObj::SMESH_SubMeshObj( SMESH_MeshObj* theMeshObj )
00784 {
00785   if ( MYDEBUG ) MESSAGE( "SMESH_SubMeshObj - theMeshObj = " << theMeshObj );
00786   
00787   myMeshObj = theMeshObj;
00788 }
00789 
00790 SMESH_SubMeshObj::~SMESH_SubMeshObj()
00791 {
00792 }
00793 
00794 //=================================================================================
00795 // function : GetElemDimension
00796 // purpose  : Get dimension of element
00797 //=================================================================================
00798 int SMESH_SubMeshObj::GetElemDimension( const int theObjId )
00799 {
00800   return myMeshObj == 0 ? 0 : myMeshObj->GetElemDimension( theObjId );
00801 }
00802 
00803 //=================================================================================
00804 // function : UpdateFunctor
00805 // purpose  : Update functor in accordance with current mesh
00806 //=================================================================================
00807 void SMESH_SubMeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor )
00808 {
00809   theFunctor->SetMesh( myMeshObj->GetMesh() );
00810 }
00811 
00812 //=================================================================================
00813 // function : Update
00814 // purpose  : Update mesh object and fill grid with new values 
00815 //=================================================================================
00816 bool SMESH_SubMeshObj::Update( int theIsClear )
00817 {
00818         MESSAGE("SMESH_SubMeshObj::Update " << this)
00819   bool changed = myMeshObj->Update( theIsClear );
00820   buildPrs(true);
00821   return changed;
00822 }
00823 
00824 
00825 /*
00826   Class       : SMESH_GroupObj
00827   Description : Class for visualisation of groups
00828 */
00829 
00830 //=================================================================================
00831 // function : SMESH_GroupObj
00832 // purpose  : Constructor
00833 //=================================================================================
00834 SMESH_GroupObj::SMESH_GroupObj( SMESH::SMESH_GroupBase_ptr theGroup, 
00835                                 SMESH_MeshObj*             theMeshObj )
00836 : SMESH_SubMeshObj( theMeshObj ),
00837   myGroupServer( SMESH::SMESH_GroupBase::_duplicate(theGroup) )
00838 {
00839   if ( MYDEBUG ) MESSAGE("SMESH_GroupObj - theGroup->_is_nil() = "<<theGroup->_is_nil());
00840   myGroupServer->Register();
00841 }
00842 
00843 SMESH_GroupObj::~SMESH_GroupObj()
00844 {
00845   if ( MYDEBUG ) MESSAGE("~SMESH_GroupObj");
00846   myGroupServer->UnRegister();
00847 }
00848 
00849 //=================================================================================
00850 // function : IsNodePrs
00851 // purpose  : Return true if node presentation is used
00852 //=================================================================================
00853 bool SMESH_GroupObj::IsNodePrs() const
00854 {
00855   return myGroupServer->GetType() == SMESH::NODE;
00856 }
00857 
00858 //=================================================================================
00859 // function : GetElementType
00860 // purpose  : Return type of elements of group
00861 //=================================================================================
00862 SMDSAbs_ElementType SMESH_GroupObj::GetElementType() const
00863 {
00864   return SMDSAbs_ElementType(myGroupServer->GetType());
00865 }
00866 
00867 //=================================================================================
00868 // function : getNodesFromElems
00869 // purpose  : Retrieve nodes from elements
00870 //=================================================================================
00871 static int getNodesFromElems( SMESH::long_array_var&              theElemIds,
00872                               const SMDS_Mesh*                    theMesh,
00873                               std::list<const SMDS_MeshElement*>& theResList )
00874 {
00875   set<const SMDS_MeshElement*> aNodeSet;
00876 
00877   for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ )
00878   {
00879     const SMDS_MeshElement* anElem = theMesh->FindElement( theElemIds[ i ] );
00880     if ( anElem != 0 )
00881     {
00882       SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
00883       while ( anIter->more() )
00884       {
00885         const SMDS_MeshElement* aNode = anIter->next();
00886         if ( aNode != 0 )
00887           aNodeSet.insert( aNode );
00888       }
00889     }
00890   }
00891 
00892   set<const SMDS_MeshElement*>::const_iterator anIter;
00893   for ( anIter = aNodeSet.begin(); anIter != aNodeSet.end(); ++anIter )
00894     theResList.push_back( *anIter );
00895 
00896   return theResList.size();    
00897 }
00898 
00899 //=================================================================================
00900 // function : getPointers
00901 // purpose  : Get std::list<const SMDS_MeshElement*> from list of IDs
00902 //=================================================================================
00903 static int getPointers( const SMDSAbs_ElementType            theRequestType,
00904                         SMESH::long_array_var&              theElemIds,
00905                         const SMDS_Mesh*                    theMesh,
00906                         std::list<const SMDS_MeshElement*>& theResList )
00907 {
00908   for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ )
00909   {
00910     const SMDS_MeshElement* anElem = theRequestType == SMDSAbs_Node
00911       ? theMesh->FindNode( theElemIds[ i ] ) : theMesh->FindElement( theElemIds[ i ] );
00912 
00913     if ( anElem != 0 )
00914       theResList.push_back( anElem );
00915   }
00916 
00917   return theResList.size();
00918 }
00919 
00920 
00921 //=================================================================================
00922 // function : GetEntities
00923 // purpose  : Get entities of specified type. Return number of entities
00924 //=================================================================================
00925 int SMESH_GroupObj::GetNbEntities( const SMDSAbs_ElementType theType) const
00926 {
00927   if(SMDSAbs_ElementType(myGroupServer->GetType()) == theType){
00928     return myGroupServer->Size();
00929   }
00930   return 0;
00931 }
00932 
00933 int SMESH_GroupObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& theResList ) const
00934 {
00935   theResList.clear();
00936   SMDS_Mesh* aMesh = myMeshObj->GetMesh();
00937   
00938   if ( myGroupServer->Size() == 0 || aMesh == 0 )
00939     return 0;
00940 
00941   SMDSAbs_ElementType aGrpType = SMDSAbs_ElementType(myGroupServer->GetType());
00942   SMESH::long_array_var anIds = myGroupServer->GetListOfID();
00943 
00944   if ( aGrpType == theType )
00945     return getPointers( theType, anIds, aMesh, theResList );
00946   else if ( theType == SMDSAbs_Node )
00947     return getNodesFromElems( anIds, aMesh, theResList );
00948   else
00949     return 0;
00950 }    
00951 
00952 
00953 
00954 /*
00955   Class       : SMESH_subMeshObj
00956   Description : Class for visualisation of submeshes
00957 */
00958 
00959 //=================================================================================
00960 // function : SMESH_subMeshObj
00961 // purpose  : Constructor
00962 //=================================================================================
00963 SMESH_subMeshObj::SMESH_subMeshObj( SMESH::SMESH_subMesh_ptr theSubMesh,
00964                                     SMESH_MeshObj*           theMeshObj )
00965 : SMESH_SubMeshObj( theMeshObj ),
00966   mySubMeshServer( SMESH::SMESH_subMesh::_duplicate( theSubMesh ) )
00967 {
00968   if ( MYDEBUG ) MESSAGE( "SMESH_subMeshObj - theSubMesh->_is_nil() = " << theSubMesh->_is_nil() );
00969   
00970   mySubMeshServer->Register();
00971 }
00972 
00973 SMESH_subMeshObj::~SMESH_subMeshObj()
00974 {
00975   if ( MYDEBUG ) MESSAGE( "~SMESH_subMeshObj" );
00976   mySubMeshServer->UnRegister();
00977 }
00978 
00979 //=================================================================================
00980 // function : GetEntities
00981 // purpose  : Get entities of specified type. Return number of entities
00982 //=================================================================================
00983 int SMESH_subMeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const
00984 {
00985   switch ( theType )
00986   {
00987     case SMDSAbs_Node:
00988     {
00989       return mySubMeshServer->GetNumberOfNodes( false );
00990     }
00991     break;
00992     case SMDSAbs_0DElement:
00993     case SMDSAbs_Edge:
00994     case SMDSAbs_Face:
00995     case SMDSAbs_Volume:
00996     {
00997       SMESH::long_array_var anIds = 
00998         mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
00999       return anIds->length();
01000     }
01001     default:
01002       return 0;
01003     break;
01004   }
01005 }
01006 
01007 int SMESH_subMeshObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& theResList ) const
01008 {
01009   theResList.clear();
01010 
01011   SMDS_Mesh* aMesh = myMeshObj->GetMesh();
01012   if ( aMesh == 0 )
01013     return 0;
01014 
01015   bool isNodal = IsNodePrs();
01016 
01017   if ( isNodal )
01018   {
01019     if ( theType == SMDSAbs_Node )
01020     {
01021       SMESH::long_array_var anIds = mySubMeshServer->GetNodesId();
01022       return getPointers( SMDSAbs_Node, anIds, aMesh, theResList );
01023     }
01024   }
01025   else
01026   {
01027     if ( theType == SMDSAbs_Node )
01028     {
01029       SMESH::long_array_var anIds = mySubMeshServer->GetElementsId();
01030       return getNodesFromElems( anIds, aMesh, theResList );
01031     }
01032     else
01033     {
01034       SMESH::long_array_var anIds = 
01035         mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
01036       return getPointers( theType, anIds, aMesh, theResList );
01037     }
01038   }
01039 
01040   return 0;
01041 }
01042 
01043 //=================================================================================
01044 // function : IsNodePrs
01045 // purpose  : Return true if node presentation is used
01046 //=================================================================================
01047 bool SMESH_subMeshObj::IsNodePrs() const
01048 {
01049   return mySubMeshServer->GetNumberOfElements() == 0;
01050 }
Copyright © 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS