From db557f72d0d8d68d4059ed7149d138b0ee1b351c Mon Sep 17 00:00:00 2001 From: jgv Date: Fri, 29 Jul 2022 00:40:30 +0300 Subject: [PATCH] 0032833: Shape Healing - FixShape needs to be improved Additional check before adding degenerated edge --- src/ShapeAnalysis/ShapeAnalysis_Wire.cxx | 22 ++++++++++++--------- src/ShapeAnalysis/ShapeAnalysis_Wire.hxx | 5 ++++- src/ShapeFix/ShapeFix_Wire.cxx | 25 ++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/ShapeAnalysis/ShapeAnalysis_Wire.cxx b/src/ShapeAnalysis/ShapeAnalysis_Wire.cxx index 633917eb4b..1bc3d7e03b 100644 --- a/src/ShapeAnalysis/ShapeAnalysis_Wire.cxx +++ b/src/ShapeAnalysis/ShapeAnalysis_Wire.cxx @@ -1504,7 +1504,8 @@ Standard_Boolean ShapeAnalysis_Wire::CheckIntersectingEdges (const Standard_Inte Standard_Boolean ShapeAnalysis_Wire::CheckLacking (const Standard_Integer num, const Standard_Real Tolerance, - gp_Pnt2d &p2d1, gp_Pnt2d &p2d2) + gp_Pnt2d &p2d1, gp_Pnt2d &p2d2, + gp_Vec2d& theTangent1, gp_Vec2d& theTangent2) { myStatus = ShapeExtend::EncodeStatus (ShapeExtend_OK); if ( ! IsReady() ) return Standard_False; @@ -1529,22 +1530,24 @@ Standard_Boolean ShapeAnalysis_Wire::CheckLacking (const Standard_Integer num, } Standard_Real a, b; - gp_Vec2d v1, v2, v12; + gp_Vec2d /*v1, v2,*/ v12; Handle(Geom2d_Curve) c2d; if ( ! sae.PCurve ( E1, myFace, c2d, a, b, Standard_True ) ) { myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL3); return Standard_False; } Geom2dAdaptor_Curve anAdapt(c2d); - anAdapt.D1(b, p2d1, v1); - if ( E1.Orientation() == TopAbs_REVERSED ) v1.Reverse(); + anAdapt.D1(b, p2d1, theTangent1); + if ( E1.Orientation() == TopAbs_REVERSED ) + theTangent1.Reverse(); if ( ! sae.PCurve ( E2, myFace, c2d, a, b, Standard_True ) ) { myStatus |= ShapeExtend::EncodeStatus (ShapeExtend_FAIL3); return Standard_False; } anAdapt.Load(c2d); - anAdapt.D1(a, p2d2, v2); - if ( E2.Orientation() == TopAbs_REVERSED ) v2.Reverse(); + anAdapt.D1(a, p2d2, theTangent2); + if ( E2.Orientation() == TopAbs_REVERSED ) + theTangent2.Reverse(); v12 = p2d2.XY() - p2d1.XY(); myMax2d = v12.SquareMagnitude(); @@ -1561,8 +1564,8 @@ Standard_Boolean ShapeAnalysis_Wire::CheckLacking (const Standard_Integer num, myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE1 ); if ( myMax2d < Precision::PConfusion() || //:abv 03.06.02 CTS21866.stp - ( v1.SquareMagnitude() > gp::Resolution() && Abs ( v12.Angle ( v1 ) ) > 0.9 * M_PI ) || - ( v2.SquareMagnitude() > gp::Resolution() && Abs ( v12.Angle ( v2 ) ) > 0.9 * M_PI ) ) + ( theTangent1.SquareMagnitude() > gp::Resolution() && Abs ( v12.Angle ( theTangent1 ) ) > 0.9 * M_PI ) || + ( theTangent2.SquareMagnitude() > gp::Resolution() && Abs ( v12.Angle ( theTangent2 ) ) > 0.9 * M_PI ) ) myStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE2 ); return Standard_True; } @@ -1577,7 +1580,8 @@ Standard_Boolean ShapeAnalysis_Wire::CheckLacking (const Standard_Integer num, const Standard_Real Tolerance) { gp_Pnt2d p1, p2; - return CheckLacking (num, Tolerance, p1, p2); + gp_Vec2d aTangent1, aTangent2; + return CheckLacking (num, Tolerance, p1, p2, aTangent1, aTangent2); } //======================================================================= diff --git a/src/ShapeAnalysis/ShapeAnalysis_Wire.hxx b/src/ShapeAnalysis/ShapeAnalysis_Wire.hxx index edb403eca4..d04798b9a0 100644 --- a/src/ShapeAnalysis/ShapeAnalysis_Wire.hxx +++ b/src/ShapeAnalysis/ShapeAnalysis_Wire.hxx @@ -403,7 +403,10 @@ public: //! DONE2: is set (together with DONE1) if gap is detected and the //! vector (p2d2 - p2d1) goes in direction opposite to the pcurves //! of the edges (if angle is more than 0.9*PI). - Standard_EXPORT Standard_Boolean CheckLacking (const Standard_Integer num, const Standard_Real Tolerance, gp_Pnt2d& p2d1, gp_Pnt2d& p2d2); + Standard_EXPORT Standard_Boolean CheckLacking (const Standard_Integer num, + const Standard_Real Tolerance, + gp_Pnt2d& p2d1, gp_Pnt2d& p2d2, + gp_Vec2d& theTangent1, gp_Vec2d& theTangent2); //! Checks if there is a gap in 2D between edges and not comprised by vertex tolerance //! The value of SBWD.thepreci is used. diff --git a/src/ShapeFix/ShapeFix_Wire.cxx b/src/ShapeFix/ShapeFix_Wire.cxx index f03fd76f01..f49b4f7078 100644 --- a/src/ShapeFix/ShapeFix_Wire.cxx +++ b/src/ShapeFix/ShapeFix_Wire.cxx @@ -2930,7 +2930,8 @@ Standard_Boolean ShapeFix_Wire::FixLacking (const Standard_Integer num, //============= // First phase: analysis whether the problem (gap) exists gp_Pnt2d p2d1, p2d2; - myAnalyzer->CheckLacking ( num, ( force ? Precision() : 0. ), p2d1, p2d2 ); + gp_Vec2d aTangent1, aTangent2; + myAnalyzer->CheckLacking (num, ( force ? Precision() : 0. ), p2d1, p2d2, aTangent1, aTangent2); if ( myAnalyzer->LastCheckStatus ( ShapeExtend_FAIL ) ) { myLastFixStatus |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL1 ); } @@ -3052,8 +3053,28 @@ Standard_Boolean ShapeFix_Wire::FixLacking (const Standard_Integer num, gp_Pnt pV = 0.5 * ( BRep_Tool::Pnt(V1).XYZ() + BRep_Tool::Pnt(V2).XYZ() ); gp_Pnt pm = myAnalyzer->Surface()->Value ( 0.5 * ( p2d1.XY() + p2d2.XY() ) ); + //Additional check + //const Standard_Real anAngularTol = 1.e-5; + const Standard_Real aMaxAngle = 7*M_PI/8; + Standard_Boolean anIsGoodConnection = Standard_True; + gp_Vec2d aVecP1P2 (p2d1, p2d2); + if (aVecP1P2.SquareMagnitude() > Precision::SquareConfusion() && + aTangent1.SquareMagnitude() > Precision::SquareConfusion() && + aTangent2.SquareMagnitude() > Precision::SquareConfusion()) + { + Standard_Real anAngle1 = aTangent1.Angle (aVecP1P2); + Standard_Real anAngle2 = aVecP1P2.Angle (aTangent2); + if (Abs(anAngle1) > aMaxAngle || + Abs(anAngle2) > aMaxAngle) + anIsGoodConnection = Standard_False; + } + Standard_Real dist = pV.Distance ( pm ); - if ( dist <= tol ) doAddDegen = Standard_True; + if ( dist <= tol ) + { + if (anIsGoodConnection) + doAddDegen = Standard_True; + } else if ( myTopoMode ) doAddClosed = Standard_True; else if ( dist <= MaxTolerance() ) { //:r7 abv 12 Apr 99: t3d_opt.stp #14245 after S4136 doAddDegen = Standard_True;