]> OCCT Git - occt-copy.git/commitdiff
0026664: Triangulating a very small polygon fails
authorpdn <pdn@opencascade.com>
Tue, 8 Sep 2015 15:26:16 +0000 (18:26 +0300)
committermsv <msv@opencascade.com>
Fri, 22 Apr 2016 12:26:32 +0000 (15:26 +0300)
Parameter for adaptive computation of minimal 2D meshing precision added

src/BRepMesh/BRepMesh_FaceAttribute.cxx
src/BRepMesh/BRepMesh_FaceAttribute.hxx
src/BRepMesh/BRepMesh_FastDiscret.cxx
src/BRepMesh/BRepMesh_FastDiscret.hxx
src/BRepMesh/BRepMesh_IncrementalMesh.cxx
src/BRepMesh/BRepMesh_IncrementalMesh.hxx
src/MeshTest/MeshTest.cxx

index 43e5dceb1d6b5b0c1643dd129d5e3b4ecc7989da..8d1c19cbe4529adf8b2155d75762f7465b59ea77 100644 (file)
 #include <BRepMesh_ShapeTool.hxx>
 #include <BRepMesh_Classifier.hxx>
 #include <BRepTools.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <BRep_Tool.hxx>
 
 IMPLEMENT_STANDARD_HANDLE (BRepMesh_FaceAttribute, Standard_Transient)
 IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_FaceAttribute, Standard_Transient)
@@ -34,6 +40,8 @@ BRepMesh_FaceAttribute::BRepMesh_FaceAttribute()
     myVMax            (0.),
     myDeltaX          (1.),
     myDeltaY          (1.),
+    myMinStep         (-1.),
+    myAdaptiveMin     (Standard_False),
     myStatus          (BRepMesh_NoError)
 {
   init();
@@ -54,6 +62,8 @@ BRepMesh_FaceAttribute::BRepMesh_FaceAttribute(
     myVMax            (0.),
     myDeltaX          (1.),
     myDeltaY          (1.),
+    myMinStep         (-1.),
+    myAdaptiveMin     (Standard_False),
     myStatus          (BRepMesh_NoError),
     myBoundaryVertices(theBoundaryVertices),
     myBoundaryPoints  (theBoundaryPoints),
@@ -88,6 +98,30 @@ void BRepMesh_FaceAttribute::init()
   myFace.Orientation(TopAbs_FORWARD);
   BRepTools::UVBounds(myFace, myUMin, myUMax, myVMin, myVMax);
 
+  if(myAdaptiveMin) {
+    // compute minimal UV distance
+    // between vertices
+
+    myMinStep = RealLast();
+    for(TopExp_Explorer anExp(myFace, TopAbs_WIRE);anExp.More();anExp.Next()) {
+      TopoDS_Wire aWire = TopoDS::Wire(anExp.Current());
+
+      for (TopoDS_Iterator aWireExp(aWire);aWireExp.More();aWireExp.Next()) {
+        TopoDS_Edge anEdge = TopoDS::Edge(aWireExp.Value());
+        if(BRep_Tool::IsClosed(anEdge))
+          continue;
+
+        // Get end points on 2d curve
+        gp_Pnt2d aFirst2d, aLast2d;
+        BRep_Tool::UVPoints(anEdge, myFace, aFirst2d,aLast2d);
+        Standard_Real aDist =aFirst2d.Distance(aLast2d);
+        if(aDist < myMinStep)
+          myMinStep = aDist;
+      }
+    }
+  }
+
+
   BRepAdaptor_Surface aSurfAdaptor(myFace, Standard_False);
   mySurface = new BRepAdaptor_HSurface(aSurfAdaptor);
 }
@@ -113,7 +147,11 @@ Standard_Real BRepMesh_FaceAttribute::computeParametricTolerance(
   const Standard_Real theLastParam) const
 {
   const Standard_Real aDeflectionUV = 1.e-05;
-  return Max(Precision::PConfusion(), (theLastParam - theFirstParam) * aDeflectionUV);
+  Standard_Real aPreci = (theLastParam - theFirstParam) * aDeflectionUV;
+  if(myAdaptiveMin && myMinStep < aPreci)
+    aPreci = myMinStep;
+
+  return Max(Precision::PConfusion(), aPreci);
 }
 
 //=======================================================================
index 6f3efe904fac33eed55e2b5e740cc1cbb7589c1e..70678841b182c16a99e1c222334738ddba2fde6f 100644 (file)
@@ -84,6 +84,15 @@ public: //! @name main geometrical properties.
   
   //! Returns V tolerance of face calculated regarding its parameters.
   Standard_EXPORT Standard_Real ToleranceV() const;
+
+  //! Returns modifiable adaptive parametric tolerance flag.
+  //! If this flag is set to true the minimal parametric tolerance
+  //! is computed taking minimal parametric distance between vertices
+  //! into account
+  inline Standard_Boolean& AdaptiveParametricTolerance()
+  {
+    return myAdaptiveMin;
+  }
   
   //! Gives face deflection parameter.
   inline Standard_Real GetDefFace() const
@@ -361,7 +370,9 @@ private:
   Standard_Real                           myVMax;          //!< Describes maximal value in V domain
   Standard_Real                           myDeltaX;
   Standard_Real                           myDeltaY;
+  Standard_Real                           myMinStep;
   Standard_Integer                        myStatus;
+  Standard_Boolean                        myAdaptiveMin;
 
   BRepMesh::HDMapOfVertexInteger          myBoundaryVertices;
   BRepMesh::HDMapOfIntegerPnt             myBoundaryPoints;
index 8ca846bb19b05f9ffc6208ef76bae9220dd6007c..a2f4eda19e63587d26633b932c0836a7692f8082 100644 (file)
@@ -101,6 +101,7 @@ BRepMesh_FastDiscret::BRepMesh_FastDiscret(
   myRelative (theRelative),
   myShapetrigu (theShapetrigu), 
   myInshape (theInshape),
+  myAdaptiveMin(Standard_False),
   myBoundaryVertices(new BRepMesh::DMapOfVertexInteger),
   myBoundaryPoints(new BRepMesh::DMapOfIntegerPnt),
   myMinSize(theMinSize),
@@ -135,6 +136,7 @@ BRepMesh_FastDiscret::BRepMesh_FastDiscret(
   myRelative (theRelative),
   myShapetrigu (theShapetrigu),
   myInshape (theInshape),
+  myAdaptiveMin(Standard_False),
   myBoundaryVertices(new BRepMesh::DMapOfVertexInteger),
   myBoundaryPoints(new BRepMesh::DMapOfIntegerPnt),
   myMinSize(theMinSize),
@@ -249,6 +251,7 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace)
 
       myAttributes.Bind(theFace, myAttribute);
     }
+    myAttribute->AdaptiveParametricTolerance() = myAdaptiveMin;
 
     BRepMesh::HIMapOfInteger&            aVertexEdgeMap = myAttribute->ChangeVertexEdgeMap();
     BRepMesh::HDMapOfShapePairOfPolygon& aInternalEdges = myAttribute->ChangeInternalEdges();
index a515b69909385f58a37326b8d1dc150ae20f90f0..6161b0b3c389fb08338abd142b73ac91aadb4a0a 100644 (file)
@@ -115,6 +115,15 @@ public:
     Process(face);
   }
   
+  //! Returns modifiable adaptive parametric tolerance flag.
+  //! If this flag is set to true the minimal parametric tolerance
+  //! is computed taking minimal parametric distance between vertices
+  //! into account
+  inline Standard_Boolean& AdaptiveParametricTolerance()
+  {
+    return myAdaptiveMin;
+  }
+
   //! Request algorithm to launch in multiple threads <br>
   //! to improve performance (should be supported by plugin). <br>
   inline void SetParallel(const Standard_Boolean theInParallel)
@@ -362,6 +371,7 @@ private:
   Standard_Boolean                                 myRelative;
   Standard_Boolean                                 myShapetrigu;
   Standard_Boolean                                 myInshape;
+  Standard_Boolean                                 myAdaptiveMin;
   TopTools_DataMapOfShapeReal                      myMapdefle;
 
   // Data shared for whole shape
index 8593287562e3e419eb04bcbea748f0842a8e010b..3604884ea729da18f66ebe14532c3f22335c679c 100644 (file)
@@ -70,6 +70,7 @@ IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_IncrementalMesh, BRepMesh_DiscretRoot)
 BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh()
 : myRelative  (Standard_False),
   myInParallel(Standard_False),
+  myAdaptiveMin(Standard_False),
   myMinSize   (Precision::Confusion()),
   myInternalVerticesMode(Standard_True),
   myIsControlSurfaceDeflection(Standard_True)
@@ -88,6 +89,7 @@ BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh(
   const Standard_Boolean isInParallel)
   : myRelative  (isRelative),
     myInParallel(isInParallel),
+    myAdaptiveMin(Standard_False),
     myMinSize   (Precision::Confusion()),
     myInternalVerticesMode(Standard_True),
     myIsControlSurfaceDeflection(Standard_True)
@@ -149,6 +151,8 @@ void BRepMesh_IncrementalMesh::init()
     myRelative, Standard_True, myInParallel, myMinSize,
     myInternalVerticesMode, myIsControlSurfaceDeflection);
 
+  myMesh->AdaptiveParametricTolerance() = myAdaptiveMin;
+
   myMesh->InitSharedFaces(myShape);
 }
 
index 1169a0c37859f651651cdcef1e32cb8ea5774c10..0ab189078459c104830ffeac9d535db2f02cce34 100644 (file)
@@ -78,7 +78,16 @@ public: //! @name accessing to parameters.
   {
     return myRelative;
   }
-  
+
+  //! Returns modifiable adaptive parametric tolerance flag.
+  //! If this flag is set to true the minimal parametric tolerance
+  //! is computed taking minimal parametric distance between vertices
+  //! into account
+  inline Standard_Boolean& AdaptiveParametricTolerance()
+  {
+    return myAdaptiveMin;
+  }
+
   //! Returns modified flag.
   inline Standard_Boolean IsModified() const
   {
@@ -227,6 +236,7 @@ protected:
   BRepMesh::DMapOfEdgeListOfTriangulationBool myEdges;
   Handle(BRepMesh_FastDiscret)                myMesh;
   Standard_Boolean                            myModified;
+  Standard_Boolean                            myAdaptiveMin;
   TopTools_DataMapOfShapeReal                 myEdgeDeflection;
   Standard_Real                               myMaxShapeSize;
   Standard_Integer                            myStatus;
index 103ffc6988fc224d7299bb5403f68af41635371a..b72a683020a9043d8ac3f33dfcdf1f7a16879b11 100644 (file)
@@ -139,7 +139,8 @@ options:\n\
                         (enabled by default)\n\
         -surf_def_off   disables control of deflection of mesh from real\n\
                         surface (enabled by default)\n\
-        -parallel       enables parallel execution (switched off by default)\n";
+        -parallel       enables parallel execution (switched off by default)\n\
+        -adaptive       enables adaptive computation of minimal value in parametric space\n";
     return 0;
   }
 
@@ -157,6 +158,7 @@ options:\n\
   Standard_Boolean isInParallel    = Standard_False;
   Standard_Boolean isIntVertices   = Standard_True;
   Standard_Boolean isControlSurDef = Standard_True;
+  Standard_Boolean isAdaptiveMin   = Standard_False;
 
   if (nbarg > 3)
   {
@@ -176,6 +178,8 @@ options:\n\
         isIntVertices = Standard_False;
       else if (aOpt == "-surf_def_off")
         isControlSurDef = Standard_False;
+      else if (aOpt == "-adaptive")
+        isAdaptiveMin   = Standard_True;
       else if (i < nbarg)
       {
         Standard_Real aVal = Draw::Atof(argv[i++]);
@@ -201,6 +205,7 @@ options:\n\
   aMesher.SetMinSize   (aMinSize);
   aMesher.SetInternalVerticesMode(isIntVertices);
   aMesher.SetControlSurfaceDeflection(isControlSurDef);
+  aMesher.AdaptiveParametricTolerance() = isAdaptiveMin;
   aMesher.Perform();
 
   di << "Meshing statuses: ";