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