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)
36 #include <vtkIdList.h>
37 #include <vtkIntArray.h>
38 #include <vtkCellArray.h>
39 #include <vtkUnsignedCharArray.h>
41 #include <vtkUnstructuredGrid.h>
42 #include <vtkUnstructuredGridWriter.h>
43 #include <vtkUnstructuredGridReader.h>
50 #include "utilities.h"
55 #define EXCEPTION(TYPE, MSG) {\
56 std::ostringstream aStream;\
57 aStream<<__FILE__<<"["<<__LINE__<<"]::"<<MSG;\
58 throw TYPE(aStream.str());\
63 static int MYDEBUG = 0;
64 static int MYDEBUGWITHFILES = 0;
66 static int MYDEBUG = 0;
67 static int MYDEBUGWITHFILES = 0;
71 void WriteUnstructuredGrid(vtkUnstructuredGrid* theGrid, const char* theFileName){
72 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
73 aWriter->SetFileName(theFileName);
74 aWriter->SetInput(theGrid);
75 if(theGrid->GetNumberOfCells()){
84 inline const SMDS_MeshNode* FindNode(const SMDS_Mesh* theMesh, int theId){
85 if(const SMDS_MeshNode* anElem = theMesh->FindNode(theId)) return anElem;
86 EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
90 inline const SMDS_MeshElement* FindElement(const SMDS_Mesh* theMesh, int theId){
91 if(const SMDS_MeshElement* anElem = theMesh->FindElement(theId)) return anElem;
92 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot find a SMDS_MeshElement for ID = "<<theId);
96 inline void AddNodesWithID(SMDS_Mesh* theMesh,
97 SMESH::log_array_var& theSeq,
100 const SMESH::double_array& aCoords = theSeq[theId].coords;
101 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
102 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
103 if(3*aNbElems != aCoords.length())
104 EXCEPTION(runtime_error,"AddNodesWithID - 3*aNbElems != aCoords.length()");
105 for(CORBA::Long aCoordId = 0; anElemId < aNbElems; anElemId++, aCoordId+=3){
106 SMDS_MeshElement* anElem = theMesh->AddNodeWithID(aCoords[aCoordId],
109 anIndexes[anElemId]);
111 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddNodeWithID for ID = "<<anElemId);
116 inline void AddEdgesWithID(SMDS_Mesh* theMesh,
117 SMESH::log_array_var& theSeq,
120 const SMESH::double_array& aCoords = theSeq[theId].coords;
121 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
122 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
123 if(3*aNbElems != anIndexes.length())
124 EXCEPTION(runtime_error,"AddEdgeWithID - 3*aNbElems != aCoords.length()");
125 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=3){
126 SMDS_MeshElement* anElem = theMesh->AddEdgeWithID(anIndexes[anIndexId+1],
127 anIndexes[anIndexId+2],
128 anIndexes[anIndexId]);
130 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<<anElemId);
135 inline void AddTriasWithID(SMDS_Mesh* theMesh,
136 SMESH::log_array_var& theSeq,
139 const SMESH::double_array& aCoords = theSeq[theId].coords;
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::double_array& aCoords = theSeq[theId].coords;
160 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
161 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
162 if(5*aNbElems != anIndexes.length())
163 EXCEPTION(runtime_error,"AddEdgeWithID - 4*aNbElems != anIndexes.length()");
164 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){
165 SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
166 anIndexes[anIndexId+2],
167 anIndexes[anIndexId+3],
168 anIndexes[anIndexId+4],
169 anIndexes[anIndexId]);
171 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
176 inline void AddTetrasWithID(SMDS_Mesh* theMesh,
177 SMESH::log_array_var& theSeq,
180 const SMESH::double_array& aCoords = theSeq[theId].coords;
181 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
182 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
183 if(5*aNbElems != anIndexes.length())
184 EXCEPTION(runtime_error,"AddEdgeWithID - 5*aNbElems != anIndexes.length()");
185 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){
186 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
187 anIndexes[anIndexId+2],
188 anIndexes[anIndexId+3],
189 anIndexes[anIndexId+4],
190 anIndexes[anIndexId]);
192 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
197 inline void AddPiramidsWithID(SMDS_Mesh* theMesh,
198 SMESH::log_array_var& theSeq,
201 const SMESH::double_array& aCoords = theSeq[theId].coords;
202 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
203 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
204 if(6*aNbElems != anIndexes.length())
205 EXCEPTION(runtime_error,"AddEdgeWithID - 6*aNbElems != anIndexes.length()");
206 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=6){
207 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
208 anIndexes[anIndexId+2],
209 anIndexes[anIndexId+3],
210 anIndexes[anIndexId+4],
211 anIndexes[anIndexId+5],
212 anIndexes[anIndexId]);
214 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
219 inline void AddPrismsWithID(SMDS_Mesh* theMesh,
220 SMESH::log_array_var& theSeq,
223 const SMESH::double_array& aCoords = theSeq[theId].coords;
224 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
225 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
226 if(7*aNbElems != anIndexes.length())
227 EXCEPTION(runtime_error,"AddEdgeWithID - 7*aNbElems != anIndexes.length()");
228 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=7){
229 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
230 anIndexes[anIndexId+2],
231 anIndexes[anIndexId+3],
232 anIndexes[anIndexId+4],
233 anIndexes[anIndexId+5],
234 anIndexes[anIndexId+6],
235 anIndexes[anIndexId]);
237 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
242 inline void AddHexasWithID(SMDS_Mesh* theMesh,
243 SMESH::log_array_var& theSeq,
246 const SMESH::double_array& aCoords = theSeq[theId].coords;
247 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
248 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
249 if(9*aNbElems != anIndexes.length())
250 EXCEPTION(runtime_error,"AddEdgeWithID - 9*aNbElems != anIndexes.length()");
251 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=9){
252 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
253 anIndexes[anIndexId+2],
254 anIndexes[anIndexId+3],
255 anIndexes[anIndexId+4],
256 anIndexes[anIndexId+5],
257 anIndexes[anIndexId+6],
258 anIndexes[anIndexId+7],
259 anIndexes[anIndexId+8],
260 anIndexes[anIndexId]);
262 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
269 Class : SMESH_VisualObj
270 Description : Base class for all mesh objects to be visuilised
273 //=================================================================================
274 // function : getCellType
275 // purpose : Get type of VTK cell
276 //=================================================================================
277 static inline vtkIdType getCellType( const SMESH::ElementType theType,
278 const int theNbNodes )
282 case SMESH::EDGE: return theNbNodes == 2 ? VTK_LINE : VTK_EMPTY_CELL;
284 case SMESH::FACE : if ( theNbNodes == 3 ) return VTK_TRIANGLE;
285 else if ( theNbNodes == 4 ) return VTK_QUAD;
286 else return VTK_EMPTY_CELL;
288 case SMESH::VOLUME: if ( theNbNodes == 4 ) return VTK_TETRA;
289 else if ( theNbNodes == 5 ) return VTK_PYRAMID;
290 else if ( theNbNodes == 6 ) return VTK_WEDGE;
291 else if ( theNbNodes == 8 ) return VTK_HEXAHEDRON;
292 else return VTK_EMPTY_CELL;
294 default: return VTK_EMPTY_CELL;
298 //=================================================================================
299 // functions : SMESH_VisualObj
300 // purpose : Constructor
301 //=================================================================================
302 SMESH_VisualObj::SMESH_VisualObj()
304 myGrid = vtkUnstructuredGrid::New();
306 SMESH_VisualObj::~SMESH_VisualObj()
309 MESSAGE( "~SMESH_MeshObj - myGrid->GetReferenceCount() = " << myGrid->GetReferenceCount() );
313 //=================================================================================
314 // functions : GetNodeObjId, GetNodeVTKId, GetElemObjId, GetElemVTKId
315 // purpose : Methods for retrieving VTK IDs by SMDS IDs and vice versa
316 //=================================================================================
317 vtkIdType SMESH_VisualObj::GetNodeObjId( int theVTKID )
319 return myVTK2SMDSNodes.find(theVTKID) == myVTK2SMDSNodes.end() ? -1 : myVTK2SMDSNodes[theVTKID];
322 vtkIdType SMESH_VisualObj::GetNodeVTKId( int theObjID )
324 return mySMDS2VTKNodes.find(theObjID) == mySMDS2VTKNodes.end() ? -1 : mySMDS2VTKNodes[theObjID];
327 vtkIdType SMESH_VisualObj::GetElemObjId( int theVTKID )
329 return myVTK2SMDSElems.find(theVTKID) == myVTK2SMDSElems.end() ? -1 : myVTK2SMDSElems[theVTKID];
332 vtkIdType SMESH_VisualObj::GetElemVTKId( int theObjID )
334 return mySMDS2VTKElems.find(theObjID) == mySMDS2VTKElems.end() ? -1 : mySMDS2VTKElems[theObjID];
337 //=================================================================================
338 // function : SMESH_VisualObj::createPoints
339 // purpose : Create points from nodes
340 //=================================================================================
341 void SMESH_VisualObj::createPoints( vtkPoints* thePoints )
343 if ( thePoints == 0 )
347 vtkIdType nbNodes = GetEntities( SMESH::NODE, aNodes );
348 thePoints->SetNumberOfPoints( nbNodes );
352 TEntityList::const_iterator anIter;
353 for ( anIter = aNodes.begin(); anIter != aNodes.end(); ++anIter )
355 const SMDS_MeshNode* aNode = ( const SMDS_MeshNode* )(*anIter);
358 thePoints->SetPoint( nbPoints, aNode->X(), aNode->Y(), aNode->Z() );
359 int anId = aNode->GetID();
360 mySMDS2VTKNodes.insert( TMapOfIds::value_type( anId, nbPoints ) );
361 myVTK2SMDSNodes.insert( TMapOfIds::value_type( nbPoints, anId ) );
366 if ( nbPoints != nbNodes )
367 thePoints->SetNumberOfPoints( nbPoints );
370 //=================================================================================
371 // function : buildPrs
372 // purpose : create VTK cells( fill unstructured grid )
373 //=================================================================================
374 void SMESH_VisualObj::buildPrs()
378 mySMDS2VTKNodes.clear();
379 myVTK2SMDSNodes.clear();
380 mySMDS2VTKElems.clear();
381 myVTK2SMDSElems.clear();
388 catch( const std::exception& exc )
390 INFOS("Follow exception was cought:\n\t"<<exc.what());
394 INFOS("Unknown exception was cought !!!");
397 if( MYDEBUG ) MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->GetNumberOfCells() );
398 if( MYDEBUGWITHFILES ) WriteUnstructuredGrid( myGrid,"/tmp/buildPrs" );
401 //=================================================================================
402 // function : buildNodePrs
403 // purpose : create VTK cells for nodes
404 //=================================================================================
405 void SMESH_VisualObj::buildNodePrs()
407 vtkPoints* aPoints = vtkPoints::New();
408 createPoints( aPoints );
409 int nbPoints = aPoints->GetNumberOfPoints();
410 myGrid->SetPoints( aPoints );
413 myGrid->SetCells( 0, 0, 0 );
417 vtkIdList *anIdList = vtkIdList::New();
418 anIdList->SetNumberOfIds( 1 );
420 vtkCellArray *aCells = vtkCellArray::New();
421 aCells->Allocate( 2 * nbPoints, 0 );
423 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
424 aCellTypesArray->SetNumberOfComponents( 1 );
425 aCellTypesArray->Allocate( nbPoints );
427 for( vtkIdType aCellId = 0; aCellId < nbPoints; aCellId++ )
429 anIdList->SetId( 0, aCellId );
430 aCells->InsertNextCell( anIdList );
431 aCellTypesArray->InsertNextValue( VTK_VERTEX );
434 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
435 aCellLocationsArray->SetNumberOfComponents( 1 );
436 aCellLocationsArray->SetNumberOfTuples( nbPoints );
438 aCells->InitTraversal();
439 for( vtkIdType i = 0, *pts, npts; aCells->GetNextCell( npts, pts ); i++ )
440 aCellLocationsArray->SetValue( i, aCells->GetTraversalLocation( npts ) );
442 myGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells );
444 aCellLocationsArray->Delete();
445 aCellTypesArray->Delete();
451 //=================================================================================
452 // function : buildElemPrs
453 // purpose : Create VTK cells for elements
454 //=================================================================================
455 void SMESH_VisualObj::buildElemPrs()
459 vtkPoints* aPoints = vtkPoints::New();
460 createPoints( aPoints );
461 myGrid->SetPoints( aPoints );
465 MESSAGE("Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints());
467 // Calculate cells size
469 static SMESH::ElementType aTypes[ 3 ] = { SMESH::EDGE, SMESH::FACE, SMESH::VOLUME };
472 map< int, int > nbEnts;
473 map< int, TEntityList > anEnts;
475 for ( int i = 0; i <= 2; i++ )
476 nbEnts[ aTypes[ i ] ] = GetEntities( aTypes[ i ], anEnts[ aTypes[ i ] ] );
478 vtkIdType aCellsSize = 3 * nbEnts[ SMESH::EDGE ];
480 for ( int i = 1; i <= 2; i++ ) // iterate through faces and volumes
482 if ( nbEnts[ aTypes[ i ] ] )
484 const TEntityList& aList = anEnts[ aTypes[ i ] ];
485 TEntityList::const_iterator anIter;
486 for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
487 aCellsSize += (*anIter)->NbNodes() + 1;
491 vtkIdType aNbCells = nbEnts[ SMESH::EDGE ] + nbEnts[ SMESH::FACE ] + nbEnts[ SMESH::VOLUME ];
494 MESSAGE( "Update - aNbCells = "<<aNbCells<<"; aCellsSize = "<<aCellsSize );
498 vtkCellArray* aConnectivity = vtkCellArray::New();
499 aConnectivity->Allocate( aCellsSize, 0 );
501 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
502 aCellTypesArray->SetNumberOfComponents( 1 );
503 aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
505 vtkIdList *anIdList = vtkIdList::New();
508 for ( int i = 0; i <= 2; i++ ) // iterate through edges, faces and volumes
510 if( nbEnts[ aTypes[ i ] ] > 0 )
512 const TEntityList& aList = anEnts[ aTypes[ i ] ];
513 TEntityList::const_iterator anIter;
514 for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
516 const SMDS_MeshElement* anElem = *anIter;
518 vtkIdType aNbNodes = anElem->NbNodes();
519 anIdList->SetNumberOfIds( aNbNodes );
521 int anId = anElem->GetID();
523 mySMDS2VTKElems.insert( TMapOfIds::value_type( anId, iElem ) );
524 myVTK2SMDSElems.insert( TMapOfIds::value_type( iElem, anId ) );
526 SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
527 for( vtkIdType aNodeId = 0; aNodesIter->more(); aNodeId++ )
529 const SMDS_MeshElement* aNode = aNodesIter->next();
530 anIdList->SetId( aNodeId, mySMDS2VTKNodes[aNode->GetID()] );
533 aConnectivity->InsertNextCell( anIdList );
534 aCellTypesArray->InsertNextValue( getCellType( aTypes[ i ], aNbNodes ) );
541 // Insert cells in grid
543 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
544 aCellLocationsArray->SetNumberOfComponents( 1 );
545 aCellLocationsArray->SetNumberOfTuples( aNbCells );
547 aConnectivity->InitTraversal();
548 for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
549 aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
551 myGrid->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
553 aCellLocationsArray->Delete();
554 aCellTypesArray->Delete();
555 aConnectivity->Delete();
559 //=================================================================================
560 // function : GetEdgeNodes
561 // purpose : Retrieve ids of nodes from edge of elements ( edge is numbered from 1 )
562 //=================================================================================
563 bool SMESH_VisualObj::GetEdgeNodes( const int theElemId,
564 const int theEdgeNum,
566 int& theNodeId2 ) const
568 const SMDS_Mesh* aMesh = GetMesh();
572 const SMDS_MeshElement* anElem = aMesh->FindElement( theElemId );
576 int nbNodes = anElem->NbNodes();
578 if ( theEdgeNum < 1 || theEdgeNum > 4 || nbNodes != 3 && nbNodes != 4 || theEdgeNum > nbNodes )
581 int anIds[ nbNodes ];
582 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
584 while( anIter->more() )
585 anIds[ i++ ] = anIter->next()->GetID();
587 if ( nbNodes != theEdgeNum )
589 theNodeId1 = anIds[ theEdgeNum - 1 ];
590 theNodeId2 = anIds[ theEdgeNum ];
594 theNodeId1 = anIds[ nbNodes - 1 ];
595 theNodeId2 = anIds[ 0 ];
602 Class : SMESH_MeshObj
603 Description : Class for visualisation of mesh
606 //=================================================================================
607 // function : SMESH_MeshObj
608 // purpose : Constructor
609 //=================================================================================
610 SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh)
613 MESSAGE("SMESH_MeshObj - theMesh->_is_nil() = "<<theMesh->_is_nil());
615 myMeshServer = SMESH::SMESH_Mesh::_duplicate( theMesh );
616 myMeshServer->Register();
617 myMesh = new SMDS_Mesh();
620 //=================================================================================
621 // function : ~SMESH_MeshObj
622 // purpose : Destructor
623 //=================================================================================
624 SMESH_MeshObj::~SMESH_MeshObj()
626 myMeshServer->Destroy();
630 //=================================================================================
632 // purpose : Update mesh and fill grid with new values if necessary
633 //=================================================================================
634 void SMESH_MeshObj::Update( int theIsClear )
636 // Update SMDS_Mesh on client part
640 SMESH::log_array_var aSeq = myMeshServer->GetLog( theIsClear );
641 CORBA::Long aLength = aSeq->length();
643 if( MYDEBUG ) MESSAGE( "Update: length of the script is "<<aLength );
648 for ( CORBA::Long anId = 0; anId < aLength; anId++)
650 const SMESH::double_array& aCoords = aSeq[anId].coords;
651 const SMESH::long_array& anIndexes = aSeq[anId].indexes;
652 CORBA::Long anElemId = 0, aNbElems = aSeq[anId].number;
653 SMDS_MeshElement* anElem = NULL;
654 CORBA::Long aCommand = aSeq[anId].commandType;
658 case SMESH::ADD_NODE : AddNodesWithID ( myMesh, aSeq, anId ); break;
659 case SMESH::ADD_EDGE : AddEdgesWithID ( myMesh, aSeq, anId ); break;
660 case SMESH::ADD_TRIANGLE : AddTriasWithID ( myMesh, aSeq, anId ); break;
661 case SMESH::ADD_QUADRANGLE : AddQuadsWithID ( myMesh, aSeq, anId ); break;
662 case SMESH::ADD_TETRAHEDRON: AddTetrasWithID ( myMesh, aSeq, anId ); break;
663 case SMESH::ADD_PYRAMID : AddPiramidsWithID( myMesh, aSeq, anId ); break;
664 case SMESH::ADD_PRISM : AddPrismsWithID ( myMesh, aSeq, anId ); break;
665 case SMESH::ADD_HEXAHEDRON : AddHexasWithID ( myMesh, aSeq, anId ); break;
667 case SMESH::REMOVE_NODE:
668 for( ; anElemId < aNbElems; anElemId++ )
669 myMesh->RemoveNode( FindNode( myMesh, anIndexes[anElemId] ) );
672 case SMESH::REMOVE_ELEMENT:
673 for( ; anElemId < aNbElems; anElemId++ )
674 myMesh->RemoveElement( FindElement( myMesh, anIndexes[anElemId] ) );
677 case SMESH::MOVE_NODE:
678 for(CORBA::Long aCoordId=0; anElemId < aNbElems; anElemId++, aCoordId+=3)
680 SMDS_MeshNode* node =
681 const_cast<SMDS_MeshNode*>( FindNode( myMesh, anIndexes[anElemId] ));
682 node->setXYZ( aCoords[aCoordId], aCoords[aCoordId+1], aCoords[aCoordId+2] );
686 case SMESH::CHANGE_ELEMENT_NODES:
687 for ( CORBA::Long i = 0; anElemId < aNbElems; anElemId++ )
690 const SMDS_MeshElement* elem = FindElement( myMesh, anIndexes[i++] );
692 int nbNodes = anIndexes[i++];
694 ASSERT( nbNodes < 9 );
695 const SMDS_MeshNode* aNodes[ 8 ];
696 for ( int iNode = 0; iNode < nbNodes; iNode++ )
697 aNodes[ iNode ] = FindNode( myMesh, anIndexes[i++] );
699 myMesh->ChangeElementNodes( elem, aNodes, nbNodes );
703 case SMESH::RENUMBER:
704 for(CORBA::Long i=0; anElemId < aNbElems; anElemId++, i+=3)
706 myMesh->Renumber( anIndexes[i], anIndexes[i+1], anIndexes[i+2] );
714 catch ( SALOME::SALOME_Exception& exc )
716 INFOS("Following exception was cought:\n\t"<<exc.details.text);
718 catch( const std::exception& exc)
720 INFOS("Following exception was cought:\n\t"<<exc.what());
724 INFOS("Unknown exception was cought !!!");
729 MESSAGE("Update - myMesh->NbNodes() = "<<myMesh->NbNodes());
730 MESSAGE("Update - myMesh->NbEdges() = "<<myMesh->NbEdges());
731 MESSAGE("Update - myMesh->NbFaces() = "<<myMesh->NbFaces());
732 MESSAGE("Update - myMesh->NbVolumes() = "<<myMesh->NbVolumes());
735 // Fill unstructured grid
739 //=================================================================================
740 // function : GetElemDimension
741 // purpose : Get dimension of element
742 //=================================================================================
743 int SMESH_MeshObj::GetElemDimension( const int theObjId )
745 const SMDS_MeshElement* anElem = myMesh->FindElement( theObjId );
749 int aType = anElem->GetType();
752 case SMDSAbs_Edge : return 1;
753 case SMDSAbs_Face : return 2;
754 case SMDSAbs_Volume: return 3;
759 //=================================================================================
760 // function : GetEntities
761 // purpose : Get entities of specified type. Return number of entities
762 //=================================================================================
763 int SMESH_MeshObj::GetNbEntities( const SMESH::ElementType theType) const
769 return myMesh->NbNodes();
774 return myMesh->NbEdges();
779 return myMesh->NbFaces();
784 return myMesh->NbVolumes();
793 int SMESH_MeshObj::GetEntities( const SMESH::ElementType theType, TEntityList& theObjs ) const
801 SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator();
802 while ( anIter->more() ) theObjs.push_back( anIter->next() );
807 SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
808 while ( anIter->more() ) theObjs.push_back( anIter->next() );
813 SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
814 while ( anIter->more() ) theObjs.push_back( anIter->next() );
819 SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
820 while ( anIter->more() ) theObjs.push_back( anIter->next() );
827 return theObjs.size();
830 //=================================================================================
831 // function : UpdateFunctor
832 // purpose : Update functor in accordance with current mesh
833 //=================================================================================
834 void SMESH_MeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor )
836 theFunctor->SetMesh( GetMesh() );
839 //=================================================================================
840 // function : IsNodePrs
841 // purpose : Return true if node presentation is used
842 //=================================================================================
843 bool SMESH_MeshObj::IsNodePrs() const
845 return myMesh->NbEdges() == 0 &&myMesh->NbFaces() == 0 &&myMesh->NbVolumes() == 0 ;
850 Class : SMESH_SubMeshObj
851 Description : Base class for visualisation of submeshes and groups
854 //=================================================================================
855 // function : SMESH_SubMeshObj
856 // purpose : Constructor
857 //=================================================================================
858 SMESH_SubMeshObj::SMESH_SubMeshObj( SMESH_MeshObj* theMeshObj )
860 if ( MYDEBUG ) MESSAGE( "SMESH_SubMeshObj - theMeshObj = " << theMeshObj );
862 myMeshObj = theMeshObj;
865 SMESH_SubMeshObj::~SMESH_SubMeshObj()
869 //=================================================================================
870 // function : GetElemDimension
871 // purpose : Get dimension of element
872 //=================================================================================
873 int SMESH_SubMeshObj::GetElemDimension( const int theObjId )
875 return myMeshObj == 0 ? 0 : myMeshObj->GetElemDimension( theObjId );
878 //=================================================================================
879 // function : UpdateFunctor
880 // purpose : Update functor in accordance with current mesh
881 //=================================================================================
882 void SMESH_SubMeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor )
884 theFunctor->SetMesh( myMeshObj->GetMesh() );
887 //=================================================================================
889 // purpose : Update mesh object and fill grid with new values
890 //=================================================================================
891 void SMESH_SubMeshObj::Update( int theIsClear )
893 myMeshObj->Update( theIsClear );
899 Class : SMESH_GroupObj
900 Description : Class for visualisation of groups
903 //=================================================================================
904 // function : SMESH_GroupObj
905 // purpose : Constructor
906 //=================================================================================
907 SMESH_GroupObj::SMESH_GroupObj( SMESH::SMESH_GroupBase_ptr theGroup,
908 SMESH_MeshObj* theMeshObj )
909 : SMESH_SubMeshObj( theMeshObj ),
910 myGroupServer( SMESH::SMESH_GroupBase::_duplicate(theGroup) )
912 if ( MYDEBUG ) MESSAGE("SMESH_GroupObj - theGroup->_is_nil() = "<<theGroup->_is_nil());
913 myGroupServer->Register();
916 SMESH_GroupObj::~SMESH_GroupObj()
918 if ( MYDEBUG ) MESSAGE("~SMESH_GroupObj");
919 myGroupServer->Destroy();
922 //=================================================================================
923 // function : IsNodePrs
924 // purpose : Return true if node presentation is used
925 //=================================================================================
926 bool SMESH_GroupObj::IsNodePrs() const
928 return myGroupServer->GetType() == SMESH::NODE;
931 //=================================================================================
932 // function : getNodesFromElems
933 // purpose : Retrieve nodes from elements
934 //=================================================================================
935 static int getNodesFromElems( SMESH::long_array_var& theElemIds,
936 const SMDS_Mesh* theMesh,
937 std::list<const SMDS_MeshElement*>& theResList )
939 set<const SMDS_MeshElement*> aNodeSet;
941 for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ )
943 const SMDS_MeshElement* anElem = theMesh->FindElement( theElemIds[ i ] );
946 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
947 while ( anIter->more() )
949 const SMDS_MeshElement* aNode = anIter->next();
951 aNodeSet.insert( aNode );
956 set<const SMDS_MeshElement*>::const_iterator anIter;
957 for ( anIter = aNodeSet.begin(); anIter != aNodeSet.end(); ++anIter )
958 theResList.push_back( *anIter );
960 return theResList.size();
963 //=================================================================================
964 // function : getPointers
965 // purpose : Get std::list<const SMDS_MeshElement*> from list of IDs
966 //=================================================================================
967 static int getPointers( const SMESH::ElementType theRequestType,
968 SMESH::long_array_var& theElemIds,
969 const SMDS_Mesh* theMesh,
970 std::list<const SMDS_MeshElement*>& theResList )
972 for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ )
974 const SMDS_MeshElement* anElem = theRequestType == SMESH::NODE
975 ? theMesh->FindNode( theElemIds[ i ] ) : theMesh->FindElement( theElemIds[ i ] );
978 theResList.push_back( anElem );
981 return theResList.size();
985 //=================================================================================
986 // function : GetEntities
987 // purpose : Get entities of specified type. Return number of entities
988 //=================================================================================
989 int SMESH_GroupObj::GetNbEntities( const SMESH::ElementType theType) const
991 if(myGroupServer->GetType() == theType){
992 return myGroupServer->Size();
997 int SMESH_GroupObj::GetEntities( const SMESH::ElementType theType, TEntityList& theResList ) const
1000 SMDS_Mesh* aMesh = myMeshObj->GetMesh();
1002 if ( myGroupServer->Size() == 0 || aMesh == 0 )
1005 SMESH::ElementType aGrpType = myGroupServer->GetType();
1006 SMESH::long_array_var anIds = myGroupServer->GetListOfID();
1008 if ( aGrpType == theType )
1009 return getPointers( theType, anIds, aMesh, theResList );
1010 else if ( theType == SMESH::NODE )
1011 return getNodesFromElems( anIds, aMesh, theResList );
1019 Class : SMESH_subMeshObj
1020 Description : Class for visualisation of submeshes
1023 //=================================================================================
1024 // function : SMESH_subMeshObj
1025 // purpose : Constructor
1026 //=================================================================================
1027 SMESH_subMeshObj::SMESH_subMeshObj( SMESH::SMESH_subMesh_ptr theSubMesh,
1028 SMESH_MeshObj* theMeshObj )
1029 : SMESH_SubMeshObj( theMeshObj ),
1030 mySubMeshServer( SMESH::SMESH_subMesh::_duplicate( theSubMesh ) )
1032 if ( MYDEBUG ) MESSAGE( "SMESH_subMeshObj - theSubMesh->_is_nil() = " << theSubMesh->_is_nil() );
1034 mySubMeshServer->Register();
1037 SMESH_subMeshObj::~SMESH_subMeshObj()
1039 if ( MYDEBUG ) MESSAGE( "~SMESH_subMeshObj" );
1040 mySubMeshServer->Destroy();
1043 //=================================================================================
1044 // function : GetEntities
1045 // purpose : Get entities of specified type. Return number of entities
1046 //=================================================================================
1047 int SMESH_subMeshObj::GetNbEntities( const SMESH::ElementType theType) const
1053 return mySubMeshServer->GetNumberOfNodes( false );
1060 SMESH::long_array_var anIds = mySubMeshServer->GetElementsByType( theType );
1061 return anIds->length();
1069 int SMESH_subMeshObj::GetEntities( const SMESH::ElementType theType, TEntityList& theResList ) const
1073 SMDS_Mesh* aMesh = myMeshObj->GetMesh();
1077 bool isNodal = IsNodePrs();
1081 if ( theType == SMESH::NODE )
1083 SMESH::long_array_var anIds = mySubMeshServer->GetNodesId();
1084 return getPointers( SMESH::NODE, anIds, aMesh, theResList );
1089 if ( theType == SMESH::NODE )
1091 SMESH::long_array_var anIds = mySubMeshServer->GetElementsId();
1092 return getNodesFromElems( anIds, aMesh, theResList );
1096 SMESH::long_array_var anIds = mySubMeshServer->GetElementsByType( theType );
1097 return getPointers( theType, anIds, aMesh, theResList );
1104 //=================================================================================
1105 // function : IsNodePrs
1106 // purpose : Return true if node presentation is used
1107 //=================================================================================
1108 bool SMESH_subMeshObj::IsNodePrs() const
1110 return mySubMeshServer->GetNumberOfElements() == 0;