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