0022627: Change OCCT memory management defaults
[occt.git] / src / Extrema / Extrema_ExtElCS.cxx
1 // File Extrema_ExtElCS.cxx
2
3 //  Modified by skv - Thu Jul  7 14:37:05 2005 OCC9134
4
5 #include <Extrema_ExtElCS.ixx>
6 #include <Extrema_ExtPElS.hxx>
7 #include <Extrema_ExtPElC.hxx>
8 #include <Extrema_ExtElC.hxx>
9 #include <Extrema_POnCurv.hxx>
10 #include <Standard_NotImplemented.hxx>
11 #include <StdFail_InfiniteSolutions.hxx>
12 #include <Precision.hxx>
13 #include <ElSLib.hxx>
14 #include <ElCLib.hxx>
15 #include <gp_Vec.hxx>
16
17
18 Extrema_ExtElCS::Extrema_ExtElCS() 
19 {
20   myDone = Standard_False;
21   myIsPar = Standard_False;
22 }
23
24
25 Extrema_ExtElCS::Extrema_ExtElCS(const gp_Lin& C,
26                                  const gp_Pln& S)
27 {
28   Perform(C, S);
29 }
30
31
32
33 void Extrema_ExtElCS::Perform(const gp_Lin& C,
34                               const gp_Pln& S)
35 {
36   myDone = Standard_True;
37   myIsPar = Standard_False;
38
39   if (C.Direction().IsNormal(S.Axis().Direction(), 
40                              Precision::Angular())) {
41     mySqDist = new TColStd_HArray1OfReal(1, 1);
42     mySqDist->SetValue(1, S.SquareDistance(C));
43     myIsPar = Standard_True;
44   }
45   else {
46     myNbExt = 0;
47   }
48   
49 }
50
51
52 Extrema_ExtElCS::Extrema_ExtElCS(const gp_Lin& C,
53                                  const gp_Cylinder& S)
54 {
55   Perform(C, S);
56 }
57
58
59
60 void Extrema_ExtElCS::Perform(const gp_Lin& C,
61                               const gp_Cylinder& S)
62 {
63   myDone = Standard_False;
64   myNbExt = 0;
65   myIsPar = Standard_False;
66
67   gp_Ax3 Pos = S.Position();
68 #ifdef DEB
69   gp_Pnt O = Pos.Location();
70 #else
71   Pos.Location();
72 #endif
73   Standard_Real radius = S.Radius();
74   Extrema_ExtElC Extrem(gp_Lin(Pos.Axis()), C, Precision::Angular());
75   if (Extrem.IsParallel()) {
76     mySqDist = new TColStd_HArray1OfReal(1, 1);
77     Standard_Real aDist = sqrt (Extrem.SquareDistance(1)) - radius;
78     mySqDist->SetValue(1, aDist * aDist);
79     myDone = Standard_True;
80     myIsPar = Standard_True;
81   }
82   else {
83     Standard_Integer i;
84     if (Extrem.IsDone()) {
85       Extrema_POnCurv myPOnC1, myPOnC2;
86       Extrem.Points(1, myPOnC1, myPOnC2);
87       gp_Pnt PC = myPOnC2.Value();
88
89       if ((gp_Lin(Pos.Axis())).Contains(PC, Precision::Confusion())) {
90         gp_Dir D = C.Direction();
91         gp_Vec Dp(-D.Dot(Pos.YDirection()), D.Dot(Pos.XDirection()), 0.0);
92         Standard_Real U, V;
93         gp_Pnt P1(PC.Translated(radius*Dp));
94         gp_Pnt P2(PC.Translated(-radius*Dp));
95         
96         myNbExt = 2;
97         mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
98         myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
99         myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
100         ElSLib::CylinderParameters(Pos, radius, P1, U, V);
101         Extrema_POnSurf P1S(U, V, P1);
102         ElSLib::CylinderParameters(Pos, radius, P2, U, V);
103         Extrema_POnSurf P2S(U, V, P2);
104         mySqDist->SetValue(1, PC.SquareDistance(P1));
105         mySqDist->SetValue(2, PC.SquareDistance(P2));
106         myPoint1->SetValue(1, myPOnC2);
107         myPoint1->SetValue(2, myPOnC2);
108         myPoint2->SetValue(1, P1S);
109         myPoint2->SetValue(2, P2S);
110       }
111       else {
112         Extrema_ExtPElS ExPS(myPOnC2.Value(), S, Precision::Confusion());
113         if (ExPS.IsDone()) {
114           myNbExt = ExPS.NbExt();
115           mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
116           myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
117           myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
118           for (i = 1; i <= myNbExt; i++) {
119             myPoint1->SetValue(i, myPOnC2);
120             myPoint2->SetValue(i, ExPS.Point(i));
121             mySqDist->SetValue(i,(myPOnC2.Value()).SquareDistance(ExPS.Point(i).Value()));
122           }
123         }
124       }
125       myDone = Standard_True;
126     }
127   }
128
129 }
130
131
132
133 Extrema_ExtElCS::Extrema_ExtElCS(const gp_Lin& C,
134                                  const gp_Cone& S)
135 {
136   Perform(C, S);
137 }
138
139
140
141 //void Extrema_ExtElCS::Perform(const gp_Lin& C,
142 //                            const gp_Cone& S)
143 void Extrema_ExtElCS::Perform(const gp_Lin& ,
144                               const gp_Cone& )
145 {
146   Standard_NotImplemented::Raise();
147
148 }
149
150
151
152 Extrema_ExtElCS::Extrema_ExtElCS(const gp_Lin& C,
153                                  const gp_Sphere& S)
154 {
155   Perform(C, S);
156 }
157
158
159
160 void Extrema_ExtElCS::Perform(const gp_Lin& C,
161                               const gp_Sphere& S)
162 {
163   myDone = Standard_False;
164   myNbExt = 0;
165   myIsPar = Standard_False;
166
167   gp_Pnt O = S.Location();
168
169   Extrema_ExtPElC Extrem(O, C, Precision::Angular(), RealFirst(), RealLast());
170
171   Standard_Integer i;
172   if (Extrem.IsDone()) {
173     Extrema_POnCurv myPOnC1 =  Extrem.Point(1);
174     Extrema_ExtPElS ExPS(myPOnC1.Value(), S, Precision::Confusion());
175     if (ExPS.IsDone()) {
176       myNbExt = ExPS.NbExt();
177       mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
178       myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
179       myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
180       for (i = 1; i <= myNbExt; i++) {
181         myPoint1->SetValue(i, myPOnC1);
182         myPoint2->SetValue(i, ExPS.Point(i));
183         mySqDist->SetValue(i,(myPOnC1.Value()).SquareDistance(ExPS.Point(i).Value()));
184         myDone = Standard_True;
185       }
186     }
187   }
188 }
189
190
191 Extrema_ExtElCS::Extrema_ExtElCS(const gp_Lin& C,
192                                  const gp_Torus& S)
193 {
194   Perform(C, S);
195 }
196
197
198
199 //void Extrema_ExtElCS::Perform(const gp_Lin& C,
200 //                            const gp_Torus& S)
201 void Extrema_ExtElCS::Perform(const gp_Lin& ,
202                               const gp_Torus& )
203 {
204   Standard_NotImplemented::Raise();
205
206 }
207
208
209 //        Circle-?
210
211 Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
212                                  const gp_Pln& S)
213 {
214   Perform(C, S);
215 }
216
217
218
219 //void Extrema_ExtElCS::Perform(const gp_Circ& C,
220 //                            const gp_Pln& S)
221 void Extrema_ExtElCS::Perform(const gp_Circ& ,
222                               const gp_Pln& )
223 {
224   Standard_NotImplemented::Raise();
225
226 }
227
228
229
230 Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
231                                  const gp_Cylinder& S)
232 {
233   Perform(C, S);
234 }
235
236
237
238 //  Modified by skv - Thu Jul  7 14:37:05 2005 OCC9134 Begin
239 // Implementation of the method.
240 void Extrema_ExtElCS::Perform(const gp_Circ& C,
241                               const gp_Cylinder& S)
242 {
243   myDone  = Standard_False;
244   myIsPar = Standard_False;
245   myNbExt = 0;
246
247   // Get an axis line of the cylinder.
248   gp_Lin anAxis(S.Axis());
249
250   // Compute extrema between the circle and the line.
251   Extrema_ExtElC anExtC(anAxis, C, 0.);
252
253   if (anExtC.IsDone()) {
254     if (anExtC.IsParallel()) {
255       myIsPar =     Standard_True;
256       mySqDist = new TColStd_HArray1OfReal(1, 1);
257       Standard_Real aDist = sqrt (anExtC.SquareDistance(1)) - S.Radius();
258       mySqDist->SetValue(1, aDist * aDist);
259     } else {
260       Standard_Integer aNbExt   = anExtC.NbExt();
261       gp_Pnt           aCenter  = C.Location();
262       Standard_Integer i;
263       Standard_Integer aCurI    = 1;
264       Standard_Real    aTolConf = Precision::Confusion();
265       Standard_Real    aCylRad  = S.Radius();
266
267       // Compute the extremas.
268       myNbExt  =     2*aNbExt;
269       mySqDist  = new TColStd_HArray1OfReal(1, myNbExt);
270       myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
271       myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
272
273       for (i = 1; i <= aNbExt; i++) {
274         Extrema_POnCurv aPOnAxis;
275         Extrema_POnCurv aPOnCirc;
276         Standard_Real   aSqDist = anExtC.SquareDistance(i);
277         Standard_Real   aDist = sqrt (aSqDist);
278
279         anExtC.Points(i, aPOnAxis, aPOnCirc);
280
281         if (aSqDist <= (aTolConf * aTolConf) || aCenter.IsEqual(aPOnAxis.Value(), aTolConf)) {
282           myNbExt -= 2;
283           continue;
284         }
285
286         gp_Dir           aDir(aPOnAxis.Value().XYZ().
287                               Subtracted(aPOnCirc.Value().XYZ()));
288         Standard_Real    aShift[2] = { aDist + aCylRad, aDist - aCylRad };
289         Standard_Integer j;
290
291         for (j = 0; j < 2; j++) {
292           gp_Vec aVec(aDir);
293           gp_Pnt aPntOnCyl;
294
295           aVec.Multiply(aShift[j]);
296           aPntOnCyl = aPOnCirc.Value().Translated(aVec);
297
298           Standard_Real aU;
299           Standard_Real aV;
300
301           ElSLib::Parameters(S, aPntOnCyl, aU, aV);
302
303           Extrema_POnSurf aPOnSurf(aU, aV, aPntOnCyl);
304
305           myPoint1->SetValue(aCurI, aPOnCirc);
306           myPoint2->SetValue(aCurI, aPOnSurf);
307           mySqDist->SetValue(aCurI++, aShift[j] * aShift[j]);
308         }
309       }
310     }
311
312     myDone = Standard_True;
313   }
314 }
315 //  Modified by skv - Thu Jul  7 14:37:05 2005 OCC9134 End
316
317
318
319 Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
320                                  const gp_Cone& S)
321 {
322   Perform(C, S);
323 }
324
325
326
327 //void Extrema_ExtElCS::Perform(const gp_Circ& C,
328 //                       const gp_Cone& S)
329 void Extrema_ExtElCS::Perform(const gp_Circ& ,
330                          const gp_Cone& )
331 {
332   Standard_NotImplemented::Raise();
333
334 }
335
336
337
338 Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
339                                  const gp_Sphere& S)
340 {
341   Perform(C, S);
342 }
343
344
345
346 //void Extrema_ExtElCS::Perform(const gp_Circ& C,
347 //                            const gp_Sphere& S)
348 void Extrema_ExtElCS::Perform(const gp_Circ& ,
349                               const gp_Sphere& )
350 {
351   Standard_NotImplemented::Raise();
352
353 }
354
355 Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
356                                  const gp_Torus& S)
357 {
358   Perform(C, S);
359 }
360
361
362
363 //void Extrema_ExtElCS::Perform(const gp_Circ& C,
364 //                            const gp_Torus& S)
365 void Extrema_ExtElCS::Perform(const gp_Circ& ,
366                               const gp_Torus& )
367 {
368   Standard_NotImplemented::Raise();
369
370 }
371
372 Extrema_ExtElCS::Extrema_ExtElCS(const gp_Hypr& C,
373                                  const gp_Pln& S)
374 {
375   Perform(C, S);
376 }
377
378
379
380 void Extrema_ExtElCS::Perform(const gp_Hypr& C,
381                               const gp_Pln& S)
382 {
383   myDone = Standard_True;
384   myIsPar = Standard_False;
385
386   gp_Ax2 Pos = C.Position();
387   gp_Dir NHypr = Pos.Direction();
388   gp_Dir NPln = S.Axis().Direction();
389
390   if (NHypr.IsParallel(NPln, Precision::Angular())) {
391
392     mySqDist = new TColStd_HArray1OfReal(1, 1);
393     mySqDist->SetValue(1, S.SquareDistance(C.Location()));
394     myIsPar = Standard_True;
395
396   }
397   else {
398
399     gp_Dir XDir = Pos.XDirection();
400     gp_Dir YDir = Pos.YDirection();
401
402     Standard_Real A = C.MinorRadius()*(NPln.Dot(YDir)); 
403     Standard_Real B = C.MajorRadius()*(NPln.Dot(XDir)); 
404
405     if(Abs(B) > Abs(A)) {
406       Standard_Real T = -0.5 * Log((A+B)/(B-A));
407       gp_Pnt Ph = ElCLib::HyperbolaValue(T, Pos, C.MajorRadius(), C.MinorRadius());
408       Extrema_POnCurv PC(T, Ph);
409       myPoint1 = new Extrema_HArray1OfPOnCurv(1,1);
410       myPoint1->SetValue(1, PC);
411
412       mySqDist = new TColStd_HArray1OfReal(1, 1);
413       mySqDist->SetValue(1, S.SquareDistance(Ph));
414
415       Standard_Real U, V;
416       ElSLib::PlaneParameters(S.Position(), Ph, U, V);
417       gp_Pnt Pp = ElSLib::PlaneValue(U, V, S.Position());
418       Extrema_POnSurf PS(U, V, Pp);
419       myPoint2 = new Extrema_HArray1OfPOnSurf(1,1);
420       myPoint2->SetValue(1, PS);
421
422       myNbExt = 1;
423     }
424     else {
425       myNbExt = 0;
426     }
427
428   }
429   
430 }
431
432
433 Standard_Boolean Extrema_ExtElCS::IsDone() const
434 {
435   return myDone;
436 }
437
438
439 Standard_Integer Extrema_ExtElCS::NbExt() const
440 {
441   if (myIsPar) StdFail_InfiniteSolutions::Raise();
442   return myNbExt;
443 }
444
445 Standard_Real Extrema_ExtElCS::SquareDistance(const Standard_Integer N) const
446 {
447   if (myIsPar && N != 1) StdFail_InfiniteSolutions::Raise();
448   return mySqDist->Value(N);
449 }
450
451
452 void Extrema_ExtElCS::Points(const Standard_Integer N,
453                              Extrema_POnCurv& P1,
454                              Extrema_POnSurf& P2) const
455 {
456   if (myIsPar) StdFail_InfiniteSolutions::Raise();
457   P1 = myPoint1->Value(N);
458   P2 = myPoint2->Value(N);
459 }
460
461
462 Standard_Boolean Extrema_ExtElCS::IsParallel() const
463 {
464   return myIsPar;
465 }