Salome HOME
Fix bug 10390. fix getting submesh for a shell
[modules/smesh.git] / src / SMESH / SMESH_Pattern.cxx
index fb9b5afc17fb107d97f16f3725b3adfc2df84d55..493799d3551c53b0f4a02aa8338318eb5c75391c 100644 (file)
@@ -46,6 +46,7 @@
 #include <TopoDS_Shell.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <TopoDS_Wire.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <gp_Ax2.hxx>
 #include <gp_Lin2d.hxx>
 #include <gp_Pnt2d.hxx>
@@ -2839,7 +2840,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*         theMesh,
   MESSAGE(" ::Load(volume) " );
   Clear();
   myIs2D = false;
-  SMESHDS_Mesh * aMeshDS = theMesh->GetMeshDS();
+  SMESHDS_SubMesh * aSubMesh;
 
   // load shapes in myShapeIDMap
   SMESH_Block block;
@@ -2852,7 +2853,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*         theMesh,
   for ( shapeID = 1; shapeID <= myShapeIDMap.Extent(); shapeID++ )
   {
     const TopoDS_Shape& S = myShapeIDMap( shapeID );
-    SMESHDS_SubMesh * aSubMesh = aMeshDS->MeshElements( S );
+    aSubMesh = getSubmeshWithElements( theMesh, S );
     if ( aSubMesh )
       nbNodes += aSubMesh->NbNodes();
   }
@@ -2865,7 +2866,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*         theMesh,
   {
     const TopoDS_Shape& S = myShapeIDMap( shapeID );
     list< TPoint* > & shapePoints = getShapePoints( shapeID );
-    SMESHDS_SubMesh * aSubMesh = aMeshDS->MeshElements( S );
+    aSubMesh = getSubmeshWithElements( theMesh, S );
     if ( ! aSubMesh ) continue;
     SMDS_NodeIteratorPtr nIt = aSubMesh->GetNodes();
     if ( !nIt->more() ) continue;
@@ -2929,7 +2930,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*         theMesh,
 
   // load elements
 
-  SMESHDS_SubMesh * aSubMesh = aMeshDS->MeshElements( theBlock );
+  aSubMesh = getSubmeshWithElements( theMesh, theBlock );
   if ( aSubMesh )
   {
     SMDS_ElemIteratorPtr elemIt = aSubMesh->GetElements();
@@ -2947,6 +2948,32 @@ bool SMESH_Pattern::Load (SMESH_Mesh*         theMesh,
   return setErrorCode( ERR_OK );
 }
 
+//=======================================================================
+//function : getSubmeshWithElements
+//purpose  : return submesh containing elements bound to theBlock in theMesh
+//=======================================================================
+
+SMESHDS_SubMesh * SMESH_Pattern::getSubmeshWithElements(SMESH_Mesh*         theMesh,
+                                                        const TopoDS_Shape& theShape)
+{
+  SMESHDS_SubMesh * aSubMesh = theMesh->GetMeshDS()->MeshElements( theShape );
+  if ( aSubMesh && ( aSubMesh->GetElements()->more() || aSubMesh->GetNodes()->more() ))
+    return aSubMesh;
+
+  if ( theShape.ShapeType() == TopAbs_SHELL )
+  {
+    // look for submesh of VOLUME
+    TopTools_ListIteratorOfListOfShape it( theMesh->GetAncestors( theShape ));
+    for (; it.More(); it.Next()) {
+      aSubMesh = theMesh->GetMeshDS()->MeshElements( it.Value() );
+      if ( aSubMesh && ( aSubMesh->GetElements()->more() || aSubMesh->GetNodes()->more() ))
+        return aSubMesh;
+    }
+  }
+  return 0;
+}
+
+
 //=======================================================================
 //function : Apply
 //purpose  : Compute nodes coordinates applying
@@ -3466,6 +3493,35 @@ bool SMESH_Pattern::
   return makePoly;
 }
 
+//=======================================================================
+//function : clearMesh
+//purpose  : clear mesh elements existing on myShape in theMesh
+//=======================================================================
+
+void SMESH_Pattern::clearMesh(SMESH_Mesh* theMesh) const
+{
+
+  if ( !myShape.IsNull() )
+  {
+    if ( SMESH_subMesh * aSubMesh = theMesh->GetSubMesh/*Containing*/( myShape ))
+    {
+      aSubMesh->ComputeStateEngine( SMESH_subMesh::CLEANDEP );
+    }
+    else {
+      SMESHDS_Mesh* aMeshDS = theMesh->GetMeshDS();
+      if ( SMESHDS_SubMesh* aSubMeshDS = aMeshDS->MeshElements( myShape ))
+      {
+        SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
+        while ( eIt->more() )
+          aMeshDS->RemoveElement( eIt->next() );
+        SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes();
+        while ( nIt->more() )
+          aMeshDS->RemoveNode( static_cast<const SMDS_MeshNode*>( nIt->next() ));
+      }
+    }
+  }
+}
+
 //=======================================================================
 //function : MakeMesh
 //purpose  : Create nodes and elements in <theMesh> using nodes
@@ -3485,26 +3541,12 @@ bool SMESH_Pattern::MakeMesh(SMESH_Mesh* theMesh,
   SMESHDS_Mesh* aMeshDS = theMesh->GetMeshDS();
 
   // clear elements and nodes existing on myShape
-
-  if ( !myShape.IsNull() )
-  {
-    SMESH_subMesh * aSubMesh = theMesh->GetSubMeshContaining( myShape );
-    SMESHDS_SubMesh * aSubMeshDS = aMeshDS->MeshElements( myShape );
-    if ( aSubMesh )
-      aSubMesh->ComputeStateEngine( SMESH_subMesh::CLEAN );
-    else if ( aSubMeshDS )
-    {
-      SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
-      while ( eIt->more() )
-        aMeshDS->RemoveElement( eIt->next() );
-      SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes();
-      while ( nIt->more() )
-        aMeshDS->RemoveNode( static_cast<const SMDS_MeshNode*>( nIt->next() ));
-    }
-  }
+  clearMesh(theMesh);
 
   bool onMeshElements = ( !myElements.empty() );
 
+  // Create missing nodes
+
   vector< const SMDS_MeshNode* > nodesVector; // i-th point/xyz -> node
   if ( onMeshElements )
   {