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