Version: 6.3.1

src/SMESH_I/SMESH_subMesh_i.cxx

Go to the documentation of this file.
00001 // Copyright (C) 2007-2011  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 //  $Header: /home/server/cvs/SMESH/SMESH_SRC/src/SMESH_I/SMESH_subMesh_i.cxx,v 1.14.2.3.6.2.6.2 2011-06-22 12:47:00 eap Exp $
00028 //
00029 #include "SMESH_subMesh_i.hxx"
00030 #include "SMESH_Gen_i.hxx"
00031 #include "SMESH_Mesh_i.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   MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i");
00069   _gen_i = gen_i;
00070   _mesh_i = mesh_i;
00071   _localId = localId;
00072   // ****
00073 }
00074 //=============================================================================
00078 //=============================================================================
00079 
00080 SMESH_subMesh_i::~SMESH_subMesh_i()
00081 {
00082   MESSAGE("SMESH_subMesh_i::~SMESH_subMesh_i");
00083   // ****
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   MESSAGE("SMESH_subMesh_i::GetNumberOfElements");
00166   if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
00167     return 0;
00168 
00169   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
00170   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
00171 
00172   int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
00173 
00174   // volumes are bound to shell
00175   TListOfSubMeshes smList;
00176   if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
00177   {
00178     TListOfSubMeshes::iterator sm = smList.begin();
00179     for ( ; sm != smList.end(); ++sm )
00180       nbElems += (*sm)->NbElements();
00181   }
00182   return nbElems;
00183 }
00184 
00185 //=============================================================================
00189 //=============================================================================
00190 
00191 CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
00192   throw (SALOME::SALOME_Exception)
00193 {
00194   Unexpect aCatch(SALOME_SalomeException);
00195   MESSAGE("SMESH_subMesh_i::GetNumberOfNodes");
00196   if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
00197     return 0;
00198 
00199   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
00200   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
00201 
00202   set<int> nodeIds;
00203 
00204   // nodes are bound to shell instead of solid
00205   TListOfSubMeshes smList;
00206   if ( all && getSubMeshes( aSubMesh, smList ))
00207   {
00208     TListOfSubMeshes::iterator sm = smList.begin();
00209     for ( ; sm != smList.end(); ++sm )
00210     {
00211       SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
00212       if ( eIt->more() ) {
00213         while ( eIt->more() ) {
00214           const SMDS_MeshElement* anElem = eIt->next();
00215           SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
00216           while ( nIt->more() )
00217             nodeIds.insert( nIt->next()->GetID() );
00218         }
00219       } else {
00220         SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
00221         while ( nIt->more() )
00222           nodeIds.insert( nIt->next()->GetID() );
00223       }      
00224     }
00225     return nodeIds.size();
00226   }
00227 
00228   if ( aSubMeshDS == NULL )
00229     return 0;
00230 
00231   if ( all ) { // all nodes of submesh elements
00232     SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
00233     if ( eIt->more() ) {
00234       while ( eIt->more() ) {
00235         const SMDS_MeshElement* anElem = eIt->next();
00236         SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
00237         while ( nIt->more() )
00238           nodeIds.insert( nIt->next()->GetID() );
00239       }
00240     } else {
00241       SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes();
00242       while ( nIt->more() )
00243         nodeIds.insert( nIt->next()->GetID() );
00244     }
00245     return nodeIds.size();
00246   }
00247 
00248   return aSubMeshDS->NbNodes();
00249 }
00250 
00251 //=============================================================================
00255 //=============================================================================
00256 
00257 SMESH::long_array* SMESH_subMesh_i::GetElementsId()
00258   throw (SALOME::SALOME_Exception)
00259 {
00260   Unexpect aCatch(SALOME_SalomeException);
00261   MESSAGE("SMESH_subMesh_i::GetElementsId");
00262   SMESH::long_array_var aResult = new SMESH::long_array();
00263 
00264   if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
00265     return aResult._retn();
00266 
00267   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
00268   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
00269 
00270   int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
00271   TListOfSubMeshes smList;
00272   if ( nbElems )
00273     smList.push_back( aSubMeshDS );
00274 
00275   // volumes are bound to shell
00276   if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
00277   {
00278     TListOfSubMeshes::iterator sm = smList.begin();
00279     for ( ; sm != smList.end(); ++sm )
00280       nbElems += (*sm)->NbElements();
00281   }
00282 
00283   aResult->length( nbElems );
00284   if ( nbElems )
00285   {
00286     TListOfSubMeshes::iterator sm = smList.begin();
00287     for ( int i = 0; sm != smList.end(); sm++ )
00288     {
00289       SMDS_ElemIteratorPtr anIt = (*sm)->GetElements();
00290       for ( ; i < nbElems && anIt->more(); i++ )
00291         aResult[i] = anIt->next()->GetID();
00292     }
00293   }
00294   return aResult._retn();
00295 }
00296 
00297 
00298 //=============================================================================
00302 //=============================================================================
00303 
00304 SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theElemType )
00305     throw (SALOME::SALOME_Exception)
00306 {
00307   Unexpect aCatch(SALOME_SalomeException);
00308   MESSAGE("SMESH_subMesh_i::GetElementsByType");
00309   SMESH::long_array_var aResult = new SMESH::long_array();
00310 
00311   if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
00312     return aResult._retn();
00313 
00314   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
00315   SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
00316 
00317   // PAL5440, return all nodes belonging to elements of submesh
00318   set<int> nodeIds;
00319   int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
00320 
00321   // volumes may be bound to shell instead of solid
00322   TListOfSubMeshes smList;
00323   if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
00324   {
00325     TListOfSubMeshes::iterator sm = smList.begin();
00326     for ( ; sm != smList.end(); ++sm )
00327     {
00328       if ( theElemType == SMESH::NODE )
00329       {
00330         SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
00331         if ( eIt->more() ) {
00332           while ( eIt->more() ) {
00333             const SMDS_MeshElement* anElem = eIt->next();
00334             SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
00335             while ( nIt->more() )
00336               nodeIds.insert( nIt->next()->GetID() );
00337           }
00338         } else {
00339           SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
00340           while ( nIt->more() )
00341             nodeIds.insert( nIt->next()->GetID() );
00342         }
00343       }
00344       else
00345       {
00346         nbElems += (*sm)->NbElements();
00347       }
00348     }
00349     aSubMeshDS = 0;
00350   }
00351   else
00352   {
00353     if ( nbElems )
00354       smList.push_back( aSubMeshDS );
00355   }
00356 
00357   if ( theElemType == SMESH::NODE && aSubMeshDS )
00358   {
00359     SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
00360     if ( eIt->more() ) {
00361       while ( eIt->more() ) {
00362         const SMDS_MeshElement* anElem = eIt->next();
00363         SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
00364         while ( nIt->more() )
00365           nodeIds.insert( nIt->next()->GetID() );
00366       }
00367     } else {
00368       SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes();
00369       while ( nIt->more() )
00370         nodeIds.insert( nIt->next()->GetID() );
00371     }
00372   }
00373 
00374   if ( theElemType == SMESH::NODE )
00375     aResult->length( nodeIds.size() );
00376   else
00377     aResult->length( nbElems );
00378 
00379   int i = 0, n = aResult->length();
00380 
00381   if ( theElemType == SMESH::NODE && !nodeIds.empty() ) {
00382     set<int>::iterator idIt = nodeIds.begin();
00383     for ( ; i < n && idIt != nodeIds.end() ; i++, idIt++ )
00384       aResult[i] = *idIt;
00385   }
00386 
00387   if ( theElemType != SMESH::NODE ) {
00388     TListOfSubMeshes::iterator sm = smList.begin();
00389     for ( i = 0; sm != smList.end(); sm++ )
00390     {
00391       aSubMeshDS = *sm;
00392       SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements();
00393       while ( i < n && anIt->more() ) {
00394         const SMDS_MeshElement* anElem = anIt->next();
00395         if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
00396           aResult[i++] = anElem->GetID();
00397       }
00398     }
00399   }
00400 
00401   aResult->length( i );
00402 
00403   return aResult._retn();
00404 }
00405 
00406 //=============================================================================
00410 //=============================================================================
00411   
00412 SMESH::long_array* SMESH_subMesh_i::GetNodesId()
00413   throw (SALOME::SALOME_Exception)
00414 {
00415   Unexpect aCatch(SALOME_SalomeException);
00416   MESSAGE("SMESH_subMesh_i::GetNodesId");
00417   SMESH::long_array_var aResult = GetElementsByType( SMESH::NODE );
00418   return aResult._retn();
00419 }
00420 
00421 //=============================================================================
00425 //=============================================================================
00426   
00427 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather()
00428   throw (SALOME::SALOME_Exception)
00429 {
00430   Unexpect aCatch(SALOME_SalomeException);
00431   MESSAGE("SMESH_subMesh_i::GetFather");
00432   return _mesh_i->_this();
00433 }
00434 
00435 //=============================================================================
00439 //=============================================================================
00440   
00441 CORBA::Long SMESH_subMesh_i::GetId()
00442 {
00443   MESSAGE("SMESH_subMesh_i::GetId");
00444   return _localId;
00445 }
00446 
00447 //=======================================================================
00448 //function : GetSubShape
00449 //purpose  : 
00450 //=======================================================================
00451 
00452 GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape()
00453      throw (SALOME::SALOME_Exception)
00454 {
00455   Unexpect aCatch(SALOME_SalomeException);
00456   GEOM::GEOM_Object_var aShapeObj;
00457   try {
00458     if ( _mesh_i->_mapSubMesh.find( _localId ) != _mesh_i->_mapSubMesh.end()) {
00459       TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape();
00460       if ( !S.IsNull() ) {
00461         aShapeObj = _gen_i->ShapeToGeomObject( S );
00462         //mzn: N7PAL16232, N7PAL16233
00463         //In some cases it's possible that GEOM_Client contains the shape same to S, but
00464         //with another orientation.
00465         if (aShapeObj->_is_nil())
00466           aShapeObj = _gen_i->ShapeToGeomObject( S.Reversed() );
00467       }
00468     }
00469   }
00470   catch(SALOME_Exception & S_ex) {
00471     THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
00472   }
00473   return aShapeObj._retn();
00474 }
00475 
00476 //=============================================================================
00480 //=============================================================================
00481 SALOME_MED::FAMILY_ptr SMESH_subMesh_i::GetFamily()
00482   throw (SALOME::SALOME_Exception)
00483 {
00484   Unexpect aCatch(SALOME_SalomeException);
00485   SALOME_MED::MESH_var MEDMesh = GetFather()->GetMEDMesh();
00486 
00487   SALOME_MED::Family_array_var families = 
00488     MEDMesh->getFamilies(SALOME_MED::MED_NODE);
00489     
00490   for ( int i = 0; i < families->length(); i++ ) {
00491     if ( families[i]->getIdentifier() == ( _localId ) )
00492       return families[i];
00493   }
00494   
00495   return SALOME_MED::FAMILY::_nil();
00496 }
00497 
00498 //=============================================================================
00502 //=============================================================================
00503 SMESH::long_array* SMESH_subMesh_i::GetIDs()
00504 {
00505   SMESH::long_array_var aResult = GetElementsId();
00506   return aResult._retn();
00507 }
00508 
00509 //=============================================================================
00513 //=============================================================================
00514 SMESH::ElementType SMESH_subMesh_i::GetElementType( const CORBA::Long id, const bool iselem )
00515   throw (SALOME::SALOME_Exception)
00516 {
00517   return GetFather()->GetElementType( id, iselem );
00518 }
00519 
00520 
00521 //=============================================================================
00527 //=============================================================================
00528 SMESH::long_array* SMESH_subMesh_i::GetMeshInfo()
00529 {
00530   SMESH::long_array_var aRes = new SMESH::long_array();
00531   aRes->length(SMESH::Entity_Last);
00532   for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
00533     aRes[i] = 0;
00534   
00535   // get number of nodes
00536   aRes[ SMESH::Entity_Node ] = GetNumberOfNodes(true);
00537  
00538   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
00539 
00540   // get statistic from child sub-meshes
00541   TListOfSubMeshes smList;
00542   if ( getSubMeshes( aSubMesh, smList ) )
00543     for ( TListOfSubMeshes::iterator sm = smList.begin(); sm != smList.end(); ++sm )
00544       SMESH_Mesh_i::CollectMeshInfo( (*sm)->GetElements(), aRes );
00545 
00546   return aRes._retn();
00547 }
00548 
00549 
00550 //=======================================================================
00551 //function : GetTypes
00552 //purpose  : Returns types of elements it contains
00553 //=======================================================================
00554 
00555 SMESH::array_of_ElementType* SMESH_subMesh_i::GetTypes()
00556 {
00557   SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
00558 
00559   ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
00560   if ( SMESHDS_SubMesh* smDS = aSubMesh->GetSubMeshDS() )
00561   {
00562     SMDS_ElemIteratorPtr eIt = smDS->GetElements();
00563     if ( eIt->more() )
00564     {
00565       types->length( 1 );
00566       types[0] = SMESH::ElementType( eIt->next()->GetType());
00567     }
00568     else if ( smDS->GetNodes()->more() )
00569     {
00570       TopoDS_Shape shape = aSubMesh->GetSubShape();
00571       while ( !shape.IsNull() && shape.ShapeType() == TopAbs_COMPOUND )
00572       {
00573         TopoDS_Iterator it( shape );
00574         shape = it.More() ? it.Value() : TopoDS_Shape();
00575       }
00576       if ( !shape.IsNull() && shape.ShapeType() == TopAbs_VERTEX )
00577       {
00578         types->length( 1 );
00579         types[0] = SMESH::NODE;
00580       }
00581     }
00582   }
00583   return types._retn();
00584 }
00585 
00586 //=======================================================================
00587 //function : GetMesh
00588 //purpose  : interface SMESH_IDSource
00589 //=======================================================================
00590 
00591 SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetMesh()
00592 {
00593   return GetFather();
00594 }
Copyright © 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS