7fd59977 |
1 | // File: Geom2d_BezierCurve.cxx |
2 | // Created: Thu Mar 25 10:24:39 1993 |
3 | // Author: JCV |
4 | // <fid@sdsun2> |
5 | // Copyright: Matra Datavision 1993 |
6 | |
7 | // File Geom2d_BezierCurve.cxx Septembre 1990 |
8 | // Passage en classe persistante - 23/01/91 |
9 | // Modif suite a la deuxieme revue de projet toolkit Geometry -23/01/91 |
10 | // Infos : |
11 | // Actuellement pour les champs de la courbe le tableau des poles est |
12 | // declare de 1 a NbPoles et le tableau des poids est declare de 1 a NbPoles |
13 | |
14 | |
15 | // Revised RLE Aug 19 1993 |
16 | // Suppressed Swaps, added Init, removed typedefs |
17 | |
18 | #define No_Standard_OutOfRange |
19 | #define No_Standard_DimensionError |
20 | |
21 | #include <Geom2d_BezierCurve.ixx> |
22 | #include <PLib.hxx> |
23 | #include <BSplCLib.hxx> |
24 | #include <gp.hxx> |
25 | #include <gp_XY.hxx> |
26 | #include <Standard_ConstructionError.hxx> |
27 | #include <Standard_DimensionError.hxx> |
28 | #include <Standard_OutOfRange.hxx> |
29 | #include <Standard_RangeError.hxx> |
30 | #include <TColStd_Array1OfReal.hxx> |
31 | #include <TColStd_Array1OfInteger.hxx> |
32 | |
33 | //======================================================================= |
34 | //function : Rational |
35 | //purpose : check rationality of an array of weights |
36 | //======================================================================= |
37 | |
38 | static Standard_Boolean Rational(const TColStd_Array1OfReal& W) |
39 | { |
40 | Standard_Integer i, n = W.Length(); |
41 | Standard_Boolean rat = Standard_False; |
42 | for (i = 1; i < n; i++) { |
43 | rat = Abs(W(i) - W(i+1)) > gp::Resolution(); |
44 | if (rat) break; |
45 | } |
46 | return rat; |
47 | } |
48 | |
49 | |
50 | //======================================================================= |
51 | //function : Geom2d_BezierCurve |
52 | //purpose : |
53 | //======================================================================= |
54 | |
55 | Geom2d_BezierCurve::Geom2d_BezierCurve |
56 | (const TColgp_Array1OfPnt2d& Poles): |
57 | validcache(0), parametercache(0.), spanlenghtcache(1.) |
58 | { |
59 | // copy the poles |
60 | |
61 | Handle(TColgp_HArray1OfPnt2d) npoles = |
62 | new TColgp_HArray1OfPnt2d(1,Poles.Length()); |
63 | |
64 | npoles->ChangeArray1() = Poles; |
65 | |
66 | // Init non rational |
67 | Init(npoles, |
68 | Handle(TColStd_HArray1OfReal)()); |
69 | } |
70 | |
71 | |
72 | //======================================================================= |
73 | //function : Geom2d_BezierCurve |
74 | //purpose : |
75 | //======================================================================= |
76 | |
77 | Geom2d_BezierCurve::Geom2d_BezierCurve |
78 | (const TColgp_Array1OfPnt2d& Poles, |
79 | const TColStd_Array1OfReal& Weights): |
80 | validcache(0), parametercache(0.), spanlenghtcache(1.) |
81 | |
82 | { |
83 | // copy the poles |
84 | |
85 | Handle(TColgp_HArray1OfPnt2d) npoles = |
86 | new TColgp_HArray1OfPnt2d(1,Poles.Length()); |
87 | |
88 | npoles->ChangeArray1() = Poles; |
89 | |
90 | |
91 | // check the weights |
92 | |
93 | Standard_Integer nbpoles = Poles.Length(); |
94 | |
95 | if (Weights.Length() != nbpoles) |
96 | Standard_ConstructionError::Raise(); |
97 | |
98 | Standard_Integer i; |
99 | for (i = 1; i <= nbpoles; i++) { |
100 | if (Weights(i) <= gp::Resolution()) { |
101 | Standard_ConstructionError::Raise(); |
102 | } |
103 | } |
104 | |
105 | // check really rational |
106 | Standard_Boolean rat = Rational(Weights); |
107 | |
108 | // copy the weights |
109 | Handle(TColStd_HArray1OfReal) nweights; |
110 | if (rat) { |
111 | nweights = new TColStd_HArray1OfReal(1,nbpoles); |
112 | nweights->ChangeArray1() = Weights; |
113 | } |
114 | |
115 | // Init |
116 | Init(npoles,nweights); |
117 | } |
118 | |
119 | |
120 | //======================================================================= |
121 | //function : Increase |
122 | //purpose : increase degree |
123 | //======================================================================= |
124 | |
125 | void Geom2d_BezierCurve::Increase (const Standard_Integer Deg) |
126 | { |
127 | if (Deg == Degree()) return; |
128 | |
129 | Standard_ConstructionError_Raise_if |
130 | (Deg < Degree() || |
131 | Deg > Geom2d_BezierCurve::MaxDegree(), "Geom2d_BezierCurve::Increase"); |
132 | |
133 | Handle(TColgp_HArray1OfPnt2d) npoles = |
134 | new TColgp_HArray1OfPnt2d(1,Deg+1); |
135 | |
136 | Handle(TColStd_HArray1OfReal) nweights; |
137 | |
138 | TColStd_Array1OfReal bidknots(1,2); bidknots(1) = 0.; bidknots(2) = 1.; |
139 | TColStd_Array1OfInteger bidmults(1,2); bidmults.Init(Degree() + 1); |
140 | |
141 | if (IsRational()) { |
142 | nweights = new TColStd_HArray1OfReal(1,Deg+1); |
143 | BSplCLib::IncreaseDegree(Degree(), Deg, 0, |
144 | poles->Array1(),weights->Array1(), |
145 | bidknots, bidmults, |
146 | npoles->ChangeArray1(),nweights->ChangeArray1(), |
147 | bidknots, bidmults); |
148 | } |
149 | else { |
150 | BSplCLib::IncreaseDegree(Degree(), Deg, 0, |
151 | poles->Array1(), |
152 | *((TColStd_Array1OfReal*) NULL), |
153 | bidknots, bidmults, |
154 | npoles->ChangeArray1(), |
155 | *((TColStd_Array1OfReal*) NULL), |
156 | bidknots, bidmults); |
157 | } |
158 | |
159 | Init(npoles,nweights); |
160 | } |
161 | |
162 | |
163 | //======================================================================= |
164 | //function : MaxDegree |
165 | //purpose : |
166 | //======================================================================= |
167 | |
168 | Standard_Integer Geom2d_BezierCurve::MaxDegree () |
169 | { |
170 | return BSplCLib::MaxDegree(); |
171 | } |
172 | |
173 | |
174 | //======================================================================= |
175 | //function : InsertPoleAfter |
176 | //purpose : |
177 | //======================================================================= |
178 | |
179 | void Geom2d_BezierCurve::InsertPoleAfter |
180 | (const Standard_Integer Index, |
181 | const gp_Pnt2d& P, |
182 | const Standard_Real Weight) |
183 | { |
184 | Standard_Integer nbpoles = NbPoles(); |
185 | |
186 | Standard_ConstructionError_Raise_if |
187 | (nbpoles >= Geom2d_BezierCurve::MaxDegree() || |
188 | Weight <= gp::Resolution(), |
189 | "Geom2d_BezierCurve::InsertPoleAfter" ); |
190 | |
191 | Standard_OutOfRange_Raise_if |
192 | (Index < 0 || Index > nbpoles, |
193 | "Geom2d_BezierCurve::InsertPoleAfter"); |
194 | |
195 | Standard_Integer i; |
196 | |
197 | // Insert the pole |
198 | Handle(TColgp_HArray1OfPnt2d) npoles = |
199 | new TColgp_HArray1OfPnt2d(1,nbpoles+1); |
200 | |
201 | TColgp_Array1OfPnt2d& newpoles = npoles->ChangeArray1(); |
202 | const TColgp_Array1OfPnt2d& oldpoles = poles->Array1(); |
203 | |
204 | for (i = 1; i <= Index; i++) |
205 | newpoles(i) = oldpoles(i); |
206 | |
207 | newpoles(Index+1) = P; |
208 | |
209 | for (i = Index+1; i <= nbpoles; i++) |
210 | newpoles(i+1) = oldpoles(i); |
211 | |
212 | |
213 | // Insert the weight |
214 | Handle(TColStd_HArray1OfReal) nweights; |
215 | Standard_Boolean rat = IsRational() || Abs(Weight-1.) > gp::Resolution(); |
216 | |
217 | if (rat) { |
218 | nweights = new TColStd_HArray1OfReal(1,nbpoles+1); |
219 | TColStd_Array1OfReal& newweights = nweights->ChangeArray1(); |
220 | |
221 | for (i = 1; i <= Index; i++) |
222 | if (IsRational()) |
223 | newweights(i) = weights->Value(i); |
224 | else |
225 | newweights(i) = 1.; |
226 | |
227 | newweights(Index+1) = Weight; |
228 | |
229 | for (i = Index+1; i <= nbpoles; i++) |
230 | if (IsRational()) |
231 | newweights(i+1) = weights->Value(i); |
232 | else |
233 | newweights(i+1) = 1.; |
234 | } |
235 | |
236 | |
237 | Init(npoles,nweights); |
238 | } |
239 | |
240 | |
241 | //======================================================================= |
242 | //function : InsertPoleBefore |
243 | //purpose : |
244 | //======================================================================= |
245 | |
246 | void Geom2d_BezierCurve::InsertPoleBefore |
247 | (const Standard_Integer Index, |
248 | const gp_Pnt2d& P, |
249 | const Standard_Real Weight) |
250 | { |
251 | InsertPoleAfter(Index-1,P,Weight); |
252 | } |
253 | |
254 | |
255 | //======================================================================= |
256 | //function : RemovePole |
257 | //purpose : |
258 | //======================================================================= |
259 | |
260 | void Geom2d_BezierCurve::RemovePole |
261 | (const Standard_Integer Index) |
262 | { |
263 | Standard_Integer nbpoles = NbPoles(); |
264 | |
265 | Standard_ConstructionError_Raise_if |
266 | (nbpoles <= 2 , "Geom2d_BezierCurve::RemovePole" ); |
267 | |
268 | Standard_OutOfRange_Raise_if |
269 | (Index < 1 || Index > nbpoles, |
270 | "Geom2d_BezierCurve::RemovePole"); |
271 | |
272 | Standard_Integer i; |
273 | |
274 | // Remove the pole |
275 | Handle(TColgp_HArray1OfPnt2d) npoles = |
276 | new TColgp_HArray1OfPnt2d(1,nbpoles-1); |
277 | |
278 | TColgp_Array1OfPnt2d& newpoles = npoles->ChangeArray1(); |
279 | const TColgp_Array1OfPnt2d& oldpoles = poles->Array1(); |
280 | |
281 | for (i = 1; i < Index; i++) |
282 | newpoles(i) = oldpoles(i); |
283 | |
284 | for (i = Index+1; i <= nbpoles; i++) |
285 | newpoles(i-1) = oldpoles(i); |
286 | |
287 | |
288 | // Remove the weight |
289 | Handle(TColStd_HArray1OfReal) nweights; |
290 | |
291 | if (IsRational()) { |
292 | nweights = new TColStd_HArray1OfReal(1,nbpoles-1); |
293 | TColStd_Array1OfReal& newweights = nweights->ChangeArray1(); |
294 | const TColStd_Array1OfReal& oldweights = weights->Array1(); |
295 | |
296 | for (i = 1; i < Index; i++) |
297 | newweights(i) = oldweights(i); |
298 | |
299 | for (i = Index+1; i <= nbpoles; i++) |
300 | newweights(i-1) = oldweights(i); |
301 | } |
302 | |
303 | Init(npoles,nweights); |
304 | } |
305 | |
306 | |
307 | //======================================================================= |
308 | //function : Reverse |
309 | //purpose : |
310 | //======================================================================= |
311 | |
312 | void Geom2d_BezierCurve::Reverse () |
313 | { |
314 | gp_Pnt2d P; |
315 | Standard_Integer i, nbpoles = NbPoles(); |
316 | TColgp_Array1OfPnt2d & cpoles = poles->ChangeArray1(); |
317 | |
318 | // reverse poles |
319 | for (i = 1; i <= nbpoles / 2; i++) { |
320 | P = cpoles(i); |
321 | cpoles(i) = cpoles(nbpoles-i+1); |
322 | cpoles(nbpoles-i+1) = P; |
323 | } |
324 | |
325 | // reverse weights |
326 | if (IsRational()) { |
327 | TColStd_Array1OfReal & cweights = weights->ChangeArray1(); |
328 | Standard_Real w; |
329 | for (i = 1; i <= nbpoles / 2; i++) { |
330 | w = cweights(i); |
331 | cweights(i) = cweights(nbpoles-i+1); |
332 | cweights(nbpoles-i+1) = w; |
333 | } |
334 | } |
335 | |
336 | UpdateCoefficients(); |
337 | } |
338 | |
339 | |
340 | //======================================================================= |
341 | //function : ReversedParameter |
342 | //purpose : |
343 | //======================================================================= |
344 | |
345 | Standard_Real Geom2d_BezierCurve::ReversedParameter |
346 | ( const Standard_Real U) const |
347 | { |
348 | return ( 1. - U); |
349 | } |
350 | |
351 | |
352 | //======================================================================= |
353 | //function : Segment |
354 | //purpose : |
355 | //======================================================================= |
356 | |
357 | void Geom2d_BezierCurve::Segment |
358 | (const Standard_Real U1, const Standard_Real U2) |
359 | { |
360 | closed = (Abs(Value(U1).Distance (Value(U2))) <= gp::Resolution()); |
361 | // |
362 | // WARNING : when calling trimming be carefull that the cache |
363 | // is computed regarding 0.0e0 and not 1.0e0 |
364 | // |
365 | |
366 | if (IsRational()) { |
367 | PLib::Trimming(U1,U2,coeffs->ChangeArray1(),wcoeffs->ChangeArray1()); |
368 | PLib::CoefficientsPoles(coeffs->Array1(),wcoeffs->Array1(), |
369 | poles->ChangeArray1(),weights->ChangeArray1()); |
370 | } |
371 | else { |
372 | PLib::Trimming(U1,U2,coeffs->ChangeArray1(), |
373 | *((TColStd_Array1OfReal*) NULL)); |
374 | PLib::CoefficientsPoles(coeffs->Array1(), |
375 | *((TColStd_Array1OfReal*) NULL), |
376 | poles->ChangeArray1(), |
377 | *((TColStd_Array1OfReal*) NULL)); |
378 | } |
379 | UpdateCoefficients(); |
380 | } |
381 | |
382 | |
383 | //======================================================================= |
384 | //function : SetPole |
385 | //purpose : |
386 | //======================================================================= |
387 | |
388 | void Geom2d_BezierCurve::SetPole |
389 | (const Standard_Integer Index, |
390 | const gp_Pnt2d& P) |
391 | { |
392 | Standard_OutOfRange_Raise_if (Index < 1 || Index > NbPoles(), |
393 | "Geom2d_BezierCurve::SetPole"); |
394 | |
395 | TColgp_Array1OfPnt2d& cpoles = poles->ChangeArray1(); |
396 | cpoles(Index) = P; |
397 | |
398 | if (Index == 1 || Index == cpoles.Length()) { |
399 | closed = (cpoles(1).Distance(cpoles(NbPoles())) <= gp::Resolution()); |
400 | } |
401 | |
402 | UpdateCoefficients(); |
403 | } |
404 | |
405 | |
406 | //======================================================================= |
407 | //function : SetPole |
408 | //purpose : |
409 | //======================================================================= |
410 | |
411 | void Geom2d_BezierCurve::SetPole |
412 | (const Standard_Integer Index, |
413 | const gp_Pnt2d& P, |
414 | const Standard_Real Weight) |
415 | { |
416 | SetPole(Index,P); |
417 | SetWeight(Index,Weight); |
418 | } |
419 | |
420 | |
421 | //======================================================================= |
422 | //function : SetWeight |
423 | //purpose : |
424 | //======================================================================= |
425 | |
426 | void Geom2d_BezierCurve::SetWeight |
427 | (const Standard_Integer Index, |
428 | const Standard_Real Weight) |
429 | { |
430 | Standard_Integer nbpoles = NbPoles(); |
431 | |
432 | Standard_OutOfRange_Raise_if |
433 | (Index < 1 || Index > nbpoles, |
434 | "Geom2d_BezierCurve::SetWeight"); |
435 | Standard_ConstructionError_Raise_if |
436 | (Weight <= gp::Resolution (), |
437 | "Geom2d_BezierCurve::SetWeight"); |
438 | |
439 | |
440 | // compute new rationality |
441 | Standard_Boolean wasrat = IsRational(); |
442 | if (!wasrat) { |
443 | // a weight of 1. does not turn to rational |
444 | if (Abs(Weight - 1.) <= gp::Resolution()) return; |
445 | |
446 | // set weights of 1. |
447 | weights = new TColStd_HArray1OfReal(1,nbpoles); |
448 | wcoeffs = new TColStd_HArray1OfReal(1,nbpoles); |
449 | weights->Init(1.); |
450 | } |
451 | |
452 | TColStd_Array1OfReal & cweights = weights->ChangeArray1(); |
453 | cweights(Index) = Weight; |
454 | |
455 | // is it turning into non rational |
456 | if (wasrat) { |
457 | if (!Rational(cweights)) { |
458 | weights.Nullify(); |
459 | wcoeffs.Nullify(); |
460 | } |
461 | } |
462 | |
463 | UpdateCoefficients(); |
464 | } |
465 | |
466 | |
467 | //======================================================================= |
468 | //function : IsClosed |
469 | //purpose : |
470 | //======================================================================= |
471 | |
472 | Standard_Boolean Geom2d_BezierCurve::IsClosed () const |
473 | { |
474 | return closed; |
475 | } |
476 | |
477 | |
478 | //======================================================================= |
479 | //function : IsCN |
480 | //purpose : |
481 | //======================================================================= |
482 | |
483 | Standard_Boolean Geom2d_BezierCurve::IsCN (const Standard_Integer ) const |
484 | { |
485 | return Standard_True; |
486 | } |
487 | |
488 | |
489 | //======================================================================= |
490 | //function : IsPeriodic |
491 | //purpose : |
492 | //======================================================================= |
493 | |
494 | Standard_Boolean Geom2d_BezierCurve::IsPeriodic () const |
495 | { |
496 | return Standard_False; |
497 | } |
498 | |
499 | |
500 | //======================================================================= |
501 | //function : IsRational |
502 | //purpose : |
503 | //======================================================================= |
504 | |
505 | Standard_Boolean Geom2d_BezierCurve::IsRational () const |
506 | { |
507 | return !weights.IsNull(); |
508 | } |
509 | |
510 | |
511 | //======================================================================= |
512 | //function : Continuity |
513 | //purpose : |
514 | //======================================================================= |
515 | |
516 | GeomAbs_Shape Geom2d_BezierCurve::Continuity () const |
517 | { |
518 | return GeomAbs_CN; |
519 | } |
520 | |
521 | |
522 | //======================================================================= |
523 | //function : Degree |
524 | //purpose : |
525 | //======================================================================= |
526 | |
527 | Standard_Integer Geom2d_BezierCurve::Degree () const |
528 | { |
529 | return poles->Length()-1; |
530 | } |
531 | |
532 | |
533 | //======================================================================= |
534 | //function : D0 |
535 | //purpose : |
536 | //======================================================================= |
537 | |
538 | void Geom2d_BezierCurve::D0 (const Standard_Real U, gp_Pnt2d& P ) const |
539 | { |
540 | // Idee lumineuse sacrifiee sur l autel des performances. |
541 | // |
542 | // if(!CoefficientsOK(U)) |
543 | // ((Geom2d_BezierCurve*)(void*)this)->UpdateCoefficients(U); |
544 | if (IsRational()) |
545 | BSplCLib::CacheD0(U,Degree(),parametercache,spanlenghtcache, |
546 | coeffs->Array1(),wcoeffs->Array1(),P); |
547 | else |
548 | BSplCLib::CacheD0(U,Degree(),parametercache,spanlenghtcache, |
549 | coeffs->Array1(), |
550 | *((TColStd_Array1OfReal*) NULL), |
551 | P); |
552 | } |
553 | |
554 | //======================================================================= |
555 | //function : D1 |
556 | //purpose : |
557 | //======================================================================= |
558 | |
559 | void Geom2d_BezierCurve::D1(const Standard_Real U, |
560 | gp_Pnt2d& P, |
561 | gp_Vec2d& V1) const |
562 | { |
563 | // Idee lumineuse sacrifiee sur l autel des performances. |
564 | // |
565 | // if(!CoefficientsOK(U)) |
566 | // ((Geom2d_BezierCurve*)(void*)this)->UpdateCoefficients(U); |
567 | if (IsRational()) |
568 | BSplCLib::CacheD1(U,Degree(),parametercache,spanlenghtcache, |
569 | coeffs->Array1(),wcoeffs->Array1(),P,V1); |
570 | else |
571 | BSplCLib::CacheD1(U,Degree(),parametercache,spanlenghtcache, |
572 | coeffs->Array1(), |
573 | *((TColStd_Array1OfReal*) NULL), |
574 | P,V1); |
575 | } |
576 | |
577 | //======================================================================= |
578 | //function : D2 |
579 | //purpose : |
580 | //======================================================================= |
581 | |
582 | void Geom2d_BezierCurve::D2 (const Standard_Real U, |
583 | gp_Pnt2d& P, |
584 | gp_Vec2d& V1, |
585 | gp_Vec2d& V2) const |
586 | { |
587 | // Idee lumineuse sacrifiee sur l autel des performances. |
588 | // |
589 | // if(!CoefficientsOK(U)) |
590 | // ((Geom2d_BezierCurve*)(void*)this)->UpdateCoefficients(U); |
591 | if (IsRational()) |
592 | BSplCLib::CacheD2(U,Degree(),parametercache,spanlenghtcache, |
593 | coeffs->Array1(),wcoeffs->Array1(),P,V1,V2); |
594 | else |
595 | BSplCLib::CacheD2(U,Degree(),parametercache,spanlenghtcache, |
596 | coeffs->Array1(), |
597 | *((TColStd_Array1OfReal*) NULL), |
598 | P,V1,V2); |
599 | } |
600 | |
601 | //======================================================================= |
602 | //function : D3 |
603 | //purpose : |
604 | //======================================================================= |
605 | |
606 | void Geom2d_BezierCurve::D3 (const Standard_Real U, |
607 | gp_Pnt2d& P, |
608 | gp_Vec2d& V1, |
609 | gp_Vec2d& V2, |
610 | gp_Vec2d& V3) const |
611 | { |
612 | // Idee lumineuse sacrifiee sur l autel des performances. |
613 | // |
614 | // if(!CoefficientsOK(U)) |
615 | // ((Geom2d_BezierCurve*)(void*)this)->UpdateCoefficients(U); |
616 | if (IsRational()) |
617 | BSplCLib::CacheD3(U,Degree(),parametercache,spanlenghtcache, |
618 | coeffs->Array1(),wcoeffs->Array1(),P,V1,V2,V3); |
619 | else |
620 | BSplCLib::CacheD3(U,Degree(),parametercache,spanlenghtcache, |
621 | coeffs->Array1(), |
622 | *((TColStd_Array1OfReal*) NULL), |
623 | P,V1,V2,V3); |
624 | } |
625 | |
626 | //======================================================================= |
627 | //function : DN |
628 | //purpose : |
629 | //======================================================================= |
630 | |
631 | gp_Vec2d Geom2d_BezierCurve::DN (const Standard_Real U, |
632 | const Standard_Integer N) const |
633 | { |
634 | Standard_RangeError_Raise_if (N < 1, "Geom2d_BezierCurve::DN"); |
635 | gp_Vec2d V; |
636 | |
637 | TColStd_Array1OfReal bidknots(1,2); bidknots(1) = 0.; bidknots(2) = 1.; |
638 | TColStd_Array1OfInteger bidmults(1,2); bidmults.Init(Degree() + 1); |
639 | |
640 | if (IsRational()) |
641 | BSplCLib::DN(U,N,0,Degree(),Standard_False, |
642 | poles->Array1(),weights->Array1(), |
643 | bidknots,bidmults,V); |
644 | else |
645 | BSplCLib::DN(U,N,0,Degree(),Standard_False, |
646 | poles->Array1(), |
647 | *((TColStd_Array1OfReal*) NULL), |
648 | bidknots,bidmults,V); |
649 | return V; |
650 | } |
651 | |
652 | //======================================================================= |
653 | //function : EndPoint |
654 | //purpose : |
655 | //======================================================================= |
656 | |
657 | gp_Pnt2d Geom2d_BezierCurve::EndPoint () const |
658 | { |
659 | return poles->Value (poles->Upper()); |
660 | } |
661 | |
662 | |
663 | //======================================================================= |
664 | //function : FirstParameter |
665 | //purpose : |
666 | //======================================================================= |
667 | |
668 | Standard_Real Geom2d_BezierCurve::FirstParameter () const |
669 | { |
670 | return 0.0; |
671 | } |
672 | |
673 | |
674 | //======================================================================= |
675 | //function : LastParameter |
676 | //purpose : |
677 | //======================================================================= |
678 | |
679 | Standard_Real Geom2d_BezierCurve::LastParameter () const |
680 | { |
681 | return 1.0; |
682 | } |
683 | |
684 | |
685 | //======================================================================= |
686 | //function : NbPoles |
687 | //purpose : |
688 | //======================================================================= |
689 | |
690 | Standard_Integer Geom2d_BezierCurve::NbPoles () const |
691 | { |
692 | return poles->Length(); |
693 | } |
694 | |
695 | |
696 | //======================================================================= |
697 | //function : Pole |
698 | //purpose : |
699 | //======================================================================= |
700 | |
701 | gp_Pnt2d Geom2d_BezierCurve::Pole (const Standard_Integer Index) const |
702 | { |
703 | Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(), |
704 | "Geom2d_BezierCurve::Pole"); |
705 | return poles->Value(Index); |
706 | } |
707 | |
708 | |
709 | //======================================================================= |
710 | //function : Poles |
711 | //purpose : |
712 | //======================================================================= |
713 | |
714 | void Geom2d_BezierCurve::Poles (TColgp_Array1OfPnt2d& P) const |
715 | { |
716 | Standard_DimensionError_Raise_if (P.Length() != poles->Length(), |
717 | "Geom2d_BezierCurve::Poles"); |
718 | P = poles->Array1(); |
719 | } |
720 | |
721 | |
722 | //======================================================================= |
723 | //function : StartPoint |
724 | //purpose : |
725 | //======================================================================= |
726 | |
727 | gp_Pnt2d Geom2d_BezierCurve::StartPoint () const |
728 | { |
729 | return poles->Value(1); |
730 | } |
731 | |
732 | |
733 | //======================================================================= |
734 | //function : Weight |
735 | //purpose : |
736 | //======================================================================= |
737 | |
738 | Standard_Real Geom2d_BezierCurve::Weight |
739 | (const Standard_Integer Index) const |
740 | { |
741 | Standard_OutOfRange_Raise_if (Index < 1 || Index > weights->Length(), |
742 | "Geom2d_BezierCurve::Weight"); |
743 | if (IsRational()) |
744 | return weights->Value(Index); |
745 | else |
746 | return 1.; |
747 | } |
748 | |
749 | |
750 | //======================================================================= |
751 | //function : Weights |
752 | //purpose : |
753 | //======================================================================= |
754 | |
755 | void Geom2d_BezierCurve::Weights |
756 | (TColStd_Array1OfReal& W) const |
757 | { |
758 | |
759 | Standard_Integer nbpoles = NbPoles(); |
760 | Standard_DimensionError_Raise_if (W.Length() != nbpoles, |
761 | "Geom2d_BezierCurve::Weights"); |
762 | if (IsRational()) |
763 | W = weights->Array1(); |
764 | else { |
765 | Standard_Integer i; |
766 | for (i = 1; i <= nbpoles; i++) |
767 | W(i) = 1.; |
768 | } |
769 | } |
770 | |
771 | |
772 | //======================================================================= |
773 | //function : Transform |
774 | //purpose : |
775 | //======================================================================= |
776 | |
777 | void Geom2d_BezierCurve::Transform (const gp_Trsf2d& T) |
778 | { |
779 | Standard_Integer nbpoles = NbPoles(); |
780 | TColgp_Array1OfPnt2d & cpoles = poles->ChangeArray1(); |
781 | |
782 | for (Standard_Integer i = 1; i <= nbpoles; i++) |
783 | cpoles (i).Transform(T); |
784 | |
785 | UpdateCoefficients(); |
786 | } |
787 | |
788 | |
789 | //======================================================================= |
790 | //function : Resolution |
791 | //purpose : |
792 | //======================================================================= |
793 | |
794 | void Geom2d_BezierCurve::Resolution(const Standard_Real ToleranceUV, |
795 | Standard_Real & UTolerance) |
796 | { |
797 | if(!maxderivinvok){ |
798 | TColStd_Array1OfReal bidflatknots(1, 2*(Degree()+1)); |
799 | for(Standard_Integer i = 1; i <= Degree()+1; i++){ |
800 | bidflatknots(i) = 0.; |
801 | bidflatknots(i + Degree() +1) = 1.; |
802 | } |
803 | |
804 | if (IsRational()) { |
805 | BSplCLib::Resolution(poles->Array1(), |
806 | weights->Array1(), |
807 | poles->Length(), |
808 | bidflatknots, |
809 | Degree(), |
810 | 1., |
811 | maxderivinv) ; |
812 | } |
813 | else { |
814 | BSplCLib::Resolution(poles->Array1(), |
815 | *((TColStd_Array1OfReal*) NULL), |
816 | poles->Length(), |
817 | bidflatknots, |
818 | Degree(), |
819 | 1., |
820 | maxderivinv) ; |
821 | } |
822 | maxderivinvok = 1; |
823 | } |
824 | UTolerance = ToleranceUV * maxderivinv; |
825 | } |
826 | |
827 | |
828 | //======================================================================= |
829 | //function : Copy |
830 | //purpose : |
831 | //======================================================================= |
832 | |
833 | Handle(Geom2d_Geometry) Geom2d_BezierCurve::Copy() const { |
834 | |
835 | Handle(Geom2d_BezierCurve) C; |
836 | if (IsRational()) |
837 | C = new Geom2d_BezierCurve (poles->Array1(),weights->Array1()); |
838 | else |
839 | C = new Geom2d_BezierCurve (poles->Array1()); |
840 | return C; |
841 | } |
842 | |
843 | |
844 | //======================================================================= |
845 | //function : Init |
846 | //purpose : |
847 | //======================================================================= |
848 | |
849 | void Geom2d_BezierCurve::Init |
850 | (const Handle(TColgp_HArray1OfPnt2d)& Poles, |
851 | const Handle(TColStd_HArray1OfReal)& Weights) |
852 | { |
853 | Standard_Integer nbpoles = Poles->Length(); |
854 | // closed ? |
855 | const TColgp_Array1OfPnt2d& cpoles = Poles->Array1(); |
856 | closed = cpoles(1).Distance(cpoles(nbpoles)) <= gp::Resolution(); |
857 | |
858 | // rational |
859 | rational = !Weights.IsNull(); |
860 | |
861 | // set fields |
862 | poles = Poles; |
863 | coeffs = new TColgp_HArray1OfPnt2d (1,nbpoles); |
864 | |
865 | if (rational) { |
866 | weights = Weights; |
867 | wcoeffs = new TColStd_HArray1OfReal (1, nbpoles, 0.0); |
868 | } |
869 | else { |
870 | weights.Nullify(); |
871 | wcoeffs.Nullify(); |
872 | } |
873 | |
874 | UpdateCoefficients(); |
875 | } |
876 | |
877 | |
878 | //======================================================================= |
879 | //function : CoefficientsOK |
880 | //purpose : |
881 | //======================================================================= |
882 | |
883 | //Standard_Boolean Geom2d_BezierCurve::CoefficientsOK(const Standard_Real U)const |
884 | Standard_Boolean Geom2d_BezierCurve::CoefficientsOK(const Standard_Real )const |
885 | { |
886 | return (validcache) ; |
887 | |
888 | } |
889 | |
890 | |
891 | //======================================================================= |
892 | //function : UpdateCoefficients |
893 | //purpose : |
894 | //======================================================================= |
895 | |
896 | //void Geom2d_BezierCurve::UpdateCoefficients(const Standard_Real U) |
897 | void Geom2d_BezierCurve::UpdateCoefficients(const Standard_Real ) |
898 | { |
899 | maxderivinvok = 0; |
900 | parametercache = 0.; |
901 | // |
902 | // Idee lumineuse sacrifiee sur l autel des performances. |
903 | // if (U >= 1.) parametercache = 1.; |
904 | TColStd_Array1OfReal bidflatknots(BSplCLib::FlatBezierKnots(Degree()), |
905 | 1, 2*(Degree()+1)); |
906 | if (IsRational()) |
907 | BSplCLib::BuildCache(parametercache,spanlenghtcache,0,Degree(), |
908 | bidflatknots,poles->Array1(),weights->Array1(), |
909 | coeffs->ChangeArray1(),wcoeffs->ChangeArray1()); |
910 | else |
911 | BSplCLib::BuildCache(parametercache,spanlenghtcache,0,Degree(), |
912 | bidflatknots,poles->Array1(), |
913 | *((TColStd_Array1OfReal*) NULL), |
914 | coeffs->ChangeArray1(), |
915 | *((TColStd_Array1OfReal*) NULL)); |
916 | validcache = 1; |
917 | } |
918 | |