]> OCCT Git - occt-copy.git/commitdiff
0032066: Modeling Algorithms - Incorrect result of Boolean CUT operation
authorazv <azv@opencascade.com>
Fri, 19 Feb 2021 19:24:50 +0000 (22:24 +0300)
committerazv <azv@opencascade.com>
Sat, 20 Feb 2021 16:55:49 +0000 (19:55 +0300)
Use IWalking algorithm of OCCT 7.5.0

17 files changed:
src/Contap/Contap_SurfFunction.cxx
src/Contap/Contap_SurfFunction.hxx
src/Contap/Contap_TheIWalking.hxx
src/IntPatch/IntPatch_TheIWalking.hxx
src/IntSurf/IntSurf_LineOn2S.cxx
src/IntSurf/IntSurf_LineOn2S.hxx
src/IntSurf/IntSurf_LineOn2S.lxx
src/IntWalk/IntWalk_IWLine.lxx
src/IntWalk/IntWalk_IWalking_1.gxx
src/IntWalk/IntWalk_IWalking_2.gxx
src/IntWalk/IntWalk_IWalking_3.gxx
src/IntWalk/IntWalk_IWalking_4.gxx
src/IntWalk/IntWalk_IWalking_5.gxx
src/IntWalk/IntWalk_IWalking_6.gxx
src/IntWalk/IntWalk_PWalking.cxx
src/IntWalk/IntWalk_PWalking.hxx
src/IntWalk/IntWalk_PWalking.lxx

index 6645815fb3e2499788a719a3d1840dd424bd64ee..819f626a4a4bad97c1d333d22ac16fad7f222670 100644 (file)
@@ -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)
 {
index 3adca5c691409ca45c670d0903eaf067e41d59c6..60a1662b20018cee39bee8f64706f16de91cea94 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 0919a42b63710d10101b061da19c9deb1539132d..88b6935986c33d1acd2bcd7a9c2d5ea60418ba7a 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 fce79efbe2ca6bc0620e7e113cd64f9b5ee63b1d..a58d30c7facae9dc09cbd6c4f92c1cd0e97f2506 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 1b5ce0d8f54549165216c105e16393cfde3eedca..162bab7e3ab37bc36a6b394a4f59f42c5bde3af2 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,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));
+  }
 }
index be4aa1654d3bd8c6c950fcf94476f4c3135f228f..1d78429ab4258da82775b18f13b3d749cb059466 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>
@@ -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;
 
 };
 
index 75ec13deebcd1331053589dbab0519be16d9ee96..76e96da10f6e8aaf69db85b422cf2d82b680df28 100644 (file)
 
 #include <IntSurf_PntOn2S.hxx>
 
-
-
-
-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();
 }
 
index 63f048599d7403d77c9b41f333434a565a8e460e..55d44a4325a8c72feddc3a5ebcd7bbe1c8e583e8 100644 (file)
@@ -19,7 +19,7 @@
 
 inline void IntWalk_IWLine::Cut(const Standard_Integer Index)
 {
-//--   cout<<" split : "<<Index<<endl;
+//--   std::cout<<" split : "<<Index<<std::endl;
   Handle(IntSurf_LineOn2S) lost = line->Split(Index);
 }
 
@@ -146,7 +146,7 @@ inline void IntWalk_IWLine::SetTangentVector (const gp_Vec& V,
   indextg = Index;
   vcttg = V;
   
-  //-- cout<<"\n IntWalk_IWLine::SetTangentVector : "<<V.X()<<" "<<V.Y()<<" "<<V.Z()<<"   Ind:"<<Index<<"  NbPts:"<<NbPoints()<<endl;
+  //-- std::cout<<"\n IntWalk_IWLine::SetTangentVector : "<<V.X()<<" "<<V.Y()<<" "<<V.Z()<<"   Ind:"<<Index<<"  NbPts:"<<NbPoints()<<std::endl;
   
 }
 
@@ -165,7 +165,7 @@ inline void IntWalk_IWLine::SetTangencyAtEnd
 inline const gp_Vec& IntWalk_IWLine::TangentVector
   (Standard_Integer& Index) const {
 //--    if(istgtend == Standard_False && istgtbeg == Standard_False) { 
-//--      cout<<" IntWalk_IWLine.lxx : Pb "<<endl;
+//--      std::cout<<" IntWalk_IWLine.lxx : Pb "<<std::endl;
 //--    }
   Index = indextg;
   return vcttg;
index 5d8ab336858bd7a2aef102d9ac29208ae66aa7e3..272da63b03b2c5bc9104b06071bd71b73b234514 100644 (file)
@@ -59,7 +59,7 @@ static Standard_Boolean IsTangentExtCheck(TheIWFunction& theFunc,
     if(!theFunc.Value(aX, aVal))
       continue;
 
-    if(aVal(1) > 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)
 {
 }
index 69db4cd3ed009d0b854c8d43aca275d9e74a84d0..8538123c60a451a49ef6bf0e71d4b050c8b15a5b 100644 (file)
@@ -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 "<<endl;
+             std::cout<<" IntWalk_IWalking_2.gxx : bizarrerie 30 10 97 "<<std::endl;
            }
 #endif
          }
index 0ae3d9398cdf7dd0bbca0396138f2cf2672cdcb8..1faa75ca9dc69b8fbe4c358cbec8f973aaab83fb 100644 (file)
@@ -74,7 +74,7 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
   Handle(IntWalk_TheIWLine)  CurrentLine;    // line under construction
   Standard_Boolean Tgtend;
 
-  IntWalk_StatusDeflection aStatus, StatusPrecedent;
+  IntWalk_StatusDeflection aStatus = IntWalk_OK, StatusPrecedent = IntWalk_OK;
   
   Standard_Integer NbDivision; 
   // number of divisions of step for each section
@@ -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 460346a647b4d319447888cf3afde6c24be19fb3..2add80f20e972c2c8594b31c2739f1c3b00c4a7c 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);
 
@@ -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);
index 3d5d1fe30f79e3645a590aceb7e6ccadf24783ad..30d426c992c42ef60e731b318fb504f1086c403c 100644 (file)
@@ -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;
 
index e9cc440b4cd63a2b36946a3f0f41ae11ff6e17e6..259aa9f1943b59cd4ad58c8a717753c74c882a6d 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;
+}
index 1387158c26d244507a793caa7a949f7cfb6b4813..e772631af471a745ef40a7c813d29a185f0215ee 100644 (file)
@@ -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"<<endl;
+              std::cout << "IntWalk_PWalking_1.gxx: Problems with intersection"<<std::endl;
 #endif
             }
 
@@ -1690,7 +1710,7 @@ Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsop
 
     if((nbIterWithoutAppend > 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;
       }
index e3ac4bbc3d8119ee8656aef6487a60cea055281b..fcadb1f24228ba5c6535e6d057dbc2026e6361eb 100644 (file)
@@ -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)
   {
index b9216b56f8df7c45c0be0bf3e1e6f0fdf14bc7da..fe5ea6f1d4817f5b7f04dedb7876380f47c6b2ea 100644 (file)
@@ -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