]> OCCT Git - occt-copy.git/commitdiff
Intermediate state. New walking algorithm was implemented based on curve curvature... CR23914
authorabk <abk@opencascade.com>
Thu, 30 May 2013 10:59:35 +0000 (14:59 +0400)
committerabk <abk@opencascade.com>
Thu, 30 May 2013 11:02:24 +0000 (15:02 +0400)
src/IntWalk/IntWalk_PWalking_1.gxx

index a2614394eae49604bd5193107627f707352e0190..b42933202e4a903f30a7020c1d7287065314d272 100755 (executable)
@@ -416,6 +416,1119 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep,
                               const Standard_Real v1max,
                               const Standard_Real u2max,
                               const Standard_Real v2max)
+{
+  Standard_Real aU = -0.460173271833187, aV = 0.460173271833188, aW = -0.325391641034047;
+  Standard_Real aT = 0.563594854629184, aMaxN = 0;
+  //cout << endl << "start" << endl;
+  int aC = 0;
+  //xf
+  Standard_Integer i, NbPasOKConseq;
+  Standard_Real UFirst1, VFirst1, ULast1, VLast1, UFirst2, VFirst2, ULast2, VLast2;
+  Standard_Real pasMaxSV[4], aTmp;
+  TColStd_Array1OfReal Param(1,4);
+  IntImp_ConstIsoparametric ChoixIso;
+  //xt
+  //
+  done = Standard_False;
+  NbPasOKConseq=0;
+  //
+  // Caro1 and Caro2
+  const ThePSurface& Caro1 =myIntersectionOn2S.Function().AuxillarSurface1();
+  const ThePSurface& Caro2 =myIntersectionOn2S.Function().AuxillarSurface2();
+  //
+  UFirst1 = ThePSurfaceTool::FirstUParameter(Caro1);
+  VFirst1 = ThePSurfaceTool::FirstVParameter(Caro1);
+  ULast1  = ThePSurfaceTool::LastUParameter (Caro1);
+  VLast1  = ThePSurfaceTool::LastVParameter (Caro1);
+  //
+  UFirst2 = ThePSurfaceTool::FirstUParameter(Caro2);
+  VFirst2 = ThePSurfaceTool::FirstVParameter(Caro2);
+  ULast2  = ThePSurfaceTool::LastUParameter (Caro2);
+  VLast2  = ThePSurfaceTool::LastVParameter (Caro2);
+  //
+  ComputePasInit(pasuv,u1min,u1max,v1min,v1max,u2min,u2max,v2min,v2max,
+                Um1,UM1,Vm1,VM1,Um2,UM2,Vm2,VM2,Caro1,Caro2,pasMax+pasMax);
+  //
+  if(pasuv[0]<100*ResoU1) {
+    pasuv[0]=100*ResoU1; 
+  }
+  if(pasuv[1]<100*ResoV1) {
+    pasuv[1]=100*ResoV1; 
+  }
+  if(pasuv[2]<100*ResoU2) {
+    pasuv[2]=100*ResoU2;
+  }
+  if(pasuv[3]<100*ResoV2) {
+    pasuv[3]=100*ResoV2;
+  }
+  //
+  for (i=0; i<4; ++i) {
+    if(pasuv[i]>10) {
+      pasuv[i] = 10;
+    }
+    pasInit[i] = pasSav[i] = pasuv[i]; 
+  }
+  //
+  line = new IntSurf_LineOn2S ();
+  //
+  for (i=1; i<=4; ++i) {
+    aTmp=ParDep(i);
+    Param(i)=ParDep(i);
+  }
+  //-- reprise des pas uv lies aux surfaces Caro1 et Caro2
+  //-- pasuv[] et pasSav[] sont modifies lors du cheminement
+  for(i = 0; i < 4; ++i) { 
+    pasMaxSV[i] = pasSav[i] = pasuv[i] = pasInit[i]; 
+  }
+
+  //-- calcul du premier point solution
+  math_FunctionSetRoot  Rsnld(myIntersectionOn2S.Function());
+  //
+  ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld);
+  if (!myIntersectionOn2S.IsDone())   {
+    return;
+  }
+  //
+  if (myIntersectionOn2S.IsEmpty()) {
+    return;
+  }
+  //
+  if(myIntersectionOn2S.IsTangent()) {
+    return;
+  }
+  //
+  Standard_Boolean Arrive, DejaReparti;
+  Standard_Integer IncKey, RejectIndex;
+  gp_Pnt pf,pl;
+  //
+  DejaReparti = Standard_False;
+  IncKey = 0;
+  RejectIndex = 0;
+  //
+  previousPoint = myIntersectionOn2S.Point();
+  previoustg = Standard_False;
+  previousd  = myIntersectionOn2S.Direction();
+  previousd1 = myIntersectionOn2S.DirectionOnS1();
+  previousd2 = myIntersectionOn2S.DirectionOnS2();
+  indextg = 1;
+  tgdir   = previousd;
+  firstd1 = previousd1;
+  firstd2 = previousd2;
+  tgfirst = tglast = Standard_False;
+  choixIsoSav  =  ChoixIso;
+  //------------------------------------------------------------
+  //-- On Teste si le premier point de cheminement correspond 
+  //-- a un point sur frontiere. 
+  //-- Dans ce cas, DejaReparti est initialise a True
+  //-- 
+  pf = previousPoint.Value();
+  Standard_Boolean bTestFirstPoint = Standard_True;
+  
+  previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));  
+  AddAPoint(line,previousPoint);
+  {
+    const gp_Pnt & aP = pf;
+    //cout << "(X, Y, Z) = " << aP.X()  << " " << aP.Y()  << " " << aP.Z() << endl;
+  }
+  //
+  IntWalk_StatusDeflection Status = IntWalk_OK;
+  Standard_Boolean NoTestDeflection = Standard_False;
+  Standard_Real SvParam[4], f;
+  Standard_Integer LevelOfEmptyInmyIntersectionOn2S=0;
+  Standard_Integer LevelOfPointConfondu = 0; 
+  Standard_Integer LevelOfIterWithoutAppend = -1;
+  //
+  Arrive = Standard_False;
+  int aC2 = 0;
+  Standard_Boolean aReduceStep = Standard_False;
+  Standard_Real aStepCoef;
+  while(!Arrive) {//010
+    //cout << ++aC2 << endl;
+    LevelOfIterWithoutAppend++;
+    if(LevelOfIterWithoutAppend>20) { 
+      Arrive = Standard_True; 
+      if(DejaReparti) {
+       break;
+      }
+      RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
+      LevelOfIterWithoutAppend = 0;
+      aReduceStep = Standard_False;
+    }
+    //
+    // compute f
+    f = 0.;
+    switch (ChoixIso) { 
+      case IntImp_UIsoparametricOnCaro1: f = Abs(previousd1.X()); break;
+      case IntImp_VIsoparametricOnCaro1: f = Abs(previousd1.Y()); break;
+      case IntImp_UIsoparametricOnCaro2: f = Abs(previousd2.X()); break;
+      case IntImp_VIsoparametricOnCaro2: f = Abs(previousd2.Y()); break;
+      default:break;
+    }
+    //
+    if(f<0.1) {
+      f=0.1;
+    }
+    //
+    previousPoint.Parameters(Param(1),Param(2),Param(3),Param(4));
+    //
+    //--ofv.begin
+    Standard_Real aIncKey, aEps, dP1, dP2, dP3, dP4;
+    //
+    // Calculation of parameters for adaptive step.
+    //
+    if ((Status == IntWalk_PasTropGrand) || (aReduceStep == Standard_True))
+    {
+      aStepCoef *= 0.5;
+    }
+    else
+    {
+      aStepCoef = 1;
+    }
+    aReduceStep = Standard_False;
+    //cout << "aStepCoef = " << aStepCoef << endl;
+    gp_Vec aCD;
+    gp_Vec2d aSDs[2];
+    Standard_Real aR;
+    Standard_Real a2DR;
+    Standard_Boolean anIsAdaptiveStep;
+    {
+      Standard_Real aPs[] = {Param(1), Param(2), Param(3), Param(4)};
+      anIsAdaptiveStep = CalculateStepData(aPs, aCD, aSDs, aR, a2DR);
+      if (!anIsAdaptiveStep)
+      {
+        LevelOfIterWithoutAppend = 20;
+        continue;
+        //cout << "error" << endl;
+      }
+    }
+    //
+    //
+    //
+    Standard_Real aMaxStep = DBL_MAX;
+    Standard_Real aNT = 1e-12;
+    if (anIsAdaptiveStep)
+    {
+      if (aSDs[0].X() < -aNT)
+      {
+        aMaxStep = Min(aMaxStep, (UFirst1 - Param(1)) / aSDs[0].X());
+      }
+      if (aNT < aSDs[0].X())
+      {
+        aMaxStep = Min(aMaxStep, (ULast1 - Param(1)) / aSDs[0].X());
+      }
+      if (aSDs[0].Y() < -aNT)
+      {
+        aMaxStep = Min(aMaxStep, (VFirst1 - Param(2)) / aSDs[0].Y());
+      }
+      if (aNT < aSDs[0].Y())
+      {
+        aMaxStep = Min(aMaxStep, (VLast1 - Param(2)) / aSDs[0].Y());
+      }
+      //
+      if (aSDs[1].X() < -aNT)
+      {
+        aMaxStep = Min(aMaxStep, (UFirst2 - Param(3)) / aSDs[1].X());
+      }
+      if (aNT < aSDs[1].X())
+      {
+        aMaxStep = Min(aMaxStep, (ULast2 - Param(3)) / aSDs[1].X());
+      }
+      if (aSDs[1].Y() < -aNT)
+      {
+        aMaxStep = Min(aMaxStep, (VFirst2 - Param(4)) / aSDs[1].Y());
+      }
+      if (aNT < aSDs[1].Y())
+      {
+        aMaxStep = Min(aMaxStep, (VLast2 - Param(4)) / aSDs[1].Y());
+      }
+      //
+      //aMaxStep = Min(aMaxStep, aR);
+      aMaxStep = Min(aMaxStep, a2DR);
+      aMaxStep *= aStepCoef;
+      if (aMaxStep < 1e-5)
+      {
+        LevelOfIterWithoutAppend = 20;
+        continue;
+        dP1 = 0;
+        dP2 = 0;
+        dP3 = 0;
+        dP4 = 0;
+        //if (aDirection++ != 0)
+        //{
+        //  Arrive = Standard_True;
+        //  break;
+        //}
+      //  anAreCollinear = Standard_True;
+      }
+      //else
+      {
+        dP1 = aMaxStep * aSDs[0].X();
+        dP2 = aMaxStep * aSDs[0].Y();
+        dP3 = aMaxStep * aSDs[1].X();
+        dP4 = aMaxStep * aSDs[1].Y();
+      }
+    }
+    else
+    //if (anAreCollinear)
+    {
+      dP1 = sensCheminement * pasuv[0] * previousd1.X() /f;
+      dP2 = sensCheminement * pasuv[1] * previousd1.Y() /f;
+      dP3 = sensCheminement * pasuv[2] * previousd2.X() /f; 
+      dP4 = sensCheminement * pasuv[3] * previousd2.Y() /f;
+      //
+      aIncKey=5.*(Standard_Real)IncKey;
+      aEps=1.e-7;
+      if(ChoixIso == IntImp_UIsoparametricOnCaro1 && Abs(dP1) < aEps) {
+        dP1 *= aIncKey;
+      }
+      if(ChoixIso == IntImp_VIsoparametricOnCaro1 && Abs(dP2) < aEps) {
+        dP2 *= aIncKey;
+      }
+      if(ChoixIso == IntImp_UIsoparametricOnCaro2 && Abs(dP3) < aEps) {
+        dP3 *= aIncKey;
+      }
+      if(ChoixIso == IntImp_VIsoparametricOnCaro2 && Abs(dP4) < aEps) {
+        dP4 *= aIncKey;
+      }
+    }
+    //--ofv.end
+    //
+    Param(1) += dP1;
+    Param(2) += dP2;
+    Param(3) += dP3; 
+    Param(4) += dP4;
+    //
+    if (Param(1) < UFirst1)
+    {
+      Param(1) = UFirst1;
+    }
+    if (ULast1 < Param(1))
+    {
+      Param(1) = ULast1;
+    }
+    if (Param(2) < VFirst1)
+    {
+      Param(2) = VFirst1;
+    }
+    if (VLast1 < Param(2))
+    {
+      Param(2) = ULast1;
+    }
+    //
+    if (Param(3) < UFirst2)
+    {
+      Param(3) = UFirst2;
+    }
+    if (ULast2 < Param(3))
+    {
+      Param(3) = ULast2;
+    }
+    if (Param(4) < VFirst2)
+    {
+      Param(4) = VFirst2;
+    }
+    if (VLast2 < Param(4))
+    {
+      Param(4) = ULast2;
+    }
+    //==========================
+    SvParam[0]=Param(1); 
+    SvParam[1]=Param(2);
+    SvParam[2]=Param(3);
+    SvParam[3]=Param(4);
+    //
+    ChoixIso= myIntersectionOn2S.Perform(Param, Rsnld, ChoixIso);                  
+    //
+    if (!myIntersectionOn2S.IsDone())   {
+      //arret de la ligne,division
+      Arrive = Standard_False;
+      Param(1)=SvParam[0]; 
+      Param(2)=SvParam[1]; 
+      Param(3)=SvParam[2];
+      Param(4)=SvParam[3];
+      RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
+    }
+    else  {//009 
+
+                 if (!myIntersectionOn2S.IsEmpty())
+                 {
+                   Standard_Real u1,v1,u2,v2; 
+                   myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2);
+                   const gp_Pnt & aP = myIntersectionOn2S.Point().Value();
+                   gp_Pnt aP1, aP2;
+                   ThePSurfaceTool::D0(Caro1, u1, v1, aP1);
+                   ThePSurfaceTool::D0(Caro2, u2, v2, aP2);
+                   //cout << "(X, Y, Z) = " << aP.X()  << " " << aP.Y()  << " " << aP.Z() <<
+                   //  "; P1 = " << aP1.X()  << " " << aP1.Y()  << " " << aP1.Z() <<
+                   //  "; P2 = " << aP2.X()  << " " << aP2.Y()  << " " << aP2.Z() << endl;
+                   //Standard_Real aN = Abs(aU - u1) + Abs(aV - v1) + Abs(aW - u2) + Abs(aT - v2);
+                   //aMaxN = Max(aMaxN, aN);
+                   //cout << ++aC << ": N = " << aN << "; MaxN = " << aMaxN << "; u = " << u1 << "; v = " << v1 << "; w = " << u2 << "; t = " << v2 << endl;
+                   //aU = u1; aV = v1; aW = u2; aT = v2;
+                 }
+
+      //== Le calcul du point exact a partir de Param(.) est possible
+      if (myIntersectionOn2S.IsEmpty())
+      {
+        if (!anIsAdaptiveStep)
+        {
+       Standard_Real u1,v1,u2,v2;
+       previousPoint.Parameters(u1,v1,u2,v2);
+       //
+       Arrive = Standard_False;
+       if(u1<UFirst1 || u1>ULast1) {
+         Arrive=Standard_True;
+       }       
+       if(u2<UFirst2 || u2>ULast2) {
+         Arrive=Standard_True;
+       }
+       if(v1<VFirst1 || v1>VLast1) {
+         Arrive=Standard_True;
+       }
+       if(v2<VFirst2 || v2>VLast2) {
+         Arrive=Standard_True;
+       }       
+       RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
+       LevelOfEmptyInmyIntersectionOn2S++;
+       //
+       if(LevelOfEmptyInmyIntersectionOn2S>10)    {
+         pasuv[0]=pasSav[0]; 
+         pasuv[1]=pasSav[1]; 
+         pasuv[2]=pasSav[2]; 
+         pasuv[3]=pasSav[3];
+       }           
+    }
+    else
+    {
+      aReduceStep = Standard_True;
+    }
+      }
+      else {//008
+       //============================================================
+       //== Un point a ete trouve :  T E S T   D E F L E C T I O N 
+       //============================================================
+       if(NoTestDeflection) {
+         NoTestDeflection = Standard_False;
+       }                 
+       else { 
+         if(--LevelOfEmptyInmyIntersectionOn2S<=0)     { 
+           LevelOfEmptyInmyIntersectionOn2S=0;
+           if (anIsAdaptiveStep)
+           {
+             Status = IntWalk_OK;
+        Standard_Real aPs2[4];
+        gp_Vec aCD2;
+        gp_Vec2d aSDs2[2];
+        Standard_Real aR2;
+        Standard_Real a2DR2;
+        const IntSurf_PntOn2S & aMP = myIntersectionOn2S.Point();
+        aMP.Parameters(aPs2[0], aPs2[1], aPs2[2], aPs2[3]);
+        Status = IntWalk_PasTropGrand;
+        if (!CalculateStepData(aPs2, aCD2, aSDs2, aR2, a2DR2))
+        {
+          //cout << "error2" << endl;
+          //LevelOfIterWithoutAppend = 20;
+          //continue;
+        }
+        else if (a2DR2 < aMaxStep)
+        {
+          aStepCoef *= a2DR2 / aMaxStep;
+        }
+        else if (Abs(aCD * aCD2) <= 0.997)
+        {
+          //cout << "cos = " << Abs(aCD * aCD2) << endl;
+        }
+        else
+        {
+          Standard_Real aDist = previousPoint.Value().Distance(aMP.Value());
+          Standard_Real aMinR = Min(aR, aR2);
+          if (aMinR < aDist)
+          {
+            aStepCoef *= aMinR / aDist;
+          }
+          else
+          {
+            Standard_Real aSP = aSDs[0] * aSDs2[0];
+            if (aSP * aSP <= (0.997 * 0.997) * aSDs[0].SquareMagnitude() *
+                                               aSDs2[0].SquareMagnitude())
+            {
+            }
+            else
+            {
+              aSP = aSDs[1] * aSDs2[1];
+              if (aSP * aSP <= (0.997 * 0.997) * aSDs[1].SquareMagnitude() *
+                                                 aSDs2[1].SquareMagnitude())
+              {
+              }
+              else
+              {
+                Status = TestDeflection();
+              }
+            }
+          }
+        }
+             /*Status = IntWalk_OK;
+             if (!anAreCollinear)
+             {
+               {
+                 const gp_Pnt & aFP = previousPoint.Value();
+                 const gp_Pnt & aLP = myIntersectionOn2S.Point().Value();
+                 cout << "Old (X, Y, Z) " << aFP.X() << " " << aFP.Y() << " " << aFP.Z() << endl;
+                 cout << "New (X, Y, Z) " << aLP.X() << " " << aLP.Y() << " " << aLP.Z() << endl;
+                 cout << "Dir (X, Y, Z) " << aCD.X() << " " << aCD.Y() << " " << aCD.Z() << endl;
+               }
+               gp_Vec aV(previousPoint.Value(), myIntersectionOn2S.Point().Value());
+               gp_Vec aCC = aV - (aV * aCD) * aCD;
+               Standard_Real aCCN = aCC.Magnitude();
+               if (aNT < aCCN)
+               {
+                 aCC *= 1 / aCCN;
+                 {
+                   gp_Vec aCCP = gp_Vec(previousPoint.Value().Coord()) + aR * aCC;
+                   cout << "r = " << aR << "; (x, y, z) = " << aCCP.X() << " " << aCCP.Y() << " " << aCCP.Z() << endl;
+                 }
+                 Standard_Real aC = aR;
+                 if (1 < aR)
+                 {
+                   aC = 0.25;
+                   aCC *= 0.25;
+                   aV  *= 0.25 / aR;
+                 }
+                 Standard_Real aDist =
+                   Min((aV - aCC).SquareMagnitude(), (aV + aCC).SquareMagnitude());
+                 aDist = sqrt(aDist);
+                 cout << "Dist = " << aDist << "; aC = " << aC << endl;
+                 if (aC * 2e-2 < aDist)
+                 {
+                   Status = IntWalk_PasTropGrand;
+                 }
+               }
+             }*/
+           }
+           else
+           {
+             if((LevelOfIterWithoutAppend < 10))
+             {
+               Status = TestDeflection();
+             }                 
+             else   { 
+               pasuv[0]*=0.5; 
+               pasuv[1]*=0.5; 
+               pasuv[2]*=0.5; 
+               pasuv[3]*=0.5;
+             }
+           }
+         }
+       }
+       //============================================================
+       //==       T r a i t e m e n t   s u r   S t a t u s        ==
+       //============================================================
+       if(LevelOfPointConfondu > 5) { 
+         Status = IntWalk_ArretSurPoint; 
+         LevelOfPointConfondu = 0;  
+       }
+       //
+       //if (!anAreCollinear && (aMaxStep < 1e-7))
+       //{
+       //  Status = IntWalk_ArretSurPointPrecedent;
+       //}
+       //
+       if(Status==IntWalk_OK) { 
+         NbPasOKConseq++;
+         if(NbPasOKConseq >= 5) { 
+           NbPasOKConseq=0;
+           Standard_Boolean pastroppetit;
+           Standard_Real t;
+           //
+           do { 
+             pastroppetit=Standard_True;
+             //
+             if(pasuv[0]<pasInit[0])     { 
+               t = (pasInit[0]-pasuv[0])*0.25;
+               if(t>0.1*pasInit[0]) {
+                 t=0.1*pasuv[0];
+               }
+               pasuv[0]+=t; 
+               pastroppetit=Standard_False;
+             } 
+             if(pasuv[1]<pasInit[1])   { 
+               t = (pasInit[1]-pasuv[1])*0.25;
+               if(t>0.1*pasInit[1]) {
+                 t=0.1*pasuv[1];
+               }               
+               pasuv[1]+=t; 
+               pastroppetit=Standard_False;
+             } 
+             if(pasuv[2]<pasInit[2]){
+               t = (pasInit[2]-pasuv[2])*0.25;
+               if(t>0.1*pasInit[2]) {
+                 t=0.1*pasuv[2];
+               }
+               pasuv[2]+=t; 
+               pastroppetit=Standard_False;
+             } 
+             if(pasuv[3]<pasInit[3])   { 
+               t = (pasInit[3]-pasuv[3])*0.25;
+               if(t>0.1*pasInit[3]) {
+                 t=0.1*pasuv[3];
+               }
+               pasuv[3]+=t; 
+               pastroppetit=Standard_False;
+             }
+             if(pastroppetit) { 
+               if(pasMax<0.1){ 
+                 pasMax*=1.1; 
+                 pasInit[0]*=1.1; 
+                 pasInit[1]*=1.1; 
+                 pasInit[2]*=1.1; 
+                 pasInit[3]*=1.1; 
+               }
+               else {
+                 pastroppetit=Standard_False;
+               }
+             }
+           } while(pastroppetit);
+         }
+       }//Status==IntWalk_OK
+       else NbPasOKConseq=0;
+       //
+       switch(Status) {//007 
+         case IntWalk_ArretSurPointPrecedent:  {                     
+           Arrive = Standard_False;                        
+           RepartirOuDiviser(DejaReparti, ChoixIso, Arrive);
+           aReduceStep = Standard_False;
+           break;
+         }
+         case IntWalk_PasTropGrand:  {
+           Param(1)=SvParam[0]; 
+           Param(2)=SvParam[1]; 
+           Param(3)=SvParam[2]; 
+           Param(4)=SvParam[3];
+           if(LevelOfIterWithoutAppend > 5) { 
+             if(pasSav[0]<pasInit[0]) { 
+               pasInit[0]-=(pasInit[0]-pasSav[0])*0.25; 
+               LevelOfIterWithoutAppend=0;
+             }
+             if(pasSav[1]<pasInit[1]) { 
+               pasInit[1]-=(pasInit[1]-pasSav[1])*0.25;  
+               LevelOfIterWithoutAppend=0; 
+             }
+             if(pasSav[2]<pasInit[2]) { 
+               pasInit[2]-=(pasInit[2]-pasSav[2])*0.25;  
+               LevelOfIterWithoutAppend=0; 
+             }
+             if(pasSav[3]<pasInit[3]) {
+               pasInit[3]-=(pasInit[3]-pasSav[3])*0.25; 
+               LevelOfIterWithoutAppend=0; 
+             }
+           }
+           break;
+         }
+         case IntWalk_PointConfondu:   {
+           LevelOfPointConfondu++;
+           if(LevelOfPointConfondu>5)   { 
+             Standard_Boolean pastroppetit;
+             //
+             do { 
+               pastroppetit=Standard_True;
+               if(pasuv[0]<pasInit[0]) { 
+                 pasuv[0]+=(pasInit[0]-pasuv[0])*0.25;
+                 pastroppetit=Standard_False; 
+               } 
+               if(pasuv[1]<pasInit[1]) { 
+                 pasuv[1]+=(pasInit[1]-pasuv[1])*0.25;
+                 pastroppetit=Standard_False; 
+               } 
+               if(pasuv[2]<pasInit[2]) { 
+                 pasuv[2]+=(pasInit[2]-pasuv[2])*0.25;
+                 pastroppetit=Standard_False; 
+               } 
+               if(pasuv[3]<pasInit[3]) { 
+                 pasuv[3]+=(pasInit[3]-pasuv[3])*0.25; 
+                 pastroppetit=Standard_False; 
+               }
+               if(pastroppetit)  { 
+                 if(pasMax<0.1){ 
+                   pasMax*=1.1; 
+                   pasInit[0]*=1.1; 
+                   pasInit[1]*=1.1; 
+                   pasInit[2]*=1.1; 
+                   pasInit[3]*=1.1; 
+                 }
+                 else{
+                   pastroppetit=Standard_False; 
+                 }             
+               }
+             } while(pastroppetit);
+           }
+           break;
+         }
+         case IntWalk_OK:
+         case IntWalk_ArretSurPoint:  {//006
+           //=======================================================
+           //== T e s t   A r r e t   :  Cadrage sur Param(.)     ==
+           //=======================================================
+           //xft arrive here
+           Arrive = TestArret(DejaReparti,Param,ChoixIso); 
+           // JMB 30th December 1999. 
+           // Some statement below should not be put in comment because they are useful.
+           // See grid CTO 909 A1 which infinitely loops 
+           if(Arrive==Standard_False && Status==IntWalk_ArretSurPoint) { 
+             Arrive=Standard_True;
+#ifdef DEB
+             cout << "Compile avec option DEB :Si Pb d intersection : ";
+             cout << "IntWalk_PWalking_1.gxx (lbr le 1erdec98)"<<endl;
+#endif
+           }
+           if(Arrive) {
+             NbPasOKConseq = -10;
+           }
+           if(!Arrive)  {//005
+             //=====================================================
+             //== Param(.)  est dans les bornes                   ==
+             //==  et ne finit pas une ligne fermee               ==
+             //=====================================================
+             //== Verification sur Le Point Courant de myInters
+             Standard_Boolean pointisvalid = Standard_False;
+             {
+               Standard_Real u1,v1,u2,v2; 
+               myIntersectionOn2S.Point().Parameters(u1,v1,u2,v2); 
+               //
+               if(u1 <= UM1  && u2 <= UM2 && v1 <= VM1 && 
+                  v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
+                  v1 >= Vm1  && v2 >= Vm2) {
+                 pointisvalid=Standard_True;
+               }
+             }
+             //
+             if(pointisvalid) { 
+               previousPoint = myIntersectionOn2S.Point();
+               previoustg = myIntersectionOn2S.IsTangent();
+               if(!previoustg) {
+                 previousd  = myIntersectionOn2S.Direction();
+                 previousd1 = myIntersectionOn2S.DirectionOnS1();
+                 previousd2 = myIntersectionOn2S.DirectionOnS2();
+               }
+               //=====================================================
+               //== Verification sur Previous Point
+               {
+                 Standard_Real u1,v1,u2,v2; 
+                 previousPoint.Parameters(u1,v1,u2,v2); 
+                 if( u1 <= UM1  && u2 <= UM2 && v1 <= VM1 &&
+                     v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
+                     v1 >= Vm1  && v2 >= Vm2) { 
+                   pl = previousPoint.Value();
+                   if(bTestFirstPoint) {
+                     if(pf.Distance(pl) < 1.e-7){ 
+                       IncKey++; 
+                       if(IncKey == 5000) 
+                         return; 
+                       else 
+                         continue; 
+                     }
+                     else {
+                       bTestFirstPoint = Standard_False;
+                     }
+                   }
+                   //
+                   AddAPoint(line,previousPoint);
+                   {
+                     const gp_Pnt & aP = previousPoint.Value();
+                     const gp_Pnt & aP2 = line->Value(line->NbPoints() - 1).Value();
+                     //cout << "(X, Y, Z) = " << aP.X()  << " " << aP.Y()  << " " << aP.Z() << "; d = " << aP.Distance(aP2) << endl;
+                   }
+                   RejectIndex++; 
+                   if(RejectIndex >= 250000) {
+                     break; 
+                   };
+                   //
+                   LevelOfIterWithoutAppend = 0;
+                 } 
+               }
+             }//pointisvalid
+             //====================================================
+             if(Status == IntWalk_ArretSurPoint)  {
+               RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
+             }
+             else{ 
+               if (line->NbPoints() == 2) {
+                 pasSav[0] = pasuv[0]; 
+                 pasSav[1] = pasuv[1]; 
+                 pasSav[2] = pasuv[2]; 
+                 pasSav[3] = pasuv[3];
+               }
+             }
+           }//005 if(!Arrive)
+           //
+           else {//004
+             if(close) { 
+               //================= la ligne est fermee ===============
+               AddAPoint(line,line->Value(1)); //ligne fermee
+    {
+      const gp_Pnt & aP = line->Value(1).Value();
+      const gp_Pnt & aP2 = line->Value(line->NbPoints() - 1).Value();
+      //cout << "(X, Y, Z) = " << aP.X()  << " " << aP.Y()  << " " << aP.Z() << "; d = " << aP.Distance(aP2) << endl;
+    }
+               LevelOfIterWithoutAppend=0;
+             }
+             else {//$$$
+               //====================================================
+               //== Param n etait pas dans les bornes (a ete recadre)
+               //====================================================
+               Standard_Boolean bPrevNotTangent = !previoustg || !myIntersectionOn2S.IsTangent();
+               
+               IntImp_ConstIsoparametric SauvChoixIso = ChoixIso;
+               ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso);    
+               //
+               if(!myIntersectionOn2S.IsEmpty()) { //002
+                 // debordement sur le carreau reciproque ou intersection en coin
+                 if(TestArret(Standard_True,Param,ChoixIso))  {
+                   NbPasOKConseq = -10;
+                   ChoixIso = myIntersectionOn2S.Perform(Param,Rsnld,ChoixIso); 
+                   if(!myIntersectionOn2S.IsEmpty())     {
+                     previousPoint = myIntersectionOn2S.Point();         
+                     previoustg = myIntersectionOn2S.IsTangent();
+                     if (!previoustg)     {
+                       previousd  = myIntersectionOn2S.Direction();
+                       previousd1 = myIntersectionOn2S.DirectionOnS1();
+                       previousd2 = myIntersectionOn2S.DirectionOnS2();
+                     }
+                     pl = previousPoint.Value();
+                     if(bTestFirstPoint) {
+                       if(pf.Distance(pl) < 1.e-7){ 
+                         IncKey++; 
+                         if(IncKey == 5000) 
+                           return; 
+                         else 
+                           continue; 
+                       }
+                       else {
+                         bTestFirstPoint = Standard_False;
+                       }
+                     }
+                     //
+                     AddAPoint(line,previousPoint);
+          {
+            const gp_Pnt & aP = previousPoint.Value();
+                       const gp_Pnt & aP2 = line->Value(line->NbPoints() - 1).Value();
+                       //cout << "(X, Y, Z) = " << aP.X()  << " " << aP.Y()  << " " << aP.Z() << "; d = " << aP.Distance(aP2) << endl;
+          }
+                     RejectIndex++;
+                     if(RejectIndex >= 250000) {
+                       break;
+                     };
+                     //
+                     LevelOfIterWithoutAppend=0;
+                     RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
+                   }
+                   else  {
+                     //echec cadrage diviser le pas
+                     Arrive = Standard_False;
+                     RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
+                     NoTestDeflection = Standard_True;
+                     ChoixIso = SauvChoixIso;
+                   }
+                 }//if(TestArret())
+                 else {
+                   // save the last point
+                   // to revert to it if the current point is out of bounds
+                   IntSurf_PntOn2S previousPointSave = previousPoint;
+                   Standard_Boolean previoustgSave   = previoustg;
+                   gp_Dir previousdSave              = previousd;
+                   gp_Dir2d previousd1Save           = previousd1;
+                   gp_Dir2d previousd2Save           = previousd2;
+                   
+                   previousPoint = myIntersectionOn2S.Point();         
+                   previoustg = myIntersectionOn2S.IsTangent();
+                   Arrive = Standard_False; 
+                   if(!previoustg)  {
+                     previousd  = myIntersectionOn2S.Direction();
+                     previousd1 = myIntersectionOn2S.DirectionOnS1();
+                     previousd2 = myIntersectionOn2S.DirectionOnS2();
+                   }
+                   //========================================
+                   //== Verification sur PreviousPoint @@
+                   {
+                     Standard_Real u1,v1,u2,v2; 
+                     previousPoint.Parameters(u1,v1,u2,v2); 
+                     Param(1) = u1; 
+                     Param(2) = v1;    
+                     Param(3) = u2; 
+                     Param(4) = v2;
+                     //
+                     //xf
+                     Standard_Boolean bFlag1, bFlag2;
+                     Standard_Real aTol2D=1.e-11;
+                     //
+                     bFlag1=u1 >= Um1-aTol2D && v1 >= Vm1-aTol2D && u1 <= UM1+aTol2D && v1 <= VM1+aTol2D;
+                     bFlag2=u2 >= Um2-aTol2D && v2 >= Vm2-aTol2D && u2 <= UM2+aTol2D && v2 <= VM2+aTol2D;
+                     if (bFlag1 && bFlag2) {
+                     /*
+                     if(u1 <= UM1  && u2 <= UM2 && v1 <= VM1 &&
+                        v2 <= VM2  && u1 >= Um1 && u2 >= Um2 &&
+                        v1 >= Vm1  && v2 >= Vm2)  {
+                        */                     
+                     //xt
+                       pl = previousPoint.Value();
+                       if(bTestFirstPoint) {
+                         if(pf.Distance(pl) < 1.e-7) {
+                           IncKey++;
+                           if(IncKey == 5000)
+                             return; 
+                           else 
+                             continue;
+                         }
+                         else {
+                           bTestFirstPoint = Standard_False;
+                         }
+                       }
+                       AddAPoint(line,previousPoint);
+      {
+        const gp_Pnt & aP = previousPoint.Value();
+             const gp_Pnt & aP2 = line->Value(line->NbPoints() - 1).Value();
+             //cout << "(X, Y, Z) = " << aP.X()  << " " << aP.Y()  << " " << aP.Z() << "; d = " << aP.Distance(aP2) << endl;
+      }
+                       RejectIndex++;
+                       if(RejectIndex >= 250000) {
+                         break;
+                       }
+                       //
+                       LevelOfIterWithoutAppend=0;
+                       Arrive = Standard_True;
+                     }
+                     else {
+                       // revert to the last correctly calculated point
+                       previousPoint = previousPointSave;
+                       previoustg    = previoustgSave;
+                       previousd     = previousdSave;
+                       previousd1    = previousd1Save;
+                       previousd2    = previousd2Save;
+                     }
+                   }
+                   //
+                   Standard_Boolean wasExtended = Standard_False;
+                   
+                   if(Arrive && myIntersectionOn2S.IsTangent() && bPrevNotTangent) {
+                     if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti)) {
+                       wasExtended = Standard_True;
+                       Arrive = Standard_False;
+                       ChoixIso = SauvChoixIso;
+                     }
+                   }
+                   
+                   RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
+                   if(Arrive && 
+                      myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty() &&
+                      myIntersectionOn2S.IsTangent() && bPrevNotTangent &&
+                      !wasExtended) {
+                     
+                     if(ExtendLineInCommonZone(SauvChoixIso, DejaReparti)) {
+                       wasExtended = Standard_True;
+                       Arrive = Standard_False;
+                       ChoixIso = SauvChoixIso;
+                     }
+                   }
+                 }//else !TestArret() $
+               } //$$ fin succes cadrage sur frontiere (!myIntersectionOn2S.IsEmpty())
+               else  {
+                 //echec cadrage  sur frontiere;division du pas 
+                 Arrive = Standard_False;
+                 NoTestDeflection = Standard_True;
+                 RepartirOuDiviser(DejaReparti,ChoixIso,Arrive);
+               } 
+             }//$$$ fin cadrage sur frontiere (!close)
+           } //004 fin TestArret retourne Arrive = True
+         } // 006case IntWalk_ArretSurPoint:  fin Traitement Status = OK  ou ArretSurPoint 
+       } //007  switch(Status) 
+      } //008 fin traitement point en court (TEST DEFLECTION)
+    } //009 fin traitement ligne (else if myIntersectionOn2S.IsDone())
+  }  //010 fin si premier point de depart a permis un cheminement while(!Arrive)
+  done = Standard_True;
+}
+
+Standard_Boolean IntWalk_PWalking::CalculateStepData(
+  const Standard_Real theParams[4],
+  gp_Vec & theCD, gp_Vec2d theSDs[2],
+  Standard_Real & theMaxStep, Standard_Real & theMax2DStep)
+{
+  const ThePSurface & aS1 = myIntersectionOn2S.Function().AuxillarSurface1();
+  const ThePSurface & aS2 = myIntersectionOn2S.Function().AuxillarSurface2();
+  gp_Pnt aPs[2];
+  gp_Vec aDs[2][5];
+  ThePSurfaceTool::D2(aS1, theParams[0], theParams[1], aPs[0], aDs[0][0], aDs[0][1],
+    aDs[0][2], aDs[0][3], aDs[0][4]);
+  ThePSurfaceTool::D2(aS2, theParams[2], theParams[3], aPs[1], aDs[1][0], aDs[1][1],
+    aDs[1][2], aDs[1][3], aDs[1][4]);
+  Standard_Real aNT = 1e-12, aDNs[2][2];
+  aDNs[0][0] = aDs[0][0].Magnitude();
+  aDNs[0][1] = aDs[0][1].Magnitude();
+  aDNs[1][0] = aDs[1][0].Magnitude();
+  aDNs[1][1] = aDs[1][1].Magnitude();
+  if ((aDNs[0][0] <= aNT) | (aDNs[0][1] <= aNT) |
+      (aDNs[1][0] <= aNT) | (aDNs[1][1] <= aNT))
+  {
+    return Standard_False;
+  }
+  gp_Vec aNs[2];
+  {
+    gp_Vec aNDs[2][2];
+    aNDs[0][0] = aDs[0][0] / aDNs[0][0];
+    aNDs[0][1] = aDs[0][1] / aDNs[0][1];
+    aNDs[1][0] = aDs[1][0] / aDNs[1][0];
+    aNDs[1][1] = aDs[1][1] / aDNs[1][1];
+    aNs[0] = aNDs[0][0] ^ aNDs[0][1];
+    aNs[1] = aNDs[1][0] ^ aNDs[1][1];
+    Standard_Real aNNs[2] = {aNs[0].Magnitude(), aNs[1].Magnitude()};
+    if ((aNNs[0] <= aNT) | (aNNs[1] <= aNT))
+    {
+      return Standard_False;
+    }
+    aNs[0] /= aNNs[0];
+    aNs[1] /= aNNs[1];
+  }
+  //////////////////////////////////////////////////////////////////////////////
+  //
+  // Set C(s) = S1(u(s), v(s)) = S2(x(s), y(s)),
+  //   s - curve length.
+  //
+  //////////////////////////////////////////////////////////////////////////////
+  // Calculate theSDs[0] and theSDs[1] as
+  //   theSDs[0] = (du/ds, dv/ds),
+  //   theSDs[1] = (dx/ds, dy/ds)
+  // from the following identities:
+  //    ddS1/ddu * du/ds + ddS1/ddv * dv/ds =
+  //    ddS2/ddx * dx/ds + ddS2/ddy * dy/ds,
+  //   |ddS1/ddu * du/ds + ddS1/ddv * dv/ds| = 1,
+  //   |ddS2/ddx * dx/ds + ddS2/ddy * dy/ds| = 1.
+  {
+    Standard_Real aMaxN = Max(aDNs[0][0], aDNs[0][1]);
+    Standard_Real aC = 1 / aMaxN;
+    theSDs[0] = gp_Vec2d((aC * aDs[0][1]) * aNs[1], (-aC * aDs[0][0]) * aNs[1]);
+    //
+                  aMaxN = Max(aDNs[1][0], aDNs[1][1]);
+                  aC = 1 / aMaxN;
+    theSDs[1] = gp_Vec2d((aC * aDs[1][1]) * aNs[0], (-aC * aDs[1][0]) * aNs[0]);
+  }
+  theCD = theSDs[0].X() * aDs[0][0] + theSDs[0].Y() * aDs[0][1];
+  {
+    Standard_Real aSP = theCD * previousd;
+    if (((aSP < 0) && (0 < sensCheminement)) ||
+        ((0 < aSP) && (sensCheminement < 0)))
+    {
+      theCD.Reverse();
+      theSDs[0].Reverse();
+    }
+  }
+  {
+    Standard_Real aN = theCD.Magnitude();
+    if (aN <= aNT)
+    {
+      return Standard_False;
+    }
+    Standard_Real aM = 1 / aN;
+    theCD *= aM;
+    theSDs[0] *= aM;
+    //
+    gp_Vec aCDer2 = theSDs[1].X() * aDs[1][0] + theSDs[1].Y() * aDs[1][1];
+    aN = aCDer2.Magnitude();
+    if (aN <= aNT)
+    {
+      return Standard_False;
+    }
+    theSDs[1] *= 1 / aN;
+    if (aCDer2 * theCD < 0)
+    {
+      theSDs[1].Reverse();
+    }
+  }
+  // Calculate aSSDs[0] and aSSDs[1] as
+  //   aSSDs[0] = (d2u/ds2, d2v/ds2),
+  //   aSSDs[1] = (d2x/ds2, d2y/ds2)
+  // from the following identities
+  // (obtained from above identities by differentiation on s):
+  //   ddS1/ddu * d2u/ds2 + ddS1/ddv * d2v/ds2 +
+  //     dd2S1/ddu2 * (du/ds) ^ 2 + dd2S1/ddv2 * (dv/ds) ^ 2 +
+  //     2 * dd2S1/(ddu ddv) * du/ds * dv/ds =
+  //   ddS2/ddx * d2x/ds2 + ddS2/ddy * d2y/ds2 +
+  //     dd2S2/ddx2 * (dx/ds) ^ 2 + dd2S2/ddy2 * (dy/ds) ^ 2 +
+  //     2 * dd2S2/(ddx ddy) * dx/dy * dy/ds,
+  //   (ddS1/ddu * d2u/ds2 + ddS1/ddv * d2v/ds2 +
+  //     dd2S1/ddu2 * (du/ds) ^ 2 + dd2S1/ddv2 * (dv/ds) ^ 2 +
+  //     2 * dd2S1/(ddu ddv) * du/ds * dv/ds) * theCD = 0,
+  //   (ddS2/ddx * d2x/ds2 + ddS2/ddy * d2y/ds2 +
+  //     dd2S2/ddx2 * (dx/ds) ^ 2 + dd2S2/ddy2 * (dy/ds) ^ 2 +
+  //     2 * dd2S2/(ddx ddy) * dx/dy * dy/ds) * theCD = 0.
+  gp_Vec aV1 = (theSDs[0].X() * theSDs[0].X()) * aDs[0][2] +
+               (theSDs[0].Y() * theSDs[0].Y()) * aDs[0][3] +
+           (2 * theSDs[0].X() * theSDs[0].Y()) * aDs[0][4];
+  gp_Vec aV2 = (theSDs[1].X() * theSDs[1].X()) * aDs[1][2] +
+               (theSDs[1].Y() * theSDs[1].Y()) * aDs[1][3] +
+           (2 * theSDs[1].X() * theSDs[1].Y()) * aDs[1][4];
+  gp_Vec aV12 = aV2 - aV1;
+  Standard_Real aKs[4][3];
+  aKs[0][0] = aDs[0][0] * aNs[1];
+  aKs[0][1] = aDs[0][1] * aNs[1];
+  aKs[0][2] =  aV12 * aNs[1];
+  aKs[1][0] = aDs[0][0] * theCD;
+  aKs[1][1] = aDs[0][1] * theCD;
+  aKs[1][2] = -aV1 * theCD;
+  aKs[2][0] = aDs[1][0] * aNs[0];
+  aKs[2][1] = aDs[1][1] * aNs[0];
+  aKs[2][2] = -aV12 * aNs[0];
+  aKs[3][0] = aDs[1][0] * theCD;
+  aKs[3][1] = aDs[1][1] * theCD;
+  aKs[3][2] = -aV2 * theCD;
+  Standard_Real aDets[] = {aKs[0][0] * aKs[1][1] - aKs[0][1] * aKs[1][0],
+                           aKs[2][0] * aKs[3][1] - aKs[2][1] * aKs[3][0]};
+  gp_Vec2d aSSDs[] = {
+    gp_Vec2d((aKs[0][2] * aKs[1][1] - aKs[0][1] * aKs[1][2]) / aDets[0],
+             (aKs[0][0] * aKs[1][2] - aKs[0][2] * aKs[1][0]) / aDets[0]),
+    gp_Vec2d((aKs[2][2] * aKs[3][1] - aKs[2][1] * aKs[3][2]) / aDets[1],
+             (aKs[2][0] * aKs[3][2] - aKs[2][2] * aKs[3][0]) / aDets[1])};
+  // Calculate theMaxStep as radius of curvature for curve C.
+  gp_Vec aCSD = aV1 + aSSDs[0].X() * aDs[0][0] + aSSDs[0].Y() * aDs[0][1];
+  {
+    theMaxStep = DBL_MAX;
+    Standard_Real aDen = (theCD ^ aCSD).Magnitude();
+    if (aNT < aDen)
+    {
+      theMaxStep = 1 / aDen;
+    }
+  }
+  // Calculate theMax2DStep as Min(aMax2DStep1, aMax2DStep2), here
+  // aMax2DStep1 = r1 / ((du/ds) ^ 2 + (dv/ds) ^ 2) ^ 0.5,
+  // aMax2DStep2 = r2 / ((dx/ds) ^ 2 + (dy/ds) ^ 2) ^ 0.5, here
+  // r1 and r2 are radii of curvature for curves
+  // C1(s) = (u(s), v(s)) and C2(s) = (x(s), y(s)).
+  theMax2DStep = DBL_MAX;
+  Standard_Real a2DStep = Abs(theSDs[0] ^ aSSDs[0]);
+  if (aNT < a2DStep)
+  {
+    a2DStep = theSDs[0].SquareMagnitude() / a2DStep;
+    theMax2DStep = Min(theMax2DStep, a2DStep);
+  }
+                a2DStep = Abs(theSDs[1] ^ aSSDs[1]);
+  if (aNT < a2DStep)
+  {
+    a2DStep = theSDs[1].SquareMagnitude() / a2DStep;
+    theMax2DStep = Min(theMax2DStep, a2DStep);
+  }
+  return Standard_True;
+}
+
+//==================================================================================
+// function : Perform
+// purpose  : 
+//==================================================================================
+void IntWalk_PWalking::Perform2(const TColStd_Array1OfReal& ParDep,
+                              const Standard_Real u1min,
+                              const Standard_Real v1min,
+                              const Standard_Real u2min,
+                              const Standard_Real v2min,
+                              const Standard_Real u1max,
+                              const Standard_Real v1max,
+                              const Standard_Real u2max,
+                              const Standard_Real v2max)
 {
   //xf
   Standard_Integer i, NbPasOKConseq;