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