Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/opencascade/IntWalk_IWalking_2.gxx is written in an unsupported language. File is not indexed.

0001 // Copyright (c) 1995-1999 Matra Datavision
0002 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014 
0015 //-- IntWalk_IWalking_2.gxx
0016 
0017 #include <Bnd_Range.hxx>
0018 #include <TColStd_MapOfInteger.hxx>
0019 
0020 #ifndef OCCT_DEBUG
0021 #define No_Standard_RangeError
0022 #define No_Standard_OutOfRange
0023 #endif
0024 
0025 static void CutVectorByTolerances (gp_Vec2d&          theVector,
0026                                    const math_Vector& theTolerance)
0027 {
0028   if (Abs(theVector.X()) < theTolerance(1))
0029     theVector.SetX (0.);
0030   if (Abs(theVector.Y()) < theTolerance(2))
0031     theVector.SetY (0.);
0032 }
0033 
0034 // _______________________________________________
0035 //
0036 // Location of point (u, v) in the natural domain of a surface AND update  
0037 // of couple (u, v) for the calculation of the next point.
0038 //
0039 Standard_Boolean IntWalk_IWalking::Cadrage 
0040   (math_Vector& BornInf,
0041    math_Vector& BornSup,
0042    math_Vector& UVap,
0043    Standard_Real& Step,
0044 //   Standard_Real& StepV,
0045    const Standard_Integer StepSign) const 
0046 
0047 // there are always :
0048 // BorInf(1) <= UVap(1) <= BornSup(1) et BorInf(2) <= UVap(2) <= BornSup(2)
0049 // 1) check if the process point is out of the natural domain of the surface.
0050 // 2) if yes the approximated point is located on border taking the best direction
0051 // the step and a limit blocating one of the parameters during the recent call of 
0052 // FunctionSetRoot are modified;
0053 // 3) couple (u, v) is recomputed by approximation for the calculation of the next point.
0054 // 4) return Standard_True if location, Standard_False if no location.
0055 {
0056   Standard_Real Duvx = previousd2d.X();
0057   Standard_Real Duvy = previousd2d.Y();
0058 
0059   if (!reversed) {
0060     previousPoint.ParametersOnS2(UVap(1),UVap(2));
0061   }
0062   else {
0063     previousPoint.ParametersOnS1(UVap(1),UVap(2));
0064   }
0065 
0066   Standard_Real U1 = UVap(1) + Step * Duvx * StepSign;
0067   Standard_Real V1 = UVap(2) + Step * Duvy * StepSign;
0068 
0069 
0070   Standard_Boolean infu = (U1 <= BornInf(1)+Precision::PConfusion());
0071   Standard_Boolean supu = (U1 >= BornSup(1)-Precision::PConfusion());
0072   Standard_Boolean infv = (V1 <= BornInf(2)+Precision::PConfusion());
0073   Standard_Boolean supv = (V1 >= BornSup(2)-Precision::PConfusion());
0074 
0075   Standard_Real theStepU,theStepV;
0076 
0077   if (!infu && !supu && !infv && !supv) {
0078     UVap(1) = U1;
0079     UVap(2) = V1;
0080     return Standard_False;
0081   }
0082 
0083   if ((infu || supu) && (infv || supv)) {
0084     if (infu) { // jag 940616
0085       if(Duvx) { 
0086         theStepU = Abs((BornInf(1) - UVap(1)) / Duvx);  // iso U =BornInf(1)
0087       }
0088       else { 
0089         theStepU = Step; 
0090       }
0091     }
0092     else {
0093       if(Duvx) { 
0094         theStepU = Abs((BornSup(1) - UVap(1)) / Duvx);  // iso U =BornSup(1)
0095       }
0096       else { 
0097         theStepU = Step;
0098       }
0099     }
0100     if (infv) { // jag 940616
0101       if(Duvy) { 
0102         theStepV = Abs((BornInf(2) - UVap(2)) / Duvy);  // iso V =BornInf(2)
0103       }
0104       else { 
0105         theStepV = Step;
0106       }
0107     }
0108     else {
0109       if(Duvy) { 
0110         theStepV = Abs((BornSup(2) - UVap(2)) / Duvy);  // iso V =BornSup(2)
0111       }
0112       else { 
0113         theStepV = Step; 
0114       }
0115     }
0116 
0117 
0118     if (theStepU <= theStepV) {
0119       Step = theStepU;
0120       if (infu) {
0121         UVap(1) = BornInf(1);
0122         BornSup(1) = BornInf(1);
0123       }
0124       else {
0125         UVap(1) = BornSup(1);
0126         BornInf(1) = BornSup(1);
0127       }
0128       UVap(2) += Step*Duvy*StepSign;
0129     }
0130     else {
0131       Step = theStepV;
0132       if (infv) {
0133         UVap(2) = BornInf(2);
0134         BornSup(2) = BornInf(2); 
0135       }
0136       else {
0137         UVap(2) = BornSup(2);
0138         BornInf(2) = BornSup(2); 
0139       }
0140       UVap(1) += Step*Duvx*StepSign;
0141     }
0142     return Standard_True;
0143   }
0144 
0145   else if (infu) { // jag 940616
0146     if(Duvx) { 
0147       Standard_Real aStep = Abs((BornInf(1) - UVap(1)) / Duvx);  // iso U =BornInf(1)
0148       if(aStep<Step) Step=aStep;
0149     }
0150     BornSup(1) = BornInf(1);                     // limit the parameter
0151     UVap(1) = BornInf(1);
0152     UVap(2) += Step*Duvy*StepSign;
0153     return Standard_True;
0154   }
0155   else if (supu) { // jag 940616
0156     if(Duvx) { 
0157       Standard_Real aStep = Abs((BornSup(1) - UVap(1)) / Duvx);  // iso U =BornSup(1)
0158       if(aStep<Step) Step=aStep;
0159     }
0160     BornInf(1) = BornSup(1);                    // limit the parameter
0161     UVap(1) = BornSup(1);
0162     UVap(2) += Step*Duvy*StepSign;
0163     return Standard_True;
0164   }
0165   else if (infv) { // jag 940616
0166     if(Duvy) { 
0167       Standard_Real aStep = Abs((BornInf(2) - UVap(2)) / Duvy);  // iso V =BornInf(2) 
0168       if(aStep<Step) Step=aStep;
0169     }
0170     BornSup(2) = BornInf(2);
0171     UVap(1) += Step*Duvx*StepSign;
0172     UVap(2) = BornInf(2);
0173     return Standard_True;
0174   }
0175   else if (supv) { // jag 940616
0176     if(Duvy) { 
0177       Standard_Real aStep = Abs((BornSup(2) - UVap(2)) / Duvy);  // iso V =BornSup(2)
0178       if(aStep<Step) Step=aStep;
0179     }
0180     BornInf(2) = BornSup(2);
0181     UVap(1) += Step*Duvx*StepSign;
0182     UVap(2) = BornSup(2);
0183     return Standard_True;
0184   }
0185   return Standard_True;
0186 }
0187 
0188 
0189 Standard_Boolean IntWalk_IWalking::TestArretPassage
0190   (const TColStd_SequenceOfReal& Umult,
0191    const TColStd_SequenceOfReal& Vmult,
0192    TheIWFunction& sp,
0193    math_Vector& UV,
0194    Standard_Integer& Irang)
0195 
0196 // Umult et Vmult : table of stop (or crossing) points on border, 
0197 //         here only the crossing points are taken into account.
0198 // UV     : the current point.
0199 // Irang  : at exit : give index of the stop point in uvstart1 or 0.
0200 //          consider that there is no risk of crossing only if there is one crossing point.
0201 
0202 
0203 // test of stop for an OPEN intersection line
0204 // 1) crossing test on all interior points
0205 // 2) stop test on all start points
0206 // if a stop is detected, the index of the stop point (Irang) is returned  
0207 // in the iterator of start points and the associated parameters in UV space.
0208 {
0209   Standard_Real Up, Vp, Du, Dv, Dup, Dvp, Utest,Vtest; 
0210   Standard_Integer j, N, ind;
0211   Standard_Real tolu = tolerance(1);
0212   Standard_Real tolv = tolerance(2);
0213   Standard_Real tolu2 = 10.*tolerance(1);
0214   Standard_Real tolv2 = 10.*tolerance(2);
0215   
0216   Standard_Boolean Arrive = Standard_False;
0217   
0218   // crossing test  on point that can start a loop; mark 
0219   // as processed if passes through an open line 
0220   
0221   if (!reversed) {
0222     previousPoint.ParametersOnS2(Up,Vp);
0223   }
0224   else {
0225     previousPoint.ParametersOnS1(Up,Vp);
0226   }
0227 
0228   for (size_t i = 1; i < wd2.size(); i++) { 
0229     if (wd2[i].etat > 0) { 
0230       // debug jag 05.04.94
0231 
0232 //      if ((Up-wd2[i].ustart)*(UV(1)-wd2[i].ustart) +
0233 //        (Vp-wd2[i].vstart)*(UV(2)-wd2[i].vstart) <= 0)
0234       Utest = wd2[i].ustart;
0235       Vtest = wd2[i].vstart;
0236 
0237       Du  = UV(1)-Utest;
0238       Dv  = UV(2)-Vtest;
0239       Dup = Up - Utest;
0240       Dvp = Vp - Vtest;
0241       
0242 //-- lbr le 30 oct 97 
0243 
0244       //IFV for OCC20285
0245 
0246       if ((Abs(Du) < tolu2 && Abs(Dv) < tolv2) ||
0247           (Abs(Dup) < tolu2 && Abs(Dvp) < tolv2)) { 
0248             
0249         wd2[i].etat = -wd2[i].etat;
0250       }
0251       else {
0252         Standard_Real DDu = (UV(1)-Up);
0253         Standard_Real DDv = (UV(2)-Vp);
0254         Standard_Real DDD = DDu*DDu+DDv*DDv;
0255         Standard_Real DD1 = Du*Du+Dv*Dv;
0256         if(DD1<=DDD) { 
0257           Standard_Real DD2 = Dup*Dup+Dvp*Dvp;
0258           if(DD2<=DDD && ((Du*Dup) + (Dv*Dvp*tolu/tolv) <= 0.)) {       
0259             wd2[i].etat = -wd2[i].etat;
0260           }
0261         }
0262       }
0263     }
0264   }
0265 
0266   // stop test on point given at input and not yet processed
0267 
0268 //  Modified by Sergey KHROMOV - Tue Nov 20 10:55:01 2001 Begin
0269 // Check of all path points in the following order:
0270 //   * First check all not treated points;
0271 //   * After that check of already treated ones.
0272   Standard_Integer l;
0273 
0274   //// Modified by jgv, 28.07.2010 for OCC21914 ////
0275   // There are several path points between (Up,Vp) and UV
0276   // So several path points satisfy the condition
0277   // Dup*UV1mUtest + Dvp*UV2mVtest) < 0
0278   // We choose from them the path point with
0279   // minimum distance to (Up,Vp)
0280   TColStd_SequenceOfInteger i_candidates;
0281   TColStd_SequenceOfReal    SqDist_candidates;
0282 
0283   for (l = 1; l <= 2 && !Arrive; l++) {
0284     Standard_Boolean isToCheck;
0285 
0286     for (size_t i = 1; i < wd1.size(); i++) {
0287       if (l == 1)
0288         isToCheck = (wd1[i].etat > 0);
0289       else
0290         isToCheck = (wd1[i].etat < 0);
0291         
0292       if (isToCheck) {
0293 //  Modified by Sergey KHROMOV - Tue Nov 20 11:03:16 2001 End
0294 
0295         // debug jag voir avec isg
0296 
0297         Utest = wd1[i].ustart;
0298         Vtest = wd1[i].vstart;
0299         Dup = Up - Utest;
0300         Dvp = Vp - Vtest;
0301         if (Abs(Dup) >= tolu || Abs(Dvp) >= tolv) {
0302           Standard_Real UV1mUtest = UV(1)-Utest;
0303           Standard_Real UV2mVtest = UV(2)-Vtest;
0304           if(( (Dup*UV1mUtest + Dvp*UV2mVtest) < 0) ||
0305              (   Abs(UV1mUtest) < tolu 
0306               && Abs(UV2mVtest) < tolv)) {
0307             i_candidates.Append((Standard_Integer)i);
0308             SqDist_candidates.Append(Dup*Dup + Dvp*Dvp);
0309             /*
0310             Irang=i;
0311             Arrive = Standard_True;
0312             UV(1) = Utest;
0313             UV(2) = Vtest;
0314             */
0315           }
0316           else if (nbMultiplicities[i] > 0 && i_candidates.IsEmpty()) {
0317             N=0;
0318             for (size_t k = 1; k < i; k++) { 
0319               N+=nbMultiplicities[k];
0320             }
0321             for (j = N + 1; j <= N + nbMultiplicities[i]; j++) {
0322               if (((Up-Umult(j))*(UV(1)-Umult(j)) +
0323                    (Vp-Vmult(j))*(UV(2)-Vmult(j)) < 0) ||
0324                   (Abs(UV(1)-Umult(j)) < tolu &&
0325                    Abs(UV(2)-Vmult(j)) < tolv)) {
0326                 Irang=(Standard_Integer)i;
0327                 Arrive = Standard_True;
0328                 UV(1) = Utest;
0329                 UV(2) = Vtest;
0330                 break;
0331               }
0332             }
0333           }
0334           if (Arrive) {
0335             Standard_Real abidF[1], abidD[1][2];
0336             math_Vector bidF(abidF,1,1);
0337             math_Matrix bidD(abidD,1,1,1,2);
0338         sp.Values(UV,bidF,bidD);
0339             break;
0340           }
0341         }
0342       }
0343     } //end of for (i = 1; i < wd1.size(); i++)
0344     if (!i_candidates.IsEmpty())
0345       {
0346         Standard_Real MinSqDist = RealLast();
0347         for (ind = 1; ind <= i_candidates.Length(); ind++)
0348           if (SqDist_candidates(ind) < MinSqDist)
0349             {
0350               MinSqDist = SqDist_candidates(ind);
0351               Irang = i_candidates(ind);
0352             }
0353         Arrive = Standard_True;
0354         UV(1) = wd1[Irang].ustart;
0355         UV(2) = wd1[Irang].vstart;
0356       }
0357   } //end of for (l = 1; l <= 2 && !Arrive; l++)
0358   return  Arrive;
0359 }
0360 
0361 Standard_Boolean IntWalk_IWalking::TestArretPassage
0362   (const TColStd_SequenceOfReal& Umult,
0363    const TColStd_SequenceOfReal& Vmult,
0364    const math_Vector& UV, 
0365    const Standard_Integer Index, 
0366    Standard_Integer& Irang)
0367 {
0368 // Umult, Vmult : table of stop (or crossing) points on border, here
0369 //          only crossing points are taken into account.
0370 // UV     : the current point.
0371 // Index  : index of the start point in uvstart2 of the current line
0372 //          (this is an interior point).
0373 // Irang  : at output : gives the index of the point passing in uvstart1 or 0.
0374 //          consider that there is risk to cross only one crossing point.
0375 
0376 // test of stop for a CLOSED intersection line.
0377 // 1) test of crossing on all interior points.
0378 // 2) test of crossing on all crossing points.
0379 
0380   Standard_Real Up, Vp, Scal;
0381   Standard_Boolean Arrive = Standard_False;
0382   Standard_Integer N, k, i;
0383   Standard_Real Utest,Vtest;
0384   Standard_Real tolu = tolerance(1);
0385   Standard_Real tolv = tolerance(2);
0386 
0387   
0388   // tests of stop and of crossing on all interior points.
0389 
0390   if (!reversed) {
0391     previousPoint.ParametersOnS2(Up,Vp);
0392   }
0393   else {
0394     previousPoint.ParametersOnS1(Up,Vp);
0395   }
0396 
0397   Standard_Real UV1=UV(1);
0398   Standard_Real UV2=UV(2);
0399 
0400 
0401   //Normalizing factor. If it is less than 1.0 then the range will be expanded. 
0402   //This is no good for computation. Therefore, it is limited.
0403   //Do not limit this factor in case of highly anisotropic parametrization
0404   //(parametric space is considerably larger in one direction than another).
0405   const Standard_Boolean isHighlyAnisotropic = Max(tolu, tolv) > 1000. * Min(tolu, tolv);
0406   const Standard_Real deltau = mySRangeU.IsVoid() ? UM - Um
0407                                                   : (isHighlyAnisotropic ? mySRangeU.Delta()
0408                                                                          : Max(mySRangeU.Delta(), 1.0));
0409   const Standard_Real deltav = mySRangeV.IsVoid() ? VM - Vm
0410                                                   : (isHighlyAnisotropic ? mySRangeV.Delta()
0411                                                                          : Max(mySRangeV.Delta(), 1.0));
0412 
0413   Up/=deltau; UV1/=deltau; 
0414   Vp/=deltav; UV2/=deltav;
0415 
0416   tolu/=deltau;
0417   tolv/=deltav;
0418 
0419   Standard_Real tolu2=tolu+tolu;
0420   Standard_Real tolv2=tolv+tolv;
0421 
0422   
0423   Standard_Real dPreviousCurrent = (Up-UV1)*(Up-UV1)+(Vp-UV2)*(Vp-UV2);
0424   for (k = 1; k < (int)wd2.size(); k++) { 
0425     if (wd2[k].etat > 0) {
0426       Utest = wd2[k].ustart;
0427       Vtest = wd2[k].vstart;
0428       
0429       Utest/=deltau;
0430       Vtest/=deltav;
0431       
0432       Standard_Real UV1mUtest=UV1-Utest;
0433       Standard_Real UV2mVtest=UV2-Vtest;
0434       if(   (UV1mUtest<tolu2 && UV1mUtest>-tolu2)
0435          && (UV2mVtest<tolv2 && UV2mVtest>-tolv2)) { 
0436         if(Index!=k) { 
0437           //-- cout<<"* etat2 : ("<<k<<")"<<endl;
0438           wd2[k].etat=-wd2[k].etat; //-- mark the point as a crossing point 
0439         }
0440         else {  //-- Index == k
0441           //-- cout<<"* Arrive"<<endl;
0442           Arrive=Standard_True;
0443         }
0444       }
0445       else { 
0446         Standard_Real UpmUtest = (Up-Utest);
0447         Standard_Real VpmVtest = (Vp-Vtest);
0448         Standard_Real dPreviousStart = (UpmUtest)*(UpmUtest)+(VpmVtest)*(VpmVtest);
0449         Standard_Real dCurrentStart  = UV1mUtest * UV1mUtest + UV2mVtest * UV2mVtest;
0450 
0451         Scal=(UpmUtest)*(UV1mUtest)+(VpmVtest)*(UV2mVtest);
0452         if( (Abs(UpmUtest)<tolu && Abs(VpmVtest)<tolv)) { 
0453           if(Index != k ) { 
0454             //-- cout<<"** etat2 : ("<<k<<")"<<endl;
0455             wd2[k].etat = -wd2[k].etat;
0456           }
0457         }
0458         else if(Scal<0 && (dPreviousStart+dCurrentStart < dPreviousCurrent)) { 
0459           if (Index == k ) { // on a boucle.
0460             Arrive = Standard_True;
0461             //-- cout<<"** Arrive  : k="<<k<<endl;
0462           }
0463           else {
0464             //-- cout<<"*** etat2 : ("<<k<<")"<<endl;
0465             wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point 
0466           }
0467         }
0468         else if(k!=Index) {
0469           if(dPreviousStart < dPreviousCurrent*0.25) { 
0470             wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point 
0471             //-- cout<<"**** etat2 : ("<<k<<")"<<endl;
0472           }
0473           else { 
0474             if(dCurrentStart < dPreviousCurrent*0.25) {
0475               //-- cout<<"***** etat2 : ("<<k<<")"<<endl;
0476               wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point 
0477             }
0478             else { 
0479               Standard_Real UMidUtest = 0.5*(UV1+Up)-Utest;
0480               Standard_Real VMidVtest = 0.5*(UV2+Vp)-Vtest;         
0481               Standard_Real dMiddleStart =  UMidUtest* UMidUtest+VMidVtest*VMidVtest;
0482 
0483               if(dMiddleStart < dPreviousCurrent*0.5) { 
0484                 //-- cout<<"*********** etat2 : ("<<k<<")"<<endl;
0485                 wd2[k].etat = -wd2[k].etat; // mark the point as a crossing point 
0486               }
0487             }
0488           }
0489         }
0490       }
0491     }
0492   }
0493 
0494   // crossing test on crossing points.
0495   
0496   Irang =0;
0497   for (i = 1; i < (int)wd1.size(); i++) {
0498     if (wd1[i].etat > 0 && wd1[i].etat < 11) { //test of crossing points 
0499       Utest = wd1[i].ustart;
0500       Vtest = wd1[i].vstart;
0501       Utest/=deltau;
0502       Vtest/=deltav;
0503       
0504       if (((Up-Utest) * (UV1-Utest) + (Vp-Vtest) * (UV2-Vtest) < 0) ||
0505           (Abs(UV1-Utest) < tolu &&  Abs(UV2-Vtest) < tolv)) 
0506         Irang = i;
0507       else if (nbMultiplicities[i] > 0) {
0508         N=0;
0509         for (k = 1; k < i; k++) N = N + nbMultiplicities[k];
0510         for (Standard_Integer j = N + 1; j <= N + nbMultiplicities[i]; j++) {
0511           Standard_Real Umultj = Umult(j)/deltau;
0512           Standard_Real Vmultj = Vmult(j)/deltav;         
0513           if (((Up-Umultj)*(UV1-Umultj) +
0514                (Vp-Vmultj)*(UV2-Vmultj) < 0) ||
0515               (Abs(UV1-Umultj) < tolu &&
0516                Abs(UV2-Vmultj) < tolv)) {
0517             Irang=i;
0518             break;
0519           }
0520         }
0521       }
0522     }    
0523   }
0524   return Arrive;
0525 }
0526 
0527 
0528 Standard_Boolean IntWalk_IWalking::TestArretAjout
0529   (TheIWFunction& sp,
0530    math_Vector& UV, 
0531    Standard_Integer& Irang,
0532    IntSurf_PntOn2S& Psol) 
0533 
0534 // test of stop on added points 
0535 // these are the points on the natural biorder that were not given at input
0536 // return : Psol,  the added point.
0537 //          Irang, index in the iterator of added points.
0538 //          UV,    parameter of the added point.
0539 //
0540 {
0541   Standard_Boolean Arrive = Standard_False;
0542   Standard_Real U1,V1;
0543   Standard_Real Up,Vp; 
0544 
0545   if (!reversed) {
0546     previousPoint.ParametersOnS2(Up,Vp);
0547   }
0548   else {
0549     previousPoint.ParametersOnS1(Up,Vp);
0550   }
0551 
0552   Standard_Integer nbAjout = seqAjout.Length();
0553   for (Standard_Integer i = 1; i <= nbAjout; i++) {
0554     Irang = seqAjout.Value(i);
0555 
0556 // add test Abs(Irang) <= lines.Length() for the case when 
0557 // a closed line is opened by adding a  1 point on this same
0558 // line. Anyway there is a huge problem as 2 points will be 
0559 // added on this line...
0560 
0561     if (Abs(Irang) <= lines.Length()) {
0562 
0563       const Handle(IntWalk_TheIWLine)& Line = lines.Value(Abs(Irang));
0564       if (Irang>0) 
0565         Psol = Line->Value(Line->NbPoints()); 
0566       else 
0567         Psol = Line->Value(1);
0568       if (!reversed) {
0569         Psol.ParametersOnS2(U1, V1);
0570       }
0571       else {
0572         Psol.ParametersOnS1(U1, V1);
0573       }
0574       if (((Up-U1) * (UV(1)-U1) + 
0575            (Vp-V1) * (UV(2)-V1)) < 0 ||
0576           (Abs(UV(1)-U1) < tolerance(1) &&  
0577            Abs(UV(2)-V1) < tolerance(2))) {
0578 //jag 940615    Irang= -Abs(Irang); 
0579         Arrive = Standard_True; 
0580         UV(1) = U1;
0581         UV(2) = V1;
0582         Standard_Real abidF[1], abidD[1][2];
0583         math_Vector bidF(abidF,1,1);
0584         math_Matrix bidD(abidD,1,1,1,2);
0585     sp.Values(UV,bidF,bidD);
0586         break;
0587       }
0588     }
0589   }
0590   return Arrive;
0591 }
0592 
0593 void IntWalk_IWalking::FillPntsInHoles(TheIWFunction& sp,
0594                                        TColStd_SequenceOfInteger& CopySeqAlone,
0595                                        IntSurf_SequenceOfInteriorPoint& PntsInHoles)
0596 {
0597   math_Vector BornInf(1,2), BornSup(1,2);
0598   BornInf(1) = Um;
0599   BornSup(1) = UM;
0600   BornInf(2) = Vm;
0601   BornSup(2) = VM;
0602   PointLineLine.Clear();
0603   TColStd_SequenceOfInteger SeqToRemove;
0604   TColStd_MapOfInteger BadSolutions;
0605   
0606   for (Standard_Integer i = 1; i < CopySeqAlone.Length(); i++)
0607   {
0608     Standard_Integer Irang1 = CopySeqAlone(i);
0609     if (Irang1 == 0)
0610       continue;
0611     Standard_Boolean ToRemove = Standard_False;
0612     IntSurf_PntOn2S PointAlone1, PointAlone2;
0613     const Handle(IntWalk_TheIWLine)& Line1 = lines.Value(Abs(Irang1));
0614     if (Irang1 > 0) 
0615       PointAlone1 = Line1->Value(Line1->NbPoints()); 
0616     else 
0617       PointAlone1 = Line1->Value(1);
0618     gp_Pnt2d P2d1 = PointAlone1.ValueOnSurface(reversed), P2d2;
0619     Standard_Real MinSqDist = RealLast();
0620     Standard_Integer MinRang = 0, MinIndex = 0;
0621     for (Standard_Integer j = i+1; j <= CopySeqAlone.Length(); j++)
0622     {
0623       Standard_Integer Irang2 = CopySeqAlone(j);
0624       if (Irang2 == 0 ||
0625           BadSolutions.Contains(Irang2))
0626         continue;
0627       const Handle(IntWalk_TheIWLine)& Line2 = lines.Value(Abs(Irang2));
0628       if (Irang2 > 0)
0629         PointAlone2 = Line2->Value(Line2->NbPoints());
0630       else
0631         PointAlone2 = Line2->Value(1);
0632       P2d2 = PointAlone2.ValueOnSurface(reversed);
0633       Standard_Real aSqDist = P2d1.SquareDistance(P2d2);
0634       if (aSqDist < MinSqDist)
0635       {
0636         MinSqDist = aSqDist;
0637         MinRang = Irang2;
0638         MinIndex = j;
0639       }
0640     }
0641     //processing points from Irang1 and MinRang
0642     if (MinRang == 0)
0643     {
0644       SeqToRemove.Append(Irang1);
0645       BadSolutions.Clear();
0646       continue;
0647     }
0648     //Ends of same line
0649     if (Abs(Irang1) == Abs(MinRang) &&
0650         lines.Value(Abs(Irang1))->NbPoints() == 2)
0651     {
0652       SeqToRemove.Append(Irang1);
0653       SeqToRemove.Append(MinRang);
0654       CopySeqAlone(i) = 0;
0655       CopySeqAlone(MinIndex) = 0;
0656       BadSolutions.Clear();
0657       continue;
0658     }
0659     ///////////////////
0660     const Handle(IntWalk_TheIWLine)& Line2 = lines.Value(Abs(MinRang));
0661     if (MinRang > 0)
0662       PointAlone2 = Line2->Value(Line2->NbPoints());
0663     else
0664       PointAlone2 = Line2->Value(1);
0665     gp_Pnt Pnt1 = PointAlone1.Value();
0666     gp_Pnt Pnt2 = PointAlone2.Value();
0667     P2d2 = PointAlone2.ValueOnSurface(reversed);
0668     Standard_Real MinSqDist3d = Pnt1.SquareDistance(Pnt2);
0669     if (MinSqDist3d <= epsilon ||
0670         (Abs(P2d1.X() - P2d2.X()) <= tolerance(1) &&
0671          Abs(P2d1.Y() - P2d2.Y()) <= tolerance(2))) //close points
0672       ToRemove = Standard_True;
0673     else //real curve
0674     {
0675       math_Vector UVap(1,2), UV(1,2);
0676       UVap(1) = (P2d1.X() + P2d2.X())/2;
0677       UVap(2) = (P2d1.Y() + P2d2.Y())/2;
0678       math_FunctionSetRoot Rsnld(sp, tolerance);
0679       Rsnld.Perform(sp, UVap, BornInf, BornSup);
0680       if (Rsnld.IsDone() &&
0681           Abs(sp.Root()) <= sp.Tolerance() &&
0682           !sp.IsTangent())
0683       {
0684         Rsnld.Root(UV);
0685         gp_Pnt2d Pmid(UV(1),UV(2));
0686         gp_Vec2d P1P2(P2d1, P2d2);
0687         gp_Vec2d P1Pmid(P2d1, Pmid);
0688         gp_Vec2d P2Pmid(P2d2, Pmid);
0689         Standard_Real ScalProd1 = P1P2 * P1Pmid;
0690         Standard_Real ScalProd2 = P1P2 * P2Pmid;
0691         Standard_Boolean IsPmidValid = (ScalProd1 > 0. && ScalProd2 < 0); //Pmid is in the middle
0692         if (IsPmidValid)
0693         {
0694           for (Standard_Integer iline = 1; iline <= lines.Length(); iline++)
0695             if (IsPointOnLine(Pmid,iline))
0696             {
0697               IsPmidValid = Standard_False;
0698               break;
0699             }
0700         }
0701         if (IsPmidValid)
0702         {
0703           IntSurf_InteriorPoint aPoint(sp.Point(), UV(1), UV(2),
0704                                        sp.Direction3d(),
0705                                        sp.Direction2d());
0706           PntsInHoles.Append(aPoint);
0707           TColStd_ListOfInteger LineLine;
0708           LineLine.Append(Irang1);
0709           LineLine.Append(MinRang);
0710           PointLineLine.Bind(PntsInHoles.Length(), LineLine);
0711         }
0712         else
0713         {
0714           BadSolutions.Add(MinRang);
0715           i--;
0716           continue;
0717         }
0718       }
0719       else
0720       {
0721         BadSolutions.Add(MinRang);
0722         i--;
0723         continue;
0724       }
0725     }
0726     CopySeqAlone(i) = 0;
0727     CopySeqAlone(MinIndex) = 0;
0728     if (ToRemove)
0729     {
0730       SeqToRemove.Append(Irang1);
0731       SeqToRemove.Append(MinRang);
0732     }
0733     BadSolutions.Clear();
0734   }
0735 
0736   for (Standard_Integer i = 1; i <= SeqToRemove.Length(); i++)
0737     for (Standard_Integer j = 1; j <= seqAlone.Length(); j++)
0738       if (seqAlone(j) == SeqToRemove(i))
0739       {
0740         seqAlone.Remove(j);
0741         break;
0742       }
0743 }
0744 
0745 void IntWalk_IWalking::TestArretCadre
0746   (const TColStd_SequenceOfReal& Umult,
0747    const TColStd_SequenceOfReal& Vmult,
0748    const Handle(IntWalk_TheIWLine)& Line,
0749    TheIWFunction& sp,
0750    math_Vector& UV,
0751    Standard_Integer& Irang)
0752 
0753 // test of stop when located on border.
0754 // tried all tests of stop and arrived.
0755 // test of stop on all given departure points already marked and on the entire current line.
0756 // This line can be shortened if the stop point is found.
0757 // Abs(Irang) = index in the iterator of departure points or 0
0758 //  if Irang <0 , it is necessary to add this point on the line (no Line->Cut)
0759 // UV = parameter of the departure point
0760 {
0761   Standard_Real Scal, Up, Vp, Uc, Vc;
0762   Standard_Integer N;
0763   Standard_Boolean Found = Standard_False;
0764 
0765 
0766   Irang =0;
0767   for (Standard_Integer i = 1; i < (int)wd1.size(); i++) {
0768     if (wd1[i].etat < 0) {
0769       N=0; // range in UVMult.
0770       if (nbMultiplicities[i] > 0) {
0771         for (Standard_Integer k = 1; k < i; k++) 
0772           N+=nbMultiplicities[k];
0773       }
0774       if (!reversed) {
0775         Line->Value(1).ParametersOnS2(Up,Vp);
0776       }
0777       else {
0778         Line->Value(1).ParametersOnS1(Up,Vp);
0779       }
0780       Standard_Integer nbp= Line->NbPoints();
0781       for (Standard_Integer j = 2; j <= nbp; j++) {
0782         if (!reversed) {
0783           Line->Value(j).ParametersOnS2(Uc,Vc);
0784         }
0785         else {
0786           Line->Value(j).ParametersOnS1(Uc,Vc);
0787         }
0788 
0789         gp_Vec2d aVec1 (Up-wd1[i].ustart, Vp-wd1[i].vstart),
0790           aVec2 (Uc-wd1[i].ustart, Vc-wd1[i].vstart);
0791         CutVectorByTolerances (aVec1, tolerance);
0792         CutVectorByTolerances (aVec2, tolerance);
0793 
0794         Scal = aVec1 * aVec2;
0795         
0796         // if a stop point is found: stop the line on this point.
0797         if (Scal < 0) { 
0798           Line->Cut(j);  nbp= Line->NbPoints();
0799           Irang = i;
0800           UV(1) = wd1[Irang].ustart;
0801           UV(2) = wd1[Irang].vstart;
0802           Found = Standard_True;
0803         }
0804         else if (Abs(Uc-wd1[i].ustart) < tolerance(1) &&
0805                  Abs(Vc-wd1[i].vstart) < tolerance(2) ) {
0806           Line->Cut(j);  nbp= Line->NbPoints();
0807           Irang=i; 
0808           UV(1) = wd1[Irang].ustart;
0809           UV(2) = wd1[Irang].vstart;
0810           Found = Standard_True;
0811         }
0812         else if (nbMultiplicities[i] > 0) {
0813           for (Standard_Integer k = N+1; k <= N + nbMultiplicities[i]; k++) {
0814 
0815             aVec1.SetCoord (Up-Umult(k), Vp-Vmult(k)),
0816             aVec2.SetCoord (Uc-Umult(k), Vc-Vmult(k));
0817             CutVectorByTolerances (aVec1, tolerance);
0818             CutVectorByTolerances (aVec2, tolerance);
0819 
0820             Scal = aVec1 * aVec2;
0821             
0822             if (Scal < 0) { 
0823               Line->Cut(j);  nbp= Line->NbPoints();
0824               Irang=i;
0825               UV(1) = wd1[Irang].ustart;
0826               UV(2) = wd1[Irang].vstart;
0827               Found = Standard_True;
0828               break;
0829             }
0830             else if (Abs(Uc-Umult(k)) < tolerance(1) &&
0831                      Abs(Vc-Vmult(k)) < tolerance(2)) {
0832               Line->Cut(j);  nbp= Line->NbPoints();
0833               Irang=i; 
0834               UV(1) = wd1[Irang].ustart;
0835               UV(2) = wd1[Irang].vstart;
0836               Found = Standard_True;
0837               break;
0838             }
0839           }
0840         }
0841         if (Found) {
0842           Standard_Real abidF[1], abidD[1][2];
0843           math_Vector bidF(abidF,1,1);
0844           math_Matrix bidD(abidD,1,1,1,2);
0845       sp.Values(UV,bidF,bidD);
0846           Standard_Integer NBP =  Line->NbPoints();
0847           Standard_Integer Indextg;       
0848           Line->TangentVector(Indextg);
0849           if(Indextg > NBP) { 
0850             if(j>3 && j<=NBP+1) { 
0851               gp_Vec Dir3d = sp.Direction3d();
0852               gp_Vec Dir3d1 = gp_Vec(Line->Value(j-2).Value(),Line->Value(j-1).Value());
0853               Standard_Real dot = Dir3d.Dot(Dir3d1);
0854               if(dot<0.0) { // Normally this Function should not be used often !!! 
0855                 Dir3d.Reverse();
0856                 //-- cout<<" IntWalk_IWalking_2.gxx REVERSE "<<endl;
0857               }
0858               Line->SetTangentVector(previousd3d,j-1);
0859             }
0860 #ifdef OCCT_DEBUG
0861             else { 
0862               std::cout<<" IntWalk_IWalking_2.gxx : bizarrerie 30 10 97 "<<std::endl;
0863             }
0864 #endif
0865           }
0866 
0867           return;
0868         }
0869         Up = Uc;
0870         Vp = Vc;
0871       }
0872 
0873       // now the last point of the line and the last calculated point are compated.
0874       // there will be no need to "Cut"
0875 
0876       gp_Vec2d aVec1 (Up-wd1[i].ustart, Vp-wd1[i].vstart),
0877         aVec2 (UV(1)-wd1[i].ustart, UV(2)-wd1[i].vstart);
0878       CutVectorByTolerances (aVec1, tolerance);
0879       CutVectorByTolerances (aVec2, tolerance);
0880       
0881       Scal = aVec1 * aVec2;
0882       
0883       if (Scal < 0) { 
0884         Irang = i;
0885         UV(1) = wd1[Irang].ustart;
0886         UV(2) = wd1[Irang].vstart;
0887         Found = Standard_True;
0888       }
0889       else if (Abs(UV(1)-wd1[i].ustart) < tolerance(1) &&
0890                Abs(UV(2)-wd1[i].vstart) < tolerance(2)) {
0891         Irang=i; 
0892         UV(1) = wd1[Irang].ustart;
0893         UV(2) = wd1[Irang].vstart;
0894         Found = Standard_True;
0895       }
0896       else if (nbMultiplicities[i] > 0) {
0897         for (Standard_Integer j = N+1; j <= N+nbMultiplicities[i]; j++) {
0898 
0899           aVec1.SetCoord (Up-Umult(j), Vp-Vmult(j));
0900           aVec2.SetCoord (UV(1)-Umult(j), UV(2)-Vmult(j));
0901           CutVectorByTolerances (aVec1, tolerance);
0902           CutVectorByTolerances (aVec2, tolerance);
0903           
0904           Scal = aVec1 * aVec2;
0905           
0906           if (Scal < 0) { 
0907             Irang=i;
0908             UV(1) = wd1[Irang].ustart;
0909             UV(2) = wd1[Irang].vstart;
0910             Found = Standard_True;
0911             break;
0912           }
0913           else if (Abs(UV(1)-Umult(j)) < tolerance(1) &&
0914                    Abs(UV(2)-Vmult(j)) < tolerance(2)) {
0915             Irang=i; 
0916             UV(1) = wd1[Irang].ustart;
0917             UV(2) = wd1[Irang].vstart;
0918             Found = Standard_True;
0919             break;
0920           }
0921         }
0922       }
0923       if (Found) {
0924         Irang = -Irang; // jag 941017
0925         Standard_Real abidF[1], abidD[1][2];
0926         math_Vector bidF(abidF,1,1);
0927         math_Matrix bidD(abidD,1,1,1,2);
0928     sp.Values(UV,bidF,bidD);
0929         return;
0930       }
0931     }
0932   } 
0933 }
0934 
0935