1 // Copyright (C) 2007-2010 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
23 // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
24 // File : SMESH_subMesh_i.cxx
25 // Author : Paul RASCLE, EDF
29 #include "SMESH_subMesh_i.hxx"
30 #include "SMESH_Gen_i.hxx"
31 #include "SMESH_Mesh_i.hxx"
33 #include "Utils_CorbaException.hxx"
34 #include "utilities.h"
36 #include "Utils_ExceptHandlers.hxx"
38 #include <TopoDS_Iterator.hxx>
39 #include <TopExp_Explorer.hxx>
43 //=============================================================================
47 //=============================================================================
49 SMESH_subMesh_i::SMESH_subMesh_i()
50 : SALOME::GenericObj_i( PortableServer::POA::_nil() )
52 MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i default, not for use");
56 //=============================================================================
60 //=============================================================================
62 SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA,
66 : SALOME::GenericObj_i( thePOA )
68 MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i");
74 //=============================================================================
78 //=============================================================================
80 SMESH_subMesh_i::~SMESH_subMesh_i()
82 MESSAGE("SMESH_subMesh_i::~SMESH_subMesh_i");
86 //=======================================================================
87 //function : getSubMeshes
88 //purpose : for a submesh on shape to which elements are not bound directly,
89 // return submeshes containing elements
90 //=======================================================================
92 typedef list<SMESHDS_SubMesh*> TListOfSubMeshes;
94 bool getSubMeshes(::SMESH_subMesh* theSubMesh,
95 TListOfSubMeshes& theSubMeshList)
97 int size = theSubMeshList.size();
99 SMESH_Mesh* aMesh = theSubMesh->GetFather();
100 SMESHDS_Mesh* aMeshDS = aMesh->GetMeshDS();
101 SMESHDS_SubMesh* aSubMeshDS = theSubMesh->GetSubMeshDS();
103 // nodes can be bound to either vertex, edge, face or solid_or_shell
104 TopoDS_Shape aShape = theSubMesh->GetSubShape();
105 switch ( aShape.ShapeType() )
108 // add submesh of solid itself
109 aSubMeshDS = aMeshDS->MeshElements( aShape );
111 theSubMeshList.push_back( aSubMeshDS );
112 // and of the first shell
113 TopExp_Explorer exp( aShape, TopAbs_SHELL );
115 aSubMeshDS = aMeshDS->MeshElements( exp.Current() );
117 theSubMeshList.push_back( aSubMeshDS );
122 case TopAbs_COMPOUND:
123 case TopAbs_COMPSOLID: {
124 // call getSubMeshes() for sub-shapes
125 list<TopoDS_Shape> shapeList;
126 shapeList.push_back( aShape );
127 list<TopoDS_Shape>::iterator sh = shapeList.begin();
128 for ( ; sh != shapeList.end(); ++sh ) {
129 for ( TopoDS_Iterator it( *sh ); it.More(); it.Next() ) {
130 if ( ::SMESH_subMesh* aSubMesh = aMesh->GetSubMeshContaining( it.Value() ))
131 getSubMeshes( aSubMesh, theSubMeshList ); // add found submesh or explore deeper
133 // no submesh for a compound inside compound
134 shapeList.push_back( it.Value() );
137 // return only unique submeshes
138 set<SMESHDS_SubMesh*> smSet;
139 TListOfSubMeshes::iterator sm = theSubMeshList.begin();
140 while ( sm != theSubMeshList.end() ) {
141 if ( !smSet.insert( *sm ).second )
142 sm = theSubMeshList.erase( sm );
150 theSubMeshList.push_back( aSubMeshDS );
152 return size < theSubMeshList.size();
155 //=============================================================================
159 //=============================================================================
161 CORBA::Long SMESH_subMesh_i::GetNumberOfElements()
162 throw (SALOME::SALOME_Exception)
164 Unexpect aCatch(SALOME_SalomeException);
165 MESSAGE("SMESH_subMesh_i::GetNumberOfElements");
166 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
169 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
170 SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
172 int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
174 // volumes are bound to shell
175 TListOfSubMeshes smList;
176 if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
178 TListOfSubMeshes::iterator sm = smList.begin();
179 for ( ; sm != smList.end(); ++sm )
180 nbElems += (*sm)->NbElements();
185 //=============================================================================
189 //=============================================================================
191 CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
192 throw (SALOME::SALOME_Exception)
194 Unexpect aCatch(SALOME_SalomeException);
195 MESSAGE("SMESH_subMesh_i::GetNumberOfNodes");
196 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
199 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
200 SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
204 // nodes are bound to shell instead of solid
205 TListOfSubMeshes smList;
206 if ( all && getSubMeshes( aSubMesh, smList ))
208 TListOfSubMeshes::iterator sm = smList.begin();
209 for ( ; sm != smList.end(); ++sm )
211 SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
213 while ( eIt->more() ) {
214 const SMDS_MeshElement* anElem = eIt->next();
215 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
216 while ( nIt->more() )
217 nodeIds.insert( nIt->next()->GetID() );
220 SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
221 while ( nIt->more() )
222 nodeIds.insert( nIt->next()->GetID() );
225 return nodeIds.size();
228 if ( aSubMeshDS == NULL )
231 if ( all ) { // all nodes of submesh elements
232 SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
234 while ( eIt->more() ) {
235 const SMDS_MeshElement* anElem = eIt->next();
236 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
237 while ( nIt->more() )
238 nodeIds.insert( nIt->next()->GetID() );
241 SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes();
242 while ( nIt->more() )
243 nodeIds.insert( nIt->next()->GetID() );
245 return nodeIds.size();
248 return aSubMeshDS->NbNodes();
251 //=============================================================================
255 //=============================================================================
257 SMESH::long_array* SMESH_subMesh_i::GetElementsId()
258 throw (SALOME::SALOME_Exception)
260 Unexpect aCatch(SALOME_SalomeException);
261 MESSAGE("SMESH_subMesh_i::GetElementsId");
262 SMESH::long_array_var aResult = new SMESH::long_array();
264 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
265 return aResult._retn();
267 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
268 SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
270 int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
271 TListOfSubMeshes smList;
273 smList.push_back( aSubMeshDS );
275 // volumes are bound to shell
276 if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
278 TListOfSubMeshes::iterator sm = smList.begin();
279 for ( ; sm != smList.end(); ++sm )
280 nbElems += (*sm)->NbElements();
283 aResult->length( nbElems );
286 TListOfSubMeshes::iterator sm = smList.begin();
287 for ( int i = 0; sm != smList.end(); sm++ )
289 SMDS_ElemIteratorPtr anIt = (*sm)->GetElements();
290 for ( ; i < nbElems && anIt->more(); i++ )
291 aResult[i] = anIt->next()->GetID();
294 return aResult._retn();
298 //=============================================================================
302 //=============================================================================
304 SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theElemType )
305 throw (SALOME::SALOME_Exception)
307 Unexpect aCatch(SALOME_SalomeException);
308 MESSAGE("SMESH_subMesh_i::GetElementsByType");
309 SMESH::long_array_var aResult = new SMESH::long_array();
311 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
312 return aResult._retn();
314 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
315 SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
317 // PAL5440, return all nodes belonging to elements of submesh
319 int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
321 // volumes may be bound to shell instead of solid
322 TListOfSubMeshes smList;
323 if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
325 TListOfSubMeshes::iterator sm = smList.begin();
326 for ( ; sm != smList.end(); ++sm )
328 if ( theElemType == SMESH::NODE )
330 SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
332 while ( eIt->more() ) {
333 const SMDS_MeshElement* anElem = eIt->next();
334 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
335 while ( nIt->more() )
336 nodeIds.insert( nIt->next()->GetID() );
339 SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
340 while ( nIt->more() )
341 nodeIds.insert( nIt->next()->GetID() );
346 nbElems += (*sm)->NbElements();
354 smList.push_back( aSubMeshDS );
357 if ( theElemType == SMESH::NODE && aSubMeshDS )
359 SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
361 while ( eIt->more() ) {
362 const SMDS_MeshElement* anElem = eIt->next();
363 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
364 while ( nIt->more() )
365 nodeIds.insert( nIt->next()->GetID() );
368 SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes();
369 while ( nIt->more() )
370 nodeIds.insert( nIt->next()->GetID() );
374 if ( theElemType == SMESH::NODE )
375 aResult->length( nodeIds.size() );
377 aResult->length( nbElems );
379 int i = 0, n = aResult->length();
381 if ( theElemType == SMESH::NODE && !nodeIds.empty() ) {
382 set<int>::iterator idIt = nodeIds.begin();
383 for ( ; i < n && idIt != nodeIds.end() ; i++, idIt++ )
387 if ( theElemType != SMESH::NODE ) {
388 TListOfSubMeshes::iterator sm = smList.begin();
389 for ( i = 0; sm != smList.end(); sm++ )
392 SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements();
393 while ( i < n && anIt->more() ) {
394 const SMDS_MeshElement* anElem = anIt->next();
395 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
396 aResult[i++] = anElem->GetID();
401 aResult->length( i );
403 return aResult._retn();
406 //=============================================================================
410 //=============================================================================
412 SMESH::long_array* SMESH_subMesh_i::GetNodesId()
413 throw (SALOME::SALOME_Exception)
415 Unexpect aCatch(SALOME_SalomeException);
416 MESSAGE("SMESH_subMesh_i::GetNodesId");
417 SMESH::long_array_var aResult = GetElementsByType( SMESH::NODE );
418 return aResult._retn();
421 //=============================================================================
425 //=============================================================================
427 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather()
428 throw (SALOME::SALOME_Exception)
430 Unexpect aCatch(SALOME_SalomeException);
431 MESSAGE("SMESH_subMesh_i::GetFather");
432 return _mesh_i->_this();
435 //=============================================================================
439 //=============================================================================
441 CORBA::Long SMESH_subMesh_i::GetId()
443 MESSAGE("SMESH_subMesh_i::GetId");
447 //=======================================================================
448 //function : GetSubShape
450 //=======================================================================
452 GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape()
453 throw (SALOME::SALOME_Exception)
455 Unexpect aCatch(SALOME_SalomeException);
456 GEOM::GEOM_Object_var aShapeObj;
458 if ( _mesh_i->_mapSubMesh.find( _localId ) != _mesh_i->_mapSubMesh.end()) {
459 TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape();
461 aShapeObj = _gen_i->ShapeToGeomObject( S );
462 //mzn: N7PAL16232, N7PAL16233
463 //In some cases it's possible that GEOM_Client contains the shape same to S, but
464 //with another orientation.
465 if (aShapeObj->_is_nil())
466 aShapeObj = _gen_i->ShapeToGeomObject( S.Reversed() );
470 catch(SALOME_Exception & S_ex) {
471 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
473 return aShapeObj._retn();
476 //=============================================================================
480 //=============================================================================
481 SALOME_MED::FAMILY_ptr SMESH_subMesh_i::GetFamily()
482 throw (SALOME::SALOME_Exception)
484 Unexpect aCatch(SALOME_SalomeException);
485 SALOME_MED::MESH_var MEDMesh = GetFather()->GetMEDMesh();
487 SALOME_MED::Family_array_var families =
488 MEDMesh->getFamilies(SALOME_MED::MED_NODE);
490 for ( int i = 0; i < families->length(); i++ ) {
491 if ( families[i]->getIdentifier() == ( _localId ) )
495 return SALOME_MED::FAMILY::_nil();
498 //=============================================================================
502 //=============================================================================
503 SMESH::long_array* SMESH_subMesh_i::GetIDs()
505 SMESH::long_array_var aResult = GetElementsId();
506 return aResult._retn();
509 //=============================================================================
513 //=============================================================================
514 SMESH::ElementType SMESH_subMesh_i::GetElementType( const CORBA::Long id, const bool iselem )
515 throw (SALOME::SALOME_Exception)
517 return GetFather()->GetElementType( id, iselem );
521 //=============================================================================
523 * Returns statistic of mesh elements
524 * Result array of number enityties
525 * Inherited from SMESH_IDSource
527 //=============================================================================
528 SMESH::long_array* SMESH_subMesh_i::GetMeshInfo()
530 SMESH::long_array_var aRes = new SMESH::long_array();
531 aRes->length(SMESH::Entity_Last);
532 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
535 // get number of nodes
536 aRes[ SMESH::Entity_Node ] = GetNumberOfNodes(true);
538 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
540 // get statistic from child sub-meshes
541 TListOfSubMeshes smList;
542 if ( getSubMeshes( aSubMesh, smList ) )
543 for ( TListOfSubMeshes::iterator sm = smList.begin(); sm != smList.end(); ++sm )
544 SMESH_Mesh_i::CollectMeshInfo( (*sm)->GetElements(), aRes );
550 //=======================================================================
551 //function : GetTypes
552 //purpose : Returns types of elements it contains
553 //=======================================================================
555 SMESH::array_of_ElementType* SMESH_subMesh_i::GetTypes()
557 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
559 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
560 TopoDS_Shape shape = aSubMesh->GetSubShape();
561 while ( !shape.IsNull() && shape.ShapeType() == TopAbs_COMPOUND )
563 TopoDS_Iterator it( shape );
564 shape = it.More() ? it.Value() : TopoDS_Shape();
566 if ( !shape.IsNull() )
569 switch ( ::SMESH_Gen::GetShapeDim( shape ))
571 case 0: types[0] = SMESH::ELEM0D; break;
572 case 1: types[0] = SMESH::EDGE; break;
573 case 2: types[0] = SMESH::FACE; break;
574 case 3: types[0] = SMESH::VOLUME; break;
579 return types._retn();