OCC22529 FitALL works incorrectly for small flat shapes
[occt.git] / src / Extrema / Extrema_GExtCC.gxx
CommitLineData
7fd59977 1// File: Extrema_GExtCC.gxx
2// Created: Wed Jul 6 10:14:26 1994
3// Author: Laurent PAINNOT
4// <lpa@metrox>
5
6// Modified by MPS (june 96) : correction du trap dans le cas droite/Bezier
7// Modified by MPS (mai 97) : PRO 7598
8// tri des solutions pour eviter de rendre plusieurs
9// fois la meme solution
10
11#include Extrema_ECC_hxx
12
13#include <StdFail_NotDone.hxx>
14#include <Extrema_ExtElC.hxx>
15#include <Standard_Failure.hxx>
16#include <GeomAbs_CurveType.hxx>
17#include <Geom_Curve.hxx>
18#include <Geom_TrimmedCurve.hxx>
19#include <Geom_Ellipse.hxx>
20#include <Geom_Circle.hxx>
21#include <Geom_Line.hxx>
22#include <Geom_Parabola.hxx>
23#include <Geom_Hyperbola.hxx>
24#include <Extrema_POnCurv.hxx>
25#include <Extrema_SequenceOfPOnCurv.hxx>
26#include <TColStd_SequenceOfReal.hxx>
27#include <TColStd_ListIteratorOfListOfTransient.hxx>
28#include <Standard_NotImplemented.hxx>
29#include <Precision.hxx>
30#include <TColStd_Array1OfReal.hxx>
31#include <ElCLib.hxx>
32#include <Extrema_ExtPElC.hxx>
33#include <Standard_NullObject.hxx>
34
35//=======================================================================
36//function : Extrema_GExtCC
37//purpose :
38//=======================================================================
39
40Extrema_GExtCC::Extrema_GExtCC (const Standard_Real TolC1,
41 const Standard_Real TolC2) :
42 myDone (Standard_False)
43{
44 myC[0] = 0; myC[1] = 0;
45 myTol[0] = TolC1; myTol[1] = TolC2;
46}
47
48//=======================================================================
49//function : Extrema_GExtCC
50//purpose :
51//=======================================================================
52
53Extrema_GExtCC::Extrema_GExtCC(const Curve1& C1,
54 const Curve2& C2,
55 const Standard_Real U1,
56 const Standard_Real U2,
57 const Standard_Real V1,
58 const Standard_Real V2,
59 const Standard_Real TolC1,
60 const Standard_Real TolC2) :
61 myDone (Standard_False)
62{
63 SetCurve (1, C1, U1, U2);
64 SetCurve (2, C2, V1, V2);
65 SetTolerance (1, TolC1);
66 SetTolerance (2, TolC2);
67 Perform();
68}
69
70
71//=======================================================================
72//function : Extrema_GExtCC
73//purpose :
74//=======================================================================
75
76Extrema_GExtCC::Extrema_GExtCC(const Curve1& C1,
77 const Curve2& C2,
78 const Standard_Real TolC1,
79 const Standard_Real TolC2) :
80 myDone (Standard_False)
81{
82 SetCurve (1, C1, C1.FirstParameter(), C1.LastParameter());
83 SetCurve (2, C2, C2.FirstParameter(), C2.LastParameter());
84 SetTolerance (1, TolC1);
85 SetTolerance (2, TolC2);
86 Perform();
87}
88
89//=======================================================================
90//function : SetCurve
91//purpose :
92//=======================================================================
93
94void Extrema_GExtCC::SetCurve (const Standard_Integer theRank, const Curve1& C)
95{
96 Standard_OutOfRange_Raise_if (theRank < 1 || theRank > 2, "Extrema_GExtCC::SetCurve()")
97 Standard_Integer anInd = theRank - 1;
98 myC[anInd] = (Standard_Address)&C;
99
100 //clear the previous cache to rebuild it later in Perform()
101 myCacheLists[anInd].Clear();
102}
103
104//=======================================================================
105//function : SetCurve
106//purpose :
107//=======================================================================
108
109void Extrema_GExtCC::SetCurve (const Standard_Integer theRank, const Curve1& C,
110 const Standard_Real Uinf, const Standard_Real Usup)
111{
112 SetCurve (theRank, C);
113 SetRange (theRank, Uinf, Usup);
114}
115
116//=======================================================================
117//function : SetRange
118//purpose :
119//=======================================================================
120
121void Extrema_GExtCC::SetRange (const Standard_Integer theRank,
122 const Standard_Real Uinf, const Standard_Real Usup)
123{
124 Standard_OutOfRange_Raise_if (theRank < 1 || theRank > 2, "Extrema_GExtCC::SetRange()")
125 Standard_Integer anInd = theRank - 1;
126 myInf[anInd] = Uinf;
127 mySup[anInd] = Usup;
128}
129
130//=======================================================================
131//function : SetTolerance
132//purpose :
133//=======================================================================
134
135void Extrema_GExtCC::SetTolerance (const Standard_Integer theRank, const Standard_Real theTol)
136{
137 Standard_OutOfRange_Raise_if (theRank < 1 || theRank > 2, "Extrema_GExtCC::SetTolerance()")
138 Standard_Integer anInd = theRank - 1;
139 myTol[anInd] = theTol;
140}
141
142
143//=======================================================================
144//function : Perform
145//purpose :
146//=======================================================================
147
148void Extrema_GExtCC::Perform()
149{
150 Standard_NullObject_Raise_if (!myC[0] || !myC[1], "Extrema_GExtCC::Perform()")
151 myDone = Standard_False;
152 mypoints.Clear();
153 mySqDist.Clear();
154 myIsPar = Standard_False;
155
156 GeomAbs_CurveType type1 = (*((Curve1*)myC[0])).GetType();
157 GeomAbs_CurveType type2 = (*((Curve2*)myC[1])).GetType();
158 Standard_Real U11, U12, U21, U22, Tol = Min(myTol[0], myTol[1]);
159 mynbext = 0;
160 inverse = Standard_False;
161
162 U11 = myInf[0];
163 U12 = mySup[0];
164 U21 = myInf[1];
165 U22 = mySup[1];
166
167 if (!Precision::IsInfinite(U11)) P1f = Tool1::Value(*((Curve1*)myC[0]), U11);
168 if (!Precision::IsInfinite(U12)) P1l = Tool1::Value(*((Curve1*)myC[0]), U12);
169 if (!Precision::IsInfinite(U21)) P2f = Tool2::Value(*((Curve2*)myC[1]), U21);
170 if (!Precision::IsInfinite(U22)) P2l = Tool2::Value(*((Curve2*)myC[1]), U22);
171
172
173 if (Precision::IsInfinite(U11) || Precision::IsInfinite(U21)) mydist11 = RealLast();
174 else mydist11 = P1f.SquareDistance(P2f);
175 if (Precision::IsInfinite(U11) || Precision::IsInfinite(U22)) mydist12 = RealLast();
176 else mydist12 = P1f.SquareDistance(P2l);
177 if (Precision::IsInfinite(U12) || Precision::IsInfinite(U21)) mydist21 = RealLast();
178 else mydist21 = P1l.SquareDistance(P2f);
179 if (Precision::IsInfinite(U12) || Precision::IsInfinite(U22)) mydist22 = RealLast();
180 else mydist22 = P1l.SquareDistance(P2l);
181
182 myECC.SetTolerance (Tol);
183
184 //Depending on the types of curves, the algorithm is chosen:
185 //- _ExtElC, when one of the curves is a line and the other is elementary,
186 // or there are two circles;
187 //- _GenExtCC, in all other cases
188 if ( (type1 == GeomAbs_Line && type2 <= GeomAbs_Parabola) ||
189 (type2 == GeomAbs_Line && type1 <= GeomAbs_Parabola) ) {
190 //analytical case - one curve is always a line
191 Standard_Integer anInd1 = 0, anInd2 = 1;
192 GeomAbs_CurveType aType2 = type2;
193 if (inverse = (type1 > type2)) {
194 //algorithm uses inverse order of arguments
195 anInd1 = 1;
196 anInd2 = 0;
197 aType2 = type1;
198 }
199 switch (aType2) {
200 case GeomAbs_Line: {
201 Extrema_ExtElC Xtrem((*((Curve1*)myC[anInd1])).Line(), (*((Curve1*)myC[anInd2])).Line(), Tol);
202 Results(Xtrem, U11, U12, U21, U22);
203 break;
204 }
205 case GeomAbs_Circle: {
206 Extrema_ExtElC Xtrem((*((Curve1*)myC[anInd1])).Line(), (*((Curve1*)myC[anInd2])).Circle(), Tol);
207 Results(Xtrem, U11, U12, U21, U22);
208 break;
209 }
210 case GeomAbs_Ellipse: {
211 Extrema_ExtElC Xtrem((*((Curve1*)myC[anInd1])).Line(), (*((Curve1*)myC[anInd2])).Ellipse());
212 Results(Xtrem, U11, U12, U21, U22);
213 break;
214 }
215 case GeomAbs_Hyperbola: {
216 Extrema_ExtElC Xtrem((*((Curve1*)myC[anInd1])).Line(), (*((Curve1*)myC[anInd2])).Hyperbola());
217 Results(Xtrem, U11, U12, U21, U22);
218 break;
219 }
220 case GeomAbs_Parabola: {
221 Extrema_ExtElC Xtrem((*((Curve1*)myC[anInd1])).Line(), (*((Curve1*)myC[anInd2])).Parabola());
222 Results(Xtrem, U11, U12, U21, U22);
223 break;
224 }
225 default: break;
226 }
227 } else if (type1 == GeomAbs_Circle && type2 == GeomAbs_Circle) {
228 //analytical case - two circles
229 Standard_Boolean bIsDone;
230 Extrema_ExtElC CCXtrem ((*((Curve1*)myC[0])).Circle(), (*((Curve2*)myC[1])).Circle());
231 bIsDone = CCXtrem.IsDone();
232 //modified by NIZNHY-PKV Fri Nov 21 10:48:14 2008f
233 if(bIsDone) {
234 Results(CCXtrem, U11, U12, U21, U22);
235 }
236 //if(CCXtrem.IsParallel()) {
237 //Results(CCXtrem, U11, U12, U21, U22);
238 //}
239 //modified by NIZNHY-PKV Fri Nov 21 10:48:23 2008t
240 else {
241 Standard_Integer i;
242 Standard_Integer aNbS = 32; //default number of sample points per interval (why 32?)
243 for (i = 0; i < 2; i++) {
244 TColStd_ListOfTransient& aCacheList = myCacheLists[i];
245 if (aCacheList.IsEmpty()) {
246 //no caches, build them
247 Curve1& aC = *(Curve1*)myC[i];
248 //single interval from myInf[i] to mySup[i]
249 Handle(Extrema_CCache) aCache = new Extrema_CCache (aC, myInf[i], mySup[i], aNbS, Standard_True);
250 aCacheList.Append (aCache);
251 }
252 }
253 Handle(Extrema_CCache) aCache1 = Handle(Extrema_CCache)::DownCast (myCacheLists[0].First());
254 myECC.SetCurveCache (1, aCache1);
255 Handle(Extrema_CCache) aCache2 = Handle(Extrema_CCache)::DownCast (myCacheLists[1].First());
256 myECC.SetCurveCache (2, aCache2);
257 myECC.Perform();
258 Results (myECC, U11, U12, U21, U22);
259 }
260 } else {
261 //common case - use _GenExtCC
262 //1. check and prepare caches
263
264 Standard_Integer i, aNbS[2] = {32, 32}, aNbInter[2] = {1, 1};
265 Standard_Real rf = 0., rl = 0., LL[2] = {-1., -1.};
266 for (i = 0; i < 2; i++) {
267 TColStd_ListOfTransient& aCacheList = myCacheLists[i];
268 if (aCacheList.IsEmpty()) {
269 //no caches, build them
270 Curve1& aC = *(Curve1*)myC[i];
271
272 Standard_Real du1 = 0., t = 0.;
273 gp_Pnt P1, P2;
274 GeomAbs_CurveType aType = aC.GetType();
275 switch (aType) {
276 case GeomAbs_BezierCurve:
277 aNbS[i] = aC.NbPoles() * 2;
278 break;
279 case GeomAbs_BSplineCurve:
280 aNbS[i] = aC.NbPoles() * 2;
281 rf = (Tool1::BSpline(*((Curve1*)myC[i])))->FirstParameter();
282 rl = (Tool1::BSpline(*((Curve1*)myC[i])))->LastParameter();
283 aNbS[i] = (Standard_Integer) ( aNbS[i] * ((mySup[i] - myInf[i]) / (rl - rf)) + 1 );
284 case GeomAbs_OtherCurve:
285 //adjust number of sample points for B-Splines and Other curves
286 aNbInter[i] = aC.NbIntervals (GeomAbs_C2);
287 aNbS[i] = Max(aNbS[i] / aNbInter[i], 3);
288 LL[i] = 0.;
289 du1 = (mySup[i] - myInf[i]) / ((aNbS[i]-1)*aNbInter[i]);
290 P1 = Tool1::Value(*((Curve1*)myC[i]), myInf[i]);
291 for(t = myInf[i] + du1; t <= mySup[i]; t += du1) {
292 P2 = Tool1::Value(*((Curve1*)myC[i]), t);
293 LL[i] += P1.Distance(P2);
294 P1 = P2;
295 }
296 LL[i] /= ((aNbS[i]-1)*aNbInter[i]);
297 break;
298 default:
299 break;
300 }
301 }
302 }
303
304 if(LL[0] > 0. && LL[1] > 0.) {
305 if(LL[0] > 4.*LL[1]) {
306 aNbS[0] = (Standard_Integer) ( aNbS[0] * LL[0]/LL[1]/2. );
307 }
308 else if(LL[1] > 4.*LL[0]) {
309 aNbS[1] = (Standard_Integer) (aNbS[1] * LL[1]/LL[0]/2. );
310 }
311 }
312
313 for (i = 0; i < 2; i++) {
314 TColStd_ListOfTransient& aCacheList = myCacheLists[i];
315 if (aCacheList.IsEmpty()) {
316 //no caches, build them
317 Curve1& aC = *(Curve1*)myC[i];
318
319 if (aC.GetType() >= GeomAbs_BSplineCurve) {
320 //can be multiple intervals, one cache per one C2 interval
321 TColStd_Array1OfReal anArr (1, aNbInter[i] + 1);
322 aC.Intervals (anArr, GeomAbs_C2);
323 for (Standard_Integer k = 1; k <= aNbInter[i]; k++) {
324 Handle(Extrema_CCache) aCache = new Extrema_CCache (aC,
325 anArr(k), anArr(k+1), aNbS[i], Standard_True);
326 aCacheList.Append (aCache);
327 }
328 } else {
329 //single interval from myInf[i] to mySup[i]
330 Handle(Extrema_CCache) aCache = new Extrema_CCache (aC,
331 myInf[i], mySup[i], aNbS[i], Standard_True);
332 aCacheList.Append (aCache);
333 }
334 }
335 }
336
337 //2. process each cache from one list with each cache from the other
338 TColStd_ListIteratorOfListOfTransient anIt1 (myCacheLists[0]);
339 for (; anIt1.More(); anIt1.Next()) {
340 Handle(Extrema_CCache) aCache1 = Handle(Extrema_CCache)::DownCast (anIt1.Value());
341 myECC.SetCurveCache (1, aCache1);
342 TColStd_ListIteratorOfListOfTransient anIt2 (myCacheLists[1]);
343 for (; anIt2.More(); anIt2.Next()) {
344 Handle(Extrema_CCache) aCache2 = Handle(Extrema_CCache)::DownCast (anIt2.Value());
345 myECC.SetCurveCache (2, aCache2);
346 myECC.Perform();
347 Results(myECC, U11, U12, U21, U22);
348 }
349 }
350 }
351}
352
353
354//=======================================================================
355//function : IsDone
356//purpose :
357//=======================================================================
358
359Standard_Boolean Extrema_GExtCC::IsDone() const
360{
361 return myDone;
362}
363
364//=======================================================================
365//function : IsParallel
366//purpose :
367//=======================================================================
368
369Standard_Boolean Extrema_GExtCC::IsParallel() const
370{
371 return myIsPar;
372}
373
374
375//=======================================================================
376//function : Value
377//purpose :
378//=======================================================================
379
380Standard_Real Extrema_GExtCC::SquareDistance(const Standard_Integer N) const
381{
382 if(!myDone) StdFail_NotDone::Raise();
383 if ((N <= 0) || (N > mynbext)) Standard_OutOfRange::Raise();
384 return mySqDist.Value(N);
385}
386
387
388//=======================================================================
389//function : NbExt
390//purpose :
391//=======================================================================
392
393Standard_Integer Extrema_GExtCC::NbExt() const
394{
395 if(!myDone) StdFail_NotDone::Raise();
396 return mynbext;
397}
398
399
400//=======================================================================
401//function : Points
402//purpose :
403//=======================================================================
404
405void Extrema_GExtCC::Points(const Standard_Integer N,
406 Extrema_POnCurv& P1,
407 Extrema_POnCurv& P2) const
408{
409 if(!myDone) StdFail_NotDone::Raise();
410 if ((N <= 0) || (N > mynbext)) Standard_OutOfRange::Raise();
411 P1 = mypoints.Value(2*N-1);
412 P2 = mypoints.Value(2*N);
413}
414
415
416
417//=======================================================================
418//function : TrimmedDistances
419//purpose :
420//=======================================================================
421
422void Extrema_GExtCC::TrimmedSquareDistances(Standard_Real& dist11,
423 Standard_Real& dist12,
424 Standard_Real& dist21,
425 Standard_Real& dist22,
426 gp_Pnt& P11 ,
427 gp_Pnt& P12 ,
428 gp_Pnt& P21 ,
429 gp_Pnt& P22 ) const {
430
431 dist11 = mydist11;
432 dist12 = mydist12;
433 dist21 = mydist21;
434 dist22 = mydist22;
435 P11 = P1f;
436 P12 = P1l;
437 P21 = P2f;
438 P22 = P2l;
439}
440
441
442
443//=======================================================================
444//function : Results
445//purpose :
446//=======================================================================
447
448void Extrema_GExtCC::Results(const Extrema_ExtElC& AlgExt,
449 const Standard_Real Ut11,
450 const Standard_Real Ut12,
451 const Standard_Real Ut21,
452 const Standard_Real Ut22)
453{
454 Standard_Integer i, NbExt;
455 Standard_Real Val, U, U2;
456 Extrema_POnCurv P1, P2;
457
458 myDone = AlgExt.IsDone();
459 if (myDone) {
460 myIsPar = AlgExt.IsParallel();
461 if (myIsPar) {
462 GeomAbs_CurveType type = Tool1::GetType(*((Curve1*)myC[0]));
463 GeomAbs_CurveType type2 = Tool2::GetType(*((Curve2*)myC[1]));
464 // Parallel case is only for line-line, circle-circle and circle-line!!!
465 // But really for trimmed curves extremas can not exist!
466 Extrema_POnCurv dummypoint(0., gp_Pnt(0.,0.,0.));
467 if(type != type2) {
468 mySqDist.Append(AlgExt.SquareDistance(1));
469 if(type == GeomAbs_Circle) {
470 gp_Pnt PonC1 = Tool1::Value(*((Curve1*)myC[0]), Ut11);
471 P1.SetValues(Ut11, PonC1);
472 Extrema_ExtPElC ExtPLin(PonC1, Tool2::Line(*((Curve2*)myC[1])), Precision::Confusion(), Ut21, Ut22);
473 if(ExtPLin.IsDone()) {
474 mynbext = 1;
475 P2 = ExtPLin.Point(1);
476 mypoints.Append(P1);
477 mypoints.Append(P2);
478 }
479 else {
480 myIsPar = Standard_False;
481 mynbext = 0;
482 mypoints.Append(dummypoint);
483 mypoints.Append(dummypoint);
484 }
485 }
486 else {
487 gp_Pnt PonC2 = Tool2::Value(*((Curve2*)myC[1]), Ut21);
488 P2.SetValues(Ut21, PonC2);
489 Extrema_ExtPElC ExtPLin(PonC2, Tool1::Line(*((Curve1*)myC[0])), Precision::Confusion(), Ut11, Ut12);
490 if(ExtPLin.IsDone()) {
491 mynbext = 1;
492 P1 = ExtPLin.Point(1);
493 mypoints.Append(P1);
494 mypoints.Append(P2);
495 }
496 else {
497 myIsPar = Standard_False;
498 mynbext = 0;
499 mypoints.Append(dummypoint);
500 mypoints.Append(dummypoint);
501 }
502 }
503 return;
504 }
505
506 if(type == GeomAbs_Line) {
507 Standard_Boolean infinite = Precision::IsInfinite(Ut11) &&
508 Precision::IsInfinite(Ut12) &&
509 Precision::IsInfinite(Ut21) &&
510 Precision::IsInfinite(Ut22);
511
512 if(infinite) {
513 mynbext = 1;
514 mySqDist.Append(AlgExt.SquareDistance(1));
515 gp_Pnt PonC1 = Tool1::Value(*((Curve1*)myC[0]), 0.);
516 P1.SetValues(0., PonC1);
517 Extrema_ExtPElC ExtPLin(PonC1, Tool2::Line(*((Curve2*)myC[1])), Precision::Confusion(), Ut21, Ut22);
518 if(ExtPLin.IsDone()) {
519 P2 = ExtPLin.Point(1);
520 mypoints.Append(P1);
521 mypoints.Append(P2);
522 }
523 else {
524 myIsPar = Standard_False;
525 mypoints.Append(dummypoint);
526 mypoints.Append(dummypoint);
527 }
528 }
529 else {
530 Standard_Boolean finish = Standard_False;
531 if(!Precision::IsInfinite(Ut11)) {
532 gp_Pnt PonC1 = Tool1::Value(*((Curve1*)myC[0]), Ut11);
533 Extrema_ExtPElC ExtPLin(PonC1, Tool2::Line(*((Curve2*)myC[1])), Precision::Confusion(), Ut21, Ut22);
534 if(ExtPLin.IsDone() && ExtPLin.NbExt() > 0) {
535 mynbext = 1;
536 mySqDist.Append(AlgExt.SquareDistance(1));
537 P1.SetValues(Ut11, PonC1);
538 P2 = ExtPLin.Point(1);
539 mypoints.Append(P1);
540 mypoints.Append(P2);
541 finish = Standard_True;
542 }
543 }
544 if(!finish) {
545 if(!Precision::IsInfinite(Ut12)) {
546 gp_Pnt PonC1 = Tool1::Value(*((Curve1*)myC[0]), Ut12);
547 Extrema_ExtPElC ExtPLin(PonC1, Tool2::Line(*((Curve2*)myC[1])), Precision::Confusion(), Ut21, Ut22);
548 if(ExtPLin.IsDone() && ExtPLin.NbExt() > 0) {
549 mynbext = 1;
550 mySqDist.Append(AlgExt.SquareDistance(1));
551 P1.SetValues(Ut12, PonC1);
552 P2 = ExtPLin.Point(1);
553 mypoints.Append(P1);
554 mypoints.Append(P2);
555 finish = Standard_True;
556 }
557 }
558 }
559 if(!finish) {
560 if(!Precision::IsInfinite(Ut21)) {
561 gp_Pnt PonC2 = Tool2::Value(*((Curve2*)myC[1]), Ut21);
562 Extrema_ExtPElC ExtPLin(PonC2, Tool1::Line(*((Curve1*)myC[0])), Precision::Confusion(), Ut11, Ut12);
563 if(ExtPLin.IsDone() && ExtPLin.NbExt() > 0) {
564 mynbext = 1;
565 mySqDist.Append(AlgExt.SquareDistance(1));
566 P2.SetValues(Ut21, PonC2);
567 P1 = ExtPLin.Point(1);
568 mypoints.Append(P1);
569 mypoints.Append(P2);
570 finish = Standard_True;
571 }
572 }
573 }
574 if(!finish) {
575 if(!Precision::IsInfinite(Ut22)) {
576 gp_Pnt PonC2 = Tool2::Value(*((Curve2*)myC[1]), Ut22);
577 Extrema_ExtPElC ExtPLin(PonC2, Tool1::Line(*((Curve1*)myC[0])), Precision::Confusion(), Ut11, Ut12);
578 if(ExtPLin.IsDone() && ExtPLin.NbExt() > 0) {
579 mynbext = 1;
580 mySqDist.Append(AlgExt.SquareDistance(1));
581 P2.SetValues(Ut22, PonC2);
582 P1 = ExtPLin.Point(1);
583 mypoints.Append(P1);
584 mypoints.Append(P2);
585 finish = Standard_True;
586 }
587 }
588 }
589 if(!finish) {
590 mynbext = 0;
591 myIsPar = Standard_False;
592 mySqDist.Append(AlgExt.SquareDistance(1));
593 mypoints.Append(dummypoint);
594 mypoints.Append(dummypoint);
595 }
596 }
597
598 }
599 else {
600 Standard_Boolean finish = Standard_False;
601 gp_Pnt PonC1 = Tool1::Value(*((Curve1*)myC[0]), Ut11);
602 P1.SetValues(Ut11, PonC1);
603 Extrema_ExtPElC ExtPCir(PonC1, Tool2::Circle(*((Curve2*)myC[1])), Precision::Confusion(), Ut21, Ut22);
604 if(ExtPCir.IsDone() && ExtPCir.NbExt() > 0) {
605 for(i = 1; i <= ExtPCir.NbExt(); i++) {
606 mynbext++;
607 P2 = ExtPCir.Point(i);
608 mySqDist.Append(ExtPCir.SquareDistance(i));
609 mypoints.Append(P1);
610 mypoints.Append(P2);
611 }
612 if(mynbext == 2) finish = Standard_True;
613 }
614 if(!finish) {
615 PonC1 = Tool1::Value(*((Curve1*)myC[0]), Ut12);
616 ExtPCir.Perform(PonC1, Tool2::Circle(*((Curve2*)myC[1])), Precision::Confusion(), Ut21, Ut22);
617 P1.SetValues(Ut12, PonC1);
618 if(ExtPCir.IsDone() && ExtPCir.NbExt() > 0) {
619 if(mynbext == 0) {
620 for(i = 1; i <= ExtPCir.NbExt(); i++) {
621 mynbext++;
622 P2 = ExtPCir.Point(i);
623 mySqDist.Append(ExtPCir.SquareDistance(i));
624 mypoints.Append(P1);
625 mypoints.Append(P2);
626 }
627 }
628 else {
629 for(i = 1; i <= ExtPCir.NbExt(); i++) {
630 Standard_Real dist = mySqDist(1);
631 if(Abs(dist - ExtPCir.SquareDistance(i)) > Precision::Confusion()) {
632 mynbext++;
633 P2 = ExtPCir.Point(i);
634 mySqDist.Append(ExtPCir.SquareDistance(i));
635 mypoints.Append(P1);
636 mypoints.Append(P2);
637 }
638 }
639 }
640
641 if(mynbext == 2) finish = Standard_True;
642 }
643 }
644 if(!finish) {
645 gp_Pnt PonC2 = Tool2::Value(*((Curve2*)myC[1]), Ut21);
646 ExtPCir.Perform(PonC2, Tool1::Circle(*((Curve1*)myC[0])), Precision::Confusion(), Ut11, Ut12);
647 P2.SetValues(Ut21, PonC2);
648 if(ExtPCir.IsDone() && ExtPCir.NbExt() > 0) {
649 if(mynbext == 0) {
650 for(i = 1; i <= ExtPCir.NbExt(); i++) {
651 mynbext++;
652 P1 = ExtPCir.Point(i);
653 mySqDist.Append(ExtPCir.SquareDistance(i));
654 mypoints.Append(P1);
655 mypoints.Append(P2);
656 }
657 }
658 else {
659 for(i = 1; i <= ExtPCir.NbExt(); i++) {
660 Standard_Real dist = mySqDist(1);
661 if(Abs(dist - ExtPCir.SquareDistance(i)) > Precision::Confusion()) {
662 mynbext++;
663 P1 = ExtPCir.Point(i);
664 mySqDist.Append(ExtPCir.SquareDistance(i));
665 mypoints.Append(P1);
666 mypoints.Append(P2);
667 }
668 }
669 }
670
671 if(mynbext == 2) finish = Standard_True;
672 }
673 }
674 if(!finish) {
675 gp_Pnt PonC2 = Tool2::Value(*((Curve2*)myC[1]), Ut22);
676 ExtPCir.Perform(PonC2, Tool1::Circle(*((Curve1*)myC[0])), Precision::Confusion(), Ut11, Ut12);
677 P2.SetValues(Ut22, PonC2);
678 if(ExtPCir.IsDone() && ExtPCir.NbExt() > 0) {
679 if(mynbext == 0) {
680 for(i = 1; i <= ExtPCir.NbExt(); i++) {
681 mynbext++;
682 P1 = ExtPCir.Point(i);
683 mySqDist.Append(ExtPCir.SquareDistance(i));
684 mypoints.Append(P1);
685 mypoints.Append(P2);
686 }
687 }
688 else {
689 for(i = 1; i <= ExtPCir.NbExt(); i++) {
690 Standard_Real dist = mySqDist(1);
691 if(Abs(dist - ExtPCir.SquareDistance(i)) > Precision::Confusion()) {
692 mynbext++;
693 P1 = ExtPCir.Point(i);
694 mySqDist.Append(ExtPCir.SquareDistance(i));
695 mypoints.Append(P1);
696 mypoints.Append(P2);
697 }
698 }
699 }
700
701 if(mynbext == 2) finish = Standard_True;
702 }
703 }
704 if(mynbext == 0) {
705 myIsPar = Standard_False;
706 mySqDist.Append(AlgExt.SquareDistance(1));
707 mypoints.Append(dummypoint);
708 mypoints.Append(dummypoint);
709 mySqDist.Append(AlgExt.SquareDistance(2));
710 mypoints.Append(dummypoint);
711 mypoints.Append(dummypoint);
712 }
713 }
714 }
715 else {
716 NbExt = AlgExt.NbExt();
717 for (i = 1; i <= NbExt; i++) {
718 // Verification de la validite des parametres
719 AlgExt.Points(i, P1, P2);
720 if (!inverse) {
721 U = P1.Parameter();
722 U2 = P2.Parameter();
723 }
724 else {
725 U2 = P1.Parameter();
726 U = P2.Parameter();
727 }
728
729 if (Tool1::IsPeriodic(*((Curve1*)myC[0]))) {
730 U = ElCLib::InPeriod(U, Ut11, Ut11+Tool1::Period(*((Curve1*)myC[0])));
731 }
732 if (Tool2::IsPeriodic(*((Curve2*)myC[1]))) {
733 U2 = ElCLib::InPeriod(U2, Ut21, Ut21+Tool2::Period(*((Curve2*)myC[1])));
734 }
735
736 if ((U >= Ut11 - RealEpsilon()) &&
737 (U <= Ut12 + RealEpsilon()) &&
738 (U2 >= Ut21 - RealEpsilon()) &&
739 (U2 <= Ut22 + RealEpsilon())) {
740 mynbext++;
741 Val = AlgExt.SquareDistance(i);
742 mySqDist.Append(Val);
743 if (!inverse) {
744 P1.SetValues(U, P1.Value());
745 P2.SetValues(U2, P2.Value());
746 mypoints.Append(P1);
747 mypoints.Append(P2);
748 }
749 else {
750 P1.SetValues(U2, P1.Value());
751 P2.SetValues(U, P2.Value());
752 mypoints.Append(P2);
753 mypoints.Append(P1);
754 }
755 }
756 }
757 }
758 }
759
760}
761
762
763//=======================================================================
764//function : Results
765//purpose :
766//=======================================================================
767
768void Extrema_GExtCC::Results(const Extrema_ECC& AlgExt,
769 const Standard_Real Ut11,
770 const Standard_Real Ut12,
771 const Standard_Real Ut21,
772 const Standard_Real Ut22)
773{
774 Standard_Integer i, j,NbExt;
775 Standard_Real Val, U, U2,Uj,U2j;
776 Extrema_POnCurv P1, P2,P1j,P2j;
777 Standard_Boolean IsExtrema;
778
779 myDone = AlgExt.IsDone();
780 if (myDone) {
781 NbExt = AlgExt.NbExt();
782 for (i = 1; i <= NbExt; i++) {
783 AlgExt.Points(i, P1, P2);
784 U = P1.Parameter();
785 U2 = P2.Parameter();
786 IsExtrema=Standard_True;
787 for (j=1;j<=mynbext;j++)
788 { P1j=mypoints.Value(2*j-1);
789 P2j=mypoints.Value(2*j);
790 Uj=P1j.Parameter();
791 U2j=P2j.Parameter();
792 if ((Abs(Uj-U)<=myTol[0]) && (Abs(U2j-U2)<=myTol[1]))
793 IsExtrema=Standard_False;}
794
795 if (IsExtrema)
796 {
797// Verification de la validite des parametres
798 if (Tool1::IsPeriodic(*((Curve1*)myC[0]))) {
799 U = ElCLib::InPeriod(U, Ut11, Ut11+Tool1::Period(*((Curve1*)myC[0])));
800 }
801 if (Tool2::IsPeriodic(*((Curve2*)myC[1]))) {
802 U2 = ElCLib::InPeriod(U2, Ut21, Ut21+Tool2::Period(*((Curve2*)myC[1])));
803 }
804
805 if ((U >= Ut11 - RealEpsilon()) &&
806 (U <= Ut12 + RealEpsilon()) &&
807 (U2 >= Ut21 - RealEpsilon()) &&
808 (U2 <= Ut22 + RealEpsilon()))
809 { mynbext++;
810 Val = AlgExt.SquareDistance(i);
811 mySqDist.Append(Val);
812 P1.SetValues(U, P1.Value());
813 P2.SetValues(U2, P2.Value());
814 mypoints.Append(P1);
815 mypoints.Append(P2);
816 }
817 }
818 }
819 }
820}