1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 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.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // SMESH OBJECT : interactive object for SMESH visualization
23 // File : SMESH_Grid.cxx
24 // Author : Nicolas REJNERI
27 #include "SMESH_ObjectDef.h"
28 #include "SMESH_ActorUtils.h"
30 #include "SMDS_Mesh.hxx"
31 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
32 #include "SMESH_Actor.h"
33 #include "SMESH_ControlsDef.hxx"
34 #include "SalomeApp_Application.h"
35 #include "VTKViewer_ExtractUnstructuredGrid.h"
36 #include "VTKViewer_CellLocationsArray.h"
38 #include CORBA_SERVER_HEADER(SMESH_Gen)
39 #include CORBA_SERVER_HEADER(SALOME_Exception)
42 #include <vtkIdList.h>
43 #include <vtkCellArray.h>
44 #include <vtkUnsignedCharArray.h>
46 #include <vtkUnstructuredGrid.h>
53 #include "utilities.h"
58 #define EXCEPTION(TYPE, MSG) {\
59 std::ostringstream aStream;\
60 aStream<<__FILE__<<"["<<__LINE__<<"]::"<<MSG;\
61 throw TYPE(aStream.str());\
66 static int MYDEBUG = 1;
67 static int MYDEBUGWITHFILES = 0;
69 static int MYDEBUG = 0;
70 static int MYDEBUGWITHFILES = 0;
75 Class : SMESH_VisualObjDef
76 Description : Base class for all mesh objects to be visuilised
79 //=================================================================================
80 // function : getCellType
81 // purpose : Get type of VTK cell
82 //=================================================================================
83 static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
85 const int theNbNodes )
89 case SMDSAbs_0DElement:
93 if( theNbNodes == 2 ) return VTK_LINE;
94 else if ( theNbNodes == 3 ) return VTK_QUADRATIC_EDGE;
95 else return VTK_EMPTY_CELL;
98 if (thePoly && theNbNodes>2 ) return VTK_POLYGON;
99 else if ( theNbNodes == 3 ) return VTK_TRIANGLE;
100 else if ( theNbNodes == 4 ) return VTK_QUAD;
101 else if ( theNbNodes == 6 ) return VTK_QUADRATIC_TRIANGLE;
102 else if ( theNbNodes == 8 ) return VTK_QUADRATIC_QUAD;
103 else return VTK_EMPTY_CELL;
106 if (thePoly && theNbNodes>3 ) return VTK_CONVEX_POINT_SET;
107 else if ( theNbNodes == 4 ) return VTK_TETRA;
108 else if ( theNbNodes == 5 ) return VTK_PYRAMID;
109 else if ( theNbNodes == 6 ) return VTK_WEDGE;
110 else if ( theNbNodes == 8 ) return VTK_HEXAHEDRON;
111 else if ( theNbNodes == 10 ) {
112 return VTK_QUADRATIC_TETRA;
114 else if ( theNbNodes == 20 ) {
115 return VTK_QUADRATIC_HEXAHEDRON;
117 else if ( theNbNodes == 15 ) {
118 return VTK_QUADRATIC_WEDGE;
120 else if ( theNbNodes==13 ) {
121 return VTK_CONVEX_POINT_SET;
123 else return VTK_EMPTY_CELL;
125 default: return VTK_EMPTY_CELL;
129 //=================================================================================
130 // functions : SMESH_VisualObjDef
131 // purpose : Constructor
132 //=================================================================================
133 SMESH_VisualObjDef::SMESH_VisualObjDef()
135 MESSAGE("---------------------------------------------SMESH_VisualObjDef::SMESH_VisualObjDef");
136 myGrid = vtkUnstructuredGrid::New();
138 SMESH_VisualObjDef::~SMESH_VisualObjDef()
140 MESSAGE("---------------------------------------------SMESH_VisualObjDef::~SMESH_VisualObjDef");
142 MESSAGE( "~SMESH_MeshObj - myGrid->GetReferenceCount() = " << myGrid->GetReferenceCount() );
146 //=================================================================================
147 // functions : GetNodeObjId, GetNodeVTKId, GetElemObjId, GetElemVTKId
148 // purpose : Methods for retrieving VTK IDs by SMDS IDs and vice versa
149 //=================================================================================
150 vtkIdType SMESH_VisualObjDef::GetNodeObjId( int theVTKID )
152 // TMapOfIds::const_iterator i = myVTK2SMDSNodes.find(theVTKID);
153 // return i == myVTK2SMDSNodes.end() ? -1 : i->second;
157 vtkIdType SMESH_VisualObjDef::GetNodeVTKId( int theObjID )
159 // TMapOfIds::const_iterator i = mySMDS2VTKNodes.find(theObjID);
160 // return i == mySMDS2VTKNodes.end() ? -1 : i->second;
164 vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID )
166 // TMapOfIds::const_iterator i = myVTK2SMDSElems.find(theVTKID);
167 // return i == myVTK2SMDSElems.end() ? -1 : i->second;
168 return this->GetMesh()->fromVtkToSmds(theVTKID);
171 vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID )
173 // TMapOfIds::const_iterator i = mySMDS2VTKElems.find(theObjID);
174 // return i == mySMDS2VTKElems.end() ? -1 : i->second;
175 return this->GetMesh()->fromSmdsToVtk(theObjID);
178 //=================================================================================
179 // function : SMESH_VisualObjDef::createPoints
180 // purpose : Create points from nodes
181 //=================================================================================
183 //void SMESH_VisualObjDef::createPoints( vtkPoints* thePoints )
185 // if ( thePoints == 0 )
188 // TEntityList aNodes;
189 // vtkIdType nbNodes = GetEntities( SMDSAbs_Node, aNodes );
190 // thePoints->SetNumberOfPoints( nbNodes );
194 // TEntityList::const_iterator anIter;
195 // for ( anIter = aNodes.begin(); anIter != aNodes.end(); ++anIter )
197 // const SMDS_MeshNode* aNode = ( const SMDS_MeshNode* )(*anIter);
200 // thePoints->SetPoint( nbPoints, aNode->X(), aNode->Y(), aNode->Z() );
201 // int anId = aNode->GetID();
202 // mySMDS2VTKNodes.insert( TMapOfIds::value_type( anId, nbPoints ) );
203 // myVTK2SMDSNodes.insert( TMapOfIds::value_type( nbPoints, anId ) );
208 // if ( nbPoints != nbNodes )
209 // thePoints->SetNumberOfPoints( nbPoints );
212 //=================================================================================
213 // function : buildPrs
214 // purpose : create VTK cells( fill unstructured grid )
215 //=================================================================================
216 void SMESH_VisualObjDef::buildPrs()
220 // mySMDS2VTKNodes.clear();
221 // myVTK2SMDSNodes.clear();
222 // mySMDS2VTKElems.clear();
223 // myVTK2SMDSElems.clear();
225 // if ( IsNodePrs() )
232 // mySMDS2VTKNodes.clear();
233 // myVTK2SMDSNodes.clear();
234 // mySMDS2VTKElems.clear();
235 // myVTK2SMDSElems.clear();
237 // myGrid->SetPoints( 0 );
238 // myGrid->SetCells( 0, 0, 0 );
241 MESSAGE("----------------------------------------------------------SMESH_VisualObjDef::buildPrs");
242 vtkUnstructuredGrid *theGrid = GetMesh()->getGrid();
243 myGrid->ShallowCopy(theGrid);
244 MESSAGE(myGrid->GetReferenceCount());
245 MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->GetNumberOfCells() );
246 MESSAGE( "Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints() );
247 if( MYDEBUGWITHFILES ) SMESH::WriteUnstructuredGrid( myGrid,"/tmp/buildPrs" );
250 //=================================================================================
251 // function : buildNodePrs
252 // purpose : create VTK cells for nodes
253 //=================================================================================
255 //void SMESH_VisualObjDef::buildNodePrs()
257 // // PAL16631: without swap, bad_alloc is not thrown but hung up and crash instead,
258 // // so check remaining memory size for safety
259 // SMDS_Mesh::CheckMemory(); // PAL16631
260 // vtkPoints* aPoints = vtkPoints::New();
261 // createPoints( aPoints );
262 // SMDS_Mesh::CheckMemory();
263 // myGrid->SetPoints( aPoints );
264 // aPoints->Delete();
266 // myGrid->SetCells( 0, 0, 0 );
269 //=================================================================================
270 // function : buildElemPrs
271 // purpose : Create VTK cells for elements
272 //=================================================================================
275 typedef std::vector<const SMDS_MeshElement*> TConnect;
277 int GetConnect(const SMDS_ElemIteratorPtr& theNodesIter,
278 TConnect& theConnect)
281 for(; theNodesIter->more();)
282 theConnect.push_back(theNodesIter->next());
283 return theConnect.size();
287 void SetId(vtkIdList *theIdList,
288 const SMESH_VisualObjDef::TMapOfIds& theSMDS2VTKNodes,
289 const TConnect& theConnect,
293 theIdList->SetId(thePosition,theSMDS2VTKNodes.find(theConnect[theId]->GetID())->second);
299 //void SMESH_VisualObjDef::buildElemPrs()
303 // vtkPoints* aPoints = vtkPoints::New();
304 // createPoints( aPoints );
305 // myGrid->SetPoints( aPoints );
306 // aPoints->Delete();
309 // MESSAGE("Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints());
311 // // Calculate cells size
313 // static SMDSAbs_ElementType aTypes[ 4 ] =
314 // { SMDSAbs_0DElement, SMDSAbs_Edge, SMDSAbs_Face, SMDSAbs_Volume };
316 // // get entity data
317 // map<SMDSAbs_ElementType,int> nbEnts;
318 // map<SMDSAbs_ElementType,TEntityList> anEnts;
320 // for ( int i = 0; i <= 3; i++ )
321 // nbEnts[ aTypes[ i ] ] = GetEntities( aTypes[ i ], anEnts[ aTypes[ i ] ] );
323 // // PAL16631: without swap, bad_alloc is not thrown but hung up and crash instead,
324 // // so check remaining memory size for safety
325 // SMDS_Mesh::CheckMemory(); // PAL16631
327 // vtkIdType aCellsSize = 2 * nbEnts[ SMDSAbs_0DElement ] + 3 * nbEnts[ SMDSAbs_Edge ];
329 // for ( int i = 2; i <= 3; i++ ) // iterate through faces and volumes
331 // if ( nbEnts[ aTypes[ i ] ] )
333 // const TEntityList& aList = anEnts[ aTypes[ i ] ];
334 // TEntityList::const_iterator anIter;
335 // for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
336 // aCellsSize += (*anIter)->NbNodes() + 1;
340 // vtkIdType aNbCells = nbEnts[ SMDSAbs_0DElement ] + nbEnts[ SMDSAbs_Edge ] +
341 // nbEnts[ SMDSAbs_Face ] + nbEnts[ SMDSAbs_Volume ];
344 // MESSAGE( "Update - aNbCells = "<<aNbCells<<"; aCellsSize = "<<aCellsSize );
348 // vtkCellArray* aConnectivity = vtkCellArray::New();
349 // aConnectivity->Allocate( aCellsSize, 0 );
351 // SMDS_Mesh::CheckMemory(); // PAL16631
353 // vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
354 // aCellTypesArray->SetNumberOfComponents( 1 );
355 // aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
357 // SMDS_Mesh::CheckMemory(); // PAL16631
359 // vtkIdList *anIdList = vtkIdList::New();
360 // vtkIdType iElem = 0;
362 // TConnect aConnect;
363 // aConnect.reserve(VTK_CELL_SIZE);
365 // SMDS_Mesh::CheckMemory(); // PAL16631
367 // for ( int i = 0; i <= 3; i++ ) // iterate through 0d elements, edges, faces and volumes
369 // if ( nbEnts[ aTypes[ i ] ] > 0 )
371 // const SMDSAbs_ElementType& aType = aTypes[ i ];
372 // const TEntityList& aList = anEnts[ aType ];
373 // TEntityList::const_iterator anIter;
374 // for ( anIter = aList.begin(); anIter != aList.end(); ++anIter )
376 // const SMDS_MeshElement* anElem = *anIter;
378 // vtkIdType aNbNodes = anElem->NbNodes();
379 // anIdList->SetNumberOfIds( aNbNodes );
381 // int anId = anElem->GetID();
383 // mySMDS2VTKElems.insert( TMapOfIds::value_type( anId, iElem ) );
384 // myVTK2SMDSElems.insert( TMapOfIds::value_type( iElem, anId ) );
386 // SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
388 // case SMDSAbs_Volume:{
390 // std::vector<int> aConnectivities;
391 // // Convertions connectivities from SMDS to VTK
392 // if (anElem->IsPoly() && aNbNodes > 3) { // POLYEDRE
394 // if ( const SMDS_PolyhedralVolumeOfNodes* ph =
395 // dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem))
397 // aNbNodes = GetConnect(ph->uniqueNodesIterator(),aConnect);
398 // anIdList->SetNumberOfIds( aNbNodes );
400 // for (int k = 0; k < aNbNodes; k++)
401 // aConnectivities.push_back(k);
403 // } else if (aNbNodes == 4) {
404 // static int anIds[] = {0,2,1,3};
405 // for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
407 // } else if (aNbNodes == 5) {
408 // static int anIds[] = {0,3,2,1,4};
409 // for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
411 // } else if (aNbNodes == 6) {
412 // static int anIds[] = {0,1,2,3,4,5};
413 // for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
416 // else if (aNbNodes == 8) {
417 // static int anIds[] = {0,3,2,1,4,7,6,5};
418 // for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
421 // else if (aNbNodes == 10) {
422 // static int anIds[] = {0,2,1,3,6,5,4,7,9,8};
423 // for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
425 // else if (aNbNodes == 13) {
426 // static int anIds[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
427 // for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
429 // else if (aNbNodes == 15) {
430 // //static int anIds[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13};
431 // static int anIds[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
432 // for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
433 // //for (int k = 0; k < aNbNodes; k++) {
434 // // int nn = aConnectivities[k];
435 // // const SMDS_MeshNode* N = static_cast<const SMDS_MeshNode*> (aConnect[nn]);
436 // // cout<<"k="<<k<<" N("<<N->X()<<","<<N->Y()<<","<<N->Z()<<")"<<endl;
439 // else if (aNbNodes == 20) {
440 // static int anIds[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
441 // for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
446 // if ( aConnect.empty() )
447 // GetConnect(aNodesIter,aConnect);
449 // if (aConnectivities.size() > 0) {
450 // for (vtkIdType aNodeId = 0; aNodeId < aNbNodes; aNodeId++)
451 // SetId(anIdList,mySMDS2VTKNodes,aConnect,aNodeId,aConnectivities[aNodeId]);
456 // for( vtkIdType aNodeId = 0; aNodesIter->more(); aNodeId++ ){
457 // const SMDS_MeshElement* aNode = aNodesIter->next();
458 // anIdList->SetId( aNodeId, mySMDS2VTKNodes[aNode->GetID()] );
462 // aConnectivity->InsertNextCell( anIdList );
463 // aCellTypesArray->InsertNextValue( getCellType( aType, anElem->IsPoly(), aNbNodes ) );
468 // SMDS_Mesh::CheckMemory(); // PAL16631
471 // // Insert cells in grid
473 // VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
474 // aCellLocationsArray->SetNumberOfComponents( 1 );
475 // aCellLocationsArray->SetNumberOfTuples( aNbCells );
477 // SMDS_Mesh::CheckMemory(); // PAL16631
479 // aConnectivity->InitTraversal();
480 // for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
481 // aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
483 // myGrid->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
485 // aCellLocationsArray->Delete();
486 // aCellTypesArray->Delete();
487 // aConnectivity->Delete();
488 // anIdList->Delete();
490 // SMDS_Mesh::CheckMemory(); // PAL16631
493 //=================================================================================
494 // function : GetEdgeNodes
495 // purpose : Retrieve ids of nodes from edge of elements ( edge is numbered from 1 )
496 //=================================================================================
497 bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
498 const int theEdgeNum,
500 int& theNodeId2 ) const
502 const SMDS_Mesh* aMesh = GetMesh();
506 const SMDS_MeshElement* anElem = aMesh->FindElement( theElemId );
510 int nbNodes = anElem->NbNodes();
512 if ( theEdgeNum < 0 || theEdgeNum > 3 || nbNodes != 3 && nbNodes != 4 || theEdgeNum > nbNodes )
515 vector<int> anIds( nbNodes );
516 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
518 while( anIter->more() )
519 anIds[ i++ ] = anIter->next()->GetID();
521 if ( theEdgeNum < nbNodes - 1 )
523 theNodeId1 = anIds[ theEdgeNum ];
524 theNodeId2 = anIds[ theEdgeNum + 1 ];
528 theNodeId1 = anIds[ nbNodes - 1 ];
529 theNodeId2 = anIds[ 0 ];
535 vtkUnstructuredGrid* SMESH_VisualObjDef::GetUnstructuredGrid()
537 MESSAGE("SMESH_VisualObjDef::GetUnstructuredGrid " << myGrid);
542 //=================================================================================
543 // function : IsValid
544 // purpose : Return true if there are some entities
545 //=================================================================================
546 bool SMESH_VisualObjDef::IsValid() const
548 MESSAGE("SMESH_VisualObjDef::IsValid");
549 return GetNbEntities(SMDSAbs_Node) > 0 ||
550 GetNbEntities(SMDSAbs_0DElement) > 0 ||
551 GetNbEntities(SMDSAbs_Edge) > 0 ||
552 GetNbEntities(SMDSAbs_Face) > 0 ||
553 GetNbEntities(SMDSAbs_Volume) > 0 ;
557 Class : SMESH_MeshObj
558 Description : Class for visualisation of mesh
561 //=================================================================================
562 // function : SMESH_MeshObj
563 // purpose : Constructor
564 //=================================================================================
565 SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh):
566 myClient(SalomeApp_Application::orb(),theMesh)
570 MESSAGE("SMESH_MeshObj - this = "<<this<<"; theMesh->_is_nil() = "<<theMesh->_is_nil());
573 //=================================================================================
574 // function : ~SMESH_MeshObj
575 // purpose : Destructor
576 //=================================================================================
577 SMESH_MeshObj::~SMESH_MeshObj()
580 MESSAGE("SMESH_MeshObj - this = "<<this<<"\n");
583 //=================================================================================
585 // purpose : Update mesh and fill grid with new values if necessary
586 //=================================================================================
587 bool SMESH_MeshObj::Update( int theIsClear )
589 // Update SMDS_Mesh on client part
590 MESSAGE("SMESH_MeshObj::Update");
591 if ( myClient.Update(theIsClear) || GetUnstructuredGrid()->GetNumberOfPoints()==0) {
592 buildPrs(); // Fill unstructured grid
598 bool SMESH_MeshObj::NulData()
600 MESSAGE ("SMESH_MeshObj::NulData() ==================================================================================");
603 myEmptyGrid = SMDS_UnstructuredGrid::New();
604 myEmptyGrid->Initialize();
605 myEmptyGrid->Allocate();
606 vtkPoints* points = vtkPoints::New();
607 points->SetNumberOfPoints(0);
608 myEmptyGrid->SetPoints( points );
610 myEmptyGrid->BuildLinks();
612 myGrid->ShallowCopy(myEmptyGrid);
614 //=================================================================================
615 // function : GetElemDimension
616 // purpose : Get dimension of element
617 //=================================================================================
618 int SMESH_MeshObj::GetElemDimension( const int theObjId )
620 const SMDS_MeshElement* anElem = myClient->FindElement( theObjId );
624 int aType = anElem->GetType();
627 case SMDSAbs_0DElement : return 0;
628 case SMDSAbs_Edge : return 1;
629 case SMDSAbs_Face : return 2;
630 case SMDSAbs_Volume: return 3;
635 //=================================================================================
636 // function : GetEntities
637 // purpose : Get entities of specified type. Return number of entities
638 //=================================================================================
639 int SMESH_MeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const
645 return myClient->NbNodes();
648 case SMDSAbs_0DElement:
650 return myClient->Nb0DElements();
655 return myClient->NbEdges();
660 return myClient->NbFaces();
665 return myClient->NbVolumes();
674 int SMESH_MeshObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& theObjs ) const
682 SMDS_NodeIteratorPtr anIter = myClient->nodesIterator();
683 while ( anIter->more() ) theObjs.push_back( anIter->next() );
686 case SMDSAbs_0DElement:
688 SMDS_0DElementIteratorPtr anIter = myClient->elements0dIterator();
689 while ( anIter->more() ) theObjs.push_back( anIter->next() );
694 SMDS_EdgeIteratorPtr anIter = myClient->edgesIterator();
695 while ( anIter->more() ) theObjs.push_back( anIter->next() );
700 SMDS_FaceIteratorPtr anIter = myClient->facesIterator();
701 while ( anIter->more() ) theObjs.push_back( anIter->next() );
706 SMDS_VolumeIteratorPtr anIter = myClient->volumesIterator();
707 while ( anIter->more() ) theObjs.push_back( anIter->next() );
714 return theObjs.size();
717 //=================================================================================
718 // function : UpdateFunctor
719 // purpose : Update functor in accordance with current mesh
720 //=================================================================================
721 void SMESH_MeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor )
723 theFunctor->SetMesh( GetMesh() );
726 //=================================================================================
727 // function : IsNodePrs
728 // purpose : Return true if node presentation is used
729 //=================================================================================
730 bool SMESH_MeshObj::IsNodePrs() const
732 return myClient->Nb0DElements() == 0 && myClient->NbEdges() == 0 && myClient->NbFaces() == 0 && myClient->NbVolumes() == 0 ;
737 Class : SMESH_SubMeshObj
738 Description : Base class for visualisation of submeshes and groups
741 //=================================================================================
742 // function : SMESH_SubMeshObj
743 // purpose : Constructor
744 //=================================================================================
745 SMESH_SubMeshObj::SMESH_SubMeshObj( SMESH_MeshObj* theMeshObj )
747 if ( MYDEBUG ) MESSAGE( "SMESH_SubMeshObj - theMeshObj = " << theMeshObj );
749 myMeshObj = theMeshObj;
752 SMESH_SubMeshObj::~SMESH_SubMeshObj()
756 //=================================================================================
757 // function : GetElemDimension
758 // purpose : Get dimension of element
759 //=================================================================================
760 int SMESH_SubMeshObj::GetElemDimension( const int theObjId )
762 return myMeshObj == 0 ? 0 : myMeshObj->GetElemDimension( theObjId );
765 //=================================================================================
766 // function : UpdateFunctor
767 // purpose : Update functor in accordance with current mesh
768 //=================================================================================
769 void SMESH_SubMeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor )
771 theFunctor->SetMesh( myMeshObj->GetMesh() );
774 //=================================================================================
776 // purpose : Update mesh object and fill grid with new values
777 //=================================================================================
778 bool SMESH_SubMeshObj::Update( int theIsClear )
780 bool changed = myMeshObj->Update( theIsClear );
787 Class : SMESH_GroupObj
788 Description : Class for visualisation of groups
791 //=================================================================================
792 // function : SMESH_GroupObj
793 // purpose : Constructor
794 //=================================================================================
795 SMESH_GroupObj::SMESH_GroupObj( SMESH::SMESH_GroupBase_ptr theGroup,
796 SMESH_MeshObj* theMeshObj )
797 : SMESH_SubMeshObj( theMeshObj ),
798 myGroupServer( SMESH::SMESH_GroupBase::_duplicate(theGroup) )
800 if ( MYDEBUG ) MESSAGE("SMESH_GroupObj - theGroup->_is_nil() = "<<theGroup->_is_nil());
801 myGroupServer->Register();
804 SMESH_GroupObj::~SMESH_GroupObj()
806 if ( MYDEBUG ) MESSAGE("~SMESH_GroupObj");
807 myGroupServer->Destroy();
810 //=================================================================================
811 // function : IsNodePrs
812 // purpose : Return true if node presentation is used
813 //=================================================================================
814 bool SMESH_GroupObj::IsNodePrs() const
816 return myGroupServer->GetType() == SMESH::NODE;
819 //=================================================================================
820 // function : GetElementType
821 // purpose : Return type of elements of group
822 //=================================================================================
823 SMDSAbs_ElementType SMESH_GroupObj::GetElementType() const
825 return SMDSAbs_ElementType(myGroupServer->GetType());
828 //=================================================================================
829 // function : getNodesFromElems
830 // purpose : Retrieve nodes from elements
831 //=================================================================================
832 static int getNodesFromElems( SMESH::long_array_var& theElemIds,
833 const SMDS_Mesh* theMesh,
834 std::list<const SMDS_MeshElement*>& theResList )
836 set<const SMDS_MeshElement*> aNodeSet;
838 for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ )
840 const SMDS_MeshElement* anElem = theMesh->FindElement( theElemIds[ i ] );
843 SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
844 while ( anIter->more() )
846 const SMDS_MeshElement* aNode = anIter->next();
848 aNodeSet.insert( aNode );
853 set<const SMDS_MeshElement*>::const_iterator anIter;
854 for ( anIter = aNodeSet.begin(); anIter != aNodeSet.end(); ++anIter )
855 theResList.push_back( *anIter );
857 return theResList.size();
860 //=================================================================================
861 // function : getPointers
862 // purpose : Get std::list<const SMDS_MeshElement*> from list of IDs
863 //=================================================================================
864 static int getPointers( const SMDSAbs_ElementType theRequestType,
865 SMESH::long_array_var& theElemIds,
866 const SMDS_Mesh* theMesh,
867 std::list<const SMDS_MeshElement*>& theResList )
869 for ( CORBA::Long i = 0, n = theElemIds->length(); i < n; i++ )
871 const SMDS_MeshElement* anElem = theRequestType == SMDSAbs_Node
872 ? theMesh->FindNode( theElemIds[ i ] ) : theMesh->FindElement( theElemIds[ i ] );
875 theResList.push_back( anElem );
878 return theResList.size();
882 //=================================================================================
883 // function : GetEntities
884 // purpose : Get entities of specified type. Return number of entities
885 //=================================================================================
886 int SMESH_GroupObj::GetNbEntities( const SMDSAbs_ElementType theType) const
888 if(SMDSAbs_ElementType(myGroupServer->GetType()) == theType){
889 return myGroupServer->Size();
894 int SMESH_GroupObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& theResList ) const
897 SMDS_Mesh* aMesh = myMeshObj->GetMesh();
899 if ( myGroupServer->Size() == 0 || aMesh == 0 )
902 SMDSAbs_ElementType aGrpType = SMDSAbs_ElementType(myGroupServer->GetType());
903 SMESH::long_array_var anIds = myGroupServer->GetListOfID();
905 if ( aGrpType == theType )
906 return getPointers( theType, anIds, aMesh, theResList );
907 else if ( theType == SMDSAbs_Node )
908 return getNodesFromElems( anIds, aMesh, theResList );
916 Class : SMESH_subMeshObj
917 Description : Class for visualisation of submeshes
920 //=================================================================================
921 // function : SMESH_subMeshObj
922 // purpose : Constructor
923 //=================================================================================
924 SMESH_subMeshObj::SMESH_subMeshObj( SMESH::SMESH_subMesh_ptr theSubMesh,
925 SMESH_MeshObj* theMeshObj )
926 : SMESH_SubMeshObj( theMeshObj ),
927 mySubMeshServer( SMESH::SMESH_subMesh::_duplicate( theSubMesh ) )
929 if ( MYDEBUG ) MESSAGE( "SMESH_subMeshObj - theSubMesh->_is_nil() = " << theSubMesh->_is_nil() );
931 mySubMeshServer->Register();
934 SMESH_subMeshObj::~SMESH_subMeshObj()
936 if ( MYDEBUG ) MESSAGE( "~SMESH_subMeshObj" );
937 mySubMeshServer->Destroy();
940 //=================================================================================
941 // function : GetEntities
942 // purpose : Get entities of specified type. Return number of entities
943 //=================================================================================
944 int SMESH_subMeshObj::GetNbEntities( const SMDSAbs_ElementType theType) const
950 return mySubMeshServer->GetNumberOfNodes( false );
953 case SMDSAbs_0DElement:
958 SMESH::long_array_var anIds =
959 mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
960 return anIds->length();
968 int SMESH_subMeshObj::GetEntities( const SMDSAbs_ElementType theType, TEntityList& theResList ) const
972 SMDS_Mesh* aMesh = myMeshObj->GetMesh();
976 bool isNodal = IsNodePrs();
980 if ( theType == SMDSAbs_Node )
982 SMESH::long_array_var anIds = mySubMeshServer->GetNodesId();
983 return getPointers( SMDSAbs_Node, anIds, aMesh, theResList );
988 if ( theType == SMDSAbs_Node )
990 SMESH::long_array_var anIds = mySubMeshServer->GetElementsId();
991 return getNodesFromElems( anIds, aMesh, theResList );
995 SMESH::long_array_var anIds =
996 mySubMeshServer->GetElementsByType( SMESH::ElementType(theType) );
997 return getPointers( theType, anIds, aMesh, theResList );
1004 //=================================================================================
1005 // function : IsNodePrs
1006 // purpose : Return true if node presentation is used
1007 //=================================================================================
1008 bool SMESH_subMeshObj::IsNodePrs() const
1010 return mySubMeshServer->GetNumberOfElements() == 0;