Salome HOME
#18963 Minimize compiler warnings
[modules/smesh.git] / src / SMESH_I / SMESH_subMesh_i.cxx
1 // Copyright (C) 2007-2020  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  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, or (at your option) any later version.
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.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
24 //  File   : SMESH_subMesh_i.cxx
25 //  Author : Paul RASCLE, EDF
26 //  Module : SMESH
27 //
28 #include "SMESH_subMesh_i.hxx"
29
30 #include "SMESHDS_Mesh.hxx"
31 #include "SMESHDS_SubMesh.hxx"
32 #include "SMESH_Gen_i.hxx"
33 #include "SMESH_Mesh_i.hxx"
34 #include "SMESH_MesherHelper.hxx"
35 #include "SMESH_PreMeshInfo.hxx"
36
37 #include "Utils_CorbaException.hxx"
38 #include "utilities.h"
39 #include "OpUtil.hxx"
40 #include "Utils_ExceptHandlers.hxx"
41
42 #include <TopoDS_Iterator.hxx>
43
44 using namespace std;
45
46 //=============================================================================
47 /*!
48  *  
49  */
50 //=============================================================================
51
52 SMESH_subMesh_i::SMESH_subMesh_i()
53      : SALOME::GenericObj_i( PortableServer::POA::_nil() )
54 {
55   MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i default, not for use");
56   ASSERT(0);
57 }
58
59 //=============================================================================
60 /*!
61  *  
62  */
63 //=============================================================================
64
65 SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA,
66                                   SMESH_Gen_i*            gen_i,
67                                   SMESH_Mesh_i*           mesh_i,
68                                   int                     localId )
69      : SALOME::GenericObj_i( thePOA )
70 {
71   _gen_i = gen_i;
72   _mesh_i = mesh_i;
73   _localId = localId;
74   _preMeshInfo = NULL;
75 }
76 //=============================================================================
77 /*!
78  *  
79  */
80 //=============================================================================
81
82 SMESH_subMesh_i::~SMESH_subMesh_i()
83 {
84   if ( _preMeshInfo ) delete _preMeshInfo;
85   _preMeshInfo = NULL;
86 }
87
88 //=======================================================================
89 //function : getSubMeshes
90 //purpose  : for a submesh on shape to which elements are not bound directly,
91 //           return submeshes containing elements
92 //=======================================================================
93
94 typedef list<SMESHDS_SubMesh*> TListOfSubMeshes;
95
96 bool getSubMeshes(::SMESH_subMesh*  theSubMesh,
97                   TListOfSubMeshes& theSubMeshList)
98 {
99   if ( !theSubMesh )
100     return false; // "invalid sub-mesh" created by SMESH_Gen_i::CopyMeshWithGeom()
101   size_t size = theSubMeshList.size();
102
103   // check all child sub-meshes of one complexity,
104   // if no elements found and no algo assigned, go to children of lower complexity
105
106   TopoDS_Shape            shape = theSubMesh->GetSubShape();
107   TopAbs_ShapeEnum     mainType = SMESH_MesherHelper::GetGroupType( shape, /*noCompound=*/true );
108   TopAbs_ShapeEnum    shapeType = shape.ShapeType();
109   bool            elementsFound = false;
110   bool                algoFound = false;
111   SMESH_subMeshIteratorPtr smIt = theSubMesh->getDependsOnIterator(/*includeSelf=*/true,
112                                                                    /*complexFirst=*/true);
113   while ( smIt->more() )
114   {
115     ::SMESH_subMesh* sm = smIt->next();
116     if ( sm->GetSubShape().ShapeType() != shapeType )
117     {
118       if ( elementsFound || algoFound )
119         break;
120       if ( sm->GetSubShape().ShapeType() == TopAbs_VERTEX &&
121            mainType != TopAbs_VERTEX )
122         break;
123     }
124     shapeType = sm->GetSubShape().ShapeType();
125     if ( !sm->IsEmpty() )
126     {
127       elementsFound = true;
128       theSubMeshList.push_back( sm->GetSubMeshDS() );
129     }
130     if ( sm->GetAlgo() )
131       algoFound = true;
132   }
133
134   return size < theSubMeshList.size();
135 }
136
137 //=============================================================================
138 /*!
139  *  
140  */
141 //=============================================================================
142
143 CORBA::Long SMESH_subMesh_i::GetNumberOfElements()
144 {
145   Unexpect aCatch(SALOME_SalomeException);
146
147   if ( _preMeshInfo )
148     return _preMeshInfo->NbElements();
149
150   if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
151     return 0;
152
153   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
154
155   int nbElems = 0;
156
157   TListOfSubMeshes smList;
158   if ( getSubMeshes( aSubMesh, smList ))
159   {
160     TListOfSubMeshes::iterator sm = smList.begin();
161     for ( ; sm != smList.end(); ++sm )
162       nbElems += (*sm)->NbElements();
163   }
164   return nbElems;
165 }
166
167 //=============================================================================
168 /*!
169  *  
170  */
171 //=============================================================================
172
173 CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
174 {
175   Unexpect aCatch(SALOME_SalomeException);
176
177   if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
178     return 0;
179
180   if ( _preMeshInfo )
181   {
182     if ( all ) return _preMeshInfo->NbNodes();
183     else _preMeshInfo->FullLoadFromFile();
184   }
185   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
186   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
187
188   if ( aSubMeshDS && aSubMeshDS->IsComplexSubmesh() )
189   {
190     // sub-mesh on a geom group, always return all nodes
191     return aSubMeshDS->NbNodes();
192   }
193   if ( aSubMeshDS && !all )
194   {
195     // return anything we have
196     return aSubMeshDS->NbNodes();
197   }
198   if ( all ) // get nodes from aSubMesh and all child sub-meshes
199   {
200     int nbNodes = 0;
201     SMESH_subMeshIteratorPtr smIt = aSubMesh->getDependsOnIterator( /*includeSelf=*/true );
202     while ( smIt->more() )
203     {
204       aSubMesh = smIt->next();
205       if (( aSubMeshDS = aSubMesh->GetSubMeshDS() ))
206         nbNodes += aSubMeshDS->NbNodes();
207     }
208     return nbNodes;
209   }
210
211   return aSubMeshDS ? aSubMeshDS->NbNodes() : 0;
212 }
213
214 //=============================================================================
215 /*!
216  *  
217  */
218 //=============================================================================
219
220 SMESH::long_array* SMESH_subMesh_i::GetElementsId()
221 {
222   Unexpect aCatch(SALOME_SalomeException);
223
224   SMESH::long_array_var aResult = new SMESH::long_array();
225
226   if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
227     return aResult._retn();
228
229   if ( _preMeshInfo )
230     _preMeshInfo->FullLoadFromFile();
231
232   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
233
234   int nbElems = 0;
235   TListOfSubMeshes smList;
236   if ( getSubMeshes( aSubMesh, smList ))
237   {
238     TListOfSubMeshes::iterator sm = smList.begin();
239     for ( ; sm != smList.end(); ++sm )
240       nbElems += (*sm)->NbElements();
241   }
242
243   aResult->length( nbElems );
244   if ( nbElems )
245   {
246     TListOfSubMeshes::iterator sm = smList.begin();
247     for ( int i = 0; sm != smList.end(); sm++ )
248     {
249       SMDS_ElemIteratorPtr anIt = (*sm)->GetElements();
250       for ( ; i < nbElems && anIt->more(); i++ )
251         aResult[i] = anIt->next()->GetID();
252     }
253   }
254   return aResult._retn();
255 }
256
257
258 //=============================================================================
259 /*!
260  *  
261  */
262 //=============================================================================
263
264 SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theElemType )
265 {
266   Unexpect aCatch(SALOME_SalomeException);
267
268   SMESH::long_array_var aResult = new SMESH::long_array();
269
270   if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
271     return aResult._retn();
272
273   if ( _preMeshInfo )
274     _preMeshInfo->FullLoadFromFile();
275
276   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
277
278   // PAL5440, return all nodes belonging to elements of the sub-mesh
279   set<int> nodeIds;
280   int nbElems = 0;
281
282   // volumes may be bound to shell instead of solid
283   TListOfSubMeshes smList;
284   if ( getSubMeshes( aSubMesh, smList ))
285   {
286     TListOfSubMeshes::iterator sm = smList.begin();
287     for ( ; sm != smList.end(); ++sm )
288     {
289       if ( theElemType == SMESH::NODE )
290       {
291         SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
292         if ( eIt->more() ) {
293           while ( eIt->more() ) {
294             const SMDS_MeshElement* anElem = eIt->next();
295             SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
296             while ( nIt->more() )
297               nodeIds.insert( nIt->next()->GetID() );
298           }
299         } else {
300           SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
301           while ( nIt->more() )
302             nodeIds.insert( nIt->next()->GetID() );
303         }
304       }
305       else
306       {
307         nbElems += (*sm)->NbElements();
308       }
309     }
310   }
311
312   if ( theElemType == SMESH::NODE )
313     aResult->length( nodeIds.size() );
314   else
315     aResult->length( nbElems );
316
317   int i = 0, n = aResult->length();
318
319   if ( theElemType == SMESH::NODE && !nodeIds.empty() ) {
320     set<int>::iterator idIt = nodeIds.begin();
321     for ( ; i < n && idIt != nodeIds.end() ; i++, idIt++ )
322       aResult[i] = *idIt;
323   }
324
325   if ( theElemType != SMESH::NODE ) {
326     TListOfSubMeshes::iterator sm = smList.begin();
327     for ( i = 0; sm != smList.end(); sm++ )
328     {
329       SMDS_ElemIteratorPtr anIt = (*sm)->GetElements();
330       while ( i < n && anIt->more() ) {
331         const SMDS_MeshElement* anElem = anIt->next();
332         if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
333           aResult[i++] = anElem->GetID();
334       }
335     }
336   }
337
338   aResult->length( i );
339
340   return aResult._retn();
341 }
342
343 //=============================================================================
344 /*!
345  *  
346  */
347 //=============================================================================
348   
349 SMESH::long_array* SMESH_subMesh_i::GetNodesId()
350 {
351   Unexpect aCatch(SALOME_SalomeException);
352
353   SMESH::long_array_var aResult = GetElementsByType( SMESH::NODE );
354   return aResult._retn();
355 }
356
357 //=============================================================================
358 /*!
359  *  
360  */
361 //=============================================================================
362   
363 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather()
364 {
365   Unexpect aCatch(SALOME_SalomeException);
366   return _mesh_i->_this();
367 }
368
369 //=============================================================================
370 /*!
371  *  
372  */
373 //=============================================================================
374   
375 CORBA::Long SMESH_subMesh_i::GetId()
376 {
377   return _localId;
378 }
379
380 //=======================================================================
381 //function : GetSubShape
382 //purpose  : 
383 //=======================================================================
384
385 GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape()
386 {
387   Unexpect aCatch(SALOME_SalomeException);
388   GEOM::GEOM_Object_var aShapeObj;
389   try {
390     if ( _mesh_i->_mapSubMesh.find( _localId ) != _mesh_i->_mapSubMesh.end()) {
391       TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape();
392       if ( !S.IsNull() ) {
393         aShapeObj = _gen_i->ShapeToGeomObject( S );
394         //mzn: N7PAL16232, N7PAL16233
395         //In some cases it's possible that GEOM_Client contains the shape same to S, but
396         //with another orientation.
397         if (aShapeObj->_is_nil())
398           aShapeObj = _gen_i->ShapeToGeomObject( S.Reversed() );
399       }
400     }
401   }
402   catch(SALOME_Exception & S_ex) {
403     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
404   }
405   return aShapeObj._retn();
406 }
407
408 //=============================================================================
409 /*!
410  *  
411  */
412 //=============================================================================
413 SMESH::long_array* SMESH_subMesh_i::GetIDs()
414 {
415   return GetElementsId();
416 }
417
418 //=============================================================================
419 /*!
420  *
421  */
422 //=============================================================================
423 SMESH::ElementType SMESH_subMesh_i::GetElementType( const CORBA::Long id, const bool iselem )
424 {
425   if ( _preMeshInfo )
426     _preMeshInfo->FullLoadFromFile();
427   return GetFather()->GetElementType( id, iselem );
428 }
429
430 //=============================================================================
431 /*
432  * Returns number of mesh elements of each \a EntityType
433  * @return array of number of elements per \a EntityType
434  */
435 //=============================================================================
436
437 SMESH::long_array* SMESH_subMesh_i::GetMeshInfo()
438 {
439   if ( _preMeshInfo )
440     return _preMeshInfo->GetMeshInfo();
441
442   SMESH::long_array_var aRes = new SMESH::long_array();
443   aRes->length(SMESH::Entity_Last);
444   for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
445     aRes[i] = 0;
446   
447   // get number of nodes
448   aRes[ SMESH::Entity_Node ] = GetNumberOfNodes(true);
449  
450   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
451
452   // get statistic from child sub-meshes
453   TListOfSubMeshes smList;
454   if ( getSubMeshes( aSubMesh, smList ) )
455     for ( TListOfSubMeshes::iterator sm = smList.begin(); sm != smList.end(); ++sm )
456       SMESH_Mesh_i::CollectMeshInfo( (*sm)->GetElements(), aRes );
457
458   return aRes._retn();
459 }
460
461 //=======================================================================
462 /*
463  * Returns number of mesh elements of each \a ElementType
464  */
465 //=======================================================================
466
467 SMESH::long_array* SMESH_subMesh_i::GetNbElementsByType()
468 {
469   SMESH::long_array_var aRes = new SMESH::long_array();
470   aRes->length(SMESH::NB_ELEMENT_TYPES);
471   for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
472     if ( _preMeshInfo )
473       aRes[ i ] = _preMeshInfo->NbElements( SMDSAbs_ElementType( i ));
474     else
475       aRes[ i ] = 0;
476
477   if ( !_preMeshInfo )
478   {
479     aRes[ SMESH::NODE ] = GetNumberOfNodes(true);
480
481     ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
482     TListOfSubMeshes smList;
483     if ( getSubMeshes( aSubMesh, smList ))
484     {
485       TListOfSubMeshes::iterator smDS = smList.begin();
486       for ( ; smDS != smList.end(); ++smDS )
487       {
488         SMDS_ElemIteratorPtr eIt = (*smDS)->GetElements();
489         if ( eIt->more() )
490           aRes[ eIt->next()->GetType() ] = (*smDS)->NbElements();
491       }
492     }
493   }
494   return aRes._retn();
495 }
496
497
498 //=======================================================================
499 //function : GetTypes
500 //purpose  : Returns types of elements it contains
501 //=======================================================================
502
503 SMESH::array_of_ElementType* SMESH_subMesh_i::GetTypes()
504 {
505   if ( _preMeshInfo )
506     return _preMeshInfo->GetTypes();
507
508   SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
509
510   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
511
512   TListOfSubMeshes smList;
513   if ( getSubMeshes( aSubMesh, smList ))
514   {
515     TListOfSubMeshes::iterator smDS = smList.begin();
516     for ( ; smDS != smList.end(); ++smDS )
517     {
518       SMDS_ElemIteratorPtr eIt = (*smDS)->GetElements();
519       if ( eIt->more() )
520       {
521         types->length( 1 );
522         types[0] = SMESH::ElementType( eIt->next()->GetType());
523         break;
524       }
525     }
526
527     if ( types->length() == 0 )
528     {
529       for ( smDS = smList.begin(); smDS != smList.end(); ++smDS )
530       {
531         if ( (*smDS)->GetNodes()->more() )
532         {
533           int smID = (*smDS)->GetID();
534           TopoDS_Shape shape = (*smDS)->GetParent()->IndexToShape( smID );
535           if ( !shape.IsNull() && shape.ShapeType() == TopAbs_VERTEX )
536           {
537             types->length( 1 );
538             types[0] = SMESH::NODE;
539             break;
540           }
541         }
542       }
543     }
544   }
545   return types._retn();
546 }
547
548 //=======================================================================
549 //function : GetMesh
550 //purpose  : interface SMESH_IDSource
551 //=======================================================================
552
553 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetMesh()
554 {
555   return GetFather();
556 }
557
558 //=======================================================================
559 //function : IsMeshInfoCorrect
560 //purpose  : * Returns false if GetMeshInfo() returns incorrect information that may
561 //           * happen if mesh data is not yet fully loaded from the file of study.
562 //=======================================================================
563
564 bool SMESH_subMesh_i::IsMeshInfoCorrect()
565 {
566   return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
567 }
568
569 //=======================================================================
570 //function : GetVtkUgStream
571 //purpose  : Return data vtk unstructured grid (not implemented)
572 //=======================================================================
573
574 SALOMEDS::TMPFile* SMESH_subMesh_i::GetVtkUgStream()
575 {
576   SALOMEDS::TMPFile_var SeqFile;
577   return SeqFile._retn();
578 }
579
580 //=======================================================================
581 //function : SMESH_Invalid_subMesh_i
582 //purpose  : constructor of "invalid sub-mesh" created by SMESH_Gen_i::CopyMeshWithGeom()
583 //=======================================================================
584
585 SMESH_Invalid_subMesh_i::SMESH_Invalid_subMesh_i( PortableServer::POA_ptr thePOA,
586                                                   SMESH_Gen_i*            gen_i,
587                                                   SMESH_Mesh_i*           mesh_i,
588                                                   int                     localId,
589                                                   GEOM::GEOM_Object_ptr   shape )
590   : SALOME::GenericObj_i( thePOA ),
591     SMESH_subMesh_i( thePOA, gen_i, mesh_i, localId )
592 {
593   _geom = GEOM::GEOM_Object::_duplicate( shape );
594 }
595
596 //=======================================================================
597 //function : GetSubShape
598 //purpose  : return geometry which is not a sub-shape of the main shape
599 //=======================================================================
600
601 GEOM::GEOM_Object_ptr SMESH_Invalid_subMesh_i::GetSubShape()
602 {
603   return GEOM::GEOM_Object::_duplicate( _geom );
604 }