From: pdn Date: Tue, 8 Sep 2015 15:26:16 +0000 (+0300) Subject: 0026664: Triangulating a very small polygon fails X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=3898bfaad66c430980c2ef93e2b1e6323943fe1b;p=occt-copy.git 0026664: Triangulating a very small polygon fails Parameter for adaptive computation of minimal 2D meshing precision added --- diff --git a/src/BRepMesh/BRepMesh_FaceAttribute.cxx b/src/BRepMesh/BRepMesh_FaceAttribute.cxx index 43e5dceb1d..8d1c19cbe4 100644 --- a/src/BRepMesh/BRepMesh_FaceAttribute.cxx +++ b/src/BRepMesh/BRepMesh_FaceAttribute.cxx @@ -18,6 +18,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include 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); } //======================================================================= diff --git a/src/BRepMesh/BRepMesh_FaceAttribute.hxx b/src/BRepMesh/BRepMesh_FaceAttribute.hxx index 6f3efe904f..70678841b1 100644 --- a/src/BRepMesh/BRepMesh_FaceAttribute.hxx +++ b/src/BRepMesh/BRepMesh_FaceAttribute.hxx @@ -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; diff --git a/src/BRepMesh/BRepMesh_FastDiscret.cxx b/src/BRepMesh/BRepMesh_FastDiscret.cxx index 8ca846bb19..a2f4eda19e 100644 --- a/src/BRepMesh/BRepMesh_FastDiscret.cxx +++ b/src/BRepMesh/BRepMesh_FastDiscret.cxx @@ -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(); diff --git a/src/BRepMesh/BRepMesh_FastDiscret.hxx b/src/BRepMesh/BRepMesh_FastDiscret.hxx index a515b69909..6161b0b3c3 100644 --- a/src/BRepMesh/BRepMesh_FastDiscret.hxx +++ b/src/BRepMesh/BRepMesh_FastDiscret.hxx @@ -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
//! to improve performance (should be supported by plugin).
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 diff --git a/src/BRepMesh/BRepMesh_IncrementalMesh.cxx b/src/BRepMesh/BRepMesh_IncrementalMesh.cxx index 7777764eee..02d2332c78 100644 --- a/src/BRepMesh/BRepMesh_IncrementalMesh.cxx +++ b/src/BRepMesh/BRepMesh_IncrementalMesh.cxx @@ -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); } diff --git a/src/BRepMesh/BRepMesh_IncrementalMesh.hxx b/src/BRepMesh/BRepMesh_IncrementalMesh.hxx index 1169a0c378..0ab1890784 100644 --- a/src/BRepMesh/BRepMesh_IncrementalMesh.hxx +++ b/src/BRepMesh/BRepMesh_IncrementalMesh.hxx @@ -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; diff --git a/src/MeshTest/MeshTest.cxx b/src/MeshTest/MeshTest.cxx index 103ffc6988..b72a683020 100644 --- a/src/MeshTest/MeshTest.cxx +++ b/src/MeshTest/MeshTest.cxx @@ -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: ";