mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
0027135: Incorrect result of the normal projection algorithm
New check for possible local traps was added to build correct projection cache. test case added.
This commit is contained in:
@@ -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
|
||||
|
@@ -14,20 +14,33 @@
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <ProjLib_CompProjectedCurve.ixx>
|
||||
#include <ProjLib_HCompProjectedCurve.hxx>
|
||||
#include <gp_XY.hxx>
|
||||
#include <gp_Mat2d.hxx>
|
||||
#include <Extrema_ExtPS.hxx>
|
||||
#include <Precision.hxx>
|
||||
|
||||
#include <Adaptor2d_HCurve2d.hxx>
|
||||
#include <Adaptor3d_HCurve.hxx>
|
||||
#include <Adaptor3d_HSurface.hxx>
|
||||
#include <Extrema_ExtCS.hxx>
|
||||
#include <TColgp_HSequenceOfPnt.hxx>
|
||||
#include <Extrema_ExtPS.hxx>
|
||||
#include <Extrema_GenLocateExtPS.hxx>
|
||||
#include <Extrema_POnSurf.hxx>
|
||||
#include <Extrema_POnCurv.hxx>
|
||||
#include <ProjLib_PrjResolve.hxx>
|
||||
#include <Extrema_POnSurf.hxx>
|
||||
#include <GeomAbs_CurveType.hxx>
|
||||
#include <GeomLib.hxx>
|
||||
#include <gp_Mat2d.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
#include <gp_XY.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <ProjLib_CompProjectedCurve.hxx>
|
||||
#include <ProjLib_HCompProjectedCurve.hxx>
|
||||
#include <ProjLib_PrjResolve.hxx>
|
||||
#include <Standard_DomainError.hxx>
|
||||
#include <Standard_NoSuchObject.hxx>
|
||||
#include <Standard_NotImplemented.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <TColgp_HSequenceOfPnt.hxx>
|
||||
#include <ProjLib_HSequenceOfHSequenceOfPnt.hxx>
|
||||
#include <TColStd_HArray1OfReal.hxx>
|
||||
#include <TColStd_HArray1OfBoolean.hxx>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
23
tests/bugs/moddata_3/bug27135
Normal file
23
tests/bugs/moddata_3/bug27135
Normal file
@@ -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
|
Reference in New Issue
Block a user