1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

Compare commits

...

1 Commits

Author SHA1 Message Date
jgv
db557f72d0 0032833: Shape Healing - FixShape needs to be improved
Additional check before adding degenerated edge
2022-07-29 00:40:30 +03:00
3 changed files with 40 additions and 12 deletions

View File

@@ -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);
}
//=======================================================================

View File

@@ -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.

View File

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