X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH_I%2FSMESH_subMesh_i.cxx;h=f90cb300a536a2729e311d12c34e06dd89955bbc;hp=50d689eb3e131c42f4d20d83d1d59d96ed2bd65e;hb=127d2277c6a516d0e9fadd77b4ef0b0c6286cf17;hpb=658c72bc1dca06562a157a35c087fdbb2b9751cd diff --git a/src/SMESH_I/SMESH_subMesh_i.cxx b/src/SMESH_I/SMESH_subMesh_i.cxx index 50d689eb3..f90cb300a 100644 --- a/src/SMESH_I/SMESH_subMesh_i.cxx +++ b/src/SMESH_I/SMESH_subMesh_i.cxx @@ -1,32 +1,30 @@ -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// 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 +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // +// You should have received a copy of the GNU Lesser General Public +// 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.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_subMesh_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH // $Header$ - -using namespace std; +// #include "SMESH_subMesh_i.hxx" #include "SMESH_Gen_i.hxx" #include "SMESH_Mesh_i.hxx" @@ -36,6 +34,11 @@ using namespace std; #include "OpUtil.hxx" #include "Utils_ExceptHandlers.hxx" +#include +#include + +using namespace std; + //============================================================================= /*! * @@ -65,7 +68,6 @@ SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA, _gen_i = gen_i; _mesh_i = mesh_i; _localId = localId; - thePOA->activate_object( this ); // **** } //============================================================================= @@ -80,6 +82,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(); +} + //============================================================================= /*! * @@ -100,16 +171,12 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfElements() int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0; // volumes are bound to shell - if ( nbElems == 0 && aSubMesh->GetSubShape().ShapeType() <= TopAbs_SOLID ) + TListOfSubMeshes smList; + if ( nbElems == 0 && getSubMeshes( aSubMesh, smList )) { - SMESHDS_Mesh* aMeshDS = aSubMesh->GetFather()->GetMeshDS(); - TopExp_Explorer exp( aSubMesh->GetSubShape(), TopAbs_SHELL ); - for ( ; exp.More(); exp.Next() ) - { - aSubMeshDS = aMeshDS->MeshElements( exp.Current() ); - if ( aSubMeshDS ) - nbElems += aSubMeshDS->NbElements(); - } + TListOfSubMeshes::iterator sm = smList.begin(); + for ( ; sm != smList.end(); ++sm ) + nbElems += (*sm)->NbElements(); } return nbElems; } @@ -133,23 +200,26 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all) set nodeIds; - // node are bound to shell instead of solid - if ( all && aSubMesh->GetSubShape().ShapeType() <= TopAbs_SOLID ) + // nodes are bound to shell instead of solid + TListOfSubMeshes smList; + if ( all && getSubMeshes( aSubMesh, smList )) { - SMESHDS_Mesh* aMeshDS = aSubMesh->GetFather()->GetMeshDS(); - TopExp_Explorer exp( aSubMesh->GetSubShape(), TopAbs_SHELL ); - for ( ; exp.More(); exp.Next() ) + TListOfSubMeshes::iterator sm = smList.begin(); + for ( ; sm != smList.end(); ++sm ) { - aSubMeshDS = aMeshDS->MeshElements( exp.Current() ); - if ( aSubMeshDS ) { - SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements(); + SMDS_ElemIteratorPtr eIt = (*sm)->GetElements(); + if ( eIt->more() ) { while ( eIt->more() ) { const SMDS_MeshElement* anElem = eIt->next(); SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); while ( nIt->more() ) nodeIds.insert( nIt->next()->GetID() ); } - } + } else { + SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes(); + while ( nIt->more() ) + nodeIds.insert( nIt->next()->GetID() ); + } } return nodeIds.size(); } @@ -159,15 +229,21 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all) if ( all ) { // all nodes of submesh elements SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements(); - while ( eIt->more() ) { - const SMDS_MeshElement* anElem = eIt->next(); - SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); + if ( eIt->more() ) { + while ( eIt->more() ) { + const SMDS_MeshElement* anElem = eIt->next(); + SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); + while ( nIt->more() ) + nodeIds.insert( nIt->next()->GetID() ); + } + } else { + SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes(); while ( nIt->more() ) nodeIds.insert( nIt->next()->GetID() ); } return nodeIds.size(); } - + return aSubMeshDS->NbNodes(); } @@ -176,7 +252,7 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all) * */ //============================================================================= - + SMESH::long_array* SMESH_subMesh_i::GetElementsId() throw (SALOME::SALOME_Exception) { @@ -191,34 +267,26 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsId() SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS(); int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0; - list smList; + TListOfSubMeshes smList; if ( nbElems ) smList.push_back( aSubMeshDS ); // volumes are bound to shell - if ( nbElems == 0 && aSubMesh->GetSubShape().ShapeType() <= TopAbs_SOLID ) + if ( nbElems == 0 && getSubMeshes( aSubMesh, smList )) { - SMESHDS_Mesh* aMeshDS = aSubMesh->GetFather()->GetMeshDS(); - TopExp_Explorer exp( aSubMesh->GetSubShape(), TopAbs_SHELL ); - for ( ; exp.More(); exp.Next() ) - { - aSubMeshDS = aMeshDS->MeshElements( exp.Current() ); - if ( aSubMeshDS ) { - smList.push_back( aSubMeshDS ); - nbElems += aSubMeshDS->NbElements(); - } - } + TListOfSubMeshes::iterator sm = smList.begin(); + for ( ; sm != smList.end(); ++sm ) + nbElems += (*sm)->NbElements(); } + aResult->length( nbElems ); if ( nbElems ) { - aResult->length( nbElems ); - list::iterator sm = smList.begin(); + TListOfSubMeshes::iterator sm = smList.begin(); for ( int i = 0; sm != smList.end(); sm++ ) { - aSubMeshDS = *sm; - SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements(); - for ( int n = aSubMeshDS->NbElements(); i < n && anIt->more(); i++ ) + SMDS_ElemIteratorPtr anIt = (*sm)->GetElements(); + for ( ; i < nbElems && anIt->more(); i++ ) aResult[i] = anIt->next()->GetID(); } } @@ -250,29 +318,31 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theEle int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0; // volumes may be bound to shell instead of solid - list< SMESHDS_SubMesh* > smList; - if ( nbElems == 0 && aSubMesh->GetSubShape().ShapeType() <= TopAbs_SOLID ) + TListOfSubMeshes smList; + if ( nbElems == 0 && getSubMeshes( aSubMesh, smList )) { - SMESHDS_Mesh* aMeshDS = aSubMesh->GetFather()->GetMeshDS(); - TopExp_Explorer exp( aSubMesh->GetSubShape(), TopAbs_SHELL ); - for ( ; exp.More(); exp.Next() ) + TListOfSubMeshes::iterator sm = smList.begin(); + for ( ; sm != smList.end(); ++sm ) { - aSubMeshDS = aMeshDS->MeshElements( exp.Current() ); - if ( !aSubMeshDS ) continue; if ( theElemType == SMESH::NODE ) { - SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements(); - while ( eIt->more() ) { - const SMDS_MeshElement* anElem = eIt->next(); - SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); + SMDS_ElemIteratorPtr eIt = (*sm)->GetElements(); + if ( eIt->more() ) { + while ( eIt->more() ) { + const SMDS_MeshElement* anElem = eIt->next(); + SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); + while ( nIt->more() ) + nodeIds.insert( nIt->next()->GetID() ); + } + } else { + SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes(); while ( nIt->more() ) nodeIds.insert( nIt->next()->GetID() ); } } else { - smList.push_back( aSubMeshDS ); - nbElems += aSubMeshDS->NbElements(); + nbElems += (*sm)->NbElements(); } } aSubMeshDS = 0; @@ -286,9 +356,15 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theEle if ( theElemType == SMESH::NODE && aSubMeshDS ) { SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements(); - while ( eIt->more() ) { - const SMDS_MeshElement* anElem = eIt->next(); - SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); + if ( eIt->more() ) { + while ( eIt->more() ) { + const SMDS_MeshElement* anElem = eIt->next(); + SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); + while ( nIt->more() ) + nodeIds.insert( nIt->next()->GetID() ); + } + } else { + SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes(); while ( nIt->more() ) nodeIds.insert( nIt->next()->GetID() ); } @@ -308,7 +384,7 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theEle } if ( theElemType != SMESH::NODE ) { - list::iterator sm = smList.begin(); + TListOfSubMeshes::iterator sm = smList.begin(); for ( i = 0; sm != smList.end(); sm++ ) { aSubMeshDS = *sm; @@ -380,8 +456,14 @@ GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape() try { if ( _mesh_i->_mapSubMesh.find( _localId ) != _mesh_i->_mapSubMesh.end()) { TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape(); - if ( !S.IsNull() ) + if ( !S.IsNull() ) { aShapeObj = _gen_i->ShapeToGeomObject( S ); + //mzn: N7PAL16232, N7PAL16233 + //In some cases it's possible that GEOM_Client contains the shape same to S, but + //with another orientation. + if (aShapeObj->_is_nil()) + aShapeObj = _gen_i->ShapeToGeomObject( S.Reversed() ); + } } } catch(SALOME_Exception & S_ex) { @@ -422,3 +504,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 ); +}