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