From: oan Date: Tue, 27 Dec 2022 12:25:50 +0000 (+0300) Subject: 0031395: Mesh - BRepMesh produces poor mesh on shape with hidden self-intersections X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=refs%2Fheads%2FCR31395;p=occt.git 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. --- diff --git a/src/BRepMesh/BRepMesh_CurveTessellator.cxx b/src/BRepMesh/BRepMesh_CurveTessellator.cxx index ac17847667..1cb3a141ea 100644 --- a/src/BRepMesh/BRepMesh_CurveTessellator.cxx +++ b/src/BRepMesh/BRepMesh_CurveTessellator.cxx @@ -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) * 1.1; + 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; } //======================================================================= diff --git a/src/BRepMesh/BRepMesh_CurveTessellator.hxx b/src/BRepMesh/BRepMesh_CurveTessellator.hxx index d9406a8423..22b3494ad0 100644 --- a/src/BRepMesh/BRepMesh_CurveTessellator.hxx +++ b/src/BRepMesh/BRepMesh_CurveTessellator.hxx @@ -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; diff --git a/src/BRepMesh/BRepMesh_EdgeDiscret.cxx b/src/BRepMesh/BRepMesh_EdgeDiscret.cxx index 31c7963c59..efbaa5a5f2 100644 --- a/src/BRepMesh/BRepMesh_EdgeDiscret.cxx +++ b/src/BRepMesh/BRepMesh_EdgeDiscret.cxx @@ -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); } //======================================================================= diff --git a/src/BRepMesh/BRepMesh_EdgeDiscret.hxx b/src/BRepMesh/BRepMesh_EdgeDiscret.hxx index 89b67eda39..27747c820f 100644 --- a/src/BRepMesh/BRepMesh_EdgeDiscret.hxx +++ b/src/BRepMesh/BRepMesh_EdgeDiscret.hxx @@ -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( diff --git a/src/BRepMesh/BRepMesh_FaceChecker.cxx b/src/BRepMesh/BRepMesh_FaceChecker.cxx index b78238d692..5ea498ecbf 100644 --- a/src/BRepMesh/BRepMesh_FaceChecker.cxx +++ b/src/BRepMesh/BRepMesh_FaceChecker.cxx @@ -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); diff --git a/src/BRepMesh/BRepMesh_ModelHealer.cxx b/src/BRepMesh/BRepMesh_ModelHealer.cxx index 4c2eed209a..1285f95769 100644 --- a/src/BRepMesh/BRepMesh_ModelHealer.cxx +++ b/src/BRepMesh/BRepMesh_ModelHealer.cxx @@ -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,