0024284: Some trivial warnings produced by ICC 14
[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       Standard_Integer i;
312       Standard_Integer aCurI    = 1;
313       Standard_Real    aTolConf = Precision::Confusion();
314       Standard_Real    aCylRad  = S.Radius();
315
316       // Check whether two objects have intersection points
317       IntAna_Quadric aCylQuad(S);
318       IntAna_IntConicQuad aCircCylInter(C, aCylQuad);
319       Standard_Integer aNbInter = aCircCylInter.NbPoints();
320       if (!aCircCylInter.IsDone())
321         aNbInter = 0;
322
323       // Compute the extremas.
324       myNbExt  =     2*aNbExt + aNbInter;
325       mySqDist  = new TColStd_HArray1OfReal(1, myNbExt);
326       myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
327       myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
328
329       for (i = 1; i <= aNbExt; i++) {
330         Extrema_POnCurv aPOnAxis;
331         Extrema_POnCurv aPOnCirc;
332         Standard_Real   aSqDist = anExtC.SquareDistance(i);
333         Standard_Real   aDist = sqrt (aSqDist);
334
335         anExtC.Points(i, aPOnAxis, aPOnCirc);
336
337         if (aSqDist <= (aTolConf * aTolConf)) {
338           myNbExt -= 2;
339           continue;
340         }
341
342         gp_Dir aDir(aPOnAxis.Value().XYZ().Subtracted(aPOnCirc.Value().XYZ()));
343         Standard_Real aShift[2] = { aDist + aCylRad, aDist - aCylRad };
344         Standard_Integer j;
345
346         for (j = 0; j < 2; j++) {
347           gp_Vec aVec(aDir);
348           gp_Pnt aPntOnCyl;
349
350           aVec.Multiply(aShift[j]);
351           aPntOnCyl = aPOnCirc.Value().Translated(aVec);
352
353           Standard_Real aU;
354           Standard_Real aV;
355
356           ElSLib::Parameters(S, aPntOnCyl, aU, aV);
357
358           Extrema_POnSurf aPOnSurf(aU, aV, aPntOnCyl);
359
360           myPoint1->SetValue(aCurI, aPOnCirc);
361           myPoint2->SetValue(aCurI, aPOnSurf);
362           mySqDist->SetValue(aCurI++, aShift[j] * aShift[j]);
363         }
364       }
365
366       // Adding intersection points to the list of extremas
367       for (i=1; i<=aNbInter; i++)
368       {
369         Standard_Real aU;
370         Standard_Real aV;
371
372         gp_Pnt aInterPnt = aCircCylInter.Point(i);
373
374         aU = ElCLib::Parameter(C, aInterPnt);
375         Extrema_POnCurv aPOnCirc(aU, aInterPnt);
376
377         ElSLib::Parameters(S, aInterPnt, aU, aV);
378         Extrema_POnSurf aPOnCyl(aU, aV, aInterPnt);
379         myPoint1->SetValue(aCurI, aPOnCirc);
380         myPoint2->SetValue(aCurI, aPOnCyl);
381         mySqDist->SetValue(aCurI++, 0.0);
382       }
383     }
384
385     myDone = Standard_True;
386   }
387 }
388 //  Modified by skv - Thu Jul  7 14:37:05 2005 OCC9134 End
389
390
391
392 Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
393                                  const gp_Cone& S)
394 {
395   Perform(C, S);
396 }
397
398
399
400 //void Extrema_ExtElCS::Perform(const gp_Circ& C,
401 //                       const gp_Cone& S)
402 void Extrema_ExtElCS::Perform(const gp_Circ& ,
403                          const gp_Cone& )
404 {
405   Standard_NotImplemented::Raise();
406
407 }
408
409
410
411 Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
412                                  const gp_Sphere& S)
413 {
414   Perform(C, S);
415 }
416
417
418
419 //void Extrema_ExtElCS::Perform(const gp_Circ& C,
420 //                            const gp_Sphere& S)
421 void Extrema_ExtElCS::Perform(const gp_Circ& ,
422                               const gp_Sphere& )
423 {
424   Standard_NotImplemented::Raise();
425
426 }
427
428 Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
429                                  const gp_Torus& S)
430 {
431   Perform(C, S);
432 }
433
434
435
436 //void Extrema_ExtElCS::Perform(const gp_Circ& C,
437 //                            const gp_Torus& S)
438 void Extrema_ExtElCS::Perform(const gp_Circ& ,
439                               const gp_Torus& )
440 {
441   Standard_NotImplemented::Raise();
442
443 }
444
445 Extrema_ExtElCS::Extrema_ExtElCS(const gp_Hypr& C,
446                                  const gp_Pln& S)
447 {
448   Perform(C, S);
449 }
450
451
452
453 void Extrema_ExtElCS::Perform(const gp_Hypr& C,
454                               const gp_Pln& S)
455 {
456   myDone = Standard_True;
457   myIsPar = Standard_False;
458
459   gp_Ax2 Pos = C.Position();
460   gp_Dir NHypr = Pos.Direction();
461   gp_Dir NPln = S.Axis().Direction();
462
463   if (NHypr.IsParallel(NPln, Precision::Angular())) {
464
465     mySqDist = new TColStd_HArray1OfReal(1, 1);
466     mySqDist->SetValue(1, S.SquareDistance(C.Location()));
467     myIsPar = Standard_True;
468
469   }
470   else {
471
472     gp_Dir XDir = Pos.XDirection();
473     gp_Dir YDir = Pos.YDirection();
474
475     Standard_Real A = C.MinorRadius()*(NPln.Dot(YDir)); 
476     Standard_Real B = C.MajorRadius()*(NPln.Dot(XDir)); 
477
478     if(Abs(B) > Abs(A)) {
479       Standard_Real T = -0.5 * Log((A+B)/(B-A));
480       gp_Pnt Ph = ElCLib::HyperbolaValue(T, Pos, C.MajorRadius(), C.MinorRadius());
481       Extrema_POnCurv PC(T, Ph);
482       myPoint1 = new Extrema_HArray1OfPOnCurv(1,1);
483       myPoint1->SetValue(1, PC);
484
485       mySqDist = new TColStd_HArray1OfReal(1, 1);
486       mySqDist->SetValue(1, S.SquareDistance(Ph));
487
488       Standard_Real U, V;
489       ElSLib::PlaneParameters(S.Position(), Ph, U, V);
490       gp_Pnt Pp = ElSLib::PlaneValue(U, V, S.Position());
491       Extrema_POnSurf PS(U, V, Pp);
492       myPoint2 = new Extrema_HArray1OfPOnSurf(1,1);
493       myPoint2->SetValue(1, PS);
494
495       myNbExt = 1;
496     }
497     else {
498       myNbExt = 0;
499     }
500
501   }
502   
503 }
504
505
506 Standard_Boolean Extrema_ExtElCS::IsDone() const
507 {
508   return myDone;
509 }
510
511
512 Standard_Integer Extrema_ExtElCS::NbExt() const
513 {
514   if (myIsPar) StdFail_InfiniteSolutions::Raise();
515   return myNbExt;
516 }
517
518 Standard_Real Extrema_ExtElCS::SquareDistance(const Standard_Integer N) const
519 {
520   if (myIsPar && N != 1) StdFail_InfiniteSolutions::Raise();
521   return mySqDist->Value(N);
522 }
523
524
525 void Extrema_ExtElCS::Points(const Standard_Integer N,
526                              Extrema_POnCurv& P1,
527                              Extrema_POnSurf& P2) const
528 {
529   if (myIsPar) StdFail_InfiniteSolutions::Raise();
530   P1 = myPoint1->Value(N);
531   P2 = myPoint2->Value(N);
532 }
533
534
535 Standard_Boolean Extrema_ExtElCS::IsParallel() const
536 {
537   return myIsPar;
538 }