b311480e |
1 | // Created on: 1991-07-05 |
2 | // Created by: JCV |
3 | // Copyright (c) 1991-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 | // 03-02-97 : pmn ->LocateU sur Periodic (PRO6963), |
18 | // bon appel a LocateParameter (PRO6973) et mise en conformite avec |
19 | // le cdl de LocateU, lorsque U est un noeud (PRO6988) |
20 | |
21 | #define No_Standard_OutOfRange |
22 | #define No_Standard_DimensionError |
23 | |
24 | #include <Geom2d_BSplineCurve.jxx> |
25 | #include <BSplCLib.hxx> |
26 | #include <gp.hxx> |
27 | |
28 | #include <Geom2d_UndefinedDerivative.hxx> |
29 | #include <Standard_DimensionError.hxx> |
30 | #include <Standard_OutOfRange.hxx> |
31 | #include <Standard_DomainError.hxx> |
32 | #include <Standard_RangeError.hxx> |
83ada95b |
33 | #include <Standard_Mutex.hxx> |
7fd59977 |
34 | |
35 | #define POLES (poles->Array1()) |
36 | #define KNOTS (knots->Array1()) |
37 | #define FKNOTS (flatknots->Array1()) |
38 | #define FMULTS (BSplCLib::NoMults()) |
39 | |
40 | //======================================================================= |
41 | //function : IsCN |
42 | //purpose : |
43 | //======================================================================= |
44 | |
45 | Standard_Boolean Geom2d_BSplineCurve::IsCN ( const Standard_Integer N) const |
46 | { |
47 | Standard_RangeError_Raise_if |
48 | (N < 0, "Geom2d_BSplineCurve::IsCN"); |
49 | |
50 | switch (smooth) { |
51 | case GeomAbs_CN : return Standard_True; |
52 | case GeomAbs_C0 : return N <= 0; |
53 | case GeomAbs_G1 : return N <= 0; |
54 | case GeomAbs_C1 : return N <= 1; |
55 | case GeomAbs_G2 : return N <= 1; |
56 | case GeomAbs_C2 : return N <= 2; |
57 | case GeomAbs_C3 : |
58 | return N <= 3 ? Standard_True : |
59 | N <= deg - BSplCLib::MaxKnotMult (mults->Array1(), mults->Lower() + 1, mults->Upper() - 1); |
60 | default: |
61 | return Standard_False; |
62 | } |
63 | } |
3d58dc49 |
64 | //======================================================================= |
65 | //function : IsG1 |
66 | //purpose : |
67 | //======================================================================= |
68 | |
69 | Standard_Boolean Geom2d_BSplineCurve::IsG1 ( const Standard_Real theTf, |
70 | const Standard_Real theTl, |
71 | const Standard_Real theAngTol) const |
72 | { |
73 | |
74 | if(IsCN(1)) |
75 | { |
76 | return Standard_True; |
77 | } |
78 | |
79 | Standard_Integer start = FirstUKnotIndex()+1, |
80 | finish = LastUKnotIndex()-1; |
81 | Standard_Integer aDeg = Degree(); |
82 | for(Standard_Integer aNKnot = start; aNKnot <= finish; aNKnot++) |
83 | { |
84 | const Standard_Real aTpar = Knot(aNKnot); |
85 | |
86 | if(aTpar < theTf) |
87 | continue; |
88 | if(aTpar > theTl) |
89 | break; |
90 | |
91 | Standard_Integer mult = Multiplicity(aNKnot); |
92 | if (mult < aDeg) |
93 | continue; |
94 | |
95 | gp_Pnt2d aP1, aP2; |
96 | gp_Vec2d aV1, aV2; |
97 | LocalD1(aTpar, aNKnot-1, aNKnot, aP1, aV1); |
98 | LocalD1(aTpar, aNKnot, aNKnot+1, aP2, aV2); |
99 | |
100 | if((aV1.SquareMagnitude() <= gp::Resolution()) || |
101 | aV2.SquareMagnitude() <= gp::Resolution()) |
102 | { |
103 | return Standard_False; |
104 | } |
105 | |
106 | if(Abs(aV1.Angle(aV2)) > theAngTol) |
107 | return Standard_False; |
108 | } |
109 | |
110 | if(!IsPeriodic()) |
111 | return Standard_True; |
112 | |
113 | const Standard_Real aFirstParam = FirstParameter(), |
114 | aLastParam = LastParameter(); |
115 | |
116 | if( ((aFirstParam - theTf)*(theTl - aFirstParam) < 0.0) && |
117 | ((aLastParam - theTf)*(theTl - aLastParam) < 0.0)) |
118 | { |
119 | //Range [theTf, theTl] does not intersect curve bounadries |
120 | return Standard_True; |
121 | } |
122 | |
123 | //Curve is closed or periodic and range [theTf, theTl] |
124 | //intersect curve boundary. Therefore, it is necessary to |
125 | //check if curve is smooth in its first and last point. |
126 | |
127 | gp_Pnt2d aP; |
128 | gp_Vec2d aV1, aV2; |
129 | D1(Knot(FirstUKnotIndex()), aP, aV1); |
130 | D1(Knot(LastUKnotIndex()), aP, aV2); |
131 | |
132 | if((aV1.SquareMagnitude() <= gp::Resolution()) || |
133 | aV2.SquareMagnitude() <= gp::Resolution()) |
134 | { |
135 | return Standard_False; |
136 | } |
137 | |
138 | if(Abs(aV1.Angle(aV2)) > theAngTol) |
139 | return Standard_False; |
140 | |
141 | |
142 | return Standard_True; |
143 | |
144 | } |
7fd59977 |
145 | |
146 | //======================================================================= |
147 | //function : IsClosed |
148 | //purpose : |
149 | //======================================================================= |
150 | |
151 | Standard_Boolean Geom2d_BSplineCurve::IsClosed () const |
152 | { return (StartPoint().Distance (EndPoint())) <= gp::Resolution (); } |
153 | |
154 | |
155 | |
156 | //======================================================================= |
157 | //function : IsPeriodic |
158 | //purpose : |
159 | //======================================================================= |
160 | |
161 | Standard_Boolean Geom2d_BSplineCurve::IsPeriodic () const |
162 | { return periodic; } |
163 | |
164 | //======================================================================= |
165 | //function : Continuity |
166 | //purpose : |
167 | //======================================================================= |
168 | |
169 | GeomAbs_Shape Geom2d_BSplineCurve::Continuity () const |
170 | { return smooth; } |
171 | |
172 | //======================================================================= |
173 | //function : Degree |
174 | //purpose : |
175 | //======================================================================= |
176 | |
177 | Standard_Integer Geom2d_BSplineCurve::Degree () const |
178 | { return deg; } |
179 | |
180 | |
181 | //======================================================================= |
182 | //function : D0 |
183 | //purpose : |
184 | //======================================================================= |
185 | |
186 | void Geom2d_BSplineCurve::D0 ( const Standard_Real U, |
187 | gp_Pnt2d& P) const |
188 | { |
83ada95b |
189 | Standard_Real NewU(U); |
190 | PeriodicNormalization(NewU); |
191 | |
192 | Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this; |
193 | Standard_Mutex::Sentry aSentry(MyCurve->myMutex); |
194 | |
195 | if (!IsCacheValid(NewU)) |
196 | MyCurve->ValidateCache(NewU); |
7fd59977 |
197 | |
83ada95b |
198 | if(rational) |
199 | { |
7fd59977 |
200 | BSplCLib::CacheD0(NewU, |
201 | deg, |
202 | parametercache, |
203 | spanlenghtcache, |
204 | (cachepoles->Array1()), |
205 | cacheweights->Array1(), |
206 | P) ; |
207 | } |
208 | else { |
209 | BSplCLib::CacheD0(NewU, |
210 | deg, |
211 | parametercache, |
212 | spanlenghtcache, |
213 | (cachepoles->Array1()), |
214 | BSplCLib::NoWeights(), |
215 | P) ; |
216 | } |
217 | } |
218 | |
219 | |
220 | //======================================================================= |
221 | //function : D1 |
222 | //purpose : |
223 | //======================================================================= |
224 | |
225 | void Geom2d_BSplineCurve::D1 (const Standard_Real U, |
226 | gp_Pnt2d& P, |
227 | gp_Vec2d& V1) const |
228 | { |
83ada95b |
229 | Standard_Real NewU(U); |
230 | PeriodicNormalization(NewU); |
7fd59977 |
231 | |
83ada95b |
232 | Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this; |
233 | Standard_Mutex::Sentry aSentry(MyCurve->myMutex); |
234 | |
235 | if (!IsCacheValid(NewU)) |
236 | MyCurve->ValidateCache(NewU); |
237 | |
238 | if(rational) |
239 | { |
7fd59977 |
240 | BSplCLib::CacheD1(NewU, |
241 | deg, |
242 | parametercache, |
243 | spanlenghtcache, |
244 | (cachepoles->Array1()), |
245 | cacheweights->Array1(), |
246 | P, |
247 | V1) ; |
248 | } |
249 | else { |
250 | BSplCLib::CacheD1(NewU, |
251 | deg, |
252 | parametercache, |
253 | spanlenghtcache, |
254 | (cachepoles->Array1()), |
255 | BSplCLib::NoWeights(), |
256 | P, |
257 | V1) ; |
258 | } |
259 | } |
260 | |
261 | //======================================================================= |
262 | //function : D2 |
263 | //purpose : |
264 | //======================================================================= |
265 | |
266 | void Geom2d_BSplineCurve::D2 (const Standard_Real U , |
267 | gp_Pnt2d& P , |
268 | gp_Vec2d& V1, |
269 | gp_Vec2d& V2 ) const |
270 | { |
83ada95b |
271 | Standard_Real NewU(U); |
272 | PeriodicNormalization(NewU); |
273 | |
274 | Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this; |
275 | Standard_Mutex::Sentry aSentry(MyCurve->myMutex); |
276 | |
277 | if (!IsCacheValid(NewU)) |
278 | MyCurve->ValidateCache(NewU); |
7fd59977 |
279 | |
83ada95b |
280 | if(rational) |
281 | { |
7fd59977 |
282 | BSplCLib::CacheD2(NewU, |
283 | deg, |
284 | parametercache, |
285 | spanlenghtcache, |
286 | (cachepoles->Array1()), |
287 | cacheweights->Array1(), |
288 | P, |
289 | V1, |
290 | V2) ; |
291 | } |
292 | else { |
293 | BSplCLib::CacheD2(NewU, |
294 | deg, |
295 | parametercache, |
296 | spanlenghtcache, |
297 | (cachepoles->Array1()), |
298 | BSplCLib::NoWeights(), |
299 | P, |
300 | V1, |
301 | V2) ; |
302 | } |
303 | } |
304 | |
305 | //======================================================================= |
306 | //function : D3 |
307 | //purpose : |
308 | //======================================================================= |
309 | |
310 | void Geom2d_BSplineCurve::D3 (const Standard_Real U , |
311 | gp_Pnt2d& P , |
312 | gp_Vec2d& V1, |
313 | gp_Vec2d& V2, |
314 | gp_Vec2d& V3 ) const |
315 | { |
83ada95b |
316 | Standard_Real NewU(U); |
317 | PeriodicNormalization(NewU); |
7fd59977 |
318 | |
83ada95b |
319 | Geom2d_BSplineCurve* MyCurve = (Geom2d_BSplineCurve *) this; |
320 | Standard_Mutex::Sentry aSentry(MyCurve->myMutex); |
321 | |
322 | if (!IsCacheValid(NewU)) |
323 | MyCurve->ValidateCache(NewU); |
324 | |
325 | if(rational) |
326 | { |
7fd59977 |
327 | BSplCLib::CacheD3(NewU, |
328 | deg, |
329 | parametercache, |
330 | spanlenghtcache, |
331 | (cachepoles->Array1()), |
332 | cacheweights->Array1(), |
333 | P, |
334 | V1, |
335 | V2, |
336 | V3) ; |
337 | } |
338 | else { |
339 | BSplCLib::CacheD3(NewU, |
340 | deg, |
341 | parametercache, |
342 | spanlenghtcache, |
343 | (cachepoles->Array1()), |
344 | BSplCLib::NoWeights(), |
345 | P, |
346 | V1, |
347 | V2, |
348 | V3) ; |
349 | } |
350 | } |
351 | |
352 | //======================================================================= |
353 | //function : DN |
354 | //purpose : |
355 | //======================================================================= |
356 | |
357 | gp_Vec2d Geom2d_BSplineCurve::DN (const Standard_Real U, |
358 | const Standard_Integer N ) const |
359 | { |
360 | gp_Vec2d V; |
361 | |
362 | if ( rational ) { |
363 | BSplCLib::DN(U,N,0,deg,periodic,POLES, |
364 | weights->Array1(), |
365 | FKNOTS,FMULTS,V); |
366 | } |
367 | else { |
368 | BSplCLib::DN(U,N,0,deg,periodic,POLES, |
369 | *((TColStd_Array1OfReal*) NULL), |
370 | FKNOTS,FMULTS,V); |
371 | } |
372 | return V; |
373 | } |
374 | |
375 | //======================================================================= |
376 | //function : EndPoint |
377 | //purpose : |
378 | //======================================================================= |
379 | |
380 | gp_Pnt2d Geom2d_BSplineCurve::EndPoint () const |
381 | { |
382 | if (mults->Value (knots->Upper ()) == deg + 1) |
383 | return poles->Value (poles->Upper()); |
384 | else |
385 | return Value(LastParameter()); |
386 | } |
387 | |
388 | //======================================================================= |
389 | //function : FirstUKnotIndex |
390 | //purpose : |
391 | //======================================================================= |
392 | |
393 | Standard_Integer Geom2d_BSplineCurve::FirstUKnotIndex () const |
394 | { |
395 | if (periodic) return 1; |
396 | else return BSplCLib::FirstUKnotIndex (deg, mults->Array1()); |
397 | } |
398 | |
399 | //======================================================================= |
400 | //function : FirstParameter |
401 | //purpose : |
402 | //======================================================================= |
403 | |
404 | Standard_Real Geom2d_BSplineCurve::FirstParameter () const |
405 | { |
406 | return flatknots->Value (deg+1); |
407 | } |
408 | |
409 | //======================================================================= |
410 | //function : Knot |
411 | //purpose : |
412 | //======================================================================= |
413 | |
414 | Standard_Real Geom2d_BSplineCurve::Knot (const Standard_Integer Index) const |
415 | { |
416 | Standard_OutOfRange_Raise_if |
417 | (Index < 1 || Index > knots->Length(), "Geom2d_BSplineCurve::Knot"); |
418 | return knots->Value (Index); |
419 | } |
420 | |
421 | //======================================================================= |
422 | //function : KnotDistribution |
423 | //purpose : |
424 | //======================================================================= |
425 | |
426 | GeomAbs_BSplKnotDistribution Geom2d_BSplineCurve::KnotDistribution () const |
427 | { |
428 | return knotSet; |
429 | } |
430 | |
431 | //======================================================================= |
432 | //function : Knots |
433 | //purpose : |
434 | //======================================================================= |
435 | |
436 | void Geom2d_BSplineCurve::Knots (TColStd_Array1OfReal& K) const |
437 | { |
438 | Standard_DimensionError_Raise_if |
439 | (K.Length() != knots->Length(), "Geom2d_BSplineCurve::Knots"); |
440 | K = knots->Array1(); |
441 | } |
442 | |
443 | //======================================================================= |
444 | //function : KnotSequence |
445 | //purpose : |
446 | //======================================================================= |
447 | |
448 | void Geom2d_BSplineCurve::KnotSequence (TColStd_Array1OfReal& K) const |
449 | { |
450 | Standard_DimensionError_Raise_if |
451 | (K.Length() != flatknots->Length(), "Geom2d_BSplineCurve::KnotSequence"); |
452 | K = flatknots->Array1(); |
453 | } |
454 | |
455 | //======================================================================= |
456 | //function : LastUKnotIndex |
457 | //purpose : |
458 | //======================================================================= |
459 | |
460 | Standard_Integer Geom2d_BSplineCurve::LastUKnotIndex() const |
461 | { |
462 | if (periodic) return knots->Length(); |
463 | else return BSplCLib::LastUKnotIndex (deg, mults->Array1()); |
464 | } |
465 | |
466 | //======================================================================= |
467 | //function : LastParameter |
468 | //purpose : |
469 | //======================================================================= |
470 | |
471 | Standard_Real Geom2d_BSplineCurve::LastParameter () const |
472 | { |
473 | return flatknots->Value (flatknots->Upper()-deg); |
474 | } |
475 | |
476 | //======================================================================= |
477 | //function : LocalValue |
478 | //purpose : |
479 | //======================================================================= |
480 | |
481 | gp_Pnt2d Geom2d_BSplineCurve::LocalValue |
482 | (const Standard_Real U, |
483 | const Standard_Integer FromK1, |
484 | const Standard_Integer ToK2) const |
485 | { |
486 | gp_Pnt2d P; |
487 | LocalD0(U,FromK1,ToK2,P); |
488 | return P; |
489 | } |
490 | |
491 | //======================================================================= |
492 | //function : LocalD0 |
493 | //purpose : |
494 | //======================================================================= |
495 | |
496 | void Geom2d_BSplineCurve::LocalD0 |
497 | (const Standard_Real U, |
498 | const Standard_Integer FromK1, |
499 | const Standard_Integer ToK2, |
500 | gp_Pnt2d& P) const |
501 | { |
502 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
503 | "Geom2d_BSplineCurve::LocalValue"); |
504 | |
505 | Standard_Real u = U; |
506 | Standard_Integer index = 0; |
507 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic,FromK1,ToK2, index,u); |
508 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
509 | |
510 | if ( rational ) { |
511 | BSplCLib::D0(u,index,deg,periodic,POLES, |
512 | weights->Array1(), |
513 | FKNOTS,FMULTS,P); |
514 | } |
515 | else { |
516 | BSplCLib::D0(u,index,deg,periodic,POLES, |
517 | *((TColStd_Array1OfReal*) NULL), |
518 | FKNOTS,FMULTS,P); |
519 | } |
520 | } |
521 | |
522 | //======================================================================= |
523 | //function : LocalD1 |
524 | //purpose : |
525 | //======================================================================= |
526 | |
527 | void Geom2d_BSplineCurve::LocalD1 (const Standard_Real U, |
528 | const Standard_Integer FromK1, |
529 | const Standard_Integer ToK2, |
530 | gp_Pnt2d& P, |
531 | gp_Vec2d& V1) const |
532 | { |
533 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
534 | "Geom2d_BSplineCurve::LocalD1"); |
535 | |
536 | Standard_Real u = U; |
537 | Standard_Integer index = 0; |
538 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u); |
539 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
540 | |
541 | if (rational) { |
542 | BSplCLib::D1(u,index,deg,periodic,POLES, |
543 | weights->Array1(), |
544 | FKNOTS,FMULTS,P,V1); |
545 | } |
546 | else { |
547 | BSplCLib::D1(u,index,deg,periodic,POLES, |
548 | *((TColStd_Array1OfReal*) NULL), |
549 | FKNOTS,FMULTS,P,V1); |
550 | } |
551 | } |
552 | |
553 | //======================================================================= |
554 | //function : LocalD2 |
555 | //purpose : |
556 | //======================================================================= |
557 | |
558 | void Geom2d_BSplineCurve::LocalD2 |
559 | (const Standard_Real U, |
560 | const Standard_Integer FromK1, |
561 | const Standard_Integer ToK2, |
562 | gp_Pnt2d& P, |
563 | gp_Vec2d& V1, |
564 | gp_Vec2d& V2) const |
565 | { |
566 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
567 | "Geom2d_BSplineCurve::LocalD2"); |
568 | |
569 | Standard_Real u = U; |
570 | Standard_Integer index = 0; |
571 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u); |
572 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
573 | |
574 | if ( rational ) { |
575 | BSplCLib::D2(u,index,deg,periodic,POLES, |
576 | weights->Array1(), |
577 | FKNOTS,FMULTS,P,V1,V2); |
578 | } |
579 | else { |
580 | BSplCLib::D2(u,index,deg,periodic,POLES, |
581 | *((TColStd_Array1OfReal*) NULL), |
582 | FKNOTS,FMULTS,P,V1,V2); |
583 | } |
584 | } |
585 | |
586 | //======================================================================= |
587 | //function : LocalD3 |
588 | //purpose : |
589 | //======================================================================= |
590 | |
591 | void Geom2d_BSplineCurve::LocalD3 |
592 | (const Standard_Real U, |
593 | const Standard_Integer FromK1, |
594 | const Standard_Integer ToK2, |
595 | gp_Pnt2d& P, |
596 | gp_Vec2d& V1, |
597 | gp_Vec2d& V2, |
598 | gp_Vec2d& V3) const |
599 | { |
600 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
601 | "Geom2d_BSplineCurve::LocalD3"); |
602 | |
603 | Standard_Real u = U; |
604 | Standard_Integer index = 0; |
605 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u); |
606 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
607 | |
608 | if ( rational ) { |
609 | BSplCLib::D3(u,index,deg,periodic,POLES, |
610 | weights->Array1(), |
611 | FKNOTS,FMULTS,P,V1,V2,V3); |
612 | } |
613 | else { |
614 | BSplCLib::D3(u,index,deg,periodic,POLES, |
615 | *((TColStd_Array1OfReal*) NULL), |
616 | FKNOTS,FMULTS,P,V1,V2,V3); |
617 | } |
618 | } |
619 | |
620 | //======================================================================= |
621 | //function : LocalDN |
622 | //purpose : |
623 | //======================================================================= |
624 | |
625 | gp_Vec2d Geom2d_BSplineCurve::LocalDN |
626 | (const Standard_Real U, |
627 | const Standard_Integer FromK1, |
628 | const Standard_Integer ToK2, |
629 | const Standard_Integer N ) const |
630 | { |
631 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
632 | "Geom2d_BSplineCurve::LocalD3"); |
633 | |
634 | Standard_Real u = U; |
635 | Standard_Integer index = 0; |
636 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u); |
637 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
638 | |
639 | gp_Vec2d V; |
640 | |
641 | if ( rational ) { |
642 | BSplCLib::DN(u,N,index,deg,periodic,POLES, |
643 | weights->Array1(), |
644 | FKNOTS,FMULTS,V); |
645 | } |
646 | else { |
647 | BSplCLib::DN(u,N,index,deg,periodic,POLES, |
648 | *((TColStd_Array1OfReal*) NULL), |
649 | FKNOTS,FMULTS,V); |
650 | } |
651 | return V; |
652 | } |
653 | |
654 | //======================================================================= |
655 | //function : Multiplicity |
656 | //purpose : |
657 | //======================================================================= |
658 | |
659 | Standard_Integer Geom2d_BSplineCurve::Multiplicity |
660 | (const Standard_Integer Index) const |
661 | { |
662 | Standard_OutOfRange_Raise_if (Index < 1 || Index > mults->Length(), |
663 | "Geom2d_BSplineCurve::Multiplicity"); |
664 | return mults->Value (Index); |
665 | } |
666 | |
667 | //======================================================================= |
668 | //function : Multiplicities |
669 | //purpose : |
670 | //======================================================================= |
671 | |
672 | void Geom2d_BSplineCurve::Multiplicities (TColStd_Array1OfInteger& M) const |
673 | { |
674 | Standard_DimensionError_Raise_if (M.Length() != mults->Length(), |
675 | "Geom2d_BSplineCurve::Multiplicities"); |
676 | M = mults->Array1(); |
677 | } |
678 | |
679 | //======================================================================= |
680 | //function : NbKnots |
681 | //purpose : |
682 | //======================================================================= |
683 | |
684 | Standard_Integer Geom2d_BSplineCurve::NbKnots () const |
685 | { return knots->Length(); } |
686 | |
687 | //======================================================================= |
688 | //function : NbPoles |
689 | //purpose : |
690 | //======================================================================= |
691 | |
692 | Standard_Integer Geom2d_BSplineCurve::NbPoles () const |
693 | { return poles->Length(); } |
694 | |
695 | //======================================================================= |
696 | //function : Pole |
697 | //purpose : |
698 | //======================================================================= |
699 | |
700 | gp_Pnt2d Geom2d_BSplineCurve::Pole (const Standard_Integer Index) const |
701 | { |
702 | Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(), |
703 | "Geom2d_BSplineCurve::Pole"); |
704 | return poles->Value (Index); |
705 | } |
706 | |
707 | //======================================================================= |
708 | //function : Poles |
709 | //purpose : |
710 | //======================================================================= |
711 | |
712 | void Geom2d_BSplineCurve::Poles (TColgp_Array1OfPnt2d& P) const |
713 | { |
714 | Standard_DimensionError_Raise_if (P.Length() != poles->Length(), |
715 | "Geom2d_BSplineCurve::Poles"); |
716 | P = poles->Array1(); |
717 | } |
718 | |
719 | //======================================================================= |
720 | //function : StartPoint |
721 | //purpose : |
722 | //======================================================================= |
723 | |
724 | gp_Pnt2d Geom2d_BSplineCurve::StartPoint () const |
725 | { |
726 | if (mults->Value (1) == deg + 1) |
727 | return poles->Value (1); |
728 | else |
729 | return Value(FirstParameter()); |
730 | } |
731 | |
732 | //======================================================================= |
733 | //function : Weight |
734 | //purpose : |
735 | //======================================================================= |
736 | |
737 | Standard_Real Geom2d_BSplineCurve::Weight |
738 | (const Standard_Integer Index) const |
739 | { |
740 | Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(), |
741 | "Geom2d_BSplineCurve::Weight"); |
742 | if (IsRational()) |
743 | return weights->Value (Index); |
744 | else |
745 | return 1.; |
746 | } |
747 | |
748 | //======================================================================= |
749 | //function : Weights |
750 | //purpose : |
751 | //======================================================================= |
752 | |
753 | void Geom2d_BSplineCurve::Weights |
754 | (TColStd_Array1OfReal& W) const |
755 | { |
756 | Standard_DimensionError_Raise_if (W.Length() != poles->Length(), |
757 | "Geom2d_BSplineCurve::Weights"); |
758 | if (IsRational()) |
759 | W = weights->Array1(); |
760 | else { |
761 | Standard_Integer i; |
762 | for (i = W.Lower(); i <= W.Upper(); i++) |
763 | W(i) = 1.; |
764 | } |
765 | } |
766 | |
767 | //======================================================================= |
768 | //function : IsRational |
769 | //purpose : |
770 | //======================================================================= |
771 | |
772 | Standard_Boolean Geom2d_BSplineCurve::IsRational () const |
773 | { |
774 | return !weights.IsNull(); |
775 | } |
776 | |
777 | //======================================================================= |
778 | //function : Transform |
779 | //purpose : |
780 | //======================================================================= |
781 | |
782 | void Geom2d_BSplineCurve::Transform |
783 | (const gp_Trsf2d& T) |
784 | { |
785 | TColgp_Array1OfPnt2d & CPoles = poles->ChangeArray1(); |
786 | for (Standard_Integer I = 1; I <= CPoles.Length(); I++) |
787 | CPoles (I).Transform (T); |
788 | |
789 | InvalidateCache(); |
790 | // maxderivinvok = 0; |
791 | } |
792 | |
793 | //======================================================================= |
794 | //function : LocateU |
795 | //purpose : |
796 | //======================================================================= |
797 | |
798 | void Geom2d_BSplineCurve::LocateU |
799 | (const Standard_Real U, |
800 | const Standard_Real ParametricTolerance, |
801 | Standard_Integer& I1, |
802 | Standard_Integer& I2, |
803 | const Standard_Boolean WithKnotRepetition) const |
804 | { |
805 | Standard_Real NewU = U; |
806 | Handle(TColStd_HArray1OfReal) TheKnots; |
807 | if (WithKnotRepetition) TheKnots = flatknots; |
808 | else TheKnots = knots; |
809 | |
810 | const TColStd_Array1OfReal & CKnots = TheKnots->Array1(); |
811 | |
812 | PeriodicNormalization(NewU); //Attention a la periode |
813 | Standard_Real UFirst = CKnots (1); |
814 | Standard_Real ULast = CKnots (CKnots.Length()); |
41c52af3 |
815 | Standard_Real PParametricTolerance = Abs(ParametricTolerance); |
816 | if (Abs (NewU - UFirst) <= PParametricTolerance) { I1 = I2 = 1; } |
817 | else if (Abs (NewU - ULast) <= PParametricTolerance) { |
7fd59977 |
818 | I1 = I2 = CKnots.Length(); |
819 | } |
41c52af3 |
820 | else if (NewU < UFirst) { |
7fd59977 |
821 | I2 = 1; |
822 | I1 = 0; |
823 | } |
41c52af3 |
824 | else if (NewU > ULast) { |
7fd59977 |
825 | I1 = CKnots.Length(); |
826 | I2 = I1 + 1; |
827 | } |
828 | else { |
829 | I1 = 1; |
830 | BSplCLib::Hunt (CKnots, NewU, I1); |
41c52af3 |
831 | while ( Abs( CKnots(I1+1) - NewU) <= PParametricTolerance) I1++; |
832 | if ( Abs( CKnots(I1) - NewU) <= PParametricTolerance) { |
7fd59977 |
833 | I2 = I1; |
834 | } |
835 | else { |
836 | I2 = I1 + 1; |
837 | } |
838 | } |
839 | } |
840 | |
841 | //======================================================================= |
842 | //function : Resolution |
843 | //purpose : |
844 | //======================================================================= |
845 | |
846 | void Geom2d_BSplineCurve::Resolution(const Standard_Real ToleranceUV, |
847 | Standard_Real & UTolerance) |
848 | { |
849 | Standard_Integer ii ; |
850 | if(!maxderivinvok){ |
851 | if ( periodic) { |
852 | Standard_Integer NbKnots, NbPoles; |
853 | BSplCLib::PrepareUnperiodize( deg, |
854 | mults->Array1(), |
855 | NbKnots, |
856 | NbPoles); |
857 | TColgp_Array1OfPnt2d new_poles(1,NbPoles) ; |
858 | TColStd_Array1OfReal new_weights(1,NbPoles) ; |
859 | for(ii = 1 ; ii <= NbPoles ; ii++) { |
860 | new_poles(ii) = poles->Array1()(((ii-1) % poles->Length()) + 1) ; |
861 | } |
862 | if (rational) { |
863 | for(ii = 1 ; ii <= NbPoles ; ii++) { |
864 | new_weights(ii) = weights->Array1()(((ii-1) % poles->Length()) + 1) ; |
865 | } |
866 | BSplCLib::Resolution(new_poles, |
867 | new_weights, |
868 | new_poles.Length(), |
869 | flatknots->Array1(), |
870 | deg, |
871 | 1., |
872 | maxderivinv) ; |
873 | } |
874 | else { |
875 | BSplCLib::Resolution(new_poles, |
876 | *((TColStd_Array1OfReal*) NULL), |
877 | new_poles.Length(), |
878 | flatknots->Array1(), |
879 | deg, |
880 | 1., |
881 | maxderivinv) ; |
882 | } |
883 | } |
884 | else { |
885 | if (rational) { |
886 | BSplCLib::Resolution(poles->Array1(), |
887 | weights->Array1(), |
888 | poles->Length(), |
889 | flatknots->Array1(), |
890 | deg, |
891 | 1., |
892 | maxderivinv) ; |
893 | } |
894 | else { |
895 | BSplCLib::Resolution(poles->Array1(), |
896 | *((TColStd_Array1OfReal*) NULL), |
897 | poles->Length(), |
898 | flatknots->Array1(), |
899 | deg, |
900 | 1., |
901 | maxderivinv) ; |
902 | } |
903 | } |
904 | maxderivinvok = 1; |
905 | } |
906 | UTolerance = ToleranceUV * maxderivinv; |
907 | } |
908 | |