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 myGrid = vtkUnstructuredGrid::New();
292 SMESH_VisualObjDef::~SMESH_VisualObjDef()
295 MESSAGE( "~SMESH_MeshObj - myGrid->GetReferenceCount() = " << myGrid->GetReferenceCount() );
299 //=================================================================================
300 // functions : GetNodeObjId, GetNodeVTKId, GetElemObjId, GetElemVTKId
301 // purpose : Methods for retrieving VTK IDs by SMDS IDs and vice versa
302 //=================================================================================
303 vtkIdType SMESH_VisualObjDef::GetNodeObjId( int theVTKID )
305 return myVTK2SMDSNodes.find(theVTKID) == myVTK2SMDSNodes.end() ? -1 : myVTK2SMDSNodes[theVTKID];
308 vtkIdType SMESH_VisualObjDef::GetNodeVTKId( int theObjID )
310 return mySMDS2VTKNodes.find(theObjID) == mySMDS2VTKNodes.end() ? -1 : mySMDS2VTKNodes[theObjID];
313 vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID )
315 return myVTK2SMDSElems.find(theVTKID) == myVTK2SMDSElems.end() ? -1 : myVTK2SMDSElems[theVTKID];
318 vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID )
320 return mySMDS2VTKElems.find(theObjID) == mySMDS2VTKElems.end() ? -1 : mySMDS2VTKElems[theObjID];
323 //=================================================================================
324 // function : SMESH_VisualObjDef::createPoints
325 // purpose : Create points from nodes
326 //=================================================================================
327 void SMESH_VisualObjDef::createPoints( vtkPoints* thePoints )
329 if ( thePoints == 0 )
333 vtkIdType nbNodes = GetEntities( SMDSAbs_Node, aNodes );
334 thePoints->SetNumberOfPoints( nbNodes );
338 TEntityList::const_iterator anIter;
339 for ( anIter = aNodes.begin(); anIter != aNodes.end(); ++anIter )
341 const SMDS_MeshNode* aNode = ( const SMDS_MeshNode* )(*anIter);
344 thePoints->SetPoint( nbPoints, aNode->X(), aNode->Y(), aNode->Z() );
345 int anId = aNode->GetID();
346 mySMDS2VTKNodes.insert( TMapOfIds::value_type( anId, nbPoints ) );
347 myVTK2SMDSNodes.insert( TMapOfIds::value_type( nbPoints, anId ) );
352 if ( nbPoints != nbNodes )
353 thePoints->SetNumberOfPoints( nbPoints );
356 //=================================================================================
357 // function : buildPrs
358 // purpose : create VTK cells( fill unstructured grid )
359 //=================================================================================
360 void SMESH_VisualObjDef::buildPrs()
364 mySMDS2VTKNodes.clear();
365 myVTK2SMDSNodes.clear();
366 mySMDS2VTKElems.clear();
367 myVTK2SMDSElems.clear();
374 catch( const std::exception& exc )
376 INFOS("Follow exception was cought:\n\t"<<exc.what());
380 INFOS("Unknown exception was cought !!!");
383 if( MYDEBUG ) MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->GetNumberOfCells() );
384 if( MYDEBUGWITHFILES ) SMESH::WriteUnstructuredGrid( myGrid,"/tmp/buildPrs" );
387 //=================================================================================
388 // function : buildNodePrs
389 // purpose : create VTK cells for nodes
390 //=================================================================================
391 void SMESH_VisualObjDef::buildNodePrs()
393 vtkPoints* aPoints = vtkPoints::New();
394 createPoints( aPoints );
395 myGrid->SetPoints( aPoints );
398 myGrid->SetCells( 0, 0, 0 );
402 int nbPoints = aPoints->GetNumberOfPoints();
403 vtkIdList *anIdList = vtkIdList::New();
404 anIdList->SetNumberOfIds( 1 );
406 vtkCellArray *aCells = vtkCellArray::New();
407 aCells->Allocate( 2 * nbPoints, 0 );
409 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
410 aCellTypesArray->SetNumberOfComponents( 1 );
411 aCellTypesArray->Allocate( nbPoints );
413 for( vtkIdType aCellId = 0; aCellId < nbPoints; aCellId++ )
415 anIdList->SetId( 0, aCellId );
416 aCells->InsertNextCell( anIdList );
417 aCellTypesArray->InsertNextValue( VTK_VERTEX );
420 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
421 aCellLocationsArray->SetNumberOfComponents( 1 );
422 aCellLocationsArray->SetNumberOfTuples( nbPoints );
424 aCells->InitTraversal();
425 for( vtkIdType i = 0, *pts, npts; aCells->GetNextCell( npts, pts ); i++ )
426 aCellLocationsArray->SetValue( i, aCells->GetTraversalLocation( npts ) );
428 myGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells );
430 aCellLocationsArray->Delete();
431 aCellTypesArray->Delete();
437 //=================================================================================
438 // function : buildElemPrs
439 // purpose : Create VTK cells for elements
440 //=================================================================================
443 typedef std::vector<const SMDS_MeshElement*> TConnect;
445 int GetConnect(const SMDS_ElemIteratorPtr& theNodesIter,
446 TConnect& theConnect)
449 for(; theNodesIter->more();)
450 theConnect.push_back(theNodesIter->next());
451 return theConnect.size();
455 void SetId(vtkIdList *theIdList,
456 const SMESH_VisualObjDef::TMapOfIds& theSMDS2VTKNodes,
457 const TConnect& theConnect,
461 theIdList->SetId(thePosition,theSMDS2VTKNodes.find(theConnect[theId]->GetID())->second);
467 void SMESH_VisualObjDef::buildElemPrs()
471 vtkPoints* aPoints = vtkPoints::New();
472 createPoints( aPoints );
473 myGrid->SetPoints( aPoints );
477 MESSAGE("Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints());
479 // Calculate cells size
481 static SMDSAbs_ElementType aTypes[ 3 ] = { SMDSAbs_Edge, SMDSAbs_Face, SMDSAbs_Volume };
484 map<SMDSAbs_ElementType,int> nbEnts;
485 map<SMDSAbs_ElementType,TEntityList> anEnts;
487 for ( int i = 0; i <= 2; i++ )
488 nbEnts[ aTypes[ i ] ] = GetEntities( aTypes[ i ], anEnts[ aTypes[ i ] ] );
490 vtkIdType aCellsSize = 3 * nbEnts[ SMDSAbs_Edge ];
492 for ( int i = 1; i <= 2; i++ ) // iterate through faces and volumes
494 if ( nbEnts[ aTypes[ i ] ] )
496 const TEntityList& aList = anEnts[ aTypes[ i ] ];
497 TEntityList::const_iterator anIter;
498 for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
499 aCellsSize += (*anIter)->NbNodes() + 1;
503 vtkIdType aNbCells = nbEnts[ SMDSAbs_Edge ] + nbEnts[ SMDSAbs_Face ] + nbEnts[ SMDSAbs_Volume ];
506 MESSAGE( "Update - aNbCells = "<<aNbCells<<"; aCellsSize = "<<aCellsSize );
510 vtkCellArray* aConnectivity = vtkCellArray::New();
511 aConnectivity->Allocate( aCellsSize, 0 );
513 vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
514 aCellTypesArray->SetNumberOfComponents( 1 );
515 aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
517 vtkIdList *anIdList = vtkIdList::New();
521 aConnect.reserve(VTK_CELL_SIZE);
523 for ( int i = 0; i <= 2; i++ ) // iterate through edges, faces and volumes
525 if( nbEnts[ aTypes[ i ] ] > 0 )
527 const SMDSAbs_ElementType& aType = aTypes[ i ];
528 const TEntityList& aList = anEnts[ aType ];
529 TEntityList::const_iterator anIter;
530 for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
532 const SMDS_MeshElement* anElem = *anIter;
534 vtkIdType aNbNodes = anElem->NbNodes();
535 anIdList->SetNumberOfIds( aNbNodes );
537 int anId = anElem->GetID();
539 mySMDS2VTKElems.insert( TMapOfIds::value_type( anId, iElem ) );
540 myVTK2SMDSElems.insert( TMapOfIds::value_type( iElem, anId ) );
542 SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
544 case SMDSAbs_Volume:{
545 int* aConnectivities = NULL;
546 GetConnect(aNodesIter,aConnect);
547 // Convertions connectivities from SMDS to VTK
550 static int anIds[] = {0,2,1,3};
551 aConnectivities = anIds;
555 static int anIds[] = {0,3,2,1,4};
556 aConnectivities = anIds;
560 static int anIds[] = {0,1,2,3,4,5};
561 aConnectivities = anIds;
565 static int anIds[] = {0,3,2,1,4,7,6,5};
566 aConnectivities = anIds;
571 for( vtkIdType aNodeId = 0; aNodeId < aNbNodes; aNodeId++ )
572 SetId(anIdList,mySMDS2VTKNodes,aConnect,aNodeId,aConnectivities[aNodeId]);
577 for( vtkIdType aNodeId = 0; aNodesIter->more(); aNodeId++ ){
578 const SMDS_MeshElement* aNode = aNodesIter->next();
579 anIdList->SetId( aNodeId, mySMDS2VTKNodes[aNode->GetID()] );
583 aConnectivity->InsertNextCell( anIdList );
584 aCellTypesArray->InsertNextValue( getCellType( aType, aNbNodes ) );
591 // Insert cells in grid
593 vtkIntArray* aCellLocationsArray = vtkIntArray::New();
594 aCellLocationsArray->SetNumberOfComponents( 1 );
595 aCellLocationsArray->SetNumberOfTuples( aNbCells );
597 aConnectivity->InitTraversal();
598 for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
599 aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
601 myGrid->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
603 aCellLocationsArray->Delete();
604 aCellTypesArray->Delete();
605 aConnectivity->Delete();
609 //=================================================================================
610 // function : GetEdgeNodes
611 // purpose : Retrieve ids of nodes from edge of elements ( edge is numbered from 1 )
612 //=================================================================================
613 bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
614 const int theEdgeNum,
616 int& theNodeId2 ) const
618 const SMDS_Mesh* aMesh = GetMesh();
622 const SMDS_MeshElement* anElem = aMesh->FindElement( theElemId );
626 int nbNodes = anElem->NbNodes();
628 if ( theEdgeNum < 1 || theEdgeNum > 4 || nbNodes != 3 && nbNodes != 4 || theEdgeNum > nbNodes )
631 int anIds[ nbNodes ];
632 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
634 while( anIter->more() )
635 anIds[ i++ ] = anIter->next()->GetID();
637 if ( nbNodes != theEdgeNum )
639 theNodeId1 = anIds[ theEdgeNum - 1 ];
640 theNodeId2 = anIds[ theEdgeNum ];
644 theNodeId1 = anIds[ nbNodes - 1 ];
645 theNodeId2 = anIds[ 0 ];
652 Class : SMESH_MeshObj
653 Description : Class for visualisation of mesh
656 //=================================================================================
657 // function : SMESH_MeshObj
658 // purpose : Constructor
659 //=================================================================================
660 SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh)
663 MESSAGE("SMESH_MeshObj - theMesh->_is_nil() = "<<theMesh->_is_nil());
665 myMeshServer = SMESH::SMESH_Mesh::_duplicate( theMesh );
666 myMeshServer->Register();
667 myMesh = new SMDS_Mesh();
670 //=================================================================================
671 // function : ~SMESH_MeshObj
672 // purpose : Destructor
673 //=================================================================================
674 SMESH_MeshObj::~SMESH_MeshObj()
676 myMeshServer->Destroy();
680 //=================================================================================
682 // purpose : Update mesh and fill grid with new values if necessary
683 //=================================================================================
684 void SMESH_MeshObj::Update( int theIsClear )
686 // Update SMDS_Mesh on client part
690 SMESH::log_array_var aSeq = myMeshServer->GetLog( theIsClear );
691 CORBA::Long aLength = aSeq->length();
693 if( MYDEBUG ) MESSAGE( "Update: length of the script is "<<aLength );
698 for ( CORBA::Long anId = 0; anId < aLength; anId++)
700 const SMESH::double_array& aCoords = aSeq[anId].coords;
701 const SMESH::long_array& anIndexes = aSeq[anId].indexes;
702 CORBA::Long anElemId = 0, aNbElems = aSeq[anId].number;
703 CORBA::Long aCommand = aSeq[anId].commandType;
707 case SMESH::ADD_NODE : AddNodesWithID ( myMesh, aSeq, anId ); break;
708 case SMESH::ADD_EDGE : AddEdgesWithID ( myMesh, aSeq, anId ); break;
709 case SMESH::ADD_TRIANGLE : AddTriasWithID ( myMesh, aSeq, anId ); break;
710 case SMESH::ADD_QUADRANGLE : AddQuadsWithID ( myMesh, aSeq, anId ); break;
711 case SMESH::ADD_TETRAHEDRON: AddTetrasWithID ( myMesh, aSeq, anId ); break;
712 case SMESH::ADD_PYRAMID : AddPiramidsWithID( myMesh, aSeq, anId ); break;
713 case SMESH::ADD_PRISM : AddPrismsWithID ( myMesh, aSeq, anId ); break;
714 case SMESH::ADD_HEXAHEDRON : AddHexasWithID ( myMesh, aSeq, anId ); break;
716 case SMESH::REMOVE_NODE:
717 for( ; anElemId < aNbElems; anElemId++ )
718 myMesh->RemoveNode( FindNode( myMesh, anIndexes[anElemId] ) );
721 case SMESH::REMOVE_ELEMENT:
722 for( ; anElemId < aNbElems; anElemId++ )
723 myMesh->RemoveElement( FindElement( myMesh, anIndexes[anElemId] ) );
726 case SMESH::MOVE_NODE:
727 for(CORBA::Long aCoordId=0; anElemId < aNbElems; anElemId++, aCoordId+=3)
729 SMDS_MeshNode* node =
730 const_cast<SMDS_MeshNode*>( FindNode( myMesh, anIndexes[anElemId] ));
731 node->setXYZ( aCoords[aCoordId], aCoords[aCoordId+1], aCoords[aCoordId+2] );
735 case SMESH::CHANGE_ELEMENT_NODES:
736 for ( CORBA::Long i = 0; anElemId < aNbElems; anElemId++ )
739 const SMDS_MeshElement* elem = FindElement( myMesh, anIndexes[i++] );
741 int nbNodes = anIndexes[i++];
743 ASSERT( nbNodes < 9 );
744 const SMDS_MeshNode* aNodes[ 8 ];
745 for ( int iNode = 0; iNode < nbNodes; iNode++ )
746 aNodes[ iNode ] = FindNode( myMesh, anIndexes[i++] );
748 myMesh->ChangeElementNodes( elem, aNodes, nbNodes );
752 case SMESH::RENUMBER:
753 for(CORBA::Long i=0; anElemId < aNbElems; anElemId++, i+=3)
755 myMesh->Renumber( anIndexes[i], anIndexes[i+1], anIndexes[i+2] );
763 catch ( SALOME::SALOME_Exception& exc )
765 INFOS("Following exception was cought:\n\t"<<exc.details.text);
767 catch( const std::exception& exc)
769 INFOS("Following exception was cought:\n\t"<<exc.what());
773 INFOS("Unknown exception was cought !!!");
778 MESSAGE("Update - myMesh->NbNodes() = "<<myMesh->NbNodes());
779 MESSAGE("Update - myMesh->NbEdges() = "<<myMesh->NbEdges());
780 MESSAGE("Update - myMesh->NbFaces() = "<<myMesh->NbFaces());
781 MESSAGE("Update - myMesh->NbVolumes() = "<<myMesh->NbVolumes());
784 // Fill unstructured grid
788 //=================================================================================
789 // function : GetElemDimension
790 // purpose : Get dimension of element
791 //=================================================================================
792 int SMESH_MeshObj::GetElemDimension( const int theObjId )
794 const SMDS_MeshElement* anElem = myMesh->FindElement( theObjId );
798 int aType = anElem->GetType();
801 case SMDSAbs_Edge : return 1;
802 case SMDSAbs_Face : return 2;
803 case SMDSAbs_Volume: return 3;
808 //=================================================================================
809 // function : GetEntities
810 // purpose : Get entities of specified type. Return number of entities
811 //=================================================================================
812 int SMESH_MeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const
818 return myMesh->NbNodes();
823 return myMesh->NbEdges();
828 return myMesh->NbFaces();
833 return myMesh->NbVolumes();
842 int SMESH_MeshObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& theObjs ) const
850 SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator();
851 while ( anIter->more() ) theObjs.push_back( anIter->next() );
856 SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
857 while ( anIter->more() ) theObjs.push_back( anIter->next() );
862 SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
863 while ( anIter->more() ) theObjs.push_back( anIter->next() );
868 SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
869 while ( anIter->more() ) theObjs.push_back( anIter->next() );
876 return theObjs.size();
879 //=================================================================================
880 // function : UpdateFunctor
881 // purpose : Update functor in accordance with current mesh
882 //=================================================================================
883 void SMESH_MeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor )
885 theFunctor->SetMesh( GetMesh() );
888 //=================================================================================
889 // function : IsNodePrs
890 // purpose : Return true if node presentation is used
891 //=================================================================================
892 bool SMESH_MeshObj::IsNodePrs() const
894 return myMesh->NbEdges() == 0 &&myMesh->NbFaces() == 0 &&myMesh->NbVolumes() == 0 ;
899 Class : SMESH_SubMeshObj
900 Description : Base class for visualisation of submeshes and groups
903 //=================================================================================
904 // function : SMESH_SubMeshObj
905 // purpose : Constructor
906 //=================================================================================
907 SMESH_SubMeshObj::SMESH_SubMeshObj( SMESH_MeshObj* theMeshObj )
909 if ( MYDEBUG ) MESSAGE( "SMESH_SubMeshObj - theMeshObj = " << theMeshObj );
911 myMeshObj = theMeshObj;
914 SMESH_SubMeshObj::~SMESH_SubMeshObj()
918 //=================================================================================
919 // function : GetElemDimension
920 // purpose : Get dimension of element
921 //=================================================================================
922 int SMESH_SubMeshObj::GetElemDimension( const int theObjId )
924 return myMeshObj == 0 ? 0 : myMeshObj->GetElemDimension( theObjId );
927 //=================================================================================
928 // function : UpdateFunctor
929 // purpose : Update functor in accordance with current mesh
930 //=================================================================================
931 void SMESH_SubMeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor )
933 theFunctor->SetMesh( myMeshObj->GetMesh() );
936 //=================================================================================
938 // purpose : Update mesh object and fill grid with new values
939 //=================================================================================
940 void SMESH_SubMeshObj::Update( int theIsClear )
942 myMeshObj->Update( theIsClear );
948 Class : SMESH_GroupObj
949 Description : Class for visualisation of groups
952 //=================================================================================
953 // function : SMESH_GroupObj
954 // purpose : Constructor
955 //=================================================================================
956 SMESH_GroupObj::SMESH_GroupObj( SMESH::SMESH_GroupBase_ptr theGroup,
957 SMESH_MeshObj* theMeshObj )
958 : SMESH_SubMeshObj( theMeshObj ),
959 myGroupServer( SMESH::SMESH_GroupBase::_duplicate(theGroup) )
961 if ( MYDEBUG ) MESSAGE("SMESH_GroupObj - theGroup->_is_nil() = "<<theGroup->_is_nil());
962 myGroupServer->Register();
965 SMESH_GroupObj::~SMESH_GroupObj()
967 if ( MYDEBUG ) MESSAGE("~SMESH_GroupObj");
968 myGroupServer->Destroy();
971 //=================================================================================
972 // function : IsNodePrs
973 // purpose : Return true if node presentation is used
974 //=================================================================================
975 bool SMESH_GroupObj::IsNodePrs() const
977 return myGroupServer->GetType() == SMESH::NODE;
980 //=================================================================================
981 // function : getNodesFromElems
982 // purpose : Retrieve nodes from elements
983 //=================================================================================
984 static int getNodesFromElems( SMESH::long_array_var& theElemIds,
985 const SMDS_Mesh* theMesh,
986 std::list<const SMDS_MeshElement*>& theResList )
988 set<const SMDS_MeshElement*> aNodeSet;
990 for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ )
992 const SMDS_MeshElement* anElem = theMesh->FindElement( theElemIds[ i ] );
995 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
996 while ( anIter->more() )
998 const SMDS_MeshElement* aNode = anIter->next();
1000 aNodeSet.insert( aNode );
1005 set<const SMDS_MeshElement*>::const_iterator anIter;
1006 for ( anIter = aNodeSet.begin(); anIter != aNodeSet.end(); ++anIter )
1007 theResList.push_back( *anIter );
1009 return theResList.size();
1012 //=================================================================================
1013 // function : getPointers
1014 // purpose : Get std::list<const SMDS_MeshElement*> from list of IDs
1015 //=================================================================================
1016 static int getPointers( const SMDSAbs_ElementType theRequestType,
1017 SMESH::long_array_var& theElemIds,
1018 const SMDS_Mesh* theMesh,
1019 std::list<const SMDS_MeshElement*>& theResList )
1021 for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ )
1023 const SMDS_MeshElement* anElem = theRequestType == SMDSAbs_Node
1024 ? theMesh->FindNode( theElemIds[ i ] ) : theMesh->FindElement( theElemIds[ i ] );
1027 theResList.push_back( anElem );
1030 return theResList.size();
1034 //=================================================================================
1035 // function : GetEntities
1036 // purpose : Get entities of specified type. Return number of entities
1037 //=================================================================================
1038 int SMESH_GroupObj::GetNbEntities( const SMDSAbs_ElementType theType) const
1040 if(SMDSAbs_ElementType(myGroupServer->GetType()) == theType){
1041 return myGroupServer->Size();
1046 int SMESH_GroupObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& theResList ) const
1049 SMDS_Mesh* aMesh = myMeshObj->GetMesh();
1051 if ( myGroupServer->Size() == 0 || aMesh == 0 )
1054 SMDSAbs_ElementType aGrpType = SMDSAbs_ElementType(myGroupServer->GetType());
1055 SMESH::long_array_var anIds = myGroupServer->GetListOfID();
1057 if ( aGrpType == theType )
1058 return getPointers( theType, anIds, aMesh, theResList );
1059 else if ( theType == SMDSAbs_Node )
1060 return getNodesFromElems( anIds, aMesh, theResList );
1068 Class : SMESH_subMeshObj
1069 Description : Class for visualisation of submeshes
1072 //=================================================================================
1073 // function : SMESH_subMeshObj
1074 // purpose : Constructor
1075 //=================================================================================
1076 SMESH_subMeshObj::SMESH_subMeshObj( SMESH::SMESH_subMesh_ptr theSubMesh,
1077 SMESH_MeshObj* theMeshObj )
1078 : SMESH_SubMeshObj( theMeshObj ),
1079 mySubMeshServer( SMESH::SMESH_subMesh::_duplicate( theSubMesh ) )
1081 if ( MYDEBUG ) MESSAGE( "SMESH_subMeshObj - theSubMesh->_is_nil() = " << theSubMesh->_is_nil() );
1083 mySubMeshServer->Register();
1086 SMESH_subMeshObj::~SMESH_subMeshObj()
1088 if ( MYDEBUG ) MESSAGE( "~SMESH_subMeshObj" );
1089 mySubMeshServer->Destroy();
1092 //=================================================================================
1093 // function : GetEntities
1094 // purpose : Get entities of specified type. Return number of entities
1095 //=================================================================================
1096 int SMESH_subMeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const
1102 return mySubMeshServer->GetNumberOfNodes( false );
1107 case SMDSAbs_Volume:
1109 SMESH::long_array_var anIds =
1110 mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
1111 return anIds->length();
1119 int SMESH_subMeshObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& theResList ) const
1123 SMDS_Mesh* aMesh = myMeshObj->GetMesh();
1127 bool isNodal = IsNodePrs();
1131 if ( theType == SMDSAbs_Node )
1133 SMESH::long_array_var anIds = mySubMeshServer->GetNodesId();
1134 return getPointers( SMDSAbs_Node, anIds, aMesh, theResList );
1139 if ( theType == SMDSAbs_Node )
1141 SMESH::long_array_var anIds = mySubMeshServer->GetElementsId();
1142 return getNodesFromElems( anIds, aMesh, theResList );
1146 SMESH::long_array_var anIds =
1147 mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
1148 return getPointers( theType, anIds, aMesh, theResList );
1155 //=================================================================================
1156 // function : IsNodePrs
1157 // purpose : Return true if node presentation is used
1158 //=================================================================================
1159 bool SMESH_subMeshObj::IsNodePrs() const
1161 return mySubMeshServer->GetNumberOfElements() == 0;