]> OCCT Git - occt-copy.git/commitdiff
0031461: Mesh - Add possibility to force the meshing of the shape
authoremv <emv@opencascade.com>
Mon, 23 Mar 2020 11:52:01 +0000 (14:52 +0300)
committerbugmaster <bugmaster@opencascade.com>
Wed, 1 Apr 2020 10:36:29 +0000 (13:36 +0300)
BRepMesh: Add new mesh parameter *AllowQualityDecrease* which affects the criteria used for checking of the consistency of the existing mesh to new meshing parameters.
So if set to true it will force the meshing of the shape if current deflection strongly vary from the new one, no matter in which side.

BRepTools::Clean: Keep triangulation on non-geometric shapes (faces with no surface or edges with no curves).

12 files changed:
src/BRep/BRep_Tool.cxx
src/BRep/BRep_Tool.hxx
src/BRepMesh/BRepMesh_Deflection.cxx
src/BRepMesh/BRepMesh_Deflection.hxx
src/BRepMesh/BRepMesh_EdgeDiscret.cxx
src/BRepMesh/BRepMesh_ModelPreProcessor.cxx
src/BRepTools/BRepTools.cxx
src/BRepTools/BRepTools.hxx
src/IMeshTools/IMeshTools_Parameters.hxx
src/IMeshTools/IMeshTools_ShapeExplorer.cxx
src/MeshTest/MeshTest.cxx
tests/bugs/mesh/bug31461 [new file with mode: 0644]

index 37c4f2213ee18ff756a20b902c92976dd2c0d4dc..8fb6ef863832af77735ac77666606b8edff59bd4 100644 (file)
@@ -206,6 +206,17 @@ Handle(Geom_Curve)  BRep_Tool::Curve(const TopoDS_Edge& E,
   return C;
 }
 
+//=======================================================================
+//function : IsGeometric
+//purpose  : Returns True if <F> has a surface.
+//=======================================================================
+Standard_Boolean BRep_Tool::IsGeometric (const TopoDS_Face& F)
+{
+  const BRep_TFace* TF = static_cast<const BRep_TFace*>(F.TShape().get());
+  const Handle(Geom_Surface)& S = TF->Surface();
+  return !S.IsNull();
+}
+
 //=======================================================================
 //function : IsGeometric
 //purpose  : Returns True if <E> is a 3d curve or a curve on
index 6fdc110c06dbd14d44804217df2a0ab29038455e..e81eceab23669d59d928438e09a6d731f17817f3 100644 (file)
@@ -74,6 +74,9 @@ public:
   //! Returns the  NaturalRestriction  flag of the  face.
   Standard_EXPORT static Standard_Boolean NaturalRestriction (const TopoDS_Face& F);
   
+  //! Returns True if <F> has a surface, false otherwise.
+  Standard_EXPORT static Standard_Boolean IsGeometric (const TopoDS_Face& F);
+
   //! Returns True if <E> is a 3d curve or a curve on
   //! surface.
   Standard_EXPORT static Standard_Boolean IsGeometric (const TopoDS_Edge& E);
index 776c7235bb3fbcbd5a4834344a5fae598fc1cdda..f6e37b2b48f42d9bcd19d601d75cda8573ab41e8 100644 (file)
@@ -164,3 +164,20 @@ void BRepMesh_Deflection::ComputeDeflection (
 
   theDFace->SetDeflection (aFaceDeflection);
 }
+
+//=======================================================================
+// Function: IsConsistent
+// Purpose : 
+//=======================================================================
+Standard_Boolean BRepMesh_Deflection::IsConsistent (
+  const Standard_Real theCurrent,
+  const Standard_Real theRequired,
+  const Standard_Boolean theAllowDecrease,
+  const Standard_Real theRatio)
+{
+  // Check if the deflection of existing polygonal representation
+  // fits the required deflection.
+  Standard_Boolean isConsistent = theCurrent < (1. + theRatio) * theRequired
+         && (!theAllowDecrease || theCurrent > (1. - theRatio) * theRequired);
+  return isConsistent;
+}
index 35998a839b0467ed14eeefd4ff74e2f40458f8a7..d8c7caf472f23caa7b0f469c917b4beb6c4f1f4b 100644 (file)
@@ -58,6 +58,20 @@ public:
     const IMeshData::IFaceHandle& theDFace,
     const IMeshTools_Parameters&  theParameters);
 
+  //! Checks if the deflection of current polygonal representation
+  //! is consistent with the required deflection.
+  //! @param theCurrent [in] Current deflection.
+  //! @param theRequired [in] Required deflection.
+  //! @param theAllowDecrease [in] Flag controlling the check. If decrease is allowed,
+  //! to be consistent the current and required deflections should be approximately the same.
+  //! If not allowed, the current deflection should be less than required.
+  //! @param theRatio [in] The ratio for comparison of the deflections (value from 0 to 1).
+  Standard_EXPORT static Standard_Boolean IsConsistent (
+    const Standard_Real theCurrent,
+    const Standard_Real theRequired,
+    const Standard_Boolean theAllowDecrease,
+    const Standard_Real theRatio = 0.1);
+
   DEFINE_STANDARD_RTTI_INLINE(BRepMesh_Deflection, Standard_Transient)
 };
 
index d9e575af43b9b0faffae33733bb110b6d4f7c312..4a305440d4bdc3bbcb2047fbec2f418deeb9c52a 100644 (file)
@@ -155,8 +155,10 @@ void BRepMesh_EdgeDiscret::process (const Standard_Integer theEdgeIndex) const
       const Handle (Poly_Polygon3D)& aPoly3D = BRep_Tool::Polygon3D (aDEdge->GetEdge (), aLoc);
       if (!aPoly3D.IsNull ())
       {
-        if (aPoly3D->HasParameters () &&
-            aPoly3D->Deflection () < 1.1 * aDEdge->GetDeflection ())
+        if (aPoly3D->HasParameters() &&
+            BRepMesh_Deflection::IsConsistent (aPoly3D->Deflection(),
+                                               aDEdge->GetDeflection(),
+                                               myParameters.AllowQualityDecrease))
         {
           // Edge already has suitable 3d polygon.
           aDEdge->SetStatus(IMeshData_Reused);
@@ -209,8 +211,10 @@ Standard_Real BRepMesh_EdgeDiscret::checkExistingPolygonAndUpdateStatus(
 
   if (!aPolygon.IsNull ())
   {
-    Standard_Boolean isConsistent = aPolygon->HasParameters () &&
-      aPolygon->Deflection () < 1.1 * theDEdge->GetDeflection ();
+    Standard_Boolean isConsistent = aPolygon->HasParameters() &&
+      BRepMesh_Deflection::IsConsistent (aPolygon->Deflection(),
+                                         theDEdge->GetDeflection(),
+                                         myParameters.AllowQualityDecrease);
 
     if (!isConsistent)
     {
index c9d02d486b3df171f5a715008f3870a72e4ed630..df9d9e48d937c8597f0f2b69ce2e612192221834 100644 (file)
@@ -14,6 +14,7 @@
 // commercial license or contractual agreement.
 
 #include <BRepMesh_ModelPreProcessor.hxx>
+#include <BRepMesh_Deflection.hxx>
 #include <BRepMesh_ShapeTool.hxx>
 #include <BRep_Tool.hxx>
 #include <IMeshData_Model.hxx>
@@ -30,8 +31,10 @@ namespace
   {
   public:
     //! Constructor
-    TriangulationConsistency(const Handle(IMeshData_Model)& theModel)
+    TriangulationConsistency(const Handle(IMeshData_Model)& theModel,
+                             const Standard_Boolean theAllowQualityDecrease)
       : myModel (theModel)
+      , myAllowQualityDecrease (theAllowQualityDecrease)
     {
     }
 
@@ -51,7 +54,9 @@ namespace
       if (!aTriangulation.IsNull())
       {
         Standard_Boolean isTriangulationConsistent = 
-          aTriangulation->Deflection() < 1.1 * aDFace->GetDeflection();
+          BRepMesh_Deflection::IsConsistent (aTriangulation->Deflection(),
+                                             aDFace->GetDeflection(),
+                                             myAllowQualityDecrease);
 
         if (isTriangulationConsistent)
         {
@@ -88,6 +93,7 @@ namespace
   private:
 
     Handle(IMeshData_Model) myModel;
+    Standard_Boolean myAllowQualityDecrease; //!< Flag used for consistency check
   };
 
   //! Adds additional points to seam edges on specific surfaces.
@@ -251,8 +257,10 @@ Standard_Boolean BRepMesh_ModelPreProcessor::performInternal(
     return Standard_False;
   }
 
-  OSD_Parallel::For(0, theModel->FacesNb(), SeamEdgeAmplifier(theModel, theParameters), !theParameters.InParallel);
-  OSD_Parallel::For(0, theModel->FacesNb(), TriangulationConsistency(theModel),         !theParameters.InParallel);
+  const Standard_Integer aFacesNb    = theModel->FacesNb();
+  const Standard_Boolean isOneThread = !theParameters.InParallel;
+  OSD_Parallel::For(0, aFacesNb, SeamEdgeAmplifier        (theModel, theParameters),                      isOneThread);
+  OSD_Parallel::For(0, aFacesNb, TriangulationConsistency (theModel, theParameters.AllowQualityDecrease), isOneThread);
 
   // Clean edges and faces from outdated polygons.
   Handle(NCollection_IncAllocator) aTmpAlloc(new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE));
index 327fa12a604351a9285eddd1021c7bb49857980e..cc38b3a2e55ba9b11b66de1365815d13a12c8578 100644 (file)
@@ -760,19 +760,36 @@ Standard_Boolean BRepTools::Read(TopoDS_Shape& Sh,
 //purpose  : 
 //=======================================================================
 
-void BRepTools::Clean(const TopoDS_Shape& theShape)
+void BRepTools::Clean (const TopoDS_Shape& theShape)
 {
+  if (theShape.IsNull())
+    return;
+
   BRep_Builder aBuilder;
   Handle(Poly_Triangulation) aNullTriangulation;
   Handle(Poly_PolygonOnTriangulation) aNullPoly;
 
-  if (theShape.IsNull())
-    return;
+  TopTools_MapOfShape aShapeMap;
+  const TopLoc_Location anEmptyLoc;
 
   TopExp_Explorer aFaceIt(theShape, TopAbs_FACE);
   for (; aFaceIt.More(); aFaceIt.Next())
   {
-    const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
+    TopoDS_Shape aFaceNoLoc = aFaceIt.Value();
+    aFaceNoLoc.Location (anEmptyLoc);
+    if (!aShapeMap.Add (aFaceNoLoc))
+    {
+      // the face has already been processed
+      continue;
+    }
+
+    const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current());
+    if (!BRep_Tool::IsGeometric (aFace))
+    {
+      // Do not remove triangulation as there is no surface to recompute it.
+      continue;
+    }
+
 
     TopLoc_Location aLoc;
     const Handle(Poly_Triangulation)& aTriangulation =
@@ -782,6 +799,10 @@ void BRepTools::Clean(const TopoDS_Shape& theShape)
       continue;
 
     // Nullify edges
+    // Theoretically, the edges on the face (with surface) may have no geometry
+    // (no curve 3d or 2d or both). Such faces should be considered as invalid and
+    // are not supported by current implementation. So, both triangulation of the face
+    // and polygon on triangulation of the edges are removed unconditionally.
     TopExp_Explorer aEdgeIt(aFace, TopAbs_EDGE);
     for (; aEdgeIt.More(); aEdgeIt.Next())
     {
@@ -797,14 +818,27 @@ void BRepTools::Clean(const TopoDS_Shape& theShape)
   TopExp_Explorer aEdgeIt (theShape, TopAbs_EDGE);
   for (; aEdgeIt.More (); aEdgeIt.Next ())
   {
-    const TopoDS_Edge& aEdge = TopoDS::Edge (aEdgeIt.Current ());
+    TopoDS_Edge anEdgeNoLoc = TopoDS::Edge (aEdgeIt.Value());
+    anEdgeNoLoc.Location (anEmptyLoc);
+
+    if (!aShapeMap.Add (anEdgeNoLoc))
+    {
+      // the edge has already been processed
+      continue;
+    }
+
+    if (!BRep_Tool::IsGeometric (TopoDS::Edge (anEdgeNoLoc)))
+    {
+      // Do not remove polygon 3d as there is no curve to recompute it.
+      continue;
+    }
 
     TopLoc_Location aLoc;
-    Handle (Poly_Polygon3D) aPoly3d = BRep_Tool::Polygon3D (aEdge, aLoc);
-    if (aPoly3d.IsNull ())
+    Handle (Poly_Polygon3D) aPoly3d = BRep_Tool::Polygon3D (anEdgeNoLoc, aLoc);
+    if (aPoly3d.IsNull())
       continue;
 
-    aBuilder.UpdateEdge (aEdge, aNullPoly3d);  
+    aBuilder.UpdateEdge (anEdgeNoLoc, aNullPoly3d);
   }
 }
 //=======================================================================
index 5cfc5f725901f46da43e875c7cd1c905f48111db..1e1b916ddb60763a1e0be28670271660050b4366 100644 (file)
@@ -150,9 +150,11 @@ public:
   //! edge on the face.
   Standard_EXPORT static void UpdateFaceUVPoints (const TopoDS_Face& theF);
   
-  //! Removes all the triangulations of the faces of <S>
-  //! and removes all polygons on triangulations of the
-  //! edges.
+  //! Removes all cashed polygonal representation of the shape,
+  //! i.e. the triangulations of the faces of <S> and polygons on
+  //! triangulations and polygons 3d of the edges.
+  //! In case polygonal representation is the only available representation
+  //! for the shape (shape does not have geometry) it is not removed.
   Standard_EXPORT static void Clean (const TopoDS_Shape& S);
   
   //! Removes geometry (curves and surfaces) from all edges and faces of the shape
index c0526becdbc14c63a7545b402a238f457f21fcf8..17c35911132ce71c8c72360be30b5328ed423b3c 100644 (file)
@@ -35,7 +35,8 @@ struct IMeshTools_Parameters {
     ControlSurfaceDeflection (Standard_True),
     CleanModel (Standard_True),
     AdjustMinSize (Standard_False),
-    ForceFaceDeflection (Standard_False)
+    ForceFaceDeflection (Standard_False),
+    AllowQualityDecrease (Standard_False)
   {
   }
 
@@ -89,6 +90,10 @@ struct IMeshTools_Parameters {
   //! Enables/disables usage of shape tolerances for computing face deflection.
   //! Disabled by default.
   Standard_Boolean                                 ForceFaceDeflection;
+
+  //! Allows/forbids the decrease of the quality of the generated mesh
+  //! over the existing one.
+  Standard_Boolean                                 AllowQualityDecrease;
 };
 
 #endif
index bc690a40df17fbaf6ccff2011683415f640d6c3c..a6214ee7004ec2f1d1ab82dd69319f04c98416d2 100644 (file)
@@ -88,7 +88,6 @@ void IMeshTools_ShapeExplorer::Accept (
   BRepLib::ReverseSortFaces (GetShape (), aFaceList);
   TopTools_MapOfShape aFaceMap;
 
-  TopLoc_Location aDummyLoc;
   const TopLoc_Location aEmptyLoc;
   TopTools_ListIteratorOfListOfShape aFaceIter (aFaceList);
   for (; aFaceIter.More (); aFaceIter.Next ())
@@ -101,8 +100,7 @@ void IMeshTools_ShapeExplorer::Accept (
     }
 
     const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Value ());
-    const Handle (Geom_Surface)& aSurf = BRep_Tool::Surface (aFace, aDummyLoc);
-    if (aSurf.IsNull())
+    if (!BRep_Tool::IsGeometric (aFace))
     {
       continue;
     }
index 9882f5226630ebe217ccb55da16651a6a124e109..3624575271d13ae0a9277f626364b7177f419a7a 100644 (file)
@@ -89,7 +89,9 @@ options:\n\
                         surface (enabled by default)\n\
         -parallel       enables parallel execution (switched off by default)\n\
         -adjust_min     enables local adjustment of min size depending on edge size (switched off by default)\n\
-        -force_face_def disables usage of shape tolerances for computing face deflection (switched off by default). \n";
+        -force_face_def disables usage of shape tolerances for computing face deflection (switched off by default)\n\
+        -decrease       enforces the meshing of the shape even if current mesh satisfies the new criteria\
+                        (switched off by default).\n";
     return 0;
   }
 
@@ -126,6 +128,8 @@ options:\n\
         aMeshParams.AdjustMinSize = Standard_True;
       else if (aOpt == "-force_face_def")
         aMeshParams.ForceFaceDeflection = Standard_True;
+      else if (aOpt == "-decrease")
+        aMeshParams.AllowQualityDecrease = Standard_True;
       else if (i < nbarg)
       {
         Standard_Real aVal = Draw::Atof(argv[i++]);
diff --git a/tests/bugs/mesh/bug31461 b/tests/bugs/mesh/bug31461
new file mode 100644 (file)
index 0000000..bd1c569
--- /dev/null
@@ -0,0 +1,17 @@
+puts "======="
+puts "0031461: Mesh - Add possibility to force the meshing of the shape"
+puts "======="
+puts ""
+
+psphere s 10
+
+incmesh s 0.01
+checktrinfo s -tri 10108 -nod 5106
+
+incmesh s 0.1 -decrease
+checktrinfo s -tri 978 -nod 507
+
+tclean -geom s
+incmesh s 0.01
+tclean s
+checktrinfo s -tri 978 -nod 507