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