0029866: Intersector returns two overlapped curves as a result
authornbv <nbv@opencascade.com>
Tue, 3 Jul 2018 15:14:30 +0000 (18:14 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 13 Jul 2018 12:05:03 +0000 (15:05 +0300)
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.

15 files changed:
src/Contap/Contap_SurfFunction.hxx
src/Contap/Contap_TheIWalking.hxx
src/IntPatch/IntPatch_ImpPrmIntersection.cxx
src/IntPatch/IntPatch_PointLine.hxx
src/IntPatch/IntPatch_RLine.hxx
src/IntPatch/IntPatch_TheIWalking.hxx
src/IntPatch/IntPatch_WLine.cxx
src/IntPatch/IntPatch_WLine.hxx
src/IntSurf/IntSurf_LineOn2S.cxx
src/IntSurf/IntSurf_LineOn2S.hxx
src/IntSurf/IntSurf_LineOn2S.lxx
src/IntWalk/IntWalk_IWalking_3.gxx
src/IntWalk/IntWalk_IWalking_4.gxx
src/IntWalk/IntWalk_IWalking_6.gxx
tests/bugs/modalg_7/bug29866 [new file with mode: 0644]

index 3adca5c..60a1662 100644 (file)
@@ -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:
index 0919a42..88b6935 100644 (file)
@@ -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:
index a54ded5..5c74b94 100644 (file)
@@ -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;
     }
index ec0a78a..1852a86 100644 (file)
@@ -20,6 +20,8 @@
 #include <IntPatch_Line.hxx>
 #include <Standard_Type.hxx>
 
+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:
index 5532d0a..84321b0 100644 (file)
 #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;
@@ -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
   {
index fce79ef..a58d30c 100644 (file)
@@ -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);
 
 
 
index b79d125..9727293 100644 (file)
@@ -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);
 }
index 64eba46..1443839 100644 (file)
 #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;
@@ -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);
-  
-  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;
@@ -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;
index 1b5ce0d..be46727 100644 (file)
 
 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);
+}
+
index be4aa16..0ba15db 100644 (file)
@@ -20,6 +20,8 @@
 #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>
@@ -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;
 
 };
 
index 75ec13d..ddf1a86 100644 (file)
 
 
 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();
 }
 
index 0ae3d93..85af62c 100644 (file)
@@ -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
index 460346a..0824c58 100644 (file)
@@ -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);
 
index e9cc440..259aa9f 100644 (file)
@@ -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 (file)
index 0000000..53ad0a9
--- /dev/null
@@ -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