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