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 SMESH_I : idl implementation based on 'SMESH' unit's calsses
23 // File : SMESH_subMesh_i.cxx
24 // Author : Paul RASCLE, EDF
28 #include "SMESH_subMesh_i.hxx"
29 #include "SMESH_Gen_i.hxx"
30 #include "SMESH_Mesh_i.hxx"
32 #include "Utils_CorbaException.hxx"
33 #include "utilities.h"
35 #include "Utils_ExceptHandlers.hxx"
37 #include <TopoDS_Iterator.hxx>
38 #include <TopExp_Explorer.hxx>
42 //=============================================================================
46 //=============================================================================
48 SMESH_subMesh_i::SMESH_subMesh_i()
49 : SALOME::GenericObj_i( PortableServer::POA::_nil() )
51 MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i default, not for use");
55 //=============================================================================
59 //=============================================================================
61 SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA,
65 : SALOME::GenericObj_i( thePOA )
67 MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i");
73 //=============================================================================
77 //=============================================================================
79 SMESH_subMesh_i::~SMESH_subMesh_i()
81 MESSAGE("SMESH_subMesh_i::~SMESH_subMesh_i");
85 //=======================================================================
86 //function : getSubMeshes
87 //purpose : for a submesh on shape to which elements are not bound directly,
88 // return submeshes containing elements
89 //=======================================================================
91 typedef list<SMESHDS_SubMesh*> TListOfSubMeshes;
93 bool getSubMeshes(::SMESH_subMesh* theSubMesh,
94 TListOfSubMeshes& theSubMeshList)
96 int size = theSubMeshList.size();
98 SMESH_Mesh* aMesh = theSubMesh->GetFather();
99 SMESHDS_Mesh* aMeshDS = aMesh->GetMeshDS();
100 SMESHDS_SubMesh* aSubMeshDS = theSubMesh->GetSubMeshDS();
102 // nodes can be bound to either vertex, edge, face or solid_or_shell
103 TopoDS_Shape aShape = theSubMesh->GetSubShape();
104 switch ( aShape.ShapeType() )
107 // add submesh of solid itself
108 aSubMeshDS = aMeshDS->MeshElements( aShape );
110 theSubMeshList.push_back( aSubMeshDS );
111 // and of the first shell
112 TopExp_Explorer exp( aShape, TopAbs_SHELL );
114 aSubMeshDS = aMeshDS->MeshElements( exp.Current() );
116 theSubMeshList.push_back( aSubMeshDS );
121 case TopAbs_COMPOUND:
122 case TopAbs_COMPSOLID: {
123 // call getSubMeshes() for sub-shapes
124 list<TopoDS_Shape> shapeList;
125 shapeList.push_back( aShape );
126 list<TopoDS_Shape>::iterator sh = shapeList.begin();
127 for ( ; sh != shapeList.end(); ++sh ) {
128 for ( TopoDS_Iterator it( *sh ); it.More(); it.Next() ) {
129 if ( ::SMESH_subMesh* aSubMesh = aMesh->GetSubMeshContaining( it.Value() ))
130 getSubMeshes( aSubMesh, theSubMeshList ); // add found submesh or explore deeper
132 // no submesh for a compound inside compound
133 shapeList.push_back( it.Value() );
136 // return only unique submeshes
137 set<SMESHDS_SubMesh*> smSet;
138 TListOfSubMeshes::iterator sm = theSubMeshList.begin();
139 while ( sm != theSubMeshList.end() ) {
140 if ( !smSet.insert( *sm ).second )
141 sm = theSubMeshList.erase( sm );
149 theSubMeshList.push_back( aSubMeshDS );
151 return size < theSubMeshList.size();
154 //=============================================================================
158 //=============================================================================
160 CORBA::Long SMESH_subMesh_i::GetNumberOfElements()
161 throw (SALOME::SALOME_Exception)
163 Unexpect aCatch(SALOME_SalomeException);
164 MESSAGE("SMESH_subMesh_i::GetNumberOfElements");
165 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
168 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
169 SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
171 int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
173 // volumes are bound to shell
174 TListOfSubMeshes smList;
175 if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
177 TListOfSubMeshes::iterator sm = smList.begin();
178 for ( ; sm != smList.end(); ++sm )
179 nbElems += (*sm)->NbElements();
184 //=============================================================================
188 //=============================================================================
190 CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
191 throw (SALOME::SALOME_Exception)
193 Unexpect aCatch(SALOME_SalomeException);
194 MESSAGE("SMESH_subMesh_i::GetNumberOfNodes");
195 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
198 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
199 SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
203 // nodes are bound to shell instead of solid
204 TListOfSubMeshes smList;
205 if ( all && getSubMeshes( aSubMesh, smList ))
207 TListOfSubMeshes::iterator sm = smList.begin();
208 for ( ; sm != smList.end(); ++sm )
210 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 SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
220 while ( nIt->more() )
221 nodeIds.insert( nIt->next()->GetID() );
224 return nodeIds.size();
227 if ( aSubMeshDS == NULL )
230 if ( all ) { // all nodes of submesh elements
231 SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
233 while ( eIt->more() ) {
234 const SMDS_MeshElement* anElem = eIt->next();
235 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
236 while ( nIt->more() )
237 nodeIds.insert( nIt->next()->GetID() );
240 SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes();
241 while ( nIt->more() )
242 nodeIds.insert( nIt->next()->GetID() );
244 return nodeIds.size();
247 return aSubMeshDS->NbNodes();
250 //=============================================================================
254 //=============================================================================
256 SMESH::long_array* SMESH_subMesh_i::GetElementsId()
257 throw (SALOME::SALOME_Exception)
259 Unexpect aCatch(SALOME_SalomeException);
260 MESSAGE("SMESH_subMesh_i::GetElementsId");
261 SMESH::long_array_var aResult = new SMESH::long_array();
263 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
264 return aResult._retn();
266 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
267 SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
269 int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
270 TListOfSubMeshes smList;
272 smList.push_back( aSubMeshDS );
274 // volumes are bound to shell
275 if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
277 TListOfSubMeshes::iterator sm = smList.begin();
278 for ( ; sm != smList.end(); ++sm )
279 nbElems += (*sm)->NbElements();
282 aResult->length( nbElems );
285 TListOfSubMeshes::iterator sm = smList.begin();
286 for ( int i = 0; sm != smList.end(); sm++ )
288 SMDS_ElemIteratorPtr anIt = (*sm)->GetElements();
289 for ( ; i < nbElems && anIt->more(); i++ )
290 aResult[i] = anIt->next()->GetID();
293 return aResult._retn();
297 //=============================================================================
301 //=============================================================================
303 SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theElemType )
304 throw (SALOME::SALOME_Exception)
306 Unexpect aCatch(SALOME_SalomeException);
307 MESSAGE("SMESH_subMesh_i::GetElementsByType");
308 SMESH::long_array_var aResult = new SMESH::long_array();
310 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
311 return aResult._retn();
313 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
314 SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
316 // PAL5440, return all nodes belonging to elements of submesh
318 int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
320 // volumes may be bound to shell instead of solid
321 TListOfSubMeshes smList;
322 if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
324 TListOfSubMeshes::iterator sm = smList.begin();
325 for ( ; sm != smList.end(); ++sm )
327 if ( theElemType == SMESH::NODE )
329 SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
331 while ( eIt->more() ) {
332 const SMDS_MeshElement* anElem = eIt->next();
333 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
334 while ( nIt->more() )
335 nodeIds.insert( nIt->next()->GetID() );
338 SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
339 while ( nIt->more() )
340 nodeIds.insert( nIt->next()->GetID() );
345 nbElems += (*sm)->NbElements();
353 smList.push_back( aSubMeshDS );
356 if ( theElemType == SMESH::NODE && aSubMeshDS )
358 SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
360 while ( eIt->more() ) {
361 const SMDS_MeshElement* anElem = eIt->next();
362 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
363 while ( nIt->more() )
364 nodeIds.insert( nIt->next()->GetID() );
367 SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes();
368 while ( nIt->more() )
369 nodeIds.insert( nIt->next()->GetID() );
373 if ( theElemType == SMESH::NODE )
374 aResult->length( nodeIds.size() );
376 aResult->length( nbElems );
378 int i = 0, n = aResult->length();
380 if ( theElemType == SMESH::NODE && !nodeIds.empty() ) {
381 set<int>::iterator idIt = nodeIds.begin();
382 for ( ; i < n && idIt != nodeIds.end() ; i++, idIt++ )
386 if ( theElemType != SMESH::NODE ) {
387 TListOfSubMeshes::iterator sm = smList.begin();
388 for ( i = 0; sm != smList.end(); sm++ )
391 SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements();
392 while ( i < n && anIt->more() ) {
393 const SMDS_MeshElement* anElem = anIt->next();
394 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
395 aResult[i++] = anElem->GetID();
400 aResult->length( i );
402 return aResult._retn();
405 //=============================================================================
409 //=============================================================================
411 SMESH::long_array* SMESH_subMesh_i::GetNodesId()
412 throw (SALOME::SALOME_Exception)
414 Unexpect aCatch(SALOME_SalomeException);
415 MESSAGE("SMESH_subMesh_i::GetNodesId");
416 SMESH::long_array_var aResult = GetElementsByType( SMESH::NODE );
417 return aResult._retn();
420 //=============================================================================
424 //=============================================================================
426 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather()
427 throw (SALOME::SALOME_Exception)
429 Unexpect aCatch(SALOME_SalomeException);
430 MESSAGE("SMESH_subMesh_i::GetFather");
431 return _mesh_i->_this();
434 //=============================================================================
438 //=============================================================================
440 CORBA::Long SMESH_subMesh_i::GetId()
442 MESSAGE("SMESH_subMesh_i::GetId");
446 //=======================================================================
447 //function : GetSubShape
449 //=======================================================================
451 GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape()
452 throw (SALOME::SALOME_Exception)
454 Unexpect aCatch(SALOME_SalomeException);
455 GEOM::GEOM_Object_var aShapeObj;
457 if ( _mesh_i->_mapSubMesh.find( _localId ) != _mesh_i->_mapSubMesh.end()) {
458 TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape();
460 aShapeObj = _gen_i->ShapeToGeomObject( S );
461 //mzn: N7PAL16232, N7PAL16233
462 //In some cases it's possible that GEOM_Client contains the shape same to S, but
463 //with another orientation.
464 if (aShapeObj->_is_nil())
465 aShapeObj = _gen_i->ShapeToGeomObject( S.Reversed() );
469 catch(SALOME_Exception & S_ex) {
470 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
472 return aShapeObj._retn();
475 //=============================================================================
479 //=============================================================================
480 SALOME_MED::FAMILY_ptr SMESH_subMesh_i::GetFamily()
481 throw (SALOME::SALOME_Exception)
483 Unexpect aCatch(SALOME_SalomeException);
484 SALOME_MED::MESH_var MEDMesh = GetFather()->GetMEDMesh();
486 SALOME_MED::Family_array_var families =
487 MEDMesh->getFamilies(SALOME_MED::MED_NODE);
489 for ( int i = 0; i < families->length(); i++ ) {
490 if ( families[i]->getIdentifier() == ( _localId ) )
494 return SALOME_MED::FAMILY::_nil();
497 //=============================================================================
501 //=============================================================================
502 SMESH::long_array* SMESH_subMesh_i::GetIDs()
504 SMESH::long_array_var aResult = GetElementsId();
505 return aResult._retn();
508 //=============================================================================
512 //=============================================================================
513 SMESH::ElementType SMESH_subMesh_i::GetElementType( const CORBA::Long id, const bool iselem )
514 throw (SALOME::SALOME_Exception)
516 return GetFather()->GetElementType( id, iselem );