void Blend_CSWalking::InternalPerform(Blend_CSFunction& Func, // Blend_CSFuncInv& FuncInv, math_Vector& sol, const Standard_Real Bound) { Standard_Real stepw = pasmax; Standard_Real parprec = param; Blend_Status State; TopAbs_State situ; Standard_Real w,U,V; Standard_Integer nbarc; #ifndef DEB Standard_Integer Index = 0; Standard_Boolean Isvtx = Standard_False; #else Standard_Integer Index; Standard_Boolean Isvtx; #endif Standard_Integer Nbvar = Func.NbVariables(); Standard_Boolean Arrive,recad,echecrecad; gp_Pnt2d p2d; // math_Vector tolerance(1,3),infbound(1,3),supbound(1,3),parinit(1,3); // math_Vector solrst(1,3); math_Vector tolerance(1,Nbvar),infbound(1,Nbvar),supbound(1,Nbvar), parinit(1,Nbvar); math_Vector solrst(1,Nbvar); TheVertex Vtx; TheExtremity Exts,Extc; //IntSurf_Transition Tline,Tarc; Func.GetTolerance(tolerance,tolesp); Func.GetBounds(infbound,supbound); math_FunctionSetRoot rsnld(Func,tolerance,30); parinit = sol; param = parprec + sens*stepw; Arrive = (sens *(param - Bound) > 0.) ; // if (Arrive) { // line->Clear(); // } while (!Arrive) { Func.Set(param); rsnld.Perform(Func,parinit,infbound,supbound); if (!rsnld.IsDone()) { State = Blend_StepTooLarge; } else { rsnld.Root(sol); // situ1 = TheTopolTool::Classify(surf1,gp_Pnt2d(sol(1),sol(2)), // Max(tolerance(1),tolerance(2))); // situ2 = TheTopolTool::Classify(surf2,gp_Pnt2d(sol(3),sol(4)), // Max(tolerance(3),tolerance(4))); /* situ = domain->Classify(gp_Pnt2d(sol(1),sol(2)), Min(tolerance(1),tolerance(2))); */ situ = domain->Classify(Func.Pnt2d(), Min(tolerance(1),tolerance(2))); w = Bound; recad = Standard_False; echecrecad = Standard_False; if (situ == TopAbs_OUT || situ == TopAbs_ON) { // pb inverse sur surf // recad = Recadre(FuncInv,sol,solrst,Index,Isvtx,Vtx); Isvtx = Standard_False; // en attendant Recadre if (recad) { w = solrst(2); } else { echecrecad = Standard_True; } } if (!echecrecad) { if (recad) { // sol sur surf State = Blend_OnRst1; param = w; domain->Init(); nbarc = 1; while (nbarc < Index) { nbarc++; domain->Next(); } p2d = TheArcTool::Value(domain->Value(),solrst(1)); sol(1) = p2d.X(); sol(2) = p2d.Y(); sol(3) = solrst(3); Func.Set(param); } else { State = Blend_OK; } State = TestArret(Func,sol,Standard_True,State); } else { // Echec recadrage. On sort avec PointsConfondus State = Blend_SamePoints; } } switch (State) { case Blend_OK : { #ifdef DEB if (Blend_GettraceDRAWSECT()){ Drawsect(surf,curv,param,Func); } #endif // Mettre a jour la ligne. if (sens>0.) { line->Append(previousP); } else { line->Prepend(previousP); } parinit = sol; parprec = param; if (param == Bound) { Arrive = Standard_True; /* Exts.SetValue(previousP.PointOnS(),sol(1),sol(2),tolesp); Extc.SetValue(previousP.PointOnC(),sol(3),tolesp); */ previousP.ParametersOnS(U,V); Exts.SetValue(previousP.PointOnS(),U,V, previousP.Parameter(),tolesp); Extc.SetValue(previousP.PointOnC(),previousP.ParameterOnC(), previousP.Parameter(),tolesp); // Indiquer que fin sur Bound. } else { param = param + sens*stepw; if (sens*(param - Bound) > - tolgui) { param = Bound; } } } break; case Blend_StepTooLarge : { stepw = stepw/2.; if (Abs(stepw) < tolgui) { /* Exts.SetValue(previousP.PointOnS(),sol(1),sol(2),tolesp); Extc.SetValue(previousP.PointOnC(),sol(3),sol(4),tolesp); */ previousP.ParametersOnS(U,V); Exts.SetValue(previousP.PointOnS(),U,V, previousP.Parameter(),tolesp); Extc.SetValue(previousP.PointOnC(),previousP.ParameterOnC(), previousP.Parameter(),tolesp); Arrive = Standard_True; if (line->NbPoints()>=2) { // Indiquer qu on s arrete en cours de cheminement } // else { // line->Clear(); // } } else { param = parprec + sens*stepw; // on ne risque pas de depasser Bound. } } break; case Blend_StepTooSmall : { #ifdef DEB if (Blend_GettraceDRAWSECT()){ Drawsect(surf,curv,param,Func); } #endif // Mettre a jour la ligne. if (sens>0.) { line->Append(previousP); } else { line->Prepend(previousP); } parinit = sol; parprec = param; stepw = Min(1.5*stepw,pasmax); if (param == Bound) { Arrive = Standard_True; /* Exts.SetValue(previousP.PointOnS(),sol(1),sol(2),tolesp); Extc.SetValue(previousP.PointOnC(),sol(3),tolesp); */ previousP.ParametersOnS(U,V); Exts.SetValue(previousP.PointOnS(),U,V, previousP.Parameter(),tolesp); Extc.SetValue(previousP.PointOnC(),previousP.ParameterOnC(), previousP.Parameter(),tolesp); // Indiquer que fin sur Bound. } else { param = param + sens*stepw; if (sens*(param - Bound) > - tolgui) { param = Bound; } } } break; case Blend_OnRst1 : { #ifdef DEB if (Blend_GettraceDRAWSECT()){ Drawsect(surf,curv,param,Func); } #endif if (sens>0.) { line->Append(previousP); } else { line->Prepend(previousP); } MakeExtremity(Exts,Index,solrst(1),Isvtx,Vtx); // Extc.SetValue(previousP.PointOnC(),sol(3),tolesp); Extc.SetValue(previousP.PointOnC(),previousP.ParameterOnC(), previousP.Parameter(),tolesp); Arrive = Standard_True; } break; case Blend_SamePoints : { // On arrete cout << " Points confondus dans le cheminement" << endl; /* Exts.SetValue(previousP.PointOnS(),sol(1),sol(2),tolesp); Extc.SetValue(previousP.PointOnC(),sol(3),tolesp); */ previousP.ParametersOnS(U,V); Exts.SetValue(previousP.PointOnS(),U,V, previousP.Parameter(),tolesp); Extc.SetValue(previousP.PointOnC(),previousP.ParameterOnC(), previousP.Parameter(),tolesp); Arrive = Standard_True; } break; #ifndef DEB default: break; #endif } if (Arrive) { if (sens > 0.) { line->SetEndPoints(Exts,Extc); } else { line->SetStartPoints(Exts,Extc); } } } }