Since now a new WLine is not created if its start point lies in another earlier computed WLine. It allows avoiding creation of duplicate WLines in the intersection result.
<!break>
1. Methods IsOutSurf1Box(...), IsOutSurf2Box(...), IsOutBox(...) for classes IntSurf_LineOn2S and IntPatch_RLine have been created.
const Handle(Adaptor3d_HSurface)& Surface() const;
-
+ //! Method is entered for compatibility with IntPatch_TheSurfFunction.
+ const Handle(Adaptor3d_HSurface)& PSurface() const
+ {
+ return Surface();
+ }
protected:
class Contap_SurfFunction;
class Contap_TheIWLineOfTheIWalking;
class IntSurf_PntOn2S;
+class math_FunctionSetRoot;
class Contap_TheIWalking
{
//! 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:
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;
}
#include <IntPatch_Line.hxx>
#include <Standard_Type.hxx>
+class gp_Pnt;
+class gp_Pnt2d;
class IntSurf_PntOn2S;
class IntSurf_LineOn2S;
class IntPatch_Point;
//! 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.
const Handle(Adaptor3d_HSurface)& theS2,
const IntSurf_PntOn2S& theUVPoint);
-
DEFINE_STANDARD_RTTIEXT(IntPatch_PointLine,IntPatch_Line)
protected:
#include <Standard_Integer.hxx>
#include <IntPatch_SequenceOfPoint.hxx>
#include <IntPatch_PointLine.hxx>
-#include <IntSurf_TypeTrans.hxx>
+#include <IntSurf_LineOn2S.hxx>
#include <IntSurf_Situation.hxx>
+#include <IntSurf_TypeTrans.hxx>
class Adaptor2d_HCurve2d;
-class IntSurf_LineOn2S;
class Standard_DomainError;
class Standard_OutOfRange;
class IntPatch_Point;
//! 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
{
class IntPatch_TheSurfFunction;
class IntPatch_TheIWLineOfTheIWalking;
class IntSurf_PntOn2S;
+class math_FunctionSetRoot;
class IntPatch_TheIWalking
{
//! 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);
{
typ = IntPatch_Walking;
curv = Line;
- Buv1.SetWhole();
- Buv2.SetWhole();
- Bxyz.SetWhole();
u1period=v1period=u2period=v2period=0.0;
}
{
typ = IntPatch_Walking;
curv = Line;
- Buv1.SetWhole();
- Buv2.SetWhole();
- Bxyz.SetWhole();
u1period=v1period=u2period=v2period=0.0;
}
{
typ = IntPatch_Walking;
curv = Line;
- Buv1.SetWhole();
- Buv2.SetWhole();
- Bxyz.SetWhole();
u1period=v1period=u2period=v2period=0.0;
}
}
-
-
-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);
}
#include <Standard_Boolean.hxx>
#include <Standard_Integer.hxx>
#include <IntPatch_SequenceOfPoint.hxx>
-#include <Bnd_Box2d.hxx>
-#include <Bnd_Box.hxx>
#include <Standard_Real.hxx>
#include <IntPatch_PointLine.hxx>
-#include <IntSurf_TypeTrans.hxx>
+#include <IntSurf_LineOn2S.hxx>
#include <IntSurf_Situation.hxx>
-class IntSurf_LineOn2S;
+#include <IntSurf_TypeTrans.hxx>
class Adaptor2d_HCurve2d;
class Standard_OutOfRange;
class Standard_DomainError;
//! Returns set of intersection points
Standard_EXPORT virtual Handle(IntSurf_LineOn2S) Curve() const Standard_OVERRIDE;
- Standard_EXPORT Standard_Boolean IsOutSurf1Box (const gp_Pnt2d& P1);
-
- Standard_EXPORT Standard_Boolean IsOutSurf2Box (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 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;
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;
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)
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);
+}
+
#include <Standard.hxx>
#include <Standard_Type.hxx>
+#include <Bnd_Box.hxx>
+#include <Bnd_Box2d.hxx>
#include <IntSurf_SequenceOfPntOn2S.hxx>
#include <Standard_Transient.hxx>
#include <IntSurf_Allocator.hxx>
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)
IntSurf_SequenceOfPntOn2S mySeq;
-
+ Bnd_Box2d myBuv1;
+ Bnd_Box2d myBuv2;
+ Bnd_Box myBxyz;
};
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));
+ }
}
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();
}
}
// 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);
// 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
}
}
+ 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);
// 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();
}
-
-
}
}
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;
+}
--- /dev/null
+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