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_ImpPrmIntersection.cxx b/src/IntPatch/IntPatch_ImpPrmIntersection.cxx index a54ded5135..5c74b941ee 100644 --- a/src/IntPatch/IntPatch_ImpPrmIntersection.cxx +++ b/src/IntPatch/IntPatch_ImpPrmIntersection.cxx @@ -686,13 +686,9 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur NbPointDep=seqpdep.Length(); // if (NbPointDep || NbPointIns) { - IntPatch_TheIWalking iwalk(TolTang,Fleche,Pas); - if (!reversed) { - iwalk.Perform(seqpdep,seqpins,Func,Surf2); - } - else { - iwalk.Perform(seqpdep,seqpins,Func,Surf1,Standard_True); - } + IntPatch_TheIWalking iwalk(TolTang, Fleche, Pas); + iwalk.Perform(seqpdep, seqpins, Func, reversed ? Surf1 : Surf2, reversed); + if(!iwalk.IsDone()) { return; } diff --git a/src/IntPatch/IntPatch_PointLine.hxx b/src/IntPatch/IntPatch_PointLine.hxx index ec0a78a869..1852a86dc2 100644 --- a/src/IntPatch/IntPatch_PointLine.hxx +++ b/src/IntPatch/IntPatch_PointLine.hxx @@ -20,6 +20,8 @@ #include #include +class gp_Pnt; +class gp_Pnt2d; class IntSurf_PntOn2S; class IntSurf_LineOn2S; class IntPatch_Point; @@ -67,6 +69,17 @@ public: //! Returns set of intersection points Standard_EXPORT virtual Handle(IntSurf_LineOn2S) Curve() const = 0; + //! Returns TRUE if P1 is out of the box built from + //! the points on 1st surface + Standard_EXPORT virtual Standard_Boolean IsOutSurf1Box(const gp_Pnt2d& P1) const = 0; + + //! Returns TRUE if P2 is out of the box built from + //! the points on 2nd surface + Standard_EXPORT virtual Standard_Boolean IsOutSurf2Box(const gp_Pnt2d& P2) const = 0; + + //! Returns TRUE if P is out of the box built from 3D-points. + Standard_EXPORT virtual Standard_Boolean IsOutBox(const gp_Pnt& P) const = 0; + //! Returns the radius of curvature of //! the intersection line in given point. //! Returns negative value if computation is not possible. @@ -75,7 +88,6 @@ public: const Handle(Adaptor3d_HSurface)& theS2, const IntSurf_PntOn2S& theUVPoint); - DEFINE_STANDARD_RTTIEXT(IntPatch_PointLine,IntPatch_Line) protected: diff --git a/src/IntPatch/IntPatch_RLine.hxx b/src/IntPatch/IntPatch_RLine.hxx index 5532d0a43f..84321b0f52 100644 --- a/src/IntPatch/IntPatch_RLine.hxx +++ b/src/IntPatch/IntPatch_RLine.hxx @@ -25,10 +25,10 @@ #include #include #include -#include +#include #include +#include class Adaptor2d_HCurve2d; -class IntSurf_LineOn2S; class Standard_DomainError; class Standard_OutOfRange; class IntPatch_Point; @@ -152,6 +152,26 @@ public: //! Returns set of intersection points virtual Handle(IntSurf_LineOn2S) Curve() const Standard_OVERRIDE; + //! Returns TRUE if theP is out of the box built from + //! the points on 1st surface + virtual Standard_Boolean IsOutSurf1Box(const gp_Pnt2d& theP) const Standard_OVERRIDE + { + return curv->IsOutSurf1Box(theP); + } + + //! Returns TRUE if theP is out of the box built from + //! the points on 2nd surface + virtual Standard_Boolean IsOutSurf2Box(const gp_Pnt2d& theP) const Standard_OVERRIDE + { + return curv->IsOutSurf2Box(theP); + } + + //! Returns TRUE if theP is out of the box built from 3D-points. + virtual Standard_Boolean IsOutBox(const gp_Pnt& theP) const Standard_OVERRIDE + { + return curv->IsOutBox(theP); + } + //! Removes vertices from the line (i.e. cleans svtx member) virtual void ClearVertexes() Standard_OVERRIDE { 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/IntPatch/IntPatch_WLine.cxx b/src/IntPatch/IntPatch_WLine.cxx index b79d125907..9727293c63 100644 --- a/src/IntPatch/IntPatch_WLine.cxx +++ b/src/IntPatch/IntPatch_WLine.cxx @@ -46,9 +46,6 @@ IntPatch_WLine::IntPatch_WLine (const Handle(IntSurf_LineOn2S)& Line, { typ = IntPatch_Walking; curv = Line; - Buv1.SetWhole(); - Buv2.SetWhole(); - Bxyz.SetWhole(); u1period=v1period=u2period=v2period=0.0; } @@ -63,9 +60,6 @@ IntPatch_WLine::IntPatch_WLine (const Handle(IntSurf_LineOn2S)& Line, { typ = IntPatch_Walking; curv = Line; - Buv1.SetWhole(); - Buv2.SetWhole(); - Bxyz.SetWhole(); u1period=v1period=u2period=v2period=0.0; } @@ -78,9 +72,6 @@ IntPatch_WLine::IntPatch_WLine (const Handle(IntSurf_LineOn2S)& Line, { typ = IntPatch_Walking; curv = Line; - Buv1.SetWhole(); - Buv2.SetWhole(); - Bxyz.SetWhole(); u1period=v1period=u2period=v2period=0.0; } @@ -947,87 +938,6 @@ void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol) } - - -Standard_Boolean IntPatch_WLine::IsOutSurf1Box(const gp_Pnt2d& P1uv) { - if(Buv1.IsWhole()) { - Standard_Integer n=NbPnts(); - Standard_Real pu1,pu2,pv1,pv2; - Buv1.SetVoid(); - for(Standard_Integer i=1;i<=n;i++) { - curv->Value(i).Parameters(pu1,pv1,pu2,pv2); - Buv1.Add(gp_Pnt2d(pu1,pv1)); - } - Buv1.Get(pu1,pv1,pu2,pv2); - pu2-=pu1; - pv2-=pv1; - if(pu2>pv2) { - Buv1.Enlarge(pu2*0.01); - } - else { - Buv1.Enlarge(pv2*0.01); - } - } - Standard_Boolean out=Buv1.IsOut(P1uv); - return(out); -} - -Standard_Boolean IntPatch_WLine::IsOutSurf2Box(const gp_Pnt2d& P2uv) { - if(Buv2.IsWhole()) { - Standard_Integer n=NbPnts(); - Standard_Real pu1,pu2,pv1,pv2; - Buv2.SetVoid(); - for(Standard_Integer i=1;i<=n;i++) { - curv->Value(i).Parameters(pu1,pv1,pu2,pv2); - Buv2.Add(gp_Pnt2d(pu2,pv2)); - } - Buv2.Get(pu1,pv1,pu2,pv2); - pu2-=pu1; - pv2-=pv1; - if(pu2>pv2) { - Buv2.Enlarge(pu2*0.01); - } - else { - Buv2.Enlarge(pv2*0.01); - } - } - Standard_Boolean out=Buv2.IsOut(P2uv); - return(out); -} - -Standard_Boolean IntPatch_WLine::IsOutBox(const gp_Pnt& Pxyz) { - if(Bxyz.IsWhole()) { - Standard_Integer n=NbPnts(); - Bxyz.SetVoid(); - for(Standard_Integer i=1;i<=n;i++) { - gp_Pnt P=curv->Value(i).Value(); - Bxyz.Add(P); - } - Standard_Real x0,y0,z0,x1,y1,z1; - Bxyz.Get(x0,y0,z0,x1,y1,z1); - x1-=x0; y1-=y0; z1-=z0; - if(x1>y1) { - if(x1>z1) { - Bxyz.Enlarge(x1*0.01); - } - else { - Bxyz.Enlarge(z1*0.01); - } - } - else { - if(y1>z1) { - Bxyz.Enlarge(y1*0.01); - } - else { - Bxyz.Enlarge(z1*0.01); - } - } - } - Standard_Boolean out=Bxyz.IsOut(Pxyz); - return(out); -} - - Standard_Boolean IntPatch_WLine::HasArcOnS1() const { return(hasArcOnS1); } diff --git a/src/IntPatch/IntPatch_WLine.hxx b/src/IntPatch/IntPatch_WLine.hxx index 64eba46b29..1443839950 100644 --- a/src/IntPatch/IntPatch_WLine.hxx +++ b/src/IntPatch/IntPatch_WLine.hxx @@ -23,13 +23,11 @@ #include #include #include -#include -#include #include #include -#include +#include #include -class IntSurf_LineOn2S; +#include class Adaptor2d_HCurve2d; class Standard_OutOfRange; class Standard_DomainError; @@ -129,12 +127,26 @@ public: //! Returns set of intersection points Standard_EXPORT virtual Handle(IntSurf_LineOn2S) Curve() const Standard_OVERRIDE; - Standard_EXPORT Standard_Boolean IsOutSurf1Box (const gp_Pnt2d& P1); + //! Returns TRUE if theP is out of the box built from + //! the points on 1st surface + Standard_Boolean IsOutSurf1Box (const gp_Pnt2d& theP) const Standard_OVERRIDE + { + return curv->IsOutSurf1Box(theP); + } - Standard_EXPORT Standard_Boolean IsOutSurf2Box (const gp_Pnt2d& P1); - - Standard_EXPORT Standard_Boolean IsOutBox (const gp_Pnt& P); + //! Returns TRUE if theP is out of the box built from + //! the points on 2nd surface + Standard_Boolean IsOutSurf2Box(const gp_Pnt2d& theP) const Standard_OVERRIDE + { + return curv->IsOutSurf2Box(theP); + } + //! Returns TRUE if theP is out of the box built from 3D-points. + Standard_Boolean IsOutBox(const gp_Pnt& theP) const Standard_OVERRIDE + { + return curv->IsOutBox(theP); + } + Standard_EXPORT void SetPeriod (const Standard_Real pu1, const Standard_Real pv1, const Standard_Real pu2, const Standard_Real pv2); Standard_EXPORT Standard_Real U1Period() const; @@ -200,9 +212,6 @@ private: Standard_Integer indf; Standard_Integer indl; IntPatch_SequenceOfPoint svtx; - Bnd_Box2d Buv1; - Bnd_Box2d Buv2; - Bnd_Box Bxyz; Standard_Real u1period; Standard_Real v1period; Standard_Real u2period; diff --git a/src/IntSurf/IntSurf_LineOn2S.cxx b/src/IntSurf/IntSurf_LineOn2S.cxx index 1b5ce0d8f5..be46727c20 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,124 @@ 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); +} + diff --git a/src/IntSurf/IntSurf_LineOn2S.hxx b/src/IntSurf/IntSurf_LineOn2S.hxx index be4aa1654d..0ba15db35a 100644 --- a/src/IntSurf/IntSurf_LineOn2S.hxx +++ b/src/IntSurf/IntSurf_LineOn2S.hxx @@ -20,6 +20,8 @@ #include #include +#include +#include #include #include #include @@ -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..ddf1a8680f 100644 --- a/src/IntSurf/IntSurf_LineOn2S.lxx +++ b/src/IntSurf/IntSurf_LineOn2S.lxx @@ -18,8 +18,21 @@ inline 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)); + } } @@ -53,10 +66,22 @@ inline void IntSurf_LineOn2S::SetUV(const Standard_Integer Index, 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)); + } } inline void IntSurf_LineOn2S::Clear () { mySeq.Clear(); + myBuv1.SetWhole(); + myBuv2.SetWhole(); + myBxyz.SetWhole(); } diff --git a/src/IntWalk/IntWalk_IWalking_3.gxx b/src/IntWalk/IntWalk_IWalking_3.gxx index 0ae3d9398c..85af62c398 100644 --- a/src/IntWalk/IntWalk_IWalking_3.gxx +++ b/src/IntWalk/IntWalk_IWalking_3.gxx @@ -99,20 +99,29 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult, } // modified by NIZHNY-MKK Fri Oct 27 12:32:38 2000.END + TheIWFunction aFuncForDuplicate = Func; + for (I = 1; I <= nbPath; I++) { //start point of the progression // if (wd1[I].etat > 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..0824c58210 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); 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/tests/bugs/modalg_7/bug29866 b/tests/bugs/modalg_7/bug29866 new file mode 100644 index 0000000000..53ad0a9535 --- /dev/null +++ b/tests/bugs/modalg_7/bug29866 @@ -0,0 +1,73 @@ +puts "================" +puts "OCC29866: Intersector returns two overlapped curves as a result" +puts "================" +puts "" + +set GoodNbCurv 1 + +binrestore [locate_data_file bug29866_sur1.bin] f1 +binrestore [locate_data_file bug29866_sur2.bin] f2 + +mksurface s1 f1 +mksurface s2 f2 +trim s2 s2 + +intersect result s1 s2 + +set che [whatis result] +set ind [string first "3d curve" $che] +if {${ind} >= 0} { + #Only variable "result" exists + renamevar result result_1 +} + +set ic 1 +set AllowRepeate 1 +while { $AllowRepeate != 0 } { + set che [whatis result_$ic] + set ind [string first "3d curve" $che] + if {${ind} < 0} { + set AllowRepeate 0 + } else { + display result_$ic + + bounds result_$ic U1 U2 + + dump U1 U2 + + if {[dval U2-U1] < 1.0e-9} { + puts "Error: Wrong curve's range!" + } + + xdistcs result_$ic s1 U1 U2 10 4.0e-5 + xdistcs result_$ic s2 U1 U2 10 1.0e-5 + + for { set ip [expr $ic-1] } { $ip > 0 } { incr ip -1 } { + mkedge e1 result_$ic + mkedge e2 result_$ip + + set coe [checkoverlapedges e1 e2 5.0e-5] + + puts "result_$ic <-> result_$ip: $coe" + if { [regexp "Edges is not overlaped" $coe] != 1 } { + puts "Error: result_$ic and result_$ip are overlaped" + } + } + + incr ic + } +} + +if {[expr {$ic - 1}] == $GoodNbCurv} { + puts "OK: Number of curves is good!" + checklength result_1 -l 2.6307272714501035 +} else { + puts "Error: $GoodNbCurv curves are expected but [expr {$ic - 1}] are found!" +} + +smallview +don result* +fit +clear +don s1 s2 result* +checkview -screenshot -2d -path ${imagedir}/${test_image}.png \ No newline at end of file