Salome HOME
#19982 EDF 21954 - Compute mesh fails
[modules/smesh.git] / src / StdMeshers / StdMeshers_ViscousLayers.cxx
index d82b30bcc699899820034b6e1370c17dca4049c5..310b164d5add0f235547b13ddf6c5fed30941035 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2019  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2020  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -917,7 +917,7 @@ namespace VISCOUS_3D
 
   private:
 
-    bool findSolidsWithLayers();
+    bool findSolidsWithLayers(const bool checkFaceMesh=true);
     bool setBefore( _SolidData& solidBefore, _SolidData& solidAfter );
     bool findFacesWithLayers(const bool onlyWith=false);
     void findPeriodicFaces();
@@ -2040,7 +2040,7 @@ SMESH_ComputeErrorPtr _ViscousBuilder::CheckHypotheses( SMESH_Mesh&         mesh
     return SMESH_ComputeErrorPtr(); // everything already computed
 
 
-  findSolidsWithLayers();
+  findSolidsWithLayers( /*checkFaceMesh=*/false );
   bool ok = findFacesWithLayers( true );
 
   // remove _MeshOfSolid's of _SolidData's
@@ -2059,7 +2059,7 @@ SMESH_ComputeErrorPtr _ViscousBuilder::CheckHypotheses( SMESH_Mesh&         mesh
  */
 //================================================================================
 
-bool _ViscousBuilder::findSolidsWithLayers()
+bool _ViscousBuilder::findSolidsWithLayers(const bool checkFaceMesh)
 {
   // get all solids
   TopTools_IndexedMapOfShape allSolids;
@@ -2069,13 +2069,28 @@ bool _ViscousBuilder::findSolidsWithLayers()
   SMESH_HypoFilter filter;
   for ( int i = 1; i <= allSolids.Extent(); ++i )
   {
-    // find StdMeshers_ViscousLayers hyp assigned to the i-th solid
     SMESH_subMesh* sm = _mesh->GetSubMesh( allSolids(i) );
     if ( sm->GetSubMeshDS() && sm->GetSubMeshDS()->NbElements() > 0 )
       continue; // solid is already meshed
+    // TODO: check if algo is hidden
     SMESH_Algo* algo = sm->GetAlgo();
     if ( !algo ) continue;
-    // TODO: check if algo is hidden
+    // check if all FACEs are meshed, which can be false if Compute() a sub-shape
+    if ( checkFaceMesh )
+    {
+      bool facesMeshed = true;
+      SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(false,true);
+      while ( smIt->more() && facesMeshed )
+      {
+        SMESH_subMesh * faceSM = smIt->next();
+        if ( faceSM->GetSubShape().ShapeType() != TopAbs_FACE )
+          break;
+        facesMeshed = faceSM->IsMeshComputed();
+      }
+      if ( !facesMeshed )
+        continue;
+    }
+    // find StdMeshers_ViscousLayers hyp assigned to the i-th solid
     const list <const SMESHDS_Hypothesis *> & allHyps =
       algo->GetUsedHypothesis(*_mesh, allSolids(i), /*ignoreAuxiliary=*/false);
     _SolidData* soData = 0;
@@ -3304,12 +3319,22 @@ bool _ViscousBuilder::findShapesToSmooth( _SolidData& data )
           if ( isC1 )
           {
             double maxEdgeLen = 3 * Min( eov._edges[0]->_maxLen, eov._hyp.GetTotalThickness() );
-            double eLen1 = SMESH_Algo::EdgeLength( TopoDS::Edge( dirOfEdges[i].first->_shape ));
-            double eLen2 = SMESH_Algo::EdgeLength( TopoDS::Edge( dirOfEdges[j].first->_shape ));
-            if ( eLen1 < maxEdgeLen ) eov._eosC1.push_back( dirOfEdges[i].first );
-            if ( eLen2 < maxEdgeLen ) eov._eosC1.push_back( dirOfEdges[j].first );
-            dirOfEdges[i].first = 0;
-            dirOfEdges[j].first = 0;
+            for ( int isJ = 0; isJ < 2; ++isJ ) // loop on [i,j]
+            {
+              size_t k = isJ ? j : i;
+              const TopoDS_Edge& e = TopoDS::Edge( dirOfEdges[k].first->_shape );
+              double eLen = SMESH_Algo::EdgeLength( e );
+              if ( eLen < maxEdgeLen )
+              {
+                TopoDS_Shape oppV = SMESH_MesherHelper::IthVertex( 0, e );
+                if ( oppV.IsSame( V ))
+                  oppV = SMESH_MesherHelper::IthVertex( 1, e );
+                _EdgesOnShape* eovOpp = data.GetShapeEdges( oppV );
+                if ( dirOfEdges[k].second * eovOpp->_edges[0]->_normal < 0 )
+                  eov._eosC1.push_back( dirOfEdges[k].first );
+              }
+              dirOfEdges[k].first = 0;
+            }
           }
         }
   } // fill _eosC1 of VERTEXes