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