1 // Copyright (C) 2007-2016 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 calsses
24 // File : SMESH_subMesh_i.cxx
25 // Author : Paul RASCLE, EDF
28 #include "SMESH_subMesh_i.hxx"
30 #include "SMESHDS_SubMesh.hxx"
31 #include "SMESH_Gen_i.hxx"
32 #include "SMESH_Mesh_i.hxx"
33 #include "SMESH_MesherHelper.hxx"
34 #include "SMESH_PreMeshInfo.hxx"
36 #include "Utils_CorbaException.hxx"
37 #include "utilities.h"
39 #include "Utils_ExceptHandlers.hxx"
41 #include <TopoDS_Iterator.hxx>
45 //=============================================================================
49 //=============================================================================
51 SMESH_subMesh_i::SMESH_subMesh_i()
52 : SALOME::GenericObj_i( PortableServer::POA::_nil() )
54 MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i default, not for use");
58 //=============================================================================
62 //=============================================================================
64 SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA,
68 : SALOME::GenericObj_i( thePOA )
75 //=============================================================================
79 //=============================================================================
81 SMESH_subMesh_i::~SMESH_subMesh_i()
83 if ( _preMeshInfo ) delete _preMeshInfo;
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)
99 return false; // "invalid sub-mesh" created by SMESH_Gen_i::CopyMeshWithGeom()
100 size_t size = theSubMeshList.size();
102 // check all child sub-meshes of one complexity,
103 // if no elements found and no algo assigned, go to children of lower complexity
105 TopoDS_Shape shape = theSubMesh->GetSubShape();
106 TopAbs_ShapeEnum mainType = SMESH_MesherHelper::GetGroupType( shape, /*noCompound=*/true );
107 TopAbs_ShapeEnum shapeType = shape.ShapeType();
108 bool elementsFound = false;
109 bool algoFound = false;
110 SMESH_subMeshIteratorPtr smIt = theSubMesh->getDependsOnIterator(/*includeSelf=*/true,
111 /*complexFirst=*/true);
112 while ( smIt->more() )
114 ::SMESH_subMesh* sm = smIt->next();
115 if ( sm->GetSubShape().ShapeType() != shapeType )
117 if ( elementsFound || algoFound )
119 if ( sm->GetSubShape().ShapeType() == TopAbs_VERTEX &&
120 mainType != TopAbs_VERTEX )
123 shapeType = sm->GetSubShape().ShapeType();
124 if ( !sm->IsEmpty() )
126 elementsFound = true;
127 theSubMeshList.push_back( sm->GetSubMeshDS() );
133 return size < theSubMeshList.size();
136 //=============================================================================
140 //=============================================================================
142 CORBA::Long SMESH_subMesh_i::GetNumberOfElements()
143 throw (SALOME::SALOME_Exception)
145 Unexpect aCatch(SALOME_SalomeException);
148 return _preMeshInfo->NbElements();
150 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
153 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
157 TListOfSubMeshes smList;
158 if ( getSubMeshes( aSubMesh, smList ))
160 TListOfSubMeshes::iterator sm = smList.begin();
161 for ( ; sm != smList.end(); ++sm )
162 nbElems += (*sm)->NbElements();
167 //=============================================================================
171 //=============================================================================
173 CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
174 throw (SALOME::SALOME_Exception)
176 Unexpect aCatch(SALOME_SalomeException);
178 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
183 if ( all ) return _preMeshInfo->NbNodes();
184 else _preMeshInfo->FullLoadFromFile();
186 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
187 SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
189 if ( aSubMeshDS && aSubMeshDS->IsComplexSubmesh() )
191 // sub-mesh on a geom group, always return all nodes
192 return aSubMeshDS->NbNodes();
194 if ( aSubMeshDS && !all )
196 // return anything we have
197 return aSubMeshDS->NbNodes();
199 if ( all ) // get nodes from aSubMesh and all child sub-meshes
202 SMESH_subMeshIteratorPtr smIt = aSubMesh->getDependsOnIterator( /*includeSelf=*/true );
203 while ( smIt->more() )
205 aSubMesh = smIt->next();
206 if (( aSubMeshDS = aSubMesh->GetSubMeshDS() ))
207 nbNodes += aSubMeshDS->NbNodes();
212 return aSubMeshDS ? aSubMeshDS->NbNodes() : 0;
215 //=============================================================================
219 //=============================================================================
221 SMESH::long_array* SMESH_subMesh_i::GetElementsId()
222 throw (SALOME::SALOME_Exception)
224 Unexpect aCatch(SALOME_SalomeException);
226 SMESH::long_array_var aResult = new SMESH::long_array();
228 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
229 return aResult._retn();
232 _preMeshInfo->FullLoadFromFile();
234 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
237 TListOfSubMeshes smList;
238 if ( getSubMeshes( aSubMesh, smList ))
240 TListOfSubMeshes::iterator sm = smList.begin();
241 for ( ; sm != smList.end(); ++sm )
242 nbElems += (*sm)->NbElements();
245 aResult->length( nbElems );
248 TListOfSubMeshes::iterator sm = smList.begin();
249 for ( int i = 0; sm != smList.end(); sm++ )
251 SMDS_ElemIteratorPtr anIt = (*sm)->GetElements();
252 for ( ; i < nbElems && anIt->more(); i++ )
253 aResult[i] = anIt->next()->GetID();
256 return aResult._retn();
260 //=============================================================================
264 //=============================================================================
266 SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theElemType )
267 throw (SALOME::SALOME_Exception)
269 Unexpect aCatch(SALOME_SalomeException);
271 SMESH::long_array_var aResult = new SMESH::long_array();
273 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
274 return aResult._retn();
277 _preMeshInfo->FullLoadFromFile();
279 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
281 // PAL5440, return all nodes belonging to elements of the sub-mesh
285 // volumes may be bound to shell instead of solid
286 TListOfSubMeshes smList;
287 if ( getSubMeshes( aSubMesh, smList ))
289 TListOfSubMeshes::iterator sm = smList.begin();
290 for ( ; sm != smList.end(); ++sm )
292 if ( theElemType == SMESH::NODE )
294 SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
296 while ( eIt->more() ) {
297 const SMDS_MeshElement* anElem = eIt->next();
298 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
299 while ( nIt->more() )
300 nodeIds.insert( nIt->next()->GetID() );
303 SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
304 while ( nIt->more() )
305 nodeIds.insert( nIt->next()->GetID() );
310 nbElems += (*sm)->NbElements();
315 if ( theElemType == SMESH::NODE )
316 aResult->length( nodeIds.size() );
318 aResult->length( nbElems );
320 int i = 0, n = aResult->length();
322 if ( theElemType == SMESH::NODE && !nodeIds.empty() ) {
323 set<int>::iterator idIt = nodeIds.begin();
324 for ( ; i < n && idIt != nodeIds.end() ; i++, idIt++ )
328 if ( theElemType != SMESH::NODE ) {
329 TListOfSubMeshes::iterator sm = smList.begin();
330 for ( i = 0; sm != smList.end(); sm++ )
332 SMDS_ElemIteratorPtr anIt = (*sm)->GetElements();
333 while ( i < n && anIt->more() ) {
334 const SMDS_MeshElement* anElem = anIt->next();
335 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
336 aResult[i++] = anElem->GetID();
341 aResult->length( i );
343 return aResult._retn();
346 //=============================================================================
350 //=============================================================================
352 SMESH::long_array* SMESH_subMesh_i::GetNodesId()
353 throw (SALOME::SALOME_Exception)
355 Unexpect aCatch(SALOME_SalomeException);
357 SMESH::long_array_var aResult = GetElementsByType( SMESH::NODE );
358 return aResult._retn();
361 //=============================================================================
365 //=============================================================================
367 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather()
368 throw (SALOME::SALOME_Exception)
370 Unexpect aCatch(SALOME_SalomeException);
371 return _mesh_i->_this();
374 //=============================================================================
378 //=============================================================================
380 CORBA::Long SMESH_subMesh_i::GetId()
385 //=======================================================================
386 //function : GetSubShape
388 //=======================================================================
390 GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape()
391 throw (SALOME::SALOME_Exception)
393 Unexpect aCatch(SALOME_SalomeException);
394 GEOM::GEOM_Object_var aShapeObj;
396 if ( _mesh_i->_mapSubMesh.find( _localId ) != _mesh_i->_mapSubMesh.end()) {
397 TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape();
399 aShapeObj = _gen_i->ShapeToGeomObject( S );
400 //mzn: N7PAL16232, N7PAL16233
401 //In some cases it's possible that GEOM_Client contains the shape same to S, but
402 //with another orientation.
403 if (aShapeObj->_is_nil())
404 aShapeObj = _gen_i->ShapeToGeomObject( S.Reversed() );
408 catch(SALOME_Exception & S_ex) {
409 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
411 return aShapeObj._retn();
414 //=============================================================================
418 //=============================================================================
419 SMESH::long_array* SMESH_subMesh_i::GetIDs()
421 return GetElementsId();
424 //=============================================================================
428 //=============================================================================
429 SMESH::ElementType SMESH_subMesh_i::GetElementType( const CORBA::Long id, const bool iselem )
430 throw (SALOME::SALOME_Exception)
433 _preMeshInfo->FullLoadFromFile();
434 return GetFather()->GetElementType( id, iselem );
437 //=============================================================================
439 * Returns number of mesh elements of each \a EntityType
440 * @return array of number of elements per \a EntityType
442 //=============================================================================
444 SMESH::long_array* SMESH_subMesh_i::GetMeshInfo()
447 return _preMeshInfo->GetMeshInfo();
449 SMESH::long_array_var aRes = new SMESH::long_array();
450 aRes->length(SMESH::Entity_Last);
451 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
454 // get number of nodes
455 aRes[ SMESH::Entity_Node ] = GetNumberOfNodes(true);
457 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
459 // get statistic from child sub-meshes
460 TListOfSubMeshes smList;
461 if ( getSubMeshes( aSubMesh, smList ) )
462 for ( TListOfSubMeshes::iterator sm = smList.begin(); sm != smList.end(); ++sm )
463 SMESH_Mesh_i::CollectMeshInfo( (*sm)->GetElements(), aRes );
468 //=======================================================================
470 * Returns number of mesh elements of each \a ElementType
472 //=======================================================================
474 SMESH::long_array* SMESH_subMesh_i::GetNbElementsByType()
476 SMESH::long_array_var aRes = new SMESH::long_array();
477 aRes->length(SMESH::NB_ELEMENT_TYPES);
478 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
480 aRes[ i ] = _preMeshInfo->NbElements( SMDSAbs_ElementType( i ));
486 aRes[ SMESH::NODE ] = GetNumberOfNodes(true);
488 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
489 if ( SMESHDS_SubMesh* smDS = aSubMesh->GetSubMeshDS() )
491 SMDS_ElemIteratorPtr eIt = smDS->GetElements();
493 aRes[ eIt->next()->GetType() ] = smDS->NbElements();
500 //=======================================================================
501 //function : GetTypes
502 //purpose : Returns types of elements it contains
503 //=======================================================================
505 SMESH::array_of_ElementType* SMESH_subMesh_i::GetTypes()
508 return _preMeshInfo->GetTypes();
510 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
512 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
513 if ( SMESHDS_SubMesh* smDS = aSubMesh->GetSubMeshDS() )
515 SMDS_ElemIteratorPtr eIt = smDS->GetElements();
519 types[0] = SMESH::ElementType( eIt->next()->GetType());
521 else if ( smDS->GetNodes()->more() )
523 TopoDS_Shape shape = aSubMesh->GetSubShape();
524 while ( !shape.IsNull() && shape.ShapeType() == TopAbs_COMPOUND )
526 TopoDS_Iterator it( shape );
527 shape = it.More() ? it.Value() : TopoDS_Shape();
529 if ( !shape.IsNull() && shape.ShapeType() == TopAbs_VERTEX )
532 types[0] = SMESH::NODE;
536 return types._retn();
539 //=======================================================================
541 //purpose : interface SMESH_IDSource
542 //=======================================================================
544 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetMesh()
549 //=======================================================================
550 //function : IsMeshInfoCorrect
551 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
552 // * happen if mesh data is not yet fully loaded from the file of study.
553 //=======================================================================
555 bool SMESH_subMesh_i::IsMeshInfoCorrect()
557 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
560 //=======================================================================
561 //function : GetVtkUgStream
562 //purpose : Return data vtk unstructured grid (not implemented)
563 //=======================================================================
565 SALOMEDS::TMPFile* SMESH_subMesh_i::GetVtkUgStream()
567 SALOMEDS::TMPFile_var SeqFile;
568 return SeqFile._retn();
571 //=======================================================================
572 //function : SMESH_Invalid_subMesh_i
573 //purpose : constructor of "invalid sub-mesh" created by SMESH_Gen_i::CopyMeshWithGeom()
574 //=======================================================================
576 SMESH_Invalid_subMesh_i::SMESH_Invalid_subMesh_i( PortableServer::POA_ptr thePOA,
578 SMESH_Mesh_i* mesh_i,
580 GEOM::GEOM_Object_ptr shape )
581 : SALOME::GenericObj_i( thePOA ),
582 SMESH_subMesh_i( thePOA, gen_i, mesh_i, localId )
584 _geom = GEOM::GEOM_Object::_duplicate( shape );
587 //=======================================================================
588 //function : GetSubShape
589 //purpose : return geomtry which is not a sub-shape of the main shape
590 //=======================================================================
592 GEOM::GEOM_Object_ptr SMESH_Invalid_subMesh_i::GetSubShape()
593 throw (SALOME::SALOME_Exception)
595 return GEOM::GEOM_Object::_duplicate( _geom );