From: aml Date: Thu, 11 Feb 2016 11:42:04 +0000 (+0300) Subject: 0027135: Incorrect result of the normal projection algorithm X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=7c53747c3e449783ca8ffbf2f33832324b9a813d;p=occt-copy.git 0027135: Incorrect result of the normal projection algorithm New check for possible local traps was added to build correct projection cache. test case added. --- diff --git a/src/ProjLib/ProjLib_CompProjectedCurve.cdl b/src/ProjLib/ProjLib_CompProjectedCurve.cdl index f6e77cf33d..d06da45be9 100644 --- a/src/ProjLib/ProjLib_CompProjectedCurve.cdl +++ b/src/ProjLib/ProjLib_CompProjectedCurve.cdl @@ -192,6 +192,9 @@ is raises OutOfRange from Standard is private; + + UpdateTripleByTrapCriteria(me; thePoint : out Pnt from gp) + is private; MaxDistance(me; Index: Integer) ---Purpose: returns the maximum distance between diff --git a/src/ProjLib/ProjLib_CompProjectedCurve.cxx b/src/ProjLib/ProjLib_CompProjectedCurve.cxx index 6b2535eaed..2105dd09c2 100644 --- a/src/ProjLib/ProjLib_CompProjectedCurve.cxx +++ b/src/ProjLib/ProjLib_CompProjectedCurve.cxx @@ -14,20 +14,33 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -#include -#include -#include -#include -#include -#include + +#include +#include +#include #include -#include +#include #include -#include #include -#include +#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #define FuncTol 1.e-10 @@ -614,8 +627,8 @@ void ProjLib_CompProjectedCurve::Init() //Basic loop while(t <= LastU) { - //Search for the begining a new continuous part - //To avoid infinite computation in some difficult cases + // Search for the beginning of a new continuous part + // to avoid infinite computation in some difficult cases. new_part = Standard_False; if(t > FirstU && Abs(t-prevDeb) <= Precision::PConfusion()) SameDeb=Standard_True; while(t <= LastU && !new_part && !FromLastU && !SameDeb) @@ -627,7 +640,7 @@ void ProjLib_CompProjectedCurve::Init() gp_Pnt CPoint; Standard_Real ParT,ParU,ParV; - // Search an initpoint in the list of Extrema Curve-Surface + // Search an initial point in the list of Extrema Curve-Surface if(Nend != 0 && !CExt.IsParallel()) { for (i=1;i<=Nend;i++) @@ -725,9 +738,9 @@ void ProjLib_CompProjectedCurve::Init() { //Search for exact boundary point Tol = Min(myTolU, myTolV); - gp_Vec2d D; - d1(Triple.X(), Triple.Y(), Triple.Z(), D, myCurve, mySurface); - Tol /= Max(Abs(D.X()), Abs(D.Y())); + gp_Vec2d aD; + d1(Triple.X(), Triple.Y(), Triple.Z(), aD, myCurve, mySurface); + Tol /= Max(Abs(aD.X()), Abs(aD.Y())); if(!ExactBound(Triple, t - Step, Tol, myTolU, myTolV, myCurve, mySurface)) @@ -851,27 +864,13 @@ void ProjLib_CompProjectedCurve::Init() prevStep = Step; Triple = gp_Pnt(t, aPrjPS.Solution().X(), aPrjPS.Solution().Y()); - if (mySurface->GetType() == GeomAbs_SurfaceOfRevolution && - (Abs (Triple.Z() - mySurface->FirstVParameter()) < Precision::Confusion() || - Abs (Triple.Z() - mySurface->LastVParameter() ) < Precision::Confusion() )) - { - // Go out from possible attraktor. - - Standard_Real U,V; - InitialPoint(myCurve->Value(t), t, myCurve, mySurface, myTolU, myTolV, U, V); - if (Abs (Abs(U - Triple.Y()) - mySurface->UPeriod()) < Precision::Confusion()) - { - // Handle period jump. - U = Triple.Y(); - } - Triple.SetY(U); - Triple.SetZ(V); - } + // Check local traps. + UpdateTripleByTrapCriteria(Triple); if((Triple.X() - mySequence->Value(myNbCurves)->Value(mySequence->Value(myNbCurves)->Length()).X()) > 1.e-10) mySequence->Value(myNbCurves)->Append(Triple); - if (t == LastU) {t = LastU + 1; break;}//return; + if (t == LastU) {t = LastU + 1; break;}//return; //Computation of WalkStep d2CurvOnSurf(Triple.X(), Triple.Y(), Triple.Z(), D1, D2, myCurve, mySurface); MagnD1 = D1.Magnitude(); @@ -889,7 +888,7 @@ void ProjLib_CompProjectedCurve::Init() } } } - // Sequence postproceeding + // Sequence post-proceeding. Standard_Integer j; // 1. Removing poor parts @@ -921,11 +920,11 @@ void ProjLib_CompProjectedCurve::Init() for(i = 1; i <= myNbCurves; i++) for(j = 1; j <= mySequence->Value(i)->Length(); j++) { - gp_Pnt POnC, POnS, Triple; + gp_Pnt POnC, POnS, aTriple; Standard_Real Distance; - Triple = mySequence->Value(i)->Value(j); - myCurve->D0(Triple.X(), POnC); - mySurface->D0(Triple.Y(), Triple.Z(), POnS); + aTriple = mySequence->Value(i)->Value(j); + myCurve->D0(aTriple.X(), POnC); + mySurface->D0(aTriple.Y(), aTriple.Z(), POnS); Distance = POnC.Distance(POnS); if (myMaxDistance->Value(i) < Distance) myMaxDistance->ChangeValue(i) = Distance; @@ -1235,12 +1234,12 @@ void ProjLib_CompProjectedCurve::D0(const Standard_Real U,gp_Pnt2d& P) const Extrema_ExtPS aExtPS(thePoint, mySurface->Surface(), myTolU, myTolV); if (aExtPS.IsDone() && aExtPS.NbExt()) { - Standard_Integer i, Nend, imin = 1; + Standard_Integer k, Nend, imin = 1; // Search for the nearest solution which is also a normal projection Nend = aExtPS.NbExt(); - for(i = 2; i <= Nend; i++) - if (aExtPS.SquareDistance(i) < aExtPS.SquareDistance(imin)) - imin = i; + for(k = 2; k <= Nend; k++) + if (aExtPS.SquareDistance(k) < aExtPS.SquareDistance(imin)) + imin = k; const Extrema_POnSurf& POnS = aExtPS.Point(imin); Standard_Real ParU,ParV; POnS.Parameter(ParU, ParV); @@ -1612,3 +1611,51 @@ GeomAbs_CurveType ProjLib_CompProjectedCurve::GetType() const { return GeomAbs_OtherCurve; } + +//======================================================================= +//function : UpdateTripleByTrapCriteria +//purpose : +//======================================================================= +void ProjLib_CompProjectedCurve::UpdateTripleByTrapCriteria(gp_Pnt &thePoint) const +{ + Standard_Boolean isProblemsPossible = Standard_False; + // Check possible traps cases: + + // 25892 bug. + if (mySurface->GetType() == GeomAbs_SurfaceOfRevolution && + (Abs (thePoint.Z() - mySurface->FirstVParameter()) < Precision::PConfusion() || + Abs (thePoint.Z() - mySurface->LastVParameter() ) < Precision::PConfusion() )) + { + isProblemsPossible = Standard_True; + } + + // 27135 bug. Trap on degenerated edge. + if (mySurface->GetType() == GeomAbs_Sphere && + (Abs (thePoint.Z() - mySurface->FirstVParameter()) < Precision::PConfusion() || + Abs (thePoint.Z() - mySurface->LastVParameter() ) < Precision::PConfusion() || + Abs (thePoint.Y() - mySurface->FirstUParameter()) < Precision::PConfusion() || + Abs (thePoint.Y() - mySurface->LastUParameter() ) < Precision::PConfusion() )) + { + isProblemsPossible = Standard_True; + } + + if (!isProblemsPossible) + return; + + Standard_Real U,V; + InitialPoint(myCurve->Value(thePoint.X()), thePoint.X(), myCurve, mySurface, myTolU, myTolV, U, V); + + // Restore original position in case of period jump. + if (mySurface->IsUPeriodic() && + Abs (Abs(U - thePoint.Y()) - mySurface->UPeriod()) < Precision::PConfusion()) + { + U = thePoint.Y(); + } + if (mySurface->IsVPeriodic() && + Abs (Abs(V - thePoint.Z()) - mySurface->VPeriod()) < Precision::PConfusion()) + { + V = thePoint.Z(); + } + thePoint.SetY(U); + thePoint.SetZ(V); +} diff --git a/tests/bugs/moddata_3/bug27135 b/tests/bugs/moddata_3/bug27135 new file mode 100644 index 0000000000..0376155941 --- /dev/null +++ b/tests/bugs/moddata_3/bug27135 @@ -0,0 +1,23 @@ +puts "================" +puts "0027135" +puts "================" +puts "" +############################################################## +# Incorrect result of the normal projection algorithm +# Degenerated edge in result +############################################################## + +restore [locate_data_file bug27135.brep] aShape +explode aShape + +nproject result aShape_1 aShape_2 + +# Result length check. +checkprops result -l 5.74501 + +# Visual check. +donly result +smallview +fit +display aShape_2 +checkview -screenshot -2d -path ${imagedir}/${test_image}.png