0026042: OCCT won't work with the latest Xcode
[occt.git] / src / Geom / Geom_BSplineSurface.cxx
CommitLineData
b311480e 1// Created on: 1993-03-09
2// Created by: JCV
3// Copyright (c) 1993-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
7fd59977 17// 14-Mar-96 : xab portage hp
18// pmn : 28-Jun-96 Distinction entre la continuite en U et V (bug PRO4625)
19// pmn : 07-Jan-97 Centralisation des verif rational (PRO6834)
20// et ajout des InvalideCache() dans les SetWeight*(PRO6833)
21// RBD : 15-10-98 ; Le cache est maintenant calcule sur [-1,1] (pro15537).
22// jct : 19-01-99 ; permutation de urational et vrational dans Rational.
7fd59977 23#define No_Standard_OutOfRange
24
7fd59977 25
7fd59977 26#include <BSplCLib.hxx>
27#include <BSplSLib.hxx>
42cf5bc1 28#include <Geom_BSplineSurface.hxx>
29#include <Geom_Curve.hxx>
30#include <Geom_Geometry.hxx>
31#include <Geom_UndefinedDerivative.hxx>
32#include <gp.hxx>
33#include <gp_Pnt.hxx>
34#include <gp_Trsf.hxx>
35#include <gp_Vec.hxx>
36#include <Precision.hxx>
7fd59977 37#include <Standard_ConstructionError.hxx>
42cf5bc1 38#include <Standard_DimensionError.hxx>
39#include <Standard_DomainError.hxx>
40#include <Standard_NoSuchObject.hxx>
7fd59977 41#include <Standard_NotImplemented.hxx>
42#include <Standard_OutOfRange.hxx>
42cf5bc1 43#include <Standard_RangeError.hxx>
44#include <Standard_Type.hxx>
7fd59977 45
46//=======================================================================
47//function : CheckSurfaceData
48//purpose : Internal use only.
49//=======================================================================
7fd59977 50static void CheckSurfaceData
51(const TColgp_Array2OfPnt& SPoles,
52 const TColStd_Array1OfReal& SUKnots,
53 const TColStd_Array1OfReal& SVKnots,
54 const TColStd_Array1OfInteger& SUMults,
55 const TColStd_Array1OfInteger& SVMults,
56 const Standard_Integer UDegree,
57 const Standard_Integer VDegree,
58 const Standard_Boolean UPeriodic,
59 const Standard_Boolean VPeriodic)
60{
61 if (UDegree < 1 || UDegree > Geom_BSplineSurface::MaxDegree () ||
62 VDegree < 1 || VDegree > Geom_BSplineSurface::MaxDegree ()) {
63 Standard_ConstructionError::Raise("Geom_BSplineSurface");
64 }
65 if (SPoles.ColLength () < 2 || SPoles.RowLength () < 2) {
66 Standard_ConstructionError::Raise("Geom_BSplineSurface");
67 }
68
69 if (SUKnots.Length() != SUMults.Length() ||
70 SVKnots.Length() != SVMults.Length()) {
71 Standard_ConstructionError::Raise("Geom_BSplineSurface");
72 }
73
74 Standard_Integer i;
75 for (i = SUKnots.Lower(); i < SUKnots.Upper(); i++) {
76 if (SUKnots(i+1) - SUKnots(i) <= Epsilon(Abs(SUKnots(i)))) {
77 Standard_ConstructionError::Raise("Geom_BSplineSurface");
78 }
79 }
80
81 for (i = SVKnots.Lower(); i < SVKnots.Upper(); i++) {
82 if (SVKnots(i+1) - SVKnots(i) <= Epsilon(Abs(SVKnots(i)))) {
83 Standard_ConstructionError::Raise("Geom_BSplineSurface");
84 }
85 }
86
87 if (SPoles.ColLength() != BSplCLib::NbPoles(UDegree,UPeriodic,SUMults))
88 Standard_ConstructionError::Raise("Geom_BSplineSurface");
89
90 if (SPoles.RowLength() != BSplCLib::NbPoles(VDegree,VPeriodic,SVMults))
91 Standard_ConstructionError::Raise("Geom_BSplineSurface");
92}
93
94//=======================================================================
7fd59977 95//function : Rational
96//purpose : Internal use only.
97//=======================================================================
98
99static void Rational(const TColStd_Array2OfReal& Weights,
100 Standard_Boolean& Urational,
101 Standard_Boolean& Vrational)
102{
103 Standard_Integer I,J;
104 J = Weights.LowerCol ();
105 Vrational = Standard_False;
106 while (!Vrational && J <= Weights.UpperCol()) {
107 I = Weights.LowerRow();
108 while (!Vrational && I <= Weights.UpperRow() - 1) {
109 Vrational = (Abs(Weights (I, J) - Weights (I+1, J))
110 > Epsilon (Abs(Weights (I, J))));
111 I++;
112 }
113 J++;
114 }
115
116 I = Weights.LowerRow ();
117 Urational = Standard_False;
118 while (!Urational && I <= Weights.UpperRow()) {
119 J = Weights.LowerCol();
120 while (!Urational && J <= Weights.UpperCol() - 1) {
121 Urational = (Abs(Weights (I, J) - Weights (I, J+1))
122 > Epsilon (Abs(Weights (I, J))));
123 J++;
124 }
125 I++;
126 }
127}
128
129//=======================================================================
130//function : Copy
131//purpose :
132//=======================================================================
133
134Handle(Geom_Geometry) Geom_BSplineSurface::Copy () const
135{
136 Handle(Geom_BSplineSurface) S;
137 if (urational || vrational)
138 S = new Geom_BSplineSurface (poles->Array2() , weights->Array2(),
139 uknots->Array1(), vknots->Array1(),
140 umults->Array1(), vmults->Array1(),
141 udeg , vdeg,
142 uperiodic, vperiodic);
143 else
144 S = new Geom_BSplineSurface (poles->Array2(),
145 uknots->Array1(), vknots->Array1(),
146 umults->Array1(), vmults->Array1(),
147 udeg , vdeg,
148 uperiodic, vperiodic);
149 return S;
150}
151
152//=======================================================================
153//function : Geom_BSplineSurface
154//purpose :
155//=======================================================================
156
157Geom_BSplineSurface::Geom_BSplineSurface
158(const TColgp_Array2OfPnt& Poles,
159 const TColStd_Array1OfReal& UKnots,
160 const TColStd_Array1OfReal& VKnots,
161 const TColStd_Array1OfInteger& UMults,
162 const TColStd_Array1OfInteger& VMults,
163 const Standard_Integer UDegree,
164 const Standard_Integer VDegree,
165 const Standard_Boolean UPeriodic,
166 const Standard_Boolean VPeriodic
167 ) :
168 urational(Standard_False),
169 vrational(Standard_False),
170 uperiodic(UPeriodic),
171 vperiodic(VPeriodic),
172 udeg(UDegree),
173 vdeg(VDegree),
174 maxderivinvok(0)
175
176{
7fd59977 177
178 // check
179
180 CheckSurfaceData(Poles,
181 UKnots , VKnots,
182 UMults , VMults,
183 UDegree , VDegree,
184 UPeriodic, VPeriodic);
185
186 // copy arrays
187
188 poles = new TColgp_HArray2OfPnt(1,Poles.ColLength(),
189 1,Poles.RowLength());
190 poles->ChangeArray2() = Poles;
191
192 weights = new TColStd_HArray2OfReal (1,Poles.ColLength(),
193 1,Poles.RowLength(), 1.0);
194
195 uknots = new TColStd_HArray1OfReal (1,UKnots.Length());
196 uknots->ChangeArray1() = UKnots;
197
198 umults = new TColStd_HArray1OfInteger (1,UMults.Length());
199 umults->ChangeArray1() = UMults;
200
201 vknots = new TColStd_HArray1OfReal (1,VKnots.Length());
202 vknots->ChangeArray1() = VKnots;
203
204 vmults = new TColStd_HArray1OfInteger (1,VMults.Length());
205 vmults->ChangeArray1() = VMults;
7fd59977 206
207 UpdateUKnots();
208 UpdateVKnots();
209}
210
211//=======================================================================
212//function : Geom_BSplineSurface
213//purpose :
214//=======================================================================
215
216Geom_BSplineSurface::Geom_BSplineSurface
217(const TColgp_Array2OfPnt& Poles,
218 const TColStd_Array2OfReal& Weights,
219 const TColStd_Array1OfReal& UKnots,
220 const TColStd_Array1OfReal& VKnots,
221 const TColStd_Array1OfInteger& UMults,
222 const TColStd_Array1OfInteger& VMults,
223 const Standard_Integer UDegree,
224 const Standard_Integer VDegree,
225 const Standard_Boolean UPeriodic,
226 const Standard_Boolean VPeriodic) :
227 urational(Standard_False),
228 vrational(Standard_False),
229 uperiodic(UPeriodic),
230 vperiodic(VPeriodic),
231 udeg(UDegree),
232 vdeg(VDegree),
233 maxderivinvok(0)
234{
7fd59977 235 // check weights
236
237 if (Weights.ColLength() != Poles.ColLength())
238 Standard_ConstructionError::Raise("Geom_BSplineSurface");
239
240 if (Weights.RowLength() != Poles.RowLength())
241 Standard_ConstructionError::Raise("Geom_BSplineSurface");
242
243 Standard_Integer i,j;
244 for (i = Weights.LowerRow(); i <= Weights.UpperRow(); i++) {
245 for (j = Weights.LowerCol(); j <= Weights.UpperCol(); j++) {
246 if (Weights(i,j) <= gp::Resolution())
247 Standard_ConstructionError::Raise("Geom_BSplineSurface");
248 }
249 }
250
251 // check really rational
252
253 Rational(Weights, urational, vrational);
254
255 // check
256
257 CheckSurfaceData(Poles,
258 UKnots , VKnots,
259 UMults , VMults,
260 UDegree , VDegree,
261 UPeriodic, VPeriodic);
262
263 // copy arrays
264
265 poles = new TColgp_HArray2OfPnt(1,Poles.ColLength(),
266 1,Poles.RowLength());
267 poles->ChangeArray2() = Poles;
268
269 weights = new TColStd_HArray2OfReal (1,Poles.ColLength(),
270 1,Poles.RowLength());
271 weights->ChangeArray2() = Weights;
272
273 uknots = new TColStd_HArray1OfReal (1,UKnots.Length());
274 uknots->ChangeArray1() = UKnots;
275
276 umults = new TColStd_HArray1OfInteger (1,UMults.Length());
277 umults->ChangeArray1() = UMults;
278
279 vknots = new TColStd_HArray1OfReal (1,VKnots.Length());
280 vknots->ChangeArray1() = VKnots;
281
282 vmults = new TColStd_HArray1OfInteger (1,VMults.Length());
283 vmults->ChangeArray1() = VMults;
7fd59977 284
285 UpdateUKnots();
286 UpdateVKnots();
287}
288
289//=======================================================================
290//function : ExchangeUV
291//purpose :
292//=======================================================================
293
294void Geom_BSplineSurface::ExchangeUV ()
295{
296 Standard_Integer LC = poles->LowerCol();
297 Standard_Integer UC = poles->UpperCol();
298 Standard_Integer LR = poles->LowerRow();
299 Standard_Integer UR = poles->UpperRow();
300
301 Handle(TColgp_HArray2OfPnt) npoles =
302 new TColgp_HArray2OfPnt (LC, UC, LR, UR);
303 Handle(TColStd_HArray2OfReal) nweights =
304 new TColStd_HArray2OfReal (LC, UC, LR, UR);
305
306 const TColgp_Array2OfPnt & spoles = poles->Array2();
307 const TColStd_Array2OfReal & sweights = weights->Array2();
308
309 TColgp_Array2OfPnt& snpoles = npoles->ChangeArray2();
310 TColStd_Array2OfReal& snweights = nweights->ChangeArray2();
311
312 Standard_Integer i, j;
313 for (i = LC; i <= UC; i++) {
314 for (j = LR; j <= UR; j++) {
315 snpoles (i,j) = spoles (j,i);
316 snweights (i,j) = sweights (j,i);
317 }
318 }
319
320 poles = npoles;
321 weights = nweights;
322
323 Standard_Boolean temp = urational;
324 urational = vrational;
325 vrational = temp;
326
327 temp = uperiodic;
328 uperiodic = vperiodic;
329 vperiodic = temp;
330
331 Standard_Integer tempdeg = udeg;
332 udeg = vdeg;
333 vdeg = tempdeg;
334
335
336 Handle(TColStd_HArray1OfReal) tempknots = uknots;
337 uknots = vknots;
338 vknots = tempknots;
339
340 Handle(TColStd_HArray1OfInteger) tempmults = umults;
341 umults = vmults;
342 vmults = tempmults;
343
344 UpdateUKnots();
345 UpdateVKnots();
346}
347
348//=======================================================================
349//function : IncreaseDegree
350//purpose :
351//=======================================================================
352
353void Geom_BSplineSurface::IncreaseDegree (const Standard_Integer UDegree,
354 const Standard_Integer VDegree)
355{
356 if (UDegree != udeg) {
357 if ( UDegree < udeg || UDegree > Geom_BSplineSurface::MaxDegree())
358 Standard_ConstructionError::Raise();
359
360 Standard_Integer FromK1 = FirstUKnotIndex();
361 Standard_Integer ToK2 = LastUKnotIndex();
362
363 Standard_Integer Step = UDegree - udeg;
364
365 Handle(TColgp_HArray2OfPnt) npoles = new
366 TColgp_HArray2OfPnt( 1, poles->ColLength() + Step * (ToK2 - FromK1),
367 1, poles->RowLength());
368
369 Standard_Integer nbknots = BSplCLib::IncreaseDegreeCountKnots
370 (udeg,UDegree,uperiodic,umults->Array1());
371
372 Handle(TColStd_HArray1OfReal) nknots =
373 new TColStd_HArray1OfReal(1,nbknots);
374
375 Handle(TColStd_HArray1OfInteger) nmults =
376 new TColStd_HArray1OfInteger(1,nbknots);
377
378 Handle(TColStd_HArray2OfReal) nweights
379 = new TColStd_HArray2OfReal(1,npoles->ColLength(),
380 1,npoles->RowLength(), 1.);
381
382 if (urational || vrational) {
383
384 BSplSLib::IncreaseDegree
385 (Standard_True, udeg, UDegree, uperiodic,
0e14656b 386 poles->Array2(),&weights->Array2(),
7fd59977 387 uknots->Array1(),umults->Array1(),
0e14656b 388 npoles->ChangeArray2(),&nweights->ChangeArray2(),
7fd59977 389 nknots->ChangeArray1(),nmults->ChangeArray1());
390 }
391 else {
392
393 BSplSLib::IncreaseDegree
394 (Standard_True, udeg, UDegree, uperiodic,
395 poles->Array2(),BSplSLib::NoWeights(),
396 uknots->Array1(),umults->Array1(),
0e14656b 397 npoles->ChangeArray2(),BSplSLib::NoWeights(),
7fd59977 398 nknots->ChangeArray1(),nmults->ChangeArray1());
399 }
400 udeg = UDegree;
401 poles = npoles;
402 weights = nweights;
403 uknots = nknots;
404 umults = nmults;
405 UpdateUKnots();
406 }
407
408 if (VDegree != vdeg) {
409 if ( VDegree < vdeg || VDegree > Geom_BSplineSurface::MaxDegree())
410 Standard_ConstructionError::Raise();
411
412 Standard_Integer FromK1 = FirstVKnotIndex();
413 Standard_Integer ToK2 = LastVKnotIndex();
414
415 Standard_Integer Step = VDegree - vdeg;
416
417 Handle(TColgp_HArray2OfPnt) npoles = new
418 TColgp_HArray2OfPnt( 1, poles->ColLength(),
419 1, poles->RowLength() + Step * (ToK2 - FromK1));
420
421 Standard_Integer nbknots = BSplCLib::IncreaseDegreeCountKnots
422 (vdeg,VDegree,vperiodic,vmults->Array1());
423
424 Handle(TColStd_HArray1OfReal) nknots =
425 new TColStd_HArray1OfReal(1,nbknots);
426
427 Handle(TColStd_HArray1OfInteger) nmults =
428 new TColStd_HArray1OfInteger(1,nbknots);
429
430 Handle(TColStd_HArray2OfReal) nweights
431 = new TColStd_HArray2OfReal(1,npoles->ColLength(),
432 1,npoles->RowLength(), 1.);
433
434 if (urational || vrational) {
435
436 BSplSLib::IncreaseDegree
437 (Standard_False, vdeg, VDegree, vperiodic,
0e14656b 438 poles->Array2(),&weights->Array2(),
7fd59977 439 vknots->Array1(),vmults->Array1(),
0e14656b 440 npoles->ChangeArray2(),&nweights->ChangeArray2(),
7fd59977 441 nknots->ChangeArray1(),nmults->ChangeArray1());
442 }
443 else {
444
445 BSplSLib::IncreaseDegree
446 (Standard_False, vdeg, VDegree, vperiodic,
447 poles->Array2(),BSplSLib::NoWeights(),
448 vknots->Array1(),vmults->Array1(),
0e14656b 449 npoles->ChangeArray2(),BSplSLib::NoWeights(),
7fd59977 450 nknots->ChangeArray1(),nmults->ChangeArray1());
451 }
452 vdeg = VDegree;
453 poles = npoles;
454 weights = nweights;
455 vknots = nknots;
456 vmults = nmults;
457 UpdateVKnots();
458 }
459}
460
461//=======================================================================
462//function : IncreaseUMultiplicity
463//purpose :
464//=======================================================================
465
466void Geom_BSplineSurface::IncreaseUMultiplicity
467(const Standard_Integer UIndex,
468 const Standard_Integer M)
469{
470 TColStd_Array1OfReal k(1,1);
471 k(1) = uknots->Value(UIndex);
472 TColStd_Array1OfInteger m(1,1);
473 m(1) = M - umults->Value(UIndex);
474 InsertUKnots(k,m,Epsilon(1.),Standard_True);
475}
476
477//=======================================================================
478//function : IncreaseUMultiplicity
479//purpose :
480//=======================================================================
481
482void Geom_BSplineSurface::IncreaseUMultiplicity
483(const Standard_Integer FromI1,
484 const Standard_Integer ToI2,
485 const Standard_Integer M)
486{
487 Handle(TColStd_HArray1OfReal) tk = uknots;
488 TColStd_Array1OfReal k((uknots->Array1())(FromI1),FromI1,ToI2);
489 TColStd_Array1OfInteger m(FromI1, ToI2);
490 for (Standard_Integer i = FromI1; i <= ToI2; i++)
491 m(i) = M - umults->Value(i);
492 InsertUKnots(k,m,Epsilon(1.),Standard_True);
493}
494
495//=======================================================================
496//function : IncreaseVMultiplicity
497//purpose :
498//=======================================================================
499
500void Geom_BSplineSurface::IncreaseVMultiplicity
501(const Standard_Integer VIndex,
502 const Standard_Integer M)
503{
504 TColStd_Array1OfReal k(1,1);
505 k(1) = vknots->Value(VIndex);
506 TColStd_Array1OfInteger m(1,1);
507 m(1) = M - vmults->Value(VIndex);
508 InsertVKnots(k,m,Epsilon(1.),Standard_True);
509}
510
511//=======================================================================
512//function : IncreaseVMultiplicity
513//purpose :
514//=======================================================================
515
516void Geom_BSplineSurface::IncreaseVMultiplicity
517(const Standard_Integer FromI1,
518 const Standard_Integer ToI2,
519 const Standard_Integer M)
520{
521 Handle(TColStd_HArray1OfReal) tk = vknots;
522 TColStd_Array1OfReal k((vknots->Array1())(FromI1),FromI1,ToI2);
523 TColStd_Array1OfInteger m(FromI1,ToI2);
524 for (Standard_Integer i = FromI1; i <= ToI2; i++)
525 m(i) = M - vmults->Value(i);
526 InsertVKnots(k,m,Epsilon(1.),Standard_True);
527}
528
529//=======================================================================
530//function : Segment
531//purpose :
532//=======================================================================
533
534void Geom_BSplineSurface::Segment(const Standard_Real U1,
535 const Standard_Real U2,
536 const Standard_Real V1,
537 const Standard_Real V2)
538{
539
540 Standard_DomainError_Raise_if ( (U2 < U1) || (V2 < V1),
541 "Geom_BSplineCurve::Segment");
542 Standard_Real deltaU = Max(Abs(U2),Abs(U1));
543 Standard_Real EpsU = Epsilon(deltaU);
544 deltaU = U2 - U1;
545
546 Standard_Real deltaV = Max(Abs(V2),Abs(V1));
547 Standard_Real EpsV = Epsilon(deltaV);
548 deltaV = V2 - V1;
549
550 Standard_Real NewU1, NewU2, NewV1, NewV2;
551 Standard_Real U,V;
552 Standard_Integer indexU, indexV;
553
554 // inserting the UKnots
555 TColStd_Array1OfReal UKnots(1,2);
556 TColStd_Array1OfInteger UMults(1,2);
557
558 indexU = 0;
559 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
560 U1,uperiodic,uknots->Lower(),uknots->Upper(),
561 indexU,NewU1);
562 indexU = 0;
563 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
564 U2,uperiodic,uknots->Lower(),uknots->Upper(),
565 indexU,NewU2);
566 UKnots( 1) = Min( NewU1, NewU2);
567 UKnots( 2) = Max( NewU1, NewU2);
568 UMults( 1) = UMults( 2) = udeg;
569 InsertUKnots( UKnots, UMults, EpsU);
570
571 // Inserting the VKnots
572 TColStd_Array1OfReal VKnots(1,2);
573 TColStd_Array1OfInteger VMults(1,2);
574
575 indexV = 0;
576 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
577 V1,vperiodic,vknots->Lower(),vknots->Upper(),
578 indexV,NewV1);
579 indexV = 0;
580 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
581 V2,vperiodic,vknots->Lower(),vknots->Upper(),
582 indexV,NewV2);
583 VKnots( 1) = Min( NewV1, NewV2);
584 VKnots( 2) = Max( NewV1, NewV2);
585 VMults( 1) = VMults( 2) = vdeg;
586 InsertVKnots( VKnots, VMults, EpsV);
587
588
589 if (uperiodic) { // set the origine at NewU1
590 Standard_Integer index = 0;
591 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
592 U1,uperiodic,uknots->Lower(),uknots->Upper(),
593 index,U);
594 if ( Abs(uknots->Value(index+1)-U) <= EpsU)
595 index++;
596 SetUOrigin(index);
597 SetUNotPeriodic();
598 }
599
600 // compute index1 and index2 to set the new knots and mults
601 Standard_Integer index1U = 0, index2U = 0;
602 Standard_Integer FromU1 = uknots->Lower();
603 Standard_Integer ToU2 = uknots->Upper();
604 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
605 NewU1,uperiodic,FromU1,ToU2,index1U,U);
606 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
607 NewU1 + deltaU,uperiodic,FromU1,ToU2,index2U,U);
608 if ( Abs(uknots->Value(index2U+1)-U) <= EpsU)
609 index2U++;
610
611 Standard_Integer nbuknots = index2U - index1U + 1;
612
613 Handle(TColStd_HArray1OfReal)
614 nuknots = new TColStd_HArray1OfReal(1,nbuknots);
615 Handle(TColStd_HArray1OfInteger)
616 numults = new TColStd_HArray1OfInteger(1,nbuknots);
617
618 Standard_Integer i , k = 1;
619 for ( i = index1U; i<= index2U; i++) {
620 nuknots->SetValue(k, uknots->Value(i));
621 numults->SetValue(k, umults->Value(i));
622 k++;
623 }
624 numults->SetValue( 1, udeg + 1);
625 numults->SetValue(nbuknots, udeg + 1);
626
627
628 if (vperiodic) { // set the origine at NewV1
629 Standard_Integer index = 0;
630 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
631 V1,vperiodic,vknots->Lower(),vknots->Upper(),
632 index,V);
633 if ( Abs(vknots->Value(index+1)-V) <= EpsV)
634 index++;
635 SetVOrigin(index);
636 SetVNotPeriodic();
637 }
638
639 // compute index1 and index2 to set the new knots and mults
640 Standard_Integer index1V = 0, index2V = 0;
641 Standard_Integer FromV1 = vknots->Lower();
642 Standard_Integer ToV2 = vknots->Upper();
643 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
644 NewV1,vperiodic,FromV1,ToV2,index1V,V);
645 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
646 NewV1 + deltaV,vperiodic,FromV1,ToV2,index2V,V);
647 if ( Abs(vknots->Value(index2V+1)-V) <= EpsV)
648 index2V++;
649
650 Standard_Integer nbvknots = index2V - index1V + 1;
651
652 Handle(TColStd_HArray1OfReal)
653 nvknots = new TColStd_HArray1OfReal(1,nbvknots);
654 Handle(TColStd_HArray1OfInteger)
655 nvmults = new TColStd_HArray1OfInteger(1,nbvknots);
656
657 k = 1;
658 for ( i = index1V; i<= index2V; i++) {
659 nvknots->SetValue(k, vknots->Value(i));
660 nvmults->SetValue(k, vmults->Value(i));
661 k++;
662 }
663 nvmults->SetValue( 1, vdeg + 1);
664 nvmults->SetValue(nbvknots, vdeg + 1);
665
666
667 // compute index1 and index2 to set the new poles and weights
668 Standard_Integer pindex1U
669 = BSplCLib::PoleIndex(udeg,index1U,uperiodic,umults->Array1());
670 Standard_Integer pindex2U
671 = BSplCLib::PoleIndex(udeg,index2U,uperiodic,umults->Array1());
672
673 pindex1U++;
674 pindex2U = Min( pindex2U+1, poles->ColLength());
675
676 Standard_Integer nbupoles = pindex2U - pindex1U + 1;
677
678 // compute index1 and index2 to set the new poles and weights
679 Standard_Integer pindex1V
680 = BSplCLib::PoleIndex(vdeg,index1V,vperiodic,vmults->Array1());
681 Standard_Integer pindex2V
682 = BSplCLib::PoleIndex(vdeg,index2V,vperiodic,vmults->Array1());
683
684 pindex1V++;
685 pindex2V = Min( pindex2V+1, poles->RowLength());
686
687 Standard_Integer nbvpoles = pindex2V - pindex1V + 1;
688
689
690 Handle(TColStd_HArray2OfReal) nweights;
691
692 Handle(TColgp_HArray2OfPnt)
693 npoles = new TColgp_HArray2OfPnt(1,nbupoles,1,nbvpoles);
694
695 k = 1;
696 Standard_Integer j, l;
697 if ( urational || vrational) {
698 nweights = new TColStd_HArray2OfReal( 1,nbupoles,1,nbvpoles);
699 for ( i = pindex1U; i <= pindex2U; i++) {
700 l = 1;
701 for ( j = pindex1V; j <= pindex2V; j++) {
702 npoles->SetValue(k,l, poles->Value(i,j));
703 nweights->SetValue(k,l, weights->Value(i,j));
704 l++;
705 }
706 k++;
707 }
708 }
709 else {
710 for ( i = pindex1U; i <= pindex2U; i++) {
711 l = 1;
712 for ( j = pindex1V; j <= pindex2V; j++) {
713 npoles->SetValue(k,l, poles->Value(i,j));
714 l++;
715 }
716 k++;
717 }
718 }
719
720 uknots = nuknots;
721 umults = numults;
722 vknots = nvknots;
723 vmults = nvmults;
724 poles = npoles;
725 if ( urational || vrational)
726 weights = nweights;
727 else
728 weights = new TColStd_HArray2OfReal (1,poles->ColLength(),
729 1,poles->RowLength(), 1.0);
730
731 maxderivinvok = 0;
732 UpdateUKnots();
733 UpdateVKnots();
734
735}
736
737//=======================================================================
738//function : CheckAndSegment
739//purpose :
740//=======================================================================
741
742void Geom_BSplineSurface::CheckAndSegment(const Standard_Real U1,
743 const Standard_Real U2,
744 const Standard_Real V1,
745 const Standard_Real V2)
746{
747
748 Standard_DomainError_Raise_if ( (U2 < U1) || (V2 < V1),
749 "Geom_BSplineCurve::Segment");
750 Standard_Real deltaU = Max(Abs(U2),Abs(U1));
751 Standard_Real EpsU = Epsilon(deltaU);
752 deltaU = U2 - U1;
753
754 Standard_Real deltaV = Max(Abs(V2),Abs(V1));
755 Standard_Real EpsV = Epsilon(deltaV);
756 deltaV = V2 - V1;
757
758 Standard_Real NewU1, NewU2, NewV1, NewV2;
759 Standard_Real U,V;
760 Standard_Integer indexU, indexV;
761
762 Standard_Boolean segment_in_U = Standard_True;
763 Standard_Boolean segment_in_V = Standard_True;
764 segment_in_U = ( Abs(U1 - uknots->Value(uknots->Lower())) > EpsU )
765 || ( Abs(U2 - uknots->Value(uknots->Upper())) > EpsU );
766 segment_in_V = ( Abs(V1 - vknots->Value(vknots->Lower())) > EpsV )
767 || ( Abs(V2 - vknots->Value(vknots->Upper())) > EpsV );
768
769 indexU = 0;
770 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
771 U1,uperiodic,uknots->Lower(),uknots->Upper(),
772 indexU,NewU1);
773 indexU = 0;
774 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
775 U2,uperiodic,uknots->Lower(),uknots->Upper(),
776 indexU,NewU2);
777 if (segment_in_U) {
778 // inserting the UKnots
779 TColStd_Array1OfReal UKnots(1,2);
780 TColStd_Array1OfInteger UMults(1,2);
781 UKnots( 1) = Min( NewU1, NewU2);
782 UKnots( 2) = Max( NewU1, NewU2);
783 UMults( 1) = UMults( 2) = udeg;
784
785 InsertUKnots( UKnots, UMults, EpsU);
786 }
787
788 indexV = 0;
789 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
790 V1,vperiodic,vknots->Lower(),vknots->Upper(),
791 indexV,NewV1);
792 indexV = 0;
793 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
794 V2,vperiodic,vknots->Lower(),vknots->Upper(),
795 indexV,NewV2);
796 if (segment_in_V) {
797 // Inserting the VKnots
798 TColStd_Array1OfReal VKnots(1,2);
799 TColStd_Array1OfInteger VMults(1,2);
800
801 VKnots( 1) = Min( NewV1, NewV2);
802 VKnots( 2) = Max( NewV1, NewV2);
803 VMults( 1) = VMults( 2) = vdeg;
804 InsertVKnots( VKnots, VMults, EpsV);
805 }
806
807 if (uperiodic && segment_in_U) { // set the origine at NewU1
808 Standard_Integer index = 0;
809 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
810 U1,uperiodic,uknots->Lower(),uknots->Upper(),
811 index,U);
812 if ( Abs(uknots->Value(index+1)-U) <= EpsU)
813 index++;
814 SetUOrigin(index);
815 SetUNotPeriodic();
816 }
817
818 // compute index1 and index2 to set the new knots and mults
819 Standard_Integer index1U = 0, index2U = 0;
820 Standard_Integer FromU1 = uknots->Lower();
821 Standard_Integer ToU2 = uknots->Upper();
822 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
823 NewU1,uperiodic,FromU1,ToU2,index1U,U);
824 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
825 NewU1 + deltaU,uperiodic,FromU1,ToU2,index2U,U);
826 if ( Abs(uknots->Value(index2U+1)-U) <= EpsU)
827 index2U++;
828
829 Standard_Integer nbuknots = index2U - index1U + 1;
830
831 Handle(TColStd_HArray1OfReal)
832 nuknots = new TColStd_HArray1OfReal(1,nbuknots);
833 Handle(TColStd_HArray1OfInteger)
834 numults = new TColStd_HArray1OfInteger(1,nbuknots);
835
836 Standard_Integer i , k = 1;
837 for ( i = index1U; i<= index2U; i++) {
838 nuknots->SetValue(k, uknots->Value(i));
839 numults->SetValue(k, umults->Value(i));
840 k++;
841 }
842 if (segment_in_U) {
843 numults->SetValue( 1, udeg + 1);
844 numults->SetValue(nbuknots, udeg + 1);
845 }
846
847 if (vperiodic&& segment_in_V) { // set the origine at NewV1
848 Standard_Integer index = 0;
849 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
850 V1,vperiodic,vknots->Lower(),vknots->Upper(),
851 index,V);
852 if ( Abs(vknots->Value(index+1)-V) <= EpsV)
853 index++;
854 SetVOrigin(index);
855 SetVNotPeriodic();
856 }
857
858 // compute index1 and index2 to set the new knots and mults
859 Standard_Integer index1V = 0, index2V = 0;
860 Standard_Integer FromV1 = vknots->Lower();
861 Standard_Integer ToV2 = vknots->Upper();
862 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
863 NewV1,vperiodic,FromV1,ToV2,index1V,V);
864 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
865 NewV1 + deltaV,vperiodic,FromV1,ToV2,index2V,V);
866 if ( Abs(vknots->Value(index2V+1)-V) <= EpsV)
867 index2V++;
868
869 Standard_Integer nbvknots = index2V - index1V + 1;
870
871 Handle(TColStd_HArray1OfReal)
872 nvknots = new TColStd_HArray1OfReal(1,nbvknots);
873 Handle(TColStd_HArray1OfInteger)
874 nvmults = new TColStd_HArray1OfInteger(1,nbvknots);
875
876 k = 1;
877 for ( i = index1V; i<= index2V; i++) {
878 nvknots->SetValue(k, vknots->Value(i));
879 nvmults->SetValue(k, vmults->Value(i));
880 k++;
881 }
882 if (segment_in_V) {
883 nvmults->SetValue( 1, vdeg + 1);
884 nvmults->SetValue(nbvknots, vdeg + 1);
885 }
886
887 // compute index1 and index2 to set the new poles and weights
888 Standard_Integer pindex1U
889 = BSplCLib::PoleIndex(udeg,index1U,uperiodic,umults->Array1());
890 Standard_Integer pindex2U
891 = BSplCLib::PoleIndex(udeg,index2U,uperiodic,umults->Array1());
892
893 pindex1U++;
894 pindex2U = Min( pindex2U+1, poles->ColLength());
895
896 Standard_Integer nbupoles = pindex2U - pindex1U + 1;
897
898 // compute index1 and index2 to set the new poles and weights
899 Standard_Integer pindex1V
900 = BSplCLib::PoleIndex(vdeg,index1V,vperiodic,vmults->Array1());
901 Standard_Integer pindex2V
902 = BSplCLib::PoleIndex(vdeg,index2V,vperiodic,vmults->Array1());
903
904 pindex1V++;
905 pindex2V = Min( pindex2V+1, poles->RowLength());
906
907 Standard_Integer nbvpoles = pindex2V - pindex1V + 1;
908
909
910 Handle(TColStd_HArray2OfReal) nweights;
911
912 Handle(TColgp_HArray2OfPnt)
913 npoles = new TColgp_HArray2OfPnt(1,nbupoles,1,nbvpoles);
914
915 k = 1;
916 Standard_Integer j, l;
917 if ( urational || vrational) {
918 nweights = new TColStd_HArray2OfReal( 1,nbupoles,1,nbvpoles);
919 for ( i = pindex1U; i <= pindex2U; i++) {
920 l = 1;
921 for ( j = pindex1V; j <= pindex2V; j++) {
922 npoles->SetValue(k,l, poles->Value(i,j));
923 nweights->SetValue(k,l, weights->Value(i,j));
924 l++;
925 }
926 k++;
927 }
928 }
929 else {
930 for ( i = pindex1U; i <= pindex2U; i++) {
931 l = 1;
932 for ( j = pindex1V; j <= pindex2V; j++) {
933 npoles->SetValue(k,l, poles->Value(i,j));
934 l++;
935 }
936 k++;
937 }
938 }
939
940 uknots = nuknots;
941 umults = numults;
942 vknots = nvknots;
943 vmults = nvmults;
944 poles = npoles;
945 if ( urational || vrational)
946 weights = nweights;
947 else
948 weights = new TColStd_HArray2OfReal (1,poles->ColLength(),
949 1,poles->RowLength(), 1.0);
950
951 maxderivinvok = 0;
952 UpdateUKnots();
953 UpdateVKnots();
954
955}
956
957//=======================================================================
958//function : SetUKnot
959//purpose :
960//=======================================================================
961
962void Geom_BSplineSurface::SetUKnot
963(const Standard_Integer UIndex,
964 const Standard_Real K )
965{
966 if (UIndex < 1 || UIndex > uknots->Length()) Standard_OutOfRange::Raise();
967
968 Standard_Integer NewIndex = UIndex;
969 Standard_Real DU = Abs(Epsilon (K));
970 if (UIndex == 1) {
971 if (K >= uknots->Value (2) - DU) Standard_ConstructionError::Raise();
972 }
973 else if (UIndex == uknots->Length()) {
974 if (K <= uknots->Value (uknots->Length()-1) + DU) {
975 Standard_ConstructionError::Raise();
976 }
977 }
978 else {
979 if (K <= uknots->Value (NewIndex-1) + DU ||
980 K >= uknots->Value (NewIndex+1) - DU ) {
981 Standard_ConstructionError::Raise();
982 }
983 }
984
985 if (K != uknots->Value (NewIndex)) {
986 uknots->SetValue (NewIndex, K);
987 maxderivinvok = 0;
988 UpdateUKnots();
989 }
990}
991
992//=======================================================================
993//function : SetUKnots
994//purpose :
995//=======================================================================
996
997void Geom_BSplineSurface::SetUKnots (const TColStd_Array1OfReal& UK) {
998
999 Standard_Integer Lower = UK.Lower();
1000 Standard_Integer Upper = UK.Upper();
1001 if (Lower < 1 || Lower > uknots->Length() ||
1002 Upper < 1 || Upper > uknots->Length() ) {
1003 Standard_OutOfRange::Raise();
1004 }
7fd59977 1005 if (Lower > 1) {
7fd59977 1006 if (Abs (UK (Lower) - uknots->Value (Lower-1)) <= gp::Resolution()) {
1007 Standard_ConstructionError::Raise();
1008 }
1009 }
1010 if (Upper < uknots->Length ()) {
7fd59977 1011 if (Abs (UK (Upper) - uknots->Value (Upper+1)) <= gp::Resolution()) {
1012 Standard_ConstructionError::Raise();
1013 }
1014 }
1015 Standard_Real K1 = UK (Lower);
1016 for (Standard_Integer i = Lower; i <= Upper; i++) {
1017 uknots->SetValue (i, UK(i));
1018 if (i != Lower) {
7fd59977 1019 if (Abs (UK(i) - K1) <= gp::Resolution()) {
1020 Standard_ConstructionError::Raise();
1021 }
1022 K1 = UK (i);
1023 }
1024 }
1025
1026 maxderivinvok = 0;
1027 UpdateUKnots();
1028}
1029
1030//=======================================================================
1031//function : SetUKnot
1032//purpose :
1033//=======================================================================
1034
1035void Geom_BSplineSurface::SetUKnot
1036(const Standard_Integer UIndex,
1037 const Standard_Real K,
1038 const Standard_Integer M)
1039{
1040 IncreaseUMultiplicity (UIndex, M);
1041 SetUKnot (UIndex, K);
1042}
1043
1044//=======================================================================
1045//function : SetVKnot
1046//purpose :
1047//=======================================================================
1048
1049void Geom_BSplineSurface::SetVKnot
1050(const Standard_Integer VIndex,
1051 const Standard_Real K)
1052{
1053 if (VIndex < 1 || VIndex > vknots->Length()) Standard_OutOfRange::Raise();
1054 Standard_Integer NewIndex = VIndex + vknots->Lower() - 1;
1055 Standard_Real DV = Abs(Epsilon (K));
1056 if (VIndex == 1) {
1057 if (K >= vknots->Value (2) - DV) {
1058 Standard_ConstructionError::Raise();
1059 }
1060 }
1061 else if (VIndex == vknots->Length()) {
1062 if (K <= vknots->Value (vknots->Length()-1) + DV) {
1063 Standard_ConstructionError::Raise();
1064 }
1065 }
1066 else {
1067 if (K <= vknots->Value (NewIndex-1) + DV ||
1068 K >= vknots->Value (NewIndex+1) - DV ) {
1069 Standard_ConstructionError::Raise();
1070 }
1071 }
1072
1073 maxderivinvok = 0;
1074 UpdateVKnots();
1075}
1076
1077//=======================================================================
1078//function : SetVKnots
1079//purpose :
1080//=======================================================================
1081
1082void Geom_BSplineSurface::SetVKnots (const TColStd_Array1OfReal& VK) {
1083
1084 Standard_Integer Lower = VK.Lower();
1085 Standard_Integer Upper = VK.Upper();
1086 if (Lower < 1 || Lower > vknots->Length() ||
1087 Upper < 1 || Upper > vknots->Length() ) {
1088 Standard_OutOfRange::Raise();
1089 }
7fd59977 1090 if (Lower > 1) {
7fd59977 1091 if (Abs (VK (Lower) - vknots->Value (Lower-1)) <= gp::Resolution()) {
1092 Standard_ConstructionError::Raise();
1093 }
1094 }
1095 if (Upper < vknots->Length ()) {
7fd59977 1096 if (Abs (VK (Upper) - vknots->Value (Upper+1)) <= gp::Resolution()) {
1097 Standard_ConstructionError::Raise();
1098 }
1099 }
1100 Standard_Real K1 = VK (Lower);
1101 for (Standard_Integer i = Lower; i <= Upper; i++) {
1102 vknots->SetValue (i, VK(i));
1103 if (i != Lower) {
7fd59977 1104 if (Abs (VK(i) - K1) <= gp::Resolution()) {
1105 Standard_ConstructionError::Raise();
1106 }
1107 K1 = VK (i);
1108 }
1109 }
1110
1111 maxderivinvok = 0;
1112 UpdateVKnots();
1113}
1114
1115//=======================================================================
1116//function : SetVKnot
1117//purpose :
1118//=======================================================================
1119
1120void Geom_BSplineSurface::SetVKnot
1121(const Standard_Integer VIndex,
1122 const Standard_Real K,
1123 const Standard_Integer M)
1124{
1125 IncreaseVMultiplicity (VIndex, M);
1126 SetVKnot (VIndex, K);
1127}
1128
1129//=======================================================================
1130//function : InsertUKnot
1131//purpose :
1132//=======================================================================
1133
1134void Geom_BSplineSurface::InsertUKnot
1135(const Standard_Real U,
1136 const Standard_Integer M,
1137 const Standard_Real ParametricTolerance,
1138 const Standard_Boolean Add)
1139{
1140 TColStd_Array1OfReal k(1,1);
1141 k(1) = U;
1142 TColStd_Array1OfInteger m(1,1);
1143 m(1) = M;
1144 InsertUKnots(k,m,ParametricTolerance,Add);
1145}
1146
1147//=======================================================================
1148//function : InsertVKnot
1149//purpose :
1150//=======================================================================
1151
1152void Geom_BSplineSurface::InsertVKnot
1153(const Standard_Real V,
1154 const Standard_Integer M,
1155 const Standard_Real ParametricTolerance,
1156 const Standard_Boolean Add)
1157{
1158 TColStd_Array1OfReal k(1,1);
1159 k(1) = V;
1160 TColStd_Array1OfInteger m(1,1);
1161 m(1) = M;
1162 InsertVKnots(k,m,ParametricTolerance,Add);
1163}
1164
1165//=======================================================================
1166//function : IncrementUMultiplicity
1167//purpose :
1168//=======================================================================
1169
1170void Geom_BSplineSurface::IncrementUMultiplicity
1171(const Standard_Integer FromI1,
1172 const Standard_Integer ToI2,
1173 const Standard_Integer Step)
1174{
1175 Handle(TColStd_HArray1OfReal) tk = uknots;
1176 TColStd_Array1OfReal k( (uknots->Array1())(FromI1), FromI1, ToI2);
1177 TColStd_Array1OfInteger m( FromI1, ToI2) ;
1178 m.Init(Step);
1179 InsertUKnots( k, m, Epsilon(1.));
1180}
1181
1182//=======================================================================
1183//function : IncrementVMultiplicity
1184//purpose :
1185//=======================================================================
1186
1187void Geom_BSplineSurface::IncrementVMultiplicity
1188(const Standard_Integer FromI1,
1189 const Standard_Integer ToI2,
1190 const Standard_Integer Step)
1191{
1192 Handle(TColStd_HArray1OfReal) tk = vknots;
1193 TColStd_Array1OfReal k( (vknots->Array1())(FromI1), FromI1, ToI2);
1194
1195 TColStd_Array1OfInteger m( FromI1, ToI2) ;
1196 m.Init(Step);
1197
1198 InsertVKnots( k, m, Epsilon(1.));
1199}
1200
1201//=======================================================================
1202//function : UpdateUKnots
1203//purpose :
1204//=======================================================================
1205
1206void Geom_BSplineSurface::UpdateUKnots()
1207{
1208
1209 Standard_Integer MaxKnotMult = 0;
06be28a4 1210 BSplCLib::KnotAnalysis (udeg, uperiodic,
7fd59977 1211 uknots->Array1(),
1212 umults->Array1(),
1213 uknotSet, MaxKnotMult);
1214
1215 if (uknotSet == GeomAbs_Uniform && !uperiodic) {
1216 ufknots = uknots;
1217 }
1218 else {
1219 ufknots = new TColStd_HArray1OfReal
1220 (1, BSplCLib::KnotSequenceLength(umults->Array1(),udeg,uperiodic));
1221
1222 BSplCLib::KnotSequence (uknots->Array1(),
1223 umults->Array1(),
1224 udeg,uperiodic,
1225 ufknots->ChangeArray1());
1226 }
1227
1228 if (MaxKnotMult == 0) Usmooth = GeomAbs_CN;
1229 else {
1230 switch (udeg - MaxKnotMult) {
1231 case 0 : Usmooth = GeomAbs_C0; break;
1232 case 1 : Usmooth = GeomAbs_C1; break;
1233 case 2 : Usmooth = GeomAbs_C2; break;
1234 case 3 : Usmooth = GeomAbs_C3; break;
1235 default : Usmooth = GeomAbs_C3; break;
1236 }
1237 }
7fd59977 1238}
1239
1240//=======================================================================
1241//function : UpdateVKnots
1242//purpose :
1243//=======================================================================
1244
1245void Geom_BSplineSurface::UpdateVKnots()
1246{
1247 Standard_Integer MaxKnotMult = 0;
06be28a4 1248 BSplCLib::KnotAnalysis (vdeg, vperiodic,
7fd59977 1249 vknots->Array1(),
1250 vmults->Array1(),
1251 vknotSet, MaxKnotMult);
1252
1253 if (vknotSet == GeomAbs_Uniform && !vperiodic) {
1254 vfknots = vknots;
1255 }
1256 else {
1257 vfknots = new TColStd_HArray1OfReal
1258 (1, BSplCLib::KnotSequenceLength(vmults->Array1(),vdeg,vperiodic));
1259
1260 BSplCLib::KnotSequence (vknots->Array1(),
1261 vmults->Array1(),
1262 vdeg,vperiodic,
1263 vfknots->ChangeArray1());
1264 }
1265
1266 if (MaxKnotMult == 0) Vsmooth = GeomAbs_CN;
1267 else {
1268 switch (vdeg - MaxKnotMult) {
1269 case 0 : Vsmooth = GeomAbs_C0; break;
1270 case 1 : Vsmooth = GeomAbs_C1; break;
1271 case 2 : Vsmooth = GeomAbs_C2; break;
1272 case 3 : Vsmooth = GeomAbs_C3; break;
1273 default : Vsmooth = GeomAbs_C3; break;
1274 }
1275 }
7fd59977 1276}
1277
7fd59977 1278
1279//=======================================================================
1280//function : Normalizes the parameters if the curve is periodic
1281//purpose : that is compute the cache so that it is valid
1282//=======================================================================
1283
1284void Geom_BSplineSurface::PeriodicNormalization
1285(Standard_Real& Uparameter,
1286 Standard_Real& Vparameter) const
1287{
1288 Standard_Real Period, aMaxVal, aMinVal;
1289
1290 if (uperiodic) {
1291 aMaxVal = ufknots->Value(ufknots->Upper() - udeg);
1292 aMinVal = ufknots->Value (udeg + 1);
1293 Standard_Real eps = Abs(Epsilon(Uparameter));
1294 Period = aMaxVal - aMinVal;
1295
1296 if(Period <= eps)
1297 Standard_OutOfRange::Raise("Geom_BSplineSurface::PeriodicNormalization: Uparameter is too great number");
1298
9cbe6290 1299 Standard_Boolean isLess, isGreater;
1300 isLess = aMinVal - Uparameter > 0;
1301 isGreater = Uparameter - aMaxVal > 0;
1302 if (isLess || isGreater) {
1303 Standard_Real aDPar, aNbPer;
1304 aDPar = (isLess) ? (aMaxVal - Uparameter) : (aMinVal - Uparameter);
1305 modf(aDPar / Period, &aNbPer);
1306 Uparameter += aNbPer * Period;
7fd59977 1307 }
1308 }
1309 if (vperiodic) {
1310 aMaxVal = vfknots->Value(vfknots->Upper() - vdeg);
1311 aMinVal = vfknots->Value (vdeg + 1);
1312 Standard_Real eps = Abs(Epsilon(Vparameter));
1313 Period = aMaxVal - aMinVal;
1314
1315 if(Period <= eps)
1316 Standard_OutOfRange::Raise("Geom_BSplineSurface::PeriodicNormalization: Vparameter is too great number");
1317
9cbe6290 1318 Standard_Boolean isLess, isGreater;
1319 isLess = aMinVal - Vparameter > 0;
1320 isGreater = Vparameter - aMaxVal > 0;
1321 if (isLess || isGreater) {
1322 Standard_Real aDPar, aNbPer;
1323 aDPar = (isLess) ? (aMaxVal - Vparameter) : (aMinVal - Vparameter);
1324 modf(aDPar / Period, &aNbPer);
1325 Vparameter += aNbPer * Period;
7fd59977 1326 }
1327 }
1328}
1329
1330//=======================================================================
7fd59977 1331//function : SetWeight
1332//purpose :
1333//=======================================================================
1334
1335void Geom_BSplineSurface::SetWeight (const Standard_Integer UIndex,
1336 const Standard_Integer VIndex,
1337 const Standard_Real Weight)
1338{
1339 if (Weight <= gp::Resolution()) Standard_ConstructionError::Raise();
1340 TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1341 if (UIndex < 1 || UIndex > Weights.ColLength() ||
1342 VIndex < 1 || VIndex > Weights.RowLength() ) {
1343 Standard_OutOfRange::Raise();
1344 }
1345 Weights (UIndex+Weights.LowerRow()-1, VIndex+Weights.LowerCol()-1) = Weight;
1346 Rational(Weights, urational, vrational);
7fd59977 1347}
1348
1349//=======================================================================
1350//function : SetWeightCol
1351//purpose :
1352//=======================================================================
1353
1354void Geom_BSplineSurface::SetWeightCol
1355(const Standard_Integer VIndex,
1356 const TColStd_Array1OfReal& CPoleWeights)
1357{
1358 TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1359 if (VIndex < 1 || VIndex > Weights.RowLength()) {
1360 Standard_OutOfRange::Raise();
1361 }
1362 if (CPoleWeights.Lower() < 1 ||
1363 CPoleWeights.Lower() > Weights.ColLength() ||
1364 CPoleWeights.Upper() < 1 ||
1365 CPoleWeights.Upper() > Weights.ColLength() ) {
1366 Standard_ConstructionError::Raise();
1367 }
1368 Standard_Integer I = CPoleWeights.Lower();
1369 while (I <= CPoleWeights.Upper()) {
1370 if (CPoleWeights(I) <= gp::Resolution()) {
1371 Standard_ConstructionError::Raise();
1372 }
1373 Weights (I+Weights.LowerRow()-1, VIndex+Weights.LowerCol()-1) =
1374 CPoleWeights (I);
1375 I++;
1376 }
1377 // Verifie si c'est rationnel
1378 Rational(Weights, urational, vrational);
7fd59977 1379}
1380
1381//=======================================================================
1382//function : SetWeightRow
1383//purpose :
1384//=======================================================================
1385
1386void Geom_BSplineSurface::SetWeightRow
1387(const Standard_Integer UIndex,
1388 const TColStd_Array1OfReal& CPoleWeights)
1389{
1390 TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1391 if (UIndex < 1 || UIndex > Weights.ColLength()) {
1392 Standard_OutOfRange::Raise();
1393 }
1394 if (CPoleWeights.Lower() < 1 ||
1395 CPoleWeights.Lower() > Weights.RowLength() ||
1396 CPoleWeights.Upper() < 1 ||
1397 CPoleWeights.Upper() > Weights.RowLength() ) {
1398
1399 Standard_ConstructionError::Raise();
1400 }
1401 Standard_Integer I = CPoleWeights.Lower();
1402
1403 while (I <= CPoleWeights.Upper()) {
1404 if (CPoleWeights(I)<=gp::Resolution()) {
1405 Standard_ConstructionError::Raise();
1406 }
1407 Weights (UIndex+Weights.LowerRow()-1, I+Weights.LowerCol()-1) =
1408 CPoleWeights (I);
1409 I++;
1410 }
1411 // Verifie si c'est rationnel
1412 Rational(Weights, urational, vrational);
7fd59977 1413}
1414