1 // Copyright (C) 2007-2020 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, or (at your option) any later version.
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
23 // SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes
24 // File : SMESH_subMesh_i.cxx
25 // Author : Paul RASCLE, EDF
28 #include "SMESH_subMesh_i.hxx"
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"
37 #include "Utils_CorbaException.hxx"
38 #include "utilities.h"
40 #include "Utils_ExceptHandlers.hxx"
42 #include <TopoDS_Iterator.hxx>
46 //=============================================================================
50 //=============================================================================
52 SMESH_subMesh_i::SMESH_subMesh_i()
53 : SALOME::GenericObj_i( PortableServer::POA::_nil() )
55 MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i default, not for use");
59 //=============================================================================
63 //=============================================================================
65 SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA,
69 : SALOME::GenericObj_i( thePOA )
76 //=============================================================================
80 //=============================================================================
82 SMESH_subMesh_i::~SMESH_subMesh_i()
84 if ( _preMeshInfo ) delete _preMeshInfo;
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)
100 return false; // "invalid sub-mesh" created by SMESH_Gen_i::CopyMeshWithGeom()
101 size_t size = theSubMeshList.size();
103 // check all child sub-meshes of one complexity,
104 // if no elements found and no algo assigned, go to children of lower complexity
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() )
115 ::SMESH_subMesh* sm = smIt->next();
116 if ( sm->GetSubShape().ShapeType() != shapeType )
118 if ( elementsFound || algoFound )
120 if ( sm->GetSubShape().ShapeType() == TopAbs_VERTEX &&
121 mainType != TopAbs_VERTEX )
124 shapeType = sm->GetSubShape().ShapeType();
125 if ( !sm->IsEmpty() )
127 elementsFound = true;
128 theSubMeshList.push_back( sm->GetSubMeshDS() );
134 return size < theSubMeshList.size();
137 //=============================================================================
141 //=============================================================================
143 CORBA::Long SMESH_subMesh_i::GetNumberOfElements()
144 throw (SALOME::SALOME_Exception)
146 Unexpect aCatch(SALOME_SalomeException);
149 return _preMeshInfo->NbElements();
151 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
154 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
158 TListOfSubMeshes smList;
159 if ( getSubMeshes( aSubMesh, smList ))
161 TListOfSubMeshes::iterator sm = smList.begin();
162 for ( ; sm != smList.end(); ++sm )
163 nbElems += (*sm)->NbElements();
168 //=============================================================================
172 //=============================================================================
174 CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
175 throw (SALOME::SALOME_Exception)
177 Unexpect aCatch(SALOME_SalomeException);
179 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
184 if ( all ) return _preMeshInfo->NbNodes();
185 else _preMeshInfo->FullLoadFromFile();
187 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
188 SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
190 if ( aSubMeshDS && aSubMeshDS->IsComplexSubmesh() )
192 // sub-mesh on a geom group, always return all nodes
193 return aSubMeshDS->NbNodes();
195 if ( aSubMeshDS && !all )
197 // return anything we have
198 return aSubMeshDS->NbNodes();
200 if ( all ) // get nodes from aSubMesh and all child sub-meshes
203 SMESH_subMeshIteratorPtr smIt = aSubMesh->getDependsOnIterator( /*includeSelf=*/true );
204 while ( smIt->more() )
206 aSubMesh = smIt->next();
207 if (( aSubMeshDS = aSubMesh->GetSubMeshDS() ))
208 nbNodes += aSubMeshDS->NbNodes();
213 return aSubMeshDS ? aSubMeshDS->NbNodes() : 0;
216 //=============================================================================
220 //=============================================================================
222 SMESH::long_array* SMESH_subMesh_i::GetElementsId()
223 throw (SALOME::SALOME_Exception)
225 Unexpect aCatch(SALOME_SalomeException);
227 SMESH::long_array_var aResult = new SMESH::long_array();
229 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
230 return aResult._retn();
233 _preMeshInfo->FullLoadFromFile();
235 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
238 TListOfSubMeshes smList;
239 if ( getSubMeshes( aSubMesh, smList ))
241 TListOfSubMeshes::iterator sm = smList.begin();
242 for ( ; sm != smList.end(); ++sm )
243 nbElems += (*sm)->NbElements();
246 aResult->length( nbElems );
249 TListOfSubMeshes::iterator sm = smList.begin();
250 for ( int i = 0; sm != smList.end(); sm++ )
252 SMDS_ElemIteratorPtr anIt = (*sm)->GetElements();
253 for ( ; i < nbElems && anIt->more(); i++ )
254 aResult[i] = anIt->next()->GetID();
257 return aResult._retn();
261 //=============================================================================
265 //=============================================================================
267 SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theElemType )
268 throw (SALOME::SALOME_Exception)
270 Unexpect aCatch(SALOME_SalomeException);
272 SMESH::long_array_var aResult = new SMESH::long_array();
274 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
275 return aResult._retn();
278 _preMeshInfo->FullLoadFromFile();
280 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
282 // PAL5440, return all nodes belonging to elements of the sub-mesh
286 // volumes may be bound to shell instead of solid
287 TListOfSubMeshes smList;
288 if ( getSubMeshes( aSubMesh, smList ))
290 TListOfSubMeshes::iterator sm = smList.begin();
291 for ( ; sm != smList.end(); ++sm )
293 if ( theElemType == SMESH::NODE )
295 SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
297 while ( eIt->more() ) {
298 const SMDS_MeshElement* anElem = eIt->next();
299 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
300 while ( nIt->more() )
301 nodeIds.insert( nIt->next()->GetID() );
304 SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
305 while ( nIt->more() )
306 nodeIds.insert( nIt->next()->GetID() );
311 nbElems += (*sm)->NbElements();
316 if ( theElemType == SMESH::NODE )
317 aResult->length( nodeIds.size() );
319 aResult->length( nbElems );
321 int i = 0, n = aResult->length();
323 if ( theElemType == SMESH::NODE && !nodeIds.empty() ) {
324 set<int>::iterator idIt = nodeIds.begin();
325 for ( ; i < n && idIt != nodeIds.end() ; i++, idIt++ )
329 if ( theElemType != SMESH::NODE ) {
330 TListOfSubMeshes::iterator sm = smList.begin();
331 for ( i = 0; sm != smList.end(); sm++ )
333 SMDS_ElemIteratorPtr anIt = (*sm)->GetElements();
334 while ( i < n && anIt->more() ) {
335 const SMDS_MeshElement* anElem = anIt->next();
336 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
337 aResult[i++] = anElem->GetID();
342 aResult->length( i );
344 return aResult._retn();
347 //=============================================================================
351 //=============================================================================
353 SMESH::long_array* SMESH_subMesh_i::GetNodesId()
354 throw (SALOME::SALOME_Exception)
356 Unexpect aCatch(SALOME_SalomeException);
358 SMESH::long_array_var aResult = GetElementsByType( SMESH::NODE );
359 return aResult._retn();
362 //=============================================================================
366 //=============================================================================
368 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather()
369 throw (SALOME::SALOME_Exception)
371 Unexpect aCatch(SALOME_SalomeException);
372 return _mesh_i->_this();
375 //=============================================================================
379 //=============================================================================
381 CORBA::Long SMESH_subMesh_i::GetId()
386 //=======================================================================
387 //function : GetSubShape
389 //=======================================================================
391 GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape()
392 throw (SALOME::SALOME_Exception)
394 Unexpect aCatch(SALOME_SalomeException);
395 GEOM::GEOM_Object_var aShapeObj;
397 if ( _mesh_i->_mapSubMesh.find( _localId ) != _mesh_i->_mapSubMesh.end()) {
398 TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape();
400 aShapeObj = _gen_i->ShapeToGeomObject( S );
401 //mzn: N7PAL16232, N7PAL16233
402 //In some cases it's possible that GEOM_Client contains the shape same to S, but
403 //with another orientation.
404 if (aShapeObj->_is_nil())
405 aShapeObj = _gen_i->ShapeToGeomObject( S.Reversed() );
409 catch(SALOME_Exception & S_ex) {
410 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
412 return aShapeObj._retn();
415 //=============================================================================
419 //=============================================================================
420 SMESH::long_array* SMESH_subMesh_i::GetIDs()
422 return GetElementsId();
425 //=============================================================================
429 //=============================================================================
430 SMESH::ElementType SMESH_subMesh_i::GetElementType( const CORBA::Long id, const bool iselem )
431 throw (SALOME::SALOME_Exception)
434 _preMeshInfo->FullLoadFromFile();
435 return GetFather()->GetElementType( id, iselem );
438 //=============================================================================
440 * Returns number of mesh elements of each \a EntityType
441 * @return array of number of elements per \a EntityType
443 //=============================================================================
445 SMESH::long_array* SMESH_subMesh_i::GetMeshInfo()
448 return _preMeshInfo->GetMeshInfo();
450 SMESH::long_array_var aRes = new SMESH::long_array();
451 aRes->length(SMESH::Entity_Last);
452 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
455 // get number of nodes
456 aRes[ SMESH::Entity_Node ] = GetNumberOfNodes(true);
458 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
460 // get statistic from child sub-meshes
461 TListOfSubMeshes smList;
462 if ( getSubMeshes( aSubMesh, smList ) )
463 for ( TListOfSubMeshes::iterator sm = smList.begin(); sm != smList.end(); ++sm )
464 SMESH_Mesh_i::CollectMeshInfo( (*sm)->GetElements(), aRes );
469 //=======================================================================
471 * Returns number of mesh elements of each \a ElementType
473 //=======================================================================
475 SMESH::long_array* SMESH_subMesh_i::GetNbElementsByType()
477 SMESH::long_array_var aRes = new SMESH::long_array();
478 aRes->length(SMESH::NB_ELEMENT_TYPES);
479 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
481 aRes[ i ] = _preMeshInfo->NbElements( SMDSAbs_ElementType( i ));
487 aRes[ SMESH::NODE ] = GetNumberOfNodes(true);
489 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
490 TListOfSubMeshes smList;
491 if ( getSubMeshes( aSubMesh, smList ))
493 TListOfSubMeshes::iterator smDS = smList.begin();
494 for ( ; smDS != smList.end(); ++smDS )
496 SMDS_ElemIteratorPtr eIt = (*smDS)->GetElements();
498 aRes[ eIt->next()->GetType() ] = (*smDS)->NbElements();
506 //=======================================================================
507 //function : GetTypes
508 //purpose : Returns types of elements it contains
509 //=======================================================================
511 SMESH::array_of_ElementType* SMESH_subMesh_i::GetTypes()
514 return _preMeshInfo->GetTypes();
516 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
518 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
520 TListOfSubMeshes smList;
521 if ( getSubMeshes( aSubMesh, smList ))
523 TListOfSubMeshes::iterator smDS = smList.begin();
524 for ( ; smDS != smList.end(); ++smDS )
526 SMDS_ElemIteratorPtr eIt = (*smDS)->GetElements();
530 types[0] = SMESH::ElementType( eIt->next()->GetType());
535 if ( types->length() == 0 )
537 for ( smDS = smList.begin(); smDS != smList.end(); ++smDS )
539 if ( (*smDS)->GetNodes()->more() )
541 int smID = (*smDS)->GetID();
542 TopoDS_Shape shape = (*smDS)->GetParent()->IndexToShape( smID );
543 if ( !shape.IsNull() && shape.ShapeType() == TopAbs_VERTEX )
546 types[0] = SMESH::NODE;
553 return types._retn();
556 //=======================================================================
558 //purpose : interface SMESH_IDSource
559 //=======================================================================
561 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetMesh()
566 //=======================================================================
567 //function : IsMeshInfoCorrect
568 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
569 // * happen if mesh data is not yet fully loaded from the file of study.
570 //=======================================================================
572 bool SMESH_subMesh_i::IsMeshInfoCorrect()
574 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
577 //=======================================================================
578 //function : GetVtkUgStream
579 //purpose : Return data vtk unstructured grid (not implemented)
580 //=======================================================================
582 SALOMEDS::TMPFile* SMESH_subMesh_i::GetVtkUgStream()
584 SALOMEDS::TMPFile_var SeqFile;
585 return SeqFile._retn();
588 //=======================================================================
589 //function : SMESH_Invalid_subMesh_i
590 //purpose : constructor of "invalid sub-mesh" created by SMESH_Gen_i::CopyMeshWithGeom()
591 //=======================================================================
593 SMESH_Invalid_subMesh_i::SMESH_Invalid_subMesh_i( PortableServer::POA_ptr thePOA,
595 SMESH_Mesh_i* mesh_i,
597 GEOM::GEOM_Object_ptr shape )
598 : SALOME::GenericObj_i( thePOA ),
599 SMESH_subMesh_i( thePOA, gen_i, mesh_i, localId )
601 _geom = GEOM::GEOM_Object::_duplicate( shape );
604 //=======================================================================
605 //function : GetSubShape
606 //purpose : return geometry which is not a sub-shape of the main shape
607 //=======================================================================
609 GEOM::GEOM_Object_ptr SMESH_Invalid_subMesh_i::GetSubShape()
610 throw (SALOME::SALOME_Exception)
612 return GEOM::GEOM_Object::_duplicate( _geom );