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_ObjectDef.h"
30 #include "SMDS_Mesh.hxx"
31 #include "SMESH_Actor.h"
32 #include "SMESH_ControlsDef.hxx"
33 #include "SALOME_ExtractUnstructuredGrid.h"
35 #include CORBA_SERVER_HEADER(SALOME_Exception)
38 #include <vtkIdList.h>
39 #include <vtkIntArray.h>
40 #include <vtkCellArray.h>
41 #include <vtkUnsignedCharArray.h>
43 #include <vtkUnstructuredGrid.h>
44 #include <vtkUnstructuredGridWriter.h>
45 #include <vtkUnstructuredGridReader.h>
52 #include "utilities.h"
57 #define EXCEPTION(TYPE, MSG) {\
58 std::ostringstream aStream;\
59 aStream<<__FILE__<<"["<<__LINE__<<"]::"<<MSG;\
60 throw TYPE(aStream.str());\
65 static int MYDEBUG = 0;
66 static int MYDEBUGWITHFILES = 0;
68 static int MYDEBUG = 0;
69 static int MYDEBUGWITHFILES = 0;
73 void WriteUnstructuredGrid(vtkUnstructuredGrid* theGrid, const char* theFileName){
74 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
75 aWriter->SetFileName(theFileName);
76 aWriter->SetInput(theGrid);
77 if(theGrid->GetNumberOfCells()){
86 inline const SMDS_MeshNode* FindNode(const SMDS_Mesh* theMesh, int theId){
87 if(const SMDS_MeshNode* anElem = theMesh->FindNode(theId)) return anElem;
88 EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
92 inline const SMDS_MeshElement* FindElement(const SMDS_Mesh* theMesh, int theId){
93 if(const SMDS_MeshElement* anElem = theMesh->FindElement(theId)) return anElem;
94 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot find a SMDS_MeshElement for ID = "<<theId);
98 inline void AddNodesWithID(SMDS_Mesh* theMesh,
99 SMESH::log_array_var& theSeq,
102 const SMESH::double_array& aCoords = theSeq[theId].coords;
103 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
104 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
105 if(3*aNbElems != aCoords.length())
106 EXCEPTION(runtime_error,"AddNodesWithID - 3*aNbElems != aCoords.length()");
107 for(CORBA::Long aCoordId = 0; anElemId < aNbElems; anElemId++, aCoordId+=3){
108 SMDS_MeshElement* anElem = theMesh->AddNodeWithID(aCoords[aCoordId],
111 anIndexes[anElemId]);
113 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddNodeWithID for ID = "<<anElemId);
118 inline void AddEdgesWithID(SMDS_Mesh* theMesh,
119 SMESH::log_array_var& theSeq,
122 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
123 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
124 if(3*aNbElems != anIndexes.length())
125 EXCEPTION(runtime_error,"AddEdgeWithID - 3*aNbElems != aCoords.length()");
126 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=3){
127 SMDS_MeshElement* anElem = theMesh->AddEdgeWithID(anIndexes[anIndexId+1],
128 anIndexes[anIndexId+2],
129 anIndexes[anIndexId]);
131 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<<anElemId);
136 inline void AddTriasWithID(SMDS_Mesh* theMesh,
137 SMESH::log_array_var& theSeq,
140 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
141 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
142 if(4*aNbElems != anIndexes.length())
143 EXCEPTION(runtime_error,"AddEdgeWithID - 4*aNbElems != anIndexes.length()");
144 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=4){
145 SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
146 anIndexes[anIndexId+2],
147 anIndexes[anIndexId+3],
148 anIndexes[anIndexId]);
150 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
155 inline void AddQuadsWithID(SMDS_Mesh* theMesh,
156 SMESH::log_array_var theSeq,
159 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
160 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
161 if(5*aNbElems != anIndexes.length())
162 EXCEPTION(runtime_error,"AddEdgeWithID - 4*aNbElems != anIndexes.length()");
163 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){
164 SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
165 anIndexes[anIndexId+2],
166 anIndexes[anIndexId+3],
167 anIndexes[anIndexId+4],
168 anIndexes[anIndexId]);
170 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
175 inline void AddTetrasWithID(SMDS_Mesh* theMesh,
176 SMESH::log_array_var& theSeq,
179 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
180 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
181 if(5*aNbElems != anIndexes.length())
182 EXCEPTION(runtime_error,"AddEdgeWithID - 5*aNbElems != anIndexes.length()");
183 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){
184 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
185 anIndexes[anIndexId+2],
186 anIndexes[anIndexId+3],
187 anIndexes[anIndexId+4],
188 anIndexes[anIndexId]);
190 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
195 inline void AddPiramidsWithID(SMDS_Mesh* theMesh,
196 SMESH::log_array_var& theSeq,
199 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
200 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
201 if(6*aNbElems != anIndexes.length())
202 EXCEPTION(runtime_error,"AddEdgeWithID - 6*aNbElems != anIndexes.length()");
203 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=6){
204 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
205 anIndexes[anIndexId+2],
206 anIndexes[anIndexId+3],
207 anIndexes[anIndexId+4],
208 anIndexes[anIndexId+5],
209 anIndexes[anIndexId]);
211 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
216 inline void AddPrismsWithID(SMDS_Mesh* theMesh,
217 SMESH::log_array_var& theSeq,
220 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
221 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
222 if(7*aNbElems != anIndexes.length())
223 EXCEPTION(runtime_error,"AddEdgeWithID - 7*aNbElems != anIndexes.length()");
224 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=7){
225 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
226 anIndexes[anIndexId+2],
227 anIndexes[anIndexId+3],
228 anIndexes[anIndexId+4],
229 anIndexes[anIndexId+5],
230 anIndexes[anIndexId+6],
231 anIndexes[anIndexId]);
233 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
238 inline void AddHexasWithID(SMDS_Mesh* theMesh,
239 SMESH::log_array_var& theSeq,
242 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
243 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
244 if(9*aNbElems != anIndexes.length())
245 EXCEPTION(runtime_error,"AddEdgeWithID - 9*aNbElems != anIndexes.length()");
246 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=9){
247 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
248 anIndexes[anIndexId+2],
249 anIndexes[anIndexId+3],
250 anIndexes[anIndexId+4],
251 anIndexes[anIndexId+5],
252 anIndexes[anIndexId+6],
253 anIndexes[anIndexId+7],
254 anIndexes[anIndexId+8],
255 anIndexes[anIndexId]);
257 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
264 Class : SMESH_VisualObjDef
265 Description : Base class for all mesh objects to be visuilised
268 //=================================================================================
269 // function : getCellType
270 // purpose : Get type of VTK cell
271 //=================================================================================
272 static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
273 const int theNbNodes )
278 return theNbNodes == 2 ? VTK_LINE : VTK_EMPTY_CELL;
281 if ( theNbNodes == 3 ) return VTK_TRIANGLE;
282 else if ( theNbNodes == 4 ) return VTK_QUAD;
283 else return VTK_EMPTY_CELL;
286 if ( theNbNodes == 4 ) return VTK_TETRA;
287 else if ( theNbNodes == 5 ) return VTK_PYRAMID;
288 else if ( theNbNodes == 6 ) return VTK_WEDGE;
289 else if ( theNbNodes == 8 ) return VTK_HEXAHEDRON;
290 else return VTK_EMPTY_CELL;
292 default: return VTK_EMPTY_CELL;
296 //=================================================================================
297 // functions : SMESH_VisualObjDef
298 // purpose : Constructor
299 //=================================================================================
300 SMESH_VisualObjDef::SMESH_VisualObjDef()
302 myGrid = vtkUnstructuredGrid::New();
304 SMESH_VisualObjDef::~SMESH_VisualObjDef()
307 MESSAGE( "~SMESH_MeshObj - myGrid->GetReferenceCount() = " << myGrid->GetReferenceCount() );
311 //=================================================================================
312 // functions : GetNodeObjId, GetNodeVTKId, GetElemObjId, GetElemVTKId
313 // purpose : Methods for retrieving VTK IDs by SMDS IDs and vice versa
314 //=================================================================================
315 vtkIdType SMESH_VisualObjDef::GetNodeObjId( int theVTKID )
317 return myVTK2SMDSNodes.find(theVTKID) == myVTK2SMDSNodes.end() ? -1 : myVTK2SMDSNodes[theVTKID];
320 vtkIdType SMESH_VisualObjDef::GetNodeVTKId( int theObjID )
322 return mySMDS2VTKNodes.find(theObjID) == mySMDS2VTKNodes.end() ? -1 : mySMDS2VTKNodes[theObjID];
325 vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID )
327 return myVTK2SMDSElems.find(theVTKID) == myVTK2SMDSElems.end() ? -1 : myVTK2SMDSElems[theVTKID];
330 vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID )
332 return mySMDS2VTKElems.find(theObjID) == mySMDS2VTKElems.end() ? -1 : mySMDS2VTKElems[theObjID];
335 //=================================================================================
336 // function : SMESH_VisualObjDef::createPoints
337 // purpose : Create points from nodes
338 //=================================================================================
339 void SMESH_VisualObjDef::createPoints( vtkPoints* thePoints )
341 if ( thePoints == 0 )
345 vtkIdType nbNodes = GetEntities( SMDSAbs_Node, aNodes );
346 thePoints->SetNumberOfPoints( nbNodes );
350 TEntityList::const_iterator anIter;
351 for ( anIter = aNodes.begin(); anIter != aNodes.end(); ++anIter )
353 const SMDS_MeshNode* aNode = ( const SMDS_MeshNode* )(*anIter);
356 thePoints->SetPoint( nbPoints, aNode->X(), aNode->Y(), aNode->Z() );
357 int anId = aNode->GetID();
358 mySMDS2VTKNodes.insert( TMapOfIds::value_type( anId, nbPoints ) );
359 myVTK2SMDSNodes.insert( TMapOfIds::value_type( nbPoints, anId ) );
364 if ( nbPoints != nbNodes )
365 thePoints->SetNumberOfPoints( nbPoints );
368 //=================================================================================
369 // function : buildPrs
370 // purpose : create VTK cells( fill unstructured grid )
371 //=================================================================================
372 void SMESH_VisualObjDef::buildPrs()
376 mySMDS2VTKNodes.clear();
377 myVTK2SMDSNodes.clear();
378 mySMDS2VTKElems.clear();
379 myVTK2SMDSElems.clear();
386 catch( const std::exception& exc )
388 INFOS("Follow exception was cought:\n\t"<<exc.what());
392 INFOS("Unknown exception was cought !!!");
395 if( MYDEBUG ) MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->GetNumberOfCells() );
396 if( MYDEBUGWITHFILES ) WriteUnstructuredGrid( myGrid,"/tmp/buildPrs" );
399 //=================================================================================
400 // function : buildNodePrs
401 // purpose : create VTK cells for nodes
402 //=================================================================================
403 void SMESH_VisualObjDef::buildNodePrs()
405 vtkPoints* aPoints = vtkPoints::New();
406 createPoints( aPoints );
407 myGrid->SetPoints( aPoints );
410 myGrid->SetCells( 0, 0, 0 );
414 int nbPoints = aPoints->GetNumberOfPoints();
415 vtkIdList *anIdList = vtkIdList::New();
416 anIdList->SetNumberOfIds( 1 );
418 vtkCellArray *aCells = vtkCellArray::New();
419 aCells->Allocate( 2 * nbPoints, 0 );
421 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
422 aCellTypesArray->SetNumberOfComponents( 1 );
423 aCellTypesArray->Allocate( nbPoints );
425 for( vtkIdType aCellId = 0; aCellId < nbPoints; aCellId++ )
427 anIdList->SetId( 0, aCellId );
428 aCells->InsertNextCell( anIdList );
429 aCellTypesArray->InsertNextValue( VTK_VERTEX );
432 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
433 aCellLocationsArray->SetNumberOfComponents( 1 );
434 aCellLocationsArray->SetNumberOfTuples( nbPoints );
436 aCells->InitTraversal();
437 for( vtkIdType i = 0, *pts, npts; aCells->GetNextCell( npts, pts ); i++ )
438 aCellLocationsArray->SetValue( i, aCells->GetTraversalLocation( npts ) );
440 myGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells );
442 aCellLocationsArray->Delete();
443 aCellTypesArray->Delete();
449 //=================================================================================
450 // function : buildElemPrs
451 // purpose : Create VTK cells for elements
452 //=================================================================================
453 void SMESH_VisualObjDef::buildElemPrs()
457 vtkPoints* aPoints = vtkPoints::New();
458 createPoints( aPoints );
459 myGrid->SetPoints( aPoints );
463 MESSAGE("Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints());
465 // Calculate cells size
467 static SMDSAbs_ElementType aTypes[ 3 ] = { SMDSAbs_Edge, SMDSAbs_Face, SMDSAbs_Volume };
470 map< int, int > nbEnts;
471 map< int, TEntityList > anEnts;
473 for ( int i = 0; i <= 2; i++ )
474 nbEnts[ aTypes[ i ] ] = GetEntities( aTypes[ i ], anEnts[ aTypes[ i ] ] );
476 vtkIdType aCellsSize = 3 * nbEnts[ SMDSAbs_Edge ];
478 for ( int i = 1; i <= 2; i++ ) // iterate through faces and volumes
480 if ( nbEnts[ aTypes[ i ] ] )
482 const TEntityList& aList = anEnts[ aTypes[ i ] ];
483 TEntityList::const_iterator anIter;
484 for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
485 aCellsSize += (*anIter)->NbNodes() + 1;
489 vtkIdType aNbCells = nbEnts[ SMDSAbs_Edge ] + nbEnts[ SMDSAbs_Face ] + nbEnts[ SMDSAbs_Volume ];
492 MESSAGE( "Update - aNbCells = "<<aNbCells<<"; aCellsSize = "<<aCellsSize );
496 vtkCellArray* aConnectivity = vtkCellArray::New();
497 aConnectivity->Allocate( aCellsSize, 0 );
499 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
500 aCellTypesArray->SetNumberOfComponents( 1 );
501 aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
503 vtkIdList *anIdList = vtkIdList::New();
506 for ( int i = 0; i <= 2; i++ ) // iterate through edges, faces and volumes
508 if( nbEnts[ aTypes[ i ] ] > 0 )
510 const TEntityList& aList = anEnts[ aTypes[ i ] ];
511 TEntityList::const_iterator anIter;
512 for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
514 const SMDS_MeshElement* anElem = *anIter;
516 vtkIdType aNbNodes = anElem->NbNodes();
517 anIdList->SetNumberOfIds( aNbNodes );
519 int anId = anElem->GetID();
521 mySMDS2VTKElems.insert( TMapOfIds::value_type( anId, iElem ) );
522 myVTK2SMDSElems.insert( TMapOfIds::value_type( iElem, anId ) );
524 SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
525 for( vtkIdType aNodeId = 0; aNodesIter->more(); aNodeId++ )
527 const SMDS_MeshElement* aNode = aNodesIter->next();
528 anIdList->SetId( aNodeId, mySMDS2VTKNodes[aNode->GetID()] );
531 aConnectivity->InsertNextCell( anIdList );
532 aCellTypesArray->InsertNextValue( getCellType( aTypes[ i ], aNbNodes ) );
539 // Insert cells in grid
541 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
542 aCellLocationsArray->SetNumberOfComponents( 1 );
543 aCellLocationsArray->SetNumberOfTuples( aNbCells );
545 aConnectivity->InitTraversal();
546 for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
547 aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
549 myGrid->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
551 aCellLocationsArray->Delete();
552 aCellTypesArray->Delete();
553 aConnectivity->Delete();
557 //=================================================================================
558 // function : GetEdgeNodes
559 // purpose : Retrieve ids of nodes from edge of elements ( edge is numbered from 1 )
560 //=================================================================================
561 bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
562 const int theEdgeNum,
564 int& theNodeId2 ) const
566 const SMDS_Mesh* aMesh = GetMesh();
570 const SMDS_MeshElement* anElem = aMesh->FindElement( theElemId );
574 int nbNodes = anElem->NbNodes();
576 if ( theEdgeNum < 1 || theEdgeNum > 4 || nbNodes != 3 && nbNodes != 4 || theEdgeNum > nbNodes )
579 int anIds[ nbNodes ];
580 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
582 while( anIter->more() )
583 anIds[ i++ ] = anIter->next()->GetID();
585 if ( nbNodes != theEdgeNum )
587 theNodeId1 = anIds[ theEdgeNum - 1 ];
588 theNodeId2 = anIds[ theEdgeNum ];
592 theNodeId1 = anIds[ nbNodes - 1 ];
593 theNodeId2 = anIds[ 0 ];
600 Class : SMESH_MeshObj
601 Description : Class for visualisation of mesh
604 //=================================================================================
605 // function : SMESH_MeshObj
606 // purpose : Constructor
607 //=================================================================================
608 SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh)
611 MESSAGE("SMESH_MeshObj - theMesh->_is_nil() = "<<theMesh->_is_nil());
613 myMeshServer = SMESH::SMESH_Mesh::_duplicate( theMesh );
614 myMeshServer->Register();
615 myMesh = new SMDS_Mesh();
618 //=================================================================================
619 // function : ~SMESH_MeshObj
620 // purpose : Destructor
621 //=================================================================================
622 SMESH_MeshObj::~SMESH_MeshObj()
624 myMeshServer->Destroy();
628 //=================================================================================
630 // purpose : Update mesh and fill grid with new values if necessary
631 //=================================================================================
632 void SMESH_MeshObj::Update( int theIsClear )
634 // Update SMDS_Mesh on client part
638 SMESH::log_array_var aSeq = myMeshServer->GetLog( theIsClear );
639 CORBA::Long aLength = aSeq->length();
641 if( MYDEBUG ) MESSAGE( "Update: length of the script is "<<aLength );
646 for ( CORBA::Long anId = 0; anId < aLength; anId++)
648 const SMESH::double_array& aCoords = aSeq[anId].coords;
649 const SMESH::long_array& anIndexes = aSeq[anId].indexes;
650 CORBA::Long anElemId = 0, aNbElems = aSeq[anId].number;
651 CORBA::Long aCommand = aSeq[anId].commandType;
655 case SMESH::ADD_NODE : AddNodesWithID ( myMesh, aSeq, anId ); break;
656 case SMESH::ADD_EDGE : AddEdgesWithID ( myMesh, aSeq, anId ); break;
657 case SMESH::ADD_TRIANGLE : AddTriasWithID ( myMesh, aSeq, anId ); break;
658 case SMESH::ADD_QUADRANGLE : AddQuadsWithID ( myMesh, aSeq, anId ); break;
659 case SMESH::ADD_TETRAHEDRON: AddTetrasWithID ( myMesh, aSeq, anId ); break;
660 case SMESH::ADD_PYRAMID : AddPiramidsWithID( myMesh, aSeq, anId ); break;
661 case SMESH::ADD_PRISM : AddPrismsWithID ( myMesh, aSeq, anId ); break;
662 case SMESH::ADD_HEXAHEDRON : AddHexasWithID ( myMesh, aSeq, anId ); break;
664 case SMESH::REMOVE_NODE:
665 for( ; anElemId < aNbElems; anElemId++ )
666 myMesh->RemoveNode( FindNode( myMesh, anIndexes[anElemId] ) );
669 case SMESH::REMOVE_ELEMENT:
670 for( ; anElemId < aNbElems; anElemId++ )
671 myMesh->RemoveElement( FindElement( myMesh, anIndexes[anElemId] ) );
674 case SMESH::MOVE_NODE:
675 for(CORBA::Long aCoordId=0; anElemId < aNbElems; anElemId++, aCoordId+=3)
677 SMDS_MeshNode* node =
678 const_cast<SMDS_MeshNode*>( FindNode( myMesh, anIndexes[anElemId] ));
679 node->setXYZ( aCoords[aCoordId], aCoords[aCoordId+1], aCoords[aCoordId+2] );
683 case SMESH::CHANGE_ELEMENT_NODES:
684 for ( CORBA::Long i = 0; anElemId < aNbElems; anElemId++ )
687 const SMDS_MeshElement* elem = FindElement( myMesh, anIndexes[i++] );
689 int nbNodes = anIndexes[i++];
691 ASSERT( nbNodes < 9 );
692 const SMDS_MeshNode* aNodes[ 8 ];
693 for ( int iNode = 0; iNode < nbNodes; iNode++ )
694 aNodes[ iNode ] = FindNode( myMesh, anIndexes[i++] );
696 myMesh->ChangeElementNodes( elem, aNodes, nbNodes );
700 case SMESH::RENUMBER:
701 for(CORBA::Long i=0; anElemId < aNbElems; anElemId++, i+=3)
703 myMesh->Renumber( anIndexes[i], anIndexes[i+1], anIndexes[i+2] );
711 catch ( SALOME::SALOME_Exception& exc )
713 INFOS("Following exception was cought:\n\t"<<exc.details.text);
715 catch( const std::exception& exc)
717 INFOS("Following exception was cought:\n\t"<<exc.what());
721 INFOS("Unknown exception was cought !!!");
726 MESSAGE("Update - myMesh->NbNodes() = "<<myMesh->NbNodes());
727 MESSAGE("Update - myMesh->NbEdges() = "<<myMesh->NbEdges());
728 MESSAGE("Update - myMesh->NbFaces() = "<<myMesh->NbFaces());
729 MESSAGE("Update - myMesh->NbVolumes() = "<<myMesh->NbVolumes());
732 // Fill unstructured grid
736 //=================================================================================
737 // function : GetElemDimension
738 // purpose : Get dimension of element
739 //=================================================================================
740 int SMESH_MeshObj::GetElemDimension( const int theObjId )
742 const SMDS_MeshElement* anElem = myMesh->FindElement( theObjId );
746 int aType = anElem->GetType();
749 case SMDSAbs_Edge : return 1;
750 case SMDSAbs_Face : return 2;
751 case SMDSAbs_Volume: return 3;
756 //=================================================================================
757 // function : GetEntities
758 // purpose : Get entities of specified type. Return number of entities
759 //=================================================================================
760 int SMESH_MeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const
766 return myMesh->NbNodes();
771 return myMesh->NbEdges();
776 return myMesh->NbFaces();
781 return myMesh->NbVolumes();
790 int SMESH_MeshObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& theObjs ) const
798 SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator();
799 while ( anIter->more() ) theObjs.push_back( anIter->next() );
804 SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
805 while ( anIter->more() ) theObjs.push_back( anIter->next() );
810 SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
811 while ( anIter->more() ) theObjs.push_back( anIter->next() );
816 SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
817 while ( anIter->more() ) theObjs.push_back( anIter->next() );
824 return theObjs.size();
827 //=================================================================================
828 // function : UpdateFunctor
829 // purpose : Update functor in accordance with current mesh
830 //=================================================================================
831 void SMESH_MeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor )
833 theFunctor->SetMesh( GetMesh() );
836 //=================================================================================
837 // function : IsNodePrs
838 // purpose : Return true if node presentation is used
839 //=================================================================================
840 bool SMESH_MeshObj::IsNodePrs() const
842 return myMesh->NbEdges() == 0 &&myMesh->NbFaces() == 0 &&myMesh->NbVolumes() == 0 ;
847 Class : SMESH_SubMeshObj
848 Description : Base class for visualisation of submeshes and groups
851 //=================================================================================
852 // function : SMESH_SubMeshObj
853 // purpose : Constructor
854 //=================================================================================
855 SMESH_SubMeshObj::SMESH_SubMeshObj( SMESH_MeshObj* theMeshObj )
857 if ( MYDEBUG ) MESSAGE( "SMESH_SubMeshObj - theMeshObj = " << theMeshObj );
859 myMeshObj = theMeshObj;
862 SMESH_SubMeshObj::~SMESH_SubMeshObj()
866 //=================================================================================
867 // function : GetElemDimension
868 // purpose : Get dimension of element
869 //=================================================================================
870 int SMESH_SubMeshObj::GetElemDimension( const int theObjId )
872 return myMeshObj == 0 ? 0 : myMeshObj->GetElemDimension( theObjId );
875 //=================================================================================
876 // function : UpdateFunctor
877 // purpose : Update functor in accordance with current mesh
878 //=================================================================================
879 void SMESH_SubMeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor )
881 theFunctor->SetMesh( myMeshObj->GetMesh() );
884 //=================================================================================
886 // purpose : Update mesh object and fill grid with new values
887 //=================================================================================
888 void SMESH_SubMeshObj::Update( int theIsClear )
890 myMeshObj->Update( theIsClear );
896 Class : SMESH_GroupObj
897 Description : Class for visualisation of groups
900 //=================================================================================
901 // function : SMESH_GroupObj
902 // purpose : Constructor
903 //=================================================================================
904 SMESH_GroupObj::SMESH_GroupObj( SMESH::SMESH_GroupBase_ptr theGroup,
905 SMESH_MeshObj* theMeshObj )
906 : SMESH_SubMeshObj( theMeshObj ),
907 myGroupServer( SMESH::SMESH_GroupBase::_duplicate(theGroup) )
909 if ( MYDEBUG ) MESSAGE("SMESH_GroupObj - theGroup->_is_nil() = "<<theGroup->_is_nil());
910 myGroupServer->Register();
913 SMESH_GroupObj::~SMESH_GroupObj()
915 if ( MYDEBUG ) MESSAGE("~SMESH_GroupObj");
916 myGroupServer->Destroy();
919 //=================================================================================
920 // function : IsNodePrs
921 // purpose : Return true if node presentation is used
922 //=================================================================================
923 bool SMESH_GroupObj::IsNodePrs() const
925 return myGroupServer->GetType() == SMESH::NODE;
928 //=================================================================================
929 // function : getNodesFromElems
930 // purpose : Retrieve nodes from elements
931 //=================================================================================
932 static int getNodesFromElems( SMESH::long_array_var& theElemIds,
933 const SMDS_Mesh* theMesh,
934 std::list<const SMDS_MeshElement*>& theResList )
936 set<const SMDS_MeshElement*> aNodeSet;
938 for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ )
940 const SMDS_MeshElement* anElem = theMesh->FindElement( theElemIds[ i ] );
943 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
944 while ( anIter->more() )
946 const SMDS_MeshElement* aNode = anIter->next();
948 aNodeSet.insert( aNode );
953 set<const SMDS_MeshElement*>::const_iterator anIter;
954 for ( anIter = aNodeSet.begin(); anIter != aNodeSet.end(); ++anIter )
955 theResList.push_back( *anIter );
957 return theResList.size();
960 //=================================================================================
961 // function : getPointers
962 // purpose : Get std::list<const SMDS_MeshElement*> from list of IDs
963 //=================================================================================
964 static int getPointers( const SMDSAbs_ElementType theRequestType,
965 SMESH::long_array_var& theElemIds,
966 const SMDS_Mesh* theMesh,
967 std::list<const SMDS_MeshElement*>& theResList )
969 for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ )
971 const SMDS_MeshElement* anElem = theRequestType == SMDSAbs_Node
972 ? theMesh->FindNode( theElemIds[ i ] ) : theMesh->FindElement( theElemIds[ i ] );
975 theResList.push_back( anElem );
978 return theResList.size();
982 //=================================================================================
983 // function : GetEntities
984 // purpose : Get entities of specified type. Return number of entities
985 //=================================================================================
986 int SMESH_GroupObj::GetNbEntities( const SMDSAbs_ElementType theType) const
988 if(SMDSAbs_ElementType(myGroupServer->GetType()) == theType){
989 return myGroupServer->Size();
994 int SMESH_GroupObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& theResList ) const
997 SMDS_Mesh* aMesh = myMeshObj->GetMesh();
999 if ( myGroupServer->Size() == 0 || aMesh == 0 )
1002 SMDSAbs_ElementType aGrpType = SMDSAbs_ElementType(myGroupServer->GetType());
1003 SMESH::long_array_var anIds = myGroupServer->GetListOfID();
1005 if ( aGrpType == theType )
1006 return getPointers( theType, anIds, aMesh, theResList );
1007 else if ( theType == SMDSAbs_Node )
1008 return getNodesFromElems( anIds, aMesh, theResList );
1016 Class : SMESH_subMeshObj
1017 Description : Class for visualisation of submeshes
1020 //=================================================================================
1021 // function : SMESH_subMeshObj
1022 // purpose : Constructor
1023 //=================================================================================
1024 SMESH_subMeshObj::SMESH_subMeshObj( SMESH::SMESH_subMesh_ptr theSubMesh,
1025 SMESH_MeshObj* theMeshObj )
1026 : SMESH_SubMeshObj( theMeshObj ),
1027 mySubMeshServer( SMESH::SMESH_subMesh::_duplicate( theSubMesh ) )
1029 if ( MYDEBUG ) MESSAGE( "SMESH_subMeshObj - theSubMesh->_is_nil() = " << theSubMesh->_is_nil() );
1031 mySubMeshServer->Register();
1034 SMESH_subMeshObj::~SMESH_subMeshObj()
1036 if ( MYDEBUG ) MESSAGE( "~SMESH_subMeshObj" );
1037 mySubMeshServer->Destroy();
1040 //=================================================================================
1041 // function : GetEntities
1042 // purpose : Get entities of specified type. Return number of entities
1043 //=================================================================================
1044 int SMESH_subMeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const
1050 return mySubMeshServer->GetNumberOfNodes( false );
1055 case SMDSAbs_Volume:
1057 SMESH::long_array_var anIds =
1058 mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
1059 return anIds->length();
1067 int SMESH_subMeshObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& theResList ) const
1071 SMDS_Mesh* aMesh = myMeshObj->GetMesh();
1075 bool isNodal = IsNodePrs();
1079 if ( theType == SMDSAbs_Node )
1081 SMESH::long_array_var anIds = mySubMeshServer->GetNodesId();
1082 return getPointers( SMDSAbs_Node, anIds, aMesh, theResList );
1087 if ( theType == SMDSAbs_Node )
1089 SMESH::long_array_var anIds = mySubMeshServer->GetElementsId();
1090 return getNodesFromElems( anIds, aMesh, theResList );
1094 SMESH::long_array_var anIds =
1095 mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
1096 return getPointers( theType, anIds, aMesh, theResList );
1103 //=================================================================================
1104 // function : IsNodePrs
1105 // purpose : Return true if node presentation is used
1106 //=================================================================================
1107 bool SMESH_subMeshObj::IsNodePrs() const
1109 return mySubMeshServer->GetNumberOfElements() == 0;