Back to index

salome-smesh  6.5.0
SMESH_subMesh_i.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
00024 //  File   : SMESH_subMesh_i.cxx
00025 //  Author : Paul RASCLE, EDF
00026 //  Module : SMESH
00027 //
00028 #include "SMESH_subMesh_i.hxx"
00029 #include "SMESH_Gen_i.hxx"
00030 #include "SMESH_Mesh_i.hxx"
00031 #include "SMESH_PreMeshInfo.hxx"
00032 
00033 #include "Utils_CorbaException.hxx"
00034 #include "utilities.h"
00035 #include "OpUtil.hxx"
00036 #include "Utils_ExceptHandlers.hxx"
00037 
00038 #include <TopoDS_Iterator.hxx>
00039 #include <TopExp_Explorer.hxx>
00040 
00041 using namespace std;
00042 
00043 //=============================================================================
00047 //=============================================================================
00048 
00049 SMESH_subMesh_i::SMESH_subMesh_i()
00050      : SALOME::GenericObj_i( PortableServer::POA::_nil() )
00051 {
00052   MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i default, not for use");
00053   ASSERT(0);
00054 }
00055 
00056 //=============================================================================
00060 //=============================================================================
00061 
00062 SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA,
00063                                   SMESH_Gen_i*            gen_i,
00064                                   SMESH_Mesh_i*           mesh_i,
00065                                   int                     localId )
00066      : SALOME::GenericObj_i( thePOA )
00067 {
00068   _gen_i = gen_i;
00069   _mesh_i = mesh_i;
00070   _localId = localId;
00071   _preMeshInfo = NULL;
00072 }
00073 //=============================================================================
00077 //=============================================================================
00078 
00079 SMESH_subMesh_i::~SMESH_subMesh_i()
00080 {
00081   MESSAGE("SMESH_subMesh_i::~SMESH_subMesh_i");
00082   if ( _preMeshInfo ) delete _preMeshInfo;
00083   _preMeshInfo = NULL;
00084 }
00085 
00086 //=======================================================================
00087 //function : getSubMeshes
00088 //purpose  : for a submesh on shape to which elements are not bound directly,
00089 //           return submeshes containing elements
00090 //=======================================================================
00091 
00092 typedef list<SMESHDS_SubMesh*> TListOfSubMeshes;
00093 
00094 bool getSubMeshes(::SMESH_subMesh*  theSubMesh,
00095                   TListOfSubMeshes& theSubMeshList)
00096 {
00097   int size = theSubMeshList.size();
00098 
00099   SMESH_Mesh*      aMesh      = theSubMesh->GetFather();
00100   SMESHDS_Mesh*    aMeshDS    = aMesh->GetMeshDS();
00101   SMESHDS_SubMesh* aSubMeshDS = theSubMesh->GetSubMeshDS();
00102 
00103   // nodes can be bound to either vertex, edge, face or solid_or_shell
00104   TopoDS_Shape aShape = theSubMesh->GetSubShape();
00105   switch ( aShape.ShapeType() )
00106   {
00107   case TopAbs_SOLID: {
00108     // add submesh of solid itself
00109     aSubMeshDS = aMeshDS->MeshElements( aShape );
00110     if ( aSubMeshDS )
00111       theSubMeshList.push_back( aSubMeshDS );
00112     // and of the first shell
00113     TopExp_Explorer exp( aShape, TopAbs_SHELL );
00114     if ( exp.More() ) {
00115       aSubMeshDS = aMeshDS->MeshElements( exp.Current() );
00116       if ( aSubMeshDS )
00117         theSubMeshList.push_back( aSubMeshDS );
00118     }
00119     break;
00120   }
00121   case TopAbs_WIRE:
00122   case TopAbs_COMPOUND:
00123   case TopAbs_COMPSOLID: {
00124     // call getSubMeshes() for sub-shapes
00125     list<TopoDS_Shape> shapeList;
00126     shapeList.push_back( aShape );
00127     list<TopoDS_Shape>::iterator sh = shapeList.begin();
00128     for ( ; sh != shapeList.end(); ++sh ) {
00129       for ( TopoDS_Iterator it( *sh ); it.More(); it.Next() ) {
00130         if ( ::SMESH_subMesh* aSubMesh = aMesh->GetSubMeshContaining( it.Value() ))
00131           getSubMeshes( aSubMesh, theSubMeshList ); // add found submesh or explore deeper
00132         else
00133           // no submesh for a compound inside compound
00134           shapeList.push_back( it.Value() );
00135       }
00136     }
00137     // return only unique submeshes
00138     set<SMESHDS_SubMesh*> smSet;
00139     TListOfSubMeshes::iterator sm = theSubMeshList.begin();
00140     while ( sm != theSubMeshList.end() ) {
00141       if ( !smSet.insert( *sm ).second )
00142         sm = theSubMeshList.erase( sm );
00143       else
00144         ++sm;
00145     }
00146     break;
00147   }
00148   default:
00149     if ( aSubMeshDS )
00150       theSubMeshList.push_back( aSubMeshDS );
00151   }
00152   return size < theSubMeshList.size();
00153 }
00154 
00155 //=============================================================================
00159 //=============================================================================
00160 
00161 CORBA::Long SMESH_subMesh_i::GetNumberOfElements()
00162   throw (SALOME::SALOME_Exception)
00163 {
00164   Unexpect aCatch(SALOME_SalomeException);
00165 
00166   if ( _preMeshInfo )
00167     return _preMeshInfo->NbElements();
00168 
00169   if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
00170     return 0;
00171 
00172   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
00173   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
00174 
00175   int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
00176 
00177   // volumes are bound to shell
00178   TListOfSubMeshes smList;
00179   if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
00180   {
00181     TListOfSubMeshes::iterator sm = smList.begin();
00182     for ( ; sm != smList.end(); ++sm )
00183       nbElems += (*sm)->NbElements();
00184   }
00185   return nbElems;
00186 }
00187 
00188 //=============================================================================
00192 //=============================================================================
00193 
00194 CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
00195   throw (SALOME::SALOME_Exception)
00196 {
00197   Unexpect aCatch(SALOME_SalomeException);
00198 
00199   if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
00200     return 0;
00201 
00202   if ( _preMeshInfo )
00203   {
00204     if ( all ) return _preMeshInfo->NbNodes();
00205     else _preMeshInfo->FullLoadFromFile();
00206   }
00207   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
00208   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
00209 
00210   set<int> nodeIds;
00211 
00212   // nodes are bound to shell instead of solid
00213   TListOfSubMeshes smList;
00214   if ( all && getSubMeshes( aSubMesh, smList ))
00215   {
00216     TListOfSubMeshes::iterator sm = smList.begin();
00217     for ( ; sm != smList.end(); ++sm )
00218     {
00219       SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
00220       if ( eIt->more() ) {
00221         while ( eIt->more() ) {
00222           const SMDS_MeshElement* anElem = eIt->next();
00223           SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
00224           while ( nIt->more() )
00225             nodeIds.insert( nIt->next()->GetID() );
00226         }
00227       } else {
00228         SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
00229         while ( nIt->more() )
00230           nodeIds.insert( nIt->next()->GetID() );
00231       }      
00232     }
00233     return nodeIds.size();
00234   }
00235 
00236   if ( aSubMeshDS == NULL )
00237     return 0;
00238 
00239   if ( all ) { // all nodes of submesh elements
00240     SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
00241     if ( eIt->more() ) {
00242       while ( eIt->more() ) {
00243         const SMDS_MeshElement* anElem = eIt->next();
00244         SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
00245         while ( nIt->more() )
00246           nodeIds.insert( nIt->next()->GetID() );
00247       }
00248     } else {
00249       SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes();
00250       while ( nIt->more() )
00251         nodeIds.insert( nIt->next()->GetID() );
00252     }
00253     return nodeIds.size();
00254   }
00255 
00256   return aSubMeshDS->NbNodes();
00257 }
00258 
00259 //=============================================================================
00263 //=============================================================================
00264 
00265 SMESH::long_array* SMESH_subMesh_i::GetElementsId()
00266   throw (SALOME::SALOME_Exception)
00267 {
00268   Unexpect aCatch(SALOME_SalomeException);
00269 
00270   SMESH::long_array_var aResult = new SMESH::long_array();
00271 
00272   if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
00273     return aResult._retn();
00274 
00275   if ( _preMeshInfo )
00276     _preMeshInfo->FullLoadFromFile();
00277 
00278   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
00279   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
00280 
00281   int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
00282   TListOfSubMeshes smList;
00283   if ( nbElems )
00284     smList.push_back( aSubMeshDS );
00285 
00286   // volumes are bound to shell
00287   if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
00288   {
00289     TListOfSubMeshes::iterator sm = smList.begin();
00290     for ( ; sm != smList.end(); ++sm )
00291       nbElems += (*sm)->NbElements();
00292   }
00293 
00294   aResult->length( nbElems );
00295   if ( nbElems )
00296   {
00297     TListOfSubMeshes::iterator sm = smList.begin();
00298     for ( int i = 0; sm != smList.end(); sm++ )
00299     {
00300       SMDS_ElemIteratorPtr anIt = (*sm)->GetElements();
00301       for ( ; i < nbElems && anIt->more(); i++ )
00302         aResult[i] = anIt->next()->GetID();
00303     }
00304   }
00305   return aResult._retn();
00306 }
00307 
00308 
00309 //=============================================================================
00313 //=============================================================================
00314 
00315 SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theElemType )
00316     throw (SALOME::SALOME_Exception)
00317 {
00318   Unexpect aCatch(SALOME_SalomeException);
00319 
00320   SMESH::long_array_var aResult = new SMESH::long_array();
00321 
00322   if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
00323     return aResult._retn();
00324 
00325   if ( _preMeshInfo )
00326     _preMeshInfo->FullLoadFromFile();
00327 
00328   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
00329   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
00330 
00331   // PAL5440, return all nodes belonging to elements of submesh
00332   set<int> nodeIds;
00333   int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
00334 
00335   // volumes may be bound to shell instead of solid
00336   TListOfSubMeshes smList;
00337   if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
00338   {
00339     TListOfSubMeshes::iterator sm = smList.begin();
00340     for ( ; sm != smList.end(); ++sm )
00341     {
00342       if ( theElemType == SMESH::NODE )
00343       {
00344         SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
00345         if ( eIt->more() ) {
00346           while ( eIt->more() ) {
00347             const SMDS_MeshElement* anElem = eIt->next();
00348             SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
00349             while ( nIt->more() )
00350               nodeIds.insert( nIt->next()->GetID() );
00351           }
00352         } else {
00353           SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
00354           while ( nIt->more() )
00355             nodeIds.insert( nIt->next()->GetID() );
00356         }
00357       }
00358       else
00359       {
00360         nbElems += (*sm)->NbElements();
00361       }
00362     }
00363     aSubMeshDS = 0;
00364   }
00365   else
00366   {
00367     if ( nbElems )
00368       smList.push_back( aSubMeshDS );
00369   }
00370 
00371   if ( theElemType == SMESH::NODE && aSubMeshDS )
00372   {
00373     SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
00374     if ( eIt->more() ) {
00375       while ( eIt->more() ) {
00376         const SMDS_MeshElement* anElem = eIt->next();
00377         SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
00378         while ( nIt->more() )
00379           nodeIds.insert( nIt->next()->GetID() );
00380       }
00381     } else {
00382       SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes();
00383       while ( nIt->more() )
00384         nodeIds.insert( nIt->next()->GetID() );
00385     }
00386   }
00387 
00388   if ( theElemType == SMESH::NODE )
00389     aResult->length( nodeIds.size() );
00390   else
00391     aResult->length( nbElems );
00392 
00393   int i = 0, n = aResult->length();
00394 
00395   if ( theElemType == SMESH::NODE && !nodeIds.empty() ) {
00396     set<int>::iterator idIt = nodeIds.begin();
00397     for ( ; i < n && idIt != nodeIds.end() ; i++, idIt++ )
00398       aResult[i] = *idIt;
00399   }
00400 
00401   if ( theElemType != SMESH::NODE ) {
00402     TListOfSubMeshes::iterator sm = smList.begin();
00403     for ( i = 0; sm != smList.end(); sm++ )
00404     {
00405       aSubMeshDS = *sm;
00406       SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements();
00407       while ( i < n && anIt->more() ) {
00408         const SMDS_MeshElement* anElem = anIt->next();
00409         if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
00410           aResult[i++] = anElem->GetID();
00411       }
00412     }
00413   }
00414 
00415   aResult->length( i );
00416 
00417   return aResult._retn();
00418 }
00419 
00420 //=============================================================================
00424 //=============================================================================
00425   
00426 SMESH::long_array* SMESH_subMesh_i::GetNodesId()
00427   throw (SALOME::SALOME_Exception)
00428 {
00429   Unexpect aCatch(SALOME_SalomeException);
00430 
00431   SMESH::long_array_var aResult = GetElementsByType( SMESH::NODE );
00432   return aResult._retn();
00433 }
00434 
00435 //=============================================================================
00439 //=============================================================================
00440   
00441 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather()
00442   throw (SALOME::SALOME_Exception)
00443 {
00444   Unexpect aCatch(SALOME_SalomeException);
00445   return _mesh_i->_this();
00446 }
00447 
00448 //=============================================================================
00452 //=============================================================================
00453   
00454 CORBA::Long SMESH_subMesh_i::GetId()
00455 {
00456   return _localId;
00457 }
00458 
00459 //=======================================================================
00460 //function : GetSubShape
00461 //purpose  : 
00462 //=======================================================================
00463 
00464 GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape()
00465      throw (SALOME::SALOME_Exception)
00466 {
00467   Unexpect aCatch(SALOME_SalomeException);
00468   GEOM::GEOM_Object_var aShapeObj;
00469   try {
00470     if ( _mesh_i->_mapSubMesh.find( _localId ) != _mesh_i->_mapSubMesh.end()) {
00471       TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape();
00472       if ( !S.IsNull() ) {
00473         aShapeObj = _gen_i->ShapeToGeomObject( S );
00474         //mzn: N7PAL16232, N7PAL16233
00475         //In some cases it's possible that GEOM_Client contains the shape same to S, but
00476         //with another orientation.
00477         if (aShapeObj->_is_nil())
00478           aShapeObj = _gen_i->ShapeToGeomObject( S.Reversed() );
00479       }
00480     }
00481   }
00482   catch(SALOME_Exception & S_ex) {
00483     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
00484   }
00485   return aShapeObj._retn();
00486 }
00487 
00488 //=============================================================================
00492 //=============================================================================
00493 SALOME_MED::FAMILY_ptr SMESH_subMesh_i::GetFamily()
00494   throw (SALOME::SALOME_Exception)
00495 {
00496   Unexpect aCatch(SALOME_SalomeException);
00497   if ( _preMeshInfo )
00498     _preMeshInfo->FullLoadFromFile();
00499   SALOME_MED::MESH_var MEDMesh = GetFather()->GetMEDMesh();
00500 
00501   SALOME_MED::Family_array_var families = 
00502     MEDMesh->getFamilies(SALOME_MED::MED_NODE);
00503     
00504   for ( int i = 0; i < families->length(); i++ ) {
00505     if ( families[i]->getIdentifier() == ( _localId ) )
00506       return families[i];
00507   }
00508   
00509   return SALOME_MED::FAMILY::_nil();
00510 }
00511 
00512 //=============================================================================
00516 //=============================================================================
00517 SMESH::long_array* SMESH_subMesh_i::GetIDs()
00518 {
00519   return GetElementsId();
00520 }
00521 
00522 //=============================================================================
00526 //=============================================================================
00527 SMESH::ElementType SMESH_subMesh_i::GetElementType( const CORBA::Long id, const bool iselem )
00528   throw (SALOME::SALOME_Exception)
00529 {
00530   if ( _preMeshInfo )
00531     _preMeshInfo->FullLoadFromFile();
00532   return GetFather()->GetElementType( id, iselem );
00533 }
00534 
00535 
00536 //=============================================================================
00542 //=============================================================================
00543 SMESH::long_array* SMESH_subMesh_i::GetMeshInfo()
00544 {
00545   if ( _preMeshInfo )
00546     return _preMeshInfo->GetMeshInfo();
00547 
00548   SMESH::long_array_var aRes = new SMESH::long_array();
00549   aRes->length(SMESH::Entity_Last);
00550   for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
00551     aRes[i] = 0;
00552   
00553   // get number of nodes
00554   aRes[ SMESH::Entity_Node ] = GetNumberOfNodes(true);
00555  
00556   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
00557 
00558   // get statistic from child sub-meshes
00559   TListOfSubMeshes smList;
00560   if ( getSubMeshes( aSubMesh, smList ) )
00561     for ( TListOfSubMeshes::iterator sm = smList.begin(); sm != smList.end(); ++sm )
00562       SMESH_Mesh_i::CollectMeshInfo( (*sm)->GetElements(), aRes );
00563 
00564   return aRes._retn();
00565 }
00566 
00567 
00568 //=======================================================================
00569 //function : GetTypes
00570 //purpose  : Returns types of elements it contains
00571 //=======================================================================
00572 
00573 SMESH::array_of_ElementType* SMESH_subMesh_i::GetTypes()
00574 {
00575   if ( _preMeshInfo )
00576     return _preMeshInfo->GetTypes();
00577 
00578   SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
00579 
00580   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
00581   if ( SMESHDS_SubMesh* smDS = aSubMesh->GetSubMeshDS() )
00582   {
00583     SMDS_ElemIteratorPtr eIt = smDS->GetElements();
00584     if ( eIt->more() )
00585     {
00586       types->length( 1 );
00587       types[0] = SMESH::ElementType( eIt->next()->GetType());
00588     }
00589     else if ( smDS->GetNodes()->more() )
00590     {
00591       TopoDS_Shape shape = aSubMesh->GetSubShape();
00592       while ( !shape.IsNull() && shape.ShapeType() == TopAbs_COMPOUND )
00593       {
00594         TopoDS_Iterator it( shape );
00595         shape = it.More() ? it.Value() : TopoDS_Shape();
00596       }
00597       if ( !shape.IsNull() && shape.ShapeType() == TopAbs_VERTEX )
00598       {
00599         types->length( 1 );
00600         types[0] = SMESH::NODE;
00601       }
00602     }
00603   }
00604   return types._retn();
00605 }
00606 
00607 //=======================================================================
00608 //function : GetMesh
00609 //purpose  : interface SMESH_IDSource
00610 //=======================================================================
00611 
00612 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetMesh()
00613 {
00614   return GetFather();
00615 }
00616 
00617 //=======================================================================
00618 //function : IsMeshInfoCorrect
00619 //purpose  : * Returns false if GetMeshInfo() returns incorrect information that may
00620 //           * happen if mesh data is not yet fully loaded from the file of study.
00621 //=======================================================================
00622 
00623 bool SMESH_subMesh_i::IsMeshInfoCorrect()
00624 {
00625   return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
00626 }