0024530: TKMesh - remove unused package IntPoly
[occt.git] / src / Extrema / Extrema_ExtElCS.cxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
973c2be1 6// This library is free software; you can redistribute it and / or modify it
7// under the terms of the GNU Lesser General Public version 2.1 as published
8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
7fd59977 14
15// Modified by skv - Thu Jul 7 14:37:05 2005 OCC9134
16
17#include <Extrema_ExtElCS.ixx>
18#include <Extrema_ExtPElS.hxx>
19#include <Extrema_ExtPElC.hxx>
20#include <Extrema_ExtElC.hxx>
21#include <Extrema_POnCurv.hxx>
22#include <Standard_NotImplemented.hxx>
23#include <StdFail_InfiniteSolutions.hxx>
24#include <Precision.hxx>
25#include <ElSLib.hxx>
26#include <ElCLib.hxx>
27#include <gp_Vec.hxx>
f34cd0d1 28#include <IntAna_Quadric.hxx>
29#include <IntAna_IntConicQuad.hxx>
7fd59977 30
31
32Extrema_ExtElCS::Extrema_ExtElCS()
33{
34 myDone = Standard_False;
35 myIsPar = Standard_False;
36}
37
38
39Extrema_ExtElCS::Extrema_ExtElCS(const gp_Lin& C,
40 const gp_Pln& S)
41{
42 Perform(C, S);
43}
44
45
46
47void Extrema_ExtElCS::Perform(const gp_Lin& C,
48 const gp_Pln& S)
49{
50 myDone = Standard_True;
51 myIsPar = Standard_False;
52
53 if (C.Direction().IsNormal(S.Axis().Direction(),
54 Precision::Angular())) {
55 mySqDist = new TColStd_HArray1OfReal(1, 1);
56 mySqDist->SetValue(1, S.SquareDistance(C));
57 myIsPar = Standard_True;
58 }
59 else {
60 myNbExt = 0;
61 }
62
63}
64
65
66Extrema_ExtElCS::Extrema_ExtElCS(const gp_Lin& C,
67 const gp_Cylinder& S)
68{
69 Perform(C, S);
70}
71
72
73
74void Extrema_ExtElCS::Perform(const gp_Lin& C,
75 const gp_Cylinder& S)
76{
77 myDone = Standard_False;
78 myNbExt = 0;
79 myIsPar = Standard_False;
80
81 gp_Ax3 Pos = S.Position();
f34cd0d1 82 gp_Pnt Origin = Pos.Location();
83 gp_Pnt LineOrig = C.Location();
84
7fd59977 85 Standard_Real radius = S.Radius();
86 Extrema_ExtElC Extrem(gp_Lin(Pos.Axis()), C, Precision::Angular());
87 if (Extrem.IsParallel()) {
88 mySqDist = new TColStd_HArray1OfReal(1, 1);
f34cd0d1 89 myPoint1 = new Extrema_HArray1OfPOnCurv(1, 1);
90 myPoint2 = new Extrema_HArray1OfPOnSurf(1, 1);
91 Standard_Real aDist = sqrt(Extrem.SquareDistance(1)) - radius;
7fd59977 92 mySqDist->SetValue(1, aDist * aDist);
f34cd0d1 93 Standard_Real u, v, w;
94 gp_Vec aVec(LineOrig, Origin);
95 gp_Vec aDirVec(C.Direction());
96 w = aVec*aDirVec;
97 gp_Pnt LinPoint = LineOrig.Translated(w * aDirVec);
98 Extrema_POnCurv PonC(w, LinPoint);
99 myPoint1->SetValue(1, PonC);
100 gp_Pnt CylPoint;
101 gp_Vec OrigToLine(Origin, LinPoint);
102 if (OrigToLine.Magnitude() <= gp::Resolution())
103 {
104 u = 0.;
105 v = 0.;
106 CylPoint = ElSLib::Value(u, v, S);
107 }
108 else
109 {
110 OrigToLine.Normalize();
111 CylPoint = Origin.Translated(radius * OrigToLine);
112 ElSLib::CylinderParameters(Pos, radius, CylPoint, u, v);
113 }
114 Extrema_POnSurf PonS(u, v, CylPoint);
115 myPoint2->SetValue(1, PonS);
7fd59977 116 myDone = Standard_True;
117 myIsPar = Standard_True;
118 }
119 else {
120 Standard_Integer i;
f34cd0d1 121
122 Extrema_POnCurv myPOnC1, myPOnC2;
123 Extrem.Points(1, myPOnC1, myPOnC2);
124 gp_Pnt PonAxis = myPOnC1.Value();
125 gp_Pnt PC = myPOnC2.Value();
126
127 // line is tangent or outside of the cylunder -- single solution
128 if (radius - PonAxis.Distance(PC) < Precision::PConfusion())
129 {
130 Extrema_ExtPElS ExPS(PC, S, Precision::Confusion());
131 if (ExPS.IsDone()) {
132 myNbExt = ExPS.NbExt();
133 mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
134 myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
135 myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
136 for (i = 1; i <= myNbExt; i++) {
137 myPoint1->SetValue(i, myPOnC2);
138 myPoint2->SetValue(i, ExPS.Point(i));
139 mySqDist->SetValue(i,(myPOnC2.Value()).SquareDistance(ExPS.Point(i).Value()));
140 }
7fd59977 141 }
f34cd0d1 142 }
143 // line intersects the cylinder
144 else
145 {
146 IntAna_Quadric theQuadric(S);
147 IntAna_IntConicQuad Inters(C, theQuadric);
148 if (Inters.IsDone())
149 {
150 myNbExt = Inters.NbPoints();
151 if (myNbExt > 0)
152 {
153 mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
154 myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
155 myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
156 Standard_Real u, v, w;
157 for (i = 1; i <= myNbExt; i++)
158 {
159 mySqDist->SetValue(i, 0.);
160 gp_Pnt P_int = Inters.Point(i);
161 w = Inters.ParamOnConic(i);
162 Extrema_POnCurv PonC(w, P_int);
163 myPoint1->SetValue(i, PonC);
164 ElSLib::CylinderParameters(Pos, radius, P_int, u, v);
165 Extrema_POnSurf PonS(u, v, P_int);
166 myPoint2->SetValue(i, PonS);
167 }
168 }
7fd59977 169 }
7fd59977 170 }
f34cd0d1 171 myDone = Standard_True;
7fd59977 172 }
173
174}
175
176
177
178Extrema_ExtElCS::Extrema_ExtElCS(const gp_Lin& C,
179 const gp_Cone& S)
180{
181 Perform(C, S);
182}
183
184
185
186//void Extrema_ExtElCS::Perform(const gp_Lin& C,
187// const gp_Cone& S)
188void Extrema_ExtElCS::Perform(const gp_Lin& ,
189 const gp_Cone& )
190{
191 Standard_NotImplemented::Raise();
192
193}
194
195
196
197Extrema_ExtElCS::Extrema_ExtElCS(const gp_Lin& C,
198 const gp_Sphere& S)
199{
200 Perform(C, S);
201}
202
203
204
205void Extrema_ExtElCS::Perform(const gp_Lin& C,
206 const gp_Sphere& S)
207{
208 myDone = Standard_False;
209 myNbExt = 0;
210 myIsPar = Standard_False;
211
212 gp_Pnt O = S.Location();
213
214 Extrema_ExtPElC Extrem(O, C, Precision::Angular(), RealFirst(), RealLast());
215
216 Standard_Integer i;
217 if (Extrem.IsDone()) {
218 Extrema_POnCurv myPOnC1 = Extrem.Point(1);
219 Extrema_ExtPElS ExPS(myPOnC1.Value(), S, Precision::Confusion());
220 if (ExPS.IsDone()) {
221 myNbExt = ExPS.NbExt();
222 mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
223 myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
224 myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
225 for (i = 1; i <= myNbExt; i++) {
226 myPoint1->SetValue(i, myPOnC1);
227 myPoint2->SetValue(i, ExPS.Point(i));
228 mySqDist->SetValue(i,(myPOnC1.Value()).SquareDistance(ExPS.Point(i).Value()));
229 myDone = Standard_True;
230 }
231 }
232 }
233}
234
235
236Extrema_ExtElCS::Extrema_ExtElCS(const gp_Lin& C,
237 const gp_Torus& S)
238{
239 Perform(C, S);
240}
241
242
243
244//void Extrema_ExtElCS::Perform(const gp_Lin& C,
245// const gp_Torus& S)
246void Extrema_ExtElCS::Perform(const gp_Lin& ,
247 const gp_Torus& )
248{
249 Standard_NotImplemented::Raise();
250
251}
252
253
254// Circle-?
255
256Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
257 const gp_Pln& S)
258{
259 Perform(C, S);
260}
261
262
263
264//void Extrema_ExtElCS::Perform(const gp_Circ& C,
265// const gp_Pln& S)
266void Extrema_ExtElCS::Perform(const gp_Circ& ,
267 const gp_Pln& )
268{
269 Standard_NotImplemented::Raise();
270
271}
272
273
274
275Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
276 const gp_Cylinder& S)
277{
278 Perform(C, S);
279}
280
281
282
283// Modified by skv - Thu Jul 7 14:37:05 2005 OCC9134 Begin
284// Implementation of the method.
285void Extrema_ExtElCS::Perform(const gp_Circ& C,
286 const gp_Cylinder& S)
287{
288 myDone = Standard_False;
289 myIsPar = Standard_False;
290 myNbExt = 0;
291
292 // Get an axis line of the cylinder.
293 gp_Lin anAxis(S.Axis());
294
295 // Compute extrema between the circle and the line.
296 Extrema_ExtElC anExtC(anAxis, C, 0.);
297
298 if (anExtC.IsDone()) {
299 if (anExtC.IsParallel()) {
300 myIsPar = Standard_True;
301 mySqDist = new TColStd_HArray1OfReal(1, 1);
302 Standard_Real aDist = sqrt (anExtC.SquareDistance(1)) - S.Radius();
303 mySqDist->SetValue(1, aDist * aDist);
304 } else {
305 Standard_Integer aNbExt = anExtC.NbExt();
7fd59977 306 Standard_Integer i;
307 Standard_Integer aCurI = 1;
308 Standard_Real aTolConf = Precision::Confusion();
309 Standard_Real aCylRad = S.Radius();
310
19875353 311 // Check whether two objects have intersection points
312 IntAna_Quadric aCylQuad(S);
313 IntAna_IntConicQuad aCircCylInter(C, aCylQuad);
314 Standard_Integer aNbInter = aCircCylInter.NbPoints();
315 if (!aCircCylInter.IsDone())
316 aNbInter = 0;
317
7fd59977 318 // Compute the extremas.
19875353 319 myNbExt = 2*aNbExt + aNbInter;
7fd59977 320 mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
321 myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
322 myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
323
324 for (i = 1; i <= aNbExt; i++) {
19875353 325 Extrema_POnCurv aPOnAxis;
326 Extrema_POnCurv aPOnCirc;
327 Standard_Real aSqDist = anExtC.SquareDistance(i);
328 Standard_Real aDist = sqrt (aSqDist);
329
330 anExtC.Points(i, aPOnAxis, aPOnCirc);
331
332 if (aSqDist <= (aTolConf * aTolConf)) {
333 myNbExt -= 2;
334 continue;
335 }
336
337 gp_Dir aDir(aPOnAxis.Value().XYZ().Subtracted(aPOnCirc.Value().XYZ()));
338 Standard_Real aShift[2] = { aDist + aCylRad, aDist - aCylRad };
339 Standard_Integer j;
7fd59977 340
19875353 341 for (j = 0; j < 2; j++) {
342 gp_Vec aVec(aDir);
343 gp_Pnt aPntOnCyl;
7fd59977 344
19875353 345 aVec.Multiply(aShift[j]);
346 aPntOnCyl = aPOnCirc.Value().Translated(aVec);
7fd59977 347
19875353 348 Standard_Real aU;
349 Standard_Real aV;
7fd59977 350
19875353 351 ElSLib::Parameters(S, aPntOnCyl, aU, aV);
7fd59977 352
19875353 353 Extrema_POnSurf aPOnSurf(aU, aV, aPntOnCyl);
7fd59977 354
19875353 355 myPoint1->SetValue(aCurI, aPOnCirc);
356 myPoint2->SetValue(aCurI, aPOnSurf);
357 mySqDist->SetValue(aCurI++, aShift[j] * aShift[j]);
358 }
359 }
360
361 // Adding intersection points to the list of extremas
362 for (i=1; i<=aNbInter; i++)
363 {
364 Standard_Real aU;
365 Standard_Real aV;
7fd59977 366
19875353 367 gp_Pnt aInterPnt = aCircCylInter.Point(i);
7fd59977 368
19875353 369 aU = ElCLib::Parameter(C, aInterPnt);
370 Extrema_POnCurv aPOnCirc(aU, aInterPnt);
7fd59977 371
19875353 372 ElSLib::Parameters(S, aInterPnt, aU, aV);
373 Extrema_POnSurf aPOnCyl(aU, aV, aInterPnt);
374 myPoint1->SetValue(aCurI, aPOnCirc);
375 myPoint2->SetValue(aCurI, aPOnCyl);
376 mySqDist->SetValue(aCurI++, 0.0);
7fd59977 377 }
378 }
379
380 myDone = Standard_True;
381 }
382}
383// Modified by skv - Thu Jul 7 14:37:05 2005 OCC9134 End
384
385
386
387Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
388 const gp_Cone& S)
389{
390 Perform(C, S);
391}
392
393
394
395//void Extrema_ExtElCS::Perform(const gp_Circ& C,
396// const gp_Cone& S)
397void Extrema_ExtElCS::Perform(const gp_Circ& ,
398 const gp_Cone& )
399{
400 Standard_NotImplemented::Raise();
401
402}
403
404
405
406Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
407 const gp_Sphere& S)
408{
409 Perform(C, S);
410}
411
412
413
414//void Extrema_ExtElCS::Perform(const gp_Circ& C,
415// const gp_Sphere& S)
416void Extrema_ExtElCS::Perform(const gp_Circ& ,
417 const gp_Sphere& )
418{
419 Standard_NotImplemented::Raise();
420
421}
422
423Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
424 const gp_Torus& S)
425{
426 Perform(C, S);
427}
428
429
430
431//void Extrema_ExtElCS::Perform(const gp_Circ& C,
432// const gp_Torus& S)
433void Extrema_ExtElCS::Perform(const gp_Circ& ,
434 const gp_Torus& )
435{
436 Standard_NotImplemented::Raise();
437
438}
439
440Extrema_ExtElCS::Extrema_ExtElCS(const gp_Hypr& C,
441 const gp_Pln& S)
442{
443 Perform(C, S);
444}
445
446
447
448void Extrema_ExtElCS::Perform(const gp_Hypr& C,
449 const gp_Pln& S)
450{
451 myDone = Standard_True;
452 myIsPar = Standard_False;
453
454 gp_Ax2 Pos = C.Position();
455 gp_Dir NHypr = Pos.Direction();
456 gp_Dir NPln = S.Axis().Direction();
457
458 if (NHypr.IsParallel(NPln, Precision::Angular())) {
459
460 mySqDist = new TColStd_HArray1OfReal(1, 1);
461 mySqDist->SetValue(1, S.SquareDistance(C.Location()));
462 myIsPar = Standard_True;
463
464 }
465 else {
466
467 gp_Dir XDir = Pos.XDirection();
468 gp_Dir YDir = Pos.YDirection();
469
470 Standard_Real A = C.MinorRadius()*(NPln.Dot(YDir));
471 Standard_Real B = C.MajorRadius()*(NPln.Dot(XDir));
472
473 if(Abs(B) > Abs(A)) {
474 Standard_Real T = -0.5 * Log((A+B)/(B-A));
475 gp_Pnt Ph = ElCLib::HyperbolaValue(T, Pos, C.MajorRadius(), C.MinorRadius());
476 Extrema_POnCurv PC(T, Ph);
477 myPoint1 = new Extrema_HArray1OfPOnCurv(1,1);
478 myPoint1->SetValue(1, PC);
479
480 mySqDist = new TColStd_HArray1OfReal(1, 1);
481 mySqDist->SetValue(1, S.SquareDistance(Ph));
482
483 Standard_Real U, V;
484 ElSLib::PlaneParameters(S.Position(), Ph, U, V);
485 gp_Pnt Pp = ElSLib::PlaneValue(U, V, S.Position());
486 Extrema_POnSurf PS(U, V, Pp);
487 myPoint2 = new Extrema_HArray1OfPOnSurf(1,1);
488 myPoint2->SetValue(1, PS);
489
490 myNbExt = 1;
491 }
492 else {
493 myNbExt = 0;
494 }
495
496 }
497
498}
499
500
501Standard_Boolean Extrema_ExtElCS::IsDone() const
502{
503 return myDone;
504}
505
506
507Standard_Integer Extrema_ExtElCS::NbExt() const
508{
509 if (myIsPar) StdFail_InfiniteSolutions::Raise();
510 return myNbExt;
511}
512
513Standard_Real Extrema_ExtElCS::SquareDistance(const Standard_Integer N) const
514{
515 if (myIsPar && N != 1) StdFail_InfiniteSolutions::Raise();
516 return mySqDist->Value(N);
517}
518
519
520void Extrema_ExtElCS::Points(const Standard_Integer N,
521 Extrema_POnCurv& P1,
522 Extrema_POnSurf& P2) const
523{
524 if (myIsPar) StdFail_InfiniteSolutions::Raise();
525 P1 = myPoint1->Value(N);
526 P2 = myPoint2->Value(N);
527}
528
529
530Standard_Boolean Extrema_ExtElCS::IsParallel() const
531{
532 return myIsPar;
533}