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 | |
40 | Extrema_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 | |
53 | Extrema_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 | |
76 | Extrema_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 | |
94 | void 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 | |
109 | void 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 | |
121 | void 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 | |
135 | void 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 | |
148 | void 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 | |
359 | Standard_Boolean Extrema_GExtCC::IsDone() const |
360 | { |
361 | return myDone; |
362 | } |
363 | |
364 | //======================================================================= |
365 | //function : IsParallel |
366 | //purpose : |
367 | //======================================================================= |
368 | |
369 | Standard_Boolean Extrema_GExtCC::IsParallel() const |
370 | { |
371 | return myIsPar; |
372 | } |
373 | |
374 | |
375 | //======================================================================= |
376 | //function : Value |
377 | //purpose : |
378 | //======================================================================= |
379 | |
380 | Standard_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 | |
393 | Standard_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 | |
405 | void 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 | |
422 | void 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 | |
448 | void 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 | |
768 | void 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 | } |