0022922: Clean up warnings on uninitialized / unused variables
[occt.git] / src / GCPnts / GCPnts_UniformAbscissa.gxx
CommitLineData
7fd59977 1#include <StdFail_NotDone.hxx>
2#include <Standard_DomainError.hxx>
3#include <Standard_OutOfRange.hxx>
4#include <Standard_ConstructionError.hxx>
5#include <GCPnts_AbscissaType.hxx>
6#include <TColStd_HArray1OfReal.hxx>
7#include <TColStd_Array1OfReal.hxx>
8#include <GeomAbs_CurveType.hxx>
9#include <CPnts_AbscissaPoint.hxx>
10#include <GCPnts_AbscissaPoint.hxx>
11#include <Precision.hxx>
12#include <gp_Circ.hxx>
13#include <gp_Circ2d.hxx>
14#include <gp_Vec.hxx>
15#include <gp_Vec2d.hxx>
16
17
18static Standard_Real GetParameterLengthRatio(TheCurve& C)
19{
20 switch (C.GetType()) {
21
22 case GeomAbs_Circle :
23 return C.Circle().Radius();
24
25 case GeomAbs_Line :
26 return 1.;
27
28 case GeomAbs_BezierCurve :
29 case GeomAbs_BSplineCurve :
30 {
31 if (!C.IsRational())
32 return C.DN(0., 1).Magnitude();
33 else
34 return RealLast();
35 }
36
37 default :
38 return RealLast();
39
40 }
41}
42
43
44static GCPnts_AbscissaType GetAbsType(TheCurve& C)
45{
46 if (C.NbIntervals(GeomAbs_C1) > 1)
47 return GCPnts_AbsComposite;
48
49 switch (C.GetType()) {
50
51 case GeomAbs_Line:
52 case GeomAbs_Circle:
53 return GCPnts_LengthParametrized;
54 case GeomAbs_BezierCurve:
55 {
56 Handle_TheBezierCurve BZ = C.Bezier();
57 if (BZ->NbPoles() == 2 && !BZ->IsRational())
58 return GCPnts_LengthParametrized;
59 else
60 return GCPnts_Parametrized;
61 }
62 case GeomAbs_BSplineCurve:
63 {
64 Handle_TheBSplineCurve BS = C.BSpline() ;
65 if (BS->NbPoles() == 2 && !BS->IsRational())
66 return GCPnts_LengthParametrized;
67 else
68 return GCPnts_Parametrized;
69 }
70 default:
71 return GCPnts_Parametrized ;
72 }
73}
74
75static Standard_Boolean Perform(Handle(TColStd_HArray1OfReal)& HParameters,
76 TheCurve& C,
77 const Standard_Real Abscissa,
78 const Standard_Real U1,
79 const Standard_Real U2,
80 const Standard_Real TotalLength,
81 Standard_Integer &NbPoints,
82 const Standard_Real EPSILON)
83{
84 Standard_Boolean NotDone = Standard_True;
85 Standard_Boolean LocalDone = Standard_True;
86// Standard_Boolean Forward = Standard_True ;
87 Standard_Real UU1 = Min(U1, U2), UU2 = Max(U1, U2) ;
88 Standard_Integer Index ;
89// Standard_Real UCurrent, Delta, Ui;
90 Standard_Real Delta, Ui;
91 NbPoints = 0 ;
92
93//
94// this initialization avoids the computation of the Length
95// of the curve
96
97 Delta = (Abscissa/TotalLength) * (UU2 - UU1) ;
98 Index = 1 ;
99 HParameters->SetValue(Index,UU1) ;
100 while (NotDone) {
101 Ui = HParameters->Value(Index) + Delta;
102 if (Ui > UU2) {
103 // MSV 21.04.2004: OCC5739 (GCPnts_UniformAbscissa gives incorrect
104 // distribution of points)
105// if (UU2 - HParameters->Value(Index) > 0.01*Delta) {
106// Index += 1;
107// }
108// HParameters->SetValue(Index, UU2);
109// NotDone = Standard_False;
110// break;
111 Ui = UU2;
112 }
113 GCPnts_AbscissaPoint AbscissaFinder(C,
114 Abscissa,
115 HParameters->Value(Index),
116 Ui,
117 EPSILON) ;
118 if (AbscissaFinder.IsDone()) {
119 Index += 1 ;
120 Ui = AbscissaFinder.Parameter();
121 if (Abs(Ui-UU2) <= EPSILON) {
122 HParameters->SetValue(Index, UU2);
123 NotDone = Standard_False;
124 }
125 else if (Ui < UU2) {
126 HParameters->SetValue(Index, Ui);
127 }
128 else {
129 HParameters->SetValue(Index, UU2);
130 NotDone = Standard_False;
131 }
132 NotDone = NotDone && (Index + 1 <= HParameters->Length()) ;
133 }
134 else {
135
136 LocalDone = Standard_False ;
137 NotDone = Standard_True ;
138 Delta -= Delta/10;
139 if (Delta <= Precision::PConfusion()) break;
140 }
141 }
142 NbPoints = Index ;
143 return (LocalDone) ;
144}
145
146
147static Standard_Boolean
148PerformLengthParametrized( Handle(TColStd_HArray1OfReal)& HParameters,
149 TheCurve& C,
150 const Standard_Real Abscissa,
151 const Standard_Real U1,
152 const Standard_Real U2,
153 const Standard_Real TotalLength,
154 Standard_Integer &NbPoints,
155 const Standard_Real EPSILON)
156{
157 Standard_Boolean NotDone = Standard_True;
158// Standard_Boolean LocalDone = Standard_True;
159 Standard_Boolean Forward = Standard_True ;
160 Standard_Real UU1 = Min(U1, U2);
161// Standard_Real UCurrent;
162 Standard_Real Delta, Ui;
163 Standard_Real UU2 = Max(U1, U2);
7fd59977 164 Standard_Integer Index ;
165
166// Ratio is defined as dl = Ratio * du
167// for a circle of gp Ratio is equal to the radius of the circle.
168// for a line of gp ratio is equal to 1.0
169 Standard_Real Ratio = GetParameterLengthRatio(C);
170
171
172 if (Abscissa < 0.0e0) {
173 Forward = Standard_False ;
174 UU2 = Min(U1, U2);
175 UU1 = Max(U1, U2);
176 }
177 Delta = (Abscissa/TotalLength) * (UU2 - UU1) ;
178 Index = 1 ;
179 NbPoints = 0 ;
180 HParameters->SetValue(Index,UU1) ;
181 while (NotDone) {
182 Index += 1 ;
183 Ui = HParameters->Value(Index-1) + Delta;
184 if (Abs(Ui-UU2) <= EPSILON) {
185 HParameters->SetValue(Index, UU2);
186 NotDone = Standard_False;
187 }
188 else if (Ui < UU2) {
189 HParameters->SetValue(Index, Ui);
190 }
191 else {
192 NotDone = Standard_False;
193 if (Abs(HParameters->Value(Index-1) - UU2)*Ratio/Abscissa < 0.1) {
194 HParameters->SetValue(Index-1, UU2);
195 Index -= 1;
196 }
197 else
198 HParameters->SetValue(Index, UU2);
199 }
200 NotDone = (Index+1 <= HParameters->Length()) && NotDone ;
201 }
202
203 NbPoints = Index ;
204 return Standard_True ;
205}
206
207
208//=======================================================================
209//function : Initialize
210//purpose :
211//=======================================================================
212
213void GCPnts_UniformAbscissa::Initialize (TheCurve& C,
214 const Standard_Real Abscissa,
215 const Standard_Real Tol)
216{
217 Initialize(C, Abscissa, C.FirstParameter(),
218 C.LastParameter(), Tol);
219}
220
221//=======================================================================
222//function : GCPnts_UniformAbscissa
223//purpose :
224//=======================================================================
225
226GCPnts_UniformAbscissa::GCPnts_UniformAbscissa (TheCurve& C,
227 const Standard_Real Abscissa,
228 const Standard_Real Tol)
229{
230 Initialize(C, Abscissa, Tol);
231}
232
233//=======================================================================
234//function : GCPnts_UniformAbscissa
235//purpose :
236//=======================================================================
237
238GCPnts_UniformAbscissa::GCPnts_UniformAbscissa (TheCurve& C,
239 const Standard_Real Abscissa,
240 const Standard_Real U1,
241 const Standard_Real U2,
242 const Standard_Real Tol)
243{
244 Initialize(C, Abscissa, U1, U2, Tol);
245}
246
247//=======================================================================
248//function : GCPnts_UniformAbscissa
249//purpose :
250//=======================================================================
251
252GCPnts_UniformAbscissa::GCPnts_UniformAbscissa(TheCurve& C,
253 const Standard_Integer NbPoints,
254 const Standard_Real Tol)
255{
256 Initialize(C, NbPoints, Tol);
257}
258
259//=======================================================================
260//function : GCPnts_UniformAbscissa
261//purpose :
262//=======================================================================
263
264GCPnts_UniformAbscissa::GCPnts_UniformAbscissa(TheCurve& C,
265 const Standard_Integer NbPoints,
266 const Standard_Real U1,
267 const Standard_Real U2,
268 const Standard_Real Tol)
269{
270 Initialize(C, NbPoints, U1, U2, Tol);
271}
272
273//=======================================================================
274//function : Initialize
275//purpose :
276//=======================================================================
277
278void GCPnts_UniformAbscissa::Initialize(TheCurve& C,
279 const Standard_Real Abscissa,
280 const Standard_Real U1,
281 const Standard_Real U2,
282 const Standard_Real Tol)
283{
284 Standard_Real L ;
285 myAbscissa = Abscissa;
286 myNbPoints = 0 ;
287 myDone = Standard_False;
288 Standard_Real EPSILON;
289
290 if(Tol < Precision::Confusion())
291 EPSILON = C.Resolution(Precision::Confusion());
292 else
293 EPSILON = C.Resolution(Tol);
294
295 L = GCPnts_AbscissaPoint::Length(C, U1, U2, EPSILON);
296 if (L <= Precision::Confusion()) {
297 return;
298 }
299 Standard_Integer size ;
300
301//
302// compute the total Length here so that we can
303// guess the number of points instead of letting the
304// constructor of CPnts_AbscissaPoint do that and loosing
305// the information
306//
307//
308
309// modified by Igor Motchalov 23/04/2001
310// size = (Standard_Integer )( (L/Abs(Abscissa)) + 5 );
311 Standard_Real sizeR=L/Abs(Abscissa) + 5;
312 if (sizeR < IntegerLast()) {
313 size=(Standard_Integer) sizeR;
314 } else {
315 return;
316 }
317
318 if (!myParams.IsNull()) {
319 if (myParams->Length() < size) {
320 myParams.Nullify() ;
321 myParams = new
322 TColStd_HArray1OfReal(1,size) ;
323 }
324 }
325 else {
326 myParams = new
327 TColStd_HArray1OfReal(1,size) ;
328 }
329
330// Standard_Real EPSILON = C.Resolution(Precision::Confusion());
331 GCPnts_AbscissaType Type = GetAbsType(C);
332 switch (Type) {
333 case GCPnts_LengthParametrized :
334 myDone = PerformLengthParametrized(myParams,
335 C,
336 Abscissa,
337 U1,
338 U2,
339 L,
340 myNbPoints,
341 EPSILON);
342 break;
343 case GCPnts_Parametrized:
344 case GCPnts_AbsComposite:
345 myDone = Perform(myParams,
346 C,
347 Abscissa,
348 U1,
349 U2,
350 L,
351 myNbPoints,
352 EPSILON);
353 break;
354 }
355}
356
357
358//=======================================================================
359//function : Initialize
360//purpose :
361//=======================================================================
362
363void GCPnts_UniformAbscissa::Initialize(TheCurve& C,
364 const Standard_Integer NbPoints,
365 const Standard_Real Tol)
366{
367 Initialize(C, NbPoints, C.FirstParameter(),
368 C.LastParameter(), Tol);
369}
370
371
372//=======================================================================
373//function : Initialize
374//purpose :
375//=======================================================================
376
377void GCPnts_UniformAbscissa::Initialize(TheCurve& C,
378 const Standard_Integer NbPoints,
379 const Standard_Real U1,
380 const Standard_Real U2,
381 const Standard_Real Tol)
382{
383 Standard_ConstructionError_Raise_if(NbPoints <= 1, "");
384 Standard_Real Abscissa ;
385 myNbPoints = 0 ;
386 myDone = Standard_False;
387 Standard_Real EPSILON;
388
389 if(Tol < Precision::Confusion())
390 EPSILON = C.Resolution(Precision::Confusion());
391 else
392 EPSILON = C.Resolution(Tol);
393
394//
395// although very similar to Initialize with Abscissa this avoid
396// the computation of the total length of the curve twice
397//
398 Standard_Real L = GCPnts_AbscissaPoint::Length(C, U1, U2, EPSILON) ;
399
400 if (L <= Precision::Confusion()) {
401 return;
402 }
403
404 Abscissa =
405 myAbscissa = L / (NbPoints - 1);
406
407 Standard_Integer size ;
408
409//
410// compute the total Length here so that we can
411// guess the number of points instead of letting the
412// constructor of CPnts_AbscissaPoint do that and loosing
413// the information
414//
415//
416
417 size = NbPoints + 5 ;
418
419
420 if (!myParams.IsNull()) {
421 if (myParams->Length() < size) {
422 myParams.Nullify() ;
423 myParams = new
424 TColStd_HArray1OfReal(1,size) ;
425 }
426 }
427 else {
428 myParams = new
429 TColStd_HArray1OfReal(1,size) ;
430 }
431
432
433 myNbPoints = 0 ;
434 GCPnts_AbscissaType Type = GetAbsType(C);
435 switch (Type) {
436 case GCPnts_LengthParametrized:
437 myDone = PerformLengthParametrized(myParams,
438 C,
439 Abscissa,
440 U1,
441 U2,
442 L,
443 myNbPoints,
444 EPSILON);
445 break;
446 case GCPnts_Parametrized:
447 case GCPnts_AbsComposite:
448 myDone = Perform(myParams,
449 C,
450 Abscissa,
451 U1,
452 U2,
453 L,
454 myNbPoints,
455 EPSILON);
456 break;
457 }
458}
459
460
461
462
463
464