0026674: Performance regression in BRepExtrema_DistShapeShape in OCCT 6.9.0 in compar...
[occt.git] / src / Extrema / Extrema_ExtCC2d.cxx
1 // Created on: 1994-07-06
2 // Created by: Laurent PAINNOT
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <Adaptor2d_Curve2d.hxx>
19 #include <ElCLib.hxx>
20 #include <Extrema_Curve2dTool.hxx>
21 #include <Extrema_ECC2d.hxx>
22 #include <Extrema_ExtCC2d.hxx>
23 #include <Extrema_ExtElC.hxx>
24 #include <Extrema_ExtElC2d.hxx>
25 #include <Extrema_POnCurv2d.hxx>
26 #include <Extrema_SequenceOfPOnCurv2d.hxx>
27 #include <Geom2d_Circle.hxx>
28 #include <Geom2d_Curve.hxx>
29 #include <Geom2d_Ellipse.hxx>
30 #include <Geom2d_Hyperbola.hxx>
31 #include <Geom2d_Line.hxx>
32 #include <Geom2d_Parabola.hxx>
33 #include <Geom2d_TrimmedCurve.hxx>
34 #include <GeomAbs_CurveType.hxx>
35 #include <gp_Pnt2d.hxx>
36 #include <Precision.hxx>
37 #include <Standard_Failure.hxx>
38 #include <Standard_NotImplemented.hxx>
39 #include <Standard_OutOfRange.hxx>
40 #include <StdFail_InfiniteSolutions.hxx>
41 #include <StdFail_NotDone.hxx>
42
43 Extrema_ExtCC2d::Extrema_ExtCC2d()
44 : myIsFindSingleSolution(Standard_False)
45 {
46 }
47
48
49 Extrema_ExtCC2d::Extrema_ExtCC2d(const Adaptor2d_Curve2d&       C1,
50                                  const Adaptor2d_Curve2d&       C2,
51                                  const Standard_Real TolC1,
52                                  const Standard_Real TolC2)
53 : myIsFindSingleSolution(Standard_False)
54 {
55   Initialize(C2, Extrema_Curve2dTool::FirstParameter(C2), Extrema_Curve2dTool::LastParameter(C2), TolC1, TolC2);
56   Perform(C1, Extrema_Curve2dTool::FirstParameter(C1), Extrema_Curve2dTool::LastParameter(C1));
57 }
58
59 Extrema_ExtCC2d::Extrema_ExtCC2d(const Adaptor2d_Curve2d&        C1, 
60                                  const Adaptor2d_Curve2d&        C2,
61                                  const Standard_Real  U1,
62                                  const Standard_Real  U2,
63                                  const Standard_Real  V1,
64                                  const Standard_Real  V2,
65                                  const Standard_Real  TolC1,
66                                  const Standard_Real  TolC2)
67 : myIsFindSingleSolution(Standard_False)
68 {
69   Initialize(C2, V1, V2, TolC1, TolC2);
70   Perform(C1, U1, U2);
71 }
72
73
74
75 void Extrema_ExtCC2d::Initialize(const Adaptor2d_Curve2d&        C2,
76                                   const Standard_Real  V1,
77                                   const Standard_Real  V2,
78                                   const Standard_Real  TolC1,
79                                   const Standard_Real  TolC2)
80 {
81   myC = (Standard_Address)&C2;
82   myv1 = V1;
83   myv2 = V2;
84   mytolc1 = TolC1;
85   mytolc2 = TolC2;
86 }
87
88
89
90 void Extrema_ExtCC2d::Perform (const Adaptor2d_Curve2d&       C1,
91                                 const Standard_Real U1,
92                                 const Standard_Real U2)
93 {
94   mypoints.Clear();
95   mySqDist.Clear();
96   GeomAbs_CurveType type1 = Extrema_Curve2dTool::GetType(C1), type2 = Extrema_Curve2dTool::GetType(*((Adaptor2d_Curve2d*)myC));
97   Standard_Real U11, U12, U21, U22, Tol = Min(mytolc1, mytolc2);
98 //  Extrema_POnCurv2d P1, P2;
99   mynbext = 0;
100   inverse = Standard_False;
101   myIsPar = Standard_False;
102
103   U11 = U1;
104   U12 = U2;
105   U21 = myv1;
106   U22 = myv2;
107   P1f = Extrema_Curve2dTool::Value(C1, U11);
108   P1l = Extrema_Curve2dTool::Value(C1, U12);
109   P2f = Extrema_Curve2dTool::Value(*((Adaptor2d_Curve2d*)myC), U21);
110   P2l = Extrema_Curve2dTool::Value(*((Adaptor2d_Curve2d*)myC), U22);
111
112
113   switch(type1) {
114     //
115     //  La premiere courbe est un cercle:
116     //
117   case GeomAbs_Circle: {
118
119     switch(type2) {
120       case GeomAbs_Circle: {
121         Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Circle(C1), Extrema_Curve2dTool::Circle(*((Adaptor2d_Curve2d*)myC)));
122         Results(Xtrem, U11, U12, U21, U22, 2*M_PI, 2*M_PI);
123         }
124         break;
125       case GeomAbs_Ellipse: {
126         Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Circle(C1), Extrema_Curve2dTool::Ellipse(*((Adaptor2d_Curve2d*)myC)));
127         Results(Xtrem, U11, U12, U21, U22, 2*M_PI, 2*M_PI );
128         }
129         break;
130       case GeomAbs_Parabola: {
131         Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Circle(C1), Extrema_Curve2dTool::Parabola(*((Adaptor2d_Curve2d*)myC)));
132         Results(Xtrem, U11, U12, U21, U22, 2*M_PI, 0.);
133       }
134         break;
135       case GeomAbs_Hyperbola: {
136         Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Circle(C1), Extrema_Curve2dTool::Hyperbola(*((Adaptor2d_Curve2d*)myC)));
137         Results(Xtrem, U11, U12, U21, U22, 2*M_PI, 0. );
138       }
139         break;
140       case GeomAbs_BezierCurve:
141       case GeomAbs_OtherCurve:
142       case GeomAbs_BSplineCurve: {
143           Extrema_ECC2d aParamSolver(C1, *((Adaptor2d_Curve2d*)myC));
144           aParamSolver.SetSingleSolutionFlag(GetSingleSolutionFlag());
145           aParamSolver.Perform();
146           Standard_Real Period2 = 0.;
147           if (Extrema_Curve2dTool::IsPeriodic(*((Adaptor2d_Curve2d*)myC))) Period2 = Extrema_Curve2dTool::Period(*((Adaptor2d_Curve2d*)myC));
148           Results(aParamSolver, U11, U12, U21, U22, 2*M_PI,Period2);
149         }
150         break;
151       case GeomAbs_Line: {
152         inverse = Standard_True;
153         Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Line(*((Adaptor2d_Curve2d*)myC)), Extrema_Curve2dTool::Circle(C1), Tol);
154         Results(Xtrem, U11, U12, U21, U22, 2*M_PI, 0.);
155         }
156         break;
157       };  // switch(type2)
158     }
159     break;
160
161     //
162     // La premiere courbe est une ellipse:
163     //
164   case GeomAbs_Ellipse: {
165
166     switch(type2) {
167       case GeomAbs_Circle: {
168         inverse = Standard_True;
169         Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Circle(*((Adaptor2d_Curve2d*)myC)), Extrema_Curve2dTool::Ellipse(C1));
170         Results(Xtrem, U11, U12, U21, U22, 2*M_PI, 2*M_PI);
171         }
172         break;
173       case GeomAbs_Ellipse:
174         {
175         Extrema_ECC2d aParamSolver(C1, *((Adaptor2d_Curve2d*)myC));
176         aParamSolver.SetSingleSolutionFlag(GetSingleSolutionFlag());
177         aParamSolver.Perform();
178         Results(aParamSolver, U11, U12, U21, U22,2*M_PI, 2*M_PI);
179         }
180         break;
181       case GeomAbs_Parabola: {
182         //Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Ellipse(C1), Extrema_Curve2dTool::Parabola(*((Adaptor2d_Curve2d*)myC)));
183         Extrema_ECC2d aParamSolver(C1, *((Adaptor2d_Curve2d*)myC));
184         aParamSolver.SetSingleSolutionFlag(GetSingleSolutionFlag());
185         aParamSolver.Perform();
186         Results(aParamSolver, U11, U12, U21, U22, 2*M_PI, 0.);
187       }
188         break;
189       case GeomAbs_Hyperbola: {
190         //Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Ellipse(C1), Extrema_Curve2dTool::Hyperbola(*((Adaptor2d_Curve2d*)myC)));
191         Extrema_ECC2d aParamSolver(C1, *((Adaptor2d_Curve2d*)myC));
192         aParamSolver.SetSingleSolutionFlag(GetSingleSolutionFlag());
193         aParamSolver.Perform();
194         Results(aParamSolver, U11, U12, U21, U22, 2*M_PI, 0.);
195       }
196         break;
197       case GeomAbs_BezierCurve:
198       case GeomAbs_OtherCurve:
199       case GeomAbs_BSplineCurve: {
200         Extrema_ECC2d aParamSolver(C1, *((Adaptor2d_Curve2d*)myC));
201         aParamSolver.SetSingleSolutionFlag(GetSingleSolutionFlag());
202         aParamSolver.Perform();
203         Standard_Real Period2 = 0.;
204         if (Extrema_Curve2dTool::IsPeriodic(*((Adaptor2d_Curve2d*)myC))) Period2 = Extrema_Curve2dTool::Period(*((Adaptor2d_Curve2d*)myC));
205         Results(aParamSolver, U11, U12, U21, U22, 2*M_PI,Period2);
206         }
207         break;
208       case GeomAbs_Line: {
209         inverse = Standard_True;
210         Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Line(*((Adaptor2d_Curve2d*)myC)), Extrema_Curve2dTool::Ellipse(C1));
211         Results(Xtrem, U11, U12, U21, U22, 2*M_PI, 0.);
212         }
213         break;
214       };  // switch(type2)
215     }
216     break;
217
218     //
219     // La premiere courbe est une parabole: 
220     //
221   case GeomAbs_Parabola: {
222
223     switch(type2) {
224       case GeomAbs_Circle: {
225         inverse = Standard_True;
226         Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Circle(*((Adaptor2d_Curve2d*)myC)), Extrema_Curve2dTool::Parabola(C1));
227         Results(Xtrem, U11, U12, U21, U22, 0., 2*M_PI);
228         }
229         break;
230       case GeomAbs_Ellipse: {
231         //inverse = Standard_True;
232         //Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Ellipse(*((Adaptor2d_Curve2d*)myC)), Extrema_Curve2dTool::Parabola(C1));
233         Extrema_ECC2d aParamSolver(C1, *((Adaptor2d_Curve2d*)myC));
234         aParamSolver.SetSingleSolutionFlag(GetSingleSolutionFlag());
235         aParamSolver.Perform();
236         Results(aParamSolver, U11, U12, U21, U22, 0., 2*M_PI);
237         }
238         break;
239       case GeomAbs_Parabola: {
240         //Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Parabola(C1), Extrema_Curve2dTool::Parabola(*((Adaptor2d_Curve2d*)myC)));
241         Extrema_ECC2d aParamSolver(C1, *((Adaptor2d_Curve2d*)myC));
242         aParamSolver.SetSingleSolutionFlag(GetSingleSolutionFlag());
243         aParamSolver.Perform();
244         Results(aParamSolver, U11, U12, U21, U22, 0., 0.);
245       }
246         break;
247       case GeomAbs_Hyperbola: {
248         //inverse = Standard_True;
249         //Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Hyperbola(*((Adaptor2d_Curve2d*)myC)), Extrema_Curve2dTool::Parabola(C1));
250         Extrema_ECC2d aParamSolver(C1, *((Adaptor2d_Curve2d*)myC));
251         aParamSolver.SetSingleSolutionFlag(GetSingleSolutionFlag());
252         aParamSolver.Perform();
253         Results(aParamSolver, U11, U12, U21, U22, 0., 0.);
254       }
255         break;
256       case GeomAbs_BezierCurve:
257       case GeomAbs_OtherCurve:
258       case GeomAbs_BSplineCurve: {
259         Extrema_ECC2d aParamSolver(C1, *((Adaptor2d_Curve2d*)myC));
260         aParamSolver.SetSingleSolutionFlag(GetSingleSolutionFlag());
261         aParamSolver.Perform();
262         Standard_Real Period2 = 0.;
263         if (Extrema_Curve2dTool::IsPeriodic(*((Adaptor2d_Curve2d*)myC))) Period2 = Extrema_Curve2dTool::Period(*((Adaptor2d_Curve2d*)myC));
264         Results(aParamSolver, U11, U12, U21, U22, 0., Period2);
265         }
266         break;
267       case GeomAbs_Line: {
268         inverse = Standard_True;
269         Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Line(*((Adaptor2d_Curve2d*)myC)), Extrema_Curve2dTool::Parabola(C1));
270         Results(Xtrem, U11, U12, U21, U22, 0., 0.);
271         }
272         break;
273       };  // switch(type2)
274     }
275     break;
276
277     //
278     // La premiere courbe est une hyperbole:
279     //
280   case GeomAbs_Hyperbola: {
281
282     switch(type2) {
283       case GeomAbs_Circle: {
284         inverse = Standard_True;
285         Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Circle(*((Adaptor2d_Curve2d*)myC)), Extrema_Curve2dTool::Hyperbola(C1));
286         Results(Xtrem, U11, U12, U21, U22, 0., 2*M_PI);
287         }
288         break;
289       case GeomAbs_Ellipse: {
290         //inverse = Standard_True;
291         //Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Ellipse(*((Adaptor2d_Curve2d*)myC)), Extrema_Curve2dTool::Hyperbola(C1));
292         Extrema_ECC2d aParamSolver(C1, *((Adaptor2d_Curve2d*)myC));
293         aParamSolver.SetSingleSolutionFlag(GetSingleSolutionFlag());
294         aParamSolver.Perform();
295         Results(aParamSolver, U11, U12, U21, U22, 0., 2*M_PI );
296         }
297         break;
298       case GeomAbs_Parabola: {
299         //Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Hyperbola(C1), Extrema_Curve2dTool::Parabola(*((Adaptor2d_Curve2d*)myC)));
300         Extrema_ECC2d aParamSolver(C1, *((Adaptor2d_Curve2d*)myC));
301         aParamSolver.SetSingleSolutionFlag(GetSingleSolutionFlag());
302         aParamSolver.Perform();
303         Results(aParamSolver, U11, U12, U21, U22, 0., 0.);
304       }
305         break;
306       case GeomAbs_Hyperbola: {
307         //Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Hyperbola(C1), Extrema_Curve2dTool::Hyperbola(*((Adaptor2d_Curve2d*)myC)));
308         Extrema_ECC2d aParamSolver(C1, *((Adaptor2d_Curve2d*)myC));
309         aParamSolver.SetSingleSolutionFlag(GetSingleSolutionFlag());
310         aParamSolver.Perform();
311         Results(aParamSolver, U11, U12, U21, U22, 0., 0.);
312       }
313         break;
314       case GeomAbs_OtherCurve:
315       case GeomAbs_BezierCurve:
316       case GeomAbs_BSplineCurve: {
317         Extrema_ECC2d aParamSolver(C1, *((Adaptor2d_Curve2d*)myC));
318         aParamSolver.SetSingleSolutionFlag(GetSingleSolutionFlag());
319         aParamSolver.Perform();
320         Standard_Real Period2 = 0.;
321         if (Extrema_Curve2dTool::IsPeriodic(*((Adaptor2d_Curve2d*)myC))) Period2 = Extrema_Curve2dTool::Period(*((Adaptor2d_Curve2d*)myC));
322         Results(aParamSolver, U11, U12, U21, U22, 0., Period2);
323         }
324         break;
325       case GeomAbs_Line: {
326         inverse = Standard_True;
327         Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Line(*((Adaptor2d_Curve2d*)myC)), Extrema_Curve2dTool::Hyperbola(C1));
328         Results(Xtrem, U11, U12, U21, U22, 0., 0.);
329         }
330         break;
331       };  // switch(type2)
332     }
333     break;
334
335     //
336     // La premiere courbe est une BezierCurve ou une BSplineCurve:
337     //
338   case GeomAbs_BezierCurve:
339   case GeomAbs_OtherCurve:
340   case GeomAbs_BSplineCurve: {
341     Extrema_ECC2d aParamSolver(C1, *((Adaptor2d_Curve2d*)myC));
342     aParamSolver.SetSingleSolutionFlag(GetSingleSolutionFlag());
343     aParamSolver.Perform();
344     Standard_Real Period1 = 0.;
345     if (Extrema_Curve2dTool::IsPeriodic(C1)) Period1 = Extrema_Curve2dTool::Period(C1);
346     Standard_Real Period2 = 0.;
347     if (Extrema_Curve2dTool::IsPeriodic(*((Adaptor2d_Curve2d*)myC))) Period2 = Extrema_Curve2dTool::Period(*((Adaptor2d_Curve2d*)myC));
348     Results(aParamSolver, U11, U12, U21, U22, Period1, Period2);
349   }
350   break;
351
352     //
353     // La premiere courbe est une Line:
354     //
355   case GeomAbs_Line: {
356
357     switch(type2) {
358       case GeomAbs_Circle: {
359         Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Line(C1), Extrema_Curve2dTool::Circle(*((Adaptor2d_Curve2d*)myC)), Tol);
360         Results(Xtrem, U11, U12, U21, U22, 0., 2*M_PI);
361         }
362         break;
363       case GeomAbs_Ellipse: {
364         Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Line(C1), Extrema_Curve2dTool::Ellipse(*((Adaptor2d_Curve2d*)myC)));
365         Results(Xtrem, U11, U12, U21, U22, 0., 2*M_PI);
366         }
367         break;
368       case GeomAbs_Parabola: {
369         Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Line(C1), Extrema_Curve2dTool::Parabola(*((Adaptor2d_Curve2d*)myC)));
370         Results(Xtrem, U11, U12, U21, U22, 0., 0.);
371       }
372         break;
373       case GeomAbs_Hyperbola: {
374         Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Line(C1), Extrema_Curve2dTool::Hyperbola(*((Adaptor2d_Curve2d*)myC)));
375         Results(Xtrem, U11, U12, U21, U22, 0., 0.);
376       }
377         break;
378       case GeomAbs_BezierCurve:
379       case GeomAbs_OtherCurve:
380       case GeomAbs_BSplineCurve: {
381         Extrema_ECC2d aParamSolver(C1, *((Adaptor2d_Curve2d*)myC));
382         aParamSolver.SetSingleSolutionFlag(GetSingleSolutionFlag());
383         aParamSolver.Perform();
384         Standard_Real Period2 = 0.;
385         if (Extrema_Curve2dTool::IsPeriodic(*((Adaptor2d_Curve2d*)myC))) Period2 = Extrema_Curve2dTool::Period(*((Adaptor2d_Curve2d*)myC));
386         Results(aParamSolver, U11, U12, U21, U22, 0., Period2);
387         }
388         break;
389       case GeomAbs_Line: {
390         Extrema_ExtElC2d Xtrem(Extrema_Curve2dTool::Line(C1), Extrema_Curve2dTool::Line(*((Adaptor2d_Curve2d*)myC)), Tol);
391         Results(Xtrem, U11, U12, U21, U22, 0., 0.);
392         } 
393         break;
394       };  // switch(type2)
395     }
396     break;
397
398   };
399     
400 }
401
402
403 Standard_Boolean Extrema_ExtCC2d::IsDone() const
404 {
405   return myDone;
406 }
407
408
409 Standard_Real Extrema_ExtCC2d::SquareDistance(const Standard_Integer N) const 
410 {
411   if(!myDone) StdFail_NotDone::Raise();
412   if ((N <= 0) || (N > mynbext)) Standard_OutOfRange::Raise();
413   return mySqDist.Value(N);
414 }
415
416
417 Standard_Integer Extrema_ExtCC2d::NbExt() const
418 {
419   if(!myDone) StdFail_NotDone::Raise();
420   return mynbext;
421 }
422
423
424 void Extrema_ExtCC2d::Points(const Standard_Integer N, 
425                               Extrema_POnCurv2d& P1,
426                               Extrema_POnCurv2d& P2) const
427 {
428   if(!myDone) StdFail_NotDone::Raise();
429   if ((N <= 0) || (N > mynbext)) Standard_OutOfRange::Raise();
430   P1 = mypoints.Value(2*N-1);
431   P2 = mypoints.Value(2*N);
432 }
433
434
435
436 void Extrema_ExtCC2d::TrimmedSquareDistances(Standard_Real& dist11,
437                                         Standard_Real& dist12,
438                                         Standard_Real& dist21,
439                                         Standard_Real& dist22,
440                                         gp_Pnt2d&      P11,
441                                         gp_Pnt2d&      P12,
442                                         gp_Pnt2d&      P21,
443                                         gp_Pnt2d&      P22) const 
444 {
445   dist11 = mydist11;
446   dist12 = mydist12;
447   dist21 = mydist21;
448   dist22 = mydist22;
449   P11 = P1f;
450   P12 = P1l;
451   P21 = P2f;
452   P22 = P2l;
453 }
454
455
456
457 void Extrema_ExtCC2d::Results(const Extrema_ExtElC2d&  AlgExt,
458                                const Standard_Real      Ut11,
459                                const Standard_Real      Ut12,
460                                const Standard_Real      Ut21,
461                                const Standard_Real      Ut22,
462                                const Standard_Real      Period1,
463                                const Standard_Real      Period2)
464 {
465   Standard_Integer i, NbExt;
466   Standard_Real Val, U, U2;
467   Extrema_POnCurv2d P1, P2;
468   
469   myDone = AlgExt.IsDone();
470   myIsPar = AlgExt.IsParallel();
471   if (myDone) {
472     if (!myIsPar) {
473       NbExt = AlgExt.NbExt();
474       for (i = 1; i <= NbExt; i++) {
475         // Verification de la validite des parametres pour le cas trimme:
476         AlgExt.Points(i, P1, P2);
477         if (!inverse) {
478           U = P1.Parameter();
479           if (Period1 != 0.0) U = ElCLib::InPeriod(U,Ut11,Ut11+Period1);
480           U2 = P2.Parameter();
481           if (Period2 != 0.0) U2 = ElCLib::InPeriod(U2,Ut21,Ut21+Period2);
482         }
483         else {
484           U2 = P1.Parameter();
485           if (Period2 != 0.0) U2 = ElCLib::InPeriod(U2,Ut21,Ut21+Period2);
486           U = P2.Parameter();
487           if (Period1 != 0.0) U = ElCLib::InPeriod(U,Ut11,Ut11+Period1);
488         }
489         if ((U  >= Ut11 - Precision::PConfusion())  && 
490             (U  <= Ut12 + Precision::PConfusion())  &&
491             (U2 >= Ut21 - Precision::PConfusion())  &&
492             (U2 <= Ut22 + Precision::PConfusion())) {
493           mynbext++;
494           Val = AlgExt.SquareDistance(i);
495           mySqDist.Append(Val);
496           if (!inverse) {
497             P1.SetValues(U, P1.Value());
498             P2.SetValues(U2, P2.Value());
499             mypoints.Append(P1);
500             mypoints.Append(P2);
501           }
502           else {
503             P1.SetValues(U2, P1.Value());
504             P2.SetValues(U, P2.Value());
505             mypoints.Append(P2);
506             mypoints.Append(P1);
507           }
508         }
509       }
510     }
511
512     mydist11 = P1f.SquareDistance(P2f);
513     mydist12 = P1f.SquareDistance(P2l);
514     mydist21 = P1l.SquareDistance(P2f);
515     mydist22 = P1l.SquareDistance(P2l);
516   }
517 }
518
519
520 void Extrema_ExtCC2d::Results(const Extrema_ECC2d& AlgExt,
521                               const Standard_Real  Ut11,
522                               const Standard_Real  Ut12,
523                               const Standard_Real  Ut21,
524                               const Standard_Real  Ut22,
525                               const Standard_Real  Period1,
526                               const Standard_Real  Period2)
527 {
528   Standard_Integer i, NbExt;
529   Standard_Real Val, U, U2;
530   Extrema_POnCurv2d P1, P2;
531
532   myDone = AlgExt.IsDone();
533   if (myDone)
534   {
535     myIsPar = AlgExt.IsParallel();
536     if (!myIsPar)
537     {
538       NbExt = AlgExt.NbExt();
539       for (i = 1; i <= NbExt; i++)
540       {
541         // Verification de la validite des parametres pour le cas trimme:
542         AlgExt.Points(i, P1, P2);
543         U = P1.Parameter();
544         if (Period1 != 0.0) 
545           U = ElCLib::InPeriod(U,Ut11,Ut11+Period1);
546         U2 = P2.Parameter();
547         if (Period2 != 0.0) 
548           U2 = ElCLib::InPeriod(U2,Ut21,Ut21+Period2);
549
550         if ((U  >= Ut11 - Precision::PConfusion())  && 
551             (U  <= Ut12 + Precision::PConfusion())  &&
552             (U2 >= Ut21 - Precision::PConfusion())  &&
553             (U2 <= Ut22 + Precision::PConfusion()))
554         {
555             mynbext++;
556             Val = AlgExt.SquareDistance(i);
557             P1.SetValues(U, P1.Value());
558             P2.SetValues(U2, P2.Value());
559             mySqDist.Append(Val);
560             mypoints.Append(P1);
561             mypoints.Append(P2);
562         }
563       }
564     }
565
566     mydist11 = P1f.SquareDistance(P2f);
567     mydist12 = P1f.SquareDistance(P2l);
568     mydist21 = P1l.SquareDistance(P2f);
569     mydist22 = P1l.SquareDistance(P2l);
570   }
571 }
572
573
574 Standard_Boolean Extrema_ExtCC2d::IsParallel() const
575 {
576   if (!myDone) StdFail_NotDone::Raise();
577   return myIsPar;
578 }
579
580 //=======================================================================
581 //function : SetSingleSolutionFlag
582 //purpose  : 
583 //=======================================================================
584 void Extrema_ExtCC2d::SetSingleSolutionFlag(const Standard_Boolean theFlag)
585 {
586   myIsFindSingleSolution = theFlag;
587 }
588
589 //=======================================================================
590 //function : GetSingleSolutionFlag
591 //purpose  : 
592 //=======================================================================
593 Standard_Boolean Extrema_ExtCC2d::GetSingleSolutionFlag() const
594 {
595   return myIsFindSingleSolution;
596 }