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.salome-platform.org/ or email : webmaster.salome@opencascade.com
24 // File : SMESH_subMesh_i.cxx
25 // Author : Paul RASCLE, EDF
30 #include "SMESH_subMesh_i.hxx"
31 #include "SMESH_Gen_i.hxx"
32 #include "SMESH_Mesh_i.hxx"
34 #include "Utils_CorbaException.hxx"
35 #include "utilities.h"
37 #include "Utils_ExceptHandlers.hxx"
39 #include <BRepTools.hxx>
41 #include <TopoDS_Iterator.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");
72 thePOA->activate_object( this );
75 //=============================================================================
79 //=============================================================================
81 SMESH_subMesh_i::~SMESH_subMesh_i()
83 MESSAGE("SMESH_subMesh_i::~SMESH_subMesh_i");
87 //=======================================================================
88 //function : getSubMeshes
89 //purpose : for a submesh on shape to which elements are not bound directly,
90 // return submeshes containing elements
91 //=======================================================================
93 typedef list<SMESHDS_SubMesh*> TListOfSubMeshes;
95 bool getSubMeshes(::SMESH_subMesh* theSubMesh,
96 TListOfSubMeshes& theSubMeshList)
98 int size = theSubMeshList.size();
100 SMESH_Mesh* aMesh = theSubMesh->GetFather();
101 SMESHDS_Mesh* aMeshDS = aMesh->GetMeshDS();
102 SMESHDS_SubMesh* aSubMeshDS = theSubMesh->GetSubMeshDS();
104 // nodes can be bound to either vertex, edge, face or solid_or_shell
105 TopoDS_Shape aShape = theSubMesh->GetSubShape();
106 switch ( aShape.ShapeType() )
109 // add submesh of solid itself
110 aSubMeshDS = aMeshDS->MeshElements( aShape );
112 theSubMeshList.push_back( aSubMeshDS );
113 // and of the first shell
114 TopExp_Explorer exp( aShape, TopAbs_SHELL );
116 aSubMeshDS = aMeshDS->MeshElements( exp.Current() );
118 theSubMeshList.push_back( aSubMeshDS );
123 case TopAbs_COMPOUND:
124 case TopAbs_COMPSOLID: {
125 // call getSubMeshes() for sub-shapes
126 list<TopoDS_Shape> shapeList;
127 shapeList.push_back( aShape );
128 list<TopoDS_Shape>::iterator sh = shapeList.begin();
129 for ( ; sh != shapeList.end(); ++sh ) {
130 for ( TopoDS_Iterator it( *sh ); it.More(); it.Next() ) {
131 if ( ::SMESH_subMesh* aSubMesh = aMesh->GetSubMeshContaining( it.Value() ))
132 getSubMeshes( aSubMesh, theSubMeshList ); // add found submesh or explore deeper
134 // no submesh for a compound inside compound
135 shapeList.push_back( it.Value() );
138 // return only unique submeshes
139 set<SMESHDS_SubMesh*> smSet;
140 TListOfSubMeshes::iterator sm = theSubMeshList.begin();
141 while ( sm != theSubMeshList.end() ) {
142 if ( !smSet.insert( *sm ).second )
143 sm = theSubMeshList.erase( sm );
151 theSubMeshList.push_back( aSubMeshDS );
153 return size < theSubMeshList.size();
156 //=============================================================================
160 //=============================================================================
162 CORBA::Long SMESH_subMesh_i::GetNumberOfElements()
163 throw (SALOME::SALOME_Exception)
165 Unexpect aCatch(SALOME_SalomeException);
166 MESSAGE("SMESH_subMesh_i::GetNumberOfElements");
167 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
170 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
171 SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
173 int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
175 // volumes are bound to shell
176 TListOfSubMeshes smList;
177 if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
179 TListOfSubMeshes::iterator sm = smList.begin();
180 for ( ; sm != smList.end(); ++sm )
181 nbElems += (*sm)->NbElements();
186 //=============================================================================
190 //=============================================================================
192 CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
193 throw (SALOME::SALOME_Exception)
195 Unexpect aCatch(SALOME_SalomeException);
196 MESSAGE("SMESH_subMesh_i::GetNumberOfNodes");
197 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
200 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
201 SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
205 // nodes are bound to shell instead of solid
206 TListOfSubMeshes smList;
207 if ( all && getSubMeshes( aSubMesh, smList ))
209 TListOfSubMeshes::iterator sm = smList.begin();
210 for ( ; sm != smList.end(); ++sm )
212 SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
214 while ( eIt->more() ) {
215 const SMDS_MeshElement* anElem = eIt->next();
216 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
217 while ( nIt->more() )
218 nodeIds.insert( nIt->next()->GetID() );
221 SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
222 while ( nIt->more() )
223 nodeIds.insert( nIt->next()->GetID() );
226 return nodeIds.size();
229 if ( aSubMeshDS == NULL )
232 if ( all ) { // all nodes of submesh elements
233 SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
235 while ( eIt->more() ) {
236 const SMDS_MeshElement* anElem = eIt->next();
237 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
238 while ( nIt->more() )
239 nodeIds.insert( nIt->next()->GetID() );
242 SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes();
243 while ( nIt->more() )
244 nodeIds.insert( nIt->next()->GetID() );
246 return nodeIds.size();
249 return aSubMeshDS->NbNodes();
252 //=============================================================================
256 //=============================================================================
258 SMESH::long_array* SMESH_subMesh_i::GetElementsId()
259 throw (SALOME::SALOME_Exception)
261 Unexpect aCatch(SALOME_SalomeException);
262 MESSAGE("SMESH_subMesh_i::GetElementsId");
263 SMESH::long_array_var aResult = new SMESH::long_array();
265 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
266 return aResult._retn();
268 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
269 SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
271 int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
272 TListOfSubMeshes smList;
274 smList.push_back( aSubMeshDS );
276 // volumes are bound to shell
277 if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
279 TListOfSubMeshes::iterator sm = smList.begin();
280 for ( ; sm != smList.end(); ++sm )
281 nbElems += (*sm)->NbElements();
284 aResult->length( nbElems );
287 TListOfSubMeshes::iterator sm = smList.begin();
288 for ( int i = 0; sm != smList.end(); sm++ )
290 SMDS_ElemIteratorPtr anIt = (*sm)->GetElements();
291 for ( ; i < nbElems && anIt->more(); i++ )
292 aResult[i] = anIt->next()->GetID();
295 return aResult._retn();
299 //=============================================================================
303 //=============================================================================
305 SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theElemType )
306 throw (SALOME::SALOME_Exception)
308 Unexpect aCatch(SALOME_SalomeException);
309 MESSAGE("SMESH_subMesh_i::GetElementsByType");
310 SMESH::long_array_var aResult = new SMESH::long_array();
312 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
313 return aResult._retn();
315 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
316 SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
318 // PAL5440, return all nodes belonging to elements of submesh
320 int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
322 // volumes may be bound to shell instead of solid
323 TListOfSubMeshes smList;
324 if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
326 TListOfSubMeshes::iterator sm = smList.begin();
327 for ( ; sm != smList.end(); ++sm )
329 if ( theElemType == SMESH::NODE )
331 SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
333 while ( eIt->more() ) {
334 const SMDS_MeshElement* anElem = eIt->next();
335 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
336 while ( nIt->more() )
337 nodeIds.insert( nIt->next()->GetID() );
340 SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
341 while ( nIt->more() )
342 nodeIds.insert( nIt->next()->GetID() );
347 nbElems += (*sm)->NbElements();
355 smList.push_back( aSubMeshDS );
358 if ( theElemType == SMESH::NODE && aSubMeshDS )
360 SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
362 while ( eIt->more() ) {
363 const SMDS_MeshElement* anElem = eIt->next();
364 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
365 while ( nIt->more() )
366 nodeIds.insert( nIt->next()->GetID() );
369 SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes();
370 while ( nIt->more() )
371 nodeIds.insert( nIt->next()->GetID() );
375 if ( theElemType == SMESH::NODE )
376 aResult->length( nodeIds.size() );
378 aResult->length( nbElems );
380 int i = 0, n = aResult->length();
382 if ( theElemType == SMESH::NODE && !nodeIds.empty() ) {
383 set<int>::iterator idIt = nodeIds.begin();
384 for ( ; i < n && idIt != nodeIds.end() ; i++, idIt++ )
388 if ( theElemType != SMESH::NODE ) {
389 TListOfSubMeshes::iterator sm = smList.begin();
390 for ( i = 0; sm != smList.end(); sm++ )
393 SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements();
394 while ( i < n && anIt->more() ) {
395 const SMDS_MeshElement* anElem = anIt->next();
396 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
397 aResult[i++] = anElem->GetID();
402 aResult->length( i );
404 return aResult._retn();
407 //=============================================================================
411 //=============================================================================
413 SMESH::long_array* SMESH_subMesh_i::GetNodesId()
414 throw (SALOME::SALOME_Exception)
416 Unexpect aCatch(SALOME_SalomeException);
417 MESSAGE("SMESH_subMesh_i::GetNodesId");
418 SMESH::long_array_var aResult = GetElementsByType( SMESH::NODE );
419 return aResult._retn();
422 //=============================================================================
426 //=============================================================================
428 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather()
429 throw (SALOME::SALOME_Exception)
431 Unexpect aCatch(SALOME_SalomeException);
432 MESSAGE("SMESH_subMesh_i::GetFather");
433 return _mesh_i->_this();
436 //=============================================================================
440 //=============================================================================
442 CORBA::Long SMESH_subMesh_i::GetId()
444 MESSAGE("SMESH_subMesh_i::GetId");
448 //=======================================================================
449 //function : GetSubShape
451 //=======================================================================
453 GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape()
454 throw (SALOME::SALOME_Exception)
456 Unexpect aCatch(SALOME_SalomeException);
457 GEOM::GEOM_Object_var aShapeObj;
459 if ( _mesh_i->_mapSubMesh.find( _localId ) != _mesh_i->_mapSubMesh.end()) {
460 TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape();
462 aShapeObj = _gen_i->ShapeToGeomObject( S );
463 //mzn: N7PAL16232, N7PAL16233
464 //In some cases it's possible that GEOM_Client contains the shape same to S, but
465 //with another orientation.
466 if (aShapeObj->_is_nil())
467 aShapeObj = _gen_i->ShapeToGeomObject( S.Reversed() );
471 catch(SALOME_Exception & S_ex) {
472 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
474 return aShapeObj._retn();
477 //=============================================================================
481 //=============================================================================
482 SALOME_MED::FAMILY_ptr SMESH_subMesh_i::GetFamily()
483 throw (SALOME::SALOME_Exception)
485 Unexpect aCatch(SALOME_SalomeException);
486 SALOME_MED::MESH_var MEDMesh = GetFather()->GetMEDMesh();
488 SALOME_MED::Family_array_var families =
489 MEDMesh->getFamilies(SALOME_MED::MED_NODE);
491 for ( int i = 0; i < families->length(); i++ ) {
492 if ( families[i]->getIdentifier() == ( _localId ) )
496 return SALOME_MED::FAMILY::_nil();
499 //=============================================================================
503 //=============================================================================
504 SMESH::long_array* SMESH_subMesh_i::GetIDs()
506 SMESH::long_array_var aResult = GetElementsId();
507 return aResult._retn();
510 //=============================================================================
514 //=============================================================================
515 SMESH::ElementType SMESH_subMesh_i::GetElementType( const CORBA::Long id, const bool iselem )
516 throw (SALOME::SALOME_Exception)
518 return GetFather()->GetElementType( id, iselem );