0031035: Coding - uninitialized class fields reported by Visual Studio Code Analysis
[occt.git] / src / CPnts / CPnts_AbscissaPoint.cxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 //------------------------------------------------------------------------
16 //  Calculate a point with given abscissa starting from a given point 
17 //  cases processed: straight segment, arc of circle, parameterized curve
18 //  curve should be C1
19 //  for a parameterized curve:
20 //  calculate the total length of the curve
21 //  calculate an approached point by assimilating the curve to a staight line
22 //  calculate the length of the curve between the start point and the approached point
23 //  by succsessive iteration find the point and its associated parameter
24 //  call to FunctionRoot
25
26 #include <Adaptor2d_Curve2d.hxx>
27 #include <Adaptor3d_Curve.hxx>
28 #include <CPnts_AbscissaPoint.hxx>
29 #include <Geom2d_BezierCurve.hxx>
30 #include <Geom2d_BSplineCurve.hxx>
31 #include <Geom_BezierCurve.hxx>
32 #include <Geom_BSplineCurve.hxx>
33 #include <gp_Vec.hxx>
34 #include <gp_Vec2d.hxx>
35 #include <math_FunctionRoot.hxx>
36 #include <math_GaussSingleIntegration.hxx>
37 #include <Precision.hxx>
38 #include <Standard_ConstructionError.hxx>
39 #include <StdFail_NotDone.hxx>
40
41 // auxiliary functions to compute the length of the derivative
42 static Standard_Real f3d(const Standard_Real X, const Standard_Address C)
43 {
44   gp_Pnt P;
45   gp_Vec V;
46   ((Adaptor3d_Curve*)C)->D1(X,P,V);
47   return V.Magnitude();
48 }
49
50 static Standard_Real f2d(const Standard_Real X, const Standard_Address C)
51 {
52   gp_Pnt2d P;
53   gp_Vec2d V;
54   ((Adaptor2d_Curve2d*)C)->D1(X,P,V);
55   return V.Magnitude();
56 }
57
58 static Standard_Integer order(const Adaptor3d_Curve& C)
59 {
60   switch (C.GetType()) {
61     
62   case GeomAbs_Line :
63     return 2;
64
65   case GeomAbs_Parabola :
66     return 5;
67
68   case GeomAbs_BezierCurve :
69     return Min(24, 2*C.Degree());
70
71   case GeomAbs_BSplineCurve :
72     return Min(24, 2*C.NbPoles()-1);
73     
74     default :
75       return 10;
76   }
77 }
78
79 static Standard_Integer order(const Adaptor2d_Curve2d& C)
80 {
81   switch (C.GetType()) {
82     
83   case GeomAbs_Line :
84     return 2;
85
86   case GeomAbs_Parabola :
87     return 5;
88
89   case GeomAbs_BezierCurve :
90     return Min(24, 2*C.Bezier()->Degree());
91
92   case GeomAbs_BSplineCurve :
93     return Min(24, 2*C.BSpline()->NbPoles()-1);
94     
95     default :
96       return 10;
97   }
98 }
99
100
101 //=======================================================================
102 //function : Length
103 //purpose  : 3d
104 //=======================================================================
105
106 Standard_Real CPnts_AbscissaPoint::Length(const Adaptor3d_Curve& C) 
107 {
108   return CPnts_AbscissaPoint::Length(C, C.FirstParameter(), 
109                                         C.LastParameter());
110 }
111
112 //=======================================================================
113 //function : Length
114 //purpose  : 2d
115 //=======================================================================
116
117 Standard_Real CPnts_AbscissaPoint::Length(const Adaptor2d_Curve2d& C) 
118 {
119   return CPnts_AbscissaPoint::Length(C, C.FirstParameter(), 
120                                         C.LastParameter());
121 }
122
123 //=======================================================================
124 //function : Length
125 //purpose  : 3d with tolerance
126 //=======================================================================
127
128 Standard_Real CPnts_AbscissaPoint::Length(const Adaptor3d_Curve& C, const Standard_Real Tol) 
129 {
130   return CPnts_AbscissaPoint::Length(C, C.FirstParameter(), 
131                                         C.LastParameter(), Tol);
132 }
133
134 //=======================================================================
135 //function : Length
136 //purpose  : 2d with tolerance
137 //=======================================================================
138
139 Standard_Real CPnts_AbscissaPoint::Length(const Adaptor2d_Curve2d& C, const Standard_Real Tol) 
140 {
141   return CPnts_AbscissaPoint::Length(C, C.FirstParameter(), 
142                                         C.LastParameter(), Tol);
143 }
144
145
146 //=======================================================================
147 //function : Length
148 //purpose  : 3d with parameters
149 //=======================================================================
150
151 Standard_Real CPnts_AbscissaPoint::Length(const Adaptor3d_Curve& C,
152                                           const Standard_Real U1,
153                                           const Standard_Real U2) 
154 {
155   CPnts_MyGaussFunction FG;
156 //POP pout WNT
157   CPnts_RealFunction rf = f3d;
158   FG.Init(rf,(Standard_Address)&C);
159 //  FG.Init(f3d,(Standard_Address)&C);
160   math_GaussSingleIntegration TheLength(FG, U1, U2, order(C));
161   if (!TheLength.IsDone()) {
162     throw Standard_ConstructionError();
163   }
164   return Abs(TheLength.Value());
165 }
166
167 //=======================================================================
168 //function : Length
169 //purpose  : 2d with parameters
170 //=======================================================================
171
172 Standard_Real CPnts_AbscissaPoint::Length(const Adaptor2d_Curve2d& C,
173                                           const Standard_Real U1,
174                                           const Standard_Real U2) 
175 {
176   CPnts_MyGaussFunction FG;
177 //POP pout WNT
178   CPnts_RealFunction rf = f2d;
179   FG.Init(rf,(Standard_Address)&C);
180 //  FG.Init(f2d,(Standard_Address)&C);
181   math_GaussSingleIntegration TheLength(FG, U1, U2, order(C));
182   if (!TheLength.IsDone()) {
183     throw Standard_ConstructionError();
184   }
185   return Abs(TheLength.Value());
186 }
187
188 //=======================================================================
189 //function : Length
190 //purpose  : 3d with parameters and tolerance
191 //=======================================================================
192
193 Standard_Real CPnts_AbscissaPoint::Length(const Adaptor3d_Curve& C,
194                                           const Standard_Real U1,
195                                           const Standard_Real U2,
196                                           const Standard_Real Tol) 
197 {
198   CPnts_MyGaussFunction FG;
199 //POP pout WNT
200   CPnts_RealFunction rf = f3d;
201   FG.Init(rf,(Standard_Address)&C);
202 //  FG.Init(f3d,(Standard_Address)&C);
203   math_GaussSingleIntegration TheLength(FG, U1, U2, order(C), Tol);
204   if (!TheLength.IsDone()) {
205     throw Standard_ConstructionError();
206   }
207   return Abs(TheLength.Value());
208 }
209
210 //=======================================================================
211 //function : Length
212 //purpose  : 2d with parameters and tolerance
213 //=======================================================================
214
215 Standard_Real CPnts_AbscissaPoint::Length(const Adaptor2d_Curve2d& C,
216                                           const Standard_Real U1,
217                                           const Standard_Real U2,
218                                           const Standard_Real Tol) 
219 {
220   CPnts_MyGaussFunction FG;
221 //POP pout WNT
222   CPnts_RealFunction rf = f2d;
223   FG.Init(rf,(Standard_Address)&C);
224 //  FG.Init(f2d,(Standard_Address)&C);
225   math_GaussSingleIntegration TheLength(FG, U1, U2, order(C), Tol);
226   if (!TheLength.IsDone()) {
227     throw Standard_ConstructionError();
228   }
229   return Abs(TheLength.Value());
230 }
231
232 //=======================================================================
233 //function : CPnts_AbscissaPoint
234 //purpose  : 
235 //=======================================================================
236
237 CPnts_AbscissaPoint::CPnts_AbscissaPoint()
238 : myDone(Standard_False),
239   myL(0.0),
240   myParam(0.0),
241   myUMin(0.0),
242   myUMax(0.0)
243 {
244 }
245
246 //=======================================================================
247 //function : CPnts_AbscissaPoint
248 //purpose  : 
249 //=======================================================================
250
251 CPnts_AbscissaPoint::CPnts_AbscissaPoint(const Adaptor3d_Curve& C,
252                                          const Standard_Real   Abscissa,
253                                          const Standard_Real   U0,
254                                          const Standard_Real   Resolution)
255 {
256 //  Init(C);
257   Init(C, Resolution); //rbv's modification
258 //
259   Perform(Abscissa, U0, Resolution);
260 }
261
262 //=======================================================================
263 //function : CPnts_AbscissaPoint
264 //purpose  : 
265 //=======================================================================
266
267 CPnts_AbscissaPoint::CPnts_AbscissaPoint(const Adaptor2d_Curve2d& C,
268                                          const Standard_Real   Abscissa,
269                                          const Standard_Real   U0,
270                                          const Standard_Real   Resolution)
271 {
272   Init(C);
273   Perform(Abscissa, U0, Resolution);
274 }
275
276
277 //=======================================================================
278 //function : CPnts_AbscissaPoint
279 //purpose  : 
280 //=======================================================================
281
282 CPnts_AbscissaPoint::CPnts_AbscissaPoint(const Adaptor3d_Curve& C,
283                                          const Standard_Real   Abscissa,
284                                          const Standard_Real   U0,
285                                          const Standard_Real   Ui,
286                                          const Standard_Real   Resolution)
287 {
288   Init(C);
289   Perform(Abscissa, U0, Ui, Resolution);
290 }
291
292 //=======================================================================
293 //function : CPnts_AbscissaPoint
294 //purpose  : 
295 //=======================================================================
296
297 CPnts_AbscissaPoint::CPnts_AbscissaPoint(const Adaptor2d_Curve2d& C,
298                                          const Standard_Real   Abscissa,
299                                          const Standard_Real   U0,
300                                          const Standard_Real   Ui,
301                                          const Standard_Real   Resolution)
302 {
303   Init(C);
304   Perform(Abscissa, U0, Ui, Resolution);
305 }
306
307
308 //=======================================================================
309 //function : Init
310 //purpose  : 
311 //=======================================================================
312
313 void CPnts_AbscissaPoint::Init(const Adaptor3d_Curve& C)
314 {
315   Init(C,C.FirstParameter(),C.LastParameter());
316 }
317
318 //=======================================================================
319 //function : Init
320 //purpose  : 
321 //=======================================================================
322
323 void CPnts_AbscissaPoint::Init(const Adaptor2d_Curve2d& C)
324 {
325   Init(C,C.FirstParameter(),C.LastParameter());
326 }
327
328 //=======================================================================
329 //function : Init
330 //purpose  : introduced by rbv for curvilinear parametrization
331 //=======================================================================
332
333 void CPnts_AbscissaPoint::Init(const Adaptor3d_Curve& C, const Standard_Real Tol)
334 {
335   Init(C,C.FirstParameter(),C.LastParameter(), Tol);
336 }
337
338 //=======================================================================
339 //function : Init
340 //purpose  : 
341 //=======================================================================
342
343 void CPnts_AbscissaPoint::Init(const Adaptor2d_Curve2d& C, const Standard_Real Tol)
344 {
345   Init(C,C.FirstParameter(),C.LastParameter(), Tol);
346 }
347
348 //=======================================================================
349 //function : Init
350 //purpose  : 
351 //=======================================================================
352
353 void CPnts_AbscissaPoint::Init(const Adaptor3d_Curve& C,
354                                const Standard_Real  U1,
355                                const Standard_Real  U2)
356 {
357 //POP pout WNT
358   CPnts_RealFunction rf = f3d;
359   myF.Init(rf,(Standard_Address)&C,order(C));
360 //  myF.Init(f3d,(Standard_Address)&C,order(C));
361   myL = CPnts_AbscissaPoint::Length(C, U1, U2);
362   myUMin = Min(U1, U2);
363   myUMax = Max(U1, U2);
364   Standard_Real DU = myUMax - myUMin;
365   myUMin = myUMin - DU;
366   myUMax = myUMax + DU;
367 }
368
369 //=======================================================================
370 //function : Init
371 //purpose  : 
372 //=======================================================================
373
374 void CPnts_AbscissaPoint::Init(const Adaptor2d_Curve2d& C,
375                                const Standard_Real    U1,
376                                const Standard_Real    U2)
377 {
378 //POP pout WNT
379   CPnts_RealFunction rf = f2d;
380   myF.Init(rf,(Standard_Address)&C,order(C));
381 //  myF.Init(f2d,(Standard_Address)&C,order(C));
382   myL = CPnts_AbscissaPoint::Length(C, U1, U2);
383   myUMin = Min(U1, U2);
384   myUMax = Max(U1, U2);
385   Standard_Real DU = myUMax - myUMin;
386   myUMin = myUMin - DU;
387   myUMax = myUMax + DU;
388 }
389
390
391 //=======================================================================
392 //function : Init
393 //purpose  : introduced by rbv for curvilinear parametrization
394 //=======================================================================
395
396 void CPnts_AbscissaPoint::Init(const Adaptor3d_Curve& C,
397                                const Standard_Real  U1,
398                                const Standard_Real  U2,
399                                const Standard_Real  Tol)
400 {
401 //POP pout WNT
402   CPnts_RealFunction rf = f3d;
403   myF.Init(rf,(Standard_Address)&C,order(C));
404 //  myF.Init(f3d,(Standard_Address)&C,order(C));
405   myL = CPnts_AbscissaPoint::Length(C, U1, U2, Tol);
406   myUMin = Min(U1, U2);
407   myUMax = Max(U1, U2);
408   Standard_Real DU = myUMax - myUMin;
409   myUMin = myUMin - DU;
410   myUMax = myUMax + DU;
411 }
412
413 //=======================================================================
414 //function : Init
415 //purpose  : 
416 //=======================================================================
417
418 void CPnts_AbscissaPoint::Init(const Adaptor2d_Curve2d& C,
419                                const Standard_Real    U1,
420                                const Standard_Real    U2,
421                                const Standard_Real    Tol)
422 {
423 //POP pout WNT
424   CPnts_RealFunction rf = f2d;
425   myF.Init(rf,(Standard_Address)&C,order(C));
426 //  myF.Init(f2d,(Standard_Address)&C,order(C));
427   myL = CPnts_AbscissaPoint::Length(C, U1, U2, Tol);
428   myUMin = Min(U1, U2);
429   myUMax = Max(U1, U2);
430   Standard_Real DU = myUMax - myUMin;
431   myUMin = myUMin - DU;
432   myUMax = myUMax + DU;
433 }
434
435 //=======================================================================
436 //function : Perform
437 //purpose  : 
438 //=======================================================================
439
440 void CPnts_AbscissaPoint::Perform(const Standard_Real   Abscissa,
441                                   const Standard_Real   U0,
442                                   const Standard_Real   Resolution) 
443 {
444   if (myL < Precision::Confusion()) {
445     //
446     //  leave less violently : it is expected that 
447     //  the increment of the level of myParam will not be great
448     //
449     myDone = Standard_True ;
450     myParam = U0 ;
451   
452   }
453   else {
454     Standard_Real Ui = U0 + (Abscissa / myL) * (myUMax - myUMin) / 3.;
455     // exercice : why 3 ?
456     Perform(Abscissa,U0,Ui,Resolution);
457   }
458 }
459
460 //=======================================================================
461 //function : Perform
462 //purpose  : 
463 //=======================================================================
464
465 void CPnts_AbscissaPoint::Perform(const Standard_Real   Abscissa,
466                                   const Standard_Real   U0,
467                                   const Standard_Real   Ui,
468                                   const Standard_Real   Resolution) 
469 {
470   if (myL < Precision::Confusion()) {
471     //
472     //  leave less violently :
473     //
474     myDone = Standard_True ;
475     myParam = U0 ;
476   }
477   else {
478     myDone = Standard_False;
479     myF.Init(U0, Abscissa);
480
481     math_FunctionRoot Solution(myF, Ui, Resolution, myUMin, myUMax);
482     
483 // Temporarily suspend the validity test of the solution
484 // it is necessary to make a tolreached as soon as one will make a cdl
485 // lbo 21/03/97
486 //    if (Solution.IsDone()) {
487 //      Standard_Real D;
488 //      myF.Derivative(Solution.Root(),D);
489 //      if (Abs(Solution.Value()) < Resolution * D) {
490 //      myDone = Standard_True;
491 //      myParam = Solution.Root();
492 //      }
493 //    }
494     if (Solution.IsDone()) {
495       myDone = Standard_True;
496       myParam = Solution.Root();
497     }
498   }
499 }
500
501 //=======================================================================
502 //function : AdvPerform
503 //purpose  : 
504 //=======================================================================
505
506 void CPnts_AbscissaPoint::AdvPerform(const Standard_Real   Abscissa,
507                                   const Standard_Real   U0,
508                                   const Standard_Real   Ui,
509                                   const Standard_Real   Resolution) 
510 {
511   if (myL < Precision::Confusion()) {
512     //
513     //  leave less violently :
514     //
515     myDone = Standard_True ;
516     myParam = U0 ;
517   }
518   else {
519     myDone = Standard_False;
520 //    myF.Init(U0, Abscissa);
521     myF.Init(U0, Abscissa, Resolution/10); // rbv's modification
522
523     math_FunctionRoot Solution(myF, Ui, Resolution, myUMin, myUMax);
524     
525 // Temporarily suspend the validity test of the solution
526 // it is necessary to make a tolreached as soon as one will make a cdl
527 // lbo 21/03/97
528 //    if (Solution.IsDone()) {
529 //      Standard_Real D;
530 //      myF.Derivative(Solution.Root(),D);
531 //      if (Abs(Solution.Value()) < Resolution * D) {
532 //      myDone = Standard_True;
533 //      myParam = Solution.Root();
534 //      }
535 //    }
536     if (Solution.IsDone()) {
537       myDone = Standard_True;
538       myParam = Solution.Root();
539     }
540   }
541 }