Salome HOME
PAL8021. Correct work with submeshes on shape more complex than SHELL.
[modules/smesh.git] / src / SMESH_I / SMESH_subMesh_i.cxx
1 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
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. 
10 // 
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. 
15 // 
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 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SMESH_subMesh_i.cxx
25 //  Author : Paul RASCLE, EDF
26 //  Module : SMESH
27 //  $Header$
28
29 using namespace std;
30 #include "SMESH_subMesh_i.hxx"
31 #include "SMESH_Gen_i.hxx"
32 #include "SMESH_Mesh_i.hxx"
33
34 #include "Utils_CorbaException.hxx"
35 #include "utilities.h"
36 #include "OpUtil.hxx"
37 #include "Utils_ExceptHandlers.hxx"
38
39 //=============================================================================
40 /*!
41  *  
42  */
43 //=============================================================================
44
45 SMESH_subMesh_i::SMESH_subMesh_i()
46      : SALOME::GenericObj_i( PortableServer::POA::_nil() )
47 {
48   MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i default, not for use");
49     ASSERT(0);
50 }
51
52 //=============================================================================
53 /*!
54  *  
55  */
56 //=============================================================================
57
58 SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA,
59                                   SMESH_Gen_i*            gen_i,
60                                   SMESH_Mesh_i*           mesh_i,
61                                   int                     localId )
62      : SALOME::GenericObj_i( thePOA )
63 {
64   MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i");
65   _gen_i = gen_i;
66   _mesh_i = mesh_i;
67   _localId = localId;
68   thePOA->activate_object( this );
69   // ****
70 }
71 //=============================================================================
72 /*!
73  *  
74  */
75 //=============================================================================
76
77 SMESH_subMesh_i::~SMESH_subMesh_i()
78 {
79   MESSAGE("SMESH_subMesh_i::~SMESH_subMesh_i");
80   // ****
81 }
82
83 //=============================================================================
84 /*!
85  *  
86  */
87 //=============================================================================
88
89 CORBA::Long SMESH_subMesh_i::GetNumberOfElements()
90   throw (SALOME::SALOME_Exception)
91 {
92   Unexpect aCatch(SALOME_SalomeException);
93   MESSAGE("SMESH_subMesh_i::GetNumberOfElements");
94   if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
95     return 0;
96
97   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
98   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
99
100   int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
101
102   // volumes are bound to shell
103   if ( nbElems == 0 && aSubMesh->GetSubShape().ShapeType() <= TopAbs_SOLID )
104   {
105     SMESHDS_Mesh* aMeshDS = aSubMesh->GetFather()->GetMeshDS();
106     TopExp_Explorer exp( aSubMesh->GetSubShape(), TopAbs_SHELL );
107     for ( ; exp.More(); exp.Next() )
108     {
109       aSubMeshDS = aMeshDS->MeshElements( exp.Current() );
110       if ( aSubMeshDS )
111         nbElems += aSubMeshDS->NbElements();
112     }
113   }
114   return nbElems;
115 }
116
117 //=============================================================================
118 /*!
119  *  
120  */
121 //=============================================================================
122
123 CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
124   throw (SALOME::SALOME_Exception)
125 {
126   Unexpect aCatch(SALOME_SalomeException);
127   MESSAGE("SMESH_subMesh_i::GetNumberOfNodes");
128   if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
129     return 0;
130
131   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
132   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
133
134   set<int> nodeIds;
135
136   // node are bound to shell instead of solid
137   if ( all && aSubMesh->GetSubShape().ShapeType() <= TopAbs_SOLID )
138   {
139     SMESHDS_Mesh* aMeshDS = aSubMesh->GetFather()->GetMeshDS();
140     TopExp_Explorer exp( aSubMesh->GetSubShape(), TopAbs_SHELL );
141     for ( ; exp.More(); exp.Next() )
142     {
143       aSubMeshDS = aMeshDS->MeshElements( exp.Current() );
144       if ( aSubMeshDS ) {
145         SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
146         while ( eIt->more() ) {
147           const SMDS_MeshElement* anElem = eIt->next();
148           SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
149           while ( nIt->more() )
150             nodeIds.insert( nIt->next()->GetID() );
151         }
152       }
153     }
154     return nodeIds.size();
155   }
156
157   if ( aSubMeshDS == NULL )
158     return 0;
159
160   if ( all ) { // all nodes of submesh elements
161     SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
162     while ( eIt->more() ) {
163       const SMDS_MeshElement* anElem = eIt->next();
164       SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
165       while ( nIt->more() )
166         nodeIds.insert( nIt->next()->GetID() );
167     }
168     return nodeIds.size();
169   }
170     
171   return aSubMeshDS->NbNodes();
172 }
173
174 //=============================================================================
175 /*!
176  *  
177  */
178 //=============================================================================
179   
180 SMESH::long_array* SMESH_subMesh_i::GetElementsId()
181   throw (SALOME::SALOME_Exception)
182 {
183   Unexpect aCatch(SALOME_SalomeException);
184   MESSAGE("SMESH_subMesh_i::GetElementsId");
185   SMESH::long_array_var aResult = new SMESH::long_array();
186
187   if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
188     return aResult._retn();
189
190   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
191   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
192
193   int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
194   list<SMESHDS_SubMesh*> smList;
195   if ( nbElems )
196     smList.push_back( aSubMeshDS );
197
198   // volumes are bound to shell
199   if ( nbElems == 0 && aSubMesh->GetSubShape().ShapeType() <= TopAbs_SOLID )
200   {
201     SMESHDS_Mesh* aMeshDS = aSubMesh->GetFather()->GetMeshDS();
202     TopExp_Explorer exp( aSubMesh->GetSubShape(), TopAbs_SHELL );
203     for ( ; exp.More(); exp.Next() )
204     {
205       aSubMeshDS = aMeshDS->MeshElements( exp.Current() );
206       if ( aSubMeshDS ) {
207         smList.push_back( aSubMeshDS );
208         nbElems += aSubMeshDS->NbElements();
209       }
210     }
211   }
212
213   if ( nbElems )
214   {
215     aResult->length( nbElems );
216     list<SMESHDS_SubMesh*>::iterator sm = smList.begin();
217     for ( int i = 0; sm != smList.end(); sm++ )
218     {
219       aSubMeshDS = *sm;
220       SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements();
221       for ( int n = aSubMeshDS->NbElements(); i < n && anIt->more(); i++ )
222         aResult[i] = anIt->next()->GetID();
223     }
224   }
225   return aResult._retn();
226 }
227
228
229 //=============================================================================
230 /*!
231  *  
232  */
233 //=============================================================================
234
235 SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theElemType )
236     throw (SALOME::SALOME_Exception)
237 {
238   Unexpect aCatch(SALOME_SalomeException);
239   MESSAGE("SMESH_subMesh_i::GetElementsByType");
240   SMESH::long_array_var aResult = new SMESH::long_array();
241
242   if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
243     return aResult._retn();
244
245   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
246   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
247
248   // PAL5440, return all nodes belonging to elements of submesh
249   set<int> nodeIds;
250   int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
251
252   // volumes may be bound to shell instead of solid
253   list< SMESHDS_SubMesh* > smList;
254   if ( nbElems == 0 && aSubMesh->GetSubShape().ShapeType() <= TopAbs_SOLID )
255   {
256     SMESHDS_Mesh* aMeshDS = aSubMesh->GetFather()->GetMeshDS();
257     TopExp_Explorer exp( aSubMesh->GetSubShape(), TopAbs_SHELL );
258     for ( ; exp.More(); exp.Next() )
259     {
260       aSubMeshDS = aMeshDS->MeshElements( exp.Current() );
261       if ( !aSubMeshDS ) continue;
262       if ( theElemType == SMESH::NODE )
263       {
264         SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
265         while ( eIt->more() ) {
266           const SMDS_MeshElement* anElem = eIt->next();
267           SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
268           while ( nIt->more() )
269             nodeIds.insert( nIt->next()->GetID() );
270         }
271       }
272       else
273       {
274         smList.push_back( aSubMeshDS );
275         nbElems += aSubMeshDS->NbElements();
276       }
277     }
278     aSubMeshDS = 0;
279   }
280   else
281   {
282     if ( nbElems )
283       smList.push_back( aSubMeshDS );
284   }
285
286   if ( theElemType == SMESH::NODE && aSubMeshDS )
287   {
288     SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
289     while ( eIt->more() ) {
290       const SMDS_MeshElement* anElem = eIt->next();
291       SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
292       while ( nIt->more() )
293         nodeIds.insert( nIt->next()->GetID() );
294     }
295   }
296
297   if ( theElemType == SMESH::NODE )
298     aResult->length( nodeIds.size() );
299   else
300     aResult->length( nbElems );
301
302   int i = 0, n = aResult->length();
303
304   if ( theElemType == SMESH::NODE && !nodeIds.empty() ) {
305     set<int>::iterator idIt = nodeIds.begin();
306     for ( ; i < n && idIt != nodeIds.end() ; i++, idIt++ )
307       aResult[i] = *idIt;
308   }
309
310   if ( theElemType != SMESH::NODE ) {
311     list<SMESHDS_SubMesh*>::iterator sm = smList.begin();
312     for ( i = 0; sm != smList.end(); sm++ )
313     {
314       aSubMeshDS = *sm;
315       SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements();
316       while ( i < n && anIt->more() ) {
317         const SMDS_MeshElement* anElem = anIt->next();
318         if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
319           aResult[i++] = anElem->GetID();
320       }
321     }
322   }
323
324   aResult->length( i );
325
326   return aResult._retn();
327 }
328
329 //=============================================================================
330 /*!
331  *  
332  */
333 //=============================================================================
334   
335 SMESH::long_array* SMESH_subMesh_i::GetNodesId()
336   throw (SALOME::SALOME_Exception)
337 {
338   Unexpect aCatch(SALOME_SalomeException);
339   MESSAGE("SMESH_subMesh_i::GetNodesId");
340   SMESH::long_array_var aResult = GetElementsByType( SMESH::NODE );
341   return aResult._retn();
342 }
343
344 //=============================================================================
345 /*!
346  *  
347  */
348 //=============================================================================
349   
350 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather()
351   throw (SALOME::SALOME_Exception)
352 {
353   Unexpect aCatch(SALOME_SalomeException);
354   MESSAGE("SMESH_subMesh_i::GetFather");
355   return _mesh_i->_this();
356 }
357
358 //=============================================================================
359 /*!
360  *  
361  */
362 //=============================================================================
363   
364 CORBA::Long SMESH_subMesh_i::GetId()
365 {
366   MESSAGE("SMESH_subMesh_i::GetId");
367   return _localId;
368 }
369
370 //=======================================================================
371 //function : GetSubShape
372 //purpose  : 
373 //=======================================================================
374
375 GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape()
376      throw (SALOME::SALOME_Exception)
377 {
378   Unexpect aCatch(SALOME_SalomeException);
379   GEOM::GEOM_Object_var aShapeObj;
380   try {
381     if ( _mesh_i->_mapSubMesh.find( _localId ) != _mesh_i->_mapSubMesh.end()) {
382       TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape();
383       if ( !S.IsNull() )
384         aShapeObj = _gen_i->ShapeToGeomObject( S );
385     }
386   }
387   catch(SALOME_Exception & S_ex) {
388     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
389   }
390   return aShapeObj._retn();
391 }
392
393 //=============================================================================
394 /*!
395  *  
396  */
397 //=============================================================================
398 SALOME_MED::FAMILY_ptr SMESH_subMesh_i::GetFamily()
399   throw (SALOME::SALOME_Exception)
400 {
401   Unexpect aCatch(SALOME_SalomeException);
402   SALOME_MED::MESH_var MEDMesh = GetFather()->GetMEDMesh();
403
404   SALOME_MED::Family_array_var families = 
405     MEDMesh->getFamilies(SALOME_MED::MED_NODE);
406     
407   for ( int i = 0; i < families->length(); i++ ) {
408     if ( families[i]->getIdentifier() == ( _localId ) )
409       return families[i];
410   }
411   
412   return SALOME_MED::FAMILY::_nil();
413 }
414
415 //=============================================================================
416 /*!
417  *  
418  */
419 //=============================================================================
420 SMESH::long_array* SMESH_subMesh_i::GetIDs()
421 {
422   SMESH::long_array_var aResult = GetElementsId();
423   return aResult._retn();
424 }