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 MESSAGE("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)
99 size_t size = theSubMeshList.size();
101 // check all child sub-meshes of one complexity,
102 // if no elements found and no algo assigned, go to children of lower complexity
104 TopoDS_Shape shape = theSubMesh->GetSubShape();
105 TopAbs_ShapeEnum mainType = SMESH_MesherHelper::GetGroupType( shape, /*noCompound=*/true );
106 TopAbs_ShapeEnum shapeType = shape.ShapeType();
107 bool elementsFound = false;
108 bool algoFound = false;
109 SMESH_subMeshIteratorPtr smIt = theSubMesh->getDependsOnIterator(/*includeSelf=*/true,
110 /*complexFirst=*/true);
111 while ( smIt->more() )
113 ::SMESH_subMesh* sm = smIt->next();
114 if ( sm->GetSubShape().ShapeType() != shapeType )
116 if ( elementsFound || algoFound )
118 if ( sm->GetSubShape().ShapeType() == TopAbs_VERTEX &&
119 mainType != TopAbs_VERTEX )
122 shapeType = sm->GetSubShape().ShapeType();
123 if ( !sm->IsEmpty() )
125 elementsFound = true;
126 theSubMeshList.push_back( sm->GetSubMeshDS() );
132 return size < theSubMeshList.size();
135 //=============================================================================
139 //=============================================================================
141 CORBA::Long SMESH_subMesh_i::GetNumberOfElements()
142 throw (SALOME::SALOME_Exception)
144 Unexpect aCatch(SALOME_SalomeException);
147 return _preMeshInfo->NbElements();
149 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
152 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
156 TListOfSubMeshes smList;
157 if ( getSubMeshes( aSubMesh, smList ))
159 TListOfSubMeshes::iterator sm = smList.begin();
160 for ( ; sm != smList.end(); ++sm )
161 nbElems += (*sm)->NbElements();
166 //=============================================================================
170 //=============================================================================
172 CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
173 throw (SALOME::SALOME_Exception)
175 Unexpect aCatch(SALOME_SalomeException);
177 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
182 if ( all ) return _preMeshInfo->NbNodes();
183 else _preMeshInfo->FullLoadFromFile();
185 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
186 SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
188 if ( aSubMeshDS && aSubMeshDS->IsComplexSubmesh() )
190 // sub-mesh on a geom group, always return all nodes
191 return aSubMeshDS->NbNodes();
193 if ( aSubMeshDS && !all )
195 // return anything we have
196 return aSubMeshDS->NbNodes();
198 if ( all ) // get nodes from aSubMesh and all child sub-meshes
201 SMESH_subMeshIteratorPtr smIt = aSubMesh->getDependsOnIterator( /*includeSelf=*/true );
202 while ( smIt->more() )
204 aSubMesh = smIt->next();
205 if (( aSubMeshDS = aSubMesh->GetSubMeshDS() ))
206 nbNodes += aSubMeshDS->NbNodes();
211 return aSubMeshDS ? aSubMeshDS->NbNodes() : 0;
214 //=============================================================================
218 //=============================================================================
220 SMESH::long_array* SMESH_subMesh_i::GetElementsId()
221 throw (SALOME::SALOME_Exception)
223 Unexpect aCatch(SALOME_SalomeException);
225 SMESH::long_array_var aResult = new SMESH::long_array();
227 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
228 return aResult._retn();
231 _preMeshInfo->FullLoadFromFile();
233 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
236 TListOfSubMeshes smList;
237 if ( getSubMeshes( aSubMesh, smList ))
239 TListOfSubMeshes::iterator sm = smList.begin();
240 for ( ; sm != smList.end(); ++sm )
241 nbElems += (*sm)->NbElements();
244 aResult->length( nbElems );
247 TListOfSubMeshes::iterator sm = smList.begin();
248 for ( int i = 0; sm != smList.end(); sm++ )
250 SMDS_ElemIteratorPtr anIt = (*sm)->GetElements();
251 for ( ; i < nbElems && anIt->more(); i++ )
252 aResult[i] = anIt->next()->GetID();
255 return aResult._retn();
259 //=============================================================================
263 //=============================================================================
265 SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theElemType )
266 throw (SALOME::SALOME_Exception)
268 Unexpect aCatch(SALOME_SalomeException);
270 SMESH::long_array_var aResult = new SMESH::long_array();
272 if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
273 return aResult._retn();
276 _preMeshInfo->FullLoadFromFile();
278 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
280 // PAL5440, return all nodes belonging to elements of the sub-mesh
284 // volumes may be bound to shell instead of solid
285 TListOfSubMeshes smList;
286 if ( getSubMeshes( aSubMesh, smList ))
288 TListOfSubMeshes::iterator sm = smList.begin();
289 for ( ; sm != smList.end(); ++sm )
291 if ( theElemType == SMESH::NODE )
293 SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
295 while ( eIt->more() ) {
296 const SMDS_MeshElement* anElem = eIt->next();
297 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
298 while ( nIt->more() )
299 nodeIds.insert( nIt->next()->GetID() );
302 SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
303 while ( nIt->more() )
304 nodeIds.insert( nIt->next()->GetID() );
309 nbElems += (*sm)->NbElements();
314 if ( theElemType == SMESH::NODE )
315 aResult->length( nodeIds.size() );
317 aResult->length( nbElems );
319 int i = 0, n = aResult->length();
321 if ( theElemType == SMESH::NODE && !nodeIds.empty() ) {
322 set<int>::iterator idIt = nodeIds.begin();
323 for ( ; i < n && idIt != nodeIds.end() ; i++, idIt++ )
327 if ( theElemType != SMESH::NODE ) {
328 TListOfSubMeshes::iterator sm = smList.begin();
329 for ( i = 0; sm != smList.end(); sm++ )
331 SMDS_ElemIteratorPtr anIt = (*sm)->GetElements();
332 while ( i < n && anIt->more() ) {
333 const SMDS_MeshElement* anElem = anIt->next();
334 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
335 aResult[i++] = anElem->GetID();
340 aResult->length( i );
342 return aResult._retn();
345 //=============================================================================
349 //=============================================================================
351 SMESH::long_array* SMESH_subMesh_i::GetNodesId()
352 throw (SALOME::SALOME_Exception)
354 Unexpect aCatch(SALOME_SalomeException);
356 SMESH::long_array_var aResult = GetElementsByType( SMESH::NODE );
357 return aResult._retn();
360 //=============================================================================
364 //=============================================================================
366 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather()
367 throw (SALOME::SALOME_Exception)
369 Unexpect aCatch(SALOME_SalomeException);
370 return _mesh_i->_this();
373 //=============================================================================
377 //=============================================================================
379 CORBA::Long SMESH_subMesh_i::GetId()
384 //=======================================================================
385 //function : GetSubShape
387 //=======================================================================
389 GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape()
390 throw (SALOME::SALOME_Exception)
392 Unexpect aCatch(SALOME_SalomeException);
393 GEOM::GEOM_Object_var aShapeObj;
395 if ( _mesh_i->_mapSubMesh.find( _localId ) != _mesh_i->_mapSubMesh.end()) {
396 TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape();
398 aShapeObj = _gen_i->ShapeToGeomObject( S );
399 //mzn: N7PAL16232, N7PAL16233
400 //In some cases it's possible that GEOM_Client contains the shape same to S, but
401 //with another orientation.
402 if (aShapeObj->_is_nil())
403 aShapeObj = _gen_i->ShapeToGeomObject( S.Reversed() );
407 catch(SALOME_Exception & S_ex) {
408 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
410 return aShapeObj._retn();
413 //=============================================================================
417 //=============================================================================
418 SMESH::long_array* SMESH_subMesh_i::GetIDs()
420 return GetElementsId();
423 //=============================================================================
427 //=============================================================================
428 SMESH::ElementType SMESH_subMesh_i::GetElementType( const CORBA::Long id, const bool iselem )
429 throw (SALOME::SALOME_Exception)
432 _preMeshInfo->FullLoadFromFile();
433 return GetFather()->GetElementType( id, iselem );
436 //=============================================================================
438 * Returns number of mesh elements of each \a EntityType
439 * @return array of number of elements per \a EntityType
441 //=============================================================================
443 SMESH::long_array* SMESH_subMesh_i::GetMeshInfo()
446 return _preMeshInfo->GetMeshInfo();
448 SMESH::long_array_var aRes = new SMESH::long_array();
449 aRes->length(SMESH::Entity_Last);
450 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
453 // get number of nodes
454 aRes[ SMESH::Entity_Node ] = GetNumberOfNodes(true);
456 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
458 // get statistic from child sub-meshes
459 TListOfSubMeshes smList;
460 if ( getSubMeshes( aSubMesh, smList ) )
461 for ( TListOfSubMeshes::iterator sm = smList.begin(); sm != smList.end(); ++sm )
462 SMESH_Mesh_i::CollectMeshInfo( (*sm)->GetElements(), aRes );
467 //=======================================================================
469 * Returns number of mesh elements of each \a ElementType
471 //=======================================================================
473 SMESH::long_array* SMESH_subMesh_i::GetNbElementsByType()
475 SMESH::long_array_var aRes = new SMESH::long_array();
476 aRes->length(SMESH::NB_ELEMENT_TYPES);
477 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
479 aRes[ i ] = _preMeshInfo->NbElements( SMDSAbs_ElementType( i ));
485 aRes[ SMESH::NODE ] = GetNumberOfNodes(true);
487 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
488 if ( SMESHDS_SubMesh* smDS = aSubMesh->GetSubMeshDS() )
490 SMDS_ElemIteratorPtr eIt = smDS->GetElements();
492 aRes[ eIt->next()->GetType() ] = smDS->NbElements();
499 //=======================================================================
500 //function : GetTypes
501 //purpose : Returns types of elements it contains
502 //=======================================================================
504 SMESH::array_of_ElementType* SMESH_subMesh_i::GetTypes()
507 return _preMeshInfo->GetTypes();
509 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
511 ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
512 if ( SMESHDS_SubMesh* smDS = aSubMesh->GetSubMeshDS() )
514 SMDS_ElemIteratorPtr eIt = smDS->GetElements();
518 types[0] = SMESH::ElementType( eIt->next()->GetType());
520 else if ( smDS->GetNodes()->more() )
522 TopoDS_Shape shape = aSubMesh->GetSubShape();
523 while ( !shape.IsNull() && shape.ShapeType() == TopAbs_COMPOUND )
525 TopoDS_Iterator it( shape );
526 shape = it.More() ? it.Value() : TopoDS_Shape();
528 if ( !shape.IsNull() && shape.ShapeType() == TopAbs_VERTEX )
531 types[0] = SMESH::NODE;
535 return types._retn();
538 //=======================================================================
540 //purpose : interface SMESH_IDSource
541 //=======================================================================
543 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetMesh()
548 //=======================================================================
549 //function : IsMeshInfoCorrect
550 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
551 // * happen if mesh data is not yet fully loaded from the file of study.
552 //=======================================================================
554 bool SMESH_subMesh_i::IsMeshInfoCorrect()
556 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
559 //=======================================================================
560 //function : GetVtkUgStream
561 //purpose : Return data vtk unstructured grid (not implemented)
562 //=======================================================================
564 SALOMEDS::TMPFile* SMESH_subMesh_i::GetVtkUgStream()
566 SALOMEDS::TMPFile_var SeqFile;
567 return SeqFile._retn();