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