X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH_I%2FSMESH_subMesh_i.cxx;h=c7b876c5c84006e594cca3f5be7f8ac069413b43;hb=31282d88869470e2076e06357535c486971a8248;hp=3ea9c4c0d629ff433d39b666a680d4f25cada6c5;hpb=e4737e85f0da6d3f90fd08f6be1c2825195fe16f;p=modules%2Fsmesh.git diff --git a/src/SMESH_I/SMESH_subMesh_i.cxx b/src/SMESH_I/SMESH_subMesh_i.cxx index 3ea9c4c0d..c7b876c5c 100644 --- a/src/SMESH_I/SMESH_subMesh_i.cxx +++ b/src/SMESH_I/SMESH_subMesh_i.cxx @@ -17,7 +17,7 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // // @@ -36,6 +36,10 @@ using namespace std; #include "OpUtil.hxx" #include "Utils_ExceptHandlers.hxx" +#include +#include +#include + //============================================================================= /*! * @@ -80,6 +84,75 @@ SMESH_subMesh_i::~SMESH_subMesh_i() // **** } +//======================================================================= +//function : getSubMeshes +//purpose : for a submesh on shape to which elements are not bound directly, +// return submeshes containing elements +//======================================================================= + +typedef list TListOfSubMeshes; + +bool getSubMeshes(::SMESH_subMesh* theSubMesh, + TListOfSubMeshes& theSubMeshList) +{ + int size = theSubMeshList.size(); + + SMESH_Mesh* aMesh = theSubMesh->GetFather(); + SMESHDS_Mesh* aMeshDS = aMesh->GetMeshDS(); + SMESHDS_SubMesh* aSubMeshDS = theSubMesh->GetSubMeshDS(); + + // nodes can be bound to either vertex, edge, face or solid_or_shell + TopoDS_Shape aShape = theSubMesh->GetSubShape(); + switch ( aShape.ShapeType() ) + { + case TopAbs_SOLID: { + // add submesh of solid itself + aSubMeshDS = aMeshDS->MeshElements( aShape ); + if ( aSubMeshDS ) + theSubMeshList.push_back( aSubMeshDS ); + // and of the first shell + TopExp_Explorer exp( aShape, TopAbs_SHELL ); + if ( exp.More() ) { + aSubMeshDS = aMeshDS->MeshElements( exp.Current() ); + if ( aSubMeshDS ) + theSubMeshList.push_back( aSubMeshDS ); + } + break; + } + case TopAbs_WIRE: + case TopAbs_COMPOUND: + case TopAbs_COMPSOLID: { + // call getSubMeshes() for sub-shapes + list shapeList; + shapeList.push_back( aShape ); + list::iterator sh = shapeList.begin(); + for ( ; sh != shapeList.end(); ++sh ) { + for ( TopoDS_Iterator it( *sh ); it.More(); it.Next() ) { + if ( ::SMESH_subMesh* aSubMesh = aMesh->GetSubMeshContaining( it.Value() )) + getSubMeshes( aSubMesh, theSubMeshList ); // add found submesh or explore deeper + else + // no submesh for a compound inside compound + shapeList.push_back( it.Value() ); + } + } + // return only unique submeshes + set smSet; + TListOfSubMeshes::iterator sm = theSubMeshList.begin(); + while ( sm != theSubMeshList.end() ) { + if ( !smSet.insert( *sm ).second ) + sm = theSubMeshList.erase( sm ); + else + ++sm; + } + break; + } + default: + if ( aSubMeshDS ) + theSubMeshList.push_back( aSubMeshDS ); + } + return size < theSubMeshList.size(); +} + //============================================================================= /*! * @@ -94,11 +167,20 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfElements() if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) return 0; - SMESHDS_SubMesh* aSubMeshDS = _mesh_i->_mapSubMesh[_localId]->GetSubMeshDS(); - if ( aSubMeshDS == NULL ) - return 0; + ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; + SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS(); + + int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0; - return aSubMeshDS->NbElements(); + // volumes are bound to shell + TListOfSubMeshes smList; + if ( nbElems == 0 && getSubMeshes( aSubMesh, smList )) + { + TListOfSubMeshes::iterator sm = smList.begin(); + for ( ; sm != smList.end(); ++sm ) + nbElems += (*sm)->NbElements(); + } + return nbElems; } //============================================================================= @@ -115,12 +197,33 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all) if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) return 0; - SMESHDS_SubMesh* aSubMeshDS = _mesh_i->_mapSubMesh[_localId]->GetSubMeshDS(); + ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; + SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS(); + + set nodeIds; + + // nodes are bound to shell instead of solid + TListOfSubMeshes smList; + if ( all && getSubMeshes( aSubMesh, smList )) + { + TListOfSubMeshes::iterator sm = smList.begin(); + for ( ; sm != smList.end(); ++sm ) + { + SMDS_ElemIteratorPtr eIt = (*sm)->GetElements(); + while ( eIt->more() ) { + const SMDS_MeshElement* anElem = eIt->next(); + SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); + while ( nIt->more() ) + nodeIds.insert( nIt->next()->GetID() ); + } + } + return nodeIds.size(); + } + if ( aSubMeshDS == NULL ) return 0; if ( all ) { // all nodes of submesh elements - set nodeIds; SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements(); while ( eIt->more() ) { const SMDS_MeshElement* anElem = eIt->next(); @@ -150,15 +253,33 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsId() if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) return aResult._retn(); - SMESHDS_SubMesh* aSubMeshDS = _mesh_i->_mapSubMesh[_localId]->GetSubMeshDS(); - if ( aSubMeshDS == NULL ) - return aResult._retn(); + ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; + SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS(); + + int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0; + TListOfSubMeshes smList; + if ( nbElems ) + smList.push_back( aSubMeshDS ); - aResult->length( aSubMeshDS->NbElements() ); - SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements(); - for ( int i = 0, n = aSubMeshDS->NbElements(); i < n && anIt->more(); i++ ) - aResult[i] = anIt->next()->GetID(); + // volumes are bound to shell + if ( nbElems == 0 && getSubMeshes( aSubMesh, smList )) + { + TListOfSubMeshes::iterator sm = smList.begin(); + for ( ; sm != smList.end(); ++sm ) + nbElems += (*sm)->NbElements(); + } + aResult->length( nbElems ); + if ( nbElems ) + { + TListOfSubMeshes::iterator sm = smList.begin(); + for ( int i = 0; sm != smList.end(); sm++ ) + { + SMDS_ElemIteratorPtr anIt = (*sm)->GetElements(); + for ( ; i < nbElems && anIt->more(); i++ ) + aResult[i] = anIt->next()->GetID(); + } + } return aResult._retn(); } @@ -179,19 +300,45 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theEle if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) return aResult._retn(); - SMESHDS_SubMesh* aSubMeshDS = _mesh_i->_mapSubMesh[_localId]->GetSubMeshDS(); - if ( aSubMeshDS == NULL ) - return aResult._retn(); - - // No sense in returning ids of elements along with ids of nodes: - // when theElemType == SMESH::ALL, return node ids only if - // there are no elements - bool retNodes = (theElemType == SMESH::NODE || - (theElemType == SMESH::ALL && aSubMeshDS->NbElements() == 0)); + ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; + SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS(); // PAL5440, return all nodes belonging to elements of submesh set nodeIds; - if ( retNodes ) { + int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0; + + // volumes may be bound to shell instead of solid + TListOfSubMeshes smList; + if ( nbElems == 0 && getSubMeshes( aSubMesh, smList )) + { + TListOfSubMeshes::iterator sm = smList.begin(); + for ( ; sm != smList.end(); ++sm ) + { + if ( theElemType == SMESH::NODE ) + { + SMDS_ElemIteratorPtr eIt = (*sm)->GetElements(); + while ( eIt->more() ) { + const SMDS_MeshElement* anElem = eIt->next(); + SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); + while ( nIt->more() ) + nodeIds.insert( nIt->next()->GetID() ); + } + } + else + { + nbElems += (*sm)->NbElements(); + } + } + aSubMeshDS = 0; + } + else + { + if ( nbElems ) + smList.push_back( aSubMeshDS ); + } + + if ( theElemType == SMESH::NODE && aSubMeshDS ) + { SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements(); while ( eIt->more() ) { const SMDS_MeshElement* anElem = eIt->next(); @@ -200,28 +347,31 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theEle nodeIds.insert( nIt->next()->GetID() ); } } - - if ( theElemType == SMESH::ALL ) - aResult->length( aSubMeshDS->NbElements() + nodeIds.size()); - else if ( theElemType == SMESH::NODE ) + + if ( theElemType == SMESH::NODE ) aResult->length( nodeIds.size() ); else - aResult->length( aSubMeshDS->NbElements() ); + aResult->length( nbElems ); int i = 0, n = aResult->length(); - if ( retNodes && !nodeIds.empty() ) { + if ( theElemType == SMESH::NODE && !nodeIds.empty() ) { set::iterator idIt = nodeIds.begin(); for ( ; i < n && idIt != nodeIds.end() ; i++, idIt++ ) aResult[i] = *idIt; } - if ( theElemType == SMESH::ALL || theElemType != SMESH::NODE ) { - SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements(); - while ( i < n && anIt->more() ) { - const SMDS_MeshElement* anElem = anIt->next(); - if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType ) - aResult[i++] = anElem->GetID(); + if ( theElemType != SMESH::NODE ) { + TListOfSubMeshes::iterator sm = smList.begin(); + for ( i = 0; sm != smList.end(); sm++ ) + { + aSubMeshDS = *sm; + SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements(); + while ( i < n && anIt->more() ) { + const SMDS_MeshElement* anElem = anIt->next(); + if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType ) + aResult[i++] = anElem->GetID(); + } } } @@ -241,20 +391,7 @@ SMESH::long_array* SMESH_subMesh_i::GetNodesId() { Unexpect aCatch(SALOME_SalomeException); MESSAGE("SMESH_subMesh_i::GetNodesId"); - SMESH::long_array_var aResult = new SMESH::long_array(); - - if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() ) - return aResult._retn(); - - SMESHDS_SubMesh* aSubMeshDS = _mesh_i->_mapSubMesh[_localId]->GetSubMeshDS(); - if ( aSubMeshDS == NULL ) - return aResult._retn(); - - aResult->length( aSubMeshDS->NbNodes() ); - SMDS_NodeIteratorPtr anIt = aSubMeshDS->GetNodes(); - for ( int i = 0, n = aSubMeshDS->NbNodes(); i < n && anIt->more(); i++ ) - aResult[i] = anIt->next()->GetID(); - + SMESH::long_array_var aResult = GetElementsByType( SMESH::NODE ); return aResult._retn(); } @@ -339,3 +476,14 @@ SMESH::long_array* SMESH_subMesh_i::GetIDs() SMESH::long_array_var aResult = GetElementsId(); return aResult._retn(); } + +//============================================================================= +/*! + * + */ +//============================================================================= +SMESH::ElementType SMESH_subMesh_i::GetElementType( const CORBA::Long id, const bool iselem ) + throw (SALOME::SALOME_Exception) +{ + return GetFather()->GetElementType( id, iselem ); +}