Salome HOME
22797: EDF 9014 SMESH: Problem with the 3D extrusion algorithm
authoreap <eap@opencascade.com>
Fri, 31 Oct 2014 17:38:10 +0000 (20:38 +0300)
committereap <eap@opencascade.com>
Fri, 31 Oct 2014 17:38:10 +0000 (20:38 +0300)
1) pb with invalid node param on EDGEs after 2D Projection
2) pb of search of source FACEs of the prism

src/SMESH/SMESH_MesherHelper.cxx
src/SMESH/SMESH_MesherHelper.hxx
src/StdMeshers/StdMeshers_Prism_3D.cxx
src/StdMeshers/StdMeshers_Projection_2D.cxx

index 6e5b08498b8addc06a1012b8bac388092f0612c3..0d4173c28db7da996bdd311c049c1b25ca2cfdc8 100644 (file)
@@ -2804,6 +2804,28 @@ bool SMESH_MesherHelper::IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMes
     (shape.ShapeType() == TopAbs_COMPOUND && aMesh->GetMeshDS()->IsGroupOfSubShapes( shape ));
 }
 
+//=======================================================================
+//function : IsBlock
+//purpose  : 
+//=======================================================================
+
+bool SMESH_MesherHelper::IsBlock( const TopoDS_Shape& shape )
+{
+  if ( shape.IsNull() )
+    return false;
+
+  TopoDS_Shell shell;
+  TopExp_Explorer exp( shape, TopAbs_SHELL );
+  if ( !exp.More() ) return false;
+  shell = TopoDS::Shell( exp.Current() );
+  if ( exp.Next(), exp.More() ) return false;
+
+  TopoDS_Vertex v;
+  TopTools_IndexedMapOfOrientedShape map;
+  return SMESH_Block::FindBlockShapes( shell, v, v, map );
+}
+
+
 //================================================================================
 /*!
  * \brief Return maximal tolerance of shape
index 430e6f374c71ee4a384073b07500d1283e6f0bbc..ae6767d309af00cb2ae5e8752a2164660f63b944 100644 (file)
@@ -221,6 +221,8 @@ class SMESH_EXPORT SMESH_MesherHelper
 
   static bool IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMesh );
 
+  static bool IsBlock( const TopoDS_Shape& shape );
+
   static double MaxTolerance( const TopoDS_Shape& shape );
 
   static double GetAngle( const TopoDS_Edge & E1, const TopoDS_Edge & E2,
index fbc5704bd593eb2e66cc9112afab729a84c327da..62f538d84d72e927508e3add571619d4ba4d557f 100644 (file)
@@ -687,6 +687,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
 
   TopTools_MapOfShape meshedSolids;
   list< Prism_3D::TPrismTopo > meshedPrism;
+  list< TopoDS_Face > suspectSourceFaces;
   TopTools_ListIteratorOfListOfShape solidIt;
 
   while ( meshedSolids.Extent() < nbSolids )
@@ -717,6 +718,10 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
           {
             meshedFaces.push_front( prism.myTop );
           }
+          else
+          {
+            suspectSourceFaces.push_back( prism.myTop );
+          }
           meshedPrism.push_back( prism );
         }
       }
@@ -746,6 +751,10 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
               solidList.Remove( solidIt );
               continue; // already computed prism
             }
+            if ( myHelper->IsBlock( solid )) {
+              solidIt.Next();
+              continue; // too trivial
+            }
             // find a source FACE of the SOLID: it's a FACE sharing a bottom EDGE with wFace
             const TopoDS_Edge& wEdge = (*wQuad)->side[ QUAD_TOP_SIDE ].grid->Edge(0);
             PShapeIteratorPtr faceIt = myHelper->GetAncestors( wEdge, *myHelper->GetMesh(),
@@ -760,6 +769,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
                    myHelper->IsSubShape( candidateF, solid ) &&
                    !myHelper->GetMesh()->GetSubMesh( candidateF )->IsMeshComputed() &&
                    initPrism( prism, solid ) &&
+                   !myHelper->GetMesh()->GetSubMesh( prism.myTop )->IsMeshComputed() &&
                    project2dMesh( prismIt->myBottom, candidateF))
               {
                 mySetErrorToSM = true;
@@ -789,31 +799,49 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
         break; // to compute prisms with avident sources
     }
 
+    if ( meshedFaces.empty() )
+    {
+      meshedFaces.splice( meshedFaces.end(), suspectSourceFaces );
+    }
+
     // find FACEs with local 1D hyps, which has to be computed by now,
     // or at least any computed FACEs
-    for ( int iF = 1; ( meshedFaces.empty() && iF < faceToSolids.Extent() ); ++iF )
+    if ( meshedFaces.empty() )
     {
-      const TopoDS_Face&               face = TopoDS::Face( faceToSolids.FindKey( iF ));
-      const TopTools_ListOfShape& solidList = faceToSolids.FindFromKey( face );
-      if ( solidList.IsEmpty() ) continue;
-      SMESH_subMesh*                 faceSM = theMesh.GetSubMesh( face );
-      if ( !faceSM->IsEmpty() )
+      int prevNbFaces = 0;
+      for ( int iF = 1; iF <= faceToSolids.Extent(); ++iF )
       {
-        meshedFaces.push_back( face ); // lower priority
-      }
-      else
-      {
-        bool allSubMeComputed = true;
-        SMESH_subMeshIteratorPtr smIt = faceSM->getDependsOnIterator(false,true);
-        while ( smIt->more() && allSubMeComputed )
-          allSubMeComputed = smIt->next()->IsMeshComputed();
-        if ( allSubMeComputed )
+        const TopoDS_Face&               face = TopoDS::Face( faceToSolids.FindKey( iF ));
+        const TopTools_ListOfShape& solidList = faceToSolids.FindFromKey( face );
+        if ( solidList.IsEmpty() ) continue;
+        SMESH_subMesh*                 faceSM = theMesh.GetSubMesh( face );
+        if ( !faceSM->IsEmpty() )
         {
-          faceSM->ComputeStateEngine( SMESH_subMesh::COMPUTE );
-          if ( !faceSM->IsEmpty() )
-            meshedFaces.push_front( face ); // higher priority
-          else
-            faceSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+          int nbFaces = faceSM->GetSubMeshDS()->NbElements();
+          if ( prevNbFaces < nbFaces )
+          {
+            if ( !meshedFaces.empty() ) meshedFaces.pop_back();
+            meshedFaces.push_back( face ); // lower priority
+            prevNbFaces = nbFaces;
+          }
+        }
+        else
+        {
+          bool allSubMeComputed = true;
+          SMESH_subMeshIteratorPtr smIt = faceSM->getDependsOnIterator(false,true);
+          while ( smIt->more() && allSubMeComputed )
+            allSubMeComputed = smIt->next()->IsMeshComputed();
+          if ( allSubMeComputed )
+          {
+            faceSM->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+            if ( !faceSM->IsEmpty() ) {
+              meshedFaces.push_front( face ); // higher priority
+              break;
+            }
+            else {
+              faceSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+            }
+          }
         }
       }
     }
@@ -1512,6 +1540,8 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism)
         SMESH_subMesh*    topSM = mesh->GetSubMesh( topE );
         SMESH_subMesh*    srcSM = botSM;
         SMESH_subMesh*    tgtSM = topSM;
+        srcSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+        tgtSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
         if ( !srcSM->IsMeshComputed() && tgtSM->IsMeshComputed() )
           std::swap( srcSM, tgtSM );
 
@@ -1521,7 +1551,6 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism)
           srcSM->ComputeSubMeshStateEngine( SMESH_subMesh::COMPUTE ); // nodes on VERTEXes
           srcSM->ComputeStateEngine( SMESH_subMesh::COMPUTE );        // segments on the EDGE
         }
-        srcSM->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
 
         if ( tgtSM->IsMeshComputed() &&
              tgtSM->GetSubMeshDS()->NbNodes() != srcSM->GetSubMeshDS()->NbNodes() )
index 66e7834aec0cf2846de4d283b1309f30f899284c..f8dd7501666ac0edcbb18001285b135c2e1469b3 100644 (file)
@@ -706,7 +706,12 @@ namespace {
 
     if ( !tgtFace.IsPartner( srcFace ) )
     {
+      SMESH_MesherHelper edgeHelper( *tgtMesh );
+      edgeHelper.ToFixNodeParameters( true );
+      helper.ToFixNodeParameters( true );
+
       int nbOkPos = 0;
+      bool toCheck = true;
       const double tol2d = 1e-12;
       srcN_tgtN = src2tgtNodes.begin();
       for ( ; srcN_tgtN != src2tgtNodes.end(); ++srcN_tgtN )
@@ -716,11 +721,11 @@ namespace {
         {
         case SMDS_TOP_FACE:
         {
+          if ( nbOkPos < 10 ) break;
           gp_XY uv = helper.GetNodeUV( tgtFace, n ), uvBis = uv;
           if (( helper.CheckNodeUV( tgtFace, n, uv, tol )) &&
-              (( uv - uvBis ).SquareModulus() < tol2d )    &&
-              ( ++nbOkPos > 10 ))
-            return true;
+              (( uv - uvBis ).SquareModulus() < tol2d ))
+            ++nbOkPos;
           else
             nbOkPos = 0;
           break;
@@ -728,10 +733,8 @@ namespace {
         case SMDS_TOP_EDGE:
         {
           const TopoDS_Edge & tgtE = TopoDS::Edge( tgtMeshDS->IndexToShape( n->getshapeId() ));
-          double u = helper.GetNodeU( tgtE, n ), uBis = u;
-          if (( !helper.CheckNodeU( tgtE, n, u, tol )) ||
-              (( u - uBis ) < tol2d ))
-            nbOkPos = 0;
+          edgeHelper.SetSubShape( tgtE );
+          edgeHelper.GetNodeU( tgtE, n, 0, &toCheck );
           break;
         }
         default:;