]> OCCT Git - occt-copy.git/commitdiff
0024694: Wrong processing of two surfaces (implicit and parametric) having tangential...
authorjgv <jgv@opencascade.com>
Thu, 14 Jan 2016 13:34:23 +0000 (16:34 +0300)
committerjgv <jgv@opencascade.com>
Thu, 14 Jan 2016 13:34:23 +0000 (16:34 +0300)
33 files changed:
src/BRepApprox/BRepApprox_TheZerImpFuncOfTheImpPrmSvSurfacesOfApprox.hxx
src/Contap/Contap_Contour.cxx
src/Contap/Contap_SurfFunction.hxx
src/Contap/Contap_SurfFunction.lxx
src/Contap/Contap_TheIWLineOfTheIWalking.hxx
src/Contap/Contap_TheIWalking.hxx
src/Contap/Contap_TheSearchInside.hxx
src/GeomInt/GeomInt_TheZerImpFuncOfTheImpPrmSvSurfacesOfWLApprox.hxx
src/IntImp/IntImp_ZerImpFunc.gxx
src/IntImp/IntImp_ZerImpFunc.lxx
src/IntPatch/IntPatch_ImpPrmIntersection.cxx
src/IntPatch/IntPatch_TheIWLineOfTheIWalking.hxx
src/IntPatch/IntPatch_TheIWalking.hxx
src/IntPatch/IntPatch_TheSearchInside.hxx
src/IntPatch/IntPatch_TheSurfFunction.hxx
src/IntStart/IntStart_SearchInside.gxx
src/IntStart/IntStart_SearchInside.lxx
src/IntSurf/IntSurf_PntOn2S.cxx
src/IntSurf/IntSurf_PntOn2S.hxx
src/IntSurf/IntSurf_QuadricTool.cxx
src/IntSurf/IntSurf_QuadricTool.hxx
src/IntSurf/IntSurf_QuadricTool.lxx
src/IntTools/IntTools_FaceFace.cxx
src/IntWalk/IntWalk_IWLine.gxx
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_StatusDeflection.hxx

index e863ce2a291fa743535506bb9b29ecd43a68826d..0b0dd78eda9ca5a1b20f2d59b60d3679edd59840 100644 (file)
@@ -81,10 +81,18 @@ public:
   
   Standard_EXPORT Standard_Boolean IsTangent();
   
+  Standard_EXPORT   Standard_Boolean IsTangentSmooth() ;
+  
     const gp_Vec& Direction3d();
   
     const gp_Dir2d& Direction2d();
   
+  Standard_EXPORT   Standard_Boolean DerivativesAndNormalOnPSurf (gp_Vec& D1U, gp_Vec& D1V, gp_Vec& Normal, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV) ;
+  
+  Standard_EXPORT   Standard_Boolean DerivativesAndNormalOnISurf (gp_Vec& D1U, gp_Vec& D1V, gp_Vec& Normal, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV)  const;
+  
+      Standard_Real SquareTangentError()  const;
+  
     const BRepAdaptor_Surface& PSurface() const;
   
     const IntSurf_Quadric& ISurface() const;
@@ -114,6 +122,8 @@ private:
   Standard_Real tgdu;
   Standard_Real tgdv;
   gp_Vec gradient;
+  gp_Vec d1u_isurf;
+  gp_Vec d1v_isurf;
   Standard_Boolean derived;
   gp_Vec d1u;
   gp_Vec d1v;
index 22cdbe038790b043d1e410b82ebae694ff00c7f3..9f1a348bdca28b79c93c8cb246ff780d3d6050ce 100644 (file)
@@ -1493,7 +1493,8 @@ void Contap_Contour::Perform
   if (seqpdep.Length() != 0 || seqpins.Length() != 0) {
 
     Contap_TheIWalking iwalk(Preci,Fleche,Pas);
-    iwalk.Perform(seqpdep,seqpins,mySFunc ,Surf);
+    IntSurf_SequenceOfInteriorPoint seqptang; //dummy
+    iwalk.Perform(seqpdep,seqpins,seqptang,mySFunc ,Surf);
     if(!iwalk.IsDone()) {
       return;
     }
index 3adca5c691409ca45c670d0903eaf067e41d59c6..a215ac062553aa52d55311274d26b3a0ceee18cf 100644 (file)
@@ -92,10 +92,18 @@ public:
   
   Standard_EXPORT Standard_Boolean IsTangent();
   
+      Standard_Boolean IsTangentSmooth() ;
+  
     const gp_Vec& Direction3d();
   
     const gp_Dir2d& Direction2d();
   
+      Standard_Boolean DerivativesAndNormalOnPSurf (gp_Vec& D1U, gp_Vec& D1V, gp_Vec& Normal, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV) ;
+  
+      Standard_Boolean DerivativesAndNormalOnISurf (gp_Vec& D1U, gp_Vec& D1V, gp_Vec& Normal, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV)  const;
+  
+      Standard_Real SquareTangentError()  const;
+  
     Contap_TFunction FunctionType() const;
   
     const gp_Pnt& Eye() const;
index bad8a0560cb32e6bd9808fe3ff7c7b0648f2b9eb..bccf6ccaa530922e559b731262ad429955246004 100644 (file)
@@ -100,6 +100,36 @@ inline Standard_Real Contap_SurfFunction::Angle () const
   return myAng;
 }
 
+inline Standard_Boolean Contap_SurfFunction::IsTangentSmooth()
+{
+  return Standard_False;
+}
+
+inline Standard_Boolean Contap_SurfFunction::DerivativesAndNormalOnPSurf(gp_Vec&,
+                                                                          gp_Vec&,
+                                                                          gp_Vec&,
+                                                                          gp_Vec&,
+                                                                          gp_Vec&,
+                                                                          gp_Vec&)
+{
+  return Standard_False;
+}
+
+inline Standard_Boolean Contap_SurfFunction::DerivativesAndNormalOnISurf(gp_Vec&,
+                                                                         gp_Vec&,
+                                                                         gp_Vec&,
+                                                                         gp_Vec&,
+                                                                         gp_Vec&,
+                                                                         gp_Vec&) const
+{
+  return Standard_False;
+}
+
+inline Standard_Real Contap_SurfFunction::SquareTangentError() const
+{
+  return 0.;
+}
+
 inline Contap_TFunction Contap_SurfFunction::FunctionType () const
 {
   return myType;
index 996ec9d89b2f6b1ddf80fa8904b047148ec9e761..536cb8e859d37dda859477b28af0c849a4c5b8c2 100644 (file)
@@ -76,6 +76,8 @@ public:
   
     void SetTangencyAtEnd (const Standard_Boolean IsTangent);
   
+    void SetTangency (const Standard_Boolean IsTangency) ;
+  
   //! Returns the number of points of the line (including first
   //! point and end point : see HasLastPoint and HasFirstPoint).
     Standard_Integer NbPoints() const;
@@ -139,6 +141,8 @@ public:
     Standard_Boolean IsTangentAtBegining() const;
   
     Standard_Boolean IsTangentAtEnd() const;
+  
+    Standard_Boolean IsTangency()  const;
 
 
 
@@ -166,6 +170,7 @@ private:
   gp_Vec vcttg;
   Standard_Boolean istgtbeg;
   Standard_Boolean istgtend;
+  Standard_Boolean istangency;
 
 
 };
index 1a4d886e6dcebf8de7700286dc6230b4c3560763..0d517444bd11f902d169679783f9eee33d0fc291 100644 (file)
@@ -74,7 +74,7 @@ public:
   //! Searches a set of polylines starting on a point of Pnts1
   //! or Pnts2.
   //! Each point on a resulting polyline verifies F(u,v)=0
-  Standard_EXPORT void Perform (const IntSurf_SequenceOfPathPoint& Pnts1, const IntSurf_SequenceOfInteriorPoint& Pnts2, Contap_SurfFunction& Func, const Handle(Adaptor3d_HSurface)& S, const Standard_Boolean Reversed = Standard_False);
+  Standard_EXPORT   void Perform (const IntSurf_SequenceOfPathPoint& Pnts1, const IntSurf_SequenceOfInteriorPoint& Pnts2, const IntSurf_SequenceOfInteriorPoint& Pnts3, Contap_SurfFunction& Func, const Handle(Adaptor3d_HSurface)& S, const Standard_Boolean Reversed = Standard_False) ;
   
   //! Searches a set of polylines starting on a point of Pnts1.
   //! Each point on a resulting polyline verifies F(u,v)=0
@@ -115,24 +115,32 @@ protected:
   
   Standard_EXPORT Standard_Boolean TestArretPassage (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const math_Vector& UV, const Standard_Integer Index, Standard_Integer& Irang);
   
-  Standard_EXPORT Standard_Boolean TestArretAjout (Contap_SurfFunction& Section, math_Vector& UV, Standard_Integer& Irang, IntSurf_PntOn2S& PSol);
+  Standard_EXPORT   Standard_Boolean TestArretPassageTang (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const math_Vector& UV, const Standard_Integer Index, Standard_Integer& Irang) ;
+  
+  Standard_EXPORT   Standard_Boolean TestArretAjout (Contap_SurfFunction& Section, math_Vector& UV, Standard_Integer& Irang, IntSurf_PntOn2S& PSol, Standard_Boolean& OnPrevTangency) ;
   
   Standard_EXPORT void TestArretCadre (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const Handle(Contap_TheIWLineOfTheIWalking)& Line, Contap_SurfFunction& Section, math_Vector& UV, Standard_Integer& Irang);
   
-  Standard_EXPORT IntWalk_StatusDeflection TestDeflection (Contap_SurfFunction& Section, const Standard_Boolean Finished, const math_Vector& UV, const IntWalk_StatusDeflection StatusPrecedent, Standard_Integer& NbDivision, Standard_Real& Step, const Standard_Integer StepSign);
+  Standard_EXPORT   IntWalk_StatusDeflection TestDeflection (Contap_SurfFunction& Section, const Standard_Boolean Finished, const math_Vector& UV, const IntWalk_StatusDeflection StatusPrecedent, Standard_Integer& NbDivision, Standard_Real& Step, Standard_Real& StepInit, const Standard_Integer StepSign, const Standard_Integer CurNbPoints, const Standard_Boolean ArretAjout, const Standard_Boolean PrevStepWrong, const Standard_Boolean OnPrevTangency) ;
   
   Standard_EXPORT void ComputeOpenLine (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const IntSurf_SequenceOfPathPoint& Pnts1, Contap_SurfFunction& Section, Standard_Boolean& Rajout);
   
   Standard_EXPORT void OpenLine (const Standard_Integer N, const IntSurf_PntOn2S& Psol, const IntSurf_SequenceOfPathPoint& Pnts1, Contap_SurfFunction& Section, const Handle(Contap_TheIWLineOfTheIWalking)& Line);
   
-  Standard_EXPORT void ComputeCloseLine (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const IntSurf_SequenceOfPathPoint& Pnts1, const IntSurf_SequenceOfInteriorPoint& Pnts2, Contap_SurfFunction& Section, Standard_Boolean& Rajout);
+  Standard_EXPORT   void ComputeCloseLine (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const IntSurf_SequenceOfPathPoint& Pnts1, const IntSurf_SequenceOfInteriorPoint& Pnts2, const IntSurf_SequenceOfInteriorPoint& Pnts3, Contap_SurfFunction& Section, Standard_Boolean& Rajout) ;
   
   Standard_EXPORT void AddPointInCurrentLine (const Standard_Integer N, const IntSurf_PathPoint& PathPnt, const Handle(Contap_TheIWLineOfTheIWalking)& CurrentLine) const;
   
   Standard_EXPORT void MakeWalkingPoint (const Standard_Integer Case, const Standard_Real U, const Standard_Real V, Contap_SurfFunction& Section, IntSurf_PntOn2S& Psol);
   
+  Standard_EXPORT   void FindExactCuspPoint (Contap_SurfFunction& Section, IntSurf_PntOn2S& Psol, const Standard_Integer PrevSignOfBcoeff, const Standard_Integer SignOfBcoeff) ;
+  
+  Standard_EXPORT   void FindExactTangentPoint (const Standard_Real TolTang, Contap_SurfFunction& Section, IntSurf_PntOn2S& Psol) ;
+  
+  Standard_EXPORT   Standard_Boolean ComputeDirOfTangentialIntersection (Contap_SurfFunction& Section, Standard_Integer& StepSign, Standard_Boolean& IsDiscriminantNull, Standard_Integer& SignOfBcoeff, gp_Vec& NewD3d, gp_Dir2d& NewD2d) ;
+  
   //! Clears up internal containers
-  Standard_EXPORT void Clear();
+  Standard_EXPORT   void Clear() ;
 
 
 
@@ -150,6 +158,7 @@ private:
   Standard_Boolean reversed;
   IntWalk_VectorOfWalkingData wd1;
   IntWalk_VectorOfWalkingData wd2;
+  IntWalk_VectorOfWalkingData wd3;
   IntWalk_VectorOfInteger nbMultiplicities;
   Standard_Real Um;
   Standard_Real UM;
@@ -158,6 +167,7 @@ private:
   IntSurf_PntOn2S previousPoint;
   gp_Vec previousd3d;
   gp_Dir2d previousd2d;
+  Standard_Boolean IsTangentialIntersection;
   TColStd_SequenceOfInteger seqAjout;
   Contap_SequenceOfIWLineOfTheIWalking lines;
 
index 0b069372fd2d4e25d994a17ef6fdd61f340ae501..dbc4628ed9b4fd3d13a6440e756309e7fe10c611 100644 (file)
@@ -58,12 +58,16 @@ public:
   //! returns False.
     Standard_Integer NbPoints() const;
   
+      Standard_Integer NbTangentPoints()  const;
+  
   //! Returns the point of range Index.
   //! The exception NotDone if raised if IsDone
   //! returns False.
   //! The exception OutOfRange if raised if
   //! Index <= 0 or Index > NbPoints.
-    const IntSurf_InteriorPoint& Value (const Standard_Integer Index) const;
+     const  IntSurf_InteriorPoint& Value (const Standard_Integer Index)  const;
+  
+     const  IntSurf_InteriorPoint& TangentPoint (const Standard_Integer Index)  const;
 
 
 
@@ -80,6 +84,7 @@ private:
 
   Standard_Boolean done;
   IntSurf_SequenceOfInteriorPoint list;
+  IntSurf_SequenceOfInteriorPoint myTangentPoints;
 
 
 };
index de973e31a5155ed3d8da037b917755ab458e9ab4..3dfcfe538fd87234ae876646d39044a7f0fc896d 100644 (file)
@@ -81,10 +81,18 @@ public:
   
   Standard_EXPORT Standard_Boolean IsTangent();
   
+  Standard_EXPORT   Standard_Boolean IsTangentSmooth() ;
+  
     const gp_Vec& Direction3d();
   
     const gp_Dir2d& Direction2d();
   
+  Standard_EXPORT   Standard_Boolean DerivativesAndNormalOnPSurf (gp_Vec& D1U, gp_Vec& D1V, gp_Vec& Normal, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV) ;
+  
+  Standard_EXPORT   Standard_Boolean DerivativesAndNormalOnISurf (gp_Vec& D1U, gp_Vec& D1V, gp_Vec& Normal, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV)  const;
+  
+      Standard_Real SquareTangentError()  const;
+  
     const Handle(Adaptor3d_HSurface)& PSurface() const;
   
     const IntSurf_Quadric& ISurface() const;
@@ -114,6 +122,8 @@ private:
   Standard_Real tgdu;
   Standard_Real tgdv;
   gp_Vec gradient;
+  gp_Vec d1u_isurf;
+  gp_Vec d1v_isurf;
   Standard_Boolean derived;
   gp_Vec d1u;
   gp_Vec d1v;
index aba25b341082deac4b6bfee08f86be276c260368..f573abfc9bf5ae3398746efd429a854c157338f3 100644 (file)
@@ -92,7 +92,7 @@ Standard_Boolean IntImp_ZerImpFunc::Values(const math_Vector& X,
   v = X(2);
   ThePSurfaceTool::D1(SURF, u, v, pntsol, d1u, d1v);
   TheISurfaceTool::ValueAndGradient(FUNC, pntsol.X(), pntsol.Y(), pntsol.Z(), 
-                                    valf, gradient);
+                                    valf, gradient, d1u_isurf, d1v_isurf);
   F(1) = valf;
   D(1,1) = d1u.Dot(gradient);
   D(1,2) = d1v.Dot(gradient);
@@ -118,17 +118,133 @@ Standard_Boolean IntImp_ZerImpFunc::IsTangent()
     Standard_Real N2d1v  = d1v.SquareMagnitude();
     tangent =(tgdu * tgdu <= N2grad_EpsAng2 * N2d1v) && 
              (tgdv * tgdv <= N2grad_EpsAng2 * N2d1u);
+
+#ifdef DRAW
+    if (tangent)
+    {
+      Standard_Real SumSquare = tgdu * tgdu + tgdv * tgdv;
+      gp_Vec NormSURF = d1u ^ d1v;
+      cout<<"Tangent !!!"<<endl;
+      cout<<"SumSquare = "<<SumSquare<<endl;
+      cout<<"u = "<<u<<", v = "<<v<<endl;
+      cout<<"pnt = "<<pntsol.X()<<" "<<pntsol.Y()<<" "<<pntsol.Z()<<endl;
+    }
+#endif
+    
     if(!tangent) {
       d3d.SetLinearForm(tgdu,d1u,tgdv,d1v);
       d2d = gp_Dir2d(tgdu, tgdv);
       if (d3d.Magnitude() <= Tolpetit) {    // jag
         tangent = Standard_True;
       }
-    }    
+      
+#ifdef DRAW
+      gp_Vec NormSURF = d1u ^ d1v;
+      cout<<"u = "<<u<<", v = "<<v<<endl;
+      cout<<"pnt = "<<pntsol.X()<<" "<<pntsol.Y()<<" "<<pntsol.Z()<<endl;
+      cout<<"d3d = "<<d3d.X()<<" "<<d3d.Y()<<" "<<d3d.Z()<<endl;
+#endif
+    }
   }
   return tangent;
 }
 
+Standard_Boolean IntImp_ZerImpFunc::IsTangentSmooth()
+{
+  const Standard_Real TolCrossProd = 1.e-15;
+  
+  if (!computed) {
+    computed = Standard_True;
+    if(!derived) {
+      ThePSurfaceTool::D1(SURF, u, v, pntsol, d1u, d1v);
+      derived = Standard_True;
+    }
+
+    tgdu =  gradient.Dot(d1v);
+    tgdv = -gradient.Dot(d1u);
+    
+    gp_Vec NormPSurf = d1u ^ d1v;
+    gp_Vec NormISurf = d1u_isurf ^ d1v_isurf;
+    NormPSurf.Normalize();
+    NormISurf.Normalize();
+#ifdef DRAW
+    Standard_Real theAngle = NormPSurf.Angle(NormISurf);
+#endif
+    gp_Vec CrossProd = NormPSurf ^ NormISurf;
+    Standard_Real CrossProdSqMagn = CrossProd.SquareMagnitude();
+    
+#ifdef DRAW
+    cout<<"Angle = "<<theAngle<<endl;
+    cout<<"CrossProdSqMagn = "<<CrossProdSqMagn<<endl;
+#endif
+
+    tangent = (CrossProdSqMagn <= TolCrossProd);
+    
+#ifdef DRAW
+    if (tangent)
+    {
+      Standard_Real SumSquare = tgdu * tgdu + tgdv * tgdv;
+      gp_Vec NormSURF = d1u ^ d1v;
+      cout<<"Tangent !!!"<<endl;
+      cout<<"SumSquare = "<<SumSquare<<endl;
+      cout<<"u = "<<u<<", v = "<<v<<endl;
+      cout<<"pnt = "<<pntsol.X()<<" "<<pntsol.Y()<<" "<<pntsol.Z()<<endl;
+    }
+#endif
+    
+    if(!tangent) {
+      d3d.SetLinearForm(tgdu,d1u,tgdv,d1v);
+      d2d = gp_Dir2d(tgdu, tgdv);
+      if (d3d.Magnitude() <= Tolpetit) {    // jag
+       tangent = Standard_True;
+      }
+#ifdef DRAW
+      gp_Vec NormSURF = d1u ^ d1v;
+      cout<<"u = "<<u<<", v = "<<v<<endl;
+      cout<<"pnt = "<<pntsol.X()<<" "<<pntsol.Y()<<" "<<pntsol.Z()<<endl;
+      cout<<"d3d = "<<d3d.X()<<" "<<d3d.Y()<<" "<<d3d.Z()<<endl;
+#endif
+    }
+  }
+  return tangent;
+}
+
+Standard_Boolean IntImp_ZerImpFunc::DerivativesAndNormalOnPSurf(gp_Vec& D1U,
+                                                    gp_Vec& D1V,
+                                                    gp_Vec& Normal,
+                                                    gp_Vec& D2U,
+                                                    gp_Vec& D2V,
+                                                    gp_Vec& D2UV)
+{
+  ThePSurfaceTool::D2(SURF, u, v, pntsol, D1U, D1V, D2U, D2V, D2UV);
+  Normal = D1U ^ D1V;
+  Standard_Real theMagnitude = Normal.Magnitude();
+  if (theMagnitude <= gp::Resolution())
+    return Standard_False;
+  else
+    Normal /= theMagnitude;
+
+  return Standard_True;
+}
+
+Standard_Boolean IntImp_ZerImpFunc::DerivativesAndNormalOnISurf(gp_Vec& D1U,
+                                                    gp_Vec& D1V,
+                                                    gp_Vec& Normal,
+                                                    gp_Vec& D2U,
+                                                    gp_Vec& D2V,
+                                                    gp_Vec& D2UV) const
+{
+  TheISurfaceTool::D2(FUNC, pntsol, D1U, D1V, D2U, D2V, D2UV);
+  Normal = D1U ^ D1V;
+  Standard_Real theMagnitude = Normal.Magnitude();
+  if (theMagnitude <= gp::Resolution())
+    return Standard_False;
+  else
+    Normal /= theMagnitude;
+
+  return Standard_True;
+}
+
 #undef EpsAng
 #undef EpsAng2
 #undef Tolpetit
index 5c5e0e7b5d1e5003fb6b2a87a785ecc163890bad..8340240fcf2a776ba9d46462e6d1ea18855e83c3 100644 (file)
@@ -56,6 +56,11 @@ inline const gp_Dir2d& IntImp_ZerImpFunc::Direction2d()
   return d2d;
 }
 
+inline Standard_Real IntImp_ZerImpFunc::SquareTangentError() const
+{
+  return (tgdu * tgdu + tgdv * tgdv);
+}
+
 inline const ThePSurface& IntImp_ZerImpFunc::PSurface() const 
 {
   return  (*((ThePSurface *)(surf)));
index 564725cd3e9311cf743188f17b064218b9d931a6..02f0bfcece3f38ba3b138dda7acce04a63915a2c 100644 (file)
@@ -429,7 +429,7 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
 {
   Standard_Boolean reversed, procf, procl, dofirst, dolast;
   Standard_Integer indfirst = 0, indlast = 0, ind2, NbSegm;
-  Standard_Integer NbPointIns, NbPointRst, Nblines, Nbpts, NbPointDep;
+  Standard_Integer NbPointIns, NbPointsTang, NbPointRst, Nblines, Nbpts, NbPointDep;
   Standard_Real U1,V1,U2,V2,paramf,paraml,currentparam;
 
   IntPatch_TheSegmentOfTheSOnBounds thesegm;
@@ -544,6 +544,7 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
   //
   IntSurf_SequenceOfPathPoint seqpdep;
   IntSurf_SequenceOfInteriorPoint seqpins;
+  IntSurf_SequenceOfInteriorPoint seqptang;
   //
   NbPointRst = solrst.NbPoints();
   TColStd_Array1OfInteger Destination(1,NbPointRst+1); Destination.Init(0);
@@ -615,6 +616,9 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
     for (Standard_Integer i=1; i <= NbPointIns; i++) {
       seqpins.Append(solins.Value(i));
     }
+    NbPointsTang = solins.NbTangentPoints();
+    for (Standard_Integer i = 1; i <= NbPointsTang; i++)
+      seqptang.Append(solins.TangentPoint(i));
   }
   //
   NbPointDep=seqpdep.Length();
@@ -622,10 +626,10 @@ void IntPatch_ImpPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur
   if (NbPointDep || NbPointIns) {
     IntPatch_TheIWalking iwalk(TolTang,Fleche,Pas);
     if (!reversed) {
-      iwalk.Perform(seqpdep,seqpins,Func,Surf2);
+      iwalk.Perform(seqpdep,seqpins,seqptang,Func,Surf2);
     }
     else {
-      iwalk.Perform(seqpdep,seqpins,Func,Surf1,Standard_True);
+      iwalk.Perform(seqpdep,seqpins,seqptang,Func,Surf1,Standard_True);
     }
     if(!iwalk.IsDone()) {
       return;
@@ -3246,4 +3250,4 @@ Standard_Boolean IsCoincide(IntPatch_TheSurfFunction& theFunc,
   }
 
   return Standard_True;
-}
\ No newline at end of file
+}
index 84b23982b07baff21fc5c34302a04f9013330a4d..adfa889593f225fd604cea32f4a4eafb4a94a587 100644 (file)
@@ -76,6 +76,8 @@ public:
   
     void SetTangencyAtEnd (const Standard_Boolean IsTangent);
   
+    void SetTangency (const Standard_Boolean IsTangency) ;
+  
   //! Returns the number of points of the line (including first
   //! point and end point : see HasLastPoint and HasFirstPoint).
     Standard_Integer NbPoints() const;
@@ -139,6 +141,8 @@ public:
     Standard_Boolean IsTangentAtBegining() const;
   
     Standard_Boolean IsTangentAtEnd() const;
+  
+    Standard_Boolean IsTangency()  const;
 
 
 
@@ -166,6 +170,7 @@ private:
   gp_Vec vcttg;
   Standard_Boolean istgtbeg;
   Standard_Boolean istgtend;
+  Standard_Boolean istangency;
 
 
 };
index ff296da7999af1d1f0e7714227513ff6d2078924..b10b902d6d9e2b3bba63615299210c7e86d9d026 100644 (file)
@@ -74,7 +74,7 @@ public:
   //! Searches a set of polylines starting on a point of Pnts1
   //! or Pnts2.
   //! Each point on a resulting polyline verifies F(u,v)=0
-  Standard_EXPORT void Perform (const IntSurf_SequenceOfPathPoint& Pnts1, const IntSurf_SequenceOfInteriorPoint& Pnts2, IntPatch_TheSurfFunction& Func, const Handle(Adaptor3d_HSurface)& S, const Standard_Boolean Reversed = Standard_False);
+  Standard_EXPORT   void Perform (const IntSurf_SequenceOfPathPoint& Pnts1, const IntSurf_SequenceOfInteriorPoint& Pnts2, const IntSurf_SequenceOfInteriorPoint& Pnts3, IntPatch_TheSurfFunction& Func, const Handle(Adaptor3d_HSurface)& S, const Standard_Boolean Reversed = Standard_False) ;
   
   //! Searches a set of polylines starting on a point of Pnts1.
   //! Each point on a resulting polyline verifies F(u,v)=0
@@ -115,24 +115,32 @@ protected:
   
   Standard_EXPORT Standard_Boolean TestArretPassage (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const math_Vector& UV, const Standard_Integer Index, Standard_Integer& Irang);
   
-  Standard_EXPORT Standard_Boolean TestArretAjout (IntPatch_TheSurfFunction& Section, math_Vector& UV, Standard_Integer& Irang, IntSurf_PntOn2S& PSol);
+  Standard_EXPORT   Standard_Boolean TestArretPassageTang (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const math_Vector& UV, const Standard_Integer Index, Standard_Integer& Irang) ;
+  
+  Standard_EXPORT   Standard_Boolean TestArretAjout (IntPatch_TheSurfFunction& Section, math_Vector& UV, Standard_Integer& Irang, IntSurf_PntOn2S& PSol, Standard_Boolean& OnPrevTangency) ;
   
   Standard_EXPORT void TestArretCadre (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const Handle(IntPatch_TheIWLineOfTheIWalking)& Line, IntPatch_TheSurfFunction& Section, math_Vector& UV, Standard_Integer& Irang);
   
-  Standard_EXPORT IntWalk_StatusDeflection TestDeflection (IntPatch_TheSurfFunction& Section, const Standard_Boolean Finished, const math_Vector& UV, const IntWalk_StatusDeflection StatusPrecedent, Standard_Integer& NbDivision, Standard_Real& Step, const Standard_Integer StepSign);
+  Standard_EXPORT   IntWalk_StatusDeflection TestDeflection (IntPatch_TheSurfFunction& Section, const Standard_Boolean Finished, const math_Vector& UV, const IntWalk_StatusDeflection StatusPrecedent, Standard_Integer& NbDivision, Standard_Real& Step, Standard_Real& StepInit, const Standard_Integer StepSign, const Standard_Integer CurNbPoints, const Standard_Boolean ArretAjout, const Standard_Boolean PrevStepWrong, const Standard_Boolean OnPrevTangency) ;
   
   Standard_EXPORT void ComputeOpenLine (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const IntSurf_SequenceOfPathPoint& Pnts1, IntPatch_TheSurfFunction& Section, Standard_Boolean& Rajout);
   
   Standard_EXPORT void OpenLine (const Standard_Integer N, const IntSurf_PntOn2S& Psol, const IntSurf_SequenceOfPathPoint& Pnts1, IntPatch_TheSurfFunction& Section, const Handle(IntPatch_TheIWLineOfTheIWalking)& Line);
   
-  Standard_EXPORT void ComputeCloseLine (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const IntSurf_SequenceOfPathPoint& Pnts1, const IntSurf_SequenceOfInteriorPoint& Pnts2, IntPatch_TheSurfFunction& Section, Standard_Boolean& Rajout);
+  Standard_EXPORT   void ComputeCloseLine (const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const IntSurf_SequenceOfPathPoint& Pnts1, const IntSurf_SequenceOfInteriorPoint& Pnts2, const IntSurf_SequenceOfInteriorPoint& Pnts3, IntPatch_TheSurfFunction& Section, Standard_Boolean& Rajout) ;
   
   Standard_EXPORT void AddPointInCurrentLine (const Standard_Integer N, const IntSurf_PathPoint& PathPnt, const Handle(IntPatch_TheIWLineOfTheIWalking)& CurrentLine) const;
   
   Standard_EXPORT void MakeWalkingPoint (const Standard_Integer Case, const Standard_Real U, const Standard_Real V, IntPatch_TheSurfFunction& Section, IntSurf_PntOn2S& Psol);
   
+  Standard_EXPORT   void FindExactCuspPoint (IntPatch_TheSurfFunction& Section, IntSurf_PntOn2S& Psol, const Standard_Integer PrevSignOfBcoeff, const Standard_Integer SignOfBcoeff) ;
+  
+  Standard_EXPORT   void FindExactTangentPoint (const Standard_Real TolTang, IntPatch_TheSurfFunction& Section, IntSurf_PntOn2S& Psol) ;
+  
+  Standard_EXPORT   Standard_Boolean ComputeDirOfTangentialIntersection (IntPatch_TheSurfFunction& Section, Standard_Integer& StepSign, Standard_Boolean& IsDiscriminantNull, Standard_Integer& SignOfBcoeff, gp_Vec& NewD3d, gp_Dir2d& NewD2d) ;
+  
   //! Clears up internal containers
-  Standard_EXPORT void Clear();
+  Standard_EXPORT   void Clear() ;
 
 
 
@@ -150,6 +158,7 @@ private:
   Standard_Boolean reversed;
   IntWalk_VectorOfWalkingData wd1;
   IntWalk_VectorOfWalkingData wd2;
+  IntWalk_VectorOfWalkingData wd3;
   IntWalk_VectorOfInteger nbMultiplicities;
   Standard_Real Um;
   Standard_Real UM;
@@ -158,6 +167,7 @@ private:
   IntSurf_PntOn2S previousPoint;
   gp_Vec previousd3d;
   gp_Dir2d previousd2d;
+  Standard_Boolean IsTangentialIntersection;
   TColStd_SequenceOfInteger seqAjout;
   IntPatch_SequenceOfIWLineOfTheIWalking lines;
 
index 1e69fd3fa4245db8a110d1ee7f4c3711add7ebb2..849a3344a84325b1b5189c98d037046e6502e683 100644 (file)
@@ -58,12 +58,16 @@ public:
   //! returns False.
     Standard_Integer NbPoints() const;
   
+      Standard_Integer NbTangentPoints()  const;
+  
   //! Returns the point of range Index.
   //! The exception NotDone if raised if IsDone
   //! returns False.
   //! The exception OutOfRange if raised if
   //! Index <= 0 or Index > NbPoints.
-    const IntSurf_InteriorPoint& Value (const Standard_Integer Index) const;
+     const  IntSurf_InteriorPoint& Value (const Standard_Integer Index)  const;
+  
+     const  IntSurf_InteriorPoint& TangentPoint (const Standard_Integer Index)  const;
 
 
 
@@ -80,6 +84,7 @@ private:
 
   Standard_Boolean done;
   IntSurf_SequenceOfInteriorPoint list;
+  IntSurf_SequenceOfInteriorPoint myTangentPoints;
 
 
 };
index 49f1403084100ce74000c75012a12e0e722ea56a..2f3ec1a2b0e4fcc981170404ad5f4848ea6ed701 100644 (file)
@@ -81,10 +81,18 @@ public:
   
   Standard_EXPORT Standard_Boolean IsTangent();
   
+  Standard_EXPORT   Standard_Boolean IsTangentSmooth() ;
+  
     const gp_Vec& Direction3d();
   
     const gp_Dir2d& Direction2d();
   
+  Standard_EXPORT   Standard_Boolean DerivativesAndNormalOnPSurf (gp_Vec& D1U, gp_Vec& D1V, gp_Vec& Normal, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV) ;
+  
+  Standard_EXPORT   Standard_Boolean DerivativesAndNormalOnISurf (gp_Vec& D1U, gp_Vec& D1V, gp_Vec& Normal, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV)  const;
+  
+      Standard_Real SquareTangentError()  const;
+  
     const Handle(Adaptor3d_HSurface)& PSurface() const;
   
     const IntSurf_Quadric& ISurface() const;
@@ -114,6 +122,8 @@ private:
   Standard_Real tgdu;
   Standard_Real tgdv;
   gp_Vec gradient;
+  gp_Vec d1u_isurf;
+  gp_Vec d1v_isurf;
   Standard_Boolean derived;
   gp_Vec d1u;
   gp_Vec d1v;
index 53a2225cd093d7080940d8811cc480c3c375620f..81162ffca6e637bd725c290cbec9c7520aaf880d 100644 (file)
 
 #include <TopAbs_State.hxx>
 
+#ifdef DRAW
+#include <DrawTrSurf.hxx>
+#endif
+
+
 IntStart_SearchInside::IntStart_SearchInside (): done(Standard_False)
 {}
 
@@ -49,6 +54,7 @@ void IntStart_SearchInside::Perform (TheFunction& Func,
 
   done = Standard_False;
   list.Clear();
+  myTangentPoints.Clear();
   Standard_Real aBinf[2], aBsup[2], aUVap[2], atoler[2];
   math_Vector Binf(aBinf,1,2), Bsup(aBsup,1,2), UVap(aUVap,1,2), toler(atoler,1,2);
   gp_Pnt psol;
@@ -117,6 +123,12 @@ void IntStart_SearchInside::Perform (TheFunction& Func,
   //--                 P  I I I I I I I I
   //--
 
+#ifdef DRAW
+  char* name = new char[100];
+#endif
+
+  gp_Vec NullDir(0.,0.,0.);
+  gp_Vec2d NullDir2d(0.,0.);
   
   for (i=1; i <= Nbsample+12; i++) {
     gp_Pnt2d s2d;
@@ -176,9 +188,9 @@ void IntStart_SearchInside::Perform (TheFunction& Func,
       Rsnld.Perform(Func,UVap,Binf,Bsup);
       if (Rsnld.IsDone()) {
        if (Abs(Func.Root()) <= Tol) {
+          psol = Func.Point();
+          Rsnld.Root(UVap);
          if (!Func.IsTangent()) {
-           psol = Func.Point();
-           Rsnld.Root(UVap);
            // On regarde si le point trouve est bien un nouveau point.   
            j = 1;
            nbpt = list.Length();
@@ -207,9 +219,54 @@ void IntStart_SearchInside::Perform (TheFunction& Func,
                list.Append(IntSurf_InteriorPoint(psol,UVap(1),UVap(2),
                                                  Func.Direction3d(),
                                                  Func.Direction2d()));
+#ifdef DRAW
+                gp_Pnt2d p2dsol(UVap(1),UVap(2));
+                sprintf(name, "pp%d", list.Length());
+                DrawTrSurf::Set(name, p2dsol);
+                sprintf(name, "p%d", list.Length());
+                DrawTrSurf::Set(name, psol);
+#endif
              }
            }
-         }
+         }//if (!Func.IsTangent())
+          else //tangent point
+          {
+            Standard_Boolean IsNewTangentPoint = Standard_True;
+            for (j = 1; j <= myTangentPoints.Length(); j++)
+            {
+             const IntSurf_InteriorPoint&  IPj = myTangentPoints(j);
+             const gp_Pnt& Pj = IPj.Value();
+             if (   (Abs(Pj.X()-psol.X()) <= Epsilon)
+                 && (Abs(Pj.Y()-psol.Y()) <= Epsilon)
+                 && (Abs(Pj.Z()-psol.Z()) <= Epsilon)
+                 && (Abs(UVap(1)-IPj.UParameter()) <= toler1)
+                 && (Abs(UVap(2)-IPj.VParameter()) <= toler2) )
+              {
+               IsNewTangentPoint = Standard_False;
+                break;
+             }
+            }
+            
+            if (IsNewTangentPoint)
+            {
+             situ = T->Classify(gp_Pnt2d(UVap(1),UVap(2)),
+                                Maxtoler1toler2,Standard_False);   //-- ,Standard_False pour ne pas recadrer on Periodic
+             if (situ == TopAbs_IN) {
+                myTangentPoints.Append(IntSurf_InteriorPoint(psol,UVap(1),UVap(2),
+                                                             NullDir, NullDir2d));
+#ifdef DRAW
+                gp_Pnt2d p2dsol(UVap(1),UVap(2));
+                sprintf(name, "tpp%d", myTangentPoints.Length());
+                DrawTrSurf::Set(name, p2dsol);
+                sprintf(name, "tp%d", myTangentPoints.Length());
+                DrawTrSurf::Set(name, psol);
+                cout<<myTangentPoints.Length()<<" tangent point :"<<endl;
+                cout<<"U = "<<UVap(1)<<", V = "<<UVap(2)<<endl;
+                //cout<<"Dist = "<<aRootVal<<endl<<endl;
+#endif
+              }
+            }
+          }
        }
       }
     }
@@ -231,6 +288,7 @@ void IntStart_SearchInside::Perform (TheFunction& Func,
 {
   done = Standard_False;
   list.Clear();
+  myTangentPoints.Clear();
   math_Vector Binf(1,2), Bsup(1,2), toler(1,2);
 
   Binf(1) = ThePSurfaceTool::FirstUParameter(PS);
index c4c9408c6c09f8b242ae76525b3909deeefc16df..938e6da90720645a5b09f6742bcf4b42de14ff9c 100644 (file)
@@ -27,6 +27,12 @@ inline Standard_Integer IntStart_SearchInside::NbPoints () const {
   return list.Length();
 }
 
+inline Standard_Integer IntStart_SearchInside::NbTangentPoints () const {
+
+  if (!done) {StdFail_NotDone::Raise();}
+  return myTangentPoints.Length();
+}
+
 
 inline const IntSurf_InteriorPoint& IntStart_SearchInside::Value 
      (const Standard_Integer Index) const
@@ -36,3 +42,10 @@ inline const IntSurf_InteriorPoint& IntStart_SearchInside::Value
   return list.Value(Index);
 }
 
+inline const IntSurf_InteriorPoint& IntStart_SearchInside::TangentPoint
+     (const Standard_Integer Index) const
+
+{
+  if (!done) {StdFail_NotDone::Raise();}
+  return myTangentPoints.Value(Index);
+}
index eb8a15ef241ab82aa44a4bf90402cb67c5396d79..957c17a2ba733c5a66957dafb4549ffb491004a4 100644 (file)
@@ -49,6 +49,29 @@ void IntSurf_PntOn2S::SetValue (const Standard_Boolean OnFirst,
   }
 }
 
+gp_Pnt2d IntSurf_PntOn2S::ValueOnSurface(const Standard_Boolean OnFirst) const
+{
+  gp_Pnt2d PointOnSurf;
+  if (OnFirst)
+    PointOnSurf.SetCoord(u1,v1);
+  else
+    PointOnSurf.SetCoord(u2,v2);
+  return PointOnSurf;
+}
+
+void IntSurf_PntOn2S::ParametersOnSurface(const Standard_Boolean OnFirst,
+                                          Standard_Real& U,
+                                          Standard_Real& V) const
+{
+  if (OnFirst) {
+    U = u1;
+    V = v1;
+  }
+  else {
+    U = u2;
+    V = v2;
+  }
+}
 
 Standard_Boolean IntSurf_PntOn2S::IsSame( const IntSurf_PntOn2S& theOterPoint,
                                           const Standard_Real theTol3D,
index 7dd65db9a1bc159e0db4aba110083c16a3c09324..f2986eb1de09edb0326c22a6bb72f9eb27065136 100644 (file)
@@ -25,6 +25,7 @@
 #include <Standard_Real.hxx>
 #include <Standard_Boolean.hxx>
 class gp_Pnt;
+class gp_Pnt2d;
 
 
 //! This class defines the geometric informations
@@ -61,13 +62,20 @@ public:
     void SetValue (const Standard_Real U1, const Standard_Real V1, const Standard_Real U2, const Standard_Real V2);
   
   //! Returns the point in 3d space.
-    const gp_Pnt& Value() const;
+     const  gp_Pnt& Value()  const;
+  
+  //! Returns the point in 2d space of one of the surfaces.
+  Standard_EXPORT   gp_Pnt2d ValueOnSurface (const Standard_Boolean OnFirst)  const;
   
   //! Returns the parameters of the point on the first surface.
     void ParametersOnS1 (Standard_Real& U1, Standard_Real& V1) const;
   
   //! Returns the parameters of the point on the second surface.
-    void ParametersOnS2 (Standard_Real& U2, Standard_Real& V2) const;
+      void ParametersOnS2 (Standard_Real& U2, Standard_Real& V2)  const;
+  
+  //! Returns the parameters of the point in the
+  //! parametric space of one of the surface.
+  Standard_EXPORT   void ParametersOnSurface (const Standard_Boolean OnFirst, Standard_Real& U, Standard_Real& V)  const;
   
   //! Returns the parameters of the point on both surfaces.
     void Parameters (Standard_Real& U1, Standard_Real& V1, Standard_Real& U2, Standard_Real& V2) const;
@@ -75,7 +83,7 @@ public:
   //! Returns TRUE if 2D- and 3D-coordinates of theOterPoint are equal to
   //! corresponding coordinates of me (with given tolerance).
   //! If theTol2D == 0.0 we will compare 3D-points only.
-  Standard_EXPORT Standard_Boolean IsSame (const IntSurf_PntOn2S& theOterPoint, const Standard_Real theTol3D = 0.0, const Standard_Real theTol2D = 0.0) const;
+  Standard_EXPORT   Standard_Boolean IsSame (const IntSurf_PntOn2S& theOtherPoint, const Standard_Real theTol3D = 0.0, const Standard_Real theTol2D = 0.0)  const;
 
 
 
index 5816c9f17dbc8afe85ca21202214190d308e5161..cea8909ffe8ae148945790dc3fff682b86f77634 100644 (file)
 #include <IntSurf_Quadric.hxx>
 #include <IntSurf_QuadricTool.hxx>
 
+void IntSurf_QuadricTool::ValueAndGradient (const IntSurf_Quadric& Quad,
+                                            const Standard_Real X,
+                                            const Standard_Real Y,
+                                            const Standard_Real Z,
+                                            Standard_Real& Val,
+                                            gp_Vec& Grad,
+                                            gp_Vec& D1U,
+                                            gp_Vec& D1V)
+{
+  gp_Pnt thePoint(X,Y,Z);
+  Quad.ValAndGrad(thePoint, Val, Grad);
+  Standard_Real U, V;
+  Quad.Parameters(thePoint, U, V);
+  Quad.D1(U, V, thePoint, D1U, D1V);
+}
+
+void IntSurf_QuadricTool::D2 (const IntSurf_Quadric& Quad,
+                              const gp_Pnt& aPoint,
+                              gp_Vec& D1U,
+                              gp_Vec& D1V,
+                              gp_Vec& D2U,
+                              gp_Vec& D2V,
+                              gp_Vec& D2UV)
+{
+  Standard_Real U, V;
+  Quad.Parameters(aPoint, U, V);
+  gp_Pnt thePoint;
+  Quad.D1(U, V, thePoint, D1U, D1V);
+  D2U = Quad.DN(U, V, 2, 0);
+  D2V = Quad.DN(U, V, 0, 2);
+  D2UV = Quad.DN(U, V, 1, 1);
+}
+
 Standard_Real IntSurf_QuadricTool::Tolerance (const IntSurf_Quadric& Q) {
   switch (Q.TypeQuadric()) {
   case GeomAbs_Sphere:
index 6e8563769199fb9129a536e6832fa67d160b73ad..c5ed696f94f86600333f60d628cdb4f8e8326d46 100644 (file)
@@ -24,6 +24,7 @@
 #include <Standard_Real.hxx>
 class IntSurf_Quadric;
 class gp_Vec;
+class gp_Pnt;
 
 
 //! This class provides a tool on a quadric that can be
@@ -44,7 +45,10 @@ public:
     static void Gradient (const IntSurf_Quadric& Quad, const Standard_Real X, const Standard_Real Y, const Standard_Real Z, gp_Vec& V);
   
   //! Returns the value and the gradient.
-    static void ValueAndGradient (const IntSurf_Quadric& Quad, const Standard_Real X, const Standard_Real Y, const Standard_Real Z, Standard_Real& Val, gp_Vec& Grad);
+  Standard_EXPORT static   void ValueAndGradient (const IntSurf_Quadric& Quad, const Standard_Real X, const Standard_Real Y, const Standard_Real Z, Standard_Real& Val, gp_Vec& Grad, gp_Vec& D1U_ISurf, gp_Vec& D1V_ISurf) ;
+  
+  //! Returns all first and second derivatives.
+  Standard_EXPORT static   void D2 (const IntSurf_Quadric& Quad, const gp_Pnt& Point, gp_Vec& D1U, gp_Vec& D1V, gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV) ;
   
   //! returns the tolerance of the zero of the implicit function
   Standard_EXPORT static Standard_Real Tolerance (const IntSurf_Quadric& Quad);
index 7e7ef2d6e2209ddb60aa6ed3a6fc83469cf19286..e89af93dfacf7fb50ff3acaa045b9ae2a7b239f1 100644 (file)
@@ -31,15 +31,3 @@ inline void IntSurf_QuadricTool::Gradient (const IntSurf_Quadric& Quad,
 
   V = Quad.Gradient(gp_Pnt(X,Y,Z));
 }
-
-inline void IntSurf_QuadricTool::ValueAndGradient (const IntSurf_Quadric& Quad,
-                                                  const Standard_Real X,
-                                                  const Standard_Real Y,
-                                                  const Standard_Real Z,
-                                                  Standard_Real& Val,
-                                                  gp_Vec& V) {
-
-  Quad.ValAndGrad(gp_Pnt(X,Y,Z),Val,V);
-}
-
-
index bbd68793f0048e2477530f4e235146d1c6d928ca..ae6c854cd047ec5af2e9e66fc70d343645e690ee 100644 (file)
@@ -353,7 +353,8 @@ static Standard_Boolean isTreatAnalityc(const TopoDS_Face& theF1,
   const Standard_Real Tolang = 1.e-8;
   const Standard_Real aTolF1=BRep_Tool::Tolerance(theF1);
   const Standard_Real aTolF2=BRep_Tool::Tolerance(theF2);
-  const Standard_Real aTolSum = aTolF1 + aTolF2 + Precision::Confusion();
+  //const Standard_Real aTolSum = aTolF1 + aTolF2;
+  const Standard_Real aTolSum = Min(aTolF1, aTolF2);
   Standard_Real aHigh = 0.0;
 
   const BRepAdaptor_Surface aBAS1(theF1), aBAS2(theF2);
@@ -482,7 +483,8 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
   const Standard_Real aTolF1=BRep_Tool::Tolerance(myFace1);
   const Standard_Real aTolF2=BRep_Tool::Tolerance(myFace2);
 
-  Standard_Real TolArc = aTolF1 + aTolF2 + Precision::Confusion();
+  //Standard_Real TolArc = aTolF1 + aTolF2;
+  Standard_Real TolArc = Min(aTolF1, aTolF2);
   Standard_Real TolTang = TolArc;
 
   const Standard_Boolean isFace1Quad = (aType1 == GeomAbs_Cylinder ||
index 57b9858158baf922d87b85fb69d86a94a4407327..c7a175d14e81706fff2a5e38b904183b346f4aa8 100644 (file)
@@ -20,7 +20,8 @@ IntWalk_IWLine::IntWalk_IWLine (const IntSurf_Allocator& theAllocator) :
   hasFirst (Standard_False), hasLast (Standard_False),
   firstIndex (-1), lastIndex (-1),
   indextg (-1),
-  istgtbeg (Standard_False), istgtend (Standard_False)
+  istgtbeg (Standard_False), istgtend (Standard_False),
+  istangency (Standard_False)
 {
 }
 
index 3abae884d635a705bb8110d04d5453ffe76de2e8..586659a6fcd295f2b4186499d726d1371389c0d8 100644 (file)
@@ -162,6 +162,12 @@ inline void IntWalk_IWLine::SetTangencyAtEnd
   istgtend = IsTangent;
 }
 
+inline void IntWalk_IWLine::SetTangency
+  (const Standard_Boolean IsTangency) {
+
+  istangency = IsTangency;
+}
+
 inline const gp_Vec& IntWalk_IWLine::TangentVector
   (Standard_Integer& Index) const {
 //--    if(istgtend == Standard_False && istgtbeg == Standard_False) { 
@@ -181,4 +187,8 @@ inline Standard_Boolean IntWalk_IWLine::IsTangentAtEnd () const {
   return istgtend;
 }
 
+inline Standard_Boolean IntWalk_IWLine::IsTangency () const {
+
+  return istangency;
+}
 
index 5b3b7d8ce07f4314d0b2471e66640f8130900e0f..285814716683685b21a7f86d0272d916129b0e3d 100644 (file)
@@ -20,6 +20,7 @@ OSD_Chronometer Chronrsnld;
 
 #include <NCollection_IncAllocator.hxx>
 #include <Precision.hxx>
+#include <TColStd_Array1OfBoolean.hxx>
 
 //==================================================================================
 // function : IsTangentExtCheck
@@ -78,7 +79,9 @@ IntWalk_IWalking::IntWalk_IWalking (const Standard_Real Epsilon,
       epsilon(Epsilon*Epsilon),
       wd1 (IntWalk_VectorOfWalkingData::allocator_type (new NCollection_IncAllocator)),
       wd2 (wd1.get_allocator()),
-      nbMultiplicities (wd1.get_allocator())
+      wd3 (wd2.get_allocator()),
+      nbMultiplicities (wd1.get_allocator()),
+      IsTangentialIntersection(Standard_False)
 {
 }
 
@@ -95,11 +98,13 @@ void IntWalk_IWalking::Clear()
 {
   wd1.clear();
   wd2.clear();
+  wd3.clear();
   IntWalk_WalkingData aDummy;
   aDummy.etat = -10;
   aDummy.ustart = aDummy.vstart = 0.;
   wd1.push_back (aDummy);
   wd2.push_back (aDummy);
+  wd3.push_back (aDummy);
   nbMultiplicities.clear();
   nbMultiplicities.push_back (-1);
   
@@ -127,6 +132,7 @@ void IntWalk_IWalking::Clear()
 //
 void IntWalk_IWalking::Perform(const ThePOPIterator& Pnts1,
                               const ThePOLIterator& Pnts2,
+                               const ThePOLIterator& Pnts3,
                               TheIWFunction& Func,
                               const ThePSurface& Caro,
                               const Standard_Boolean Reversed)
@@ -136,6 +142,7 @@ void IntWalk_IWalking::Perform(const ThePOPIterator& Pnts1,
   Standard_Boolean Rajout = Standard_False;
   Standard_Integer nbPnts1 = Pnts1.Length();
   Standard_Integer nbPnts2 = Pnts2.Length();
+  Standard_Integer nbPnts3 = Pnts3.Length();
   Standard_Real U,V;
 
   Clear();
@@ -204,6 +211,14 @@ void IntWalk_IWalking::Perform(const ThePOPIterator& Pnts1,
     wd2.push_back (aWD2);
   }
 
+  wd3.reserve (nbPnts3);
+  for (I = 1; I <= nbPnts3; I++) {
+    IntWalk_WalkingData aWD3;
+    aWD3.etat = 13;
+    ThePointOfLoopTool::Value2d(Pnts3.Value(I), aWD3.ustart, aWD3.vstart);
+    wd3.push_back (aWD3);
+  }
+
   tolerance(1) = ThePSurfaceTool::UResolution(Caro,Precision::Confusion());
   tolerance(2) = ThePSurfaceTool::VResolution(Caro,Precision::Confusion());
 
@@ -211,15 +226,137 @@ void IntWalk_IWalking::Perform(const ThePOPIterator& Pnts1,
 
   // calculation of all open lines   
   if (nbPnts1 != 0)
-    ComputeOpenLine(Umult,Vmult,Pnts1,Func,Rajout); 
-
+    ComputeOpenLine(Umult,Vmult,Pnts1,Func,Rajout);
   // calculation of all closed lines 
-  if (nbPnts2 != 0)
-    ComputeCloseLine(Umult,Vmult,Pnts1,Pnts2,Func,Rajout); 
-  
+  if (nbPnts2 != 0 || nbPnts3 != 0)
+    ComputeCloseLine(Umult,Vmult,Pnts1,Pnts2,Pnts3,Func,Rajout); 
   for (I = 1; I <= nbPnts1; I++) { 
     if (wd1[I].etat >0) seqSingle.Append(Pnts1(I));
   }
+
+  //Split non-tangency lines by extremities of tangency lines
+  IntSurf_SequenceOfPntOn2S EndsOfTangencies;
+  Standard_Integer i, j, k;
+  const Standard_Real TolSq = Precision::Confusion() * Precision::Confusion();
+  for (i = 1; i <= lines.Length(); i++)
+    if (lines(i)->IsTangency())
+    {
+      const IntSurf_PntOn2S& anEndPointOn2S = lines(i)->Value(1);
+      const gp_Pnt& anEndPnt = anEndPointOn2S.Value();
+      Standard_Boolean exists = Standard_False;
+      for (j = 1; j <= EndsOfTangencies.Length(); j++)
+      {
+        const gp_Pnt& anEndOfTang = EndsOfTangencies(j).Value();
+        if (anEndOfTang.SquareDistance(anEndPnt) <= TolSq)
+        {
+          exists = Standard_True;
+          break;
+        }
+      }
+      if (!exists)
+        EndsOfTangencies.Append(anEndPointOn2S);
+      if (!lines(i)->IsClosed())
+      {
+        const IntSurf_PntOn2S& anEndPointOn2S = lines(i)->Value(lines(i)->NbPoints());
+        const gp_Pnt& anEndPnt = anEndPointOn2S.Value();
+        exists = Standard_False;
+        for (j = 1; j <= EndsOfTangencies.Length(); j++)
+        {
+          const gp_Pnt& anEndOfTang = EndsOfTangencies(j).Value();
+          if (anEndOfTang.SquareDistance(anEndPnt) <= TolSq)
+          {
+            exists = Standard_True;
+            break;
+          }
+        }
+        if (!exists)
+          EndsOfTangencies.Append(anEndPointOn2S);
+      }
+    }
+
+  if (!EndsOfTangencies.IsEmpty())
+  {
+    TColStd_Array1OfBoolean SplitFlags(1, EndsOfTangencies.Length());
+    SplitFlags.Init(Standard_False);
+    
+    for (;;)
+    {
+      for (i = 1; i <= lines.Length(); i++)
+        if (!lines(i)->IsTangency())
+        {
+          Standard_Boolean IsSplit = Standard_False;
+          for (j = 1; j <= EndsOfTangencies.Length(); j++)
+          {
+            if (SplitFlags(j))
+              continue;
+            //gp_Pnt2d endoftang = EndsOfTangencies(j).ValueOnSurface(reversed);
+            gp_Pnt endoftang = EndsOfTangencies(j).Value();
+            for (k = 2; k < lines(i)->NbPoints()-1; k++)
+            {
+              const IntSurf_PntOn2S& P1 = lines(i)->Value(k);
+              const IntSurf_PntOn2S& P2 = lines(i)->Value(k+1);
+              //gp_Pnt2d pt1 = P1.ValueOnSurface(reversed);
+              //gp_Pnt2d pt2 = P2.ValueOnSurface(reversed);
+              const gp_Pnt& pt1 = P1.Value();
+              const gp_Pnt& pt2 = P2.Value();
+              //gp_Vec2d V1(endoftang, pt1);
+              //gp_Vec2d V2(endoftang, pt2);
+              gp_Vec V1(endoftang, pt1);
+              gp_Vec V2(endoftang, pt2);
+              Standard_Real ScalProd = V1 * V2;
+              if (ScalProd < 0.)
+              {
+                SplitFlags(j) = Standard_True;
+                Standard_Boolean ToRemoveFirstPnt = Standard_False, ToRemoveSecondPnt = Standard_False;
+                /*
+                Standard_Real Dist = pt1.Distance(pt2);
+                Standard_Real DistToFirst   = endoftang.Distance(pt1);
+                Standard_Real DistToSecond  = endoftang.Distance(pt2);
+                if (DistToFirst < Max(2.*Precision::Confusion(), 0.5*Dist))
+                  ToRemoveFirstPnt = Standard_True;
+                if (DistToSecond < Max(2.*Precision::Confusion(), 0.5*Dist))
+                  ToRemoveSecondPnt = Standard_True;
+                */
+                Standard_Real SqDist = pt1.SquareDistance(pt2);
+                Standard_Real SqDistToFirst   = endoftang.SquareDistance(pt1);
+                Standard_Real SqDistToSecond  = endoftang.SquareDistance(pt2);
+                if (SqDistToFirst < Max(4.*TolSq, 0.25*SqDist))
+                  ToRemoveFirstPnt = Standard_True;
+                if (SqDistToSecond < Max(4.*TolSq, 0.25*SqDist))
+                  ToRemoveSecondPnt = Standard_True;
+                Handle(IntWalk_TheIWLine) aNewLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
+                aNewLine->SetTangencyAtBegining(Standard_True);
+                aNewLine->AddStatusFirst(Standard_False, Standard_False);
+                aNewLine->AddPoint(EndsOfTangencies(j));
+                for (Standard_Integer kk = (ToRemoveSecondPnt)? k+2 : k+1;
+                     kk <= lines(i)->NbPoints(); kk++)
+                  aNewLine->AddPoint(lines(i)->Value(kk));
+                if (lines(i)->HasLastPoint())
+                  aNewLine->AddStatusLast(Standard_True, lines(i)->LastPointIndex(), lines(i)->LastPoint());
+                else
+                  aNewLine->AddStatusLast(Standard_False);
+                aNewLine->SetTangencyAtEnd(lines(i)->IsTangentAtEnd());
+                lines.Append(aNewLine);
+                lines(i)->Cut((ToRemoveFirstPnt)? k : k+1);
+                lines(i)->AddPoint(EndsOfTangencies(j));
+                lines(i)->AddStatusLast(Standard_False);
+                lines(i)->SetTangencyAtEnd(Standard_True);
+                IsSplit = Standard_True;
+                break;
+              }
+            }
+            if (IsSplit)
+              break;
+          }
+          if (IsSplit)
+            break;
+        }
+      if (i > lines.Length())
+        break;
+    }
+  }
+  ///////////////////////////////////////////////////////////
+  
   done = Standard_True;
 }
 
index f54b7a498a287e55cc9bc2d87eab843456948a0c..2ac369ddcb5224ece493e3a85ac9c0f984e460d6 100644 (file)
@@ -214,43 +214,45 @@ Standard_Boolean IntWalk_IWalking::TestArretPassage
     previousPoint.ParametersOnS1(Up,Vp);
   }
 
-  for (size_t i = 1; i < wd2.size(); i++) { 
-    if (wd2[i].etat > 0) { 
-      // debug jag 05.04.94
-
-//      if ((Up-wd2[i].ustart)*(UV(1)-wd2[i].ustart) +
-//       (Vp-wd2[i].vstart)*(UV(2)-wd2[i].vstart) <= 0)
-      Utest = wd2[i].ustart;
-      Vtest = wd2[i].vstart;
-
-      Du  = UV(1)-Utest;
-      Dv  = UV(2)-Vtest;
-      Dup = Up - Utest;
-      Dvp = Vp - Vtest;
-      
-//-- lbr le 30 oct 97 
-
-      //IFV for OCC20285
-
-      if ((Abs(Du) < tolu2 && Abs(Dv) < tolv2) ||
-         (Abs(Dup) < tolu2 && Abs(Dvp) < tolv2)) { 
-           
-       wd2[i].etat = -wd2[i].etat;
-      }
-      else {
-       Standard_Real DDu = (UV(1)-Up);
-       Standard_Real DDv = (UV(2)-Vp);
-       Standard_Real DDD = DDu*DDu+DDv*DDv;
-       Standard_Real DD1 = Du*Du+Dv*Dv;
-       if(DD1<=DDD) { 
-         Standard_Real DD2 = Dup*Dup+Dvp*Dvp;
-         if(DD2<=DDD && ((Du*Dup) + (Dv*Dvp*tolu/tolv) <= 0.)) {       
-           wd2[i].etat = -wd2[i].etat;
-         }
-       }
+  IntWalk_VectorOfWalkingData* wdata [2] = {&wd2, &wd3};
+  for (Standard_Integer ind = 0; ind < 2; ind++)
+    for (size_t i = 1; i < wdata[ind]->size(); i++) { 
+      if ((*(wdata[ind]))[i].etat > 0) { 
+        // debug jag 05.04.94
+        
+        //      if ((Up-wd2[i].ustart)*(UV(1)-wd2[i].ustart) +
+        //       (Vp-wd2[i].vstart)*(UV(2)-wd2[i].vstart) <= 0)
+        Utest = (*(wdata[ind]))[i].ustart;
+        Vtest = (*(wdata[ind]))[i].vstart;
+        
+        Du  = UV(1)-Utest;
+        Dv  = UV(2)-Vtest;
+        Dup = Up - Utest;
+        Dvp = Vp - Vtest;
+        
+        //-- lbr le 30 oct 97 
+        
+        //IFV for OCC20285
+        
+        if ((Abs(Du) < tolu2 && Abs(Dv) < tolv2) ||
+            (Abs(Dup) < tolu2 && Abs(Dvp) < tolv2)) { 
+          
+          (*(wdata[ind]))[i].etat = -(*(wdata[ind]))[i].etat;
+        }
+        else {
+          Standard_Real DDu = (UV(1)-Up);
+          Standard_Real DDv = (UV(2)-Vp);
+          Standard_Real DDD = DDu*DDu+DDv*DDv;
+          Standard_Real DD1 = Du*Du+Dv*Dv;
+          if(DD1<=DDD) { 
+            Standard_Real DD2 = Dup*Dup+Dvp*Dvp;
+            if(DD2<=DDD && ((Du*Dup) + (Dv*Dvp*tolu/tolv) <= 0.)) {    
+              (*(wdata[ind]))[i].etat = -(*(wdata[ind]))[i].etat;
+            }
+          }
+        }
       }
     }
-  }
 
   // stop test on point given at input and not yet processed
 
@@ -473,6 +475,62 @@ Standard_Boolean IntWalk_IWalking::TestArretPassage
       }
     }
   }
+  for (k = 1; k < (int)wd3.size(); k++) { 
+    if (wd3[k].etat > 0) {
+      Utest = wd3[k].ustart;
+      Vtest = wd3[k].vstart;
+      
+      Utest/=deltau;
+      Vtest/=deltav;
+      
+      Standard_Real UV1mUtest=UV1-Utest;
+      Standard_Real UV2mVtest=UV2-Vtest;
+      if(   (UV1mUtest<tolu2 && UV1mUtest>-tolu2)
+        && (UV2mVtest<tolv2 && UV2mVtest>-tolv2)) {
+        
+         wd3[k].etat = -wd3[k].etat; //-- mark the point as a crossing point 
+      }
+      else { 
+       Standard_Real UpmUtest = (Up-Utest);
+       Standard_Real VpmVtest = (Vp-Vtest);
+       Standard_Real dPreviousStart = (UpmUtest)*(UpmUtest)+(VpmVtest)*(VpmVtest);
+       Standard_Real dCurrentStart  = UV1mUtest * UV1mUtest + UV2mVtest * UV2mVtest;
+
+       Scal=(UpmUtest)*(UV1mUtest)+(VpmVtest)*(UV2mVtest);
+       if( (Abs(UpmUtest)<tolu && Abs(VpmVtest)<tolv)) {
+          
+           wd3[k].etat = -wd3[k].etat;
+       }
+       else if(Scal<0 && (dPreviousStart+dCurrentStart < dPreviousCurrent)) {
+          
+           wd3[k].etat = -wd3[k].etat; // mark the point as a crossing point 
+       }
+       else {
+         if(dPreviousStart < dPreviousCurrent*0.25) {
+            
+           wd3[k].etat = -wd3[k].etat; // mark the point as a crossing point 
+           //-- cout<<"**** etat2 : ("<<k<<")"<<endl;
+         }
+         else { 
+           if(dCurrentStart < dPreviousCurrent*0.25) {
+             //-- cout<<"***** etat2 : ("<<k<<")"<<endl;
+             wd3[k].etat = -wd3[k].etat; // mark the point as a crossing point 
+           }
+           else { 
+             Standard_Real UMidUtest = 0.5*(UV1+Up)-Utest;
+             Standard_Real VMidVtest = 0.5*(UV2+Vp)-Vtest;         
+             Standard_Real dMiddleStart =  UMidUtest*UMidUtest + VMidVtest*VMidVtest;
+
+             if(dMiddleStart < dPreviousCurrent*0.5) { 
+               //-- cout<<"*********** etat2 : ("<<k<<")"<<endl;
+               wd3[k].etat = -wd3[k].etat; // mark the point as a crossing point 
+             }
+           }
+         }
+       }
+      }
+    }
+  }
 
   // crossing test on crossing points.
   
@@ -507,12 +565,172 @@ Standard_Boolean IntWalk_IWalking::TestArretPassage
   return Arrive;
 }
 
+Standard_Boolean IntWalk_IWalking::TestArretPassageTang
+  (const TColStd_SequenceOfReal& Umult,
+   const TColStd_SequenceOfReal& Vmult,
+   const math_Vector& UV, 
+   const Standard_Integer Index, 
+   Standard_Integer& Irang)
+{
+// Umult, Vmult : table of stop (or crossing) points on border, here
+//          only crossing points are taken into account.
+// UV     : the current point.
+// Index  : index of the start point in uvstart2 of the current line
+//          (this is an interior point).
+// Irang  : at output : gives the index of the point passing in uvstart1 or 0.
+//          consider that there is risk to cross only one crossing point.
+
+// test of stop for a CLOSED intersection line.
+// 1) test of crossing on all interior points.
+// 2) test of crossing on all crossing points.
+
+  Standard_Real Up, Vp, Scal;
+  Standard_Boolean Arrive = Standard_False;
+  Standard_Integer N, k, i;
+  Standard_Real Utest,Vtest;
+  Standard_Real tolu = tolerance(1);
+  Standard_Real tolv = tolerance(2);
+
+  
+  // tests of stop and of crossing on all interior points.
+
+  if (!reversed) {
+    previousPoint.ParametersOnS2(Up,Vp);
+  }
+  else {
+    previousPoint.ParametersOnS1(Up,Vp);
+  }
+
+  Standard_Real UV1=UV(1);
+  Standard_Real UV2=UV(2);
+
+
+  //-- Put everything in one box 0 1  x 0 1 
+  //-- actually it is necessary to carry out tests in 3D
+
+  Standard_Real deltau=UM-Um;
+  Standard_Real deltav=VM-Vm;
+
+  Up/=deltau; UV1/=deltau; 
+  Vp/=deltav; UV2/=deltav;
+
+  tolu/=deltau;
+  tolv/=deltav;
+
+  Standard_Real tolu2=tolu+tolu;
+  Standard_Real tolv2=tolv+tolv;
+
+  
+  Standard_Real dPreviousCurrent = (Up-UV1)*(Up-UV1)+(Vp-UV2)*(Vp-UV2);
+  for (k = 1; k < (int)wd3.size(); k++) { 
+    if (wd3[k].etat > 0) {
+      Utest = wd3[k].ustart;
+      Vtest = wd3[k].vstart;
+      
+      Utest/=deltau;
+      Vtest/=deltav;
+      
+      Standard_Real UV1mUtest=UV1-Utest;
+      Standard_Real UV2mVtest=UV2-Vtest;
+      if(   (UV1mUtest<tolu2 && UV1mUtest>-tolu2)
+        && (UV2mVtest<tolv2 && UV2mVtest>-tolv2)) { 
+       if(Index!=k) { 
+         //-- cout<<"* etat2 : ("<<k<<")"<<endl;
+         wd3[k].etat = -wd3[k].etat; //-- mark the point as a crossing point 
+       }
+       else {  //-- Index == k
+         //-- cout<<"* Arrive"<<endl;
+         Arrive=Standard_True;
+       }
+      }
+      else { 
+       Standard_Real UpmUtest = (Up-Utest);
+       Standard_Real VpmVtest = (Vp-Vtest);
+       Standard_Real dPreviousStart = (UpmUtest)*(UpmUtest)+(VpmVtest)*(VpmVtest);
+       Standard_Real dCurrentStart  = UV1mUtest * UV1mUtest + UV2mVtest * UV2mVtest;
+
+       Scal=(UpmUtest)*(UV1mUtest)+(VpmVtest)*(UV2mVtest);
+       if( (Abs(UpmUtest)<tolu && Abs(VpmVtest)<tolv)) { 
+         if(Index != k ) { 
+           //-- cout<<"** etat2 : ("<<k<<")"<<endl;
+           wd3[k].etat = -wd3[k].etat;
+         }
+       }
+       else if(Scal<0 && (dPreviousStart+dCurrentStart < dPreviousCurrent)) { 
+         if (Index == k ) { // on a boucle.
+           Arrive = Standard_True;
+           //-- cout<<"** Arrive  : k="<<k<<endl;
+         }
+         else {
+           //-- cout<<"*** etat2 : ("<<k<<")"<<endl;
+           wd3[k].etat = -wd3[k].etat; // mark the point as a crossing point 
+         }
+       }
+       else if(k!=Index) {
+         if(dPreviousStart < dPreviousCurrent*0.25) { 
+           wd3[k].etat = -wd3[k].etat; // mark the point as a crossing point 
+           //-- cout<<"**** etat2 : ("<<k<<")"<<endl;
+         }
+         else { 
+           if(dCurrentStart < dPreviousCurrent*0.25) {
+             //-- cout<<"***** etat2 : ("<<k<<")"<<endl;
+             wd3[k].etat = -wd3[k].etat; // mark the point as a crossing point 
+           }
+           else { 
+             Standard_Real UMidUtest = 0.5*(UV1+Up)-Utest;
+             Standard_Real VMidVtest = 0.5*(UV2+Vp)-Vtest;         
+             Standard_Real dMiddleStart =  UMidUtest*UMidUtest + VMidVtest*VMidVtest;
+
+             if(dMiddleStart < dPreviousCurrent*0.5) { 
+               //-- cout<<"*********** etat2 : ("<<k<<")"<<endl;
+               wd3[k].etat = -wd3[k].etat; // mark the point as a crossing point 
+             }
+           }
+         }
+       }
+      }
+    }
+  }
+
+  // crossing test on crossing points.
+  
+  Irang =0;
+  for (i = 1; i < (int)wd1.size(); i++) {
+    if (wd1[i].etat > 0 && wd1[i].etat < 11) { //test of crossing points 
+      Utest = wd1[i].ustart;
+      Vtest = wd1[i].vstart;
+      Utest/=deltau;
+      Vtest/=deltav;
+      
+      if (((Up-Utest) * (UV1-Utest) + (Vp-Vtest) * (UV2-Vtest) < 0) ||
+         (Abs(UV1-Utest) < tolu &&  Abs(UV2-Vtest) < tolv)) 
+       Irang = i;
+      else if (nbMultiplicities[i] > 0) {
+       N=0;
+       for (k = 1; k < i; k++) N = N + nbMultiplicities[k];
+       for (Standard_Integer j = N + 1; j <= N + nbMultiplicities[i]; j++) {
+         Standard_Real Umultj = Umult(j)/deltau;
+         Standard_Real Vmultj = Vmult(j)/deltav;         
+          if (((Up-Umultj)*(UV1-Umultj) +
+              (Vp-Vmultj)*(UV2-Vmultj) < 0) ||
+             (Abs(UV1-Umultj) < tolu &&
+              Abs(UV2-Vmultj) < tolv)) {
+           Irang=i;
+           break;
+          }
+       }
+      }
+    }    
+  }
+  return Arrive;
+}
 
 Standard_Boolean IntWalk_IWalking::TestArretAjout
   (TheIWFunction& sp,
    math_Vector& UV, 
    Standard_Integer& Irang,
-   IntSurf_PntOn2S& Psol) 
+   IntSurf_PntOn2S& Psol,
+   Standard_Boolean& OnPrevTangency)
 
 // test of stop on added points 
 // these are the points on the natural biorder that were not given at input
@@ -559,7 +777,8 @@ Standard_Boolean IntWalk_IWalking::TestArretAjout
          (Abs(UV(1)-U1) < tolerance(1) &&  
           Abs(UV(2)-V1) < tolerance(2))) {
 //jag 940615   Irang= -Abs(Irang); 
-       Arrive = Standard_True; 
+       Arrive = Standard_True;
+        OnPrevTangency = Line->IsTangency();
        UV(1) = U1;
        UV(2) = V1;
        Standard_Real abidF[1], abidD[1][2];
index 6bc7b7a133e82c2ef66a377371bf398a056c7875..a32180eb81eb2cc4f728307b889f1c184be19d2c 100644 (file)
@@ -66,10 +66,12 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
   Standard_Integer I, N;
   Standard_Real aBornInf[2], aBornSup[2], aUVap[2];
   math_Vector BornInf(aBornInf,1,2), BornSup(aBornSup,1,2), UVap(aUVap,1,2);
-  Standard_Real PasC, PasCu, PasCv;
+  Standard_Real PasC, PasCu, PasCv, PasInit; //PasSav;
   Standard_Boolean Arrive; // shows if the line ends
   Standard_Boolean Cadre;  // shows if one is on border of the domain
   Standard_Boolean ArretAjout;  //shows if one is on added point
+  Standard_Boolean PrevStepWrong; //shows was Rsnld successful or not
+  Standard_Boolean OnPrevTangency; //shows if one is on added point of tangent line
   IntSurf_PntOn2S Psol;
   Handle(IntWalk_TheIWLine)  CurrentLine;    // line under construction
   Standard_Boolean Tgtend;
@@ -80,6 +82,9 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
   // number of divisions of step for each section
 
   Standard_Integer StepSign;
+  Standard_Integer StepSignTangent;
+  Standard_Integer SignOfBcoeff = 0;
+  Standard_Integer PrevSignOfBcoeff = SignOfBcoeff;
   
   ThePointOfPath PathPnt;
 
@@ -105,11 +110,16 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
     // 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);
+#ifdef DRAW
+      cout<<"PathPnt("<<I<<"):"<<endl;
+#endif
       CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
       CurrentLine->SetTangencyAtBegining(Standard_False);
       Tgtend = Standard_False;
       CurrentLine->AddStatusFirst(Standard_False, Standard_True, I, PathPnt);
+      IsTangentialIntersection = Standard_False;
+      SignOfBcoeff = PrevSignOfBcoeff = 0;
       UVap(1) = wd1[I].ustart;
       UVap(2) = wd1[I].vstart;
       MakeWalkingPoint(11, UVap(1), UVap(2), Func, previousPoint);
@@ -118,27 +128,27 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
       CurrentLine->AddPoint(previousPoint);
       // modified by NIZHNY-MKK  Fri Oct 27 12:34:32 2000.BEGIN
       if(movementdirectioninfo[I] !=0) {
-        if(movementdirectioninfo[I] < 0) {
-          StepSign = -1;
-          CurrentLine->SetTangentVector(previousd3d.Reversed(),1);
-        } else {
-          StepSign = 1; 
-          CurrentLine->SetTangentVector(previousd3d,1);
-        }
+       if(movementdirectioninfo[I] < 0) {
+         StepSign = -1;
+         CurrentLine->SetTangentVector(previousd3d.Reversed(),1);
+       } else {
+         StepSign = 1; 
+         CurrentLine->SetTangentVector(previousd3d,1);
+       }
       } else {
-        Standard_Real tyutuyt=ThePointOfPathTool::Direction3d(PathPnt) * previousd3d;
-        if( tyutuyt < 0) {
-          StepSign = -1;
-          CurrentLine->SetTangentVector(previousd3d.Reversed(),1);
-        }
-        else {
-          StepSign = 1; 
-          CurrentLine->SetTangentVector(previousd3d,1);
-        }
+       Standard_Real tyutuyt=ThePointOfPathTool::Direction3d(PathPnt) * previousd3d;
+       if( tyutuyt < 0) {
+         StepSign = -1;
+         CurrentLine->SetTangentVector(previousd3d.Reversed(),1);
+       }
+       else {
+         StepSign = 1; 
+         CurrentLine->SetTangentVector(previousd3d,1);
+       }
       }
       // modified by NIZHNY-MKK  Fri Oct 27 12:34:37 2000.END
 
-      //  Modified by Sergey KHROMOV - Tue Nov 20 10:41:45 2001 Begin
+//  Modified by Sergey KHROMOV - Tue Nov 20 10:41:45 2001 Begin
       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
@@ -146,300 +156,355 @@ void IntWalk_IWalking::ComputeOpenLine(const TColStd_SequenceOfReal& Umult,
       Standard_Real d2dx = Abs(previousd2d.X()); 
       Standard_Real d2dy = Abs(previousd2d.Y()); 
       if (d2dx < tolerance(1)) {
-        PasC = pas * (VM-Vm)/d2dy;
+       PasC = pas * (VM-Vm)/d2dy;
       }
       else if (d2dy < tolerance(2)) {
-        PasC = pas * (UM-Um)/d2dx;
+       PasC = pas * (UM-Um)/d2dx;
       }
       else {
-        PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
+       PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
       }
 
+      PasInit = PasC;
+      //PasSav = PasC;
+
       Arrive = Standard_False;
       ArretAjout = Standard_False;
+      PrevStepWrong = Standard_False;
+      OnPrevTangency = Standard_False;
       NbDivision = 0;
       StatusPrecedent = IntWalk_OK;
       // modified by NIZHNY-MKK  Fri Oct 27 12:39:37 2000
       Standard_Integer IndexOfPathPointDoNotCheck=0;
-      Standard_Integer aNbIter = 10;
+
       while (!Arrive) { //    as one of stop tests is not checked
-        Cadre = Cadrage(BornInf,BornSup,UVap,PasC,StepSign);
-        //  Border?
+
+       Cadre = Cadrage(BornInf,BornSup,UVap,PasC,StepSign);
+       //  Border?
 
 #ifdef CHRONO
-        Chronrsnld.Start();
+       Chronrsnld.Start();
 #endif
 
-        Rsnld.Perform(Func,UVap,BornInf,BornSup);
+       Rsnld.Perform(Func,UVap,BornInf,BornSup);
 
 #ifdef CHRONO
-        Chronrsnld.Stop();
+       Chronrsnld.Stop();
 #endif
 
-        if (Cadre) {
-          BornInf(1) = Um; BornSup(1) = UM; BornInf(2) = Vm; BornSup(2) = VM;
-        }
-        if (Rsnld.IsDone()) {
-          if (Abs(Func.Root()) > Func.Tolerance()) {
-            PasC = PasC / 2.0;
-            PasCu = Abs(PasC*previousd2d.X());
-            PasCv = Abs(PasC*previousd2d.Y());
-            if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
-              if (CurrentLine->NbPoints() == 1) break;
-              Arrive = Standard_True;
-              CurrentLine->AddStatusLast(Standard_False);
-              Tgtend = Standard_True; // check
+       if (Cadre) {
+         BornInf(1) = Um; BornSup(1) = UM; BornInf(2) = Vm; BornSup(2) = VM;
+       }
+       if (Rsnld.IsDone()) {
+         if (Abs(Func.Root()) > Func.Tolerance()) {
+            PrevStepWrong = Standard_True;
+           PasC = PasC / 2.0;
+           PasCu = Abs(PasC*previousd2d.X());
+           PasCv = Abs(PasC*previousd2d.Y());
+           if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
+             if (CurrentLine->NbPoints() == 1) break;
+             Arrive = Standard_True;
+             CurrentLine->AddStatusLast(Standard_False);
+             Tgtend = Standard_True; // check
               Rajout = Standard_True;
-              seqAjout.Append(lines.Length() + 1);
-            }  
-          }
-          else { // test stop
-            Rsnld.Root(UVap);
-            Arrive = TestArretPassage(Umult, Vmult, Func, UVap, N);
-            if (Arrive) {
-              Cadre = Standard_False;
-              //in case if there is a frame and arrive at the same time
-            }
-            else {
-              if (Rajout) {
-                ArretAjout =TestArretAjout(Func, UVap, N, Psol);
-                if (ArretAjout) {
-                  // jag 940615
-                  Tgtend = lines.Value(N)->IsTangentAtEnd();
-                  N = -N;
-                }
-              }
-              // modified by NIZHNY-MKK  Thu Nov  2 15:09:08 2000.BEGIN
-              if(!(Rajout && ArretAjout)) {
-                Standard_Real prevUp, prevVp;
-                if (!reversed) {
-                  previousPoint.ParametersOnS2(prevUp, prevVp);
-                }
-                else {
-                  previousPoint.ParametersOnS1(prevUp, prevVp);
-                }
-                Arrive = TestPassedSolutionWithNegativeState(wd1, Umult, Vmult, prevUp, prevVp,
-                  nbMultiplicities, tolerance, Func, UVap, N);         
-                if(Arrive) {
-                  Cadre = Standard_False;
-                }
-              }
-              // modified by NIZHNY-MKK  Thu Nov  2 15:09:13 2000.END
-              if (!ArretAjout && Cadre) {
-                if (CurrentLine->NbPoints() == 1) break; // cancel the line
-                TestArretCadre(Umult, Vmult, CurrentLine, Func, UVap, N);
-                //             if (N == 0) {
-                if (N <= 0) { // jag 941017
-                  MakeWalkingPoint(2, UVap(1), UVap(2), Func, Psol);
-                  Tgtend = Func.IsTangent();
+             seqAjout.Append(lines.Length() + 1);
+           }  
+         }
+         else { // test stop
+           Rsnld.Root(UVap);
+           Arrive = TestArretPassage(Umult, Vmult, Func, UVap, N);
+           if (Arrive) {
+             Cadre = Standard_False;
+             //in case if there is a frame and arrive at the same time
+           }
+           else {
+             if (Rajout) {
+               ArretAjout =TestArretAjout(Func, UVap, N, Psol, OnPrevTangency);
+               if (ArretAjout) {
+                 // jag 940615
+                 Tgtend = lines.Value(N)->IsTangentAtEnd();
+                 N = -N;
+               }
+             }
+             // modified by NIZHNY-MKK  Thu Nov  2 15:09:08 2000.BEGIN
+             if(!(Rajout && ArretAjout)) {
+               Standard_Real prevUp, prevVp;
+               if (!reversed) {
+                 previousPoint.ParametersOnS2(prevUp, prevVp);
+               }
+               else {
+                 previousPoint.ParametersOnS1(prevUp, prevVp);
+               }
+               Arrive = TestPassedSolutionWithNegativeState(wd1, Umult, Vmult, prevUp, prevVp,
+                                                            nbMultiplicities, tolerance, Func, UVap, N);               
+               if(Arrive) {
+                 Cadre = Standard_False;
+               }
+             }
+             // modified by NIZHNY-MKK  Thu Nov  2 15:09:13 2000.END
+             if (!ArretAjout && Cadre) {
+               if (CurrentLine->NbPoints() == 1) break; // cancel the line
+               TestArretCadre(Umult, Vmult, CurrentLine, Func, UVap, N);
+//             if (N == 0) {
+               if (N <= 0) { // jag 941017
+                 MakeWalkingPoint(2, UVap(1), UVap(2), Func, Psol);
+                 Tgtend = Func.IsTangent();
                   N = -N;
+               }
+             }
+           }
+           Status = TestDeflection(Func, Arrive, UVap, StatusPrecedent,
+                                   NbDivision,PasC,PasInit,StepSign,
+                                    CurrentLine->NbPoints(),ArretAjout,PrevStepWrong,OnPrevTangency);
+           StatusPrecedent = Status;
+
+            if (Status == IntWalk_ArretSurPoint && Func.IsTangent())
+            {
+              PrevSignOfBcoeff = SignOfBcoeff;
+              gp_Vec   newd3d;
+              gp_Dir2d newd2d;
+              Standard_Boolean IsDiscriminantNull;
+              if (ComputeDirOfTangentialIntersection(Func, StepSignTangent,
+                                                     IsDiscriminantNull, SignOfBcoeff,
+                                                     newd3d, newd2d) &&
+                  IsDiscriminantNull)
+              {
+                if (SignOfBcoeff == 0) //point of branching
+                  Status = IntWalk_ArretSurPoint;
+                else
+                {
+                  if (PrevSignOfBcoeff == 0 ||
+                      SignOfBcoeff == PrevSignOfBcoeff)
+                  {
+                    Status = IntWalk_OKtangent;
+                    MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint);
+                    previousd3d = newd3d;
+                    previousd2d = newd2d;
+                    CurrentLine->AddPoint(previousPoint);
+                  }
+                  else //change of sign of Bcoeff
+                  {
+                    MakeWalkingPoint(1, UVap(1), UVap(2), Func, Psol);
+                    FindExactCuspPoint(Func, Psol,
+                                       PrevSignOfBcoeff, SignOfBcoeff);
+                    Psol.ParametersOnSurface(reversed, UVap(1), UVap(2));
+                    Status = IntWalk_ArretSurPoint;
+                  }
                 }
               }
             }
-            Status = TestDeflection(Func, Arrive, UVap, StatusPrecedent,
-              NbDivision,PasC,StepSign);
-            StatusPrecedent = Status;
-            if (Status == IntWalk_PasTropGrand) {
-              Arrive = Standard_False;
-              ArretAjout = Standard_False;
-              Tgtend = Standard_False; // jag 940615
-              if (!reversed) {
-                previousPoint.ParametersOnS2(UVap(1), UVap(2));
-              }
-              else {
-                previousPoint.ParametersOnS1(UVap(1), UVap(2));
-              }
-            }
-            else if (ArretAjout || Cadre) {
-              Arrive = Standard_True;
-              CurrentLine->AddStatusLast(Standard_False);
-              if (Status != IntWalk_ArretSurPointPrecedent) {
-                CurrentLine->AddPoint(Psol);                      
-              }
-              if (Cadre && N==0) {
-                Rajout = Standard_True;
-                seqAjout.Append(lines.Length()+1);
-              }
+            
+           if (Status == IntWalk_PasTropGrand) {
+             Arrive = Standard_False;
+             ArretAjout = Standard_False;
+             Tgtend = Standard_False; // jag 940615
+             if (!reversed) {
+               previousPoint.ParametersOnS2(UVap(1), UVap(2));
+             }
+             else {
+               previousPoint.ParametersOnS1(UVap(1), UVap(2));
+             }
+           }
+           else if (ArretAjout || Cadre) {
+             Arrive = Standard_True;
+             CurrentLine->AddStatusLast(Standard_False);
+             if (Status != IntWalk_ArretSurPointPrecedent) {
+               CurrentLine->AddPoint(Psol);                      
+             }
+             if (Cadre && N==0) {
+               Rajout = Standard_True;
+               seqAjout.Append(lines.Length()+1);
+             }
+           }
+            /*
+           else if (Status == IntWalk_ArretSurPointPrecedent &&
+                     !Func.IsTangent()) //continue the line because no tangent point
+            {
+              Status = IntWalk_OK;
+              StatusPrecedent = IntWalk_OK;
+              PasC = PasSav;
+              MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint);
+             previousd3d = Func.Direction3d();
+             previousd2d = Func.Direction2d();
+             CurrentLine->AddPoint(previousPoint);
             }
-            else if (Status == IntWalk_ArretSurPointPrecedent) {
-              if (CurrentLine->NbPoints() == 1) { //cancel the line
-                Arrive = Standard_False;
-                break;
-              }
-              Arrive = Standard_True;
-              Rajout = Standard_True;
+            */
+           else if (Status == IntWalk_ArretSurPointPrecedent) {
+             if (CurrentLine->NbPoints() == 1) { //cancel the line
+               Arrive = Standard_False;
+               break;
+             }
+             Arrive = Standard_True;
+             Rajout = Standard_True;
               seqAjout.Append(lines.Length() + 1);
-              CurrentLine->AddStatusLast(Standard_False);
-              Tgtend = Standard_True; // check
-            }
-            else if (Arrive)  {
-              if (CurrentLine->NbPoints() == 1 &&    // cancel the line
-                (N == I || Status == IntWalk_PointConfondu) ) {
-                  // if N == I the main uv is probably lost
-                  // or the point is a point of accumulation
-                  // if point is confused the start data is bad
-                  Arrive =  Standard_False;
-                  break;
-              }
-              // necessairily N > 0 jag 940617
+             CurrentLine->AddStatusLast(Standard_False);
+             Tgtend = Standard_True; // check
+           }
+           else if (Arrive)  {
+             if (CurrentLine->NbPoints() == 1 &&    // cancel the line
+                 (N == I || Status == IntWalk_PointConfondu) ) {
+               // if N == I the main uv is probably lost
+               // or the point is a point of accumulation
+               // if point is confused the start data is bad
+               Arrive =  Standard_False;
+               break;
+             }
+             // necessairily N > 0 jag 940617
               // point of stop given at input 
-              PathPnt = Pnts1.Value(N);
+             PathPnt = Pnts1.Value(N);
+             
+             Standard_Integer etat1N=wd1[N].etat;
+             // modified by NIZHNY-MKK  Thu Nov  2 15:09:51 2000.BEGIN
+             //              if (etat1N < 11) { // passing point that is a stop  
+             if (Abs(etat1N) < 11) { // passing point that is a stop    
+               // modified by NIZHNY-MKK  Thu Nov  2 15:12:11 2000.END
+               if (Status == IntWalk_ArretSurPoint) { 
+                 CurrentLine->AddStatusLast(Standard_False);
+                 Tgtend = Standard_True; // need check
+               }
+               else { 
+                 Arrive = Standard_False;
+               }
+               CurrentLine->AddIndexPassing(N);
+             }
+             else { // point of stop given at input
+               if (etat1N == 11) {
+                 Tgtend = Standard_True;
+               }
+               CurrentLine->AddStatusLast(Standard_True, N, PathPnt);
+             }
+             AddPointInCurrentLine(N,PathPnt,CurrentLine);
+             if ((etat1N != 1 && etat1N != 11)) {
+               // modified by NIZHNY-MKK  Fri Oct 27 12:43:05 2000.BEGIN
+               //              wd1[N].etat= - wd1[N].etat;
+               wd1[N].etat = - Abs(etat1N);            
+               movementdirectioninfo[N] = (movementdirectioninfo[N]==0) ? StepSign : 0;
+               if(Arrive && movementdirectioninfo[N]!=0) {
+                 IndexOfPathPointDoNotCheck = N;
+               }
 
-              Standard_Integer etat1N=wd1[N].etat;
-              // modified by NIZHNY-MKK  Thu Nov  2 15:09:51 2000.BEGIN
-              //             if (etat1N < 11) { // passing point that is a stop  
-              if (Abs(etat1N) < 11) { // passing point that is a stop    
-                // modified by NIZHNY-MKK  Thu Nov  2 15:12:11 2000.END
-                if (Status == IntWalk_ArretSurPoint) { 
-                  CurrentLine->AddStatusLast(Standard_False);
-                  Tgtend = Standard_True; // need check
-                }
-                else { 
-                  Arrive = Standard_False;
-                }
-                CurrentLine->AddIndexPassing(N);
-              }
-              else { // point of stop given at input
-                if (etat1N == 11) {
-                  Tgtend = Standard_True;
-                }
-                CurrentLine->AddStatusLast(Standard_True, N, PathPnt);
-              }
-              AddPointInCurrentLine(N,PathPnt,CurrentLine);
-              if ((etat1N != 1 && etat1N != 11)) {
-                // modified by NIZHNY-MKK  Fri Oct 27 12:43:05 2000.BEGIN
-                //             wd1[N].etat= - wd1[N].etat;
-                wd1[N].etat = - Abs(etat1N);           
-                movementdirectioninfo[N] = (movementdirectioninfo[N]==0) ? StepSign : 0;
-                if(Arrive && movementdirectioninfo[N]!=0) {
-                  IndexOfPathPointDoNotCheck = N;
-                }
-
-                if(Arrive) {
-                  Rajout = Standard_True;
-                  seqAjout.Append(lines.Length() + 1);
-                }
-                // modified by NIZHNY-MKK  Fri Oct 27 12:45:33 2000.END
-              }
-            }
-            else if (Status == IntWalk_ArretSurPoint) {
-              Arrive = Standard_True;                   
+               if(Arrive) {
+                 Rajout = Standard_True;
+                 seqAjout.Append(lines.Length() + 1);
+               }
+               // modified by NIZHNY-MKK  Fri Oct 27 12:45:33 2000.END
+             }
+           }
+           else if (Status == IntWalk_ArretSurPoint) {
+              Arrive = Standard_True;
               CurrentLine->AddStatusLast(Standard_False);
               Tgtend = Standard_True;
               MakeWalkingPoint(1, UVap(1), UVap(2), Func, Psol);
               CurrentLine->AddPoint(Psol);
               Rajout = Standard_True;
               seqAjout.Append(lines.Length() + 1);
-            }
-            else if (Status == IntWalk_OK) { 
+           }
+           else if (Status == IntWalk_OK) { 
               MakeWalkingPoint(2, UVap(1), UVap(2), Func, previousPoint);
-              previousd3d = Func.Direction3d();
-              previousd2d = Func.Direction2d();
-              CurrentLine->AddPoint(previousPoint);
-            }     
-            else if (Status == IntWalk_PointConfondu)
-            {
-              aNbIter --;
-            }
-          }
-        }
-        else { // no numerical solution
-          PasC = PasC / 2.;
-          PasCu = Abs(PasC*previousd2d.X());
-          PasCv = Abs(PasC*previousd2d.Y());
-          if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
-            if (CurrentLine->NbPoints()==1) break;
-            Arrive = Standard_True;
-            CurrentLine->AddStatusLast(Standard_False);
-            Tgtend = Standard_True; // need check
-            Rajout = Standard_True;
+             previousd3d = Func.Direction3d();
+             previousd2d = Func.Direction2d();
+             CurrentLine->AddPoint(previousPoint);
+           }
+            PrevStepWrong = Standard_False;
+         } //(Abs(Func.Root()) <= Func.Tolerance())
+       }
+       else { // no numerical solution
+          PrevStepWrong = Standard_True;
+         PasC = PasC / 2.;
+         PasCu = Abs(PasC*previousd2d.X());
+         PasCv = Abs(PasC*previousd2d.Y());
+         if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
+           if (CurrentLine->NbPoints()==1) break;
+           Arrive = Standard_True;
+           CurrentLine->AddStatusLast(Standard_False);
+           Tgtend = Standard_True; // need check
+           Rajout = Standard_True;
             seqAjout.Append(lines.Length() + 1);
-          }  
-        }
-
-        if(aNbIter < 0)
-          break;
+         }  
+       }
       } // end of started line
       
       if (Arrive) {
-        CurrentLine->SetTangencyAtEnd(Tgtend);
-        lines.Append(CurrentLine);
-        // modified by NIZHNY-MKK  Fri Oct 27 12:59:29 2000.BEGIN
-        movementdirectioninfo[I]=0;
-        if(wd1[I].etat > 0)
-          // modified by NIZHNY-MKK  Fri Oct 27 12:59:42 2000.END
-          wd1[I].etat=-wd1[I].etat;
-
-        //-- lbr le 5 juin 97 (Pb ds Contap)
-        for(Standard_Integer av=1; av<=nbPath; av++) { 
-          // modified by NIZHNY-MKK  Fri Oct 27 13:00:22 2000.BEGIN
-          //     if (wd1[av].etat > 11) {
-          if ((wd1[av].etat > 11) || 
-            ((av!=I) && 
-            (av!=IndexOfPathPointDoNotCheck) && 
-            (wd1[av].etat < -11)  && 
-            (movementdirectioninfo[av]!=0)))
-          {
-            // modified by NIZHNY-MKK  Fri Oct 27 13:00:26 2000.END
-            Standard_Real Uav=wd1[av].ustart;
-            Standard_Real Vav=wd1[av].vstart;
-            Standard_Real Uavp,Vavp;
-            const IntSurf_PntOn2S &avP=CurrentLine->Value(CurrentLine->NbPoints());
-            if (!reversed) {
-              avP.ParametersOnS2(Uavp,Vavp);
-            }
-            else {
-              avP.ParametersOnS1(Uavp,Vavp);
-            }
-            Uav-=Uavp;
-            Vav-=Vavp;
-            Uav*=0.001; Vav*=0.001;
-            if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) { 
-              // modified by NIZHNY-MKK  Fri Oct 27 13:01:38 2000.BEGIN
-              //             wd1[av].etat=-wd1[av].etat;
-              if(wd1[av].etat < 0) {
-                movementdirectioninfo[av] = 0;
-              } else {
-                wd1[av].etat=-wd1[av].etat;
-                movementdirectioninfo[av] = StepSign;
-              }
-              // modified by NIZHNY-MKK  Fri Oct 27 13:01:42 2000.END
-              CurrentLine->AddStatusLast(Standard_True, av, Pnts1.Value(av));
-              //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
-            }
+       CurrentLine->SetTangencyAtEnd(Tgtend);
+        CurrentLine->SetTangency(IsTangentialIntersection);
+       lines.Append(CurrentLine);
+       // modified by NIZHNY-MKK  Fri Oct 27 12:59:29 2000.BEGIN
+       movementdirectioninfo[I]=0;
+       if(wd1[I].etat > 0)
+       // modified by NIZHNY-MKK  Fri Oct 27 12:59:42 2000.END
+         wd1[I].etat=-wd1[I].etat;
 
-            const IntSurf_PntOn2S &avPP=CurrentLine->Value(1);
-            if (!reversed) {
-              avPP.ParametersOnS2(Uavp,Vavp);
-            }
-            else {
-              avPP.ParametersOnS1(Uavp,Vavp);
-            }
-            Uav=wd1[av].ustart;
-            Vav=wd1[av].vstart;
-            Uav-=Uavp;
-            Vav-=Vavp;
-            Uav*=0.001; Vav*=0.001;
-            if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) { 
-              // modified by NIZHNY-MKK  Fri Oct 27 13:02:49 2000.BEGIN
-              //             wd1[av].etat=-wd1[av].etat;
-              if(wd1[av].etat < 0) {
-                movementdirectioninfo[av] = 0;
-              } else {
-                wd1[av].etat=-wd1[av].etat;
-                movementdirectioninfo[av] = -StepSign;
-              }
-              // modified by NIZHNY-MKK  Fri Oct 27 13:02:52 2000.END
-              //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
-              CurrentLine->AddStatusFirst(Standard_False, Standard_True, av, Pnts1.Value(av));
-            }
-          }
-        }
+       //-- lbr le 5 juin 97 (Pb ds Contap)
+       for(Standard_Integer av=1; av<=nbPath; av++) { 
+         // modified by NIZHNY-MKK  Fri Oct 27 13:00:22 2000.BEGIN
+         //      if (wd1[av].etat > 11) {
+         if ((wd1[av].etat > 11) || 
+             ((av!=I) && 
+              (av!=IndexOfPathPointDoNotCheck) && 
+              (wd1[av].etat < -11)  && 
+              (movementdirectioninfo[av]!=0))) {
+         // modified by NIZHNY-MKK  Fri Oct 27 13:00:26 2000.END
+           Standard_Real Uav=wd1[av].ustart;
+           Standard_Real Vav=wd1[av].vstart;
+           Standard_Real Uavp,Vavp;
+           const IntSurf_PntOn2S &avP=CurrentLine->Value(CurrentLine->NbPoints());
+           if (!reversed) {
+             avP.ParametersOnS2(Uavp,Vavp);
+           }
+           else {
+             avP.ParametersOnS1(Uavp,Vavp);
+           }
+           Uav-=Uavp;
+           Vav-=Vavp;
+           Uav*=0.001; Vav*=0.001;
+           if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) { 
+             // modified by NIZHNY-MKK  Fri Oct 27 13:01:38 2000.BEGIN
+             //              wd1[av].etat=-wd1[av].etat;
+             if(wd1[av].etat < 0) {
+               movementdirectioninfo[av] = 0;
+             } else {
+               wd1[av].etat=-wd1[av].etat;
+               movementdirectioninfo[av] = StepSign;
+             }
+             // modified by NIZHNY-MKK  Fri Oct 27 13:01:42 2000.END
+             CurrentLine->AddStatusLast(Standard_True, av, Pnts1.Value(av));
+             //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
+           }
+           
+           const IntSurf_PntOn2S &avPP=CurrentLine->Value(1);
+           if (!reversed) {
+             avPP.ParametersOnS2(Uavp,Vavp);
+           }
+           else {
+             avPP.ParametersOnS1(Uavp,Vavp);
+           }
+           Uav=wd1[av].ustart;
+           Vav=wd1[av].vstart;
+           Uav-=Uavp;
+           Vav-=Vavp;
+           Uav*=0.001; Vav*=0.001;
+           if(Abs(Uav)<tolerance(1) && Abs(Vav)<tolerance(2)) { 
+             // modified by NIZHNY-MKK  Fri Oct 27 13:02:49 2000.BEGIN
+             //              wd1[av].etat=-wd1[av].etat;
+             if(wd1[av].etat < 0) {
+               movementdirectioninfo[av] = 0;
+             } else {
+               wd1[av].etat=-wd1[av].etat;
+               movementdirectioninfo[av] = -StepSign;
+             }
+             // modified by NIZHNY-MKK  Fri Oct 27 13:02:52 2000.END
+             //-- cout<<"\n Debug ? lbr ds IntWalk_IWalking_3.gxx"<<endl;
+             CurrentLine->AddStatusFirst(Standard_False, Standard_True, av, Pnts1.Value(av));
+           }
+         }
+       }
+         
       }
     } //end of point processing
   } //end of all points
 }
 
+
 // modified by NIZHNY-MKK  Thu Nov  2 15:07:53 2000.BEGIN
 static Standard_Boolean TestPassedSolutionWithNegativeState(const IntWalk_VectorOfWalkingData& wd,
                                                            const TColStd_SequenceOfReal& Umult,
index 635ed1c674160bcab37fe737d9ea7153375c11e6..152d4683907000eb81c437184f5ac0df997fd494 100644 (file)
 // commercial license or contractual agreement.
 
 #include <NCollection_IncAllocator.hxx>
+#include <IntSurf_Quadric.hxx>
+#include <gp_Lin2d.hxx>
+#include <gce_MakeLin2d.hxx>
 
 void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
                                        const TColStd_SequenceOfReal& Vmult,
                                        const ThePOPIterator& Pnts1,
                                        const ThePOLIterator& Pnts2,
+                                       const ThePOLIterator& Pnts3,
                                        TheIWFunction& Func,
-                                        Standard_Boolean& Rajout )
+                                        Standard_Boolean& Rajout ) 
 // *********** Processing of closed line **********************
 //
 // for any interior non-processed point 
@@ -41,7 +45,9 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
 //
 // ******************************************************************** 
 {
-  Standard_Integer I,N = 0;
+  //const Standard_Real GlobalValTol = 1.e-12;
+
+  Standard_Integer I, N = 0;
   Standard_Real aBornInf[2], aBornSup[2], aUVap[2];
   math_Vector BornInf(aBornInf,1,2), BornSup(aBornSup,1,2);
   math_Vector Uvap(aUVap,1,2);// parameters of current approach
@@ -52,6 +58,8 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
   Standard_Boolean Arrive;// show if line ends
   Standard_Boolean Cadre; // show if on border of the  domains
   Standard_Boolean ArretAjout; // show if on the added point
+  Standard_Boolean PrevStepWrong; //shows was Rsnld successful or not
+  Standard_Boolean OnPrevTangency; //shows if one is on added point of tangent line
   IntSurf_PntOn2S Psol;
   Handle(IntWalk_TheIWLine)  CurrentLine; //line under construction
   ThePointOfPath PathPnt;
@@ -60,6 +68,9 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
   Standard_Boolean Tgtbeg,Tgtend;
 
   Standard_Integer StepSign;
+  Standard_Integer StepSignTangent;
+  Standard_Integer SignOfBcoeff = 0;
+  Standard_Integer PrevSignOfBcoeff = SignOfBcoeff;
   
   IntWalk_StatusDeflection Status = IntWalk_OK, StatusPrecedent;
   Standard_Integer NbDivision ;   // number of divisions of step 
@@ -79,6 +90,7 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
 
   // Check borders for degeneracy:
   math_Matrix D(1,1,1,2);
+  math_Vector FuncVal(1,1);
   const Standard_Integer aNbSamplePnt = 10;
   Standard_Boolean isLeftDegeneratedBorder[2] = {Standard_True, Standard_True};
   Standard_Boolean isRightDegeneratedBorder[2] = {Standard_True, Standard_True};
@@ -119,19 +131,30 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
   }
 
   for (I = 1;I<=nbLoop;I++) {
-    if (wd2[I].etat > 12)
-    { // start point of closed line
+    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);
+      gp_Pnt thePoint = ThePointOfLoopTool::Value3d(LoopPnt);
+      previousPoint.SetValue(thePoint,reversed,
+                            wd2[I].ustart,wd2[I].vstart);
       previousd3d = ThePointOfLoopTool::Direction3d(LoopPnt);
       previousd2d = ThePointOfLoopTool::Direction2d(LoopPnt);
-
+      
+#ifdef DRAW
+      Standard_Real theU, theV;
+      ThePointOfLoopTool::Value2d(LoopPnt, theU, theV);
+      cout<<"LoopPnt("<<I<<"):"<<endl;
+      cout<<"u = "<<theU<<", v = "<<theV<<endl;
+      cout<<"pnt = "<<thePoint.X()<<" "<<thePoint.Y()<<" "<<thePoint.Z()<<endl<<endl;
+#endif
+      
       CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
       CurrentLine->AddPoint(previousPoint);
       CurrentLine->SetTangentVector(previousd3d,1);
       Tgtbeg = Standard_False;
       Tgtend = Standard_False;
+      IsTangentialIntersection = Standard_False;
+      SignOfBcoeff = PrevSignOfBcoeff = 0;
       Uvap(1) = wd2[I].ustart;
       Uvap(2) = wd2[I].vstart;
 
@@ -142,54 +165,55 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
       Standard_Real d2dx = Abs(previousd2d.X()); 
       Standard_Real d2dy = Abs(previousd2d.Y()); 
       if (d2dx < tolerance(1)) {
-        PasC = pas * (VM-Vm)/d2dy;
+       PasC = pas * (VM-Vm)/d2dy;
       }
       else if (d2dy < tolerance(2)) {
-        PasC = pas * (UM-Um)/d2dx;
+       PasC = pas * (UM-Um)/d2dx;
       }
       else {
-        PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
+       PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
       }
 
       PasSav = PasC;
 
       Arrive = Standard_False;
       ArretAjout = Standard_False;
+      PrevStepWrong = Standard_False;
+      OnPrevTangency = Standard_False;
       NbDivision = 0;
       StatusPrecedent = IntWalk_OK;
-      Standard_Integer aNbIter = 10;
       while (!Arrive) {  // as no test of stop is passed
-        Cadre=Cadrage(BornInf,BornSup,Uvap,PasC, StepSign);  // border?
+       Cadre=Cadrage(BornInf,BornSup,Uvap,PasC, StepSign);  // border?
 #ifdef CHRONO
-        Chronrsnld.Start();
+       Chronrsnld.Start();
 #endif
-
         Rsnld.Perform(Func,Uvap,BornInf,BornSup);
 
 #ifdef CHRONO
-        Chronrsnld.Stop();
+       Chronrsnld.Stop();
 #endif
 
-        if (Cadre) { // update of limits.
-          BornInf(1) = Um;BornSup(1) = UM;BornInf(2) = Vm;BornSup(2) = VM;
-        }
-        if (Rsnld.IsDone()) {
-          if (Abs(Func.Root()) > Func.Tolerance()) { // no solution for the tolerance
-            PasC = PasC/2.;
-            PasCu = Abs(PasC*previousd2d.X());
-            PasCv = Abs(PasC*previousd2d.Y());
-
-            if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
-              if (CurrentLine->NbPoints()==1) break;
-              Arrive = Standard_True;
-              CurrentLine->AddStatusFirstLast(Standard_False,
-                Standard_False,Standard_False);
-              Rajout = Standard_True;
+       if (Cadre) { // update of limits.
+         BornInf(1) = Um;BornSup(1) = UM;BornInf(2) = Vm;BornSup(2) = VM;
+       }
+       if (Rsnld.IsDone()) {
+         if (Abs(Func.Root()) > Func.Tolerance()) { // no solution for the tolerance
+            PrevStepWrong = Standard_True;
+           PasC = PasC/2.;
+           PasCu = Abs(PasC*previousd2d.X());
+           PasCv = Abs(PasC*previousd2d.Y());
+
+           if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
+             if (CurrentLine->NbPoints()==1) break;
+             Arrive = Standard_True;
+             CurrentLine->AddStatusFirstLast(Standard_False,
+                                             Standard_False,Standard_False);
+             Rajout = Standard_True;
               seqAjout.Append(lines.Length()+1);
-              Tgtend = Standard_True;
-            }
-          }
-          else { // there is a solution
+             Tgtend = Standard_True;
+           }
+         }
+         else { // there is a solution
             Rsnld.Root(Uvap);
 
             // Avoid unitialized memory access.
@@ -231,199 +255,643 @@ void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult,
               }
             }
 
-            Arrive = TestArretPassage(Umult,Vmult,Uvap,I,Ipass);
-            if (Arrive) {//reset proper parameter to test the arrow.
-              Psol = CurrentLine->Value(1);
-              if (!reversed) {
-                Psol.ParametersOnS2(Uvap(1),Uvap(2));
-              }
-              else {
-                Psol.ParametersOnS1(Uvap(1),Uvap(2));
-              }
+           Arrive = TestArretPassage(Umult,Vmult,Uvap,I,Ipass);
+           if (Arrive) {//reset proper parameter to test the arrow.
+             Psol = CurrentLine->Value(1);
+             if (!reversed) {
+               Psol.ParametersOnS2(Uvap(1),Uvap(2));
+             }
+             else {
+               Psol.ParametersOnS1(Uvap(1),Uvap(2));
+             }
               Cadre=Standard_False; 
-              //in case if there is a frame and arrival at the same time
+             //in case if there is a frame and arrival at the same time
+           }
+           else { // modif jag 940615
+
+             if (Rajout) {    // test on added points
+               ArretAjout =TestArretAjout(Func, Uvap, N, Psol, OnPrevTangency);
+               if (ArretAjout) {
+                 if (N >0) {
+                   Tgtend = lines.Value(N)->IsTangentAtEnd();
+                   N = -N;
+                 }
+                 else {
+                   Tgtend = lines.Value(-N)->IsTangentAtBegining();
+                 }
+                 Arrive = (wd2[I].etat == 12);
+               }
+             }
+
+             if (!ArretAjout&& Cadre) {  // test on already marked points
+               if (CurrentLine->NbPoints() == 1)  break; // cancel the line
+               TestArretCadre(Umult,Vmult,CurrentLine,Func,Uvap,N);
+//             if (N==0) {
+               if (N <= 0) { // jag 941017
+                 MakeWalkingPoint(2,Uvap(1),Uvap(2),Func,Psol);
+                 Tgtend = Func.IsTangent(); // jag 940616
+                 N = -N;
+               }
+               Arrive = (wd2[I].etat == 12); // the line is open
+             }
+           }
+           Status = TestDeflection(Func, Arrive,Uvap,StatusPrecedent,
+                                   NbDivision,PasC,PasSav,StepSign,
+                                    CurrentLine->NbPoints(),ArretAjout,PrevStepWrong,OnPrevTangency);
+           StatusPrecedent = Status; 
+           if (Status == IntWalk_PasTropGrand) {// division of the step
+             Arrive = Standard_False;
+             ArretAjout = Standard_False;
+             Tgtend = Standard_False; // jag 940616
+             if (!reversed) {
+               previousPoint.ParametersOnS2(Uvap(1),Uvap(2));
+             }
+             else {
+               previousPoint.ParametersOnS1(Uvap(1),Uvap(2));
+             }
+           }
+           else if (ArretAjout || Cadre) {
+
+             if (Arrive) { // line s is open
+               CurrentLine->AddStatusLast(Standard_False);
+               if (Status != IntWalk_ArretSurPointPrecedent) {
+                 CurrentLine->AddPoint(Psol);                      
+               }
+               if (Cadre && N==0) {
+                 Rajout = Standard_True;
+                 seqAjout.Append(lines.Length()+1);
+               }
+                
+             }
+             else { // open
+               wd2[I].etat = 12; // declare it open
+               Tgtbeg = Tgtend;
+               Tgtend = Standard_False;
+               ArretAjout = Standard_False;
+               StepSign = -1;
+                StatusPrecedent = IntWalk_OK;
+               PasC = PasSav;
+               if (Status == IntWalk_ArretSurPointPrecedent) {
+                 OpenLine(0,Psol,Pnts1,Func,CurrentLine);
+               }
+               else {
+                 OpenLine(-lines.Length()-1,Psol,Pnts1,Func,CurrentLine);
+               }
+               if (Cadre && N==0) {
+                 Rajout = Standard_True;
+                 seqAjout.Append(-lines.Length()-1);
+               }
+             }
+           }
+            /*
+           else if (Status == IntWalk_ArretSurPointPrecedent &&
+                     !Func.IsTangent()) //continue the line because no tangent point
+            {
+              Status = IntWalk_OK;
+              StatusPrecedent = IntWalk_OK;
+              PasC = PasSav;
+
+             if (Ipass!=0) CurrentLine->AddIndexPassing(Ipass);
+             previousPoint.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
+             previousd3d = Func.Direction3d();
+             previousd2d = Func.Direction2d();
+             CurrentLine->AddPoint(previousPoint);
             }
-            else { // modif jag 940615
-              if (Rajout) {    // test on added points
-                ArretAjout =TestArretAjout(Func,Uvap,N,Psol);
-                if (ArretAjout) {
-                  if (N >0) {
-                    Tgtend = lines.Value(N)->IsTangentAtEnd();
-                    N = -N;
-                  }
-                  else {
-                    Tgtend = lines.Value(-N)->IsTangentAtBegining();
+            */
+           else if ( Status == IntWalk_ArretSurPointPrecedent) {
+             if (CurrentLine->NbPoints() == 1) { //cancel the line
+               Arrive = Standard_False;
+               break;
+             }
+             if (wd2[I].etat >12) { //the line should become open
+               wd2[I].etat = 12; //declare it open
+               ArretAjout = Standard_False;
+               OpenLine(0,Psol,Pnts1,Func,CurrentLine);
+               StepSign = -1;
+                StatusPrecedent = IntWalk_OK;
+               Arrive = Standard_False;
+               PasC = PasSav;
+               Rajout = Standard_True;
+                seqAjout.Append(-lines.Length()-1);
+             }
+             else { // line s is open                 
+               Arrive =Standard_True;
+               CurrentLine->AddStatusLast(Standard_False);
+               Rajout = Standard_True;
+                seqAjout.Append(lines.Length()+1);
+             } 
+           }
+           else if (Arrive)  {
+             if (wd2[I].etat > 12) {  //line closed good case
+               CurrentLine->AddStatusFirstLast(Standard_True,
+                                               Standard_False,Standard_False);
+               CurrentLine->AddPoint(CurrentLine->Value(1));              
+             }
+             else if (N >0) { //point of stop given at input 
+               PathPnt = Pnts1.Value(N);
+               CurrentLine->AddStatusLast(Standard_True,N,PathPnt);
+                AddPointInCurrentLine(N,PathPnt,CurrentLine);
+             }
+           }
+            else if (Status == IntWalk_ArretSurPoint)
+            {
+              if (Func.IsTangent())
+              {
+                PrevSignOfBcoeff = SignOfBcoeff;
+                gp_Vec   newd3d;
+                gp_Dir2d newd2d;
+                Standard_Boolean IsDiscriminantNull;
+                Standard_Boolean DirComputed =
+                  ComputeDirOfTangentialIntersection(Func, StepSignTangent,
+                                                     IsDiscriminantNull, SignOfBcoeff,
+                                                     newd3d, newd2d);
+                /*
+                if (DirComputed && !IsDiscriminantNull &&
+                    CurrentLine->NbPoints() > 1) //we have gone from tangent line
+                {
+                  //take line from prevprevP to prevP
+                  //project current solution onto this line
+                  //direction of projection is direction to find null Discriminant again
+                  //and then repeat
+                  gp_Pnt2d prevprevP = CurrentLine->Value(CurrentLine->NbPoints()-1).ValueOnSurface(reversed);
+                  gp_Pnt2d prevP = previousPoint.ValueOnSurface(reversed);
+                  gp_Lin2d prevLine = gce_MakeLin2d(prevprevP, prevP);
+                  //project
+                  gp_Pnt2d CurSol(Uvap(1),Uvap(2));
+                  gp_XY LinLoc = prevLine.Location().XY();
+                  gp_XY LinDir = prevLine.Direction().XY();
+                  Standard_Real Parameter = (CurSol.XY() - LinLoc) * LinDir;
+                  gp_Pnt2d ProjCurSol( LinLoc + Parameter * LinDir );
+                  Uvap(1) = ProjCurSol.X();
+                  Uvap(2) = ProjCurSol.Y();
+                  Func.Values(Uvap, FuncVal, D);
+                  /////////
+                  DirComputed = ComputeDirOfTangentialIntersection(Func, StepSignTangent,
+                                                                    IsDiscriminantNull, SignOfBcoeff,
+                                                                    newd3d, newd2d);
+                }
+                */
+                if (DirComputed && IsDiscriminantNull)
+                {
+                  if (SignOfBcoeff == 0) //point of branching
+                    Status = IntWalk_ArretSurPoint;
+                  else
+                  {
+                    if (PrevSignOfBcoeff == 0 ||
+                        SignOfBcoeff == PrevSignOfBcoeff)
+                    {                  
+                      Status = IntWalk_OKtangent;
+                      MakeWalkingPoint(2, Uvap(1), Uvap(2), Func, previousPoint);
+                      previousd3d = newd3d;
+                      previousd2d = newd2d;
+                      CurrentLine->AddPoint(previousPoint);
+                    }
+                    else //change of sign of Bcoeff
+                    {
+                      MakeWalkingPoint(1, Uvap(1), Uvap(2), Func, Psol);
+                      FindExactCuspPoint(Func, Psol,
+                                         PrevSignOfBcoeff, SignOfBcoeff);
+                      Psol.ParametersOnSurface(reversed, Uvap(1), Uvap(2));
+                      //Status = IntWalk_ArretSurPoint;
+                    }
                   }
-                  Arrive = (wd2[I].etat == 12);
                 }
               }
-
-              if (!ArretAjout&& Cadre) {  // test on already marked points
-                if (CurrentLine->NbPoints() == 1)  break; // cancel the line
-                TestArretCadre(Umult,Vmult,CurrentLine,Func,Uvap,N);
-                //             if (N==0) {
-                if (N <= 0) { // jag 941017
-                  MakeWalkingPoint(2,Uvap(1),Uvap(2),Func,Psol);
-                  Tgtend = Func.IsTangent(); // jag 940616
-                  N = -N;
+              if (Status == IntWalk_ArretSurPoint) {
+                if (wd2[I].etat >12) { //line should become open
+                  wd2[I].etat = 12; //declare it open
+                  Tgtbeg = Standard_True;
+                  Tgtend = Standard_False;
+                  N= -lines.Length()-1;
+                  Psol.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
+                  OpenLine(N,Psol,Pnts1,Func,CurrentLine);
+                  StepSign = -1;
+                  SignOfBcoeff = PrevSignOfBcoeff = 0;
+                  Rajout = Standard_True;
+                  seqAjout.Append(N);
+                  StatusPrecedent = IntWalk_OK;
+                  Arrive = Standard_False;
+                  PasC = PasSav;       
+                }
+                else { 
+                  Arrive = Standard_True;                   
+                  if (Ipass!=0) { //point of passage, point of stop
+                    PathPnt = Pnts1.Value(Ipass);
+                    CurrentLine->AddStatusLast(Standard_True,Ipass,PathPnt);
+                    AddPointInCurrentLine(Ipass,PathPnt,CurrentLine);
+                  }
+                  else {
+                    CurrentLine->AddStatusLast(Standard_False);
+                    IntSurf_PntOn2S newP;
+                    newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
+                    CurrentLine->AddPoint(newP);
+                    Rajout = Standard_True;
+                    seqAjout.Append(lines.Length()+1);
+                  }
                 }
-                Arrive = (wd2[I].etat == 12); // the line is open
-              }
-            }
-            Status = TestDeflection(Func, Arrive,Uvap,StatusPrecedent,
-                                                NbDivision,PasC,StepSign);
-
-            StatusPrecedent = Status; 
-            if (Status == IntWalk_PasTropGrand) {// division of the step
-              Arrive = Standard_False;
-              ArretAjout = Standard_False;
-              Tgtend = Standard_False; // jag 940616
-              if (!reversed) {
-                previousPoint.ParametersOnS2(Uvap(1),Uvap(2));
-              }
-              else {
-                previousPoint.ParametersOnS1(Uvap(1),Uvap(2));
               }
             }
-            else if (ArretAjout || Cadre) {
+           else if (Status == IntWalk_OK) { 
+             if (Ipass!=0) CurrentLine->AddIndexPassing(Ipass);
+             previousPoint.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
+             previousd3d = Func.Direction3d();
+             previousd2d = Func.Direction2d();
+             CurrentLine->AddPoint(previousPoint);
+           }
+            PrevStepWrong = Standard_False;
+         } //there is a solution
+       }
+       else { //no numerical solution NotDone
+          PrevStepWrong = Standard_True;
+         PasC = PasC/2.;
+         PasCu = Abs(PasC*previousd2d.X());
+         PasCv = Abs(PasC*previousd2d.Y());
+
+         if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
+            if (CurrentLine->NbPoints() == 1)  break; // cancel the line
+           Arrive = Standard_True;
+           CurrentLine->AddStatusFirstLast(Standard_False,Standard_False,
+                                           Standard_False);
+           Tgtend = Standard_True;
+           Rajout = Standard_True;
+           seqAjout.Append(lines.Length()+1);
+         }  
+       }
+      }// end of started line 
+      if (Arrive) {
+       CurrentLine->SetTangencyAtBegining(Tgtbeg);
+       CurrentLine->SetTangencyAtEnd(Tgtend);
+        CurrentLine->SetTangency(IsTangentialIntersection);
+       
+       lines.Append(CurrentLine);
+       wd2[I].etat=-wd2[I].etat; //mark point as processed
+      }
+    } //end of processing of start point
+  } //end of all start points
 
-              if (Arrive) { // line s is open
-                CurrentLine->AddStatusLast(Standard_False);
-                if (Status != IntWalk_ArretSurPointPrecedent) {
-                  CurrentLine->AddPoint(Psol);                      
-                }
-                if (Cadre && N==0) {
-                  Rajout = Standard_True;
-                  seqAjout.Append(lines.Length()+1);
-                }
+  //Process inner tangent points
+  IsTangentialIntersection = Standard_True;
+  StepSign = 1;
+  StepSignTangent = 1;
+  SignOfBcoeff = 0;
+  PrevSignOfBcoeff = SignOfBcoeff;
+  Standard_Integer nbTang = Pnts3.Length();
+  for (I = 1; I <= nbTang; I++) {
+    if (wd3[I].etat > 12) { // start point of closed line
+      
+      LoopPnt = Pnts3.Value(I);
+      gp_Pnt thePoint = ThePointOfLoopTool::Value3d(LoopPnt);
+      previousPoint.SetValue(thePoint,reversed,
+                            wd3[I].ustart, wd3[I].vstart);
+      Standard_Real theU, theV;
+      ThePointOfLoopTool::Value2d(LoopPnt, theU, theV);
+      IntSurf_PntOn2S PrevPointFromFunc;
+      MakeWalkingPoint(11, theU, theV, Func, PrevPointFromFunc);
+      /////
+      gp_Vec   newd3d;
+      gp_Dir2d newd2d;
+      Standard_Boolean IsDiscriminantNull;
+      if (!ComputeDirOfTangentialIntersection(Func, StepSignTangent,
+                                              IsDiscriminantNull, SignOfBcoeff,
+                                              newd3d, newd2d) ||
+          !IsDiscriminantNull)
+        continue;
+      if (SignOfBcoeff == 0) //point of branching or tangent zone
+        continue;
+      previousd3d = newd3d;
+      previousd2d = newd2d;
+      //here <previousd3d> and <previousd2d> are defined
+      
+      CurrentLine = new IntWalk_TheIWLine (new NCollection_IncAllocator());
+      CurrentLine->AddPoint(previousPoint);
+      CurrentLine->SetTangentVector(previousd3d,1);
+      Tgtbeg = Standard_False;
+      Tgtend = Standard_False;
+      SignOfBcoeff = PrevSignOfBcoeff = 0;
+      Uvap(1) = wd3[I].ustart;
+      Uvap(2) = wd3[I].vstart;
 
+      StepSign = 1;
+
+      // first step of advancement
+
+      Standard_Real d2dx = Abs(previousd2d.X()); 
+      Standard_Real d2dy = Abs(previousd2d.Y()); 
+      if (d2dx < tolerance(1)) {
+       PasC = pas * (VM-Vm)/d2dy;
+      }
+      else if (d2dy < tolerance(2)) {
+       PasC = pas * (UM-Um)/d2dx;
+      }
+      else {
+       PasC = pas * Min((UM-Um)/d2dx,(VM-Vm)/d2dy);
+      }
+
+      PasSav = PasC;
+
+      Arrive = Standard_False;
+      ArretAjout = Standard_False;
+      PrevStepWrong = Standard_False;
+      OnPrevTangency = Standard_False;
+      NbDivision = 0;
+      StatusPrecedent = IntWalk_OK;
+      while (!Arrive) {  // as no test of stop is passed
+       Cadre=Cadrage(BornInf,BornSup,Uvap,PasC, StepSign);  // border?
+#ifdef CHRONO
+       Chronrsnld.Start();
+#endif
+
+        //Standard_Boolean ExactStartSolution = Standard_False;
+        /*
+        for (Standard_Integer ind = 1; ind <= 2; ind++)
+        {
+          if (Uvap(ind) <= BornInf(ind)) Uvap(ind) = BornInf(ind);
+          else if (Uvap(ind) > BornSup(ind)) Uvap(ind) = BornSup(ind);
+        }
+        Func.Values(Uvap, FuncVal, D);
+        */
+        //if (FuncVal(1) >= GlobalValTol)
+        Rsnld.Perform(Func,Uvap,BornInf,BornSup);
+
+#ifdef CHRONO
+       Chronrsnld.Stop();
+#endif
+
+       if (Cadre) { // update of limits.
+         BornInf(1) = Um;BornSup(1) = UM;BornInf(2) = Vm;BornSup(2) = VM;
+       }
+       if (Rsnld.IsDone()) {
+         if (Abs(Func.Root()) > Func.Tolerance()) { // no solution for the tolerance
+            PrevStepWrong = Standard_True;
+           PasC = PasC/2.;
+           PasCu = Abs(PasC*previousd2d.X());
+           PasCv = Abs(PasC*previousd2d.Y());
+
+           if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
+             if (CurrentLine->NbPoints()==1) break;
+             Arrive = Standard_True;
+             CurrentLine->AddStatusFirstLast(Standard_False,
+                                             Standard_False,Standard_False);
+             Rajout = Standard_True;
+              seqAjout.Append(lines.Length()+1);
+             Tgtend = Standard_True;
+           }
+         }
+         else { // there is a solution
+            math_Vector NewUv(1,2), OldUv(1,2);
+            Rsnld.Root(NewUv);
+            gp_Pnt2d prevPnt2d, NewPnt2d(NewUv(1),NewUv(2)), Pnt2dap(Uvap(1),Uvap(2));
+            prevPnt2d = previousPoint.ValueOnSurface(reversed);
+            gp_Vec2d PrevToAp(prevPnt2d, Pnt2dap);
+            gp_Vec2d PrevToNew(prevPnt2d, NewPnt2d);
+            if (PrevToAp * PrevToNew < 0. ||
+                PrevToNew.Magnitude()/2. > PrevToAp.Magnitude()) //solution is bad
+            {
+              for (Standard_Integer ind = 1; ind <= 2; ind++)
+              {
+                if (Uvap(ind) <= BornInf(ind)) Uvap(ind) = BornInf(ind);
+                else if (Uvap(ind) > BornSup(ind)) Uvap(ind) = BornSup(ind);
               }
-              else { // open
-                wd2[I].etat = 12; // declare it open
-                Tgtbeg = Tgtend;
-                Tgtend = Standard_False;
-                ArretAjout = Standard_False;
-                StepSign = -1;
-                StatusPrecedent = IntWalk_OK;
-                PasC = PasSav;
-                if (Status == IntWalk_ArretSurPointPrecedent) {
-                  OpenLine(0,Psol,Pnts1,Func,CurrentLine);
-                }
-                else {
-                  OpenLine(-lines.Length()-1,Psol,Pnts1,Func,CurrentLine);
-                }
-                if (Cadre && N==0) {
-                  Rajout = Standard_True;
-                  seqAjout.Append(-lines.Length()-1);
-                }
-              }
+              Func.Values(Uvap, FuncVal, D);
             }
-            else if ( Status == IntWalk_ArretSurPointPrecedent) {
-              if (CurrentLine->NbPoints() == 1) { //cancel the line
-                Arrive = Standard_False;
-                break;
-              }
-              if (wd2[I].etat >12) { //the line should become open
-                wd2[I].etat = 12; //declare it open
-                ArretAjout = Standard_False;
-                OpenLine(0,Psol,Pnts1,Func,CurrentLine);
-                StepSign = -1;
+            else
+              Uvap = NewUv;
+              
+           Arrive = TestArretPassageTang(Umult,Vmult,Uvap,I,Ipass);
+           if (Arrive) {//reset proper parameter to test the arrow.
+             Psol = CurrentLine->Value(1);
+             if (!reversed) {
+               Psol.ParametersOnS2(Uvap(1),Uvap(2));
+             }
+             else {
+               Psol.ParametersOnS1(Uvap(1),Uvap(2));
+             }
+              Cadre = Standard_False; 
+             //in case if there is a frame and arrival at the same time
+           }
+           else { // modif jag 940615
+
+             if (Rajout) {    // test on added points
+               ArretAjout = TestArretAjout(Func, Uvap, N, Psol, OnPrevTangency);
+               if (ArretAjout) {
+                 if (N >0) {
+                   Tgtend = lines.Value(N)->IsTangentAtEnd();
+                   N = -N;
+                 }
+                 else {
+                   Tgtend = lines.Value(-N)->IsTangentAtBegining();
+                 }
+                 Arrive = (wd3[I].etat == 12);
+               }
+             }
+
+             if (!ArretAjout&& Cadre) {  // test on already marked points
+               if (CurrentLine->NbPoints() == 1)  break; // cancel the line
+               TestArretCadre(Umult,Vmult,CurrentLine,Func,Uvap,N);
+//             if (N==0) {
+               if (N <= 0) { // jag 941017
+                 MakeWalkingPoint(2,Uvap(1),Uvap(2),Func,Psol);
+                 Tgtend = Func.IsTangent(); // jag 940616
+                 N = -N;
+               }
+               Arrive = (wd3[I].etat == 12); // the line is open
+             }
+           }
+           Status = TestDeflection(Func, Arrive,Uvap,StatusPrecedent,
+                                   NbDivision,PasC,PasSav,StepSign,
+                                    CurrentLine->NbPoints(),ArretAjout,PrevStepWrong,OnPrevTangency);
+           StatusPrecedent = Status; 
+           if (Status == IntWalk_PasTropGrand) {// division of the step
+             Arrive = Standard_False;
+             ArretAjout = Standard_False;
+             Tgtend = Standard_False; // jag 940616
+             if (!reversed) {
+               previousPoint.ParametersOnS2(Uvap(1),Uvap(2));
+             }
+             else {
+               previousPoint.ParametersOnS1(Uvap(1),Uvap(2));
+             }
+           }
+           else if (ArretAjout || Cadre) {
+
+             if (Arrive) { // line s is open
+               CurrentLine->AddStatusLast(Standard_False);
+               if (Status != IntWalk_ArretSurPointPrecedent) {
+                 CurrentLine->AddPoint(Psol);                      
+               }
+               if (Cadre && N==0) {
+                 Rajout = Standard_True;
+                 seqAjout.Append(lines.Length()+1);
+               }
+                
+             }
+             else { // open
+               wd3[I].etat = 12; // declare it open
+               Tgtbeg = Tgtend;
+               Tgtend = Standard_False;
+               ArretAjout = Standard_False;
+               StepSign = -1;
+                StatusPrecedent = IntWalk_OK;
+               PasC = PasSav;
+               if (Status == IntWalk_ArretSurPointPrecedent) {
+                 OpenLine(0,Psol,Pnts1,Func,CurrentLine);
+               }
+               else {
+                 OpenLine(-lines.Length()-1,Psol,Pnts1,Func,CurrentLine);
+               }
+               if (Cadre && N==0) {
+                 Rajout = Standard_True;
+                 seqAjout.Append(-lines.Length()-1);
+               }
+             }
+           }
+
+           else if ( Status == IntWalk_ArretSurPointPrecedent) {
+             if (CurrentLine->NbPoints() == 1) { //cancel the line
+               Arrive = Standard_False;
+               break;
+             }
+             if (wd3[I].etat >12) { //the line should become open
+               wd3[I].etat = 12; //declare it open
+               ArretAjout = Standard_False;
+               OpenLine(0,Psol,Pnts1,Func,CurrentLine);
+               StepSign = -1;
                 StatusPrecedent = IntWalk_OK;
-                Arrive = Standard_False;
-                PasC = PasSav;
-                Rajout = Standard_True;
+               Arrive = Standard_False;
+               PasC = PasSav;
+               Rajout = Standard_True;
                 seqAjout.Append(-lines.Length()-1);
-              }
-              else { // line s is open                 
-                Arrive =Standard_True;
-                CurrentLine->AddStatusLast(Standard_False);
-                Rajout = Standard_True;
+             }
+             else { // line s is open                 
+               Arrive = Standard_True;
+               CurrentLine->AddStatusLast(Standard_False);
+               Rajout = Standard_True;
                 seqAjout.Append(lines.Length()+1);
-              
-            }
-            else if (Arrive)  {
-              if (wd2[I].etat > 12) {  //line closed good case
-                CurrentLine->AddStatusFirstLast(Standard_True,
-                  Standard_False,Standard_False);
-                CurrentLine->AddPoint(CurrentLine->Value(1));              
-              }
-              else if (N >0) { //point of stop given at input 
-                PathPnt = Pnts1.Value(N);
-                CurrentLine->AddStatusLast(Standard_True,N,PathPnt);
+             } 
+           }
+           else if (Arrive)  {
+             if (wd3[I].etat > 12) {  //line closed good case
+               CurrentLine->AddStatusFirstLast(Standard_True,
+                                               Standard_False,Standard_False);
+               CurrentLine->AddPoint(CurrentLine->Value(1));              
+             }
+             else if (N >0) { //point of stop given at input 
+               PathPnt = Pnts1.Value(N);
+               CurrentLine->AddStatusLast(Standard_True,N,PathPnt);
                 AddPointInCurrentLine(N,PathPnt,CurrentLine);
-              }
-            }
-            else if (Status == IntWalk_ArretSurPoint) {
-              if (wd2[I].etat >12) { //line should become open
-                wd2[I].etat = 12; //declare it open
-                Tgtbeg = Standard_True;
-                Tgtend = Standard_False;
-                N= -lines.Length()-1;
-                Psol.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
-                OpenLine(N,Psol,Pnts1,Func,CurrentLine);
-                StepSign = -1;
-                Rajout = Standard_True;
-                seqAjout.Append(N);
-                StatusPrecedent = IntWalk_OK;
-                Arrive = Standard_False;
-                PasC = PasSav; 
-              }
-              else { 
-                Arrive = Standard_True;                   
-                if (Ipass!=0) { //point of passage, point of stop
-                  PathPnt = Pnts1.Value(Ipass);
-                  CurrentLine->AddStatusLast(Standard_True,Ipass,PathPnt);
-                  AddPointInCurrentLine(Ipass,PathPnt,CurrentLine);
+             }
+           }
+            else if (Status == IntWalk_ArretSurPoint && Func.IsTangent())
+            {
+              PrevSignOfBcoeff = SignOfBcoeff;
+              gp_Vec   newd3d;
+              gp_Dir2d newd2d;
+              Standard_Boolean IsDiscriminantNull;
+              if (ComputeDirOfTangentialIntersection(Func, StepSignTangent,
+                                                     IsDiscriminantNull, SignOfBcoeff,
+                                                     newd3d, newd2d) &&
+                  IsDiscriminantNull)
+              {
+                if (SignOfBcoeff == 0) //point of branching
+                {
+                  //Status = IntWalk_ArretSurPoint;
                 }
-                else {
-                  CurrentLine->AddStatusLast(Standard_False);
-                  IntSurf_PntOn2S newP;
-                  newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
-                  CurrentLine->AddPoint(newP);
+                else
+                {
+                  if (PrevSignOfBcoeff == 0 ||
+                      SignOfBcoeff == PrevSignOfBcoeff)
+                  {
+                    Status = IntWalk_OKtangent;
+                    MakeWalkingPoint(2, Uvap(1), Uvap(2), Func, previousPoint);
+                    previousd3d = newd3d;
+                    previousd2d = newd2d;
+                    CurrentLine->AddPoint(previousPoint);
+                  }
+                  else //change of sign of Bcoeff
+                  {
+                    MakeWalkingPoint(1, Uvap(1), Uvap(2), Func, Psol);
+                    FindExactCuspPoint(Func, Psol,
+                                       PrevSignOfBcoeff, SignOfBcoeff);
+                    Psol.ParametersOnSurface(reversed, Uvap(1), Uvap(2));
+                    //Status = IntWalk_ArretSurPoint;
+                  }
+                }
+              }
+              if (Status == IntWalk_ArretSurPoint) {
+                if (wd3[I].etat >12) { //line should become open
+                  wd3[I].etat = 12; //declare it open
+                  Tgtbeg = Standard_True;
+                  Tgtend = Standard_False;
+                  N= -lines.Length()-1;
+                  Psol.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
+                  OpenLine(N,Psol,Pnts1,Func,CurrentLine);
+                  StepSign = -1;
+                  SignOfBcoeff = PrevSignOfBcoeff = 0;
                   Rajout = Standard_True;
-                  seqAjout.Append(lines.Length()+1);
+                  seqAjout.Append(N);
+                  StatusPrecedent = IntWalk_OK;
+                  Arrive = Standard_False;
+                  PasC = PasSav;       
+                }
+                else { 
+                  Arrive = Standard_True;                   
+                  if (Ipass!=0) { //point of passage, point of stop
+                    PathPnt = Pnts1.Value(Ipass);
+                    CurrentLine->AddStatusLast(Standard_True,Ipass,PathPnt);
+                    AddPointInCurrentLine(Ipass,PathPnt,CurrentLine);
+                  }
+                  else {
+                    CurrentLine->AddStatusLast(Standard_False);
+                    IntSurf_PntOn2S newP;
+                    newP.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
+                    CurrentLine->AddPoint(newP);
+                    Rajout = Standard_True;
+                    seqAjout.Append(lines.Length()+1);
+                  }
                 }
               }
             }
-            else if (Status == IntWalk_OK) { 
-              if (Ipass!=0) CurrentLine->AddIndexPassing(Ipass);
-              previousPoint.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
-              previousd3d = Func.Direction3d();
-              previousd2d = Func.Direction2d();
-              CurrentLine->AddPoint(previousPoint);
-            }
-            else if (Status == IntWalk_PointConfondu)
-            {
-              aNbIter --;
-            }
-          }
-        }
-        else { //no numerical solution NotDone
-          PasC = PasC/2.;
-          PasCu = Abs(PasC*previousd2d.X());
-          PasCv = Abs(PasC*previousd2d.Y());
-
-          if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
+           else if (Status == IntWalk_OK) { 
+             if (Ipass!=0) CurrentLine->AddIndexPassing(Ipass);
+             previousPoint.SetValue(Func.Point(),reversed,Uvap(1),Uvap(2));
+             //previousd3d = Func.Direction3d();
+             //previousd2d = Func.Direction2d();
+             CurrentLine->AddPoint(previousPoint);
+           }
+            PrevStepWrong = Standard_False;
+         } //there is a solution
+       }
+       else { //no numerical solution NotDone
+          PrevStepWrong = Standard_True;
+         PasC = PasC/2.;
+         PasCu = Abs(PasC*previousd2d.X());
+         PasCv = Abs(PasC*previousd2d.Y());
+
+         if (PasCu <= tolerance(1) && PasCv <= tolerance(2)) {
             if (CurrentLine->NbPoints() == 1)  break; // cancel the line
-            Arrive = Standard_True;
-            CurrentLine->AddStatusFirstLast(Standard_False,Standard_False,
-              Standard_False);
-            Tgtend = Standard_True;
-            Rajout = Standard_True;
-            seqAjout.Append(lines.Length()+1);
-          }  
-        }
-
-        if(aNbIter < 0)
-          break;
+           Arrive = Standard_True;
+           CurrentLine->AddStatusFirstLast(Standard_False,Standard_False,
+                                           Standard_False);
+           Tgtend = Standard_True;
+           Rajout = Standard_True;
+           seqAjout.Append(lines.Length()+1);
+         }  
+       }
       }// end of started line 
       if (Arrive) {
-        CurrentLine->SetTangencyAtBegining(Tgtbeg);
-        CurrentLine->SetTangencyAtEnd(Tgtend);
-
-        lines.Append(CurrentLine);
-        wd2[I].etat=-wd2[I].etat; //mark point as processed
+       CurrentLine->SetTangencyAtBegining(Tgtbeg);
+       CurrentLine->SetTangencyAtEnd(Tgtend);
+        CurrentLine->SetTangency(IsTangentialIntersection);
+       
+       lines.Append(CurrentLine);
+       wd3[I].etat = -wd3[I].etat; //mark point as processed
       }
-    } //end of processing of start point
-  } //end of all start points
+    } //end of processing of tangent point
+  } //end of all tangent points
 }
+
+
+
+
+
+
index b3454916a138816b2ebcb15a63e0f13a5634f2cb..9545be622b908bf9b7de74a0b846da22d62d312c 100644 (file)
@@ -18,8 +18,10 @@ namespace {
   static const Standard_Real CosRef2D = 0.88; // correspond to 25 d
   static const Standard_Integer MaxDivision = 60;  // max number of step division 
                                                    // because the angle is too great in 2d (U4)
+  static const Standard_Real TolDiffPnts = 4.*Precision::Confusion()*Precision::Confusion();
 }
 
+
 IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection
   (TheIWFunction& sp,
    const Standard_Boolean Finished,
@@ -27,7 +29,12 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection
    const IntWalk_StatusDeflection StatusPrecedent,
    Standard_Integer& NbDivision,
    Standard_Real& Step,
-   const Standard_Integer StepSign)
+   Standard_Real& StepInit,
+   const Standard_Integer StepSign,
+   const Standard_Integer CurNbPoints,
+   const Standard_Boolean ArretAjout,
+   const Standard_Boolean PrevStepWrong,
+   const Standard_Boolean OnPrevTangency)
 {
   // Check the step of advancement, AND recalculate this step :
   //
@@ -58,99 +65,131 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection
   //-- if epsilon is great enough (1e-11). In this case one loops 
   //-- without ever changing the values sent to Rsnld. 
   //---------------------------------------------------------------------------------
-  Standard_Real Paramu = 0.0, Paramv = 0.0;
-
-  if (!reversed) {
-    previousPoint.ParametersOnS2(Paramu, Paramv);
-  }
-  else
-  {
-    previousPoint.ParametersOnS1(Paramu, Paramv);
-  }
-
-  const Standard_Real Du = UV(1) - Paramu;
-  const Standard_Real Dv = UV(2) - Paramv;
-  const Standard_Real Duv = Du * Du + Dv * Dv;
+  Standard_Real Paramu = 0., Paramv = 0., StepU = 0., StepV = 0.;
+  Standard_Real Cosi = 0., Cosi2 = 0., Norme = 0.;
 
   gp_Vec Corde(previousPoint.Value(), sp.Point());
 
-  const Standard_Real Norme = Corde.SquareMagnitude(), 
-                      aTol = epsilon*Precision::PConfusion();
-
-  //if ((++NbPointsConfondusConsecutifs < 10) && (Norme <= epsilon)) { // the square is already taken in the constructor
-  if ((Norme <= epsilon) && ((Duv <= aTol) || (StatusPrecedent != IntWalk_OK)))
-  { // the square is already taken in the constructor
-    Status = IntWalk_PointConfondu;
-    if (StatusPrecedent == IntWalk_PasTropGrand) {
-      return IntWalk_ArretSurPointPrecedent;
+  Norme = Corde.SquareMagnitude();
+//  if (Norme <= epsilon*epsilon) {
+//  if (Norme <= epsilon) { // the square is already taken in the constructor
+  Standard_Real TolNorm = Min(TolDiffPnts, epsilon); //epsilon;
+  if (CurNbPoints == 1 && ArretAjout && OnPrevTangency)
+    TolNorm = 1.e-10;
+  if (Norme <= TolNorm) {
+    if (CurNbPoints == 1 && !ArretAjout && !OnPrevTangency &&
+        (Step > StepInit || StepInit - Step <= Precision::Confusion()))
+      //current tolerance is too big even for first step
+      epsilon = Norme / 4.;
+    else
+    {
+      if (Step > StepInit ||
+          StepInit - Step <= Precision::Confusion())
+      {
+        Standard_Real RefDist = Sqrt(Norme);
+        Standard_Real tolconf = Sqrt(TolNorm);
+        Standard_Real LocalResol = 0.;
+        if (RefDist > gp::Resolution())
+          LocalResol = Step * tolconf / RefDist;
+        if (Step < 2*LocalResol)
+          Step = StepInit = pas = 2*LocalResol;
+        return IntWalk_PointConfondu;
+      }
+      Status = IntWalk_PointConfondu;
+      if (StatusPrecedent == IntWalk_PasTropGrand)
+        return IntWalk_ArretSurPointPrecedent;
     }
   }
   else {
-    Standard_Real Cosi = Corde * previousd3d;
-    Standard_Real Cosi2 = 0.0;
-
-    if (Cosi*StepSign >= 0.) {// angle 3d <= pi/2 !!!!
-      const Standard_Real aDiv = previousd3d.SquareMagnitude()*Norme;
-      if(aDiv == 0)
-        return Status;
-      Cosi2 = Cosi * Cosi / aDiv;
+    Cosi = Corde * previousd3d;
+    if (Cosi*StepSign < 0.) { // angle 3d > pi/2 !!!!
+      Cosi2 = 0.;
+    }
+    else {
+      Cosi2 = Cosi * Cosi / previousd3d.SquareMagnitude() / Norme;
     }
     if (Cosi2 < CosRef3D) { //angle 3d too great
       Step = Step /2.0;
-      Standard_Real StepU = Abs(Step*previousd2d.X()),
-                    StepV = Abs(Step*previousd2d.Y());
+      StepU = Abs(Step*previousd2d.X());
+      StepV = Abs(Step*previousd2d.Y());
       if (StepU < tolerance(1) && StepV < tolerance(2)) 
-        Status = IntWalk_ArretSurPointPrecedent;
+       Status = IntWalk_ArretSurPointPrecedent;
       else 
-        Status = IntWalk_PasTropGrand;
+       Status = IntWalk_PasTropGrand;
       return Status;
     }
   }
 
-  const Standard_Real aMinTolU = 0.1*Abs(Step*previousd2d.X()),
-                      aMinTolV = 0.1*Abs(Step*previousd2d.Y());
-  const Standard_Real aTolU = (aMinTolU > 0.0) ? Min(tolerance(1), aMinTolU) : tolerance(1),
-                      aTolV = (aMinTolV > 0.0) ? Min(tolerance(2), aMinTolV) : tolerance(2);
-
-  //If aMinTolU==0.0 then (Abs(Du) < aMinTolU) is equivalent of (Abs(Du) < 0.0).
-  //It is impossible. Therefore, this case should be processed separately.
-  //Analogicaly for aMinTolV.
-
-  if ((Abs(Du) < aTolU) && (Abs(Dv) < aTolV))
+  if (!reversed) {
+    previousPoint.ParametersOnS2(Paramu, Paramv);
+  }
+  else {
+    previousPoint.ParametersOnS1(Paramu, Paramv);
+  }
+  Standard_Real Du = UV(1) - Paramu;
+  Standard_Real Dv = UV(2) - Paramv;
+  Standard_Real Duv = Du * Du + Dv * Dv;
+  Standard_Real TolDu = tolerance(1), TolDv = tolerance(2);
+  if (CurNbPoints == 1 && ArretAjout && OnPrevTangency)
+    TolDu = TolDv = 1.e-7;
+  if (Abs(Du) < TolDu && Abs(Dv) < TolDv)
   {
-    //Thin shapes (for which Ulast-Ufirst or/and Vlast-Vfirst is quite small)
-    //exists (see bug #25820). In this case, step is quite small too.
-    //Nevertheless, it not always means that we mark time. Therefore, Du and Dv
-    //must consider step (aMinTolU and aMinTolV parameters).
-
-    return IntWalk_ArretSurPointPrecedent; //confused point 2d
+    if (CurNbPoints == 1 && Status == IntWalk_OK &&
+        !ArretAjout && !OnPrevTangency &&
+        (Step > StepInit || StepInit - Step <= Precision::Confusion()))
+    {
+      //current tolerance is too big even for first step
+      tolerance(1) = Abs(Du)/2.;
+      tolerance(2) = Abs(Dv)/2.;
+      if (tolerance(1) <= gp::Resolution())
+        tolerance(1) = tolerance(2);
+      if (tolerance(2) <= gp::Resolution())
+        tolerance(2) = tolerance(1);
+      if (tolerance(1) <= gp::Resolution() &&
+          tolerance(2) <= gp::Resolution())
+      {
+        Status = IntWalk_PointConfondu;
+        if (StatusPrecedent == IntWalk_PasTropGrand)
+          Status = IntWalk_ArretSurPointPrecedent;
+        return Status;
+      }
+    }
+    else
+      return IntWalk_ArretSurPointPrecedent; //confused point 2d
   }
-
-  Standard_Real Cosi = StepSign * (Du * previousd2d.X() + Dv * previousd2d.Y());
-
+  Cosi = StepSign * (Du * previousd2d.X() + 
+                     Dv * previousd2d.Y());
   if (Cosi < 0 && Status == IntWalk_PointConfondu) 
     return IntWalk_ArretSurPointPrecedent; // leave as step back  
                                            // with confused point
 
-  if (sp.IsTangent()) 
-    return IntWalk_ArretSurPoint;       
+  if (IsTangentialIntersection)
+  {
+    if (sp.IsTangentSmooth()) 
+      return IntWalk_ArretSurPoint;       
+  }
+  else
+  {
+    if (sp.IsTangent()) 
+      return IntWalk_ArretSurPoint;
+  }
 
 //if during routing one has subdivided more than  MaxDivision for each
 //previous step, bug on the square; do nothing (experience U4)
 
-  if ((NbDivision < MaxDivision) && (Status != IntWalk_PointConfondu) && 
-    (StatusPrecedent!= IntWalk_PointConfondu))
-  {
-    Standard_Real Cosi2 = Cosi * Cosi / Duv;
+  if (NbDivision < MaxDivision && 
+      Status != IntWalk_PointConfondu && 
+      StatusPrecedent!= IntWalk_PointConfondu ) {
+    Cosi2 = Cosi * Cosi / Duv;
     if (Cosi2 < CosRef2D || Cosi < 0  ) {
       Step = Step / 2.0;
-      Standard_Real StepU = Abs(Step*previousd2d.X()),
-                    StepV = Abs(Step*previousd2d.Y());
+      StepU = Abs(Step*previousd2d.X());
+      StepV = Abs(Step*previousd2d.Y());
 
       if (StepU < tolerance(1) && StepV < tolerance(2))
-        Status = IntWalk_ArretSurPointPrecedent;
+       Status = IntWalk_ArretSurPointPrecedent;
       else 
-        Status = IntWalk_PasTropGrand;
+       Status = IntWalk_PasTropGrand;
       NbDivision = NbDivision + 1;
       return Status;
     }
@@ -159,152 +198,147 @@ IntWalk_StatusDeflection IntWalk_IWalking::TestDeflection
     Cosi2 = Cosi * Cosi / sp.Direction3d().SquareMagnitude() / Norme;
     if (Cosi2 < CosRef3D ){ //angle 3d too great
       Step = Step / 2.;
-      Standard_Real StepU = Abs(Step*previousd2d.X()),
-                    StepV = Abs(Step*previousd2d.Y());
+      StepU = Abs(Step*previousd2d.X());
+      StepV = Abs(Step*previousd2d.Y());
       if (StepU < tolerance(1) && StepV < tolerance(2))
-        Status = IntWalk_ArretSurPoint;
+       Status = IntWalk_ArretSurPoint;
       else 
-        Status = IntWalk_PasTropGrand;
+       Status = IntWalk_PasTropGrand;
       return Status;
     }
     Cosi = Du * sp.Direction2d().X() + 
-      Dv * sp.Direction2d().Y();
+           Dv * sp.Direction2d().Y();
     Cosi2 = Cosi * Cosi / Duv;
     if (Cosi2 < CosRef2D || 
-      sp.Direction2d() * previousd2d < 0) {
-        //angle 2d too great or change the side       
-        Step  = Step / 2.;
-        Standard_Real StepU = Abs(Step*previousd2d.X()),
-                      StepV = Abs(Step*previousd2d.Y());
-        if (StepU < tolerance(1) && StepV < tolerance(2))
-          Status = IntWalk_ArretSurPointPrecedent;
-        else 
-          Status = IntWalk_PasTropGrand;
-        return Status;
+       sp.Direction2d() * previousd2d < 0) {
+      //angle 2d too great or change the side       
+      Step  = Step / 2.;
+      StepU = Abs(Step*previousd2d.X());
+      StepV = Abs(Step*previousd2d.Y());
+      if (StepU < tolerance(1) && StepV < tolerance(2))
+       Status = IntWalk_ArretSurPointPrecedent;
+      else 
+       Status = IntWalk_PasTropGrand;
+      return Status;
     }
   }
 
   if (!Finished) {
-    if (Status == IntWalk_PointConfondu)
-    {
-      Standard_Real StepU = Min(Abs(1.5 * Du),pas*(UM-Um)),
-                    StepV = Min(Abs(1.5 * Dv),pas*(VM-Vm));
+
+    if (Status == IntWalk_PointConfondu) {
+      StepU = Min(Abs(1.5 * Du),pas*(UM-Um));
+      StepV = Min(Abs(1.5 * Dv),pas*(VM-Vm));
 
       Standard_Real d2dx = Abs(previousd2d.X()); 
       Standard_Real d2dy = Abs(previousd2d.Y()); 
 
-      if (d2dx < tolerance(1))
-      {
-        Step = StepV/d2dy;
+      Standard_Real PrevStep = Step;
+      if (d2dx < tolerance(1)) {
+       Step = StepV/d2dy;
       }
-      else if (d2dy < tolerance(2))
-      {
-        Step = StepU/d2dx;
+      else if (d2dy < tolerance(2)) {
+       Step = StepU/d2dx;
       }
-      else
-      {
-        Step = Min(StepU/d2dx,StepV/d2dy);
+      else {
+       Step = Min(StepU/d2dx,StepV/d2dy);
       }
+      if (Step <= PrevStep) //no chance for increasing of real step
+        Status = IntWalk_ArretSurPointPrecedent;
+      else if (PrevStepWrong)
+        return IntWalk_ArretSurPoint; //break of surface: end of C1-interval
     }
-    else
-    {
-      //   estimate the current vector.
-      //   if vector/2<=current vector<= vector it is considered that the criterion
-      //   is observed.
-      //   otherwise adjust the step depending on the previous step 
-
-      /*
-        Standard_Real Dist = Sqrt(Norme)/3.;
-        TColgp_Array1OfPnt Poles(1,4);
-        gp_Pnt POnCurv,Milieu;
-        Poles(1) = previousPoint.Value();
-        Poles(4) = sp.Point();
-        Poles(2) = Poles(1).XYZ() + 
-      StepSign * Dist* previousd3d.Normalized().XYZ();
-        Poles(3) = Poles(4).XYZ() - 
-      StepSign * Dist*sp.Direction3d().Normalized().XYZ();
-        BzCLib::PntPole(0.5,Poles,POnCurv);
-        Milieu = (Poles(1).XYZ() + Poles(4).XYZ())*0.5;
-      //      FlecheCourante = Milieu.Distance(POnCurv);
-        Standard_Real FlecheCourante = Milieu.SquareDistance(POnCurv);
-      */
-
-        // Direct calculation : 
-        // POnCurv=(((p1+p2)/2.+(p2+p3)/2.)/2. + ((p2+p3)/2.+(p3+P4)/2.)/2.)/2.
-        // either POnCurv = p1/8. + 3.p2/8. + 3.p3/8. + p4/8.
-        // Or p2 = p1 + lambda*d1 et p3 = p4 - lambda*d4
-        // So POnCurv = (p1 + p4)/2. + 3.*(lambda d1 - lambda d4)/8.
-        // Calculate the deviation with (p1+p4)/2. . So it is just necessary to calculate
-        // the norm (square) of 3.*lambda (d1 - d4)/8.
-        // either the norm of :
-        //    3.*(Sqrt(Norme)/3.)*StepSign*(d1-d4)/8.
-        // which produces, takin the square :
-        //         Norme * (d1-d4).SquareMagnitude()/64.
+    else {
+//   estimate the current vector.
+//   if vector/2<=current vector<= vector it is considered that the criterion
+//   is observed.
+//   otherwise adjust the step depending on the previous step 
+
+/*
+      Standard_Real Dist = Sqrt(Norme)/3.;
+      TColgp_Array1OfPnt Poles(1,4);
+      gp_Pnt POnCurv,Milieu;
+      Poles(1) = previousPoint.Value();
+      Poles(4) = sp.Point();
+      Poles(2) = Poles(1).XYZ() + 
+       StepSign * Dist* previousd3d.Normalized().XYZ();
+      Poles(3) = Poles(4).XYZ() - 
+       StepSign * Dist*sp.Direction3d().Normalized().XYZ();
+      BzCLib::PntPole(0.5,Poles,POnCurv);
+      Milieu = (Poles(1).XYZ() + Poles(4).XYZ())*0.5;
+//      FlecheCourante = Milieu.Distance(POnCurv);
+      Standard_Real FlecheCourante = Milieu.SquareDistance(POnCurv);
+*/
+
+      // Direct calculation : 
+      // POnCurv=(((p1+p2)/2.+(p2+p3)/2.)/2. + ((p2+p3)/2.+(p3+P4)/2.)/2.)/2.
+      // either POnCurv = p1/8. + 3.p2/8. + 3.p3/8. + p4/8.
+      // Or p2 = p1 + lambda*d1 et p3 = p4 - lambda*d4
+      // So POnCurv = (p1 + p4)/2. + 3.*(lambda d1 - lambda d4)/8.
+      // Calculate the deviation with (p1+p4)/2. . So it is just necessary to calculate
+      // the norm (square) of 3.*lambda (d1 - d4)/8.
+      // either the norm of :
+      //    3.*(Sqrt(Norme)/3.)*StepSign*(d1-d4)/8.
+      // which produces, takin the square :
+      //         Norme * (d1-d4).SquareMagnitude()/64.
 
       Standard_Real FlecheCourante = 
        (previousd3d.Normalized().XYZ()-sp.Direction3d().Normalized().XYZ()).SquareModulus()*Norme/64.;
 
   
 //      if (FlecheCourante <= 0.5*fleche) {
-      if (FlecheCourante <= 0.25*fleche*fleche)
-      {
-        Standard_Real d2dx = Abs(sp.Direction2d().X()); 
-        Standard_Real d2dy = Abs(sp.Direction2d().Y()); 
-        
-        Standard_Real StepU = Min(Abs(1.5*Du),pas*(UM-Um)),
-                      StepV = Min(Abs(1.5*Dv),pas*(VM-Vm));
-
-        if (d2dx < tolerance(1))
-        {
-          Step = StepV/d2dy;
-        }
-        else if (d2dy < tolerance(2))
-        {
-          Step = StepU/d2dx;
-        }
-        else
-        {
-          Step = Min(StepU/d2dx,StepV/d2dy);
-        }      
+      if (FlecheCourante <= 0.25*fleche*fleche) {
+
+       Standard_Real d2dx = Abs(sp.Direction2d().X()); 
+       Standard_Real d2dy = Abs(sp.Direction2d().Y()); 
+
+       StepU = Min(Abs(1.5*Du),pas*(UM-Um));
+       StepV = Min(Abs(1.5*Dv),pas*(VM-Vm));
+
+       if (d2dx < tolerance(1)) {
+         Step = StepV/d2dy;
+       }
+       else if (d2dy < tolerance(2)) {
+         Step = StepU/d2dx;
+       }
+       else {
+         Step = Min(StepU/d2dx,StepV/d2dy);
+       }
+       
       }
-      else
-      {
-        //if (FlecheCourante > fleche) {  // step too great
-        if (FlecheCourante > fleche*fleche)
-        {  // step too great
-          Step = Step /2.;
-          Standard_Real StepU = Abs(Step*previousd2d.X()),
-                        StepV = Abs(Step*previousd2d.Y());
-          
+      else {
+//     if (FlecheCourante > fleche) {  // step too great
+       if (FlecheCourante > fleche*fleche) {  // step too great
+         Step = Step /2.;
+          StepU = Abs(Step*previousd2d.X());
+          StepV = Abs(Step*previousd2d.Y());
           if (StepU < tolerance(1) && StepV < tolerance(2)) 
             Status = IntWalk_ArretSurPointPrecedent;
           else 
             Status = IntWalk_PasTropGrand;
-        }
-        else
-        {
-          Standard_Real d2dx = Abs(sp.Direction2d().X()); 
-          Standard_Real d2dy = Abs(sp.Direction2d().Y()); 
-          
-          Standard_Real StepU = Min(Abs(1.5*Du),pas*(UM-Um)),
-                        StepV = Min(Abs(1.5*Dv),pas*(VM-Vm));
-
-          if (d2dx < tolerance(1))
-          {
-            Step = Min(Step,StepV/d2dy);
-          }
-          else if (d2dy < tolerance(2))
-          {
-            Step = Min(Step,StepU/d2dx);
-          }
-          else
-          {
-            Step = Min(Step,Min(StepU/d2dx,StepV/d2dy));
-          }
-        }
+       }
+       else {
+         Standard_Real d2dx = Abs(sp.Direction2d().X()); 
+         Standard_Real d2dy = Abs(sp.Direction2d().Y()); 
+
+         StepU = Min(Abs(1.5*Du),pas*(UM-Um));
+         StepV = Min(Abs(1.5*Dv),pas*(VM-Vm));
+
+         if (d2dx < tolerance(1)) {
+           Step = Min(Step,StepV/d2dy);
+         }
+         else if (d2dy < tolerance(2)) {
+           Step = Min(Step,StepU/d2dx);
+         }
+         else {
+           Step = Min(Step,Min(StepU/d2dx,StepV/d2dy));
+         }
+       }
       }
     }
   }
+  else if (Status == IntWalk_PointConfondu) //finish
+    Status = IntWalk_ArretSurPointPrecedent;
+  
   return Status;     
 }
 
index 5bf7f3495872d9e6e56c9808555ca73abaa94c00..638fb67aa2939a03da6e6cc6dba2e56abcd2dc4d 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <Geom2d_Line.hxx>
+#include <GCE2d_MakeLine.hxx>
+
+
 #ifndef OCCT_DEBUG
 #define No_Standard_RangeError
 #define No_Standard_OutOfRange
 #endif
 
+const Standard_Real TolDiscr = 1.e-8;
+const Standard_Real TolB = 1.e-5;
+
+static Standard_Integer RealSign(const Standard_Real aValue)
+{
+  if (aValue >= 0.)
+    return 1;
+  else return -1;
+}
+
+static Standard_Boolean ComputeB11orB22(TheIWFunction& sp,
+                                        Standard_Boolean& IsDiscriminantNull,
+                                        Standard_Integer& SignOfBcoeff,
+                                        gp_Vec& Pu,
+                                        gp_Vec& Pv,
+                                        Standard_Real& B11,
+                                        Standard_Real& B22,
+                                        Standard_Real& B12)
+{
+  gp_Vec Puu, Puv, Pvv;
+  gp_Vec Iu, Iv, Iuu, Iuv, Ivv;
+  gp_Vec NormalP, NormalI;
+
+  if (!sp.DerivativesAndNormalOnPSurf(Pu, Pv, NormalP, Puu, Pvv, Puv))
+    return Standard_False;
+  if (!sp.DerivativesAndNormalOnISurf(Iu, Iv, NormalI, Iuu, Ivv, Iuv))
+    return Standard_False;
+
+  Standard_Real Lp, Mp, Np, Li, Mi, Ni; //second fundamental form coefficients
+  Lp = Puu * NormalP;
+  Mp = Puv * NormalP;
+  Np = Pvv * NormalP;
+  Li = Iuu * NormalI;
+  Mi = Iuv * NormalI;
+  Ni = Ivv * NormalI;
+
+  gp_Vec Normal;
+  if (NormalP * NormalI < 0.)
+    NormalI.Reverse();
+  Normal.SetXYZ(0.5*(NormalP.XYZ() + NormalI.XYZ()));
+  Normal.Normalize();
+
+  Standard_Real A11, A12, A21, A22;
+  Standard_Real NormIdotNorm = (Iu ^ Iv) * Normal;
+  A11 = ((Pu ^ Iv) * Normal) / NormIdotNorm;
+  A12 = ((Pv ^ Iv) * Normal) / NormIdotNorm;
+  A21 = ((Iu ^ Pu) * Normal) / NormIdotNorm;
+  A22 = ((Iu ^ Pv) * Normal) / NormIdotNorm;
+
+  //Standard_Real B11, B12, B22;
+  B11 = A11*A11*Li + 2*A11*A21*Mi + A21*A21*Ni - Lp;
+  B12 = A11*A12*Li + (A11*A22 + A21*A12)*Mi + A21*A22*Ni - Mp;
+  B22 = A12*A12*Li + 2*A12*A22*Mi + A22*A22*Ni - Np;
+
+  Standard_Real Discriminant = B12*B12 - B11*B22;
+
+  if (Abs(Discriminant) < TolDiscr)
+  {
+    IsDiscriminantNull = Standard_True;
+    if (Abs(B11) <= TolB && Abs(B22) <= TolB)
+    {
+#ifdef DRAW
+      cout<<"Possible branching"<<endl<<endl;
+#endif
+      SignOfBcoeff = 0;
+    }
+    else
+    {
+      gp_Vec NewPreviousD3d;
+      gp_Dir2d NewPreviousD2d;
+      if (Abs(B11) > TolB)
+      {
+#ifdef DRAW
+        cout<<"B11 = "<<B11<<endl;
+#endif
+        SignOfBcoeff = RealSign(B11);
+      }
+      else
+      {
+#ifdef DRAW
+        cout<<"B22 = "<<B22<<endl;
+#endif
+        SignOfBcoeff = RealSign(B22);
+      }
+    }
+  }
+  else
+  {
+    IsDiscriminantNull = Standard_False;
+#ifdef DRAW
+    cout<<"Discriminant = "<<Discriminant<<endl;
+#endif
+  }
+  return Standard_True;
+}
 
 void IntWalk_IWalking::AddPointInCurrentLine
          (const Standard_Integer N,
@@ -39,7 +138,6 @@ void IntWalk_IWalking::MakeWalkingPoint
          IntSurf_PntOn2S& Psol )
 
 {
-
 // Case == 1      : make a WalkinkPoint.
 // Case == 2      : make a WalkinkPoint.
 //                  The computation of the tangency on is done  
@@ -60,15 +158,117 @@ void IntWalk_IWalking::MakeWalkingPoint
     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 {
     Standard_ConstructionError::Raise();
   }
+}
 
-
+Standard_Boolean
+ IntWalk_IWalking::ComputeDirOfTangentialIntersection(TheIWFunction& sp,
+                                                      Standard_Integer& StepSignTangent,
+                                                      Standard_Boolean& IsDiscriminantNull,
+                                                      Standard_Integer& SignOfBcoeff,
+                                                      gp_Vec&   newd3d,
+                                                      gp_Dir2d& newd2d)
+{
+  gp_Vec Pu, Pv;
+  Standard_Real B11, B22, B12;
+  if (!ComputeB11orB22(sp, IsDiscriminantNull, SignOfBcoeff,
+                       Pu, Pv, B11, B22, B12))
+    return Standard_False;
+  
+  if (IsDiscriminantNull)
+  {
+    if (SignOfBcoeff != 0)
+    {
+      gp_Vec NewPreviousD3d;
+      gp_Dir2d NewPreviousD2d;
+      if (Abs(B11) > TolB)
+      {
+#ifdef DRAW
+        cout<<"B11 = "<<B11<<endl;
+#endif
+        Standard_Real CoefPu = -B12/B11;
+        NewPreviousD3d = CoefPu*Pu + Pv;
+        NewPreviousD3d.Normalize();
+        NewPreviousD2d = gp_Dir2d(CoefPu, 1.);
+      }
+      else
+      {
+#ifdef DRAW
+        cout<<"B22 = "<<B22<<endl;
+#endif
+        Standard_Real CoefPv = -B12/B22;
+        NewPreviousD3d = Pu + CoefPv*Pv;
+        NewPreviousD3d.Normalize();
+        NewPreviousD2d = gp_Dir2d(1., CoefPv);
+      }
+      
+      if (!IsTangentialIntersection)
+      {
+        IsTangentialIntersection = Standard_True;
+        if (NewPreviousD3d * previousd3d < 0)
+          StepSignTangent = -1;
+        else
+          StepSignTangent = 1;
+      }
+      newd3d = StepSignTangent * NewPreviousD3d;
+      newd2d = StepSignTangent * NewPreviousD2d;
+    }
+  }
+  return Standard_True;
 }
 
+void IntWalk_IWalking::FindExactCuspPoint(TheIWFunction& sp,
+                                          IntSurf_PntOn2S& Psol,
+                                          const Standard_Integer SignFirst,
+                                          const Standard_Integer /*SignLast*/)
+{
+  IntSurf_PntOn2S EndPoint = Psol;
+
+  IntSurf_PntOn2S Pfirst, Plast;
+
+  Standard_Real newU, newV;
+  IntSurf_PntOn2S newPoint;
+
+  Pfirst = previousPoint;
+  Plast =  EndPoint;
+
+  Standard_Integer newSign = 0;
+
+  for (;;)
+  {
+    Standard_Real Ufirst, Vfirst, Ulast, Vlast;
+    Pfirst.ParametersOnSurface(reversed, Ufirst, Vfirst);
+    Plast.ParametersOnSurface(reversed, Ulast, Vlast);
+    
+    newU = 0.5*(Ufirst + Ulast);
+    newV = 0.5*(Vfirst + Vlast);
+
+    if (Abs(newU - Ufirst) < tolerance(1) &&
+        Abs(newV - Vfirst) < tolerance(2))
+      break;
+    
+    MakeWalkingPoint(11, newU, newV, sp, newPoint);
+    Standard_Boolean IsDiscriminantNull;
+    gp_Vec Pu, Pv;
+    Standard_Real B11, B22, B12;
+    ComputeB11orB22(sp, IsDiscriminantNull, newSign,
+                    Pu, Pv, B11, B22, B12);
+    
+    if (newSign == 0)
+      break;
+
+    if (newSign == SignFirst)
+      Pfirst = newPoint;
+    else //newSign == SignLast
+      Plast = newPoint;
+  }
+
+  Psol = newPoint;
+}
 
 
 void IntWalk_IWalking::OpenLine(const Standard_Integer N,
@@ -94,8 +294,28 @@ void IntWalk_IWalking::OpenLine(const Standard_Integer N,
     previousPoint.ParametersOnS1(UV(1),UV(2));
   }
   sp.Values(UV, FF, DD);
-  previousd3d = sp.Direction3d();
-  previousd2d = sp.Direction2d();
+  if (sp.IsTangent())
+  {
+    IsTangentialIntersection = Standard_True;
+    Standard_Integer theSign = 1;
+    Standard_Integer theSignOfBcoeff = 0;
+    gp_Vec   newd3d;
+    gp_Dir2d newd2d;
+    Standard_Boolean IsDiscriminantNull;
+    if (!ComputeDirOfTangentialIntersection(sp, theSign,
+                                            IsDiscriminantNull, theSignOfBcoeff,
+                                            newd3d, newd2d) ||
+        !IsDiscriminantNull)
+      StdFail_UndefinedDerivative::Raise();
+    previousd3d = newd3d;
+    previousd2d = newd2d;
+  }
+  else
+  {
+    IsTangentialIntersection = Standard_False;
+    previousd3d = sp.Direction3d();
+    previousd2d = sp.Direction2d();
+  }
 
   if (N>0) { //departure point given at input
     PathPnt = Pnts1.Value(N);
index abbca8225753d306173cc0f48ea3bf512e496e78..7da1bf78653cf18b4126e1cfd935e18080923410 100644 (file)
@@ -1211,6 +1211,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
             break;
           }
         case IntWalk_OK:
+        case IntWalk_OKtangent:
         case IntWalk_ArretSurPoint://006
           {
             //=======================================================
@@ -1803,6 +1804,7 @@ Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsop
           break;
         }
       case IntWalk_OK:
+      case IntWalk_OKtangent:
       case IntWalk_ArretSurPoint:
         {
           //
@@ -2907,7 +2909,8 @@ IntWalk_StatusDeflection  IntWalk_PWalking::TestDeflection(const IntImp_ConstIso
       Standard_Real LocalResol = 0.;
       if (RefDist > gp::Resolution())
         LocalResol = pasuv[choixIso] * tolconf / RefDist;
-      if (pasuv[choixIso] <= LocalResol)
+      //if (pasuv[choixIso] <= LocalResol)
+      if (pasuv[choixIso] < 2*LocalResol)
         pasuv[choixIso] = pasInit[choixIso] = 2*LocalResol;
     }
     ////////////////////////////////////////
index 93ad6ea2e669099a8f97f124db492ec87bc2f7e2..a5500335f5c02cb972daee05819b25dc8670cbac 100644 (file)
@@ -24,7 +24,8 @@ IntWalk_PasTropGrand,
 IntWalk_PointConfondu,
 IntWalk_ArretSurPointPrecedent,
 IntWalk_ArretSurPoint,
-IntWalk_OK
+IntWalk_OK,
+IntWalk_OKtangent
 };
 
 #endif // _IntWalk_StatusDeflection_HeaderFile