0031035: Coding - uninitialized class fields reported by Visual Studio Code Analysis
[occt.git] / src / GeomAPI / GeomAPI_ExtremaCurveCurve.cxx
1 // Created on: 1994-03-18
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <Extrema_ExtCC.hxx>
19 #include <Geom_Curve.hxx>
20 #include <GeomAdaptor_Curve.hxx>
21 #include <GeomAPI_ExtremaCurveCurve.hxx>
22 #include <GeomAPI_ProjectPointOnCurve.hxx>
23 #include <gp_Pnt.hxx>
24 #include <Precision.hxx>
25 #include <Standard_OutOfRange.hxx>
26 #include <StdFail_NotDone.hxx>
27
28 //#include <Extrema_POnCurv.hxx>
29 //=======================================================================
30 //function : GeomAPI_ExtremaCurveCurve
31 //purpose  : 
32 //=======================================================================
33 GeomAPI_ExtremaCurveCurve::GeomAPI_ExtremaCurveCurve()
34 : myIsDone(Standard_False),
35   myIndex(0),
36   myTotalExt(Standard_False),
37   myIsInfinite(Standard_False),
38   myTotalDist(0.0)
39 {
40   memset (myTotalPars, 0, sizeof (myTotalPars));
41 }
42
43
44 //=======================================================================
45 //function : GeomAPI_ExtremaCurveCurve
46 //purpose  : 
47 //=======================================================================
48
49 GeomAPI_ExtremaCurveCurve::GeomAPI_ExtremaCurveCurve
50   (const Handle(Geom_Curve)& C1,
51    const Handle(Geom_Curve)& C2)
52 {
53   Init(C1,C2);
54 }
55
56
57 //=======================================================================
58 //function : GeomAPI_ExtremaCurveCurve
59 //purpose  : 
60 //=======================================================================
61
62 GeomAPI_ExtremaCurveCurve::GeomAPI_ExtremaCurveCurve
63   (const Handle(Geom_Curve)& C1,
64    const Handle(Geom_Curve)& C2,
65    const Standard_Real       U1min,
66    const Standard_Real       U1max,
67    const Standard_Real       U2min,
68    const Standard_Real       U2max)
69 {
70   Init(C1,C2,U1min,U1max,U2min,U2max);
71 }
72
73
74 //=======================================================================
75 //function : Init
76 //purpose  : 
77 //=======================================================================
78
79 void GeomAPI_ExtremaCurveCurve::Init
80   (const Handle(Geom_Curve)& C1,
81    const Handle(Geom_Curve)& C2)
82 {
83
84   myTotalExt = Standard_False;
85   
86   Standard_Real Tol = Precision::PConfusion();
87   myC1.Load(C1);
88   myC2.Load(C2);
89   Extrema_ExtCC theExtCC(myC1, myC2, Tol,Tol);
90   myExtCC = theExtCC;
91
92   myIsDone = myExtCC.IsDone() && ( myExtCC.NbExt() > 0);
93
94   if ( myIsDone) {
95
96     // evaluate the lower distance and its index;
97     
98     Standard_Real Dist2, Dist2Min = myExtCC.SquareDistance(1);
99     myIndex = 1;
100     
101     for ( Standard_Integer i = 2; i <= myExtCC.NbExt(); i++) {
102       Dist2 = myExtCC.SquareDistance(i);
103       if ( Dist2 < Dist2Min) {
104         Dist2Min = Dist2;
105         myIndex = i;
106       }
107     }
108   }
109 }
110
111
112 //=======================================================================
113 //function : Init
114 //purpose  : 
115 //=======================================================================
116
117 void GeomAPI_ExtremaCurveCurve::Init
118   (const Handle(Geom_Curve)& C1,
119    const Handle(Geom_Curve)& C2,
120    const Standard_Real       U1min,
121    const Standard_Real       U1max,
122    const Standard_Real       U2min,
123    const Standard_Real       U2max)
124 {
125  
126   myTotalExt = Standard_False;
127
128   Standard_Real Tol = Precision::PConfusion();
129   myC1.Load(C1);
130   myC2.Load(C2);
131   Extrema_ExtCC theExtCC(myC1,myC2,U1min,U1max,U2min,U2max,Tol,Tol);
132   myExtCC = theExtCC;
133
134   myIsDone = myExtCC.IsDone() && ( myExtCC.NbExt() > 0 );
135
136   if ( myIsDone) {
137
138     // evaluate the lower distance and its index;
139     
140     Standard_Real Dist2, Dist2Min = myExtCC.SquareDistance(1);
141     myIndex = 1;
142     
143     for ( Standard_Integer i = 2; i <= myExtCC.NbExt(); i++) {
144       Dist2 = myExtCC.SquareDistance(i);
145       if ( Dist2 < Dist2Min) {
146         Dist2Min = Dist2;
147         myIndex = i;
148       }
149     }
150   }
151 }
152
153
154 //=======================================================================
155 //function : NbExtrema
156 //purpose  : 
157 //=======================================================================
158
159 Standard_Integer GeomAPI_ExtremaCurveCurve::NbExtrema() const 
160 {
161   if ( myIsDone)
162     return myExtCC.NbExt();
163   else
164     return 0;
165 }
166
167
168 //=======================================================================
169 //function : Points
170 //purpose  : 
171 //=======================================================================
172
173 void GeomAPI_ExtremaCurveCurve::Points
174   (const Standard_Integer Index,
175          gp_Pnt&          P1,
176          gp_Pnt&          P2) const 
177 {
178   Standard_OutOfRange_Raise_if( Index < 1 || Index > NbExtrema(),
179                                "GeomAPI_ExtremaCurveCurve::Points");
180
181   Extrema_POnCurv PC1, PC2;
182   myExtCC.Points(Index,PC1,PC2);
183
184   P1 = PC1.Value();
185   P2 = PC2.Value();
186 }
187
188
189 //=======================================================================
190 //function : Parameters
191 //purpose  : 
192 //=======================================================================
193
194 void GeomAPI_ExtremaCurveCurve::Parameters
195   (const Standard_Integer Index, 
196          Standard_Real&   U1,
197          Standard_Real&   U2) const 
198 {
199   Standard_OutOfRange_Raise_if( Index < 1 || Index > NbExtrema(),
200                                "GeomAPI_ExtremaCurveCurve::Parameters");
201
202   Extrema_POnCurv PC1, PC2;
203   myExtCC.Points(Index,PC1,PC2);
204
205   U1 = PC1.Parameter();
206   U2 = PC2.Parameter();
207 }
208
209
210 //=======================================================================
211 //function : Distance
212 //purpose  : 
213 //=======================================================================
214
215 Standard_Real GeomAPI_ExtremaCurveCurve::Distance
216   (const Standard_Integer Index) const 
217 {
218   Standard_OutOfRange_Raise_if( Index < 1 || Index > NbExtrema(),
219                                "GeomAPI_ExtremaCurveCurve::Distance");
220
221   return sqrt (myExtCC.SquareDistance(Index));
222 }
223
224
225 //=======================================================================
226 //function : NearestPoints
227 //purpose  : 
228 //=======================================================================
229
230 void GeomAPI_ExtremaCurveCurve::NearestPoints(gp_Pnt& P1, gp_Pnt& P2) const 
231 {
232   StdFail_NotDone_Raise_if
233     (!myIsDone, "GeomAPI_ExtremaCurveCurve::NearestPoints");
234
235   Points(myIndex,P1,P2);
236 }
237
238
239 //=======================================================================
240 //function : LowerDistanceParameters
241 //purpose  : 
242 //=======================================================================
243
244 void GeomAPI_ExtremaCurveCurve::LowerDistanceParameters
245   (Standard_Real& U1,
246    Standard_Real& U2) const 
247 {
248   StdFail_NotDone_Raise_if
249     (!myIsDone, "GeomAPI_ExtremaCurveCurve::LowerDistanceParameters");
250
251   Parameters(myIndex,U1,U2);
252 }
253
254
255 //=======================================================================
256 //function : LowerDistance
257 //purpose  : 
258 //=======================================================================
259
260 Standard_Real GeomAPI_ExtremaCurveCurve::LowerDistance() const 
261 {
262   StdFail_NotDone_Raise_if
263     (!myIsDone, "GeomAPI_ExtremaCurveCurve::LowerDistance");
264
265   return sqrt (myExtCC.SquareDistance(myIndex));
266 }
267
268
269 //=======================================================================
270 //function : Standard_Real
271 //purpose  : 
272 //=======================================================================
273
274 GeomAPI_ExtremaCurveCurve::operator Standard_Real() const
275 {
276   return LowerDistance();
277 }
278
279
280 //=======================================================================
281 //function : Standard_Integer
282 //purpose  : 
283 //=======================================================================
284
285 GeomAPI_ExtremaCurveCurve::operator Standard_Integer() const
286 {
287   return myExtCC.NbExt();
288 }
289
290
291 Standard_Boolean GeomAPI_ExtremaCurveCurve::TotalNearestPoints(gp_Pnt& P1,gp_Pnt& P2) 
292 {
293
294   if(!myTotalExt) {
295
296     TotalPerform();
297     myTotalExt = Standard_True;
298
299   }
300
301   if(myIsInfinite) return Standard_False;
302
303   P1 = myTotalPoints[0];
304   P2 = myTotalPoints[1];
305
306   return Standard_True;
307     
308 }
309
310 Standard_Boolean GeomAPI_ExtremaCurveCurve::TotalLowerDistanceParameters(Standard_Real& U1, 
311                                                                          Standard_Real& U2) 
312 {
313   if(!myTotalExt) {
314
315     TotalPerform();
316     myTotalExt = Standard_True;
317
318   }
319
320   if(myIsInfinite) return Standard_False;
321
322   U1 = myTotalPars[0];
323   U2 = myTotalPars[1];
324
325   return Standard_True;
326
327 }
328
329 Standard_Real GeomAPI_ExtremaCurveCurve::TotalLowerDistance() 
330 {
331   if(!myTotalExt) {
332
333     TotalPerform();
334     myTotalExt = Standard_True;
335
336   }
337
338   return myTotalDist;
339
340 }
341
342
343 void GeomAPI_ExtremaCurveCurve::TotalPerform()
344
345 {
346 //  StdFail_NotDone_Raise_if
347 //    (!myExtCC.IsDone(), "GeomAPI_ExtremaCurveCurve::TotalPerform");
348
349   Standard_Real u11 = myC1.FirstParameter();
350   Standard_Real u12 = myC1.LastParameter();
351   Standard_Real u21 = myC2.FirstParameter();
352   Standard_Real u22 = myC2.LastParameter();
353   
354   Standard_Boolean infinite = Precision::IsInfinite(u11) &&
355                               Precision::IsInfinite(u12) &&
356                               Precision::IsInfinite(u21) &&
357                               Precision::IsInfinite(u22);
358
359   myIsInfinite = Standard_False;
360
361   if(infinite && myExtCC.IsParallel()) {
362     
363     myIsInfinite = Standard_True;
364
365     //calculate distance between any suitable point on C1 and C2
366     
367     gp_Pnt PonC1 = myC1.Value(0.);
368     GeomAPI_ProjectPointOnCurve proj(PonC1, myC2.Curve());
369     myTotalDist = proj.LowerDistance();
370
371     return;
372
373   }
374
375   myTotalDist = RealLast();
376
377   if(myIsDone && !myExtCC.IsParallel()) {
378     
379     Points(myIndex, myTotalPoints[0], myTotalPoints[1]);
380     Parameters(myIndex, myTotalPars[0], myTotalPars[1]);
381     myTotalDist = sqrt (myExtCC.SquareDistance(myIndex));
382
383     if(myTotalDist <= Precision::Confusion()) return;
384
385   }
386
387   gp_Pnt P11, P12, P21, P22;
388   Standard_Real d11, d12, d21, d22;
389   myExtCC.TrimmedSquareDistances(d11, d12, d21, d22, P11, P12, P21, P22);
390
391   Standard_Real aTotalDist2 = myTotalDist * myTotalDist;
392   if(aTotalDist2  > d11) {
393     myTotalDist = sqrt (d11);
394     myTotalPoints[0] = P11;
395     myTotalPoints[1] = P21;
396     myTotalPars[0] = u11;
397     myTotalPars[1] = u21;
398     
399     if(myTotalDist <= Precision::Confusion()) return;
400     
401   }
402   
403   if(aTotalDist2 > d12) {
404     myTotalDist = sqrt (d12);
405     myTotalPoints[0] = P11;
406     myTotalPoints[1] = P22;
407     myTotalPars[0] = u11;
408     myTotalPars[1] = u22;
409     
410     if(myTotalDist <= Precision::Confusion()) return;
411     
412   }
413   
414   if(aTotalDist2 > d21) {
415     myTotalDist = sqrt (d21);
416     myTotalPoints[0] = P12;
417     myTotalPoints[1] = P21;
418     myTotalPars[0] = u12;
419     myTotalPars[1] = u21;
420     
421     if(myTotalDist <= Precision::Confusion()) return;
422     
423   }
424   
425   if(aTotalDist2 > d22) {
426     myTotalDist = sqrt (d22);
427     myTotalPoints[0] = P12;
428     myTotalPoints[1] = P22;
429     myTotalPars[0] = u12;
430     myTotalPars[1] = u22;
431     
432     if(myTotalDist <= Precision::Confusion()) return;
433     
434   }
435  
436   // calculate distances between extremities one curve and other curve
437
438   if(!Precision::IsInfinite(u11)) {
439     GeomAPI_ProjectPointOnCurve proj(P11, myC2.Curve(), u21, u22);  
440
441     if(proj.NbPoints() > 0) {
442
443       Standard_Real dmin = proj.LowerDistance();
444       if(myTotalDist > dmin) {
445         myTotalDist = dmin;
446         myTotalPoints[0] = P11;
447         myTotalPars[0] = u11;
448         myTotalPoints[1] = proj.NearestPoint();
449         myTotalPars[1] = proj.LowerDistanceParameter();
450
451         if(myTotalDist <= Precision::Confusion()) return;
452     
453       }
454     }
455   }
456
457   if(!Precision::IsInfinite(u12)) {
458     GeomAPI_ProjectPointOnCurve proj(P12, myC2.Curve(), u21, u22);  
459
460     if(proj.NbPoints() > 0) {
461
462       Standard_Real dmin = proj.LowerDistance();
463       if(myTotalDist > dmin) {
464         myTotalDist = dmin;
465         myTotalPoints[0] = P12;
466         myTotalPars[0] = u12;
467         myTotalPoints[1] = proj.NearestPoint();
468         myTotalPars[1] = proj.LowerDistanceParameter();
469
470         if(myTotalDist <= Precision::Confusion()) return;
471     
472       }
473     }
474   }
475
476   if(!Precision::IsInfinite(u21)) {
477     GeomAPI_ProjectPointOnCurve proj(P21, myC1.Curve(), u11, u12);  
478
479     if(proj.NbPoints() > 0) {
480
481       Standard_Real dmin = proj.LowerDistance();
482       if(myTotalDist > dmin) {
483         myTotalDist = dmin;
484         myTotalPoints[0] = proj.NearestPoint();
485         myTotalPars[0] = proj.LowerDistanceParameter();
486         myTotalPoints[1] = P21;
487         myTotalPars[1] = u21;
488
489         if(myTotalDist <= Precision::Confusion()) return;
490     
491       }
492     }
493   }
494
495   if(!Precision::IsInfinite(u22)) {
496     GeomAPI_ProjectPointOnCurve proj(P22, myC1.Curve(), u11, u12);  
497
498     if(proj.NbPoints() > 0) {
499
500       Standard_Real dmin = proj.LowerDistance();
501       if(myTotalDist > dmin) {
502         myTotalDist = dmin;
503         myTotalPoints[0] = proj.NearestPoint();
504         myTotalPars[0] = proj.LowerDistanceParameter();
505         myTotalPoints[1] = P22;
506         myTotalPars[1] = u22;
507     
508       }
509     }
510   }
511
512
513 }