From: azv Date: Fri, 19 Feb 2021 19:24:50 +0000 (+0300) Subject: 0032066: Modeling Algorithms - Incorrect result of Boolean CUT operation X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=0281abc7ca12d036cc2ad213ceb6c4a9c37cd0d1;p=occt-copy.git 0032066: Modeling Algorithms - Incorrect result of Boolean CUT operation Use IWalking algorithm of OCCT 7.5.0 --- diff --git a/src/Contap/Contap_SurfFunction.cxx b/src/Contap/Contap_SurfFunction.cxx index 6645815fb3..819f626a4a 100644 --- a/src/Contap/Contap_SurfFunction.cxx +++ b/src/Contap/Contap_SurfFunction.cxx @@ -32,11 +32,19 @@ Contap_SurfFunction::Contap_SurfFunction (): myMean(1.), myType(Contap_ContourStd), myDir(0.,0.,1.), + myAng(0.0), myCosAng(0.), // PI/2 - Angle de depouille tol(1.e-6), + valf(0.0), + Usol(0.0), + Vsol(0.0), + Fpu(0.0), + Fpv(0.0), + tangent(Standard_False), computed(Standard_False), derived(Standard_False) -{} +{ +} void Contap_SurfFunction::Set(const Handle(Adaptor3d_HSurface)& S) { diff --git a/src/Contap/Contap_SurfFunction.hxx b/src/Contap/Contap_SurfFunction.hxx index 3adca5c691..60a1662b20 100644 --- a/src/Contap/Contap_SurfFunction.hxx +++ b/src/Contap/Contap_SurfFunction.hxx @@ -106,7 +106,11 @@ public: const Handle(Adaptor3d_HSurface)& Surface() const; - + //! Method is entered for compatibility with IntPatch_TheSurfFunction. + const Handle(Adaptor3d_HSurface)& PSurface() const + { + return Surface(); + } protected: diff --git a/src/Contap/Contap_TheIWalking.hxx b/src/Contap/Contap_TheIWalking.hxx index 0919a42b63..88b6935986 100644 --- a/src/Contap/Contap_TheIWalking.hxx +++ b/src/Contap/Contap_TheIWalking.hxx @@ -49,6 +49,7 @@ class Adaptor3d_HSurfaceTool; class Contap_SurfFunction; class Contap_TheIWLineOfTheIWalking; class IntSurf_PntOn2S; +class math_FunctionSetRoot; class Contap_TheIWalking { @@ -150,7 +151,12 @@ protected: //! Clears up internal containers Standard_EXPORT void Clear(); - + //! Returns TRUE if thePOn2S is in one of existing lines. + Standard_EXPORT Standard_Boolean IsPointOnLine(const IntSurf_PntOn2S& thePOn2S, + const math_Vector& theInfBounds, + const math_Vector& theSupBounds, + math_FunctionSetRoot& theSolver, + Contap_SurfFunction& theFunc); private: diff --git a/src/IntPatch/IntPatch_TheIWalking.hxx b/src/IntPatch/IntPatch_TheIWalking.hxx index fce79efbe2..a58d30c7fa 100644 --- a/src/IntPatch/IntPatch_TheIWalking.hxx +++ b/src/IntPatch/IntPatch_TheIWalking.hxx @@ -49,6 +49,7 @@ class Adaptor3d_HSurfaceTool; class IntPatch_TheSurfFunction; class IntPatch_TheIWLineOfTheIWalking; class IntSurf_PntOn2S; +class math_FunctionSetRoot; class IntPatch_TheIWalking { @@ -150,6 +151,12 @@ protected: //! Clears up internal containers Standard_EXPORT void Clear(); + //! Returns TRUE if thePOn2S is in one of existing lines. + Standard_EXPORT Standard_Boolean IsPointOnLine(const IntSurf_PntOn2S& thePOn2S, + const math_Vector& theInfBounds, + const math_Vector& theSupBounds, + math_FunctionSetRoot& theSolver, + IntPatch_TheSurfFunction& theFunc); diff --git a/src/IntSurf/IntSurf_LineOn2S.cxx b/src/IntSurf/IntSurf_LineOn2S.cxx index 1b5ce0d8f5..162bab7e3a 100644 --- a/src/IntSurf/IntSurf_LineOn2S.cxx +++ b/src/IntSurf/IntSurf_LineOn2S.cxx @@ -20,9 +20,13 @@ IMPLEMENT_STANDARD_RTTIEXT(IntSurf_LineOn2S,Standard_Transient) -IntSurf_LineOn2S::IntSurf_LineOn2S (const IntSurf_Allocator& theAllocator) : - mySeq (theAllocator) -{} +IntSurf_LineOn2S:: + IntSurf_LineOn2S(const IntSurf_Allocator& theAllocator) : mySeq(theAllocator) +{ + myBuv1.SetWhole(); + myBuv2.SetWhole(); + myBxyz.SetWhole(); +} Handle(IntSurf_LineOn2S) IntSurf_LineOn2S::Split (const Standard_Integer Index) @@ -46,8 +50,167 @@ void IntSurf_LineOn2S::InsertBefore(const Standard_Integer index, const IntSurf_ else { mySeq.InsertBefore(index,P); } + + if (!myBxyz.IsWhole()) + { + myBxyz.Add(P.Value()); + } + + if (!myBuv1.IsWhole()) + { + myBuv1.Add(P.ValueOnSurface(Standard_True)); + } + + if (!myBuv2.IsWhole()) + { + myBuv2.Add(P.ValueOnSurface(Standard_False)); + } } void IntSurf_LineOn2S::RemovePoint(const Standard_Integer index) { mySeq.Remove(index); + myBuv1.SetWhole(); + myBuv2.SetWhole(); + myBxyz.SetWhole(); +} + +Standard_Boolean IntSurf_LineOn2S::IsOutBox(const gp_Pnt& Pxyz) +{ + if (myBxyz.IsWhole()) + { + Standard_Integer n = NbPoints(); + myBxyz.SetVoid(); + for (Standard_Integer i = 1; i <= n; i++) + { + gp_Pnt P = mySeq(i).Value(); + myBxyz.Add(P); + } + Standard_Real x0, y0, z0, x1, y1, z1; + myBxyz.Get(x0, y0, z0, x1, y1, z1); + x1 -= x0; y1 -= y0; z1 -= z0; + if (x1>y1) + { + if (x1>z1) + { + myBxyz.Enlarge(x1*0.01); + } + else + { + myBxyz.Enlarge(z1*0.01); + } + } + else + { + if (y1>z1) + { + myBxyz.Enlarge(y1*0.01); + } + else + { + myBxyz.Enlarge(z1*0.01); + } + } + } + Standard_Boolean out = myBxyz.IsOut(Pxyz); + return(out); +} + +Standard_Boolean IntSurf_LineOn2S::IsOutSurf1Box(const gp_Pnt2d& P1uv) +{ + if (myBuv1.IsWhole()) + { + Standard_Integer n = NbPoints(); + Standard_Real pu1, pu2, pv1, pv2; + myBuv1.SetVoid(); + for (Standard_Integer i = 1; i <= n; i++) + { + mySeq(i).Parameters(pu1, pv1, pu2, pv2); + myBuv1.Add(gp_Pnt2d(pu1, pv1)); + } + myBuv1.Get(pu1, pv1, pu2, pv2); + pu2 -= pu1; + pv2 -= pv1; + if (pu2>pv2) + { + myBuv1.Enlarge(pu2*0.01); + } + else + { + myBuv1.Enlarge(pv2*0.01); + } + } + Standard_Boolean out = myBuv1.IsOut(P1uv); + return(out); +} + +Standard_Boolean IntSurf_LineOn2S::IsOutSurf2Box(const gp_Pnt2d& P2uv) +{ + if (myBuv2.IsWhole()) + { + Standard_Integer n = NbPoints(); + Standard_Real pu1, pu2, pv1, pv2; + myBuv2.SetVoid(); + for (Standard_Integer i = 1; i <= n; i++) + { + mySeq(i).Parameters(pu1, pv1, pu2, pv2); + myBuv2.Add(gp_Pnt2d(pu2, pv2)); + } + myBuv2.Get(pu1, pv1, pu2, pv2); + pu2 -= pu1; + pv2 -= pv1; + if (pu2>pv2) + { + myBuv2.Enlarge(pu2*0.01); + } + else + { + myBuv2.Enlarge(pv2*0.01); + } + } + Standard_Boolean out = myBuv2.IsOut(P2uv); + return(out); +} + +//======================================================================= +//function : Add +//purpose : +//======================================================================= +void IntSurf_LineOn2S::Add(const IntSurf_PntOn2S& P) +{ + mySeq.Append(P); + if (!myBxyz.IsWhole()) + { + myBxyz.Add(P.Value()); + } + + if (!myBuv1.IsWhole()) + { + myBuv1.Add(P.ValueOnSurface(Standard_True)); + } + + if (!myBuv2.IsWhole()) + { + myBuv2.Add(P.ValueOnSurface(Standard_False)); + } +} + +//======================================================================= +//function : SetUV +//purpose : +//======================================================================= +void IntSurf_LineOn2S::SetUV(const Standard_Integer Index, + const Standard_Boolean OnFirst, + const Standard_Real U, + const Standard_Real V) +{ + mySeq(Index).SetValue(OnFirst, U, V); + + if (OnFirst && !myBuv1.IsWhole()) + { + myBuv1.Add(gp_Pnt2d(U, V)); + } + else if (!OnFirst && !myBuv2.IsWhole()) + { + myBuv2.Add(gp_Pnt2d(U, V)); + } } diff --git a/src/IntSurf/IntSurf_LineOn2S.hxx b/src/IntSurf/IntSurf_LineOn2S.hxx index be4aa1654d..1d78429ab4 100644 --- a/src/IntSurf/IntSurf_LineOn2S.hxx +++ b/src/IntSurf/IntSurf_LineOn2S.hxx @@ -20,6 +20,8 @@ #include #include +#include +#include #include #include #include @@ -43,7 +45,7 @@ public: Standard_EXPORT IntSurf_LineOn2S(const IntSurf_Allocator& theAllocator = 0); //! Adds a point in the line. - void Add (const IntSurf_PntOn2S& P); + Standard_EXPORT void Add(const IntSurf_PntOn2S& P); //! Returns the number of points in the line. Standard_Integer NbPoints() const; @@ -63,7 +65,7 @@ public: //! Sets the parametric coordinates on one of the surfaces //! of the point of range Index in the line. - void SetUV (const Standard_Integer Index, const Standard_Boolean OnFirst, const Standard_Real U, const Standard_Real V); + Standard_EXPORT void SetUV(const Standard_Integer Index, const Standard_Boolean OnFirst, const Standard_Real U, const Standard_Real V); void Clear(); @@ -71,8 +73,16 @@ public: Standard_EXPORT void RemovePoint (const Standard_Integer I); + //! Returns TRUE if theP is out of the box built from + //! the points on 1st surface + Standard_EXPORT Standard_Boolean IsOutSurf1Box(const gp_Pnt2d& theP); + //! Returns TRUE if theP is out of the box built from + //! the points on 2nd surface + Standard_EXPORT Standard_Boolean IsOutSurf2Box(const gp_Pnt2d& theP); + //! Returns TRUE if theP is out of the box built from 3D-points. + Standard_EXPORT Standard_Boolean IsOutBox(const gp_Pnt& theP); DEFINE_STANDARD_RTTIEXT(IntSurf_LineOn2S,Standard_Transient) @@ -85,7 +95,9 @@ private: IntSurf_SequenceOfPntOn2S mySeq; - + Bnd_Box2d myBuv1; + Bnd_Box2d myBuv2; + Bnd_Box myBxyz; }; diff --git a/src/IntSurf/IntSurf_LineOn2S.lxx b/src/IntSurf/IntSurf_LineOn2S.lxx index 75ec13deeb..76e96da10f 100644 --- a/src/IntSurf/IntSurf_LineOn2S.lxx +++ b/src/IntSurf/IntSurf_LineOn2S.lxx @@ -14,15 +14,6 @@ #include - - - -inline void IntSurf_LineOn2S::Add(const IntSurf_PntOn2S& P) { - - mySeq.Append(P); -} - - inline Standard_Integer IntSurf_LineOn2S::NbPoints() const { return mySeq.Length(); @@ -47,16 +38,11 @@ inline void IntSurf_LineOn2S::Value(const Standard_Integer Index, mySeq(Index) = P; } -inline void IntSurf_LineOn2S::SetUV(const Standard_Integer Index, - const Standard_Boolean OnFirst, - const Standard_Real U, - const Standard_Real V) -{ - mySeq(Index).SetValue(OnFirst,U,V); -} - inline void IntSurf_LineOn2S::Clear () { mySeq.Clear(); + myBuv1.SetWhole(); + myBuv2.SetWhole(); + myBxyz.SetWhole(); } diff --git a/src/IntWalk/IntWalk_IWLine.lxx b/src/IntWalk/IntWalk_IWLine.lxx index 63f048599d..55d44a4325 100644 --- a/src/IntWalk/IntWalk_IWLine.lxx +++ b/src/IntWalk/IntWalk_IWLine.lxx @@ -19,7 +19,7 @@ inline void IntWalk_IWLine::Cut(const Standard_Integer Index) { -//-- cout<<" split : "<Split(Index); } @@ -146,7 +146,7 @@ inline void IntWalk_IWLine::SetTangentVector (const gp_Vec& V, indextg = Index; vcttg = V; - //-- cout<<"\n IntWalk_IWLine::SetTangentVector : "< aTol) + if(Abs(theFunc.Root()) > aTol) return Standard_False; } @@ -77,9 +77,14 @@ IntWalk_IWalking::IntWalk_IWalking (const Standard_Real Epsilon, pas(Increment), tolerance(1,2), epsilon(Epsilon*Epsilon), + reversed(Standard_False), wd1 (IntWalk_VectorOfWalkingData::allocator_type (new NCollection_IncAllocator)), wd2 (wd1.get_allocator()), nbMultiplicities (wd1.get_allocator()), + Um(0.0), + UM(0.0), + Vm(0.0), + VM(0.0), ToFillHoles(theToFillHoles) { } diff --git a/src/IntWalk/IntWalk_IWalking_2.gxx b/src/IntWalk/IntWalk_IWalking_2.gxx index 69db4cd3ed..8538123c60 100644 --- a/src/IntWalk/IntWalk_IWalking_2.gxx +++ b/src/IntWalk/IntWalk_IWalking_2.gxx @@ -141,7 +141,7 @@ Standard_Boolean IntWalk_IWalking::Cadrage } BornSup(1) = BornInf(1); // limit the parameter UVap(1) = BornInf(1); - UVap(2) += Step*Duvy*StepSign;; + UVap(2) += Step*Duvy*StepSign; return Standard_True; } else if (supu) { // jag 940616 @@ -392,8 +392,13 @@ Standard_Boolean IntWalk_IWalking::TestArretPassage //Normalizing factor. If it is less than 1.0 then the range will be expanded. //This is no good for computation. Therefore, it is limited. - const Standard_Real deltau = mySRangeU.IsVoid() ? UM - Um : Max(mySRangeU.Delta(), 1.0); - const Standard_Real deltav = mySRangeV.IsVoid() ? VM - Vm : Max(mySRangeV.Delta(), 1.0); + //Do not limit these factor in case of highly anisotropic parametrization + //(parametric space is considerably larger in one direction than another). + Standard_Boolean isHighlyAnisotropic = Max(tolu, tolv) > 1000. * Min(tolu, tolv); + Standard_Real deltau = mySRangeU.IsVoid() ? UM - Um + : (isHighlyAnisotropic ? mySRangeU.Delta() : Max(mySRangeU.Delta(), 1.0)); + Standard_Real deltav = mySRangeV.IsVoid() ? VM - Vm + : (isHighlyAnisotropic ? mySRangeV.Delta() : Max(mySRangeV.Delta(), 1.0)); Up/=deltau; UV1/=deltau; Vp/=deltav; UV2/=deltav; @@ -833,7 +838,7 @@ void IntWalk_IWalking::TestArretCadre } #ifdef OCCT_DEBUG else { - cout<<" IntWalk_IWalking_2.gxx : bizarrerie 30 10 97 "< 11) { // modified by NIZHNY-MKK Fri Oct 27 12:33:37 2000.BEGIN if ((wd1[I].etat > 11) || ((wd1[I].etat < -11) && (movementdirectioninfo[I]!=0))) { // modified by NIZHNY-MKK Fri Oct 27 12:33:43 2000.END - PathPnt = Pnts1.Value(I); + PathPnt = Pnts1.Value(I); + UVap(1) = wd1[I].ustart; + UVap(2) = wd1[I].vstart; + MakeWalkingPoint(11, UVap(1), UVap(2), Func, previousPoint); + + if (IsPointOnLine(previousPoint, BornInf, BornSup, Rsnld, aFuncForDuplicate)) + { + wd1[I].etat = -Abs(wd1[I].etat); //mark point as processed + continue; + } + CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator()); CurrentLine->SetTangencyAtBegining(Standard_False); Tgtend = Standard_False; CurrentLine->AddStatusFirst(Standard_False, Standard_True, I, PathPnt); - UVap(1) = wd1[I].ustart; - UVap(2) = wd1[I].vstart; - MakeWalkingPoint(11, UVap(1), UVap(2), Func, previousPoint); previousd3d = Func.Direction3d(); previousd2d = Func.Direction2d(); CurrentLine->AddPoint(previousPoint); @@ -139,7 +148,7 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, // modified by NIZHNY-MKK Fri Oct 27 12:34:37 2000.END // Modified by Sergey KHROMOV - Tue Nov 20 10:41:45 2001 Begin - wd1[I].etat = - abs(wd1[I].etat); + wd1[I].etat = -Abs(wd1[I].etat); movementdirectioninfo[I] = (movementdirectioninfo[I]==0) ? StepSign : 0; // Modified by Sergey KHROMOV - Tue Nov 20 10:41:56 2001 End // first step of advancement diff --git a/src/IntWalk/IntWalk_IWalking_4.gxx b/src/IntWalk/IntWalk_IWalking_4.gxx index 460346a647..2add80f20e 100644 --- a/src/IntWalk/IntWalk_IWalking_4.gxx +++ b/src/IntWalk/IntWalk_IWalking_4.gxx @@ -118,12 +118,21 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, } } + TheIWFunction aFuncForDuplicate = Func; + for (I = 1;I<=nbLoop;I++) { if (wd2[I].etat > 12) { // start point of closed line LoopPnt = Pnts2.Value(I); - previousPoint.SetValue(ThePointOfLoopTool::Value3d(LoopPnt),reversed, - wd2[I].ustart,wd2[I].vstart); + previousPoint.SetValue(ThePointOfLoopTool::Value3d(LoopPnt), reversed, + wd2[I].ustart, wd2[I].vstart); + + if (IsPointOnLine(previousPoint, BornInf, BornSup, Rsnld, aFuncForDuplicate)) + { + wd2[I].etat = -wd2[I].etat; //mark point as processed + continue; + } + previousd3d = ThePointOfLoopTool::Direction3d(LoopPnt); previousd2d = ThePointOfLoopTool::Direction2d(LoopPnt); @@ -437,9 +446,11 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, if (wd2[I].etat > 12) { //line closed good case CurrentLine->AddStatusFirstLast(Standard_True, Standard_False,Standard_False); - CurrentLine->AddPoint(CurrentLine->Value(1)); + CurrentLine->AddPoint(CurrentLine->Value(1)); } - else if (N >0) { //point of stop given at input + else if ((N >0) && (Pnts1.Length() >= N)) + { + //point of stop given at input PathPnt = Pnts1.Value(N); CurrentLine->AddStatusLast(Standard_True,N,PathPnt); AddPointInCurrentLine(N,PathPnt,CurrentLine); diff --git a/src/IntWalk/IntWalk_IWalking_5.gxx b/src/IntWalk/IntWalk_IWalking_5.gxx index 3d5d1fe30f..30d426c992 100644 --- a/src/IntWalk/IntWalk_IWalking_5.gxx +++ b/src/IntWalk/IntWalk_IWalking_5.gxx @@ -74,18 +74,19 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection gp_Vec Corde(previousPoint.Value(), sp.Point()); - const Standard_Real Norme = Corde.SquareMagnitude(), - aTol = epsilon*Precision::PConfusion(); + const Standard_Real Norme = Corde.SquareMagnitude(); - //if ((++NbPointsConfondusConsecutifs < 10) && (Norme <= epsilon)) { // the square is already taken in the constructor - if ((Norme <= epsilon) && ((Duv <= aTol) || (StatusPrecedent != IntWalk_OK))) + if ((Norme <= 4.0*Precision::SquareConfusion()) && + ((Duv <= Precision::SquarePConfusion()) || (StatusPrecedent != IntWalk_OK))) { // the square is already taken in the constructor aStatus = IntWalk_PointConfondu; - if (StatusPrecedent == IntWalk_PasTropGrand) { + if (StatusPrecedent == IntWalk_PasTropGrand) + { return IntWalk_ArretSurPointPrecedent; } } - else { + else + { Standard_Real Cosi = Corde * previousd3d; Standard_Real Cosi2 = 0.0; diff --git a/src/IntWalk/IntWalk_IWalking_6.gxx b/src/IntWalk/IntWalk_IWalking_6.gxx index e9cc440b4c..259aa9f194 100644 --- a/src/IntWalk/IntWalk_IWalking_6.gxx +++ b/src/IntWalk/IntWalk_IWalking_6.gxx @@ -47,26 +47,25 @@ void IntWalk_IWalking::MakeWalkingPoint // but F is updated according to U and V // Case == other : the exception Standard_Failure is raised. - if (Case == 1) - Psol.SetValue(sp.Point(),reversed, U, V); - else if (Case == 2) { - Psol.SetValue(sp.Point(),reversed, U, V); + if ((Case == 1) || (Case == 2)) + { + Psol.SetValue(sp.Point(), reversed, U, V); } - else if (Case == 11 || Case == 12 ) { + else if (Case == 11 || Case == 12) + { Standard_Real aUV[2], aFF[1], aDD[1][2]; - math_Vector UV(aUV,1, 2); - math_Vector FF(aFF,1, 1); - math_Matrix DD(aDD,1, 1, 1, 2); + math_Vector UV(aUV, 1, 2); + math_Vector FF(aFF, 1, 1); + math_Matrix DD(aDD, 1, 1, 1, 2); UV(1) = U; UV(2) = V; sp.Values(UV, FF, DD); - MakeWalkingPoint(Case - 10, U, V, sp, Psol); + MakeWalkingPoint(Case - 10, U, V, sp, Psol); } - else { + else + { throw Standard_ConstructionError(); } - - } @@ -167,3 +166,103 @@ Standard_Boolean IntWalk_IWalking::IsPointOnLine(const gp_Pnt2d& theP2d, } return Standard_False; } + +//================================================================================== +//function : IsPointOnLine +//purpose : Projects thePOn2S on the nearest segment of the already computed line. +// The retrieved projection point (aPa) is refined using theSolver. +// After the refinement, we will obtain a point aPb. +// If thePOn2S is quite far from aPb then thePOn2S is not +// in the line. +// Every already computed line is checked. +//================================================================================== +Standard_Boolean IntWalk_IWalking::IsPointOnLine(const IntSurf_PntOn2S& thePOn2S, + const math_Vector& theInfBounds, + const math_Vector& theSupBounds, + math_FunctionSetRoot& theSolver, + TheIWFunction& theFunc) +{ + const gp_Pnt &aP3d = thePOn2S.Value(); + + for (Standard_Integer aLIdx = 1; aLIdx <= lines.Length(); aLIdx++) + { + const Handle(IntSurf_LineOn2S) &aL = lines(aLIdx)->Line(); + + if (aL->IsOutBox(aP3d)) + continue; + + //Look for the nearest segment + Standard_Real aUMin = 0.0, aVMin = 0.0; + Standard_Real aMinSqDist = RealLast(); + for (Standard_Integer aPtIdx = 1; aPtIdx < aL->NbPoints(); aPtIdx++) + { + const gp_Pnt &aP1 = aL->Value(aPtIdx).Value(); + const gp_Pnt &aP2 = aL->Value(aPtIdx + 1).Value(); + + const gp_XYZ aP1P(aP3d.XYZ() - aP1.XYZ()); + const gp_XYZ aP1P2(aP2.XYZ() - aP1.XYZ()); + + const Standard_Real aSq12 = aP1P2.SquareModulus(); + + if (aSq12 < gp::Resolution()) + continue; + + const Standard_Real aDP = aP1P.Dot(aP1P2); + + Standard_Real aSqD = RealLast(); + if (aDP < 0.0) + { + //aSqD = aP1P.SquareModulus(); + continue; + } + else if (aDP > aSq12) + { + //aSqD = (aP3d.XYZ() - aP2.XYZ()).SquareModulus(); + continue; + } + else + { + aSqD = aP1P.CrossSquareMagnitude(aP1P2) / aSq12; + } + + if (aSqD < aMinSqDist) + { + aMinSqDist = aSqD; + + const Standard_Real aL1 = aDP / aSq12; + const Standard_Real aL2 = 1.0 - aL1; + + Standard_Real aU1, aV1, aU2, aV2; + aL->Value(aPtIdx).ParametersOnSurface(reversed, aU1, aV1); + aL->Value(aPtIdx + 1).ParametersOnSurface(reversed, aU2, aV2); + + aUMin = aL1*aU2 + aL2*aU1; + aVMin = aL1*aV2 + aL2*aV1; + } + } + + if (aMinSqDist == RealLast()) + continue; + + math_Vector aVecPrms(1, 2); + aVecPrms(1) = aUMin; + aVecPrms(2) = aVMin; + theSolver.Perform(theFunc, aVecPrms, theInfBounds, theSupBounds); + if (!theSolver.IsDone()) + continue; + + theSolver.Root(aVecPrms); + + const gp_Pnt aPa(theFunc.PSurface()->Value(aUMin, aVMin)), + aPb(theFunc.PSurface()->Value(aVecPrms(1), aVecPrms(2))); + const Standard_Real aSqD1 = aPb.SquareDistance(aP3d); + const Standard_Real aSqD2 = aPa.SquareDistance(aPb); + + if (aSqD1 < 4.0*aSqD2) + { + return Standard_True; + } + } + + return Standard_False; +} diff --git a/src/IntWalk/IntWalk_PWalking.cxx b/src/IntWalk/IntWalk_PWalking.cxx index 1387158c26..e772631af4 100644 --- a/src/IntWalk/IntWalk_PWalking.cxx +++ b/src/IntWalk/IntWalk_PWalking.cxx @@ -202,10 +202,15 @@ IntWalk_PWalking::IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1, done(Standard_True), close(Standard_False), +tgfirst(Standard_False), +tglast(Standard_False), +myTangentIdx(0), fleche(Deflection), +pasMax(0.0), tolconf(Epsilon), myTolTang(TolTangency), sensCheminement(1), +previoustg(Standard_False), myIntersectionOn2S(Caro1,Caro2,TolTangency), STATIC_BLOCAGE_SUR_PAS_TROP_GRAND(0), STATIC_PRECEDENT_INFLEXION(0) @@ -758,10 +763,13 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, Standard_Integer LevelOfIterWithoutAppend = -1; // - const Standard_Real aTol[4] = { Epsilon(u1max - u1min), - Epsilon(v1max - v1min), - Epsilon(u2max - u2min), - Epsilon(v2max - v2min)}; + const Standard_Real aTol[4] = { Epsilon(UM1 - Um1), + Epsilon(VM1 - Vm1), + Epsilon(UM2 - Um2), + Epsilon(VM2 - Vm2)}; + + Standard_Integer aPrevNbPoints = line->NbPoints(); + Arrive = Standard_False; while(!Arrive) //010 { @@ -853,8 +861,8 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, Standard_Real aNewPnt[4], anAbsParamDist[4]; myIntersectionOn2S.Point().Parameters(aNewPnt[0], aNewPnt[1], aNewPnt[2], aNewPnt[3]); - const Standard_Real aParMin[4] = {u1min, v1min, u2min, v2min}; - const Standard_Real aParMax[4] = {u1max, v1max, u2max, v2max}; + const Standard_Real aParMin[4] = {Um1, Vm1, Um2, Vm2}; + const Standard_Real aParMax[4] = {UM1, VM1, UM2, VM2}; for(Standard_Integer i = 0; i < 4; i++) { @@ -864,12 +872,13 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, aNewPnt[i] = aParMax[i]; } - if (aNewPnt[0] < u1min || aNewPnt[0] > u1max || - aNewPnt[1] < v1min || aNewPnt[1] > v1max || - aNewPnt[2] < u2min || aNewPnt[2] > u2max || - aNewPnt[3] < v2min || aNewPnt[3] > v2max) + if (aNewPnt[0] < Um1 || aNewPnt[0] > UM1 || + aNewPnt[1] < Vm1 || aNewPnt[1] > VM1 || + aNewPnt[2] < Um2 || aNewPnt[2] > UM2 || + aNewPnt[3] < Vm2 || aNewPnt[3] > VM2) { - break; // Out of borders, handle this later. + // Out of borders, process it later. + break; } myIntersectionOn2S.ChangePoint().SetValue(aNewPnt[0], @@ -959,7 +968,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, LevelOfEmptyInmyIntersectionOn2S=0; if(LevelOfIterWithoutAppend < 10) { - aStatus = TestDeflection(ChoixIso); + aStatus = TestDeflection(ChoixIso, aStatus); } else { @@ -1098,7 +1107,13 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, if(aDelta > Epsilon(pasInit[i])) { pasInit[i] -= aDelta; - LevelOfIterWithoutAppend=0; + if ((aPrevStatus != IntWalk_StepTooSmall) && + (line->NbPoints() != aPrevNbPoints)) + { + LevelOfIterWithoutAppend = 0; + } + + aPrevNbPoints = line->NbPoints(); } } } @@ -1173,8 +1188,13 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, // StepTooSmall --> Increase step --> PasTropGrand...) // nullify LevelOfIterWithoutAppend only if the condition // is satisfied: - if (aPrevStatus != IntWalk_PasTropGrand) + if ((aPrevStatus != IntWalk_PasTropGrand) && + (line->NbPoints() != aPrevNbPoints)) + { LevelOfIterWithoutAppend = 0; + } + + aPrevNbPoints = line->NbPoints(); break; } @@ -1195,7 +1215,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, { Arrive=Standard_True; #ifdef OCCT_DEBUG - cout << "IntWalk_PWalking_1.gxx: Problems with intersection"< 20) || (nbEqualPoints > 20)) { #ifdef OCCT_DEBUG - cout<<"Infinite loop detected. Stop iterations (IntWalk_PWalking_1.gxx)" << endl; + std::cout<<"Infinite loop detected. Stop iterations (IntWalk_PWalking_1.gxx)" << std::endl; #endif bStop = Standard_True; break; @@ -1740,7 +1760,7 @@ Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsop return bOutOfTangentZone; } - aStatus = TestDeflection(ChoixIso); + aStatus = TestDeflection(ChoixIso, aStatus); if(aStatus == IntWalk_OK) { @@ -2981,7 +3001,8 @@ namespace { static const Standard_Real d = 7.0; } -IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection(const IntImp_ConstIsoparametric choixIso) +IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection(const IntImp_ConstIsoparametric choixIso, + const IntWalk_StatusDeflection theStatus) // test if vector is observed by calculating an increase of vector // or the previous point and its tangent, the new calculated point and its @@ -3376,7 +3397,8 @@ IntWalk_StatusDeflection IntWalk_PWalking::TestDeflection(const IntImp_ConstIso const Standard_Real anInvSqAbsArcDeflMin = 4.0*anInvSqAbsArcDeflMax; const Standard_Real aSinB2Min = 1.0 - 2.0/(1.0 + anInvSqAbsArcDeflMin); - if((aSinB2Min < 0.0) || (aCosBetweenTangent >= 2.0 * aSinB2Min * aSinB2Min - 1.0)) + if (theStatus != IntWalk_PasTropGrand && + ((aSinB2Min < 0.0) || (aCosBetweenTangent >= 2.0 * aSinB2Min * aSinB2Min - 1.0))) {//Real deflection is less than tolconf/2.0 aStatus = IntWalk_StepTooSmall; } diff --git a/src/IntWalk/IntWalk_PWalking.hxx b/src/IntWalk/IntWalk_PWalking.hxx index e3ac4bbc3d..fcadb1f242 100644 --- a/src/IntWalk/IntWalk_PWalking.hxx +++ b/src/IntWalk/IntWalk_PWalking.hxx @@ -66,7 +66,12 @@ public: //! border of one of the domains. If an open line //! stops at the middle of a domain, one stops at the tangent point. //! Epsilon is SquareTolerance of points confusion. - Standard_EXPORT IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1, const Handle(Adaptor3d_HSurface)& Caro2, const Standard_Real TolTangency, const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Increment); + Standard_EXPORT IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1, + const Handle(Adaptor3d_HSurface)& Caro2, + const Standard_Real TolTangency, + const Standard_Real Epsilon, + const Standard_Real Deflection, + const Standard_Real Increment); //! Returns the intersection line containing the exact //! point Poin. This line is a polygonal line. @@ -81,7 +86,16 @@ public: //! border of one of the domains. If an open line //! stops at the middle of a domain, one stops at the tangent point. //! Epsilon is SquareTolerance of points confusion. - Standard_EXPORT IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1, const Handle(Adaptor3d_HSurface)& Caro2, const Standard_Real TolTangency, const Standard_Real Epsilon, const Standard_Real Deflection, const Standard_Real Increment, const Standard_Real U1, const Standard_Real V1, const Standard_Real U2, const Standard_Real V2); + Standard_EXPORT IntWalk_PWalking(const Handle(Adaptor3d_HSurface)& Caro1, + const Handle(Adaptor3d_HSurface)& Caro2, + const Standard_Real TolTangency, + const Standard_Real Epsilon, + const Standard_Real Deflection, + const Standard_Real Increment, + const Standard_Real U1, + const Standard_Real V1, + const Standard_Real U2, + const Standard_Real V2); //! calculate the line of intersection Standard_EXPORT void Perform (const TColStd_Array1OfReal& ParDep); @@ -91,10 +105,19 @@ public: //! v. (if this data is not presented as in the //! previous method, the initial steps are calculated //! starting from min and max uv of faces). - Standard_EXPORT void Perform (const TColStd_Array1OfReal& ParDep, const Standard_Real u1min, const Standard_Real v1min, const Standard_Real u2min, const Standard_Real v2min, const Standard_Real u1max, const Standard_Real v1max, const Standard_Real u2max, const Standard_Real v2max); + Standard_EXPORT void Perform (const TColStd_Array1OfReal& ParDep, + const Standard_Real u1min, + const Standard_Real v1min, + const Standard_Real u2min, + const Standard_Real v2min, + const Standard_Real u1max, + const Standard_Real v1max, + const Standard_Real u2max, + const Standard_Real v2max); //! calculate the first point of a line of intersection - Standard_EXPORT Standard_Boolean PerformFirstPoint (const TColStd_Array1OfReal& ParDep, IntSurf_PntOn2S& FirstPoint); + Standard_EXPORT Standard_Boolean PerformFirstPoint (const TColStd_Array1OfReal& ParDep, + IntSurf_PntOn2S& FirstPoint); //! Returns true if the calculus was successful. Standard_Boolean IsDone() const; @@ -126,11 +149,16 @@ public: const gp_Dir& TangentAtLine (Standard_Integer& Index) const; - Standard_EXPORT IntWalk_StatusDeflection TestDeflection (const IntImp_ConstIsoparametric ChoixIso) ; + Standard_EXPORT IntWalk_StatusDeflection TestDeflection (const IntImp_ConstIsoparametric ChoixIso, + const IntWalk_StatusDeflection theStatus); - Standard_EXPORT Standard_Boolean TestArret (const Standard_Boolean DejaReparti, TColStd_Array1OfReal& Param, IntImp_ConstIsoparametric& ChoixIso); + Standard_EXPORT Standard_Boolean TestArret (const Standard_Boolean DejaReparti, + TColStd_Array1OfReal& Param, + IntImp_ConstIsoparametric& ChoixIso); - Standard_EXPORT void RepartirOuDiviser (Standard_Boolean& DejaReparti, IntImp_ConstIsoparametric& ChoixIso, Standard_Boolean& Arrive); + Standard_EXPORT void RepartirOuDiviser (Standard_Boolean& DejaReparti, + IntImp_ConstIsoparametric& ChoixIso, + Standard_Boolean& Arrive); //! Inserts thePOn2S in the end of line void AddAPoint (const IntSurf_PntOn2S& thePOn2S); @@ -157,9 +185,12 @@ public: line->RemovePoint(anIdx); } - Standard_EXPORT Standard_Boolean PutToBoundary (const Handle(Adaptor3d_HSurface)& theASurf1, const Handle(Adaptor3d_HSurface)& theASurf2); + Standard_EXPORT Standard_Boolean PutToBoundary (const Handle(Adaptor3d_HSurface)& theASurf1, + const Handle(Adaptor3d_HSurface)& theASurf2); - Standard_EXPORT Standard_Boolean SeekAdditionalPoints (const Handle(Adaptor3d_HSurface)& theASurf1, const Handle(Adaptor3d_HSurface)& theASurf2, const Standard_Integer theMinNbPoints); + Standard_EXPORT Standard_Boolean SeekAdditionalPoints (const Handle(Adaptor3d_HSurface)& theASurf1, + const Handle(Adaptor3d_HSurface)& theASurf2, + const Standard_Integer theMinNbPoints); Standard_Real MaxStep(Standard_Integer theIndex) { diff --git a/src/IntWalk/IntWalk_PWalking.lxx b/src/IntWalk/IntWalk_PWalking.lxx index b9216b56f8..fe5ea6f1d4 100644 --- a/src/IntWalk/IntWalk_PWalking.lxx +++ b/src/IntWalk/IntWalk_PWalking.lxx @@ -65,15 +65,17 @@ inline const gp_Dir& IntWalk_PWalking::TangentAtLine(Standard_Integer& theIndex) inline void IntWalk_PWalking::AddAPoint(const IntSurf_PntOn2S& POn2S) { #if REGLAGE - Standard_Integer n=theLine->NbPoints(); + Standard_Integer n=line->NbPoints()+1; + if (n == 1) + { + std::cout << "Dump of WL" << std::endl; + } + if(n) { - gp_Vec V(POn2S.Value(),theLine->Value(n).Value()); Standard_Real u1,v1,u2,v2; - Standard_Real U1,V1,U2,V2; POn2S.Parameters(u1,v1,u2,v2); - theLine->Value(n).Parameters(U1,V1,U2,V2); - printf("\n%3d: (%10.5g)(%+12.5g %+12.5g %+12.5g) (%+12.5g %+12.5g) (%+12.5g %+12.5g)",n, - V.Magnitude(),V.X(),V.Y(),V.Z(),U1-u1,V1-v1,U2-u2,V2-v2); + printf("point p%d %+10.20f %+10.20f %+10.20f\n", + n, POn2S.Value().X(), POn2S.Value().Y(), POn2S.Value().Z()); fflush(stdout); } #endif