1 // SMESH OBJECT : interactive object for SMESH visualization
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : SMESH_Grid.cxx
25 // Author : Nicolas REJNERI
28 #include "SMESH_Object.h"
29 #include "SMDS_Mesh.hxx"
30 #include "SALOME_ExtractUnstructuredGrid.h"
31 #include "SMESH_Actor.h"
33 #include CORBA_SERVER_HEADER(SALOME_Exception)
35 #include <vtkUnstructuredGrid.h>
36 #include <vtkUnstructuredGridWriter.h>
37 #include <vtkUnstructuredGridReader.h>
44 #include "utilities.h"
49 #define EXCEPTION(TYPE, MSG) {\
50 std::ostringstream aStream;\
51 aStream<<__FILE__<<"["<<__LINE__<<"]::"<<MSG;\
52 throw TYPE(aStream.str());\
57 static int MYDEBUG = 1;
58 static int MYDEBUGWITHFILES = 0;
60 static int MYDEBUG = 0;
61 static int MYDEBUGWITHFILES = 0;
65 void WriteUnstructuredGrid(vtkUnstructuredGrid* theGrid, const char* theFileName){
66 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
67 aWriter->SetFileName(theFileName);
68 aWriter->SetInput(theGrid);
76 inline const SMDS_MeshNode* FindNode(const SMDS_Mesh* theMesh, int theId){
77 if(const SMDS_MeshNode* anElem = theMesh->FindNode(theId)) return anElem;
78 EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
82 inline const SMDS_MeshElement* FindElement(const SMDS_Mesh* theMesh, int theId){
83 if(const SMDS_MeshElement* anElem = theMesh->FindElement(theId)) return anElem;
84 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot find a SMDS_MeshElement for ID = "<<theId);
88 inline void AddNodesWithID(SMDS_Mesh* theMesh,
89 SMESH::log_array_var& theSeq,
92 const SMESH::double_array& aCoords = theSeq[theId].coords;
93 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
94 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
95 if(3*aNbElems != aCoords.length())
96 EXCEPTION(runtime_error,"AddNodesWithID - 3*aNbElems != aCoords.length()");
97 for(CORBA::Long aCoordId = 0; anElemId < aNbElems; anElemId++, aCoordId+=3){
98 SMDS_MeshElement* anElem = theMesh->AddNodeWithID(aCoords[aCoordId],
101 anIndexes[anElemId]);
103 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddNodeWithID for ID = "<<anElemId);
108 inline void AddEdgesWithID(SMDS_Mesh* theMesh,
109 SMESH::log_array_var& theSeq,
112 const SMESH::double_array& aCoords = theSeq[theId].coords;
113 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
114 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
115 if(3*aNbElems != anIndexes.length())
116 EXCEPTION(runtime_error,"AddEdgeWithID - 3*aNbElems != aCoords.length()");
117 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=3){
118 SMDS_MeshElement* anElem = theMesh->AddEdgeWithID(anIndexes[anIndexId+1],
119 anIndexes[anIndexId+2],
120 anIndexes[anIndexId]);
122 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<<anElemId);
127 inline void AddTriasWithID(SMDS_Mesh* theMesh,
128 SMESH::log_array_var& theSeq,
131 const SMESH::double_array& aCoords = theSeq[theId].coords;
132 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
133 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
134 if(4*aNbElems != anIndexes.length())
135 EXCEPTION(runtime_error,"AddEdgeWithID - 4*aNbElems != anIndexes.length()");
136 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=4){
137 SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
138 anIndexes[anIndexId+2],
139 anIndexes[anIndexId+3],
140 anIndexes[anIndexId]);
142 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
147 inline void AddQuadsWithID(SMDS_Mesh* theMesh,
148 SMESH::log_array_var theSeq,
151 const SMESH::double_array& aCoords = theSeq[theId].coords;
152 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
153 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
154 if(5*aNbElems != anIndexes.length())
155 EXCEPTION(runtime_error,"AddEdgeWithID - 4*aNbElems != anIndexes.length()");
156 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){
157 SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
158 anIndexes[anIndexId+2],
159 anIndexes[anIndexId+3],
160 anIndexes[anIndexId+4],
161 anIndexes[anIndexId]);
163 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
168 inline void AddTetrasWithID(SMDS_Mesh* theMesh,
169 SMESH::log_array_var& theSeq,
172 const SMESH::double_array& aCoords = theSeq[theId].coords;
173 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
174 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
175 if(5*aNbElems != anIndexes.length())
176 EXCEPTION(runtime_error,"AddEdgeWithID - 5*aNbElems != anIndexes.length()");
177 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){
178 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
179 anIndexes[anIndexId+2],
180 anIndexes[anIndexId+3],
181 anIndexes[anIndexId+4],
182 anIndexes[anIndexId]);
184 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
189 inline void AddPiramidsWithID(SMDS_Mesh* theMesh,
190 SMESH::log_array_var& theSeq,
193 const SMESH::double_array& aCoords = theSeq[theId].coords;
194 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
195 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
196 if(6*aNbElems != anIndexes.length())
197 EXCEPTION(runtime_error,"AddEdgeWithID - 6*aNbElems != anIndexes.length()");
198 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=6){
199 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
200 anIndexes[anIndexId+2],
201 anIndexes[anIndexId+3],
202 anIndexes[anIndexId+4],
203 anIndexes[anIndexId+5],
204 anIndexes[anIndexId]);
206 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
211 inline void AddPrismsWithID(SMDS_Mesh* theMesh,
212 SMESH::log_array_var& theSeq,
215 const SMESH::double_array& aCoords = theSeq[theId].coords;
216 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
217 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
218 if(7*aNbElems != anIndexes.length())
219 EXCEPTION(runtime_error,"AddEdgeWithID - 7*aNbElems != anIndexes.length()");
220 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=7){
221 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
222 anIndexes[anIndexId+2],
223 anIndexes[anIndexId+3],
224 anIndexes[anIndexId+4],
225 anIndexes[anIndexId+5],
226 anIndexes[anIndexId+6],
227 anIndexes[anIndexId]);
229 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
234 inline void AddHexasWithID(SMDS_Mesh* theMesh,
235 SMESH::log_array_var& theSeq,
238 const SMESH::double_array& aCoords = theSeq[theId].coords;
239 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
240 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
241 if(9*aNbElems != anIndexes.length())
242 EXCEPTION(runtime_error,"AddEdgeWithID - 9*aNbElems != anIndexes.length()");
243 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=9){
244 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
245 anIndexes[anIndexId+2],
246 anIndexes[anIndexId+3],
247 anIndexes[anIndexId+4],
248 anIndexes[anIndexId+5],
249 anIndexes[anIndexId+6],
250 anIndexes[anIndexId+7],
251 anIndexes[anIndexId+8],
252 anIndexes[anIndexId]);
254 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
261 Class : SMESH_VisualObj
262 Description : Base class for all mesh objects to be visuilised
265 //=================================================================================
266 // function : getCellType
267 // purpose : Get type of VTK cell
268 //=================================================================================
269 static inline vtkIdType getCellType( const SMESH::ElementType theType,
270 const int theNbNodes )
274 case SMESH::EDGE: return theNbNodes == 2 ? VTK_LINE : VTK_EMPTY_CELL;
276 case SMESH::FACE : if ( theNbNodes == 3 ) return VTK_TRIANGLE;
277 else if ( theNbNodes == 4 ) return VTK_QUAD;
278 else return VTK_EMPTY_CELL;
280 case SMESH::VOLUME: if ( theNbNodes == 4 ) return VTK_TETRA;
281 else if ( theNbNodes == 5 ) return VTK_PYRAMID;
282 else if ( theNbNodes == 6 ) return VTK_WEDGE;
283 else if ( theNbNodes == 8 ) return VTK_HEXAHEDRON;
284 else return VTK_EMPTY_CELL;
286 default: return VTK_EMPTY_CELL;
290 //=================================================================================
291 // functions : SMESH_VisualObj
292 // purpose : Constructor
293 //=================================================================================
294 SMESH_VisualObj::SMESH_VisualObj()
296 myGrid = vtkUnstructuredGrid::New();
298 SMESH_VisualObj::~SMESH_VisualObj()
301 MESSAGE( "~SMESH_MeshObj - myGrid->GetReferenceCount() = " << myGrid->GetReferenceCount() );
305 //=================================================================================
306 // functions : GetNodeObjId, GetNodeVTKId, GetElemObjId, GetElemVTKId
307 // purpose : Methods for retrieving VTK IDs by SMDS IDs and vice versa
308 //=================================================================================
309 vtkIdType SMESH_VisualObj::GetNodeObjId( int theVTKID )
311 return myVTK2SMDSNodes.find(theVTKID) == myVTK2SMDSNodes.end() ? -1 : myVTK2SMDSNodes[theVTKID];
314 vtkIdType SMESH_VisualObj::GetNodeVTKId( int theObjID )
316 return mySMDS2VTKNodes.find(theObjID) == mySMDS2VTKNodes.end() ? -1 : mySMDS2VTKNodes[theObjID];
319 vtkIdType SMESH_VisualObj::GetElemObjId( int theVTKID )
321 return myVTK2SMDSElems.find(theVTKID) == myVTK2SMDSElems.end() ? -1 : myVTK2SMDSElems[theVTKID];
324 vtkIdType SMESH_VisualObj::GetElemVTKId( int theObjID )
326 return mySMDS2VTKElems.find(theObjID) == mySMDS2VTKElems.end() ? -1 : mySMDS2VTKElems[theObjID];
329 //=================================================================================
330 // function : SMESH_VisualObj::createPoints
331 // purpose : Create points from nodes
332 //=================================================================================
333 void SMESH_VisualObj::createPoints( vtkPoints* thePoints )
335 if ( thePoints == 0 )
339 vtkIdType nbNodes = GetEntities( SMESH::NODE, aNodes );
340 thePoints->SetNumberOfPoints( nbNodes );
344 TEntityList::const_iterator anIter;
345 for ( anIter = aNodes.begin(); anIter != aNodes.end(); ++anIter )
347 const SMDS_MeshNode* aNode = ( const SMDS_MeshNode* )(*anIter);
350 thePoints->SetPoint( nbPoints, aNode->X(), aNode->Y(), aNode->Z() );
351 int anId = aNode->GetID();
352 mySMDS2VTKNodes.insert( TMapOfIds::value_type( anId, nbPoints ) );
353 myVTK2SMDSNodes.insert( TMapOfIds::value_type( nbPoints, anId ) );
358 if ( nbPoints != nbNodes )
359 thePoints->SetNumberOfPoints( nbPoints );
362 //=================================================================================
363 // function : buildPrs
364 // purpose : create VTK cells( fill unstructured grid )
365 //=================================================================================
366 void SMESH_VisualObj::buildPrs()
370 mySMDS2VTKNodes.clear();
371 myVTK2SMDSNodes.clear();
372 mySMDS2VTKElems.clear();
373 myVTK2SMDSElems.clear();
380 catch( const std::exception& exc )
382 INFOS("Follow exception was cought:\n\t"<<exc.what());
386 INFOS("Unknown exception was cought !!!");
389 if( MYDEBUG ) MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->GetNumberOfCells() );
390 if( MYDEBUGWITHFILES ) WriteUnstructuredGrid( myGrid,"/tmp/buildPrs" );
393 //=================================================================================
394 // function : buildNodePrs
395 // purpose : create VTK cells for nodes
396 //=================================================================================
397 void SMESH_VisualObj::buildNodePrs()
399 vtkPoints* aPoints = vtkPoints::New();
400 createPoints( aPoints );
401 int nbPoints = aPoints->GetNumberOfPoints();
402 myGrid->SetPoints( aPoints );
405 myGrid->SetCells( 0, 0, 0 );
409 /*vtkIdList *anIdList = vtkIdList::New();
410 anIdList->SetNumberOfIds( 1 );
412 vtkCellArray *aCells = vtkCellArray::New();
413 aCells->Allocate( 2 * nbPoints, 0 );
415 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
416 aCellTypesArray->SetNumberOfComponents( 1 );
417 aCellTypesArray->Allocate( nbPoints );
419 for( vtkIdType aCellId = 0; aCellId < nbPoints; aCellId++ )
421 anIdList->SetId( 0, aCellId );
422 aCells->InsertNextCell( anIdList );
423 aCellTypesArray->InsertNextValue( VTK_VERTEX );
426 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
427 aCellLocationsArray->SetNumberOfComponents( 1 );
428 aCellLocationsArray->SetNumberOfTuples( nbPoints );
430 aCells->InitTraversal();
431 for( vtkIdType i = 0, *pts, npts; aCells->GetNextCell( npts, pts ); i++ )
432 aCellLocationsArray->SetValue( i, aCells->GetTraversalLocation( npts ) );
434 myGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells );
436 aCellLocationsArray->Delete();
437 aCellTypesArray->Delete();
439 anIdList->Delete(); */
442 //=================================================================================
443 // function : buildElemPrs
444 // purpose : Create VTK cells for elements
445 //=================================================================================
446 void SMESH_VisualObj::buildElemPrs()
450 vtkPoints* aPoints = vtkPoints::New();
451 createPoints( aPoints );
452 myGrid->SetPoints( aPoints );
456 MESSAGE("Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints());
458 // Calculate cells size
460 static SMESH::ElementType aTypes[ 3 ] = { SMESH::EDGE, SMESH::FACE, SMESH::VOLUME };
463 map< int, int > nbEnts;
464 map< int, TEntityList > anEnts;
466 for ( int i = 0; i <= 2; i++ )
467 nbEnts[ aTypes[ i ] ] = GetEntities( aTypes[ i ], anEnts[ aTypes[ i ] ] );
469 vtkIdType aCellsSize = 3 * nbEnts[ SMESH::EDGE ];
471 for ( int i = 1; i <= 2; i++ ) // iterate through faces and volumes
473 if ( nbEnts[ aTypes[ i ] ] )
475 const TEntityList& aList = anEnts[ aTypes[ i ] ];
476 TEntityList::const_iterator anIter;
477 for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
478 aCellsSize += (*anIter)->NbNodes() + 1;
482 vtkIdType aNbCells = nbEnts[ SMESH::EDGE ] + nbEnts[ SMESH::FACE ] + nbEnts[ SMESH::VOLUME ];
485 MESSAGE( "Update - aNbCells = "<<aNbCells<<"; aCellsSize = "<<aCellsSize );
489 vtkCellArray* aConnectivity = vtkCellArray::New();
490 aConnectivity->Allocate( aCellsSize, 0 );
492 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
493 aCellTypesArray->SetNumberOfComponents( 1 );
494 aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
496 vtkIdList *anIdList = vtkIdList::New();
499 for ( int i = 0; i <= 2; i++ ) // iterate through edges, faces and volumes
501 if( nbEnts[ aTypes[ i ] ] > 0 )
503 const TEntityList& aList = anEnts[ aTypes[ i ] ];
504 TEntityList::const_iterator anIter;
505 for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
507 const SMDS_MeshElement* anElem = *anIter;
509 vtkIdType aNbNodes = anElem->NbNodes();
510 anIdList->SetNumberOfIds( aNbNodes );
512 int anId = anElem->GetID();
514 mySMDS2VTKElems.insert( TMapOfIds::value_type( anId, iElem ) );
515 myVTK2SMDSElems.insert( TMapOfIds::value_type( iElem, anId ) );
517 SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
518 for( vtkIdType aNodeId = 0; aNodesIter->more(); aNodeId++ )
520 const SMDS_MeshElement* aNode = aNodesIter->next();
521 anIdList->SetId( aNodeId, mySMDS2VTKNodes[aNode->GetID()] );
524 aConnectivity->InsertNextCell( anIdList );
525 aCellTypesArray->InsertNextValue( getCellType( aTypes[ i ], aNbNodes ) );
532 // Insert cells in grid
534 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
535 aCellLocationsArray->SetNumberOfComponents( 1 );
536 aCellLocationsArray->SetNumberOfTuples( aNbCells );
538 aConnectivity->InitTraversal();
539 for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
540 aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
542 myGrid->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
544 aCellLocationsArray->Delete();
545 aCellTypesArray->Delete();
546 aConnectivity->Delete();
551 Class : SMESH_MeshObj
552 Description : Class for visualisation of mesh
555 //=================================================================================
556 // function : SMESH_MeshObj
557 // purpose : Constructor
558 //=================================================================================
559 SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh)
562 MESSAGE("SMESH_MeshObj - theMesh->_is_nil() = "<<theMesh->_is_nil());
564 myMeshServer = SMESH::SMESH_Mesh::_duplicate( theMesh );
565 myMeshServer->Register();
566 myMesh = new SMDS_Mesh();
569 //=================================================================================
570 // function : ~SMESH_MeshObj
571 // purpose : Destructor
572 //=================================================================================
573 SMESH_MeshObj::~SMESH_MeshObj()
575 myMeshServer->Destroy();
579 //=================================================================================
581 // purpose : Update mesh and fill grid with new values if necessary
582 //=================================================================================
583 void SMESH_MeshObj::Update( int theIsClear )
585 // Update SMDS_Mesh on client part
589 SMESH::log_array_var aSeq = myMeshServer->GetLog( theIsClear );
590 CORBA::Long aLength = aSeq->length();
592 if( MYDEBUG ) MESSAGE( "Update: length of the script is "<<aLength );
597 for ( CORBA::Long anId = 0; anId < aLength; anId++)
599 const SMESH::double_array& aCoords = aSeq[anId].coords;
600 const SMESH::long_array& anIndexes = aSeq[anId].indexes;
601 CORBA::Long anElemId = 0, aNbElems = aSeq[anId].number;
602 SMDS_MeshElement* anElem = NULL;
603 CORBA::Long aCommand = aSeq[anId].commandType;
607 case SMESH::ADD_NODE : AddNodesWithID ( myMesh, aSeq, anId ); break;
608 case SMESH::ADD_EDGE : AddEdgesWithID ( myMesh, aSeq, anId ); break;
609 case SMESH::ADD_TRIANGLE : AddTriasWithID ( myMesh, aSeq, anId ); break;
610 case SMESH::ADD_QUADRANGLE : AddQuadsWithID ( myMesh, aSeq, anId ); break;
611 case SMESH::ADD_TETRAHEDRON: AddTetrasWithID ( myMesh, aSeq, anId ); break;
612 case SMESH::ADD_PYRAMID : AddPiramidsWithID( myMesh, aSeq, anId ); break;
613 case SMESH::ADD_PRISM : AddPrismsWithID ( myMesh, aSeq, anId ); break;
614 case SMESH::ADD_HEXAHEDRON : AddHexasWithID ( myMesh, aSeq, anId ); break;
616 case SMESH::REMOVE_NODE:
617 for( ; anElemId < aNbElems; anElemId++ )
618 myMesh->RemoveNode( FindNode( myMesh, anIndexes[anElemId] ) );
621 case SMESH::REMOVE_ELEMENT:
622 for( ; anElemId < aNbElems; anElemId++ )
623 myMesh->RemoveElement( FindElement( myMesh, anIndexes[anElemId] ) );
628 catch ( SALOME::SALOME_Exception& exc )
630 INFOS("Follow exception was cought:\n\t"<<exc.details.text);
632 catch( const std::exception& exc)
634 INFOS("Follow exception was cought:\n\t"<<exc.what());
638 INFOS("Unknown exception was cought !!!");
643 MESSAGE("Update - myMesh->NbNodes() = "<<myMesh->NbNodes());
644 MESSAGE("Update - myMesh->NbEdges() = "<<myMesh->NbEdges());
645 MESSAGE("Update - myMesh->NbFaces() = "<<myMesh->NbFaces());
646 MESSAGE("Update - myMesh->NbVolumes() = "<<myMesh->NbVolumes());
649 // Fill unstructured grid
653 //=================================================================================
654 // function : GetElemDimension
655 // purpose : Get dimension of element
656 //=================================================================================
657 int SMESH_MeshObj::GetElemDimension( const int theObjId )
659 const SMDS_MeshElement* anElem = myMesh->FindElement( theObjId );
663 int aType = anElem->GetType();
666 case SMDSAbs_Edge : return 1;
667 case SMDSAbs_Face : return 2;
668 case SMDSAbs_Volume: return 3;
673 //=================================================================================
674 // function : GetEntities
675 // purpose : Get entities of specified type. Return number of entities
676 //=================================================================================
677 int SMESH_MeshObj::GetNbEntities( const SMESH::ElementType theType) const
683 return myMesh->NbNodes();
688 return myMesh->NbEdges();
693 return myMesh->NbFaces();
698 return myMesh->NbVolumes();
707 int SMESH_MeshObj::GetEntities( const SMESH::ElementType theType, TEntityList& theObjs ) const
715 SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator();
716 while ( anIter->more() ) theObjs.push_back( anIter->next() );
721 SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
722 while ( anIter->more() ) theObjs.push_back( anIter->next() );
727 SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
728 while ( anIter->more() ) theObjs.push_back( anIter->next() );
733 SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
734 while ( anIter->more() ) theObjs.push_back( anIter->next() );
741 return theObjs.size();
744 //=================================================================================
745 // function : UpdateFunctor
746 // purpose : Update functor in accordance with current mesh
747 //=================================================================================
748 void SMESH_MeshObj::UpdateFunctor( SMESH::Functor_ptr f )
750 f->SetMesh( myMeshServer );
753 //=================================================================================
754 // function : IsNodePrs
755 // purpose : Return true if node presentation is used
756 //=================================================================================
757 bool SMESH_MeshObj::IsNodePrs() const
759 return myMesh->NbEdges() == 0 &&myMesh->NbFaces() == 0 &&myMesh->NbVolumes() == 0 ;
764 Class : SMESH_SubMeshObj
765 Description : Base class for visualisation of submeshes and groups
768 //=================================================================================
769 // function : SMESH_SubMeshObj
770 // purpose : Constructor
771 //=================================================================================
772 SMESH_SubMeshObj::SMESH_SubMeshObj( SMESH_MeshObj* theMeshObj )
774 if ( MYDEBUG ) MESSAGE( "SMESH_SubMeshObj - theMeshObj = " << theMeshObj );
776 myMeshObj = theMeshObj;
779 SMESH_SubMeshObj::~SMESH_SubMeshObj()
783 //=================================================================================
784 // function : GetElemDimension
785 // purpose : Get dimension of element
786 //=================================================================================
787 int SMESH_SubMeshObj::GetElemDimension( const int theObjId )
789 return myMeshObj == 0 ? 0 : myMeshObj->GetElemDimension( theObjId );
792 //=================================================================================
793 // function : UpdateFunctor
794 // purpose : Update functor in accordance with current mesh
795 //=================================================================================
796 void SMESH_SubMeshObj::UpdateFunctor( SMESH::Functor_ptr f )
798 f->SetMesh( myMeshObj->GetMeshServer() );
801 //=================================================================================
802 // function : UpdateFunctor
803 // purpose : Update mesh object and fill grid with new values
804 //=================================================================================
805 void SMESH_SubMeshObj::Update( int theIsClear )
807 myMeshObj->Update( theIsClear );
813 Class : SMESH_GroupObj
814 Description : Class for visualisation of groups
817 //=================================================================================
818 // function : SMESH_GroupObj
819 // purpose : Constructor
820 //=================================================================================
821 SMESH_GroupObj::SMESH_GroupObj( SMESH::SMESH_Group_ptr theGroup,
822 SMESH_MeshObj* theMeshObj )
823 : SMESH_SubMeshObj( theMeshObj ),
824 myGroupServer( SMESH::SMESH_Group::_duplicate(theGroup) )
826 if ( MYDEBUG ) MESSAGE("SMESH_GroupObj - theGroup->_is_nil() = "<<theGroup->_is_nil());
827 myGroupServer->Register();
830 SMESH_GroupObj::~SMESH_GroupObj()
832 if ( MYDEBUG ) MESSAGE("~SMESH_GroupObj");
833 myGroupServer->Destroy();
836 //=================================================================================
837 // function : IsNodePrs
838 // purpose : Return true if node presentation is used
839 //=================================================================================
840 bool SMESH_GroupObj::IsNodePrs() const
842 return myGroupServer->GetType() == SMESH::NODE;
845 //=================================================================================
846 // function : getNodesFromElems
847 // purpose : Retrieve nodes from elements
848 //=================================================================================
849 static int getNodesFromElems( SMESH::long_array_var& theElemIds,
850 const SMDS_Mesh* theMesh,
851 std::list<const SMDS_MeshElement*>& theResList )
853 set<const SMDS_MeshElement*> aNodeSet;
855 for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ )
857 const SMDS_MeshElement* anElem = theMesh->FindElement( theElemIds[ i ] );
860 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
861 while ( anIter->more() )
863 const SMDS_MeshElement* aNode = anIter->next();
865 aNodeSet.insert( aNode );
870 set<const SMDS_MeshElement*>::const_iterator anIter;
871 for ( anIter = aNodeSet.begin(); anIter != aNodeSet.end(); ++anIter )
872 theResList.push_back( *anIter );
874 return theResList.size();
877 //=================================================================================
878 // function : getPointers
879 // purpose : Get std::list<const SMDS_MeshElement*> from list of IDs
880 //=================================================================================
881 static int getPointers( const SMESH::ElementType theRequestType,
882 SMESH::long_array_var& theElemIds,
883 const SMDS_Mesh* theMesh,
884 std::list<const SMDS_MeshElement*>& theResList )
886 for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ )
888 const SMDS_MeshElement* anElem = theRequestType == SMESH::NODE
889 ? theMesh->FindNode( theElemIds[ i ] ) : theMesh->FindElement( theElemIds[ i ] );
892 theResList.push_back( anElem );
895 return theResList.size();
899 //=================================================================================
900 // function : GetEntities
901 // purpose : Get entities of specified type. Return number of entities
902 //=================================================================================
903 int SMESH_GroupObj::GetNbEntities( const SMESH::ElementType theType) const
905 if(myGroupServer->GetType() == theType){
906 return myGroupServer->Size();
911 int SMESH_GroupObj::GetEntities( const SMESH::ElementType theType, TEntityList& theResList ) const
914 SMDS_Mesh* aMesh = myMeshObj->GetMesh();
916 if ( myGroupServer->Size() == 0 || aMesh == 0 )
919 SMESH::ElementType aGrpType = myGroupServer->GetType();
920 SMESH::long_array_var anIds = myGroupServer->GetListOfID();
922 if ( aGrpType == theType )
923 return getPointers( theType, anIds, aMesh, theResList );
924 else if ( theType == SMESH::NODE )
925 return getNodesFromElems( anIds, aMesh, theResList );
933 Class : SMESH_subMeshObj
934 Description : Class for visualisation of submeshes
937 //=================================================================================
938 // function : SMESH_subMeshObj
939 // purpose : Constructor
940 //=================================================================================
941 SMESH_subMeshObj::SMESH_subMeshObj( SMESH::SMESH_subMesh_ptr theSubMesh,
942 SMESH_MeshObj* theMeshObj )
943 : SMESH_SubMeshObj( theMeshObj ),
944 mySubMeshServer( SMESH::SMESH_subMesh::_duplicate( theSubMesh ) )
946 if ( MYDEBUG ) MESSAGE( "SMESH_subMeshObj - theSubMesh->_is_nil() = " << theSubMesh->_is_nil() );
948 mySubMeshServer->Register();
951 SMESH_subMeshObj::~SMESH_subMeshObj()
953 if ( MYDEBUG ) MESSAGE( "~SMESH_subMeshObj" );
954 mySubMeshServer->Destroy();
957 //=================================================================================
958 // function : GetEntities
959 // purpose : Get entities of specified type. Return number of entities
960 //=================================================================================
961 int SMESH_subMeshObj::GetNbEntities( const SMESH::ElementType theType) const
967 return mySubMeshServer->GetNumberOfNodes();
974 SMESH::long_array_var anIds = mySubMeshServer->GetElementsByType( theType );
975 return anIds->length();
983 int SMESH_subMeshObj::GetEntities( const SMESH::ElementType theType, TEntityList& theResList ) const
987 SMDS_Mesh* aMesh = myMeshObj->GetMesh();
991 bool isNodal = IsNodePrs();
995 if ( theType == SMESH::NODE )
997 SMESH::long_array_var anIds = mySubMeshServer->GetNodesId();
998 return getPointers( SMESH::NODE, anIds, aMesh, theResList );
1003 if ( theType == SMESH::NODE )
1005 SMESH::long_array_var anIds = mySubMeshServer->GetElementsId();
1006 return getNodesFromElems( anIds, aMesh, theResList );
1010 SMESH::long_array_var anIds = mySubMeshServer->GetElementsByType( theType );
1011 return getPointers( theType, anIds, aMesh, theResList );
1018 //=================================================================================
1019 // function : IsNodePrs
1020 // purpose : Return true if node presentation is used
1021 //=================================================================================
1022 bool SMESH_subMeshObj::IsNodePrs() const
1024 return mySubMeshServer->GetNumberOfElements() == 0;