1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-19 13:40:49 +03:00

0026664: Triangulating a very small polygon fails

Parameter for adaptive computation of minimal 2D meshing precision added
This commit is contained in:
pdn
2015-09-08 18:26:16 +03:00
committed by msv
parent b6922dd7b0
commit 3898bfaad6
7 changed files with 84 additions and 3 deletions

View File

@@ -18,6 +18,12 @@
#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);
}
//=======================================================================

View 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;

View 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();

View 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

View 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);
}

View 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;

View 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: ";