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