Salome HOME
Fix MA construction
[modules/smesh.git] / src / StdMeshers / StdMeshers_Prism_3D.cxx
index a955169341023ef2813eeee95b71d7d35de854a2..6e58555e1828b93af54789620d6b29eb236fe3ab 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015  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
@@ -49,6 +49,7 @@
 #include <Bnd_B3d.hxx>
 #include <Geom2dAdaptor_Curve.hxx>
 #include <Geom2d_Line.hxx>
+#include <GeomLib_IsPlanarSurface.hxx>
 #include <Geom_Curve.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
@@ -904,7 +905,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
       return error( err );
     }
   }
-  return true;
+  return error( COMPERR_OK );
 }
 
 //================================================================================
@@ -1319,7 +1320,17 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism)
   // clear data
   myBotToColumnMap.clear();
   myBlock.Clear();
-        
+
+  // update state of sub-meshes (mostly in order to erase improper errors)
+  SMESH_subMesh* sm = myHelper->GetMesh()->GetSubMesh( thePrism.myShape3D );
+  SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/false);
+  while ( smIt->more() )
+  {
+    sm = smIt->next();
+    sm->GetComputeError().reset();
+    sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+  }
+
   return true;
 }
 
@@ -2214,11 +2225,11 @@ bool StdMeshers_Prism_3D::projectBottomToTop( const gp_Trsf &             bottom
     case 3: {
       newFace = myHelper->AddFace(nodes[0], nodes[1], nodes[2]);
       break;
-      }
+    }
     case 4: {
       newFace = myHelper->AddFace( nodes[0], nodes[1], nodes[2], nodes[3] );
       break;
-      }
+    }
     default:
       newFace = meshDS->AddPolygonalFace( nodes );
     }
@@ -2226,7 +2237,42 @@ bool StdMeshers_Prism_3D::projectBottomToTop( const gp_Trsf &             bottom
       meshDS->SetMeshElementOnShape( newFace, topFaceID );
   }
 
-  myHelper->SetElementsOnShape( oldSetElemsOnShape );  
+  myHelper->SetElementsOnShape( oldSetElemsOnShape );
+
+  // Check the projected mesh
+
+  if ( thePrism.myNbEdgesInWires.size() > 1 && // there are holes
+       topHelper.IsDistorted2D( topSM, /*checkUV=*/false ))
+  {
+    SMESH_MeshEditor editor( topHelper.GetMesh() );
+
+    // smooth in 2D or 3D?
+    TopLoc_Location loc;
+    Handle(Geom_Surface) surface = BRep_Tool::Surface( topFace, loc );
+    bool isPlanar = GeomLib_IsPlanarSurface( surface ).IsPlanar();
+
+    bool isFixed = false;
+    set<const SMDS_MeshNode*> fixedNodes;
+    for ( int iAttemp = 0; !isFixed && iAttemp < 10; ++iAttemp )
+    {
+      TIDSortedElemSet faces;
+      for ( faceIt = topSMDS->GetElements(); faceIt->more(); )
+        faces.insert( faces.end(), faceIt->next() );
+
+      SMESH_MeshEditor::SmoothMethod algo =
+        iAttemp ? SMESH_MeshEditor::CENTROIDAL : SMESH_MeshEditor::LAPLACIAN;
+
+      // smoothing
+      editor.Smooth( faces, fixedNodes, algo, /*nbIterations=*/ 10,
+                     /*theTgtAspectRatio=*/1.0, /*the2D=*/!isPlanar);
+
+      isFixed = !topHelper.IsDistorted2D( topSM, /*checkUV=*/true );
+    }
+    if ( !isFixed )
+      return toSM( error( TCom("Projection from face #") << botSM->GetId()
+                          << " to face #" << topSM->GetId()
+                          << " failed: inverted elements created"));
+  }
 
   return true;
 }
@@ -2317,7 +2363,7 @@ bool StdMeshers_Prism_3D::isSimpleBottom( const Prism_3D::TPrismTopo& thePrism )
   TopoDS_Vertex commonV;
   const list< TopoDS_Edge >& botEdges = thePrism.myBottomEdges;
   list< TopoDS_Edge >::const_iterator edge = botEdges.begin();
-  for ( ; edge != botEdges.end(); ++edge )
+  while ( edge != botEdges.end() )
   {
     if ( SMESH_Algo::isDegenerated( *edge ))
       return false;
@@ -2503,7 +2549,7 @@ namespace // utils used by StdMeshers_Prism_3D::IsApplicable()
       for ( iE = 0; iE < *nbE; ++e, ++iE )
         if ( SMESH_Algo::isDegenerated( *e ))
         {
-          ee.erase( e );
+          e = --ee.erase( e );
           --(*nbE);
           --iE;
         }