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"
29 #include "SMESH_Gen_i.hxx"
30 #include "SMESH_Mesh_i.hxx"
31 #include "SMESH_PreMeshInfo.hxx"
32 #include "SMESH_MesherHelper.hxx"
34 #include "Utils_CorbaException.hxx"
35 #include "utilities.h"
37 #include "Utils_ExceptHandlers.hxx"
39 #include <TopoDS_Iterator.hxx>
43 //=============================================================================
47 //=============================================================================
49 SMESH_subMesh_i::SMESH_subMesh_i()
50 : SALOME::GenericObj_i( PortableServer::POA::_nil() )
52 MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i default, not for use");
56 //=============================================================================
60 //=============================================================================
62 SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA,
66 : SALOME::GenericObj_i( thePOA )
73 //=============================================================================
77 //=============================================================================
79 SMESH_subMesh_i::~SMESH_subMesh_i()
81 MESSAGE("SMESH_subMesh_i::~SMESH_subMesh_i");
82 if ( _preMeshInfo ) delete _preMeshInfo;
86 //=======================================================================
87 //function : getSubMeshes
88 //purpose : for a submesh on shape to which elements are not bound directly,
89 // return submeshes containing elements
90 //=======================================================================
92 typedef list<SMESHDS_SubMesh*> TListOfSubMeshes;
94 bool getSubMeshes(::SMESH_subMesh* theSubMesh,
95 TListOfSubMeshes& theSubMeshList)
97 size_t size = theSubMeshList.size();
99 // check all child sub-meshes of one complexity,
100 // if no elements found and no algo assigned, go to children of lower complexity
102 TopoDS_Shape shape = theSubMesh->GetSubShape();
103 TopAbs_ShapeEnum mainType = SMESH_MesherHelper::GetGroupType( shape, /*noCompound=*/true );
104 TopAbs_ShapeEnum shapeType = shape.ShapeType();
105 bool elementsFound = false;
106 bool algoFound = false;
107 SMESH_subMeshIteratorPtr smIt = theSubMesh->getDependsOnIterator(/*includeSelf=*/true,
108 /*complexFirst=*/true);
109 while ( smIt->more() )
111 ::SMESH_subMesh* sm = smIt->next();
112 if ( sm->GetSubShape().ShapeType() != shapeType )
114 if ( elementsFound || algoFound )
116 if ( sm->GetSubShape().ShapeType() == TopAbs_VERTEX &&
117 mainType != TopAbs_VERTEX )
120 shapeType = sm->GetSubShape().ShapeType();
121 if ( !sm->IsEmpty() )
123 elementsFound = true;
124 theSubMeshList.push_back( sm->GetSubMeshDS() );
130 return size < theSubMeshList.size();
133 //=============================================================================
137 //=============================================================================
139 CORBA::Long SMESH_subMesh_i::GetNumberOfElements()
140 throw (SALOME::SALOME_Exception)
142 Unexpect aCatch(SALOME_SalomeException);
145 return _preMeshInfo->NbElements();
147 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
150 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
154 TListOfSubMeshes smList;
155 if ( getSubMeshes( aSubMesh, smList ))
157 TListOfSubMeshes::iterator sm = smList.begin();
158 for ( ; sm != smList.end(); ++sm )
159 nbElems += (*sm)->NbElements();
164 //=============================================================================
168 //=============================================================================
170 CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
171 throw (SALOME::SALOME_Exception)
173 Unexpect aCatch(SALOME_SalomeException);
175 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
180 if ( all ) return _preMeshInfo->NbNodes();
181 else _preMeshInfo->FullLoadFromFile();
183 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
184 SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
186 if ( aSubMeshDS && aSubMeshDS->IsComplexSubmesh() )
188 // sub-mesh on a geom group, always return all nodes
189 return aSubMeshDS->NbNodes();
191 if ( aSubMeshDS && !all )
193 // return anything we have
194 return aSubMeshDS->NbNodes();
196 if ( all ) // get nodes from aSubMesh and all child sub-meshes
199 SMESH_subMeshIteratorPtr smIt = aSubMesh->getDependsOnIterator( /*includeSelf=*/true );
200 while ( smIt->more() )
202 aSubMesh = smIt->next();
203 if (( aSubMeshDS = aSubMesh->GetSubMeshDS() ))
204 nbNodes += aSubMeshDS->NbNodes();
209 return aSubMeshDS ? aSubMeshDS->NbNodes() : 0;
212 //=============================================================================
216 //=============================================================================
218 SMESH::long_array* SMESH_subMesh_i::GetElementsId()
219 throw (SALOME::SALOME_Exception)
221 Unexpect aCatch(SALOME_SalomeException);
223 SMESH::long_array_var aResult = new SMESH::long_array();
225 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
226 return aResult._retn();
229 _preMeshInfo->FullLoadFromFile();
231 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
234 TListOfSubMeshes smList;
235 if ( getSubMeshes( aSubMesh, smList ))
237 TListOfSubMeshes::iterator sm = smList.begin();
238 for ( ; sm != smList.end(); ++sm )
239 nbElems += (*sm)->NbElements();
242 aResult->length( nbElems );
245 TListOfSubMeshes::iterator sm = smList.begin();
246 for ( int i = 0; sm != smList.end(); sm++ )
248 SMDS_ElemIteratorPtr anIt = (*sm)->GetElements();
249 for ( ; i < nbElems && anIt->more(); i++ )
250 aResult[i] = anIt->next()->GetID();
253 return aResult._retn();
257 //=============================================================================
261 //=============================================================================
263 SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theElemType )
264 throw (SALOME::SALOME_Exception)
266 Unexpect aCatch(SALOME_SalomeException);
268 SMESH::long_array_var aResult = new SMESH::long_array();
270 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
271 return aResult._retn();
274 _preMeshInfo->FullLoadFromFile();
276 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
278 // PAL5440, return all nodes belonging to elements of the sub-mesh
282 // volumes may be bound to shell instead of solid
283 TListOfSubMeshes smList;
284 if ( getSubMeshes( aSubMesh, smList ))
286 TListOfSubMeshes::iterator sm = smList.begin();
287 for ( ; sm != smList.end(); ++sm )
289 if ( theElemType == SMESH::NODE )
291 SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
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() );
300 SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
301 while ( nIt->more() )
302 nodeIds.insert( nIt->next()->GetID() );
307 nbElems += (*sm)->NbElements();
312 if ( theElemType == SMESH::NODE )
313 aResult->length( nodeIds.size() );
315 aResult->length( nbElems );
317 int i = 0, n = aResult->length();
319 if ( theElemType == SMESH::NODE && !nodeIds.empty() ) {
320 set<int>::iterator idIt = nodeIds.begin();
321 for ( ; i < n && idIt != nodeIds.end() ; i++, idIt++ )
325 if ( theElemType != SMESH::NODE ) {
326 TListOfSubMeshes::iterator sm = smList.begin();
327 for ( i = 0; sm != smList.end(); sm++ )
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();
338 aResult->length( i );
340 return aResult._retn();
343 //=============================================================================
347 //=============================================================================
349 SMESH::long_array* SMESH_subMesh_i::GetNodesId()
350 throw (SALOME::SALOME_Exception)
352 Unexpect aCatch(SALOME_SalomeException);
354 SMESH::long_array_var aResult = GetElementsByType( SMESH::NODE );
355 return aResult._retn();
358 //=============================================================================
362 //=============================================================================
364 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather()
365 throw (SALOME::SALOME_Exception)
367 Unexpect aCatch(SALOME_SalomeException);
368 return _mesh_i->_this();
371 //=============================================================================
375 //=============================================================================
377 CORBA::Long SMESH_subMesh_i::GetId()
382 //=======================================================================
383 //function : GetSubShape
385 //=======================================================================
387 GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape()
388 throw (SALOME::SALOME_Exception)
390 Unexpect aCatch(SALOME_SalomeException);
391 GEOM::GEOM_Object_var aShapeObj;
393 if ( _mesh_i->_mapSubMesh.find( _localId ) != _mesh_i->_mapSubMesh.end()) {
394 TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape();
396 aShapeObj = _gen_i->ShapeToGeomObject( S );
397 //mzn: N7PAL16232, N7PAL16233
398 //In some cases it's possible that GEOM_Client contains the shape same to S, but
399 //with another orientation.
400 if (aShapeObj->_is_nil())
401 aShapeObj = _gen_i->ShapeToGeomObject( S.Reversed() );
405 catch(SALOME_Exception & S_ex) {
406 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
408 return aShapeObj._retn();
411 //=============================================================================
415 //=============================================================================
416 SMESH::long_array* SMESH_subMesh_i::GetIDs()
418 return GetElementsId();
421 //=============================================================================
425 //=============================================================================
426 SMESH::ElementType SMESH_subMesh_i::GetElementType( const CORBA::Long id, const bool iselem )
427 throw (SALOME::SALOME_Exception)
430 _preMeshInfo->FullLoadFromFile();
431 return GetFather()->GetElementType( id, iselem );
434 //=============================================================================
436 * Returns number of mesh elements of each \a EntityType
437 * @return array of number of elements per \a EntityType
439 //=============================================================================
441 SMESH::long_array* SMESH_subMesh_i::GetMeshInfo()
444 return _preMeshInfo->GetMeshInfo();
446 SMESH::long_array_var aRes = new SMESH::long_array();
447 aRes->length(SMESH::Entity_Last);
448 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
451 // get number of nodes
452 aRes[ SMESH::Entity_Node ] = GetNumberOfNodes(true);
454 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
456 // get statistic from child sub-meshes
457 TListOfSubMeshes smList;
458 if ( getSubMeshes( aSubMesh, smList ) )
459 for ( TListOfSubMeshes::iterator sm = smList.begin(); sm != smList.end(); ++sm )
460 SMESH_Mesh_i::CollectMeshInfo( (*sm)->GetElements(), aRes );
465 //=======================================================================
467 * Returns number of mesh elements of each \a ElementType
469 //=======================================================================
471 SMESH::long_array* SMESH_subMesh_i::GetNbElementsByType()
473 SMESH::long_array_var aRes = new SMESH::long_array();
474 aRes->length(SMESH::NB_ELEMENT_TYPES);
475 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
477 aRes[ i ] = _preMeshInfo->NbElements( SMDSAbs_ElementType( i ));
483 aRes[ SMESH::NODE ] = GetNumberOfNodes(true);
485 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
486 if ( SMESHDS_SubMesh* smDS = aSubMesh->GetSubMeshDS() )
488 SMDS_ElemIteratorPtr eIt = smDS->GetElements();
490 aRes[ eIt->next()->GetType() ] = smDS->NbElements();
497 //=======================================================================
498 //function : GetTypes
499 //purpose : Returns types of elements it contains
500 //=======================================================================
502 SMESH::array_of_ElementType* SMESH_subMesh_i::GetTypes()
505 return _preMeshInfo->GetTypes();
507 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
509 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
510 if ( SMESHDS_SubMesh* smDS = aSubMesh->GetSubMeshDS() )
512 SMDS_ElemIteratorPtr eIt = smDS->GetElements();
516 types[0] = SMESH::ElementType( eIt->next()->GetType());
518 else if ( smDS->GetNodes()->more() )
520 TopoDS_Shape shape = aSubMesh->GetSubShape();
521 while ( !shape.IsNull() && shape.ShapeType() == TopAbs_COMPOUND )
523 TopoDS_Iterator it( shape );
524 shape = it.More() ? it.Value() : TopoDS_Shape();
526 if ( !shape.IsNull() && shape.ShapeType() == TopAbs_VERTEX )
529 types[0] = SMESH::NODE;
533 return types._retn();
536 //=======================================================================
538 //purpose : interface SMESH_IDSource
539 //=======================================================================
541 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetMesh()
546 //=======================================================================
547 //function : IsMeshInfoCorrect
548 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
549 // * happen if mesh data is not yet fully loaded from the file of study.
550 //=======================================================================
552 bool SMESH_subMesh_i::IsMeshInfoCorrect()
554 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
557 //=======================================================================
558 //function : GetVtkUgStream
559 //purpose : Return data vtk unstructured grid (not implemented)
560 //=======================================================================
562 SALOMEDS::TMPFile* SMESH_subMesh_i::GetVtkUgStream()
564 SALOMEDS::TMPFile_var SeqFile;
565 return SeqFile._retn();