bug 9352. correct getting mesh elements from COMPOUND, COMPSOLID, SOLID, SHELL and WIRE submeshes

This commit is contained in:
eap 2005-06-30 05:54:20 +00:00
parent d4cdc63f90
commit c981fa08d9

View File

@ -36,6 +36,10 @@ using namespace std;
#include "OpUtil.hxx" #include "OpUtil.hxx"
#include "Utils_ExceptHandlers.hxx" #include "Utils_ExceptHandlers.hxx"
#include <BRepTools.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Iterator.hxx>
//============================================================================= //=============================================================================
/*! /*!
* *
@ -80,6 +84,73 @@ 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<SMESHDS_SubMesh*> 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<TopoDS_Shape> shapeList;
shapeList.push_back( aShape );
list<TopoDS_Shape>::iterator sh = shapeList.begin();
for ( ; sh != shapeList.end(); ++sh ) {
for ( TopoDS_Iterator it( *sh ); it.More(); it.Next() ) {
::SMESH_subMesh* aSubMesh = aMesh->GetSubMeshContaining( it.Value() );
if ( aSubMesh )
getSubMeshes( aSubMesh, theSubMeshList );
else
// no submesh for a compound inside compound
shapeList.push_back( it.Value() );
}
}
// return only unique submeshes
set<SMESHDS_SubMesh*> smSet;
TListOfSubMeshes::iterator sm = theSubMeshList.begin();
while ( sm != theSubMeshList.end() ) {
if ( !smSet.insert( *sm ).second )
sm = theSubMeshList.erase( sm );
else
++sm;
}
break;
}
}
return size < theSubMeshList.size();
}
//============================================================================= //=============================================================================
/*! /*!
* *
@ -100,16 +171,12 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfElements()
int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0; int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
// volumes are bound to shell // 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(); TListOfSubMeshes::iterator sm = smList.begin();
TopExp_Explorer exp( aSubMesh->GetSubShape(), TopAbs_SHELL ); for ( ; sm != smList.end(); ++sm )
for ( ; exp.More(); exp.Next() ) nbElems += (*sm)->NbElements();
{
aSubMeshDS = aMeshDS->MeshElements( exp.Current() );
if ( aSubMeshDS )
nbElems += aSubMeshDS->NbElements();
}
} }
return nbElems; return nbElems;
} }
@ -133,16 +200,14 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
set<int> nodeIds; set<int> nodeIds;
// node are bound to shell instead of solid // nodes are bound to shell instead of solid
if ( all && aSubMesh->GetSubShape().ShapeType() <= TopAbs_SOLID ) TListOfSubMeshes smList;
if ( all && getSubMeshes( aSubMesh, smList ))
{ {
SMESHDS_Mesh* aMeshDS = aSubMesh->GetFather()->GetMeshDS(); TListOfSubMeshes::iterator sm = smList.begin();
TopExp_Explorer exp( aSubMesh->GetSubShape(), TopAbs_SHELL ); for ( ; sm != smList.end(); ++sm )
for ( ; exp.More(); exp.Next() )
{ {
aSubMeshDS = aMeshDS->MeshElements( exp.Current() ); SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
if ( aSubMeshDS ) {
SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
while ( eIt->more() ) { while ( eIt->more() ) {
const SMDS_MeshElement* anElem = eIt->next(); const SMDS_MeshElement* anElem = eIt->next();
SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
@ -150,7 +215,6 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
nodeIds.insert( nIt->next()->GetID() ); nodeIds.insert( nIt->next()->GetID() );
} }
} }
}
return nodeIds.size(); return nodeIds.size();
} }
@ -191,33 +255,25 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsId()
SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS(); SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0; int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
list<SMESHDS_SubMesh*> smList; TListOfSubMeshes smList;
if ( nbElems ) if ( nbElems )
smList.push_back( aSubMeshDS ); smList.push_back( aSubMeshDS );
// volumes are bound to shell // 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(); TListOfSubMeshes::iterator sm = smList.begin();
TopExp_Explorer exp( aSubMesh->GetSubShape(), TopAbs_SHELL ); for ( ; sm != smList.end(); ++sm )
for ( ; exp.More(); exp.Next() ) nbElems += (*sm)->NbElements();
{
aSubMeshDS = aMeshDS->MeshElements( exp.Current() );
if ( aSubMeshDS ) {
smList.push_back( aSubMeshDS );
nbElems += aSubMeshDS->NbElements();
}
}
} }
aResult->length( nbElems );
if ( nbElems ) if ( nbElems )
{ {
aResult->length( nbElems ); TListOfSubMeshes::iterator sm = smList.begin();
list<SMESHDS_SubMesh*>::iterator sm = smList.begin();
for ( int i = 0; sm != smList.end(); sm++ ) for ( int i = 0; sm != smList.end(); sm++ )
{ {
aSubMeshDS = *sm; SMDS_ElemIteratorPtr anIt = (*sm)->GetElements();
SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements();
for ( int n = aSubMeshDS->NbElements(); i < n && anIt->more(); i++ ) for ( int n = aSubMeshDS->NbElements(); i < n && anIt->more(); i++ )
aResult[i] = anIt->next()->GetID(); aResult[i] = anIt->next()->GetID();
} }
@ -250,18 +306,15 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theEle
int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0; int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
// volumes may be bound to shell instead of solid // volumes may be bound to shell instead of solid
list< SMESHDS_SubMesh* > smList; TListOfSubMeshes smList;
if ( nbElems == 0 && aSubMesh->GetSubShape().ShapeType() <= TopAbs_SOLID ) if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
{ {
SMESHDS_Mesh* aMeshDS = aSubMesh->GetFather()->GetMeshDS(); TListOfSubMeshes::iterator sm = smList.begin();
TopExp_Explorer exp( aSubMesh->GetSubShape(), TopAbs_SHELL ); for ( ; sm != smList.end(); ++sm )
for ( ; exp.More(); exp.Next() )
{ {
aSubMeshDS = aMeshDS->MeshElements( exp.Current() );
if ( !aSubMeshDS ) continue;
if ( theElemType == SMESH::NODE ) if ( theElemType == SMESH::NODE )
{ {
SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements(); SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
while ( eIt->more() ) { while ( eIt->more() ) {
const SMDS_MeshElement* anElem = eIt->next(); const SMDS_MeshElement* anElem = eIt->next();
SMDS_ElemIteratorPtr nIt = anElem->nodesIterator(); SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
@ -271,8 +324,7 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theEle
} }
else else
{ {
smList.push_back( aSubMeshDS ); nbElems += (*sm)->NbElements();
nbElems += aSubMeshDS->NbElements();
} }
} }
aSubMeshDS = 0; aSubMeshDS = 0;
@ -308,7 +360,7 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theEle
} }
if ( theElemType != SMESH::NODE ) { if ( theElemType != SMESH::NODE ) {
list<SMESHDS_SubMesh*>::iterator sm = smList.begin(); TListOfSubMeshes::iterator sm = smList.begin();
for ( i = 0; sm != smList.end(); sm++ ) for ( i = 0; sm != smList.end(); sm++ )
{ {
aSubMeshDS = *sm; aSubMeshDS = *sm;