0031035: Coding - uninitialized class fields reported by Visual Studio Code Analysis
[occt.git] / src / CPnts / CPnts_UniformDeflection.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 //                Algorithm concerns the constant arrow
17 // cases processed : parameterized curve 
18 //               the curve should be C2
19 // provide a max arrow
20 // algorithm of parameterized curve:
21 //   calculation of the step of advancement is 
22 //             du = sqrt(8*fleche*||P'(u)||/||P'(u)^P''(u)||
23 //   calculate each point such as u+Du
24 //   check if the arrow is actually taken into account, if yes, continue
25 //   otherwise correct the step
26 //   si du cannot be calculated (null curvature, singularity on the curve) 
27 //   take a constant step to reach the last point or to go past it
28 //   The last point is readjusted by the following criteria:
29 //     if the last calculated parameter is <2*resolution, reframe the last point found
30 //     between itself and the previous point and add the end point 
31 //     (avoid a concentration at the end)
32 //     otherwise if the distance (last calculated point, end point)<arrow, 
33 //     replace the last calculated point by the end point
34 //     otherwise calculate max arrow between the last but one calculated point
35 //     and the end point; if this arrow is greater than the arrow
36 //     replace the last point by this one and the end point
37 //    CONTROLS OF ARROW AND THE LAST POINT ARE DONE ONLY IF withControl=true
38 //   each iteration calculates at maximum 3 points
39 //-------------------------------------------------------------------------
40
41 #include <Adaptor2d_Curve2d.hxx>
42 #include <Adaptor3d_Curve.hxx>
43 #include <CPnts_UniformDeflection.hxx>
44 #include <gp_Pnt.hxx>
45 #include <gp_Pnt2d.hxx>
46 #include <gp_Vec.hxx>
47 #include <gp_Vec2d.hxx>
48 #include <Standard_ConstructionError.hxx>
49 #include <Standard_DomainError.hxx>
50 #include <Standard_OutOfRange.hxx>
51 #include <StdFail_NotDone.hxx>
52
53 static inline void D03d(const Standard_Address C, const Standard_Real U,
54                       gp_Pnt& P)
55 {
56   ((Adaptor3d_Curve*)C)->D0(U,P);
57 }
58
59 static  void D02d(const Standard_Address C, const Standard_Real U,
60                       gp_Pnt& PP)
61 {
62   gp_Pnt2d P;
63   ((Adaptor2d_Curve2d*)C)->D0(U,P);
64   PP.SetCoord(P.X(),P.Y(),0.);
65 }
66
67 static inline void D23d(const Standard_Address C, const Standard_Real U,
68                       gp_Pnt& P, gp_Vec& V1, gp_Vec& V2)
69 {
70   ((Adaptor3d_Curve*)C)->D2(U,P,V1,V2);
71 }
72
73 static  void D22d(const Standard_Address C, const Standard_Real U,
74                       gp_Pnt& PP, gp_Vec& VV1, gp_Vec& VV2)
75 {
76   gp_Pnt2d P;
77   gp_Vec2d V1,V2;
78   ((Adaptor2d_Curve2d*)C)->D2(U,P,V1,V2);
79   PP.SetCoord(P.X(),P.Y(),0.);
80   VV1.SetCoord(V1.X(),V1.Y(),0.);
81   VV2.SetCoord(V2.X(),V2.Y(),0.);
82 }
83
84 //=======================================================================
85 //function : Perform
86 //purpose  : 
87 //=======================================================================
88
89 void CPnts_UniformDeflection::Perform()
90 {
91   gp_Pnt P, P1, P2;
92 //  gp_Vec V1, V2, VV1, VV2, VV;
93   gp_Vec V1, V2, VV;
94   Standard_Real Un1; 
95   Standard_Real NormD1, NormD2;
96
97   myIPoint   = -1;
98   myNbPoints = -1;
99   
100   while ( (myNbPoints<2) && (!myFinish) ) {
101     
102     myNbPoints = myNbPoints + 1; 
103     myParams[myNbPoints] = myFirstParam;
104
105     if (my3d)
106       D23d(myCurve, myFirstParam, myPoints[myNbPoints], V1, V2);
107     else
108       D22d(myCurve, myFirstParam, myPoints[myNbPoints], V1, V2);
109     P = myPoints[myNbPoints] ;
110     NormD1 = V1.Magnitude();
111     if (NormD1 < myTolCur || V2.Magnitude() < myTolCur) {   
112       // singularity on the tangent or null curvature
113       myDu = Min(myDwmax, 1.5 * myDu);
114     }
115     else { 
116       NormD2 = V2.CrossMagnitude(V1);
117       if (NormD2 / NormD1 < myDeflection) {  // collinearity of derivatives
118         myDu = Min(myDwmax, 1.5 * myDu);            
119       }
120       else {
121         myDu = Sqrt(8.* myDeflection * NormD1 / NormD2 );
122         myDu = Min(Max(myDu, myTolCur), myDwmax);             
123       }
124     }
125     
126     // check if the arrow is observed if WithControl
127     
128     if (myControl) {
129       myDu = Min(myDu, myLastParam-myFirstParam);
130       if (my3d) {
131         
132         D03d(myCurve, myFirstParam + myDu,P);
133         D03d(myCurve, myFirstParam + (myDu / 2.0),P1);
134       }
135       else {
136         
137         D02d(myCurve, myFirstParam + myDu,P);
138         D02d(myCurve, myFirstParam + (myDu / 2.0),P1);
139       }
140       V1= gp_Vec(myPoints[myNbPoints], P);
141       NormD1 = V1.Magnitude(); 
142       if (NormD1 >= myDeflection) {
143         V2 = gp_Vec(myPoints[myNbPoints], P1);
144         NormD2 = V2.CrossMagnitude(V1) / NormD1;
145         
146         // passing of arrow starting from which the redivision is done is arbitrary
147         // probably it will be necessary to readjust it (differenciate the first point 
148         // from the others) this test does not work on the points of inflexion
149         
150         if (NormD2 > myDeflection / 5.0) {
151           NormD2 = Max(NormD2, 1.1 * myDeflection);
152           myDu = myDu * Sqrt(myDeflection / NormD2);
153           myDu = Min(Max(myDu, myTolCur), myDwmax);             
154         }
155       }
156     }
157     myFirstParam = myFirstParam + myDu;
158     myFinish = (myLastParam - myFirstParam < myTolCur) || (myDu == 0.);
159   }
160   if (myFinish) {
161     // the last point is corrected if control
162     if (myControl && (myNbPoints == 1) ) {
163       Un1 = myParams[0];
164       if (myLastParam - Un1 < 0.33*(myLastParam-myFirstParam)) {
165         myFirstParam = (myLastParam + Un1) / 2.0;
166         myParams[0]= myFirstParam;
167         myParams[1]= myLastParam;
168         if (my3d) {
169           D03d(myCurve, myParams[0], myPoints[0]);
170           D03d(myCurve, myParams[1], myPoints[1]);
171         }
172         else {
173           D02d(myCurve, myParams[0], myPoints[0]);
174           D02d(myCurve, myParams[1], myPoints[1]);
175         }
176       } 
177       else {
178         if (my3d) {
179           D23d(myCurve, myLastParam, P1, V1, V2);
180         }
181         else {
182           D22d(myCurve, myLastParam, P1, V1, V2);
183         }
184         P = myPoints[0] ;
185         VV = gp_Vec(P1, P);
186         NormD1 = VV.Magnitude();
187         if ( NormD1 < myDeflection) {
188           myParams[1]= myLastParam;
189           myPoints[1]= P1 ;
190         }
191         else {
192           myFirstParam = (myLastParam * (myParams[1] - Un1) + Un1 * myDu)
193               /(myFirstParam -Un1);
194           if (my3d)
195             D03d(myCurve, myFirstParam, P2);
196           else
197             D02d(myCurve, myFirstParam, P2);
198
199           if ((VV.CrossMagnitude(gp_Vec(P2, P)) / NormD1 < myDeflection) && 
200               (Un1 >= myLastParam - myDwmax) ) {
201             // point n is removed
202             myParams[1]= myLastParam;
203             myPoints[1] = P1 ;
204           }
205           else {
206             myParams[1]=myFirstParam;
207             myPoints[1] = P2 ;
208             myParams[2]=myLastParam;
209             myPoints[2] = P1 ;
210             myNbPoints = myNbPoints +1;  
211           }
212         }
213       }
214     }
215     else {
216       myNbPoints = myNbPoints +1 ;
217       if (myNbPoints >= 3) myNbPoints = 2;
218       myParams[myNbPoints]= myLastParam;
219       if (my3d) {
220           D03d(myCurve, myLastParam, myPoints[myNbPoints]);
221         }
222         else {
223           D02d(myCurve, myLastParam, myPoints[myNbPoints]);
224         }
225     }
226   }
227 }
228
229 //=======================================================================
230 //function : CPnts_UniformDeflection
231 //purpose  : 
232 //=======================================================================
233
234 CPnts_UniformDeflection::CPnts_UniformDeflection ()
235 : myDone(Standard_False),
236   my3d(Standard_False),
237   myFinish(Standard_False),
238   myTolCur(0.0),
239   myControl(Standard_False),
240   myIPoint(0),
241   myNbPoints(0),
242   myDwmax(0.0),
243   myDeflection(0.0),
244   myFirstParam(0.0),
245   myLastParam(0.0),
246   myDu(0.0)
247 {
248   memset (myParams, 0, sizeof (myParams));
249
250
251 //=======================================================================
252 //function : CPnts_UniformDeflection
253 //purpose  : 
254 //=======================================================================
255
256 CPnts_UniformDeflection::CPnts_UniformDeflection 
257                                        (const Adaptor3d_Curve& C, 
258                                         const Standard_Real Deflection,
259                                         const Standard_Real Resolution,
260                                         const Standard_Boolean WithControl)
261 {
262   Initialize(C, Deflection, Resolution, WithControl);
263 }
264
265 //=======================================================================
266 //function : CPnts_UniformDeflection
267 //purpose  : 
268 //=======================================================================
269
270 CPnts_UniformDeflection::CPnts_UniformDeflection 
271                                        (const Adaptor2d_Curve2d& C, 
272                                         const Standard_Real Deflection,
273                                         const Standard_Real Resolution,
274                                         const Standard_Boolean WithControl)
275 {
276   Initialize(C, Deflection, Resolution, WithControl);
277 }
278
279 //=======================================================================
280 //function : Initialize
281 //purpose  : 
282 //=======================================================================
283
284 void CPnts_UniformDeflection::Initialize(const Adaptor3d_Curve& C, 
285                                          const Standard_Real Deflection,
286                                          const Standard_Real Resolution,
287                                          const Standard_Boolean WithControl)
288 {
289   Initialize(C,Deflection,C.FirstParameter(),C.LastParameter(),
290              Resolution,WithControl);
291 }
292
293 //=======================================================================
294 //function : Initialize
295 //purpose  : 
296 //=======================================================================
297
298 void CPnts_UniformDeflection::Initialize(const Adaptor2d_Curve2d& C, 
299                                          const Standard_Real Deflection,
300                                          const Standard_Real Resolution,
301                                          const Standard_Boolean WithControl)
302 {
303   Initialize(C,Deflection,C.FirstParameter(),C.LastParameter(),
304              Resolution,WithControl);
305 }
306
307 //=======================================================================
308 //function : CPnts_UniformDeflection
309 //purpose  : 
310 //=======================================================================
311
312 CPnts_UniformDeflection ::CPnts_UniformDeflection
313                                       (const Adaptor3d_Curve& C,
314                                        const Standard_Real Deflection, 
315                                        const Standard_Real U1,
316                                        const Standard_Real U2,
317                                        const Standard_Real Resolution,
318                                        const Standard_Boolean WithControl)
319 {
320   Initialize(C, Deflection, U1, U2, Resolution, WithControl);
321 }
322
323 //=======================================================================
324 //function : CPnts_UniformDeflection
325 //purpose  : 
326 //=======================================================================
327
328 CPnts_UniformDeflection ::CPnts_UniformDeflection
329                                       (const Adaptor2d_Curve2d& C,
330                                        const Standard_Real Deflection, 
331                                        const Standard_Real U1,
332                                        const Standard_Real U2,
333                                        const Standard_Real Resolution,
334                                        const Standard_Boolean WithControl)
335 {
336   Initialize(C, Deflection, U1, U2, Resolution, WithControl);
337 }
338
339 //=======================================================================
340 //function : Initialize
341 //purpose  : 
342 //=======================================================================
343
344 void CPnts_UniformDeflection::Initialize (const Adaptor3d_Curve& C,
345                                           const Standard_Real Deflection, 
346                                           const Standard_Real U1,
347                                           const Standard_Real U2,
348                                           const Standard_Real Resolution,
349                                           const Standard_Boolean WithControl)
350 {
351   if (U1 > U2) {
352     myFirstParam = U2;
353     myLastParam  = U1;
354   }
355   else {
356     myFirstParam = U1;
357     myLastParam  = U2;
358   }
359   my3d         = Standard_True;
360   myDwmax      = myLastParam-myFirstParam;
361   myDu         = myDwmax/2. ;
362   myDone       = Standard_True;
363   myCurve      = (Standard_Address) &C;
364   myFinish     = Standard_False;
365   myTolCur     = Resolution;
366   myDeflection = Deflection;
367   myControl    = WithControl;
368   Perform();
369 }
370
371 //=======================================================================
372 //function : Initialize
373 //purpose  : 
374 //=======================================================================
375
376 void CPnts_UniformDeflection::Initialize (const Adaptor2d_Curve2d& C,
377                                           const Standard_Real Deflection, 
378                                           const Standard_Real U1,
379                                           const Standard_Real U2,
380                                           const Standard_Real Resolution,
381                                           const Standard_Boolean WithControl)
382 {
383   if (U1 > U2) {
384     myFirstParam = U2;
385     myLastParam  = U1;
386   }
387   else {
388     myFirstParam = U1;
389     myLastParam  = U2;
390   }
391   my3d         = Standard_False;
392   myDwmax      = myLastParam-myFirstParam;
393   myDu         = myDwmax/2. ;
394   myDone       = Standard_True;
395   myCurve      = (Standard_Address) &C;
396   myFinish     = Standard_False;
397   myTolCur     = Resolution;
398   myDeflection = Deflection;
399   myControl    = WithControl;
400   Perform();
401 }
402
403 //=======================================================================
404 //function : More
405 //purpose  : 
406 //=======================================================================
407
408 Standard_Boolean CPnts_UniformDeflection::More()
409 {
410   if(!myDone) {
411     return Standard_False;
412   }
413   else if (myIPoint == myNbPoints) {
414     if (myFinish) {
415       return Standard_False;
416     }
417     else {
418       Perform();
419       return myDone;
420     }
421   }
422   else {
423     return myIPoint < myNbPoints;
424   }
425 }
426
427
428
429
430
431
432