CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 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
973c2be1 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.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
7fd59977 15//-------------------------------------------------------------------
0d969553 16// Algorithm concerns the constant arrow
0d969553
Y
17// cases processed : parameterized curve
18// the curve should be C2
19// provide a max arrow
0d969553 20// algorithm of parameterized curve:
0d969553 21// calculation of the step of advancement is
7fd59977 22// du = sqrt(8*fleche*||P'(u)||/||P'(u)^P''(u)||
0d969553 23// calculate each point such as u+Du
0d969553
Y
24// check if the arrow is actually taken into account, if yes, continue
25// otherwise correct the step
0d969553
Y
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:
0d969553
Y
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)
0d969553
Y
32// otherwise if the distance (last calculated point, end point)<arrow,
33// replace the last calculated point by the end point
0d969553
Y
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
0d969553 37// CONTROLS OF ARROW AND THE LAST POINT ARE DONE ONLY IF withControl=true
0d969553 38// each iteration calculates at maximum 3 points
7fd59977 39//-------------------------------------------------------------------------
40
43#include <CPnts_UniformDeflection.hxx>
7fd59977 44#include <gp_Pnt.hxx>
7fd59977 45#include <gp_Pnt2d.hxx>
42cf5bc1 46#include <gp_Vec.hxx>
7fd59977 47#include <gp_Vec2d.hxx>
42cf5bc1 48#include <Standard_ConstructionError.hxx>
49#include <Standard_DomainError.hxx>
50#include <Standard_OutOfRange.hxx>
51#include <StdFail_NotDone.hxx>
7fd59977 52
53static inline void D03d(const Standard_Address C, const Standard_Real U,
54 gp_Pnt& P)
55{
57}
58
59static void D02d(const Standard_Address C, const Standard_Real U,
60 gp_Pnt& PP)
61{
62 gp_Pnt2d P;
64 PP.SetCoord(P.X(),P.Y(),0.);
65}
66
7fd59977 67static inline void D23d(const Standard_Address C, const Standard_Real U,
68 gp_Pnt& P, gp_Vec& V1, gp_Vec& V2)
69{
71}
72
73static 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;
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
89void 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) {
0d969553 112 // singularity on the tangent or null curvature
7fd59977 113 myDu = Min(myDwmax, 1.5 * myDu);
114 }
115 else {
116 NormD2 = V2.CrossMagnitude(V1);
0d969553 117 if (NormD2 / NormD1 < myDeflection) { // collinearity of derivatives
7fd59977 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
0d969553 126 // check if the arrow is observed if WithControl
7fd59977 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
0d969553
Y
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
7fd59977 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) {
0d969553 161 // the last point is corrected if control
7fd59977 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) ) {
0d969553 201 // point n is removed
7fd59977 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
234CPnts_UniformDeflection::CPnts_UniformDeflection ()
235{
236 myDone = Standard_False;
237}
238
239//=======================================================================
240//function : CPnts_UniformDeflection
241//purpose :
242//=======================================================================
243
244CPnts_UniformDeflection::CPnts_UniformDeflection
246 const Standard_Real Deflection,
247 const Standard_Real Resolution,
248 const Standard_Boolean WithControl)
249{
250 Initialize(C, Deflection, Resolution, WithControl);
251}
252
253//=======================================================================
254//function : CPnts_UniformDeflection
255//purpose :
256//=======================================================================
257
258CPnts_UniformDeflection::CPnts_UniformDeflection
260 const Standard_Real Deflection,
261 const Standard_Real Resolution,
262 const Standard_Boolean WithControl)
263{
264 Initialize(C, Deflection, Resolution, WithControl);
265}
266
267//=======================================================================
268//function : Initialize
269//purpose :
270//=======================================================================
271
273 const Standard_Real Deflection,
274 const Standard_Real Resolution,
275 const Standard_Boolean WithControl)
276{
277 Initialize(C,Deflection,C.FirstParameter(),C.LastParameter(),
278 Resolution,WithControl);
279}
280
281//=======================================================================
282//function : Initialize
283//purpose :
284//=======================================================================
285
287 const Standard_Real Deflection,
288 const Standard_Real Resolution,
289 const Standard_Boolean WithControl)
290{
291 Initialize(C,Deflection,C.FirstParameter(),C.LastParameter(),
292 Resolution,WithControl);
293}
294
295//=======================================================================
296//function : CPnts_UniformDeflection
297//purpose :
298//=======================================================================
299
300CPnts_UniformDeflection ::CPnts_UniformDeflection
302 const Standard_Real Deflection,
303 const Standard_Real U1,
304 const Standard_Real U2,
305 const Standard_Real Resolution,
306 const Standard_Boolean WithControl)
307{
308 Initialize(C, Deflection, U1, U2, Resolution, WithControl);
309}
310
311//=======================================================================
312//function : CPnts_UniformDeflection
313//purpose :
314//=======================================================================
315
316CPnts_UniformDeflection ::CPnts_UniformDeflection
318 const Standard_Real Deflection,
319 const Standard_Real U1,
320 const Standard_Real U2,
321 const Standard_Real Resolution,
322 const Standard_Boolean WithControl)
323{
324 Initialize(C, Deflection, U1, U2, Resolution, WithControl);
325}
326
327//=======================================================================
328//function : Initialize
329//purpose :
330//=======================================================================
331
333 const Standard_Real Deflection,
334 const Standard_Real U1,
335 const Standard_Real U2,
336 const Standard_Real Resolution,
337 const Standard_Boolean WithControl)
338{
339 if (U1 > U2) {
340 myFirstParam = U2;
341 myLastParam = U1;
342 }
343 else {
344 myFirstParam = U1;
345 myLastParam = U2;
346 }
347 my3d = Standard_True;
348 myDwmax = myLastParam-myFirstParam;
349 myDu = myDwmax/2. ;
350 myDone = Standard_True;
352 myFinish = Standard_False;
353 myTolCur = Resolution;
354 myDeflection = Deflection;
355 myControl = WithControl;
356 Perform();
357}
358
359//=======================================================================
360//function : Initialize
361//purpose :
362//=======================================================================
363
365 const Standard_Real Deflection,
366 const Standard_Real U1,
367 const Standard_Real U2,
368 const Standard_Real Resolution,
369 const Standard_Boolean WithControl)
370{
371 if (U1 > U2) {
372 myFirstParam = U2;
373 myLastParam = U1;
374 }
375 else {
376 myFirstParam = U1;
377 myLastParam = U2;
378 }
379 my3d = Standard_False;
380 myDwmax = myLastParam-myFirstParam;
381 myDu = myDwmax/2. ;
382 myDone = Standard_True;
384 myFinish = Standard_False;
385 myTolCur = Resolution;
386 myDeflection = Deflection;
387 myControl = WithControl;
388 Perform();
389}
390
391//=======================================================================
392//function : More
393//purpose :
394//=======================================================================
395
396Standard_Boolean CPnts_UniformDeflection::More()
397{
398 if(!myDone) {
399 return Standard_False;
400 }
401 else if (myIPoint == myNbPoints) {
402 if (myFinish) {
403 return Standard_False;
404 }
405 else {
406 Perform();
407 return myDone;
408 }
409 }
410 else {
411 return myIPoint < myNbPoints;
412 }
413}
414
415
416
417
418
419
420