0031035: Coding - uninitialized class fields reported by Visual Studio Code Analysis
[occt.git] / src / Extrema / Extrema_GLocateExtPC.gxx
1 // Created on: 1993-12-14
2 // Created by: Christophe MARION
3 // Copyright (c) 1993-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 // 05-Jun-00 : hla : meme type de corr. que xab : dans la methode "Perform",
18 //             suppression du test mal a propos "myintuinf > myintusup" avec
19 //             "return" a la suite.
20 // 05-Sep-95 : xab : correction d'un probleme de determination d'intervalle
21 //             de recherche
22
23 #include Extrema_ELPC_hxx
24 #include ThePOnC_hxx
25 #include ThePoint_hxx
26 #include TheVector_hxx
27 #include <StdFail_NotDone.hxx>
28 #include <Standard_DomainError.hxx>
29 #include <GeomAbs_CurveType.hxx>
30 #include <Precision.hxx>
31 #include <TColStd_Array1OfReal.hxx>
32
33
34 //=======================================================================
35 //function : Extrema_GLocateExtPC
36 //purpose  : 
37 //=======================================================================
38
39 Extrema_GLocateExtPC::Extrema_GLocateExtPC()
40 : myC(NULL),
41   mydist2(0.0),
42   myismin(Standard_False),
43   myDone(Standard_False),
44   myumin(0.0),
45   myusup(0.0),
46   mytol(0.0),
47   type(GeomAbs_OtherCurve),
48   numberext(0)
49 {
50 }
51
52
53 //=======================================================================
54 //function : Extrema_GLocateExtPC
55 //purpose  : 
56 //=======================================================================
57
58 Extrema_GLocateExtPC::Extrema_GLocateExtPC (const ThePoint&     P,
59   const TheCurve&     C,
60   const Standard_Real U0,
61   const Standard_Real TolF)
62 {
63   Initialize(C, TheCurveTool::FirstParameter(C), TheCurveTool::LastParameter(C), TolF);
64   Perform(P, U0);
65 }
66
67 //=======================================================================
68 //function : Extrema_GLocateExtPC
69 //purpose  : 
70 //=======================================================================
71
72 Extrema_GLocateExtPC::Extrema_GLocateExtPC (const ThePoint&     P,
73   const TheCurve&     C,
74   const Standard_Real U0, 
75   const Standard_Real Umin,
76   const Standard_Real Usup,
77   const Standard_Real TolF)
78 {
79   Initialize(C, Umin, Usup, TolF);
80   Perform(P, U0);
81 }
82
83
84
85 //=======================================================================
86 //function : Initialize
87 //purpose  : 
88 //=======================================================================
89
90 void Extrema_GLocateExtPC::Initialize(const TheCurve&     C, 
91   const Standard_Real Umin,
92   const Standard_Real Usup,
93   const Standard_Real TolF)
94 {
95   myC = (Standard_Address)&C;
96   mytol = TolF;
97   myumin = Umin;
98   myusup = Usup;
99   type = TheCurveTool::GetType(C);
100   Standard_Real tolu = TheCurveTool::Resolution(C, Precision::Confusion());
101   if ((type == GeomAbs_BSplineCurve) || 
102       (type == GeomAbs_BezierCurve)  || 
103       (type == GeomAbs_OffsetCurve)   ||
104       (type == GeomAbs_OtherCurve))
105   {
106       myLocExtPC.Initialize(C, Umin, Usup, tolu);
107   }
108   else {
109     myExtremPC.Initialize(C, Umin, Usup, tolu);
110   }
111 }
112
113
114
115
116 //=======================================================================
117 //function : Perform
118 //purpose  : 
119 //=======================================================================
120
121 void Extrema_GLocateExtPC::Perform(const ThePoint&     P,
122   const Standard_Real U0)
123 {
124   Standard_Integer i, i1, i2, inter;
125   Standard_Real Par, valU, valU2 = RealLast(),
126     local_u0 ;
127   Standard_Real myintuinf=0, myintusup=0;
128   local_u0 = U0 ;
129   switch(type)
130   {
131   case GeomAbs_OtherCurve:
132   case GeomAbs_OffsetCurve:
133   case GeomAbs_BSplineCurve:
134     {
135       // La recherche de l extremum est faite intervalle continu C2 par
136       // intervalle continu C2 de la courbe
137       Standard_Integer n = TheCurveTool::NbIntervals(*((TheCurve*)myC), GeomAbs_C2);
138       TColStd_Array1OfReal theInter(1, n+1);
139       TheCurveTool::Intervals(*((TheCurve*)myC), theInter, GeomAbs_C2);
140       //
141       //  be gentle with the caller 
142       //
143       if (local_u0 < myumin) {
144         local_u0 = myumin ; 
145       }
146       else if (local_u0 > myusup) {
147         local_u0  = myusup ;
148       }
149       // Recherche de l intervalle ou se trouve U0
150       Standard_Boolean found = Standard_False;
151       inter = 1;
152       while (!found && inter <= n) {
153         // Intervalle commun a l intervalle C2 courant de la courbe et a
154         // l intervalle total de recherche de l'extremum (hla : au cas ou
155         // myintuinf > myintusup, c est que les 2 intervalles ne s intersectent
156         // pas, mais il n'y avait aucune raison de sortir en "return")
157         myintuinf = Max(theInter(inter), myumin);
158         myintusup = Min(theInter(inter+1), myusup);
159         if ((local_u0 >= myintuinf) && (local_u0 < myintusup)) found = Standard_True;
160         inter++;
161       }
162
163       if( found ) inter--; //IFV 16.06.00 - inter is increased after found!
164
165       // Essai sur l intervalle trouve
166       myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf, 
167         myintusup, mytol);
168       myLocExtPC.Perform(P, local_u0);
169       myDone = myLocExtPC.IsDone();
170       if (myDone) {
171         mypp = myLocExtPC.Point();
172         myismin = myLocExtPC.IsMin();
173         mydist2 = myLocExtPC.SquareDistance();
174       }
175       else {
176         Standard_Integer k = 1;
177         // Essai sur les intervalles alentours:
178         i1 = inter;
179         i2 = inter;
180         Standard_Real s1inf, s2inf, s1sup, s2sup;
181         ThePoint P1;
182         TheVector V1;
183         TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1);
184         s2inf = (TheVector(P, P1)*V1);
185         TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1);
186         s1sup = (TheVector(P, P1)*V1);
187
188
189         while (!myDone && (i2 > 0) && (i1 <= n))
190         {
191           i1 = inter + k;
192           i2 = inter - k;
193           if (i1 <= n)
194           {
195             myintuinf = Max(theInter(i1), myumin);
196             myintusup = Min(theInter(i1+1), myusup);
197             if (myintuinf < myintusup)
198             {
199               TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1);
200               s2sup = (TheVector(P, P1)*V1);
201               if(Precision::IsInfinite(s2sup) || Precision::IsInfinite(s1sup))
202               {
203                 break;
204               }
205               if (s1sup*s2sup <= RealEpsilon())
206               {
207                 // extremum:
208                 myDone = Standard_True;
209                 mypp.SetValues(myintuinf, P1);
210                 myismin = (s1sup <= 0.0);
211                 mydist2 = P.SquareDistance(P1);
212                 break;
213               }
214
215               TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1);
216               s1sup = (TheVector(P, P1)*V1);
217               myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf, 
218                 myintusup, mytol);
219               myLocExtPC.Perform(P, (myintuinf + myintusup)*0.5);
220               myDone = myLocExtPC.IsDone();
221               if (myDone) {
222                 mypp = myLocExtPC.Point();
223                 myismin = myLocExtPC.IsMin();
224                 mydist2 = myLocExtPC.SquareDistance();
225                 break;
226               }
227             }
228           }
229
230           if (i2 > 0)
231           {
232             myintuinf = Max(theInter(i2), myumin);
233             myintusup = Min(theInter(i2+1), myusup);
234             if (myintuinf < myintusup)
235             {
236               TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1);
237               s1inf = (TheVector(P, P1)*V1);
238               if(Precision::IsInfinite(s2inf) || Precision::IsInfinite(s1inf))
239               {
240                 break;
241               }
242               if (s1inf*s2inf <= RealEpsilon())
243               {
244                 // extremum:
245                 myDone = Standard_True;
246                 mypp.SetValues(myintusup, P1);
247                 myismin = (s1inf <= 0.0);
248                 mydist2 = P.SquareDistance(P1);
249                 break;
250               }
251
252               TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1);
253               s2inf = (TheVector(P, P1)*V1);
254               myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf, 
255                 myintusup, mytol);
256               myLocExtPC.Perform(P, (myintuinf+myintusup)*0.5 );
257               myDone = myLocExtPC.IsDone();
258             
259               if (myDone)
260               {
261                 mypp = myLocExtPC.Point();
262                 myismin = myLocExtPC.IsMin();
263                 mydist2 = myLocExtPC.SquareDistance();
264                 break;
265               }
266             }
267           }
268
269           k++;
270         }
271       }
272     }
273
274     break;
275
276   case GeomAbs_BezierCurve:
277     {
278       myLocExtPC.Perform(P, U0);
279       myDone = myLocExtPC.IsDone();
280     }
281
282     break;
283   default:
284     {
285       myExtremPC.Perform(P);
286       numberext = 0;
287       if (myExtremPC.IsDone())
288       {
289         for (i = 1; i <= myExtremPC.NbExt(); i++)
290         {
291           Par = myExtremPC.Point(i).Parameter();
292           valU = Abs(Par - U0);
293           if (valU <= valU2)
294           {
295             valU2 = valU;
296             numberext = i;
297             myDone = Standard_True;
298           }
299         }
300       }
301
302       if (numberext == 0)
303         myDone = Standard_False;
304
305       break;
306     }
307   }
308 }
309
310
311
312
313 //=======================================================================
314 //function : IsDone
315 //purpose  : 
316 //=======================================================================
317
318 Standard_Boolean Extrema_GLocateExtPC::IsDone () const 
319 {
320   return myDone;
321 }
322
323
324 //=======================================================================
325 //function : Value
326 //purpose  : 
327 //=======================================================================
328
329 Standard_Real Extrema_GLocateExtPC::SquareDistance () const 
330 {
331   if (!IsDone())
332   {
333     throw StdFail_NotDone();
334   }
335   Standard_Real d=0;
336   if ((type == GeomAbs_BezierCurve)) {
337     d =  myLocExtPC.SquareDistance();
338   }
339   else if(type == GeomAbs_BSplineCurve ||
340           type == GeomAbs_OffsetCurve  ||
341           type == GeomAbs_OtherCurve) {
342     d = mydist2;
343   }
344   else {
345     if (numberext != 0) {
346       d = myExtremPC.SquareDistance(numberext);
347     }
348   }
349   return d;
350 }
351
352
353 //=======================================================================
354 //function : IsMin
355 //purpose  : 
356 //=======================================================================
357
358 Standard_Boolean Extrema_GLocateExtPC::IsMin () const 
359 {
360   if (!IsDone())
361   {
362     throw StdFail_NotDone();
363   }
364   Standard_Boolean b = 0;
365   if ((type == GeomAbs_BezierCurve)) {
366     b = myLocExtPC.IsMin();
367   }
368   else if(type == GeomAbs_BSplineCurve ||
369           type == GeomAbs_OffsetCurve  ||
370           type == GeomAbs_OtherCurve) {
371     b = myismin;
372   }
373   else {
374     if (numberext != 0) {
375       b = myExtremPC.IsMin(numberext);
376     }
377   }
378   return b;
379 }
380
381
382 //=======================================================================
383 //function : Point
384 //purpose  : 
385 //=======================================================================
386
387 const ThePOnC & Extrema_GLocateExtPC::Point () const 
388 {
389   if (!IsDone())
390   {
391     throw StdFail_NotDone();
392   }
393   if (type == GeomAbs_BezierCurve)
394   {
395     return myLocExtPC.Point();
396   }
397   else if(type == GeomAbs_BSplineCurve ||
398           type == GeomAbs_OffsetCurve  ||
399           type == GeomAbs_OtherCurve) {
400     return mypp;
401   }
402   return myExtremPC.Point(numberext);
403 }