1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

Compare commits

...

2 Commits

Author SHA1 Message Date
oan
924b30b508 0031395: Mesh - BRepMesh produces poor mesh on shape with hidden self-intersections
Add parameter UseVertexTolerance to curve tessellator;
Use UseVertexTolerance in case if model healer has failed 5 times at row;
Do not treat 2d loops that fit in 3d tolerance as OK cases.
2022-12-27 15:25:50 +03:00
oan
8ffccd9067 0031395: Mesh - BRepMesh produces poor mesh on shape with hidden self-intersections
Take vertex tolerance into account to avoid excessive points leading to self-intersections in discrete model
2022-12-27 14:25:59 +03:00
7 changed files with 67 additions and 20 deletions

View File

@@ -36,9 +36,11 @@ IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_CurveTessellator, IMeshTools_CurveTessellato
BRepMesh_CurveTessellator::BRepMesh_CurveTessellator(
const IMeshData::IEdgeHandle& theEdge,
const IMeshTools_Parameters& theParameters,
const Standard_Integer theMinPointsNb)
const Standard_Integer theMinPointsNb,
const Standard_Boolean isUseVertexTolerance)
: myDEdge(theEdge),
myParameters(theParameters),
myUseVertexTolerance(isUseVertexTolerance),
myEdge(theEdge->GetEdge()),
myCurve(myEdge),
myMinPointsNb (theMinPointsNb)
@@ -55,9 +57,11 @@ BRepMesh_CurveTessellator::BRepMesh_CurveTessellator (
const TopAbs_Orientation theOrientation,
const IMeshData::IFaceHandle& theFace,
const IMeshTools_Parameters& theParameters,
const Standard_Integer theMinPointsNb)
const Standard_Integer theMinPointsNb,
const Standard_Boolean isUseVertexTolerance)
: myDEdge(theEdge),
myParameters(theParameters),
myUseVertexTolerance(isUseVertexTolerance),
myEdge(TopoDS::Edge(theEdge->GetEdge().Oriented(theOrientation))),
myCurve(myEdge, theFace->GetFace()),
myMinPointsNb (theMinPointsNb)
@@ -225,10 +229,15 @@ Standard_Boolean BRepMesh_CurveTessellator::isInToleranceOfVertex (
const gp_Pnt& thePoint,
const TopoDS_Vertex& theVertex) const
{
const gp_Pnt aPoint = BRep_Tool::Pnt(theVertex);
const Standard_Real aTolerance = BRep_Tool::Tolerance(theVertex);
if (myUseVertexTolerance)
{
const gp_Pnt aPoint = BRep_Tool::Pnt(theVertex);
const Standard_Real aTolerance = BRep_Tool::Tolerance(theVertex) * 1.1;
return (thePoint.SquareDistance (aPoint) < aTolerance * aTolerance);
return (thePoint.SquareDistance (aPoint) < aTolerance * aTolerance);
}
return Standard_False;
}
//=======================================================================
@@ -243,9 +252,9 @@ Standard_Boolean BRepMesh_CurveTessellator::Value (
thePoint = myDiscretTool.Value (theIndex);
theParameter = myDiscretTool.Parameter (theIndex);
/*if (!isInToleranceOfVertex(thePoint, myFirstVertex) &&
if (!isInToleranceOfVertex(thePoint, myFirstVertex) &&
!isInToleranceOfVertex(thePoint, myLastVertex))
{*/
{
if (!myCurve.IsCurveOnSurface())
{
return Standard_True;
@@ -281,9 +290,9 @@ Standard_Boolean BRepMesh_CurveTessellator::Value (
aSurface->D0(aUV.X(), aUV.Y(), aPntOnSurf);
return (thePoint.SquareDistance(aPntOnSurf) < myEdgeSqTol);
/*}
}
return Standard_False;*/
return Standard_False;
}
//=======================================================================

View File

@@ -35,7 +35,8 @@ public:
Standard_EXPORT BRepMesh_CurveTessellator(
const IMeshData::IEdgeHandle& theEdge,
const IMeshTools_Parameters& theParameters,
const Standard_Integer theMinPointsNb = 2);
const Standard_Integer theMinPointsNb = 2,
const Standard_Boolean isUseVertexTolerance = Standard_False);
//! Constructor.
Standard_EXPORT BRepMesh_CurveTessellator (
@@ -43,7 +44,8 @@ public:
const TopAbs_Orientation theOrientation,
const IMeshData::IFaceHandle& theFace,
const IMeshTools_Parameters& theParameters,
const Standard_Integer theMinPointsNb = 2);
const Standard_Integer theMinPointsNb = 2,
const Standard_Boolean isUseVertexTolerance = Standard_False);
//! Destructor.
Standard_EXPORT virtual ~BRepMesh_CurveTessellator ();
@@ -96,6 +98,7 @@ private:
const IMeshData::IEdgeHandle& myDEdge;
const IMeshTools_Parameters& myParameters;
Standard_Boolean myUseVertexTolerance;
TopoDS_Edge myEdge;
BRepAdaptor_Curve myCurve;
Standard_Integer myMinPointsNb;

View File

@@ -64,11 +64,12 @@ Handle(IMeshTools_CurveTessellator) BRepMesh_EdgeDiscret::CreateEdgeTessellator(
const TopAbs_Orientation theOrientation,
const IMeshData::IFaceHandle& theDFace,
const IMeshTools_Parameters& theParameters,
const Standard_Integer theMinPointsNb)
const Standard_Integer theMinPointsNb,
const Standard_Boolean isUseVertexTolerance)
{
return theDEdge->GetSameParam() ?
new BRepMesh_CurveTessellator(theDEdge, theParameters, theMinPointsNb) :
new BRepMesh_CurveTessellator(theDEdge, theOrientation, theDFace, theParameters, theMinPointsNb);
new BRepMesh_CurveTessellator(theDEdge, theParameters, theMinPointsNb, isUseVertexTolerance) :
new BRepMesh_CurveTessellator(theDEdge, theOrientation, theDFace, theParameters, theMinPointsNb, isUseVertexTolerance);
}
//=======================================================================

View File

@@ -47,7 +47,8 @@ public:
const TopAbs_Orientation theOrientation,
const IMeshData::IFaceHandle& theDFace,
const IMeshTools_Parameters& theParameters,
const Standard_Integer theMinPointsNb = 2);
const Standard_Integer theMinPointsNb = 2,
const Standard_Boolean isUseVertexTolerance = Standard_False);
//! Creates instance of tessellation extractor.
Standard_EXPORT static Handle(IMeshTools_CurveTessellator) CreateEdgeTessellationExtractor(

View File

@@ -267,7 +267,7 @@ void BRepMesh_FaceChecker::perform(const Standard_Integer theWireIndex) const
Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myWiresIntersectingEdges->ChangeValue(theWireIndex);
// TODO: Tolerance is set to twice value of face deflection in order to fit regressions.
BndBox2dTreeSelector aSelector(2 * myDFace->GetDeflection());
BndBox2dTreeSelector aSelector(2 * Precision::PConfusion()/*myDFace->GetDeflection()*/);
for (Standard_Integer aWireIt = theWireIndex; aWireIt < myDFace->WiresNb(); ++aWireIt)
{
const Handle(IMeshData::BndBox2dTree)& aBndBoxTree2 = myWiresBndBoxTree->Value(aWireIt);

View File

@@ -41,11 +41,19 @@ namespace
{
public:
//! Constructor.
EdgeAmplifier(const IMeshTools_Parameters& theParameters)
: myParameters(theParameters)
EdgeAmplifier(const IMeshTools_Parameters& theParameters,
const Standard_Boolean isUseVertexTolerance = Standard_False)
: myParameters (theParameters),
myUseVertexTolerance(isUseVertexTolerance)
{
}
//! Take vertex tolerance into account.
void SetUseVertexTolerance(const Standard_Boolean isUseVertexTolerance)
{
myUseVertexTolerance = isUseVertexTolerance;
}
//! Main operator.
void operator()(const IMeshData::IEdgePtr& theDEdge) const
{
@@ -75,7 +83,7 @@ namespace
Handle(IMeshTools_CurveTessellator) aTessellator =
BRepMesh_EdgeDiscret::CreateEdgeTessellator(
aDEdge, aPCurve->GetOrientation(), aDFace,
myParameters, aPointsNb);
myParameters, aPointsNb, myUseVertexTolerance);
BRepMesh_EdgeDiscret::Tessellate3d(aDEdge, aTessellator, Standard_False);
BRepMesh_EdgeDiscret::Tessellate2d(aDEdge, Standard_False);
@@ -89,6 +97,7 @@ namespace
private:
const IMeshTools_Parameters& myParameters;
Standard_Boolean myUseVertexTolerance;
};
//! Returns True if some of two vertcies is same with reference one.
@@ -190,12 +199,14 @@ void BRepMesh_ModelHealer::amplifyEdges()
new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
Standard_Integer aAmpIt = 0;
const Standard_Real aIterNb = 5;
const Standard_Integer aIterNb = 6;
IMeshData::MapOfIEdgePtr aEdgesToUpdate(1, aTmpAlloc);
EdgeAmplifier anEdgeAmplifier (myParameters);
while (aAmpIt++ < aIterNb && popEdgesToUpdate(aEdgesToUpdate))
{
anEdgeAmplifier.SetUseVertexTolerance (aAmpIt == aIterNb);
// Try to update discretization by decreasing deflection of problematic edges.
OSD_Parallel::ForEach(aEdgesToUpdate.cbegin(), aEdgesToUpdate.cend(),
anEdgeAmplifier,

22
tests/bugs/mesh/bug31395 Normal file
View File

@@ -0,0 +1,22 @@
puts "========"
puts "0031395: Mesh - BRepMesh produces poor mesh on shape with hidden self-intersections"
puts "========"
puts ""
restore [locate_data_file log368.brep] result
tclean result
incmesh result 0.2
vinit
vsetdispmode 1
vdefaults -autoTriang 0
checkview -display result -3d -path ${imagedir}/${test_image}.png
set log [tricheck result]
if { [llength $log] != 0 } {
puts "Error : Invalid mesh"
} else {
puts "Mesh is OK"
}