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"
29 #include "SMESH_ActorUtils.h"
31 #include "SMDS_Mesh.hxx"
32 #include "SMESH_Actor.h"
33 #include "SMESH_ControlsDef.hxx"
34 #include "SALOME_ExtractUnstructuredGrid.h"
36 #include CORBA_SERVER_HEADER(SALOME_Exception)
39 #include <vtkIdList.h>
40 #include <vtkIntArray.h>
41 #include <vtkCellArray.h>
42 #include <vtkUnsignedCharArray.h>
44 #include <vtkUnstructuredGrid.h>
51 #include "utilities.h"
56 #define EXCEPTION(TYPE, MSG) {\
57 std::ostringstream aStream;\
58 aStream<<__FILE__<<"["<<__LINE__<<"]::"<<MSG;\
59 throw TYPE(aStream.str());\
64 static int MYDEBUG = 0;
65 static int MYDEBUGWITHFILES = 0;
67 static int MYDEBUG = 0;
68 static int MYDEBUGWITHFILES = 0;
74 inline const SMDS_MeshNode* FindNode(const SMDS_Mesh* theMesh, int theId){
75 if(const SMDS_MeshNode* anElem = theMesh->FindNode(theId)) return anElem;
76 EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
80 inline const SMDS_MeshElement* FindElement(const SMDS_Mesh* theMesh, int theId){
81 if(const SMDS_MeshElement* anElem = theMesh->FindElement(theId)) return anElem;
82 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot find a SMDS_MeshElement for ID = "<<theId);
86 inline void AddNodesWithID(SMDS_Mesh* theMesh,
87 SMESH::log_array_var& theSeq,
90 const SMESH::double_array& aCoords = theSeq[theId].coords;
91 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
92 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
93 if(3*aNbElems != aCoords.length())
94 EXCEPTION(runtime_error,"AddNodesWithID - 3*aNbElems != aCoords.length()");
95 for(CORBA::Long aCoordId = 0; anElemId < aNbElems; anElemId++, aCoordId+=3){
96 SMDS_MeshElement* anElem = theMesh->AddNodeWithID(aCoords[aCoordId],
101 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddNodeWithID for ID = "<<anElemId);
106 inline void AddEdgesWithID(SMDS_Mesh* theMesh,
107 SMESH::log_array_var& theSeq,
110 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
111 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
112 if(3*aNbElems != anIndexes.length())
113 EXCEPTION(runtime_error,"AddEdgeWithID - 3*aNbElems != aCoords.length()");
114 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=3){
115 SMDS_MeshElement* anElem = theMesh->AddEdgeWithID(anIndexes[anIndexId+1],
116 anIndexes[anIndexId+2],
117 anIndexes[anIndexId]);
119 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddEdgeWithID for ID = "<<anElemId);
124 inline void AddTriasWithID(SMDS_Mesh* theMesh,
125 SMESH::log_array_var& theSeq,
128 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
129 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
130 if(4*aNbElems != anIndexes.length())
131 EXCEPTION(runtime_error,"AddEdgeWithID - 4*aNbElems != anIndexes.length()");
132 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=4){
133 SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
134 anIndexes[anIndexId+2],
135 anIndexes[anIndexId+3],
136 anIndexes[anIndexId]);
138 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
143 inline void AddQuadsWithID(SMDS_Mesh* theMesh,
144 SMESH::log_array_var theSeq,
147 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
148 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
149 if(5*aNbElems != anIndexes.length())
150 EXCEPTION(runtime_error,"AddEdgeWithID - 4*aNbElems != anIndexes.length()");
151 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){
152 SMDS_MeshElement* anElem = theMesh->AddFaceWithID(anIndexes[anIndexId+1],
153 anIndexes[anIndexId+2],
154 anIndexes[anIndexId+3],
155 anIndexes[anIndexId+4],
156 anIndexes[anIndexId]);
158 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
163 inline void AddTetrasWithID(SMDS_Mesh* theMesh,
164 SMESH::log_array_var& theSeq,
167 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
168 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
169 if(5*aNbElems != anIndexes.length())
170 EXCEPTION(runtime_error,"AddEdgeWithID - 5*aNbElems != anIndexes.length()");
171 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=5){
172 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
173 anIndexes[anIndexId+2],
174 anIndexes[anIndexId+3],
175 anIndexes[anIndexId+4],
176 anIndexes[anIndexId]);
178 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
183 inline void AddPiramidsWithID(SMDS_Mesh* theMesh,
184 SMESH::log_array_var& theSeq,
187 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
188 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
189 if(6*aNbElems != anIndexes.length())
190 EXCEPTION(runtime_error,"AddEdgeWithID - 6*aNbElems != anIndexes.length()");
191 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=6){
192 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
193 anIndexes[anIndexId+2],
194 anIndexes[anIndexId+3],
195 anIndexes[anIndexId+4],
196 anIndexes[anIndexId+5],
197 anIndexes[anIndexId]);
199 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
204 inline void AddPrismsWithID(SMDS_Mesh* theMesh,
205 SMESH::log_array_var& theSeq,
208 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
209 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
210 if(7*aNbElems != anIndexes.length())
211 EXCEPTION(runtime_error,"AddEdgeWithID - 7*aNbElems != anIndexes.length()");
212 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=7){
213 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
214 anIndexes[anIndexId+2],
215 anIndexes[anIndexId+3],
216 anIndexes[anIndexId+4],
217 anIndexes[anIndexId+5],
218 anIndexes[anIndexId+6],
219 anIndexes[anIndexId]);
221 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
226 inline void AddHexasWithID(SMDS_Mesh* theMesh,
227 SMESH::log_array_var& theSeq,
230 const SMESH::long_array& anIndexes = theSeq[theId].indexes;
231 CORBA::Long anElemId = 0, aNbElems = theSeq[theId].number;
232 if(9*aNbElems != anIndexes.length())
233 EXCEPTION(runtime_error,"AddEdgeWithID - 9*aNbElems != anIndexes.length()");
234 for(CORBA::Long anIndexId = 0; anElemId < aNbElems; anElemId++, anIndexId+=9){
235 SMDS_MeshElement* anElem = theMesh->AddVolumeWithID(anIndexes[anIndexId+1],
236 anIndexes[anIndexId+2],
237 anIndexes[anIndexId+3],
238 anIndexes[anIndexId+4],
239 anIndexes[anIndexId+5],
240 anIndexes[anIndexId+6],
241 anIndexes[anIndexId+7],
242 anIndexes[anIndexId+8],
243 anIndexes[anIndexId]);
245 EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
252 Class : SMESH_VisualObjDef
253 Description : Base class for all mesh objects to be visuilised
256 //=================================================================================
257 // function : getCellType
258 // purpose : Get type of VTK cell
259 //=================================================================================
260 static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
261 const int theNbNodes )
266 return theNbNodes == 2 ? VTK_LINE : VTK_EMPTY_CELL;
269 if ( theNbNodes == 3 ) return VTK_TRIANGLE;
270 else if ( theNbNodes == 4 ) return VTK_QUAD;
271 else return VTK_EMPTY_CELL;
274 if ( theNbNodes == 4 ) return VTK_TETRA;
275 else if ( theNbNodes == 5 ) return VTK_PYRAMID;
276 else if ( theNbNodes == 6 ) return VTK_WEDGE;
277 else if ( theNbNodes == 8 ) return VTK_HEXAHEDRON;
278 else return VTK_EMPTY_CELL;
280 default: return VTK_EMPTY_CELL;
284 //=================================================================================
285 // functions : SMESH_VisualObjDef
286 // purpose : Constructor
287 //=================================================================================
288 SMESH_VisualObjDef::SMESH_VisualObjDef()
290 if(MYDEBUG) MESSAGE("SMESH_MeshObj - "<<this);
291 myGrid = vtkUnstructuredGrid::New();
293 SMESH_VisualObjDef::~SMESH_VisualObjDef()
296 MESSAGE("~SMESH_MeshObj - "<<this);
302 //=================================================================================
303 // functions : GetNodeObjId, GetNodeVTKId, GetElemObjId, GetElemVTKId
304 // purpose : Methods for retrieving VTK IDs by SMDS IDs and vice versa
305 //=================================================================================
306 vtkIdType SMESH_VisualObjDef::GetNodeObjId( int theVTKID )
308 return myVTK2SMDSNodes.find(theVTKID) == myVTK2SMDSNodes.end() ? -1 : myVTK2SMDSNodes[theVTKID];
311 vtkIdType SMESH_VisualObjDef::GetNodeVTKId( int theObjID )
313 return mySMDS2VTKNodes.find(theObjID) == mySMDS2VTKNodes.end() ? -1 : mySMDS2VTKNodes[theObjID];
316 vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID )
318 return myVTK2SMDSElems.find(theVTKID) == myVTK2SMDSElems.end() ? -1 : myVTK2SMDSElems[theVTKID];
321 vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID )
323 return mySMDS2VTKElems.find(theObjID) == mySMDS2VTKElems.end() ? -1 : mySMDS2VTKElems[theObjID];
326 //=================================================================================
327 // function : SMESH_VisualObjDef::createPoints
328 // purpose : Create points from nodes
329 //=================================================================================
330 void SMESH_VisualObjDef::createPoints( vtkPoints* thePoints )
332 if ( thePoints == 0 )
336 vtkIdType nbNodes = GetEntities( SMDSAbs_Node, aNodes );
337 thePoints->SetNumberOfPoints( nbNodes );
341 TEntityList::const_iterator anIter;
342 for ( anIter = aNodes.begin(); anIter != aNodes.end(); ++anIter )
344 const SMDS_MeshNode* aNode = ( const SMDS_MeshNode* )(*anIter);
347 thePoints->SetPoint( nbPoints, aNode->X(), aNode->Y(), aNode->Z() );
348 int anId = aNode->GetID();
349 mySMDS2VTKNodes.insert( TMapOfIds::value_type( anId, nbPoints ) );
350 myVTK2SMDSNodes.insert( TMapOfIds::value_type( nbPoints, anId ) );
355 if ( nbPoints != nbNodes )
356 thePoints->SetNumberOfPoints( nbPoints );
359 //=================================================================================
360 // function : buildPrs
361 // purpose : create VTK cells( fill unstructured grid )
362 //=================================================================================
363 void SMESH_VisualObjDef::buildPrs()
367 mySMDS2VTKNodes.clear();
368 myVTK2SMDSNodes.clear();
369 mySMDS2VTKElems.clear();
370 myVTK2SMDSElems.clear();
377 catch( const std::exception& exc )
379 INFOS("Follow exception was cought:\n\t"<<exc.what());
383 INFOS("Unknown exception was cought !!!");
386 if( MYDEBUG ) MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->GetNumberOfCells() );
387 if( MYDEBUGWITHFILES ) SMESH::WriteUnstructuredGrid( myGrid,"/tmp/buildPrs" );
390 //=================================================================================
391 // function : buildNodePrs
392 // purpose : create VTK cells for nodes
393 //=================================================================================
394 void SMESH_VisualObjDef::buildNodePrs()
396 vtkPoints* aPoints = vtkPoints::New();
397 createPoints( aPoints );
398 myGrid->SetPoints( aPoints );
401 myGrid->SetCells( 0, 0, 0 );
405 int nbPoints = aPoints->GetNumberOfPoints();
406 vtkIdList *anIdList = vtkIdList::New();
407 anIdList->SetNumberOfIds( 1 );
409 vtkCellArray *aCells = vtkCellArray::New();
410 aCells->Allocate( 2 * nbPoints, 0 );
412 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
413 aCellTypesArray->SetNumberOfComponents( 1 );
414 aCellTypesArray->Allocate( nbPoints );
416 for( vtkIdType aCellId = 0; aCellId < nbPoints; aCellId++ )
418 anIdList->SetId( 0, aCellId );
419 aCells->InsertNextCell( anIdList );
420 aCellTypesArray->InsertNextValue( VTK_VERTEX );
423 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
424 aCellLocationsArray->SetNumberOfComponents( 1 );
425 aCellLocationsArray->SetNumberOfTuples( nbPoints );
427 aCells->InitTraversal();
428 for( vtkIdType i = 0, *pts, npts; aCells->GetNextCell( npts, pts ); i++ )
429 aCellLocationsArray->SetValue( i, aCells->GetTraversalLocation( npts ) );
431 myGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells );
433 aCellLocationsArray->Delete();
434 aCellTypesArray->Delete();
440 //=================================================================================
441 // function : buildElemPrs
442 // purpose : Create VTK cells for elements
443 //=================================================================================
446 typedef std::vector<const SMDS_MeshElement*> TConnect;
448 int GetConnect(const SMDS_ElemIteratorPtr& theNodesIter,
449 TConnect& theConnect)
452 for(; theNodesIter->more();)
453 theConnect.push_back(theNodesIter->next());
454 return theConnect.size();
458 void SetId(vtkIdList *theIdList,
459 const SMESH_VisualObjDef::TMapOfIds& theSMDS2VTKNodes,
460 const TConnect& theConnect,
464 theIdList->SetId(thePosition,theSMDS2VTKNodes.find(theConnect[theId]->GetID())->second);
470 void SMESH_VisualObjDef::buildElemPrs()
474 vtkPoints* aPoints = vtkPoints::New();
475 createPoints( aPoints );
476 myGrid->SetPoints( aPoints );
480 MESSAGE("Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints());
482 // Calculate cells size
484 static SMDSAbs_ElementType aTypes[ 3 ] = { SMDSAbs_Edge, SMDSAbs_Face, SMDSAbs_Volume };
487 map<SMDSAbs_ElementType,int> nbEnts;
488 map<SMDSAbs_ElementType,TEntityList> anEnts;
490 for ( int i = 0; i <= 2; i++ )
491 nbEnts[ aTypes[ i ] ] = GetEntities( aTypes[ i ], anEnts[ aTypes[ i ] ] );
493 vtkIdType aCellsSize = 3 * nbEnts[ SMDSAbs_Edge ];
495 for ( int i = 1; i <= 2; i++ ) // iterate through faces and volumes
497 if ( nbEnts[ aTypes[ i ] ] )
499 const TEntityList& aList = anEnts[ aTypes[ i ] ];
500 TEntityList::const_iterator anIter;
501 for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
502 aCellsSize += (*anIter)->NbNodes() + 1;
506 vtkIdType aNbCells = nbEnts[ SMDSAbs_Edge ] + nbEnts[ SMDSAbs_Face ] + nbEnts[ SMDSAbs_Volume ];
509 MESSAGE( "Update - aNbCells = "<<aNbCells<<"; aCellsSize = "<<aCellsSize );
513 vtkCellArray* aConnectivity = vtkCellArray::New();
514 aConnectivity->Allocate( aCellsSize, 0 );
516 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
517 aCellTypesArray->SetNumberOfComponents( 1 );
518 aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
520 vtkIdList *anIdList = vtkIdList::New();
524 aConnect.reserve(VTK_CELL_SIZE);
526 for ( int i = 0; i <= 2; i++ ) // iterate through edges, faces and volumes
528 if( nbEnts[ aTypes[ i ] ] > 0 )
530 const SMDSAbs_ElementType& aType = aTypes[ i ];
531 const TEntityList& aList = anEnts[ aType ];
532 TEntityList::const_iterator anIter;
533 for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
535 const SMDS_MeshElement* anElem = *anIter;
537 vtkIdType aNbNodes = anElem->NbNodes();
538 anIdList->SetNumberOfIds( aNbNodes );
540 int anId = anElem->GetID();
542 mySMDS2VTKElems.insert( TMapOfIds::value_type( anId, iElem ) );
543 myVTK2SMDSElems.insert( TMapOfIds::value_type( iElem, anId ) );
545 SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
547 case SMDSAbs_Volume:{
548 int* aConnectivities = NULL;
549 GetConnect(aNodesIter,aConnect);
550 // Convertions connectivities from SMDS to VTK
553 static int anIds[] = {0,2,1,3};
554 aConnectivities = anIds;
558 static int anIds[] = {0,3,2,1,4};
559 aConnectivities = anIds;
563 static int anIds[] = {0,1,2,3,4,5};
564 aConnectivities = anIds;
568 static int anIds[] = {0,3,2,1,4,7,6,5};
569 aConnectivities = anIds;
574 for( vtkIdType aNodeId = 0; aNodeId < aNbNodes; aNodeId++ )
575 SetId(anIdList,mySMDS2VTKNodes,aConnect,aNodeId,aConnectivities[aNodeId]);
580 for( vtkIdType aNodeId = 0; aNodesIter->more(); aNodeId++ ){
581 const SMDS_MeshElement* aNode = aNodesIter->next();
582 anIdList->SetId( aNodeId, mySMDS2VTKNodes[aNode->GetID()] );
586 aConnectivity->InsertNextCell( anIdList );
587 aCellTypesArray->InsertNextValue( getCellType( aType, aNbNodes ) );
594 // Insert cells in grid
596 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
597 aCellLocationsArray->SetNumberOfComponents( 1 );
598 aCellLocationsArray->SetNumberOfTuples( aNbCells );
600 aConnectivity->InitTraversal();
601 for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
602 aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
604 myGrid->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
606 aCellLocationsArray->Delete();
607 aCellTypesArray->Delete();
608 aConnectivity->Delete();
612 //=================================================================================
613 // function : GetEdgeNodes
614 // purpose : Retrieve ids of nodes from edge of elements ( edge is numbered from 1 )
615 //=================================================================================
616 bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
617 const int theEdgeNum,
619 int& theNodeId2 ) const
621 const SMDS_Mesh* aMesh = GetMesh();
625 const SMDS_MeshElement* anElem = aMesh->FindElement( theElemId );
629 int nbNodes = anElem->NbNodes();
631 if ( theEdgeNum < 1 || theEdgeNum > 4 || nbNodes != 3 && nbNodes != 4 || theEdgeNum > nbNodes )
634 int anIds[ nbNodes ];
635 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
637 while( anIter->more() )
638 anIds[ i++ ] = anIter->next()->GetID();
640 if ( nbNodes != theEdgeNum )
642 theNodeId1 = anIds[ theEdgeNum - 1 ];
643 theNodeId2 = anIds[ theEdgeNum ];
647 theNodeId1 = anIds[ nbNodes - 1 ];
648 theNodeId2 = anIds[ 0 ];
655 Class : SMESH_MeshObj
656 Description : Class for visualisation of mesh
659 //=================================================================================
660 // function : SMESH_MeshObj
661 // purpose : Constructor
662 //=================================================================================
663 SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh)
666 MESSAGE("SMESH_MeshObj - theMesh->_is_nil() = "<<theMesh->_is_nil());
668 myMeshServer = SMESH::SMESH_Mesh::_duplicate( theMesh );
669 myMeshServer->Register();
670 myMesh = new SMDS_Mesh();
673 //=================================================================================
674 // function : ~SMESH_MeshObj
675 // purpose : Destructor
676 //=================================================================================
677 SMESH_MeshObj::~SMESH_MeshObj()
679 myMeshServer->Destroy();
683 //=================================================================================
685 // purpose : Update mesh and fill grid with new values if necessary
686 //=================================================================================
687 void SMESH_MeshObj::Update( int theIsClear )
689 // Update SMDS_Mesh on client part
693 SMESH::log_array_var aSeq = myMeshServer->GetLog( theIsClear );
694 CORBA::Long aLength = aSeq->length();
696 if( MYDEBUG ) MESSAGE( "Update: length of the script is "<<aLength );
701 for ( CORBA::Long anId = 0; anId < aLength; anId++)
703 const SMESH::double_array& aCoords = aSeq[anId].coords;
704 const SMESH::long_array& anIndexes = aSeq[anId].indexes;
705 CORBA::Long anElemId = 0, aNbElems = aSeq[anId].number;
706 CORBA::Long aCommand = aSeq[anId].commandType;
710 case SMESH::ADD_NODE : AddNodesWithID ( myMesh, aSeq, anId ); break;
711 case SMESH::ADD_EDGE : AddEdgesWithID ( myMesh, aSeq, anId ); break;
712 case SMESH::ADD_TRIANGLE : AddTriasWithID ( myMesh, aSeq, anId ); break;
713 case SMESH::ADD_QUADRANGLE : AddQuadsWithID ( myMesh, aSeq, anId ); break;
714 case SMESH::ADD_TETRAHEDRON: AddTetrasWithID ( myMesh, aSeq, anId ); break;
715 case SMESH::ADD_PYRAMID : AddPiramidsWithID( myMesh, aSeq, anId ); break;
716 case SMESH::ADD_PRISM : AddPrismsWithID ( myMesh, aSeq, anId ); break;
717 case SMESH::ADD_HEXAHEDRON : AddHexasWithID ( myMesh, aSeq, anId ); break;
719 case SMESH::REMOVE_NODE:
720 for( ; anElemId < aNbElems; anElemId++ )
721 myMesh->RemoveNode( FindNode( myMesh, anIndexes[anElemId] ) );
724 case SMESH::REMOVE_ELEMENT:
725 for( ; anElemId < aNbElems; anElemId++ )
726 myMesh->RemoveElement( FindElement( myMesh, anIndexes[anElemId] ) );
729 case SMESH::MOVE_NODE:
730 for(CORBA::Long aCoordId=0; anElemId < aNbElems; anElemId++, aCoordId+=3)
732 SMDS_MeshNode* node =
733 const_cast<SMDS_MeshNode*>( FindNode( myMesh, anIndexes[anElemId] ));
734 node->setXYZ( aCoords[aCoordId], aCoords[aCoordId+1], aCoords[aCoordId+2] );
738 case SMESH::CHANGE_ELEMENT_NODES:
739 for ( CORBA::Long i = 0; anElemId < aNbElems; anElemId++ )
742 const SMDS_MeshElement* elem = FindElement( myMesh, anIndexes[i++] );
744 int nbNodes = anIndexes[i++];
746 ASSERT( nbNodes < 9 );
747 const SMDS_MeshNode* aNodes[ 8 ];
748 for ( int iNode = 0; iNode < nbNodes; iNode++ )
749 aNodes[ iNode ] = FindNode( myMesh, anIndexes[i++] );
751 myMesh->ChangeElementNodes( elem, aNodes, nbNodes );
755 case SMESH::RENUMBER:
756 for(CORBA::Long i=0; anElemId < aNbElems; anElemId++, i+=3)
758 myMesh->Renumber( anIndexes[i], anIndexes[i+1], anIndexes[i+2] );
766 catch ( SALOME::SALOME_Exception& exc )
768 INFOS("Following exception was cought:\n\t"<<exc.details.text);
770 catch( const std::exception& exc)
772 INFOS("Following exception was cought:\n\t"<<exc.what());
776 INFOS("Unknown exception was cought !!!");
781 MESSAGE("Update - myMesh->NbNodes() = "<<myMesh->NbNodes());
782 MESSAGE("Update - myMesh->NbEdges() = "<<myMesh->NbEdges());
783 MESSAGE("Update - myMesh->NbFaces() = "<<myMesh->NbFaces());
784 MESSAGE("Update - myMesh->NbVolumes() = "<<myMesh->NbVolumes());
787 // Fill unstructured grid
791 //=================================================================================
792 // function : GetElemDimension
793 // purpose : Get dimension of element
794 //=================================================================================
795 int SMESH_MeshObj::GetElemDimension( const int theObjId )
797 const SMDS_MeshElement* anElem = myMesh->FindElement( theObjId );
801 int aType = anElem->GetType();
804 case SMDSAbs_Edge : return 1;
805 case SMDSAbs_Face : return 2;
806 case SMDSAbs_Volume: return 3;
811 //=================================================================================
812 // function : GetEntities
813 // purpose : Get entities of specified type. Return number of entities
814 //=================================================================================
815 int SMESH_MeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const
821 return myMesh->NbNodes();
826 return myMesh->NbEdges();
831 return myMesh->NbFaces();
836 return myMesh->NbVolumes();
845 int SMESH_MeshObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& theObjs ) const
853 SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator();
854 while ( anIter->more() ) theObjs.push_back( anIter->next() );
859 SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
860 while ( anIter->more() ) theObjs.push_back( anIter->next() );
865 SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
866 while ( anIter->more() ) theObjs.push_back( anIter->next() );
871 SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
872 while ( anIter->more() ) theObjs.push_back( anIter->next() );
879 return theObjs.size();
882 //=================================================================================
883 // function : UpdateFunctor
884 // purpose : Update functor in accordance with current mesh
885 //=================================================================================
886 void SMESH_MeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor )
888 theFunctor->SetMesh( GetMesh() );
891 //=================================================================================
892 // function : IsNodePrs
893 // purpose : Return true if node presentation is used
894 //=================================================================================
895 bool SMESH_MeshObj::IsNodePrs() const
897 return myMesh->NbEdges() == 0 &&myMesh->NbFaces() == 0 &&myMesh->NbVolumes() == 0 ;
902 Class : SMESH_SubMeshObj
903 Description : Base class for visualisation of submeshes and groups
906 //=================================================================================
907 // function : SMESH_SubMeshObj
908 // purpose : Constructor
909 //=================================================================================
910 SMESH_SubMeshObj::SMESH_SubMeshObj( SMESH_MeshObj* theMeshObj )
912 if ( MYDEBUG ) MESSAGE( "SMESH_SubMeshObj - theMeshObj = " << theMeshObj );
914 myMeshObj = theMeshObj;
917 SMESH_SubMeshObj::~SMESH_SubMeshObj()
921 //=================================================================================
922 // function : GetElemDimension
923 // purpose : Get dimension of element
924 //=================================================================================
925 int SMESH_SubMeshObj::GetElemDimension( const int theObjId )
927 return myMeshObj == 0 ? 0 : myMeshObj->GetElemDimension( theObjId );
930 //=================================================================================
931 // function : UpdateFunctor
932 // purpose : Update functor in accordance with current mesh
933 //=================================================================================
934 void SMESH_SubMeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor )
936 theFunctor->SetMesh( myMeshObj->GetMesh() );
939 //=================================================================================
941 // purpose : Update mesh object and fill grid with new values
942 //=================================================================================
943 void SMESH_SubMeshObj::Update( int theIsClear )
945 myMeshObj->Update( theIsClear );
951 Class : SMESH_GroupObj
952 Description : Class for visualisation of groups
955 //=================================================================================
956 // function : SMESH_GroupObj
957 // purpose : Constructor
958 //=================================================================================
959 SMESH_GroupObj::SMESH_GroupObj( SMESH::SMESH_GroupBase_ptr theGroup,
960 SMESH_MeshObj* theMeshObj )
961 : SMESH_SubMeshObj( theMeshObj ),
962 myGroupServer( SMESH::SMESH_GroupBase::_duplicate(theGroup) )
964 if ( MYDEBUG ) MESSAGE("SMESH_GroupObj - theGroup->_is_nil() = "<<theGroup->_is_nil());
965 myGroupServer->Register();
968 SMESH_GroupObj::~SMESH_GroupObj()
970 if ( MYDEBUG ) MESSAGE("~SMESH_GroupObj");
971 myGroupServer->Destroy();
974 //=================================================================================
975 // function : IsNodePrs
976 // purpose : Return true if node presentation is used
977 //=================================================================================
978 bool SMESH_GroupObj::IsNodePrs() const
980 return myGroupServer->GetType() == SMESH::NODE;
983 //=================================================================================
984 // function : getNodesFromElems
985 // purpose : Retrieve nodes from elements
986 //=================================================================================
987 static int getNodesFromElems( SMESH::long_array_var& theElemIds,
988 const SMDS_Mesh* theMesh,
989 std::list<const SMDS_MeshElement*>& theResList )
991 set<const SMDS_MeshElement*> aNodeSet;
993 for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ )
995 const SMDS_MeshElement* anElem = theMesh->FindElement( theElemIds[ i ] );
998 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
999 while ( anIter->more() )
1001 const SMDS_MeshElement* aNode = anIter->next();
1003 aNodeSet.insert( aNode );
1008 set<const SMDS_MeshElement*>::const_iterator anIter;
1009 for ( anIter = aNodeSet.begin(); anIter != aNodeSet.end(); ++anIter )
1010 theResList.push_back( *anIter );
1012 return theResList.size();
1015 //=================================================================================
1016 // function : getPointers
1017 // purpose : Get std::list<const SMDS_MeshElement*> from list of IDs
1018 //=================================================================================
1019 static int getPointers( const SMDSAbs_ElementType theRequestType,
1020 SMESH::long_array_var& theElemIds,
1021 const SMDS_Mesh* theMesh,
1022 std::list<const SMDS_MeshElement*>& theResList )
1024 for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ )
1026 const SMDS_MeshElement* anElem = theRequestType == SMDSAbs_Node
1027 ? theMesh->FindNode( theElemIds[ i ] ) : theMesh->FindElement( theElemIds[ i ] );
1030 theResList.push_back( anElem );
1033 return theResList.size();
1037 //=================================================================================
1038 // function : GetEntities
1039 // purpose : Get entities of specified type. Return number of entities
1040 //=================================================================================
1041 int SMESH_GroupObj::GetNbEntities( const SMDSAbs_ElementType theType) const
1043 if(SMDSAbs_ElementType(myGroupServer->GetType()) == theType){
1044 return myGroupServer->Size();
1049 int SMESH_GroupObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& theResList ) const
1052 SMDS_Mesh* aMesh = myMeshObj->GetMesh();
1054 if ( myGroupServer->Size() == 0 || aMesh == 0 )
1057 SMDSAbs_ElementType aGrpType = SMDSAbs_ElementType(myGroupServer->GetType());
1058 SMESH::long_array_var anIds = myGroupServer->GetListOfID();
1060 if ( aGrpType == theType )
1061 return getPointers( theType, anIds, aMesh, theResList );
1062 else if ( theType == SMDSAbs_Node )
1063 return getNodesFromElems( anIds, aMesh, theResList );
1071 Class : SMESH_subMeshObj
1072 Description : Class for visualisation of submeshes
1075 //=================================================================================
1076 // function : SMESH_subMeshObj
1077 // purpose : Constructor
1078 //=================================================================================
1079 SMESH_subMeshObj::SMESH_subMeshObj( SMESH::SMESH_subMesh_ptr theSubMesh,
1080 SMESH_MeshObj* theMeshObj )
1081 : SMESH_SubMeshObj( theMeshObj ),
1082 mySubMeshServer( SMESH::SMESH_subMesh::_duplicate( theSubMesh ) )
1084 if ( MYDEBUG ) MESSAGE( "SMESH_subMeshObj - theSubMesh->_is_nil() = " << theSubMesh->_is_nil() );
1086 mySubMeshServer->Register();
1089 SMESH_subMeshObj::~SMESH_subMeshObj()
1091 if ( MYDEBUG ) MESSAGE( "~SMESH_subMeshObj" );
1092 mySubMeshServer->Destroy();
1095 //=================================================================================
1096 // function : GetEntities
1097 // purpose : Get entities of specified type. Return number of entities
1098 //=================================================================================
1099 int SMESH_subMeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const
1105 return mySubMeshServer->GetNumberOfNodes( false );
1110 case SMDSAbs_Volume:
1112 SMESH::long_array_var anIds =
1113 mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
1114 return anIds->length();
1122 int SMESH_subMeshObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& theResList ) const
1126 SMDS_Mesh* aMesh = myMeshObj->GetMesh();
1130 bool isNodal = IsNodePrs();
1134 if ( theType == SMDSAbs_Node )
1136 SMESH::long_array_var anIds = mySubMeshServer->GetNodesId();
1137 return getPointers( SMDSAbs_Node, anIds, aMesh, theResList );
1142 if ( theType == SMDSAbs_Node )
1144 SMESH::long_array_var anIds = mySubMeshServer->GetElementsId();
1145 return getNodesFromElems( anIds, aMesh, theResList );
1149 SMESH::long_array_var anIds =
1150 mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
1151 return getPointers( theType, anIds, aMesh, theResList );
1158 //=================================================================================
1159 // function : IsNodePrs
1160 // purpose : Return true if node presentation is used
1161 //=================================================================================
1162 bool SMESH_subMeshObj::IsNodePrs() const
1164 return mySubMeshServer->GetNumberOfElements() == 0;