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