//-- File IntWalk_IWalking_4.gxx #ifndef DEB #define No_Standard_RangeError #define No_Standard_OutOfRange #endif void IntWalk_IWalking::ComputeCloseLine(const TColStd_SequenceOfReal& Umult, const TColStd_SequenceOfReal& Vmult, const ThePOPIterator& Pnts1, const ThePOLIterator& Pnts2, TheIWFunction& Func, Standard_Boolean& Rajout ) // *********** traitement ligne fermee ********************** // // pour tout point interieur non encore traite // calculer le pas d avancement=pas en fonction de la fleche // et du pas max // calculer un point approche (ce point est sur la tangente a la section // de distance = pas du point interieur) // tant que // (l ensemble des points calcules ne forme pas une boucle fermee) // ou // (l ensemble des points ne forme pas une ligne ouverte allant // d une frontiere du domaine a un autre ou d un point de tangence // a une frontiere ou de 2 points de tangence :cas singuliers) // // cadrer le point approche sur les frontieres si necessaire // calcul du point // si point non trouve diviser le pas // test d arret // calcul du pas en fonction de la fleche et du pas maxi(arret possible) // // ******************************************************************** { Standard_Integer I,N = 0; static math_Vector BornInf(1,2),BornSup(1,2); static math_Vector Uvap(1,2);// parametres approches courant Standard_Real PasC; // taux d`avancement sur la tangente Standard_Real PasCu; // pas d avancement courant en U Standard_Real PasCv; // pas d avancement courant en V Standard_Real PasSav; //sauvegarde du premier pas d avancement Standard_Boolean Arrive;// indique si ligne terminee Standard_Boolean Cadre; //indique si on est sur frontiere du domaine Standard_Boolean ArretAjout; //indique si on est sur un point ajoute IntSurf_PntOn2S Psol; Handle(IntWalk_TheIWLine) CurrentLine; //ligne en construction ThePointOfPath PathPnt; ThePointOfLoop LoopPnt; Standard_Boolean Tgtbeg,Tgtend; Standard_Integer StepSign; IntWalk_StatusDeflection Status,StatusPrecedent; Standard_Integer NbDivision ; // nombre de fois que l on a divise le pas // lors du calcul d 1 section Standard_Integer Ipass ; //indice dans l iterateur des points sur arete du point de //passage BornInf(1) = Um; BornSup(1) = UM; BornInf(2) = Vm; BornSup(2) = VM; math_FunctionSetRoot Rsnld(Func,tolerance); Standard_Integer nbLoop = Pnts2.Length(); for (I = 1;I<=nbLoop;I++) { if (etat2(I) > 12) { // point de demarrage de ligne fermee LoopPnt = Pnts2.Value(I); previousPoint.SetValue(ThePointOfLoopTool::Value3d(LoopPnt),reversed, ustart2(I),vstart2(I)); previousd3d = ThePointOfLoopTool::Direction3d(LoopPnt); previousd2d = ThePointOfLoopTool::Direction2d(LoopPnt); CurrentLine = new IntWalk_TheIWLine (); CurrentLine->AddPoint(previousPoint); CurrentLine->SetTangentVector(previousd3d,1); Tgtbeg = Standard_False; Tgtend = Standard_False; Uvap(1) = ustart2(I); Uvap(2) = vstart2(I); StepSign = 1; // premier pas d avancement 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; NbDivision = 0; StatusPrecedent = IntWalk_OK; while (!Arrive) { // tant que aucun test d arret verifie Cadre=Cadrage(BornInf,BornSup,Uvap,PasC, StepSign); // frontiere? #ifdef CHRONO Chronrsnld.Start(); #endif Rsnld.Perform(Func,Uvap,BornInf,BornSup); #ifdef CHRONO Chronrsnld.Stop(); #endif if (Cadre) { // remise a jour des bornes. BornInf(1) = Um;BornSup(1) = UM;BornInf(2) = Vm;BornSup(2) = VM; } if (Rsnld.IsDone()) { if (Abs(Func.Root()) > Func.Tolerance()) { // pas de solution a la 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; seqAjout.Append(lines.Length()+1); Tgtend = Standard_True; } } else { // il y a une solution Rsnld.Root(Uvap); Arrive = TestArretPassage(Umult,Vmult,Uvap,I,Ipass); if (Arrive) {//remettre les bons parametres pour le test de fleche. Psol = CurrentLine->Value(1); if (!reversed) { Psol.ParametersOnS2(Uvap(1),Uvap(2)); } else { Psol.ParametersOnS1(Uvap(1),Uvap(2)); } Cadre=Standard_False; //au cas ou on aurait cadre et arrive en meme temps } else { // modif jag 940615 if (Rajout) { // test sur les points rajoutes ArretAjout =TestArretAjout(Func,Uvap,N,Psol); if (ArretAjout) { if (N >0) { Tgtend = lines.Value(N)->IsTangentAtEnd(); N = -N; } else { Tgtend = lines.Value(-N)->IsTangentAtBegining(); } Arrive = (etat2(I) == 12); } } if (!ArretAjout&& Cadre) { // test sur les points deja marques if (CurrentLine->NbPoints() == 1) break; // annuler la ligne 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 = (etat2(I) == 12); // la ligne s est ouverte } } Status = TestDeflection(Func, Arrive,Uvap,StatusPrecedent, NbDivision,PasC,StepSign); StatusPrecedent = Status; if (Status == IntWalk_PasTropGrand) {// division du pas 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) { // la ligne s est ouverte CurrentLine->AddStatusLast(Standard_False); if (Status != IntWalk_ArretSurPointPrecedent) { CurrentLine->AddPoint(Psol); } if (Cadre && N==0) { Rajout = Standard_True; seqAjout.Append(lines.Length()+1); } } else { // a ouvrir etat2(I) = 12; //la declarer ouverte 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) { //annuler la ligne Arrive = Standard_False; break; } if (etat2(I) >12) { //la ligne doit s ouvrir etat2(I) = 12; //la declarer ouverte 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 { // la ligne s est ouverte Arrive =Standard_True; CurrentLine->AddStatusLast(Standard_False); Rajout = Standard_True; seqAjout.Append(lines.Length()+1); } } else if (Arrive) { if (etat2(I) > 12) { //ligne fermee bon cas CurrentLine->AddStatusFirstLast(Standard_True, Standard_False,Standard_False); CurrentLine->AddPoint(CurrentLine->Value(1)); } else if (N >0) { //point d arret donne en entree PathPnt = Pnts1.Value(N); CurrentLine->AddStatusLast(Standard_True,N,PathPnt); AddPointInCurrentLine(N,PathPnt,CurrentLine); } } else if (Status == IntWalk_ArretSurPoint) { if (etat2(I) >12) { //la ligne doit s ouvrir etat2(I) = 12; //la declarer ouverte 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 de passage ,point d arret 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 { //pas de solution numerique NotDone 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; // annuler la ligne Arrive = Standard_True; CurrentLine->AddStatusFirstLast(Standard_False,Standard_False, Standard_False); Tgtend = Standard_True; Rajout = Standard_True; seqAjout.Append(lines.Length()+1); } } }// fin de la ligne commencee if (Arrive) { CurrentLine->SetTangencyAtBegining(Tgtbeg); CurrentLine->SetTangencyAtEnd(Tgtend); lines.Append(CurrentLine); etat2(I)=-etat2(I); //marque le point comme traite } } //fin de traitement d un point de depart } //fin de tous les points de depart }