1 // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
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_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 <BRepTools.hxx>
40 #include <TopoDS_Iterator.hxx>
44 //=============================================================================
48 //=============================================================================
50 SMESH_subMesh_i::SMESH_subMesh_i()
51 : SALOME::GenericObj_i( PortableServer::POA::_nil() )
53 MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i default, not for use");
57 //=============================================================================
61 //=============================================================================
63 SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA,
67 : SALOME::GenericObj_i( thePOA )
69 MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i");
73 thePOA->activate_object( this );
76 //=============================================================================
80 //=============================================================================
82 SMESH_subMesh_i::~SMESH_subMesh_i()
84 MESSAGE("SMESH_subMesh_i::~SMESH_subMesh_i");
88 //=======================================================================
89 //function : getSubMeshes
90 //purpose : for a submesh on shape to which elements are not bound directly,
91 // return submeshes containing elements
92 //=======================================================================
94 typedef list<SMESHDS_SubMesh*> TListOfSubMeshes;
96 bool getSubMeshes(::SMESH_subMesh* theSubMesh,
97 TListOfSubMeshes& theSubMeshList)
99 int size = theSubMeshList.size();
101 SMESH_Mesh* aMesh = theSubMesh->GetFather();
102 SMESHDS_Mesh* aMeshDS = aMesh->GetMeshDS();
103 SMESHDS_SubMesh* aSubMeshDS = theSubMesh->GetSubMeshDS();
105 // nodes can be bound to either vertex, edge, face or solid_or_shell
106 TopoDS_Shape aShape = theSubMesh->GetSubShape();
107 switch ( aShape.ShapeType() )
110 // add submesh of solid itself
111 aSubMeshDS = aMeshDS->MeshElements( aShape );
113 theSubMeshList.push_back( aSubMeshDS );
114 // and of the first shell
115 TopExp_Explorer exp( aShape, TopAbs_SHELL );
117 aSubMeshDS = aMeshDS->MeshElements( exp.Current() );
119 theSubMeshList.push_back( aSubMeshDS );
124 case TopAbs_COMPOUND:
125 case TopAbs_COMPSOLID: {
126 // call getSubMeshes() for sub-shapes
127 list<TopoDS_Shape> shapeList;
128 shapeList.push_back( aShape );
129 list<TopoDS_Shape>::iterator sh = shapeList.begin();
130 for ( ; sh != shapeList.end(); ++sh ) {
131 for ( TopoDS_Iterator it( *sh ); it.More(); it.Next() ) {
132 ::SMESH_subMesh* aSubMesh = aMesh->GetSubMeshContaining( it.Value() );
134 getSubMeshes( aSubMesh, theSubMeshList );
136 // no submesh for a compound inside compound
137 shapeList.push_back( it.Value() );
140 // return only unique submeshes
141 set<SMESHDS_SubMesh*> smSet;
142 TListOfSubMeshes::iterator sm = theSubMeshList.begin();
143 while ( sm != theSubMeshList.end() ) {
144 if ( !smSet.insert( *sm ).second )
145 sm = theSubMeshList.erase( sm );
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();
212 while ( eIt->more() ) {
213 const SMDS_MeshElement* anElem = eIt->next();
214 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
215 while ( nIt->more() )
216 nodeIds.insert( nIt->next()->GetID() );
219 return nodeIds.size();
222 if ( aSubMeshDS == NULL )
225 if ( all ) { // all nodes of submesh elements
226 SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
227 while ( eIt->more() ) {
228 const SMDS_MeshElement* anElem = eIt->next();
229 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
230 while ( nIt->more() )
231 nodeIds.insert( nIt->next()->GetID() );
233 return nodeIds.size();
236 return aSubMeshDS->NbNodes();
239 //=============================================================================
243 //=============================================================================
245 SMESH::long_array* SMESH_subMesh_i::GetElementsId()
246 throw (SALOME::SALOME_Exception)
248 Unexpect aCatch(SALOME_SalomeException);
249 MESSAGE("SMESH_subMesh_i::GetElementsId");
250 SMESH::long_array_var aResult = new SMESH::long_array();
252 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
253 return aResult._retn();
255 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
256 SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
258 int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
259 TListOfSubMeshes smList;
261 smList.push_back( aSubMeshDS );
263 // volumes are bound to shell
264 if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
266 TListOfSubMeshes::iterator sm = smList.begin();
267 for ( ; sm != smList.end(); ++sm )
268 nbElems += (*sm)->NbElements();
271 aResult->length( nbElems );
274 TListOfSubMeshes::iterator sm = smList.begin();
275 for ( int i = 0; sm != smList.end(); sm++ )
277 SMDS_ElemIteratorPtr anIt = (*sm)->GetElements();
278 for ( int n = aSubMeshDS->NbElements(); i < n && anIt->more(); i++ )
279 aResult[i] = anIt->next()->GetID();
282 return aResult._retn();
286 //=============================================================================
290 //=============================================================================
292 SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theElemType )
293 throw (SALOME::SALOME_Exception)
295 Unexpect aCatch(SALOME_SalomeException);
296 MESSAGE("SMESH_subMesh_i::GetElementsByType");
297 SMESH::long_array_var aResult = new SMESH::long_array();
299 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
300 return aResult._retn();
302 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
303 SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
305 // PAL5440, return all nodes belonging to elements of submesh
307 int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
309 // volumes may be bound to shell instead of solid
310 TListOfSubMeshes smList;
311 if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
313 TListOfSubMeshes::iterator sm = smList.begin();
314 for ( ; sm != smList.end(); ++sm )
316 if ( theElemType == SMESH::NODE )
318 SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
319 while ( eIt->more() ) {
320 const SMDS_MeshElement* anElem = eIt->next();
321 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
322 while ( nIt->more() )
323 nodeIds.insert( nIt->next()->GetID() );
328 nbElems += (*sm)->NbElements();
336 smList.push_back( aSubMeshDS );
339 if ( theElemType == SMESH::NODE && aSubMeshDS )
341 SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
342 while ( eIt->more() ) {
343 const SMDS_MeshElement* anElem = eIt->next();
344 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
345 while ( nIt->more() )
346 nodeIds.insert( nIt->next()->GetID() );
350 if ( theElemType == SMESH::NODE )
351 aResult->length( nodeIds.size() );
353 aResult->length( nbElems );
355 int i = 0, n = aResult->length();
357 if ( theElemType == SMESH::NODE && !nodeIds.empty() ) {
358 set<int>::iterator idIt = nodeIds.begin();
359 for ( ; i < n && idIt != nodeIds.end() ; i++, idIt++ )
363 if ( theElemType != SMESH::NODE ) {
364 TListOfSubMeshes::iterator sm = smList.begin();
365 for ( i = 0; sm != smList.end(); sm++ )
368 SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements();
369 while ( i < n && anIt->more() ) {
370 const SMDS_MeshElement* anElem = anIt->next();
371 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
372 aResult[i++] = anElem->GetID();
377 aResult->length( i );
379 return aResult._retn();
382 //=============================================================================
386 //=============================================================================
388 SMESH::long_array* SMESH_subMesh_i::GetNodesId()
389 throw (SALOME::SALOME_Exception)
391 Unexpect aCatch(SALOME_SalomeException);
392 MESSAGE("SMESH_subMesh_i::GetNodesId");
393 SMESH::long_array_var aResult = GetElementsByType( SMESH::NODE );
394 return aResult._retn();
397 //=============================================================================
401 //=============================================================================
403 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather()
404 throw (SALOME::SALOME_Exception)
406 Unexpect aCatch(SALOME_SalomeException);
407 MESSAGE("SMESH_subMesh_i::GetFather");
408 return _mesh_i->_this();
411 //=============================================================================
415 //=============================================================================
417 CORBA::Long SMESH_subMesh_i::GetId()
419 MESSAGE("SMESH_subMesh_i::GetId");
423 //=======================================================================
424 //function : GetSubShape
426 //=======================================================================
428 GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape()
429 throw (SALOME::SALOME_Exception)
431 Unexpect aCatch(SALOME_SalomeException);
432 GEOM::GEOM_Object_var aShapeObj;
434 if ( _mesh_i->_mapSubMesh.find( _localId ) != _mesh_i->_mapSubMesh.end()) {
435 TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape();
437 aShapeObj = _gen_i->ShapeToGeomObject( S );
440 catch(SALOME_Exception & S_ex) {
441 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
443 return aShapeObj._retn();
446 //=============================================================================
450 //=============================================================================
451 SALOME_MED::FAMILY_ptr SMESH_subMesh_i::GetFamily()
452 throw (SALOME::SALOME_Exception)
454 Unexpect aCatch(SALOME_SalomeException);
455 SALOME_MED::MESH_var MEDMesh = GetFather()->GetMEDMesh();
457 SALOME_MED::Family_array_var families =
458 MEDMesh->getFamilies(SALOME_MED::MED_NODE);
460 for ( int i = 0; i < families->length(); i++ ) {
461 if ( families[i]->getIdentifier() == ( _localId ) )
465 return SALOME_MED::FAMILY::_nil();
468 //=============================================================================
472 //=============================================================================
473 SMESH::long_array* SMESH_subMesh_i::GetIDs()
475 SMESH::long_array_var aResult = GetElementsId();
476 return aResult._retn();
479 //=============================================================================
483 //=============================================================================
484 SMESH::ElementType SMESH_subMesh_i::GetElementType( const CORBA::Long id, const bool iselem )
485 throw (SALOME::SALOME_Exception)
487 return GetFather()->GetElementType( id, iselem );