1 // Created on: 1993-03-09
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
22 // 14-Mar-96 : xab portage hp
23 // pmn : 28-Jun-96 Distinction entre la continuite en U et V (bug PRO4625)
24 // pmn : 07-Jan-97 Centralisation des verif rational (PRO6834)
25 // et ajout des InvalideCache() dans les SetWeight*(PRO6833)
26 // RBD : 15-10-98 ; Le cache est maintenant calcule sur [-1,1] (pro15537).
27 // jct : 19-01-99 ; permutation de urational et vrational dans Rational.
28 #define No_Standard_OutOfRange
30 #include <Geom_BSplineSurface.ixx>
33 #include <BSplCLib.hxx>
34 #include <BSplSLib.hxx>
36 #include <Standard_ConstructionError.hxx>
37 #include <Standard_NotImplemented.hxx>
38 #include <Standard_OutOfRange.hxx>
39 #include <Precision.hxx>
41 //=======================================================================
42 //function : CheckSurfaceData
43 //purpose : Internal use only.
44 //=======================================================================
46 static void CheckSurfaceData
47 (const TColgp_Array2OfPnt& SPoles,
48 const TColStd_Array1OfReal& SUKnots,
49 const TColStd_Array1OfReal& SVKnots,
50 const TColStd_Array1OfInteger& SUMults,
51 const TColStd_Array1OfInteger& SVMults,
52 const Standard_Integer UDegree,
53 const Standard_Integer VDegree,
54 const Standard_Boolean UPeriodic,
55 const Standard_Boolean VPeriodic)
57 if (UDegree < 1 || UDegree > Geom_BSplineSurface::MaxDegree () ||
58 VDegree < 1 || VDegree > Geom_BSplineSurface::MaxDegree ()) {
59 Standard_ConstructionError::Raise("Geom_BSplineSurface");
61 if (SPoles.ColLength () < 2 || SPoles.RowLength () < 2) {
62 Standard_ConstructionError::Raise("Geom_BSplineSurface");
65 if (SUKnots.Length() != SUMults.Length() ||
66 SVKnots.Length() != SVMults.Length()) {
67 Standard_ConstructionError::Raise("Geom_BSplineSurface");
71 for (i = SUKnots.Lower(); i < SUKnots.Upper(); i++) {
72 if (SUKnots(i+1) - SUKnots(i) <= Epsilon(Abs(SUKnots(i)))) {
73 Standard_ConstructionError::Raise("Geom_BSplineSurface");
77 for (i = SVKnots.Lower(); i < SVKnots.Upper(); i++) {
78 if (SVKnots(i+1) - SVKnots(i) <= Epsilon(Abs(SVKnots(i)))) {
79 Standard_ConstructionError::Raise("Geom_BSplineSurface");
83 if (SPoles.ColLength() != BSplCLib::NbPoles(UDegree,UPeriodic,SUMults))
84 Standard_ConstructionError::Raise("Geom_BSplineSurface");
86 if (SPoles.RowLength() != BSplCLib::NbPoles(VDegree,VPeriodic,SVMults))
87 Standard_ConstructionError::Raise("Geom_BSplineSurface");
90 //=======================================================================
91 //function : KnotAnalysis
92 //purpose : Internal use only.
93 //=======================================================================
95 static void KnotAnalysis
96 (const Standard_Integer Degree,
97 const TColStd_Array1OfReal& CKnots,
98 const TColStd_Array1OfInteger& CMults,
99 GeomAbs_BSplKnotDistribution& KnotForm,
100 Standard_Integer& MaxKnotMult)
102 KnotForm = GeomAbs_NonUniform;
104 BSplCLib_KnotDistribution KSet =
105 BSplCLib::KnotForm (CKnots, 1, CKnots.Length());
108 if (KSet == BSplCLib_Uniform) {
109 BSplCLib_MultDistribution MSet =
110 BSplCLib::MultForm (CMults, 1, CMults.Length());
112 case BSplCLib_NonConstant :
114 case BSplCLib_Constant :
115 if (CKnots.Length() == 2) {
116 KnotForm = GeomAbs_PiecewiseBezier;
119 if (CMults (1) == 1) KnotForm = GeomAbs_Uniform;
122 case BSplCLib_QuasiConstant :
123 if (CMults (1) == Degree + 1) {
124 Standard_Real M = CMults (2);
125 if (M == Degree ) KnotForm = GeomAbs_PiecewiseBezier;
126 else if (M == 1) KnotForm = GeomAbs_QuasiUniform;
132 Standard_Integer FirstKM = BSplCLib::FirstUKnotIndex (Degree, CMults);
133 Standard_Integer LastKM = BSplCLib::LastUKnotIndex (Degree, CMults);
135 if (LastKM - FirstKM != 1) {
136 Standard_Integer Multi;
137 for (Standard_Integer i = FirstKM + 1; i < LastKM; i++) {
139 MaxKnotMult = Max (MaxKnotMult, Multi);
144 //=======================================================================
145 //function : Rational
146 //purpose : Internal use only.
147 //=======================================================================
149 static void Rational(const TColStd_Array2OfReal& Weights,
150 Standard_Boolean& Urational,
151 Standard_Boolean& Vrational)
153 Standard_Integer I,J;
154 J = Weights.LowerCol ();
155 Vrational = Standard_False;
156 while (!Vrational && J <= Weights.UpperCol()) {
157 I = Weights.LowerRow();
158 while (!Vrational && I <= Weights.UpperRow() - 1) {
159 Vrational = (Abs(Weights (I, J) - Weights (I+1, J))
160 > Epsilon (Abs(Weights (I, J))));
166 I = Weights.LowerRow ();
167 Urational = Standard_False;
168 while (!Urational && I <= Weights.UpperRow()) {
169 J = Weights.LowerCol();
170 while (!Urational && J <= Weights.UpperCol() - 1) {
171 Urational = (Abs(Weights (I, J) - Weights (I, J+1))
172 > Epsilon (Abs(Weights (I, J))));
179 //=======================================================================
182 //=======================================================================
184 Handle(Geom_Geometry) Geom_BSplineSurface::Copy () const
186 Handle(Geom_BSplineSurface) S;
187 if (urational || vrational)
188 S = new Geom_BSplineSurface (poles->Array2() , weights->Array2(),
189 uknots->Array1(), vknots->Array1(),
190 umults->Array1(), vmults->Array1(),
192 uperiodic, vperiodic);
194 S = new Geom_BSplineSurface (poles->Array2(),
195 uknots->Array1(), vknots->Array1(),
196 umults->Array1(), vmults->Array1(),
198 uperiodic, vperiodic);
202 //=======================================================================
203 //function : Geom_BSplineSurface
205 //=======================================================================
207 Geom_BSplineSurface::Geom_BSplineSurface
208 (const TColgp_Array2OfPnt& Poles,
209 const TColStd_Array1OfReal& UKnots,
210 const TColStd_Array1OfReal& VKnots,
211 const TColStd_Array1OfInteger& UMults,
212 const TColStd_Array1OfInteger& VMults,
213 const Standard_Integer UDegree,
214 const Standard_Integer VDegree,
215 const Standard_Boolean UPeriodic,
216 const Standard_Boolean VPeriodic
218 urational(Standard_False),
219 vrational(Standard_False),
220 uperiodic(UPeriodic),
221 vperiodic(VPeriodic),
227 Standard_Integer MinDegree,
232 CheckSurfaceData(Poles,
236 UPeriodic, VPeriodic);
240 poles = new TColgp_HArray2OfPnt(1,Poles.ColLength(),
241 1,Poles.RowLength());
242 poles->ChangeArray2() = Poles;
244 weights = new TColStd_HArray2OfReal (1,Poles.ColLength(),
245 1,Poles.RowLength(), 1.0);
247 uknots = new TColStd_HArray1OfReal (1,UKnots.Length());
248 uknots->ChangeArray1() = UKnots;
250 umults = new TColStd_HArray1OfInteger (1,UMults.Length());
251 umults->ChangeArray1() = UMults;
253 vknots = new TColStd_HArray1OfReal (1,VKnots.Length());
254 vknots->ChangeArray1() = VKnots;
256 vmults = new TColStd_HArray1OfInteger (1,VMults.Length());
257 vmults->ChangeArray1() = VMults;
258 MinDegree = Min(udeg,vdeg) ;
259 MaxDegree = Max(udeg,vdeg) ;
260 cachepoles = new TColgp_HArray2OfPnt(1,MaxDegree + 1,
263 cacheweights.Nullify() ;
264 ucacheparameter = 0.0e0 ;
265 vcacheparameter = 0.0e0 ;
266 ucachespanlenght = 1.0e0 ;
267 vcachespanlenght = 1.0e0 ;
268 ucachespanindex = 0 ;
269 vcachespanindex = 0 ;
276 //=======================================================================
277 //function : Geom_BSplineSurface
279 //=======================================================================
281 Geom_BSplineSurface::Geom_BSplineSurface
282 (const TColgp_Array2OfPnt& Poles,
283 const TColStd_Array2OfReal& Weights,
284 const TColStd_Array1OfReal& UKnots,
285 const TColStd_Array1OfReal& VKnots,
286 const TColStd_Array1OfInteger& UMults,
287 const TColStd_Array1OfInteger& VMults,
288 const Standard_Integer UDegree,
289 const Standard_Integer VDegree,
290 const Standard_Boolean UPeriodic,
291 const Standard_Boolean VPeriodic) :
292 urational(Standard_False),
293 vrational(Standard_False),
294 uperiodic(UPeriodic),
295 vperiodic(VPeriodic),
300 Standard_Integer MinDegree,
304 if (Weights.ColLength() != Poles.ColLength())
305 Standard_ConstructionError::Raise("Geom_BSplineSurface");
307 if (Weights.RowLength() != Poles.RowLength())
308 Standard_ConstructionError::Raise("Geom_BSplineSurface");
310 Standard_Integer i,j;
311 for (i = Weights.LowerRow(); i <= Weights.UpperRow(); i++) {
312 for (j = Weights.LowerCol(); j <= Weights.UpperCol(); j++) {
313 if (Weights(i,j) <= gp::Resolution())
314 Standard_ConstructionError::Raise("Geom_BSplineSurface");
318 // check really rational
320 Rational(Weights, urational, vrational);
324 CheckSurfaceData(Poles,
328 UPeriodic, VPeriodic);
332 poles = new TColgp_HArray2OfPnt(1,Poles.ColLength(),
333 1,Poles.RowLength());
334 poles->ChangeArray2() = Poles;
336 weights = new TColStd_HArray2OfReal (1,Poles.ColLength(),
337 1,Poles.RowLength());
338 weights->ChangeArray2() = Weights;
340 uknots = new TColStd_HArray1OfReal (1,UKnots.Length());
341 uknots->ChangeArray1() = UKnots;
343 umults = new TColStd_HArray1OfInteger (1,UMults.Length());
344 umults->ChangeArray1() = UMults;
346 vknots = new TColStd_HArray1OfReal (1,VKnots.Length());
347 vknots->ChangeArray1() = VKnots;
349 vmults = new TColStd_HArray1OfInteger (1,VMults.Length());
350 vmults->ChangeArray1() = VMults;
351 MinDegree = Min(udeg,vdeg) ;
352 MaxDegree = Max(udeg,vdeg) ;
353 cachepoles = new TColgp_HArray2OfPnt(1,MaxDegree + 1,
355 if (urational || vrational) {
356 cacheweights = new TColStd_HArray2OfReal (1,MaxDegree + 1,
359 ucacheparameter = 0.0e0 ;
360 vcacheparameter = 0.0e0 ;
361 ucachespanlenght = 1.0e0 ;
362 vcachespanlenght = 1.0e0 ;
363 ucachespanindex = 0 ;
364 vcachespanindex = 0 ;
371 //=======================================================================
372 //function : ExchangeUV
374 //=======================================================================
376 void Geom_BSplineSurface::ExchangeUV ()
378 Standard_Integer LC = poles->LowerCol();
379 Standard_Integer UC = poles->UpperCol();
380 Standard_Integer LR = poles->LowerRow();
381 Standard_Integer UR = poles->UpperRow();
383 Handle(TColgp_HArray2OfPnt) npoles =
384 new TColgp_HArray2OfPnt (LC, UC, LR, UR);
385 Handle(TColStd_HArray2OfReal) nweights =
386 new TColStd_HArray2OfReal (LC, UC, LR, UR);
388 const TColgp_Array2OfPnt & spoles = poles->Array2();
389 const TColStd_Array2OfReal & sweights = weights->Array2();
391 TColgp_Array2OfPnt& snpoles = npoles->ChangeArray2();
392 TColStd_Array2OfReal& snweights = nweights->ChangeArray2();
394 Standard_Integer i, j;
395 for (i = LC; i <= UC; i++) {
396 for (j = LR; j <= UR; j++) {
397 snpoles (i,j) = spoles (j,i);
398 snweights (i,j) = sweights (j,i);
405 Standard_Boolean temp = urational;
406 urational = vrational;
410 uperiodic = vperiodic;
413 Standard_Integer tempdeg = udeg;
418 Handle(TColStd_HArray1OfReal) tempknots = uknots;
422 Handle(TColStd_HArray1OfInteger) tempmults = umults;
430 //=======================================================================
431 //function : IncreaseDegree
433 //=======================================================================
435 void Geom_BSplineSurface::IncreaseDegree (const Standard_Integer UDegree,
436 const Standard_Integer VDegree)
438 if (UDegree != udeg) {
439 if ( UDegree < udeg || UDegree > Geom_BSplineSurface::MaxDegree())
440 Standard_ConstructionError::Raise();
442 Standard_Integer FromK1 = FirstUKnotIndex();
443 Standard_Integer ToK2 = LastUKnotIndex();
445 Standard_Integer Step = UDegree - udeg;
447 Handle(TColgp_HArray2OfPnt) npoles = new
448 TColgp_HArray2OfPnt( 1, poles->ColLength() + Step * (ToK2 - FromK1),
449 1, poles->RowLength());
451 Standard_Integer nbknots = BSplCLib::IncreaseDegreeCountKnots
452 (udeg,UDegree,uperiodic,umults->Array1());
454 Handle(TColStd_HArray1OfReal) nknots =
455 new TColStd_HArray1OfReal(1,nbknots);
457 Handle(TColStd_HArray1OfInteger) nmults =
458 new TColStd_HArray1OfInteger(1,nbknots);
460 Handle(TColStd_HArray2OfReal) nweights
461 = new TColStd_HArray2OfReal(1,npoles->ColLength(),
462 1,npoles->RowLength(), 1.);
464 if (urational || vrational) {
466 BSplSLib::IncreaseDegree
467 (Standard_True, udeg, UDegree, uperiodic,
468 poles->Array2(),weights->Array2(),
469 uknots->Array1(),umults->Array1(),
470 npoles->ChangeArray2(),nweights->ChangeArray2(),
471 nknots->ChangeArray1(),nmults->ChangeArray1());
475 BSplSLib::IncreaseDegree
476 (Standard_True, udeg, UDegree, uperiodic,
477 poles->Array2(),BSplSLib::NoWeights(),
478 uknots->Array1(),umults->Array1(),
479 npoles->ChangeArray2(),*((TColStd_Array2OfReal*) NULL),
480 nknots->ChangeArray1(),nmults->ChangeArray1());
490 if (VDegree != vdeg) {
491 if ( VDegree < vdeg || VDegree > Geom_BSplineSurface::MaxDegree())
492 Standard_ConstructionError::Raise();
494 Standard_Integer FromK1 = FirstVKnotIndex();
495 Standard_Integer ToK2 = LastVKnotIndex();
497 Standard_Integer Step = VDegree - vdeg;
499 Handle(TColgp_HArray2OfPnt) npoles = new
500 TColgp_HArray2OfPnt( 1, poles->ColLength(),
501 1, poles->RowLength() + Step * (ToK2 - FromK1));
503 Standard_Integer nbknots = BSplCLib::IncreaseDegreeCountKnots
504 (vdeg,VDegree,vperiodic,vmults->Array1());
506 Handle(TColStd_HArray1OfReal) nknots =
507 new TColStd_HArray1OfReal(1,nbknots);
509 Handle(TColStd_HArray1OfInteger) nmults =
510 new TColStd_HArray1OfInteger(1,nbknots);
512 Handle(TColStd_HArray2OfReal) nweights
513 = new TColStd_HArray2OfReal(1,npoles->ColLength(),
514 1,npoles->RowLength(), 1.);
516 if (urational || vrational) {
518 BSplSLib::IncreaseDegree
519 (Standard_False, vdeg, VDegree, vperiodic,
520 poles->Array2(),weights->Array2(),
521 vknots->Array1(),vmults->Array1(),
522 npoles->ChangeArray2(),nweights->ChangeArray2(),
523 nknots->ChangeArray1(),nmults->ChangeArray1());
527 BSplSLib::IncreaseDegree
528 (Standard_False, vdeg, VDegree, vperiodic,
529 poles->Array2(),BSplSLib::NoWeights(),
530 vknots->Array1(),vmults->Array1(),
531 npoles->ChangeArray2(),*((TColStd_Array2OfReal*) NULL),
532 nknots->ChangeArray1(),nmults->ChangeArray1());
543 //=======================================================================
544 //function : IncreaseUMultiplicity
546 //=======================================================================
548 void Geom_BSplineSurface::IncreaseUMultiplicity
549 (const Standard_Integer UIndex,
550 const Standard_Integer M)
552 TColStd_Array1OfReal k(1,1);
553 k(1) = uknots->Value(UIndex);
554 TColStd_Array1OfInteger m(1,1);
555 m(1) = M - umults->Value(UIndex);
556 InsertUKnots(k,m,Epsilon(1.),Standard_True);
559 //=======================================================================
560 //function : IncreaseUMultiplicity
562 //=======================================================================
564 void Geom_BSplineSurface::IncreaseUMultiplicity
565 (const Standard_Integer FromI1,
566 const Standard_Integer ToI2,
567 const Standard_Integer M)
569 Handle(TColStd_HArray1OfReal) tk = uknots;
570 TColStd_Array1OfReal k((uknots->Array1())(FromI1),FromI1,ToI2);
571 TColStd_Array1OfInteger m(FromI1, ToI2);
572 for (Standard_Integer i = FromI1; i <= ToI2; i++)
573 m(i) = M - umults->Value(i);
574 InsertUKnots(k,m,Epsilon(1.),Standard_True);
577 //=======================================================================
578 //function : IncreaseVMultiplicity
580 //=======================================================================
582 void Geom_BSplineSurface::IncreaseVMultiplicity
583 (const Standard_Integer VIndex,
584 const Standard_Integer M)
586 TColStd_Array1OfReal k(1,1);
587 k(1) = vknots->Value(VIndex);
588 TColStd_Array1OfInteger m(1,1);
589 m(1) = M - vmults->Value(VIndex);
590 InsertVKnots(k,m,Epsilon(1.),Standard_True);
593 //=======================================================================
594 //function : IncreaseVMultiplicity
596 //=======================================================================
598 void Geom_BSplineSurface::IncreaseVMultiplicity
599 (const Standard_Integer FromI1,
600 const Standard_Integer ToI2,
601 const Standard_Integer M)
603 Handle(TColStd_HArray1OfReal) tk = vknots;
604 TColStd_Array1OfReal k((vknots->Array1())(FromI1),FromI1,ToI2);
605 TColStd_Array1OfInteger m(FromI1,ToI2);
606 for (Standard_Integer i = FromI1; i <= ToI2; i++)
607 m(i) = M - vmults->Value(i);
608 InsertVKnots(k,m,Epsilon(1.),Standard_True);
611 //=======================================================================
614 //=======================================================================
616 void Geom_BSplineSurface::Segment(const Standard_Real U1,
617 const Standard_Real U2,
618 const Standard_Real V1,
619 const Standard_Real V2)
622 Standard_DomainError_Raise_if ( (U2 < U1) || (V2 < V1),
623 "Geom_BSplineCurve::Segment");
624 Standard_Real deltaU = Max(Abs(U2),Abs(U1));
625 Standard_Real EpsU = Epsilon(deltaU);
628 Standard_Real deltaV = Max(Abs(V2),Abs(V1));
629 Standard_Real EpsV = Epsilon(deltaV);
632 Standard_Real NewU1, NewU2, NewV1, NewV2;
634 Standard_Integer indexU, indexV;
636 // inserting the UKnots
637 TColStd_Array1OfReal UKnots(1,2);
638 TColStd_Array1OfInteger UMults(1,2);
641 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
642 U1,uperiodic,uknots->Lower(),uknots->Upper(),
645 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
646 U2,uperiodic,uknots->Lower(),uknots->Upper(),
648 UKnots( 1) = Min( NewU1, NewU2);
649 UKnots( 2) = Max( NewU1, NewU2);
650 UMults( 1) = UMults( 2) = udeg;
651 InsertUKnots( UKnots, UMults, EpsU);
653 // Inserting the VKnots
654 TColStd_Array1OfReal VKnots(1,2);
655 TColStd_Array1OfInteger VMults(1,2);
658 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
659 V1,vperiodic,vknots->Lower(),vknots->Upper(),
662 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
663 V2,vperiodic,vknots->Lower(),vknots->Upper(),
665 VKnots( 1) = Min( NewV1, NewV2);
666 VKnots( 2) = Max( NewV1, NewV2);
667 VMults( 1) = VMults( 2) = vdeg;
668 InsertVKnots( VKnots, VMults, EpsV);
671 if (uperiodic) { // set the origine at NewU1
672 Standard_Integer index = 0;
673 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
674 U1,uperiodic,uknots->Lower(),uknots->Upper(),
676 if ( Abs(uknots->Value(index+1)-U) <= EpsU)
682 // compute index1 and index2 to set the new knots and mults
683 Standard_Integer index1U = 0, index2U = 0;
684 Standard_Integer FromU1 = uknots->Lower();
685 Standard_Integer ToU2 = uknots->Upper();
686 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
687 NewU1,uperiodic,FromU1,ToU2,index1U,U);
688 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
689 NewU1 + deltaU,uperiodic,FromU1,ToU2,index2U,U);
690 if ( Abs(uknots->Value(index2U+1)-U) <= EpsU)
693 Standard_Integer nbuknots = index2U - index1U + 1;
695 Handle(TColStd_HArray1OfReal)
696 nuknots = new TColStd_HArray1OfReal(1,nbuknots);
697 Handle(TColStd_HArray1OfInteger)
698 numults = new TColStd_HArray1OfInteger(1,nbuknots);
700 Standard_Integer i , k = 1;
701 for ( i = index1U; i<= index2U; i++) {
702 nuknots->SetValue(k, uknots->Value(i));
703 numults->SetValue(k, umults->Value(i));
706 numults->SetValue( 1, udeg + 1);
707 numults->SetValue(nbuknots, udeg + 1);
710 if (vperiodic) { // set the origine at NewV1
711 Standard_Integer index = 0;
712 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
713 V1,vperiodic,vknots->Lower(),vknots->Upper(),
715 if ( Abs(vknots->Value(index+1)-V) <= EpsV)
721 // compute index1 and index2 to set the new knots and mults
722 Standard_Integer index1V = 0, index2V = 0;
723 Standard_Integer FromV1 = vknots->Lower();
724 Standard_Integer ToV2 = vknots->Upper();
725 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
726 NewV1,vperiodic,FromV1,ToV2,index1V,V);
727 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
728 NewV1 + deltaV,vperiodic,FromV1,ToV2,index2V,V);
729 if ( Abs(vknots->Value(index2V+1)-V) <= EpsV)
732 Standard_Integer nbvknots = index2V - index1V + 1;
734 Handle(TColStd_HArray1OfReal)
735 nvknots = new TColStd_HArray1OfReal(1,nbvknots);
736 Handle(TColStd_HArray1OfInteger)
737 nvmults = new TColStd_HArray1OfInteger(1,nbvknots);
740 for ( i = index1V; i<= index2V; i++) {
741 nvknots->SetValue(k, vknots->Value(i));
742 nvmults->SetValue(k, vmults->Value(i));
745 nvmults->SetValue( 1, vdeg + 1);
746 nvmults->SetValue(nbvknots, vdeg + 1);
749 // compute index1 and index2 to set the new poles and weights
750 Standard_Integer pindex1U
751 = BSplCLib::PoleIndex(udeg,index1U,uperiodic,umults->Array1());
752 Standard_Integer pindex2U
753 = BSplCLib::PoleIndex(udeg,index2U,uperiodic,umults->Array1());
756 pindex2U = Min( pindex2U+1, poles->ColLength());
758 Standard_Integer nbupoles = pindex2U - pindex1U + 1;
760 // compute index1 and index2 to set the new poles and weights
761 Standard_Integer pindex1V
762 = BSplCLib::PoleIndex(vdeg,index1V,vperiodic,vmults->Array1());
763 Standard_Integer pindex2V
764 = BSplCLib::PoleIndex(vdeg,index2V,vperiodic,vmults->Array1());
767 pindex2V = Min( pindex2V+1, poles->RowLength());
769 Standard_Integer nbvpoles = pindex2V - pindex1V + 1;
772 Handle(TColStd_HArray2OfReal) nweights;
774 Handle(TColgp_HArray2OfPnt)
775 npoles = new TColgp_HArray2OfPnt(1,nbupoles,1,nbvpoles);
778 Standard_Integer j, l;
779 if ( urational || vrational) {
780 nweights = new TColStd_HArray2OfReal( 1,nbupoles,1,nbvpoles);
781 for ( i = pindex1U; i <= pindex2U; i++) {
783 for ( j = pindex1V; j <= pindex2V; j++) {
784 npoles->SetValue(k,l, poles->Value(i,j));
785 nweights->SetValue(k,l, weights->Value(i,j));
792 for ( i = pindex1U; i <= pindex2U; i++) {
794 for ( j = pindex1V; j <= pindex2V; j++) {
795 npoles->SetValue(k,l, poles->Value(i,j));
807 if ( urational || vrational)
810 weights = new TColStd_HArray2OfReal (1,poles->ColLength(),
811 1,poles->RowLength(), 1.0);
819 //=======================================================================
820 //function : CheckAndSegment
822 //=======================================================================
824 void Geom_BSplineSurface::CheckAndSegment(const Standard_Real U1,
825 const Standard_Real U2,
826 const Standard_Real V1,
827 const Standard_Real V2)
830 Standard_DomainError_Raise_if ( (U2 < U1) || (V2 < V1),
831 "Geom_BSplineCurve::Segment");
832 Standard_Real deltaU = Max(Abs(U2),Abs(U1));
833 Standard_Real EpsU = Epsilon(deltaU);
836 Standard_Real deltaV = Max(Abs(V2),Abs(V1));
837 Standard_Real EpsV = Epsilon(deltaV);
840 Standard_Real NewU1, NewU2, NewV1, NewV2;
842 Standard_Integer indexU, indexV;
844 Standard_Boolean segment_in_U = Standard_True;
845 Standard_Boolean segment_in_V = Standard_True;
846 segment_in_U = ( Abs(U1 - uknots->Value(uknots->Lower())) > EpsU )
847 || ( Abs(U2 - uknots->Value(uknots->Upper())) > EpsU );
848 segment_in_V = ( Abs(V1 - vknots->Value(vknots->Lower())) > EpsV )
849 || ( Abs(V2 - vknots->Value(vknots->Upper())) > EpsV );
852 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
853 U1,uperiodic,uknots->Lower(),uknots->Upper(),
856 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
857 U2,uperiodic,uknots->Lower(),uknots->Upper(),
860 // inserting the UKnots
861 TColStd_Array1OfReal UKnots(1,2);
862 TColStd_Array1OfInteger UMults(1,2);
863 UKnots( 1) = Min( NewU1, NewU2);
864 UKnots( 2) = Max( NewU1, NewU2);
865 UMults( 1) = UMults( 2) = udeg;
867 InsertUKnots( UKnots, UMults, EpsU);
871 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
872 V1,vperiodic,vknots->Lower(),vknots->Upper(),
875 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
876 V2,vperiodic,vknots->Lower(),vknots->Upper(),
879 // Inserting the VKnots
880 TColStd_Array1OfReal VKnots(1,2);
881 TColStd_Array1OfInteger VMults(1,2);
883 VKnots( 1) = Min( NewV1, NewV2);
884 VKnots( 2) = Max( NewV1, NewV2);
885 VMults( 1) = VMults( 2) = vdeg;
886 InsertVKnots( VKnots, VMults, EpsV);
889 if (uperiodic && segment_in_U) { // set the origine at NewU1
890 Standard_Integer index = 0;
891 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
892 U1,uperiodic,uknots->Lower(),uknots->Upper(),
894 if ( Abs(uknots->Value(index+1)-U) <= EpsU)
900 // compute index1 and index2 to set the new knots and mults
901 Standard_Integer index1U = 0, index2U = 0;
902 Standard_Integer FromU1 = uknots->Lower();
903 Standard_Integer ToU2 = uknots->Upper();
904 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
905 NewU1,uperiodic,FromU1,ToU2,index1U,U);
906 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
907 NewU1 + deltaU,uperiodic,FromU1,ToU2,index2U,U);
908 if ( Abs(uknots->Value(index2U+1)-U) <= EpsU)
911 Standard_Integer nbuknots = index2U - index1U + 1;
913 Handle(TColStd_HArray1OfReal)
914 nuknots = new TColStd_HArray1OfReal(1,nbuknots);
915 Handle(TColStd_HArray1OfInteger)
916 numults = new TColStd_HArray1OfInteger(1,nbuknots);
918 Standard_Integer i , k = 1;
919 for ( i = index1U; i<= index2U; i++) {
920 nuknots->SetValue(k, uknots->Value(i));
921 numults->SetValue(k, umults->Value(i));
925 numults->SetValue( 1, udeg + 1);
926 numults->SetValue(nbuknots, udeg + 1);
929 if (vperiodic&& segment_in_V) { // set the origine at NewV1
930 Standard_Integer index = 0;
931 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
932 V1,vperiodic,vknots->Lower(),vknots->Upper(),
934 if ( Abs(vknots->Value(index+1)-V) <= EpsV)
940 // compute index1 and index2 to set the new knots and mults
941 Standard_Integer index1V = 0, index2V = 0;
942 Standard_Integer FromV1 = vknots->Lower();
943 Standard_Integer ToV2 = vknots->Upper();
944 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
945 NewV1,vperiodic,FromV1,ToV2,index1V,V);
946 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
947 NewV1 + deltaV,vperiodic,FromV1,ToV2,index2V,V);
948 if ( Abs(vknots->Value(index2V+1)-V) <= EpsV)
951 Standard_Integer nbvknots = index2V - index1V + 1;
953 Handle(TColStd_HArray1OfReal)
954 nvknots = new TColStd_HArray1OfReal(1,nbvknots);
955 Handle(TColStd_HArray1OfInteger)
956 nvmults = new TColStd_HArray1OfInteger(1,nbvknots);
959 for ( i = index1V; i<= index2V; i++) {
960 nvknots->SetValue(k, vknots->Value(i));
961 nvmults->SetValue(k, vmults->Value(i));
965 nvmults->SetValue( 1, vdeg + 1);
966 nvmults->SetValue(nbvknots, vdeg + 1);
969 // compute index1 and index2 to set the new poles and weights
970 Standard_Integer pindex1U
971 = BSplCLib::PoleIndex(udeg,index1U,uperiodic,umults->Array1());
972 Standard_Integer pindex2U
973 = BSplCLib::PoleIndex(udeg,index2U,uperiodic,umults->Array1());
976 pindex2U = Min( pindex2U+1, poles->ColLength());
978 Standard_Integer nbupoles = pindex2U - pindex1U + 1;
980 // compute index1 and index2 to set the new poles and weights
981 Standard_Integer pindex1V
982 = BSplCLib::PoleIndex(vdeg,index1V,vperiodic,vmults->Array1());
983 Standard_Integer pindex2V
984 = BSplCLib::PoleIndex(vdeg,index2V,vperiodic,vmults->Array1());
987 pindex2V = Min( pindex2V+1, poles->RowLength());
989 Standard_Integer nbvpoles = pindex2V - pindex1V + 1;
992 Handle(TColStd_HArray2OfReal) nweights;
994 Handle(TColgp_HArray2OfPnt)
995 npoles = new TColgp_HArray2OfPnt(1,nbupoles,1,nbvpoles);
998 Standard_Integer j, l;
999 if ( urational || vrational) {
1000 nweights = new TColStd_HArray2OfReal( 1,nbupoles,1,nbvpoles);
1001 for ( i = pindex1U; i <= pindex2U; i++) {
1003 for ( j = pindex1V; j <= pindex2V; j++) {
1004 npoles->SetValue(k,l, poles->Value(i,j));
1005 nweights->SetValue(k,l, weights->Value(i,j));
1012 for ( i = pindex1U; i <= pindex2U; i++) {
1014 for ( j = pindex1V; j <= pindex2V; j++) {
1015 npoles->SetValue(k,l, poles->Value(i,j));
1027 if ( urational || vrational)
1030 weights = new TColStd_HArray2OfReal (1,poles->ColLength(),
1031 1,poles->RowLength(), 1.0);
1039 //=======================================================================
1040 //function : SetUKnot
1042 //=======================================================================
1044 void Geom_BSplineSurface::SetUKnot
1045 (const Standard_Integer UIndex,
1046 const Standard_Real K )
1048 if (UIndex < 1 || UIndex > uknots->Length()) Standard_OutOfRange::Raise();
1050 Standard_Integer NewIndex = UIndex;
1051 Standard_Real DU = Abs(Epsilon (K));
1053 if (K >= uknots->Value (2) - DU) Standard_ConstructionError::Raise();
1055 else if (UIndex == uknots->Length()) {
1056 if (K <= uknots->Value (uknots->Length()-1) + DU) {
1057 Standard_ConstructionError::Raise();
1061 if (K <= uknots->Value (NewIndex-1) + DU ||
1062 K >= uknots->Value (NewIndex+1) - DU ) {
1063 Standard_ConstructionError::Raise();
1067 if (K != uknots->Value (NewIndex)) {
1068 uknots->SetValue (NewIndex, K);
1074 //=======================================================================
1075 //function : SetUKnots
1077 //=======================================================================
1079 void Geom_BSplineSurface::SetUKnots (const TColStd_Array1OfReal& UK) {
1081 Standard_Integer Lower = UK.Lower();
1082 Standard_Integer Upper = UK.Upper();
1083 if (Lower < 1 || Lower > uknots->Length() ||
1084 Upper < 1 || Upper > uknots->Length() ) {
1085 Standard_OutOfRange::Raise();
1089 Eps = Abs (Epsilon (uknots->Value (Lower-1)));
1090 if (Abs (UK (Lower) - uknots->Value (Lower-1)) <= gp::Resolution()) {
1091 Standard_ConstructionError::Raise();
1094 if (Upper < uknots->Length ()) {
1095 Eps = Abs (Epsilon (uknots->Value (Upper+1)));
1096 if (Abs (UK (Upper) - uknots->Value (Upper+1)) <= gp::Resolution()) {
1097 Standard_ConstructionError::Raise();
1100 Standard_Real K1 = UK (Lower);
1101 for (Standard_Integer i = Lower; i <= Upper; i++) {
1102 uknots->SetValue (i, UK(i));
1104 Eps = Abs (Epsilon (K1));
1105 if (Abs (UK(i) - K1) <= gp::Resolution()) {
1106 Standard_ConstructionError::Raise();
1116 //=======================================================================
1117 //function : SetUKnot
1119 //=======================================================================
1121 void Geom_BSplineSurface::SetUKnot
1122 (const Standard_Integer UIndex,
1123 const Standard_Real K,
1124 const Standard_Integer M)
1126 IncreaseUMultiplicity (UIndex, M);
1127 SetUKnot (UIndex, K);
1130 //=======================================================================
1131 //function : SetVKnot
1133 //=======================================================================
1135 void Geom_BSplineSurface::SetVKnot
1136 (const Standard_Integer VIndex,
1137 const Standard_Real K)
1139 if (VIndex < 1 || VIndex > vknots->Length()) Standard_OutOfRange::Raise();
1140 Standard_Integer NewIndex = VIndex + vknots->Lower() - 1;
1141 Standard_Real DV = Abs(Epsilon (K));
1143 if (K >= vknots->Value (2) - DV) {
1144 Standard_ConstructionError::Raise();
1147 else if (VIndex == vknots->Length()) {
1148 if (K <= vknots->Value (vknots->Length()-1) + DV) {
1149 Standard_ConstructionError::Raise();
1153 if (K <= vknots->Value (NewIndex-1) + DV ||
1154 K >= vknots->Value (NewIndex+1) - DV ) {
1155 Standard_ConstructionError::Raise();
1163 //=======================================================================
1164 //function : SetVKnots
1166 //=======================================================================
1168 void Geom_BSplineSurface::SetVKnots (const TColStd_Array1OfReal& VK) {
1170 Standard_Integer Lower = VK.Lower();
1171 Standard_Integer Upper = VK.Upper();
1172 if (Lower < 1 || Lower > vknots->Length() ||
1173 Upper < 1 || Upper > vknots->Length() ) {
1174 Standard_OutOfRange::Raise();
1178 Eps = Abs (Epsilon (vknots->Value (Lower-1)));
1179 if (Abs (VK (Lower) - vknots->Value (Lower-1)) <= gp::Resolution()) {
1180 Standard_ConstructionError::Raise();
1183 if (Upper < vknots->Length ()) {
1184 Eps = Abs (Epsilon (vknots->Value (Upper+1)));
1185 if (Abs (VK (Upper) - vknots->Value (Upper+1)) <= gp::Resolution()) {
1186 Standard_ConstructionError::Raise();
1189 Standard_Real K1 = VK (Lower);
1190 for (Standard_Integer i = Lower; i <= Upper; i++) {
1191 vknots->SetValue (i, VK(i));
1193 Eps = Abs (Epsilon (K1));
1194 if (Abs (VK(i) - K1) <= gp::Resolution()) {
1195 Standard_ConstructionError::Raise();
1205 //=======================================================================
1206 //function : SetVKnot
1208 //=======================================================================
1210 void Geom_BSplineSurface::SetVKnot
1211 (const Standard_Integer VIndex,
1212 const Standard_Real K,
1213 const Standard_Integer M)
1215 IncreaseVMultiplicity (VIndex, M);
1216 SetVKnot (VIndex, K);
1219 //=======================================================================
1220 //function : InsertUKnot
1222 //=======================================================================
1224 void Geom_BSplineSurface::InsertUKnot
1225 (const Standard_Real U,
1226 const Standard_Integer M,
1227 const Standard_Real ParametricTolerance,
1228 const Standard_Boolean Add)
1230 TColStd_Array1OfReal k(1,1);
1232 TColStd_Array1OfInteger m(1,1);
1234 InsertUKnots(k,m,ParametricTolerance,Add);
1237 //=======================================================================
1238 //function : InsertVKnot
1240 //=======================================================================
1242 void Geom_BSplineSurface::InsertVKnot
1243 (const Standard_Real V,
1244 const Standard_Integer M,
1245 const Standard_Real ParametricTolerance,
1246 const Standard_Boolean Add)
1248 TColStd_Array1OfReal k(1,1);
1250 TColStd_Array1OfInteger m(1,1);
1252 InsertVKnots(k,m,ParametricTolerance,Add);
1255 //=======================================================================
1256 //function : IncrementUMultiplicity
1258 //=======================================================================
1260 void Geom_BSplineSurface::IncrementUMultiplicity
1261 (const Standard_Integer FromI1,
1262 const Standard_Integer ToI2,
1263 const Standard_Integer Step)
1265 Handle(TColStd_HArray1OfReal) tk = uknots;
1266 TColStd_Array1OfReal k( (uknots->Array1())(FromI1), FromI1, ToI2);
1267 TColStd_Array1OfInteger m( FromI1, ToI2) ;
1269 InsertUKnots( k, m, Epsilon(1.));
1272 //=======================================================================
1273 //function : IncrementVMultiplicity
1275 //=======================================================================
1277 void Geom_BSplineSurface::IncrementVMultiplicity
1278 (const Standard_Integer FromI1,
1279 const Standard_Integer ToI2,
1280 const Standard_Integer Step)
1282 Handle(TColStd_HArray1OfReal) tk = vknots;
1283 TColStd_Array1OfReal k( (vknots->Array1())(FromI1), FromI1, ToI2);
1285 TColStd_Array1OfInteger m( FromI1, ToI2) ;
1288 InsertVKnots( k, m, Epsilon(1.));
1291 //=======================================================================
1292 //function : UpdateUKnots
1294 //=======================================================================
1296 void Geom_BSplineSurface::UpdateUKnots()
1299 Standard_Integer MaxKnotMult = 0;
1303 uknotSet, MaxKnotMult);
1305 if (uknotSet == GeomAbs_Uniform && !uperiodic) {
1309 ufknots = new TColStd_HArray1OfReal
1310 (1, BSplCLib::KnotSequenceLength(umults->Array1(),udeg,uperiodic));
1312 BSplCLib::KnotSequence (uknots->Array1(),
1315 ufknots->ChangeArray1());
1318 if (MaxKnotMult == 0) Usmooth = GeomAbs_CN;
1320 switch (udeg - MaxKnotMult) {
1321 case 0 : Usmooth = GeomAbs_C0; break;
1322 case 1 : Usmooth = GeomAbs_C1; break;
1323 case 2 : Usmooth = GeomAbs_C2; break;
1324 case 3 : Usmooth = GeomAbs_C3; break;
1325 default : Usmooth = GeomAbs_C3; break;
1332 //=======================================================================
1333 //function : UpdateVKnots
1335 //=======================================================================
1337 void Geom_BSplineSurface::UpdateVKnots()
1339 Standard_Integer MaxKnotMult = 0;
1343 vknotSet, MaxKnotMult);
1345 if (vknotSet == GeomAbs_Uniform && !vperiodic) {
1349 vfknots = new TColStd_HArray1OfReal
1350 (1, BSplCLib::KnotSequenceLength(vmults->Array1(),vdeg,vperiodic));
1352 BSplCLib::KnotSequence (vknots->Array1(),
1355 vfknots->ChangeArray1());
1358 if (MaxKnotMult == 0) Vsmooth = GeomAbs_CN;
1360 switch (vdeg - MaxKnotMult) {
1361 case 0 : Vsmooth = GeomAbs_C0; break;
1362 case 1 : Vsmooth = GeomAbs_C1; break;
1363 case 2 : Vsmooth = GeomAbs_C2; break;
1364 case 3 : Vsmooth = GeomAbs_C3; break;
1365 default : Vsmooth = GeomAbs_C3; break;
1371 //=======================================================================
1372 //function : InvalidateCache
1373 //purpose : Invalidates the Cache of the surface
1374 //=======================================================================
1376 void Geom_BSplineSurface::InvalidateCache()
1381 //=======================================================================
1382 //function : Normalizes the parameters if the curve is periodic
1383 //purpose : that is compute the cache so that it is valid
1384 //=======================================================================
1386 void Geom_BSplineSurface::PeriodicNormalization
1387 (Standard_Real& Uparameter,
1388 Standard_Real& Vparameter) const
1390 Standard_Real Period, aMaxVal, aMinVal;
1393 aMaxVal = ufknots->Value(ufknots->Upper() - udeg);
1394 aMinVal = ufknots->Value (udeg + 1);
1395 Standard_Real eps = Abs(Epsilon(Uparameter));
1396 Period = aMaxVal - aMinVal;
1399 Standard_OutOfRange::Raise("Geom_BSplineSurface::PeriodicNormalization: Uparameter is too great number");
1401 while (Uparameter > aMaxVal) {
1402 Uparameter -= Period ;
1405 while (Uparameter < aMinVal) {
1406 Uparameter += Period ;
1410 aMaxVal = vfknots->Value(vfknots->Upper() - vdeg);
1411 aMinVal = vfknots->Value (vdeg + 1);
1412 Standard_Real eps = Abs(Epsilon(Vparameter));
1413 Period = aMaxVal - aMinVal;
1416 Standard_OutOfRange::Raise("Geom_BSplineSurface::PeriodicNormalization: Vparameter is too great number");
1418 while (Vparameter > aMaxVal) {
1419 Vparameter -= Period ;
1421 while (Vparameter < aMinVal) {
1422 Vparameter += Period ;
1427 //=======================================================================
1428 //function : ValidateCache
1429 //purpose : function that validates the cache of the surface
1430 //=======================================================================
1432 void Geom_BSplineSurface::ValidateCache(const Standard_Real Uparameter,
1433 const Standard_Real Vparameter)
1435 Standard_Real NewParameter ;
1436 Standard_Integer LocalIndex = 0 ;
1437 Standard_Integer MinDegree,
1440 // check if the degree did not change
1443 MinDegree = Min(udeg,vdeg) ;
1444 MaxDegree = Max(udeg,vdeg) ;
1445 if (cachepoles->ColLength() < MaxDegree + 1 ||
1446 cachepoles->RowLength() < MinDegree + 1) {
1447 cachepoles = new TColgp_HArray2OfPnt(1,MaxDegree + 1,
1451 // Verif + poussee pour les poids
1453 if (urational || vrational) {
1454 if (cacheweights.IsNull()) {
1455 cacheweights = new TColStd_HArray2OfReal(1,MaxDegree + 1,
1459 if (cacheweights->ColLength() < MaxDegree + 1 ||
1460 cacheweights->RowLength() < MinDegree + 1) {
1461 cacheweights = new TColStd_HArray2OfReal(1,MaxDegree + 1,
1467 BSplCLib::LocateParameter(udeg,
1468 (ufknots->Array1()),
1469 (BSplCLib::NoMults()),
1474 ucachespanindex = LocalIndex ;
1475 if (Uparameter == ufknots->Value(LocalIndex + 1)) {
1478 ucacheparameter = ufknots->Value(LocalIndex) ;
1479 if (LocalIndex == ufknots->Upper() - udeg) {
1481 // for the last span if the parameter is outside of
1482 // the domain of the curve than use the last knot
1483 // and normalize with the last span Still set the
1484 // cachespanindex to flatknots->Upper() - deg so that
1485 // the IsCacheValid will know for sure we are extending
1489 ucachespanlenght = ufknots->Value(LocalIndex - 1) - ucacheparameter ;
1492 ucachespanlenght = ufknots->Value(LocalIndex + 1) - ucacheparameter ;
1496 ucacheparameter = ufknots->Value(LocalIndex) ;
1497 ucachespanlenght = ufknots->Value(LocalIndex + 1) - ucacheparameter ;
1501 BSplCLib::LocateParameter(vdeg,
1502 (vfknots->Array1()),
1503 (BSplCLib::NoMults()),
1508 vcachespanindex = LocalIndex ;
1509 if (Vparameter == vfknots->Value(LocalIndex + 1)) {
1511 vcacheparameter = vfknots->Value(LocalIndex) ;
1512 if (LocalIndex == vfknots->Upper() - vdeg) {
1514 // for the last span if the parameter is outside of
1515 // the domain of the curve than use the last knot
1516 // and normalize with the last span Still set the
1517 // cachespanindex to flatknots->Upper() - deg so that
1518 // the IsCacheValid will know for sure we are extending
1522 vcachespanlenght = vfknots->Value(LocalIndex - 1) - vcacheparameter ;
1525 vcachespanlenght = vfknots->Value(LocalIndex + 1) - vcacheparameter ;
1529 vcacheparameter = vfknots->Value(LocalIndex) ;
1530 vcachespanlenght = vfknots->Value(LocalIndex + 1) - vcacheparameter ;
1533 Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
1534 uspanlenght_11 = ucachespanlenght/2,
1535 vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
1536 vspanlenght_11 = vcachespanlenght/2 ;
1537 if (urational || vrational) {
1538 BSplSLib::BuildCache(uparameter_11,
1548 (ufknots->Array1()),
1549 (vfknots->Array1()),
1552 cachepoles->ChangeArray2(),
1553 cacheweights->ChangeArray2()) ;
1556 BSplSLib::BuildCache(uparameter_11,
1566 (ufknots->Array1()),
1567 (vfknots->Array1()),
1569 *((TColStd_Array2OfReal*) NULL),
1570 cachepoles->ChangeArray2(),
1571 *((TColStd_Array2OfReal*) NULL)) ;
1576 //=======================================================================
1577 //function : IsCacheValid
1578 //purpose : function that checks for the validity of the cache of the
1580 //=======================================================================
1581 Standard_Boolean Geom_BSplineSurface::IsCacheValid
1582 (const Standard_Real U,
1583 const Standard_Real V) const
1585 //Roman Lygin 26.12.08, see comments in Geom_BSplineCurve::IsCacheValid()
1586 Standard_Real aDeltaU = U - ucacheparameter;
1587 Standard_Real aDeltaV = V - vcacheparameter;
1589 return ( validcache &&
1590 (aDeltaU >= 0.0e0) &&
1591 ((aDeltaU < ucachespanlenght) || (ucachespanindex == ufknots->Upper() - udeg)) &&
1592 (aDeltaV >= 0.0e0) &&
1593 ((aDeltaV < vcachespanlenght) || (vcachespanindex == vfknots->Upper() - vdeg)) );
1596 //=======================================================================
1597 //function : SetWeight
1599 //=======================================================================
1601 void Geom_BSplineSurface::SetWeight (const Standard_Integer UIndex,
1602 const Standard_Integer VIndex,
1603 const Standard_Real Weight)
1605 if (Weight <= gp::Resolution()) Standard_ConstructionError::Raise();
1606 TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1607 if (UIndex < 1 || UIndex > Weights.ColLength() ||
1608 VIndex < 1 || VIndex > Weights.RowLength() ) {
1609 Standard_OutOfRange::Raise();
1611 Weights (UIndex+Weights.LowerRow()-1, VIndex+Weights.LowerCol()-1) = Weight;
1612 Rational(Weights, urational, vrational);
1616 //=======================================================================
1617 //function : SetWeightCol
1619 //=======================================================================
1621 void Geom_BSplineSurface::SetWeightCol
1622 (const Standard_Integer VIndex,
1623 const TColStd_Array1OfReal& CPoleWeights)
1625 TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1626 if (VIndex < 1 || VIndex > Weights.RowLength()) {
1627 Standard_OutOfRange::Raise();
1629 if (CPoleWeights.Lower() < 1 ||
1630 CPoleWeights.Lower() > Weights.ColLength() ||
1631 CPoleWeights.Upper() < 1 ||
1632 CPoleWeights.Upper() > Weights.ColLength() ) {
1633 Standard_ConstructionError::Raise();
1635 Standard_Integer I = CPoleWeights.Lower();
1636 while (I <= CPoleWeights.Upper()) {
1637 if (CPoleWeights(I) <= gp::Resolution()) {
1638 Standard_ConstructionError::Raise();
1640 Weights (I+Weights.LowerRow()-1, VIndex+Weights.LowerCol()-1) =
1644 // Verifie si c'est rationnel
1645 Rational(Weights, urational, vrational);
1650 //=======================================================================
1651 //function : SetWeightRow
1653 //=======================================================================
1655 void Geom_BSplineSurface::SetWeightRow
1656 (const Standard_Integer UIndex,
1657 const TColStd_Array1OfReal& CPoleWeights)
1659 TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1660 if (UIndex < 1 || UIndex > Weights.ColLength()) {
1661 Standard_OutOfRange::Raise();
1663 if (CPoleWeights.Lower() < 1 ||
1664 CPoleWeights.Lower() > Weights.RowLength() ||
1665 CPoleWeights.Upper() < 1 ||
1666 CPoleWeights.Upper() > Weights.RowLength() ) {
1668 Standard_ConstructionError::Raise();
1670 Standard_Integer I = CPoleWeights.Lower();
1672 while (I <= CPoleWeights.Upper()) {
1673 if (CPoleWeights(I)<=gp::Resolution()) {
1674 Standard_ConstructionError::Raise();
1676 Weights (UIndex+Weights.LowerRow()-1, I+Weights.LowerCol()-1) =
1680 // Verifie si c'est rationnel
1681 Rational(Weights, urational, vrational);