0024677: Control of license statements and non-ascii characters in integrated code
[occt.git] / src / IntStart / IntStart_SearchOnBoundaries.gxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <TopoDS_Edge.hxx>
16 #include <Geom_Curve.hxx>
17 #include <BRepAdaptor_Curve.hxx>
18 #include <Adaptor3d_HSurface.hxx>
19 #include <GeomAbs_SurfaceType.hxx>
20 #include <BRep_Tool.hxx>
21 #include <Geom_Line.hxx>
22 #include <gp_Lin.hxx>
23 #include <gp_Vec.hxx>
24 #include <gp_Dir.hxx>
25 #include <gp_Cylinder.hxx>
26 #include <gp_Ax1.hxx>
27 #include <gp_Lin.hxx>
28
29 #include <GeomAdaptor_Curve.hxx>
30 #include <Precision.hxx>
31 #include <Extrema_ExtCC.hxx>
32 #include <Extrema_POnCurv.hxx>
33
34 #include <math_FunctionSample.hxx>
35 #include <math_FunctionAllRoots.hxx>
36 #include <TColgp_SequenceOfPnt.hxx>
37
38 //  Modified by skv - Tue Aug 31 12:13:51 2004 OCC569
39
40 #include <Precision.hxx>
41 #include <IntSurf_Quadric.hxx>
42
43 static void FindVertex (const TheArc&,
44                         const Handle(TheTopolTool)&,
45                         TheFunction&,
46                         IntStart_SequenceOfPathPoint&,
47                         const Standard_Real);
48
49                         
50 static void BoundedArc (const TheArc& A,
51                         const Handle(TheTopolTool)& Domain,
52                         const Standard_Real Pdeb,
53                         const Standard_Real Pfin,
54                         TheFunction& Func,
55                         IntStart_SequenceOfPathPoint& pnt,
56                         IntStart_SequenceOfSegment& seg,
57                         const Standard_Real TolBoundary,
58                         const Standard_Real TolTangency,
59                         Standard_Boolean& Arcsol,
60                         const Standard_Boolean RecheckOnRegularity);
61                  
62 static void PointProcess (const gp_Pnt&,
63                           const Standard_Real,
64                           const TheArc&,
65                           const Handle(TheTopolTool)&,
66                           IntStart_SequenceOfPathPoint&,
67                           const Standard_Real,
68                           Standard_Integer&);
69
70 static Standard_Integer TreatLC (const TheArc& A,
71                                  const Handle(TheTopolTool)& aDomain,
72                                  const IntSurf_Quadric& aQuadric,
73                                  const Standard_Real TolBoundary,
74                                  IntStart_SequenceOfPathPoint& pnt);
75
76 static Standard_Boolean IsRegularity(const TheArc& A,
77                                      const Handle(TheTopolTool)& aDomain);
78
79
80 //=======================================================================
81 //function : FindVertex
82 //purpose  : 
83 //=======================================================================
84 void FindVertex (const TheArc& A,
85                  const Handle(TheTopolTool)& Domain,
86                  TheFunction& Func,
87                  IntStart_SequenceOfPathPoint& pnt,
88                  const Standard_Real Toler) 
89 {
90
91 // Find the vertex of the arc A restriction solutions. It stores
92 // Vertex in the list solutions pnt.
93
94
95   TheVertex vtx;
96   Standard_Real param,valf;
97   Standard_Integer itemp;
98
99   Domain->Initialize(A);
100   Domain->InitVertexIterator();
101   while (Domain->MoreVertex()) {
102     vtx = Domain->Vertex();
103     param = TheSOBTool::Parameter(vtx,A);
104
105     // Evaluate the function and look compared to tolerance of the
106     // Vertex. If distance <= tolerance then add a vertex to the list of solutions.
107     // The arc is already assumed in the load function.
108
109     Func.Value(param,valf);
110     if (Abs(valf) <= Toler) {
111       itemp = Func.GetStateNumber();
112       pnt.Append(IntStart_ThePathPoint(Func.Valpoint(itemp),Toler, vtx,A,param));
113       // Solution is added
114     }
115     Domain->NextVertex();
116   }
117 }
118
119 static
120 void BoundedArc (const TheArc& A,
121                  const Handle(TheTopolTool)& Domain,
122                  const Standard_Real Pdeb,
123                  const Standard_Real Pfin,
124                  TheFunction& Func,
125                  IntStart_SequenceOfPathPoint& pnt,
126                  IntStart_SequenceOfSegment& seg,
127                  const Standard_Real TolBoundary,
128                  const Standard_Real TolTangency,
129                  Standard_Boolean& Arcsol,
130                  const Standard_Boolean RecheckOnRegularity)
131 {
132   
133 // Recherche des points solutions et des bouts d arc solution sur un arc donne.
134 // On utilise la fonction math_FunctionAllRoots. Ne convient donc que pour
135 // des arcs ayant un point debut et un point de fin (intervalle ferme de
136 // parametrage).
137
138   Standard_Integer i,Nbi,Nbp;
139
140   gp_Pnt ptdeb,ptfin;
141   Standard_Real pardeb = 0., parfin = 0.;
142   Standard_Integer ideb,ifin,range,ranged,rangef;
143   
144
145   // Creer l echantillonage (math_FunctionSample ou classe heritant)
146   // Appel a math_FunctionAllRoots
147
148   Standard_Real EpsX = TheArcTool::Resolution(A,Precision::Confusion());
149   //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
150   //@@@ La Tolerance est asociee a l arc  ( Incoherence avec le cheminement )
151   //@@@   ( EpsX ~ 1e-5   et ResolutionU et V ~ 1e-9 )
152   //@@@   le vertex trouve ici n'est pas retrouve comme point d arret d une 
153   //@@@   ligne de cheminement
154   //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
155   EpsX = 0.0000000001;
156   //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
157   //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
158   //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
159   
160 //  Standard_Integer NbEchant = TheSOBTool::NbSamplesOnArc(A); 
161   Standard_Integer NbEchant = Func.NbSamples(); 
162   
163   //-- Modif 24  Aout 93 -----------------------------
164   Standard_Real nTolTangency = TolTangency;
165   if((Pfin - Pdeb) < (TolTangency*10.0)) { 
166     nTolTangency=(Pfin-Pdeb)*0.1;
167   }   
168   if(EpsX>(nTolTangency+nTolTangency)) { 
169     EpsX = nTolTangency * 0.1; 
170   }
171   //--------------------------------------------------
172   //-- Plante avec un edge avec 2 Samples  
173   //-- dont les extremites son solutions (f=0) 
174   //-- et ou la derivee est nulle 
175   //-- Exemple : un segment diametre d une sphere
176   //-- if(NbEchant<3) NbEchant = 3; //-- lbr le 19 Avril 95
177   //--------------------------------------------------
178   Standard_Real para=0,dist,maxdist;
179 /*  if(NbEchant<20) NbEchant = 20; //-- lbr le 22 Avril 96 
180                                  //-- Toujours des pbs 
181 */
182    if(NbEchant<100) NbEchant = 100; //-- lbr le 22 Avril 96 
183                                   //-- Toujours des pbs 
184
185
186   //-------------------------------------------------------------- REJECTIONS le 15 oct 98 
187   Standard_Boolean Rejection=Standard_True;  
188   Standard_Real maxdr,maxr,minr,ur,dur;
189   minr=RealLast();
190   maxr=-minr;
191   maxdr=-minr;
192   dur=(Pfin-Pdeb)*0.2;
193   for(i=1,ur=Pdeb;i<=6;i++) { 
194     Standard_Real F,D;
195     if(Func.Values(ur,F,D)) { 
196       Standard_Real lminr,lmaxr;
197       if(D<0.0) D=-D;
198       D*=dur+dur;
199       if(D>maxdr) maxdr=D;
200       lminr=F-D;
201       lmaxr=F+D;
202       if(lminr<minr) minr=lminr;
203       if(lmaxr>maxr) maxr=lmaxr;
204       if(minr<0.0 && maxr>0.0)  {
205         Rejection=Standard_False;
206         break;
207       }
208     }
209     ur+=dur;
210   }
211   if(Rejection)
212   {
213     dur=0.001+maxdr+(maxr-minr)*0.1;
214     minr-=dur;
215     maxr+=dur;
216     if(minr<0.0 && maxr>0.0)  {         
217       Rejection=Standard_False;
218     }
219   }
220
221   Arcsol=Standard_False;
222
223   if(Rejection==Standard_False) { 
224     math_FunctionSample Echant(Pdeb,Pfin,NbEchant);
225     
226     Standard_Boolean aelargir=Standard_True;
227     //modified by NIZNHY-PKV Thu Apr 12 09:25:19 2001 f
228     //
229     //maxdist = 100.0*TolBoundary;
230     maxdist = TolBoundary+TolTangency;
231     //
232     //modified by NIZNHY-PKV Thu Apr 12 09:25:23 2001 t
233     for(i=1; i<=NbEchant && aelargir;i++) { 
234       Standard_Real u = Echant.GetParameter(i);
235       if(Func.Value(u,dist)) { 
236         if(dist>maxdist || -dist>maxdist) {
237           aelargir=Standard_False;
238         }
239       }
240     }
241     if(!(aelargir && maxdist<0.01)) { 
242       maxdist = TolBoundary;
243     }
244     
245     math_FunctionAllRoots Sol(Func,Echant,EpsX,maxdist,maxdist); //-- TolBoundary,nTolTangency);
246     
247     if (!Sol.IsDone()) {Standard_Failure::Raise();}
248     
249     Nbp=Sol.NbPoints();
250     //
251     //jgv: build solution on the whole boundary
252     if (RecheckOnRegularity && Nbp > 0 && IsRegularity(A, Domain))
253     {
254       //Standard_Real theTol = Domain->MaxTolerance(A);
255       //theTol += theTol;
256       Standard_Real theTol = 5.e-4;
257       math_FunctionAllRoots SolAgain(Func,Echant,EpsX,theTol,theTol); //-- TolBoundary,nTolTangency);
258       
259       if (!SolAgain.IsDone()) {Standard_Failure::Raise();}
260       
261       Standard_Integer Nbi_again = SolAgain.NbIntervals();
262       
263       if (Nbi_again > 0)
264       {
265         Standard_Integer NbSamples = 10;
266         Standard_Real delta = (Pfin - Pdeb)/NbSamples;
267         Standard_Real GlobalTol = theTol*10;
268         Standard_Boolean SolOnBoundary = Standard_True;
269         for (i = 0; i <= NbSamples; i++)
270         {
271           Standard_Real aParam = Pdeb + i*delta;
272           Standard_Real aValue;
273           Func.Value(aParam, aValue);
274           if (Abs(aValue) > GlobalTol)
275           {
276             SolOnBoundary = Standard_False;
277             break;
278           }
279         }
280
281         if (SolOnBoundary)
282         {
283           for (i = 1; i <= Nbi_again; i++)
284           {
285             IntStart_TheSegment newseg;
286             newseg.SetValue(A);
287             // Recuperer point debut et fin, et leur parametre.
288             SolAgain.GetInterval(i,pardeb,parfin);
289             
290             if (Abs(pardeb - Pdeb) <= Precision::PConfusion())
291               pardeb = Pdeb;
292             if (Abs(parfin - Pfin) <= Precision::PConfusion())
293               parfin = Pfin;
294             
295             SolAgain.GetIntervalState(i,ideb,ifin);
296             
297             //-- cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx : i= "<<i<<" ParDeb:"<<pardeb<<"  ParFin:"<<parfin<<endl;
298             
299             ptdeb=Func.Valpoint(ideb);
300             ptfin=Func.Valpoint(ifin);
301           
302             PointProcess(ptdeb,pardeb,A,Domain,pnt,theTol,ranged);
303             newseg.SetLimitPoint(pnt.Value(ranged),Standard_True);
304             PointProcess(ptfin,parfin,A,Domain,pnt,theTol,rangef);
305             newseg.SetLimitPoint(pnt.Value(rangef),Standard_False);
306             seg.Append(newseg);
307           }
308           Arcsol=Standard_True;
309           return;
310         }
311       }
312     }
313     ////////////////////////////////////////////
314     
315     //-- detection du cas ou la fonction est quasi tangente et que les 
316     //-- zeros sont quasi confondus. 
317     //-- Dans ce cas on prend le point "milieu"
318     //-- On suppose que les solutions sont triees. 
319
320     Standard_Real *TabSol=NULL;
321     if(Nbp) { 
322       TabSol = new Standard_Real [Nbp+2];
323       for(i=1;i<=Nbp;i++) { 
324         TabSol[i]=Sol.GetPoint(i);
325       }
326       Standard_Boolean ok;
327       do { 
328         ok=Standard_True;
329         for(i=1;i<Nbp;i++) { 
330           if(TabSol[i]>TabSol[i+1]) { 
331             ok=Standard_False;
332             para=TabSol[i]; TabSol[i]=TabSol[i+1]; TabSol[i+1]=para;
333           }
334         }
335       }
336       
337       while(ok==Standard_False);
338       //modified by NIZNHY-PKV Wed Mar 21 18:34:18 2001 f
339       //////////////////////////////////////////////////////////
340       // The treatment of the situation when line(arc) that is 
341       // tangent to cylinder(domain). 
342       // We should have only one solution i.e Nbp=1. Ok?
343       // But we have 2,3,.. solutions.     That is wrong ersult.
344       // The TreatLC(...) function is dedicated to solve the pb.
345       //                           PKV Fri Mar 23 12:17:29 2001
346       Standard_Integer ip;
347       const IntSurf_Quadric& aQuadric=Func.Quadric();
348       
349       ip=TreatLC (A, Domain, aQuadric, TolBoundary, pnt);
350       if (ip) {
351       //////////////////////////////////////////////////////////
352       //modified by NIZNHY-PKV Wed Mar 21 18:34:23 2001 t
353       // 
354       // Using of old usual way proposed by Laurent 
355       //
356       for(i=1;i<Nbp;i++) { 
357         Standard_Real parap1=TabSol[i+1];
358         para=TabSol[i];
359         Standard_Real param=(para+parap1)*0.5;
360         Standard_Real ym;
361         if(Func.Value(param,ym)) {
362           if(Abs(ym)<maxdist) { 
363             //  Modified by skv - Tue Aug 31 12:13:51 2004 OCC569 Begin
364             // Consider this interval as tangent one. Treat it to find
365             // parameter with the lowest function value.
366
367             // Compute the number of nodes.
368             Standard_Real    aTol = TolBoundary*1000.0;
369             if(aTol > 0.001)
370         aTol = 0.001;
371
372             // fix floating point exception 569, chl-922-e9
373             parap1 = (Abs(parap1) < 1.e9) ? parap1 : ((parap1 >= 0.) ? 1.e9 : -1.e9);
374             para   = (Abs(para) < 1.e9) ? para : ((para >= 0.) ? 1.e9 : -1.e9);
375             
376             Standard_Integer aNbNodes = RealToInt(Ceiling((parap1 - para)/aTol));
377
378             Standard_Real    aVal     = RealLast();
379             //Standard_Integer aNbNodes = 23;
380             Standard_Real    aDelta   = (parap1 - para)/(aNbNodes + 1.);
381             Standard_Integer ii;
382             Standard_Real    aCurPar;
383             Standard_Real    aCurVal;
384
385             for (ii = 0; ii <= aNbNodes + 1; ii++) {
386         aCurPar = (ii < aNbNodes + 1) ? para + ii*aDelta : parap1;
387
388         if (Func.Value(aCurPar, aCurVal)) {
389           //if (aCurVal < aVal) {
390           if (Abs(aCurVal) < aVal) {
391             //aVal  = aCurVal;
392             aVal  = Abs(aCurVal);
393             param = aCurPar;
394           }
395         }
396             }
397             //  Modified by skv - Tue Aug 31 12:13:51 2004 OCC569 End
398             TabSol[i]=Pdeb-1;
399             TabSol[i+1]=param;
400           }
401         }
402       }
403           
404       for (i=1; i<=Nbp; i++) {
405         para=TabSol[i];
406         if((para-Pdeb)<EpsX || (Pfin-para)<EpsX) { 
407         }
408         else { 
409           if(Func.Value(para,dist)) {
410             //modified by jgv 5.07.01 for the bug buc60927
411             Standard_Integer anIndx;
412             Standard_Real aParam;
413             if (Abs(dist) < maxdist)
414         {
415           aParam = Sol.GetPoint(i);
416           if (Abs(aParam-Pdeb)<=Precision::PConfusion() || Abs(aParam-Pfin)<=Precision::PConfusion())
417             anIndx = Sol.GetPointState(i);
418           else
419             {
420               anIndx = Func.GetStateNumber(); //take the middle point
421               aParam = para;
422             }
423         }
424             else
425         {
426           anIndx = Sol.GetPointState(i);
427           aParam = Sol.GetPoint(i);
428         }
429             const gp_Pnt& aPnt = Func.Valpoint(anIndx);
430             //////////////////////////////////////////////
431
432             PointProcess(aPnt, aParam, A, Domain, pnt, TolBoundary, range);
433           }
434         }
435       }
436       
437       if(TabSol) { 
438         delete [] TabSol;
439       }
440       }// end ofif (ip)
441     } // end of if(Nbp)  
442
443     // Pour chaque intervalle trouve faire
444     //   Traiter les extremites comme des points
445     //   Ajouter intervalle dans la liste des segments
446     
447     Nbi=Sol.NbIntervals();
448
449
450     if (!RecheckOnRegularity && Nbp) { 
451       //--cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx :Nbp>0  0 <- Nbi "<<Nbi<<endl;
452       Nbi=0; 
453     }
454
455     //-- cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx : Nbi : "<<Nbi<<endl;
456     
457     for (i=1; i<=Nbi; i++) {
458       IntStart_TheSegment newseg;
459       newseg.SetValue(A);
460       // Recuperer point debut et fin, et leur parametre.
461       Sol.GetInterval(i,pardeb,parfin);
462       Sol.GetIntervalState(i,ideb,ifin);
463
464
465       //-- cout<<" Debug : IntStart_SearchOnBoundaries_1.gxx : i= "<<i<<" ParDeb:"<<pardeb<<"  ParFin:"<<parfin<<endl;
466
467       ptdeb=Func.Valpoint(ideb);
468       ptfin=Func.Valpoint(ifin);
469       
470       PointProcess(ptdeb,pardeb,A,Domain,pnt,TolBoundary,ranged);
471       newseg.SetLimitPoint(pnt.Value(ranged),Standard_True);
472       PointProcess(ptfin,parfin,A,Domain,pnt,TolBoundary,rangef);
473       newseg.SetLimitPoint(pnt.Value(rangef),Standard_False);
474       seg.Append(newseg);
475     }
476
477     if (Nbi==1) {
478       if (  (Abs(pardeb - Pdeb) < Precision::PConfusion()) &&
479             (Abs(parfin - Pfin) < Precision::PConfusion()))
480       {
481         Arcsol=Standard_True;
482       }
483     }
484   }
485 }
486
487 //=======================================================================
488 //function : ComputeBoundsfromInfinite
489 //purpose  : 
490 //=======================================================================
491 // - PROVISIONAL - TEMPORARY - NOT GOOD - NYI - TO DO
492 // - Temporary - temporary - not good - nyi - to do
493 void ComputeBoundsfromInfinite(TheFunction& Func,
494                                Standard_Real& PDeb,
495                                Standard_Real& PFin,
496                                Standard_Integer& NbEchant) 
497
498   
499   // - We are looking for parameters for start and end of the arc (2d curve)
500   // - Infinity, a way to intersect the quadric with a portion of arc
501   // - Finished.
502   //
503   // - The quadric is a plane, a cylinder, a cone and a sphere.
504   // - Idea: We take any point on the arc and the fact grow
505   // - Terminals to the signed distance function values or is likely
506   // - S cancel.
507   //
508   // - WARNING: The following calculations provide a very estimated coarse parameters.
509   // - This avoids the raises and allows a case of Boxes
510   // - Inifinies walk. It will take this code
511   // - With curve surface intersections.
512
513   NbEchant = 100;
514
515   Standard_Real U0    = 0.0;
516   Standard_Real dU    = 0.001;
517   Standard_Real Dist0,Dist1;
518
519   Func.Value(U0   , Dist0);
520   Func.Value(U0+dU, Dist1);
521   Standard_Real dDist = Dist1 - Dist0;
522   if(dDist) { 
523     U0  -=  dU*Dist0 / dDist;
524     PDeb = PFin = U0;
525     Standard_Real Umin = U0 - 1e5;
526     Func.Value(Umin   , Dist0);
527     Func.Value(Umin+dU, Dist1);
528     dDist = Dist1-Dist0;
529     if(dDist) { 
530       Umin  -=  dU*Dist0 / dDist;
531     }
532     else { 
533       Umin-=10.0; 
534     }
535     Standard_Real Umax = U0 + 1e8;
536     Func.Value(Umax   , Dist0);
537     Func.Value(Umax+dU, Dist1);
538     dDist = Dist1-Dist0;
539     if(dDist) { 
540       Umax  -=  dU*Dist0 / dDist;
541     }
542     else { 
543       Umax+=10.0; 
544     }
545     if(Umin>U0) { Umin=U0-10.0; } 
546     if(Umax<U0) { Umax=U0+10.0; } 
547     
548     PFin = Umax + 10. * (Umax - Umin);
549     PDeb = Umin - 10. * (Umax - Umin);
550   }
551   else { 
552     //-- Possibilite de Arc totalement inclu ds Quad
553     PDeb = 1e10;
554     PFin = -1e10;
555   }
556
557
558 //=======================================================================
559 //function : PointProcess
560 //purpose  : 
561 //=======================================================================
562 void PointProcess (const gp_Pnt& Pt,
563                    const Standard_Real Para,
564                    const TheArc& A,
565                    const Handle(TheTopolTool)& Domain,
566                    IntStart_SequenceOfPathPoint& pnt,
567                    const Standard_Real Tol,
568                    Standard_Integer& Range) 
569 {
570
571 // Check to see if a solution point is coincident with a vertex.
572 // If confused, you should find this vertex in the list of
573 // Start. It then returns the position of this point in the list pnt.
574 // Otherwise, add the point in the list.
575   
576   Standard_Integer k;
577   Standard_Boolean found,goon;
578   Standard_Real dist,toler;
579
580   Standard_Integer Nbsol = pnt.Length();
581   TheVertex vtx;
582   IntStart_ThePathPoint ptsol;
583
584   Domain->Initialize(A);
585   Domain->InitVertexIterator();
586   found = Standard_False;
587   goon = Domain->MoreVertex();
588   while (goon) {
589     vtx = Domain->Vertex();
590     dist= Abs(Para-TheSOBTool::Parameter(vtx,A));
591     toler = TheSOBTool::Tolerance(vtx,A);
592 #ifdef OCCT_DEBUG
593     if(toler>0.1) { 
594       cout<<"IntStart_SearchOnBoundaries_1.gxx  : ** WARNING ** Tol Vertex="<<toler<<endl;
595       cout<<"                                     Ou Edge degenere Ou Kro pointu"<<endl;
596       if(toler>10000) toler=1e-7;
597     }
598 #endif
599
600     if (dist <= toler) {
601       // Locate the vertex in the list of solutions
602       k=1;
603       found = (k>Nbsol);
604       while (!found) {
605         ptsol = pnt.Value(k);
606         if (!ptsol.IsNew()) {
607         //jag 940608  if (ptsol.Vertex() == vtx && ptsol.Arc()    == A) {
608           if (Domain->Identical(ptsol.Vertex(),vtx) &&
609                     ptsol.Arc()    == A &&
610                     Abs(ptsol.Parameter()-Para) <= toler) {
611             found=Standard_True;
612           }
613           else {
614             k=k+1;
615             found=(k>Nbsol);
616           }
617         }
618         else {
619           k=k+1;
620           found=(k>Nbsol);
621         }
622       }
623       if (k<=Nbsol) {     // We find the vertex
624         Range = k;
625       }
626       else {              // Otherwise
627         ptsol.SetValue(Pt,Tol,vtx,A,Para);
628         pnt.Append(ptsol);
629         Range = pnt.Length();
630       }
631       found = Standard_True;
632       goon = Standard_False;
633     }
634     else {
635       Domain->NextVertex();
636       goon = Domain->MoreVertex();
637     }
638   }
639
640   if (!found) {   // No one is falling on a vertex
641     //jgv: do not add segment's extremities if they already exist
642     Standard_Boolean found_internal = Standard_False;
643     for (k = 1; k <= pnt.Length(); k++)
644     {
645       ptsol = pnt.Value(k);
646       if (ptsol.Arc() != A ||
647           !ptsol.IsNew()) //vertex
648         continue;
649       if (Abs(ptsol.Parameter()-Para) <= Precision::PConfusion())
650       {
651         found_internal = Standard_True;
652         Range = k;
653       }
654     }
655     /////////////////////////////////////////////////////////////
656
657     if (!found_internal)
658     {
659       Standard_Real TOL=Tol;
660       TOL*=1000.0; 
661       //if(TOL>0.001) TOL=0.001;
662       if(TOL>0.005) TOL=0.005; //#24643
663       
664       ptsol.SetValue(Pt,TOL,A,Para);
665       pnt.Append(ptsol);
666       Range = pnt.Length();
667     }
668   }
669 }
670
671 //=======================================================================
672 //function : IsRegularity
673 //purpose  : 
674 //=======================================================================
675 Standard_Boolean IsRegularity(const TheArc& /*A*/,
676                               const Handle(TheTopolTool)& aDomain)
677 {
678   Standard_Address anEAddress=aDomain->Edge();
679   if (anEAddress==NULL) {
680     return Standard_False;
681   }
682   
683   TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress;
684   
685   return (BRep_Tool::HasContinuity(*anE));
686 }
687
688 //=======================================================================
689 //function : TreatLC
690 //purpose  : 
691 //=======================================================================
692 Standard_Integer TreatLC (const TheArc& A,
693                           const Handle(TheTopolTool)& aDomain,
694                           const IntSurf_Quadric& aQuadric,
695                           const Standard_Real TolBoundary,
696                           IntStart_SequenceOfPathPoint& pnt)
697 {
698   Standard_Integer anExitCode=1, aNbExt;
699   
700   Standard_Address anEAddress=aDomain->Edge();
701   if (anEAddress==NULL) {
702     return anExitCode;
703   }
704   
705   TopoDS_Edge* anE=(TopoDS_Edge*)anEAddress;
706
707   if (BRep_Tool::Degenerated(*anE)) {
708     return anExitCode;
709   }
710   
711   GeomAbs_CurveType   aTypeE;
712   BRepAdaptor_Curve aBAC(*anE);
713   aTypeE=aBAC.GetType();
714   
715   if (aTypeE!=GeomAbs_Line) {
716     return anExitCode;
717   }
718   
719   GeomAbs_SurfaceType aTypeS;
720   aTypeS=aQuadric.TypeQuadric();
721   
722   if (aTypeS!=GeomAbs_Cylinder) {
723     return anExitCode;
724   }
725   
726   Standard_Real f, l, U1f, U1l, U2f, U2l, UEgde, TOL, aDist, aR, aRRel, Tol;
727   Handle(Geom_Curve) aCEdge=BRep_Tool::Curve(*anE, f, l);
728   
729   gp_Cylinder aCyl=aQuadric.Cylinder();
730   const gp_Ax1& anAx1=aCyl.Axis();
731   gp_Lin aLin(anAx1);
732   Handle(Geom_Line) aCAxis=new Geom_Line (aLin);
733   aR=aCyl.Radius();
734   
735   U1f = aCAxis->FirstParameter();
736   U1l = aCAxis->LastParameter();
737   
738   U2f = aCEdge->FirstParameter();
739   U2l = aCEdge->LastParameter();
740   
741
742   GeomAdaptor_Curve C1, C2;
743   
744   C1.Load(aCAxis);
745   C2.Load(aCEdge);
746   
747   Tol = Precision::PConfusion();
748
749   Extrema_ExtCC anExtCC(C1, C2, U1f, U1l, U2f, U2l, Tol, Tol); 
750
751   aNbExt=anExtCC.NbExt();
752   if (aNbExt!=1) {
753     return anExitCode;
754   }
755
756   gp_Pnt P1,PEdge;
757   Extrema_POnCurv PC1, PC2;
758   
759   anExtCC.Points(1, PC1, PC2);
760   
761   P1   =PC1.Value();
762   PEdge=PC2.Value();
763   
764   UEgde=PC2.Parameter();
765   
766   aDist=PEdge.Distance(P1);
767   aRRel=fabs(aDist-aR)/aR;
768   if (aRRel > TolBoundary) {
769     return anExitCode;
770   }
771
772   if (UEgde < (f+TolBoundary) || UEgde > (l-TolBoundary)) {
773     return anExitCode;
774   }
775   //
776   // Do not wonder !
777   // It was done as into PointProcess(...) function 
778   //printf("TreatLC()=> tangent line is found\n");
779   TOL=1000.*TolBoundary;
780   if(TOL>0.001) TOL=0.001;
781   
782   IntStart_ThePathPoint ptsol;
783   ptsol.SetValue(PEdge, TOL, A, UEgde);
784   pnt.Append(ptsol);
785
786   anExitCode=0;
787   return anExitCode;
788
789 }
790
791
792 //=======================================================================
793 //function : IntStart_SearchOnBoundaries::IntStart_SearchOnBoundaries
794 //purpose  : 
795 //=======================================================================
796 IntStart_SearchOnBoundaries::IntStart_SearchOnBoundaries ()
797 :  done(Standard_False) 
798 {
799 }  
800
801 //=======================================================================
802 //function : Perform
803 //purpose  : 
804 //=======================================================================
805   void IntStart_SearchOnBoundaries::Perform (TheFunction& Func,
806                                              const Handle(TheTopolTool)& Domain,
807                                              const Standard_Real TolBoundary,
808                                              const Standard_Real TolTangency,
809                                              const Standard_Boolean RecheckOnRegularity)
810 {
811   
812   done = Standard_False;
813   spnt.Clear();
814   sseg.Clear();
815
816   Standard_Boolean Arcsol;
817   Standard_Real PDeb,PFin, prm, tol;
818   Standard_Integer i, nbknown, nbfound,index;
819   gp_Pnt pt;
820   
821   Domain->Init();
822
823   if (Domain->More()) {
824     all  = Standard_True;
825   }
826   else {
827     all = Standard_False;
828   }
829
830   while (Domain->More()) {
831     TheArc A = Domain->Value();
832     if (!TheSOBTool::HasBeenSeen(A)) {
833       Func.Set(A);
834       FindVertex(A,Domain,Func,spnt,TolBoundary);
835       TheSOBTool::Bounds(A,PDeb,PFin);
836       if(Precision::IsNegativeInfinite(PDeb) || 
837          Precision::IsPositiveInfinite(PFin)) { 
838         Standard_Integer NbEchant;
839         ComputeBoundsfromInfinite(Func,PDeb,PFin,NbEchant);
840       }
841       BoundedArc(A,Domain,PDeb,PFin,Func,spnt,sseg,TolBoundary,TolTangency,Arcsol,RecheckOnRegularity);
842       all = (all && Arcsol);
843     }
844     
845     else {
846       // as it seems we'll never be here, because 
847       // TheSOBTool::HasBeenSeen(A) always returns FALSE
848       nbfound = spnt.Length();
849
850       // On recupere les points connus
851       nbknown = TheSOBTool::NbPoints(A);
852       for (i=1; i<=nbknown; i++) {
853         TheSOBTool::Value(A,i,pt,tol,prm);
854         if (TheSOBTool::IsVertex(A,i)) {
855           TheVertex vtx;
856           TheSOBTool::Vertex(A,i,vtx);
857           spnt.Append(IntStart_ThePathPoint(pt,tol,vtx,A,prm));
858         }
859         else {
860           spnt.Append(IntStart_ThePathPoint(pt,tol,A,prm));
861         }
862       }
863       // On recupere les arcs solutions
864       nbknown = TheSOBTool::NbSegments(A);
865       for (i=1; i<=nbknown; i++) {
866         IntStart_TheSegment newseg;
867         newseg.SetValue(A);
868         if (TheSOBTool::HasFirstPoint(A,i,index)) {
869           newseg.SetLimitPoint(spnt.Value(nbfound+index),Standard_True);
870         }
871         if (TheSOBTool::HasLastPoint(A,i,index)) {
872           newseg.SetLimitPoint(spnt.Value(nbfound+index),Standard_False);
873         }
874         sseg.Append(newseg);
875       }
876       all = (all& TheSOBTool::IsAllSolution(A));
877     }
878     Domain->Next();
879   }
880   done = Standard_True;
881 }