#include "OpUtil.hxx"
#include "Utils_ExceptHandlers.hxx"
+#include <BRepTools.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Iterator.hxx>
+
//=============================================================================
/*!
*
// ****
}
+//=======================================================================
+//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();
+}
+
//=============================================================================
/*!
*
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;
}
set<int> 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();
- while ( eIt->more() ) {
- const SMDS_MeshElement* anElem = eIt->next();
- SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
- while ( nIt->more() )
- nodeIds.insert( nIt->next()->GetID() );
- }
+ 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();
SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
- list<SMESHDS_SubMesh*> 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<SMESHDS_SubMesh*>::iterator sm = smList.begin();
+ TListOfSubMeshes::iterator sm = smList.begin();
for ( int i = 0; sm != smList.end(); sm++ )
{
- aSubMeshDS = *sm;
- SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements();
+ SMDS_ElemIteratorPtr anIt = (*sm)->GetElements();
for ( int n = aSubMeshDS->NbElements(); i < n && anIt->more(); i++ )
aResult[i] = anIt->next()->GetID();
}
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();
+ SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
while ( eIt->more() ) {
const SMDS_MeshElement* anElem = eIt->next();
SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
}
else
{
- smList.push_back( aSubMeshDS );
- nbElems += aSubMeshDS->NbElements();
+ nbElems += (*sm)->NbElements();
}
}
aSubMeshDS = 0;
}
if ( theElemType != SMESH::NODE ) {
- list<SMESHDS_SubMesh*>::iterator sm = smList.begin();
+ TListOfSubMeshes::iterator sm = smList.begin();
for ( i = 0; sm != smList.end(); sm++ )
{
aSubMeshDS = *sm;