0023891: Function fsameparameter throws an exception.
[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
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
7fd59977 22// 14-Mar-96 : xab portage hp
23// pmn : 28-Jun-96 Distinction entre la continuite en U et V (bug PRO4625)
24// pmn : 07-Jan-97 Centralisation des verif rational (PRO6834)
25// et ajout des InvalideCache() dans les SetWeight*(PRO6833)
26// RBD : 15-10-98 ; Le cache est maintenant calcule sur [-1,1] (pro15537).
27// jct : 19-01-99 ; permutation de urational et vrational dans Rational.
7fd59977 28#define No_Standard_OutOfRange
29
30#include <Geom_BSplineSurface.ixx>
31
32#include <gp.hxx>
33#include <BSplCLib.hxx>
34#include <BSplSLib.hxx>
35
36#include <Standard_ConstructionError.hxx>
37#include <Standard_NotImplemented.hxx>
38#include <Standard_OutOfRange.hxx>
39#include <Precision.hxx>
40
41//=======================================================================
42//function : CheckSurfaceData
43//purpose : Internal use only.
44//=======================================================================
45
46static void CheckSurfaceData
47(const TColgp_Array2OfPnt& SPoles,
48 const TColStd_Array1OfReal& SUKnots,
49 const TColStd_Array1OfReal& SVKnots,
50 const TColStd_Array1OfInteger& SUMults,
51 const TColStd_Array1OfInteger& SVMults,
52 const Standard_Integer UDegree,
53 const Standard_Integer VDegree,
54 const Standard_Boolean UPeriodic,
55 const Standard_Boolean VPeriodic)
56{
57 if (UDegree < 1 || UDegree > Geom_BSplineSurface::MaxDegree () ||
58 VDegree < 1 || VDegree > Geom_BSplineSurface::MaxDegree ()) {
59 Standard_ConstructionError::Raise("Geom_BSplineSurface");
60 }
61 if (SPoles.ColLength () < 2 || SPoles.RowLength () < 2) {
62 Standard_ConstructionError::Raise("Geom_BSplineSurface");
63 }
64
65 if (SUKnots.Length() != SUMults.Length() ||
66 SVKnots.Length() != SVMults.Length()) {
67 Standard_ConstructionError::Raise("Geom_BSplineSurface");
68 }
69
70 Standard_Integer i;
71 for (i = SUKnots.Lower(); i < SUKnots.Upper(); i++) {
72 if (SUKnots(i+1) - SUKnots(i) <= Epsilon(Abs(SUKnots(i)))) {
73 Standard_ConstructionError::Raise("Geom_BSplineSurface");
74 }
75 }
76
77 for (i = SVKnots.Lower(); i < SVKnots.Upper(); i++) {
78 if (SVKnots(i+1) - SVKnots(i) <= Epsilon(Abs(SVKnots(i)))) {
79 Standard_ConstructionError::Raise("Geom_BSplineSurface");
80 }
81 }
82
83 if (SPoles.ColLength() != BSplCLib::NbPoles(UDegree,UPeriodic,SUMults))
84 Standard_ConstructionError::Raise("Geom_BSplineSurface");
85
86 if (SPoles.RowLength() != BSplCLib::NbPoles(VDegree,VPeriodic,SVMults))
87 Standard_ConstructionError::Raise("Geom_BSplineSurface");
88}
89
90//=======================================================================
91//function : KnotAnalysis
92//purpose : Internal use only.
93//=======================================================================
94
95static void KnotAnalysis
96(const Standard_Integer Degree,
97 const TColStd_Array1OfReal& CKnots,
98 const TColStd_Array1OfInteger& CMults,
99 GeomAbs_BSplKnotDistribution& KnotForm,
100 Standard_Integer& MaxKnotMult)
101{
102 KnotForm = GeomAbs_NonUniform;
103
104 BSplCLib_KnotDistribution KSet =
105 BSplCLib::KnotForm (CKnots, 1, CKnots.Length());
106
107
108 if (KSet == BSplCLib_Uniform) {
109 BSplCLib_MultDistribution MSet =
110 BSplCLib::MultForm (CMults, 1, CMults.Length());
111 switch (MSet) {
112 case BSplCLib_NonConstant :
113 break;
114 case BSplCLib_Constant :
115 if (CKnots.Length() == 2) {
116 KnotForm = GeomAbs_PiecewiseBezier;
117 }
118 else {
119 if (CMults (1) == 1) KnotForm = GeomAbs_Uniform;
120 }
121 break;
122 case BSplCLib_QuasiConstant :
123 if (CMults (1) == Degree + 1) {
124 Standard_Real M = CMults (2);
125 if (M == Degree ) KnotForm = GeomAbs_PiecewiseBezier;
126 else if (M == 1) KnotForm = GeomAbs_QuasiUniform;
127 }
128 break;
129 }
130 }
131
132 Standard_Integer FirstKM = BSplCLib::FirstUKnotIndex (Degree, CMults);
133 Standard_Integer LastKM = BSplCLib::LastUKnotIndex (Degree, CMults);
134 MaxKnotMult = 0;
135 if (LastKM - FirstKM != 1) {
136 Standard_Integer Multi;
137 for (Standard_Integer i = FirstKM + 1; i < LastKM; i++) {
138 Multi = CMults (i);
139 MaxKnotMult = Max (MaxKnotMult, Multi);
140 }
141 }
142}
143
144//=======================================================================
145//function : Rational
146//purpose : Internal use only.
147//=======================================================================
148
149static void Rational(const TColStd_Array2OfReal& Weights,
150 Standard_Boolean& Urational,
151 Standard_Boolean& Vrational)
152{
153 Standard_Integer I,J;
154 J = Weights.LowerCol ();
155 Vrational = Standard_False;
156 while (!Vrational && J <= Weights.UpperCol()) {
157 I = Weights.LowerRow();
158 while (!Vrational && I <= Weights.UpperRow() - 1) {
159 Vrational = (Abs(Weights (I, J) - Weights (I+1, J))
160 > Epsilon (Abs(Weights (I, J))));
161 I++;
162 }
163 J++;
164 }
165
166 I = Weights.LowerRow ();
167 Urational = Standard_False;
168 while (!Urational && I <= Weights.UpperRow()) {
169 J = Weights.LowerCol();
170 while (!Urational && J <= Weights.UpperCol() - 1) {
171 Urational = (Abs(Weights (I, J) - Weights (I, J+1))
172 > Epsilon (Abs(Weights (I, J))));
173 J++;
174 }
175 I++;
176 }
177}
178
179//=======================================================================
180//function : Copy
181//purpose :
182//=======================================================================
183
184Handle(Geom_Geometry) Geom_BSplineSurface::Copy () const
185{
186 Handle(Geom_BSplineSurface) S;
187 if (urational || vrational)
188 S = new Geom_BSplineSurface (poles->Array2() , weights->Array2(),
189 uknots->Array1(), vknots->Array1(),
190 umults->Array1(), vmults->Array1(),
191 udeg , vdeg,
192 uperiodic, vperiodic);
193 else
194 S = new Geom_BSplineSurface (poles->Array2(),
195 uknots->Array1(), vknots->Array1(),
196 umults->Array1(), vmults->Array1(),
197 udeg , vdeg,
198 uperiodic, vperiodic);
199 return S;
200}
201
202//=======================================================================
203//function : Geom_BSplineSurface
204//purpose :
205//=======================================================================
206
207Geom_BSplineSurface::Geom_BSplineSurface
208(const TColgp_Array2OfPnt& Poles,
209 const TColStd_Array1OfReal& UKnots,
210 const TColStd_Array1OfReal& VKnots,
211 const TColStd_Array1OfInteger& UMults,
212 const TColStd_Array1OfInteger& VMults,
213 const Standard_Integer UDegree,
214 const Standard_Integer VDegree,
215 const Standard_Boolean UPeriodic,
216 const Standard_Boolean VPeriodic
217 ) :
218 urational(Standard_False),
219 vrational(Standard_False),
220 uperiodic(UPeriodic),
221 vperiodic(VPeriodic),
222 udeg(UDegree),
223 vdeg(VDegree),
224 maxderivinvok(0)
225
226{
227 Standard_Integer MinDegree,
228 MaxDegree ;
229
230 // check
231
232 CheckSurfaceData(Poles,
233 UKnots , VKnots,
234 UMults , VMults,
235 UDegree , VDegree,
236 UPeriodic, VPeriodic);
237
238 // copy arrays
239
240 poles = new TColgp_HArray2OfPnt(1,Poles.ColLength(),
241 1,Poles.RowLength());
242 poles->ChangeArray2() = Poles;
243
244 weights = new TColStd_HArray2OfReal (1,Poles.ColLength(),
245 1,Poles.RowLength(), 1.0);
246
247 uknots = new TColStd_HArray1OfReal (1,UKnots.Length());
248 uknots->ChangeArray1() = UKnots;
249
250 umults = new TColStd_HArray1OfInteger (1,UMults.Length());
251 umults->ChangeArray1() = UMults;
252
253 vknots = new TColStd_HArray1OfReal (1,VKnots.Length());
254 vknots->ChangeArray1() = VKnots;
255
256 vmults = new TColStd_HArray1OfInteger (1,VMults.Length());
257 vmults->ChangeArray1() = VMults;
258 MinDegree = Min(udeg,vdeg) ;
259 MaxDegree = Max(udeg,vdeg) ;
260 cachepoles = new TColgp_HArray2OfPnt(1,MaxDegree + 1,
261 1,MinDegree + 1) ;
262
263 cacheweights.Nullify() ;
264 ucacheparameter = 0.0e0 ;
265 vcacheparameter = 0.0e0 ;
266 ucachespanlenght = 1.0e0 ;
267 vcachespanlenght = 1.0e0 ;
268 ucachespanindex = 0 ;
269 vcachespanindex = 0 ;
270 validcache = 0 ;
271
272 UpdateUKnots();
273 UpdateVKnots();
274}
275
276//=======================================================================
277//function : Geom_BSplineSurface
278//purpose :
279//=======================================================================
280
281Geom_BSplineSurface::Geom_BSplineSurface
282(const TColgp_Array2OfPnt& Poles,
283 const TColStd_Array2OfReal& Weights,
284 const TColStd_Array1OfReal& UKnots,
285 const TColStd_Array1OfReal& VKnots,
286 const TColStd_Array1OfInteger& UMults,
287 const TColStd_Array1OfInteger& VMults,
288 const Standard_Integer UDegree,
289 const Standard_Integer VDegree,
290 const Standard_Boolean UPeriodic,
291 const Standard_Boolean VPeriodic) :
292 urational(Standard_False),
293 vrational(Standard_False),
294 uperiodic(UPeriodic),
295 vperiodic(VPeriodic),
296 udeg(UDegree),
297 vdeg(VDegree),
298 maxderivinvok(0)
299{
300 Standard_Integer MinDegree,
301 MaxDegree ;
302 // check weights
303
304 if (Weights.ColLength() != Poles.ColLength())
305 Standard_ConstructionError::Raise("Geom_BSplineSurface");
306
307 if (Weights.RowLength() != Poles.RowLength())
308 Standard_ConstructionError::Raise("Geom_BSplineSurface");
309
310 Standard_Integer i,j;
311 for (i = Weights.LowerRow(); i <= Weights.UpperRow(); i++) {
312 for (j = Weights.LowerCol(); j <= Weights.UpperCol(); j++) {
313 if (Weights(i,j) <= gp::Resolution())
314 Standard_ConstructionError::Raise("Geom_BSplineSurface");
315 }
316 }
317
318 // check really rational
319
320 Rational(Weights, urational, vrational);
321
322 // check
323
324 CheckSurfaceData(Poles,
325 UKnots , VKnots,
326 UMults , VMults,
327 UDegree , VDegree,
328 UPeriodic, VPeriodic);
329
330 // copy arrays
331
332 poles = new TColgp_HArray2OfPnt(1,Poles.ColLength(),
333 1,Poles.RowLength());
334 poles->ChangeArray2() = Poles;
335
336 weights = new TColStd_HArray2OfReal (1,Poles.ColLength(),
337 1,Poles.RowLength());
338 weights->ChangeArray2() = Weights;
339
340 uknots = new TColStd_HArray1OfReal (1,UKnots.Length());
341 uknots->ChangeArray1() = UKnots;
342
343 umults = new TColStd_HArray1OfInteger (1,UMults.Length());
344 umults->ChangeArray1() = UMults;
345
346 vknots = new TColStd_HArray1OfReal (1,VKnots.Length());
347 vknots->ChangeArray1() = VKnots;
348
349 vmults = new TColStd_HArray1OfInteger (1,VMults.Length());
350 vmults->ChangeArray1() = VMults;
351 MinDegree = Min(udeg,vdeg) ;
352 MaxDegree = Max(udeg,vdeg) ;
353 cachepoles = new TColgp_HArray2OfPnt(1,MaxDegree + 1,
354 1,MinDegree + 1) ;
355 if (urational || vrational) {
356 cacheweights = new TColStd_HArray2OfReal (1,MaxDegree + 1,
357 1,MinDegree + 1);
358 }
359 ucacheparameter = 0.0e0 ;
360 vcacheparameter = 0.0e0 ;
361 ucachespanlenght = 1.0e0 ;
362 vcachespanlenght = 1.0e0 ;
363 ucachespanindex = 0 ;
364 vcachespanindex = 0 ;
365 validcache = 0 ;
366
367 UpdateUKnots();
368 UpdateVKnots();
369}
370
371//=======================================================================
372//function : ExchangeUV
373//purpose :
374//=======================================================================
375
376void Geom_BSplineSurface::ExchangeUV ()
377{
378 Standard_Integer LC = poles->LowerCol();
379 Standard_Integer UC = poles->UpperCol();
380 Standard_Integer LR = poles->LowerRow();
381 Standard_Integer UR = poles->UpperRow();
382
383 Handle(TColgp_HArray2OfPnt) npoles =
384 new TColgp_HArray2OfPnt (LC, UC, LR, UR);
385 Handle(TColStd_HArray2OfReal) nweights =
386 new TColStd_HArray2OfReal (LC, UC, LR, UR);
387
388 const TColgp_Array2OfPnt & spoles = poles->Array2();
389 const TColStd_Array2OfReal & sweights = weights->Array2();
390
391 TColgp_Array2OfPnt& snpoles = npoles->ChangeArray2();
392 TColStd_Array2OfReal& snweights = nweights->ChangeArray2();
393
394 Standard_Integer i, j;
395 for (i = LC; i <= UC; i++) {
396 for (j = LR; j <= UR; j++) {
397 snpoles (i,j) = spoles (j,i);
398 snweights (i,j) = sweights (j,i);
399 }
400 }
401
402 poles = npoles;
403 weights = nweights;
404
405 Standard_Boolean temp = urational;
406 urational = vrational;
407 vrational = temp;
408
409 temp = uperiodic;
410 uperiodic = vperiodic;
411 vperiodic = temp;
412
413 Standard_Integer tempdeg = udeg;
414 udeg = vdeg;
415 vdeg = tempdeg;
416
417
418 Handle(TColStd_HArray1OfReal) tempknots = uknots;
419 uknots = vknots;
420 vknots = tempknots;
421
422 Handle(TColStd_HArray1OfInteger) tempmults = umults;
423 umults = vmults;
424 vmults = tempmults;
425
426 UpdateUKnots();
427 UpdateVKnots();
428}
429
430//=======================================================================
431//function : IncreaseDegree
432//purpose :
433//=======================================================================
434
435void Geom_BSplineSurface::IncreaseDegree (const Standard_Integer UDegree,
436 const Standard_Integer VDegree)
437{
438 if (UDegree != udeg) {
439 if ( UDegree < udeg || UDegree > Geom_BSplineSurface::MaxDegree())
440 Standard_ConstructionError::Raise();
441
442 Standard_Integer FromK1 = FirstUKnotIndex();
443 Standard_Integer ToK2 = LastUKnotIndex();
444
445 Standard_Integer Step = UDegree - udeg;
446
447 Handle(TColgp_HArray2OfPnt) npoles = new
448 TColgp_HArray2OfPnt( 1, poles->ColLength() + Step * (ToK2 - FromK1),
449 1, poles->RowLength());
450
451 Standard_Integer nbknots = BSplCLib::IncreaseDegreeCountKnots
452 (udeg,UDegree,uperiodic,umults->Array1());
453
454 Handle(TColStd_HArray1OfReal) nknots =
455 new TColStd_HArray1OfReal(1,nbknots);
456
457 Handle(TColStd_HArray1OfInteger) nmults =
458 new TColStd_HArray1OfInteger(1,nbknots);
459
460 Handle(TColStd_HArray2OfReal) nweights
461 = new TColStd_HArray2OfReal(1,npoles->ColLength(),
462 1,npoles->RowLength(), 1.);
463
464 if (urational || vrational) {
465
466 BSplSLib::IncreaseDegree
467 (Standard_True, udeg, UDegree, uperiodic,
468 poles->Array2(),weights->Array2(),
469 uknots->Array1(),umults->Array1(),
470 npoles->ChangeArray2(),nweights->ChangeArray2(),
471 nknots->ChangeArray1(),nmults->ChangeArray1());
472 }
473 else {
474
475 BSplSLib::IncreaseDegree
476 (Standard_True, udeg, UDegree, uperiodic,
477 poles->Array2(),BSplSLib::NoWeights(),
478 uknots->Array1(),umults->Array1(),
479 npoles->ChangeArray2(),*((TColStd_Array2OfReal*) NULL),
480 nknots->ChangeArray1(),nmults->ChangeArray1());
481 }
482 udeg = UDegree;
483 poles = npoles;
484 weights = nweights;
485 uknots = nknots;
486 umults = nmults;
487 UpdateUKnots();
488 }
489
490 if (VDegree != vdeg) {
491 if ( VDegree < vdeg || VDegree > Geom_BSplineSurface::MaxDegree())
492 Standard_ConstructionError::Raise();
493
494 Standard_Integer FromK1 = FirstVKnotIndex();
495 Standard_Integer ToK2 = LastVKnotIndex();
496
497 Standard_Integer Step = VDegree - vdeg;
498
499 Handle(TColgp_HArray2OfPnt) npoles = new
500 TColgp_HArray2OfPnt( 1, poles->ColLength(),
501 1, poles->RowLength() + Step * (ToK2 - FromK1));
502
503 Standard_Integer nbknots = BSplCLib::IncreaseDegreeCountKnots
504 (vdeg,VDegree,vperiodic,vmults->Array1());
505
506 Handle(TColStd_HArray1OfReal) nknots =
507 new TColStd_HArray1OfReal(1,nbknots);
508
509 Handle(TColStd_HArray1OfInteger) nmults =
510 new TColStd_HArray1OfInteger(1,nbknots);
511
512 Handle(TColStd_HArray2OfReal) nweights
513 = new TColStd_HArray2OfReal(1,npoles->ColLength(),
514 1,npoles->RowLength(), 1.);
515
516 if (urational || vrational) {
517
518 BSplSLib::IncreaseDegree
519 (Standard_False, vdeg, VDegree, vperiodic,
520 poles->Array2(),weights->Array2(),
521 vknots->Array1(),vmults->Array1(),
522 npoles->ChangeArray2(),nweights->ChangeArray2(),
523 nknots->ChangeArray1(),nmults->ChangeArray1());
524 }
525 else {
526
527 BSplSLib::IncreaseDegree
528 (Standard_False, vdeg, VDegree, vperiodic,
529 poles->Array2(),BSplSLib::NoWeights(),
530 vknots->Array1(),vmults->Array1(),
531 npoles->ChangeArray2(),*((TColStd_Array2OfReal*) NULL),
532 nknots->ChangeArray1(),nmults->ChangeArray1());
533 }
534 vdeg = VDegree;
535 poles = npoles;
536 weights = nweights;
537 vknots = nknots;
538 vmults = nmults;
539 UpdateVKnots();
540 }
541}
542
543//=======================================================================
544//function : IncreaseUMultiplicity
545//purpose :
546//=======================================================================
547
548void Geom_BSplineSurface::IncreaseUMultiplicity
549(const Standard_Integer UIndex,
550 const Standard_Integer M)
551{
552 TColStd_Array1OfReal k(1,1);
553 k(1) = uknots->Value(UIndex);
554 TColStd_Array1OfInteger m(1,1);
555 m(1) = M - umults->Value(UIndex);
556 InsertUKnots(k,m,Epsilon(1.),Standard_True);
557}
558
559//=======================================================================
560//function : IncreaseUMultiplicity
561//purpose :
562//=======================================================================
563
564void Geom_BSplineSurface::IncreaseUMultiplicity
565(const Standard_Integer FromI1,
566 const Standard_Integer ToI2,
567 const Standard_Integer M)
568{
569 Handle(TColStd_HArray1OfReal) tk = uknots;
570 TColStd_Array1OfReal k((uknots->Array1())(FromI1),FromI1,ToI2);
571 TColStd_Array1OfInteger m(FromI1, ToI2);
572 for (Standard_Integer i = FromI1; i <= ToI2; i++)
573 m(i) = M - umults->Value(i);
574 InsertUKnots(k,m,Epsilon(1.),Standard_True);
575}
576
577//=======================================================================
578//function : IncreaseVMultiplicity
579//purpose :
580//=======================================================================
581
582void Geom_BSplineSurface::IncreaseVMultiplicity
583(const Standard_Integer VIndex,
584 const Standard_Integer M)
585{
586 TColStd_Array1OfReal k(1,1);
587 k(1) = vknots->Value(VIndex);
588 TColStd_Array1OfInteger m(1,1);
589 m(1) = M - vmults->Value(VIndex);
590 InsertVKnots(k,m,Epsilon(1.),Standard_True);
591}
592
593//=======================================================================
594//function : IncreaseVMultiplicity
595//purpose :
596//=======================================================================
597
598void Geom_BSplineSurface::IncreaseVMultiplicity
599(const Standard_Integer FromI1,
600 const Standard_Integer ToI2,
601 const Standard_Integer M)
602{
603 Handle(TColStd_HArray1OfReal) tk = vknots;
604 TColStd_Array1OfReal k((vknots->Array1())(FromI1),FromI1,ToI2);
605 TColStd_Array1OfInteger m(FromI1,ToI2);
606 for (Standard_Integer i = FromI1; i <= ToI2; i++)
607 m(i) = M - vmults->Value(i);
608 InsertVKnots(k,m,Epsilon(1.),Standard_True);
609}
610
611//=======================================================================
612//function : Segment
613//purpose :
614//=======================================================================
615
616void Geom_BSplineSurface::Segment(const Standard_Real U1,
617 const Standard_Real U2,
618 const Standard_Real V1,
619 const Standard_Real V2)
620{
621
622 Standard_DomainError_Raise_if ( (U2 < U1) || (V2 < V1),
623 "Geom_BSplineCurve::Segment");
624 Standard_Real deltaU = Max(Abs(U2),Abs(U1));
625 Standard_Real EpsU = Epsilon(deltaU);
626 deltaU = U2 - U1;
627
628 Standard_Real deltaV = Max(Abs(V2),Abs(V1));
629 Standard_Real EpsV = Epsilon(deltaV);
630 deltaV = V2 - V1;
631
632 Standard_Real NewU1, NewU2, NewV1, NewV2;
633 Standard_Real U,V;
634 Standard_Integer indexU, indexV;
635
636 // inserting the UKnots
637 TColStd_Array1OfReal UKnots(1,2);
638 TColStd_Array1OfInteger UMults(1,2);
639
640 indexU = 0;
641 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
642 U1,uperiodic,uknots->Lower(),uknots->Upper(),
643 indexU,NewU1);
644 indexU = 0;
645 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
646 U2,uperiodic,uknots->Lower(),uknots->Upper(),
647 indexU,NewU2);
648 UKnots( 1) = Min( NewU1, NewU2);
649 UKnots( 2) = Max( NewU1, NewU2);
650 UMults( 1) = UMults( 2) = udeg;
651 InsertUKnots( UKnots, UMults, EpsU);
652
653 // Inserting the VKnots
654 TColStd_Array1OfReal VKnots(1,2);
655 TColStd_Array1OfInteger VMults(1,2);
656
657 indexV = 0;
658 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
659 V1,vperiodic,vknots->Lower(),vknots->Upper(),
660 indexV,NewV1);
661 indexV = 0;
662 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
663 V2,vperiodic,vknots->Lower(),vknots->Upper(),
664 indexV,NewV2);
665 VKnots( 1) = Min( NewV1, NewV2);
666 VKnots( 2) = Max( NewV1, NewV2);
667 VMults( 1) = VMults( 2) = vdeg;
668 InsertVKnots( VKnots, VMults, EpsV);
669
670
671 if (uperiodic) { // set the origine at NewU1
672 Standard_Integer index = 0;
673 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
674 U1,uperiodic,uknots->Lower(),uknots->Upper(),
675 index,U);
676 if ( Abs(uknots->Value(index+1)-U) <= EpsU)
677 index++;
678 SetUOrigin(index);
679 SetUNotPeriodic();
680 }
681
682 // compute index1 and index2 to set the new knots and mults
683 Standard_Integer index1U = 0, index2U = 0;
684 Standard_Integer FromU1 = uknots->Lower();
685 Standard_Integer ToU2 = uknots->Upper();
686 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
687 NewU1,uperiodic,FromU1,ToU2,index1U,U);
688 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
689 NewU1 + deltaU,uperiodic,FromU1,ToU2,index2U,U);
690 if ( Abs(uknots->Value(index2U+1)-U) <= EpsU)
691 index2U++;
692
693 Standard_Integer nbuknots = index2U - index1U + 1;
694
695 Handle(TColStd_HArray1OfReal)
696 nuknots = new TColStd_HArray1OfReal(1,nbuknots);
697 Handle(TColStd_HArray1OfInteger)
698 numults = new TColStd_HArray1OfInteger(1,nbuknots);
699
700 Standard_Integer i , k = 1;
701 for ( i = index1U; i<= index2U; i++) {
702 nuknots->SetValue(k, uknots->Value(i));
703 numults->SetValue(k, umults->Value(i));
704 k++;
705 }
706 numults->SetValue( 1, udeg + 1);
707 numults->SetValue(nbuknots, udeg + 1);
708
709
710 if (vperiodic) { // set the origine at NewV1
711 Standard_Integer index = 0;
712 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
713 V1,vperiodic,vknots->Lower(),vknots->Upper(),
714 index,V);
715 if ( Abs(vknots->Value(index+1)-V) <= EpsV)
716 index++;
717 SetVOrigin(index);
718 SetVNotPeriodic();
719 }
720
721 // compute index1 and index2 to set the new knots and mults
722 Standard_Integer index1V = 0, index2V = 0;
723 Standard_Integer FromV1 = vknots->Lower();
724 Standard_Integer ToV2 = vknots->Upper();
725 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
726 NewV1,vperiodic,FromV1,ToV2,index1V,V);
727 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
728 NewV1 + deltaV,vperiodic,FromV1,ToV2,index2V,V);
729 if ( Abs(vknots->Value(index2V+1)-V) <= EpsV)
730 index2V++;
731
732 Standard_Integer nbvknots = index2V - index1V + 1;
733
734 Handle(TColStd_HArray1OfReal)
735 nvknots = new TColStd_HArray1OfReal(1,nbvknots);
736 Handle(TColStd_HArray1OfInteger)
737 nvmults = new TColStd_HArray1OfInteger(1,nbvknots);
738
739 k = 1;
740 for ( i = index1V; i<= index2V; i++) {
741 nvknots->SetValue(k, vknots->Value(i));
742 nvmults->SetValue(k, vmults->Value(i));
743 k++;
744 }
745 nvmults->SetValue( 1, vdeg + 1);
746 nvmults->SetValue(nbvknots, vdeg + 1);
747
748
749 // compute index1 and index2 to set the new poles and weights
750 Standard_Integer pindex1U
751 = BSplCLib::PoleIndex(udeg,index1U,uperiodic,umults->Array1());
752 Standard_Integer pindex2U
753 = BSplCLib::PoleIndex(udeg,index2U,uperiodic,umults->Array1());
754
755 pindex1U++;
756 pindex2U = Min( pindex2U+1, poles->ColLength());
757
758 Standard_Integer nbupoles = pindex2U - pindex1U + 1;
759
760 // compute index1 and index2 to set the new poles and weights
761 Standard_Integer pindex1V
762 = BSplCLib::PoleIndex(vdeg,index1V,vperiodic,vmults->Array1());
763 Standard_Integer pindex2V
764 = BSplCLib::PoleIndex(vdeg,index2V,vperiodic,vmults->Array1());
765
766 pindex1V++;
767 pindex2V = Min( pindex2V+1, poles->RowLength());
768
769 Standard_Integer nbvpoles = pindex2V - pindex1V + 1;
770
771
772 Handle(TColStd_HArray2OfReal) nweights;
773
774 Handle(TColgp_HArray2OfPnt)
775 npoles = new TColgp_HArray2OfPnt(1,nbupoles,1,nbvpoles);
776
777 k = 1;
778 Standard_Integer j, l;
779 if ( urational || vrational) {
780 nweights = new TColStd_HArray2OfReal( 1,nbupoles,1,nbvpoles);
781 for ( i = pindex1U; i <= pindex2U; i++) {
782 l = 1;
783 for ( j = pindex1V; j <= pindex2V; j++) {
784 npoles->SetValue(k,l, poles->Value(i,j));
785 nweights->SetValue(k,l, weights->Value(i,j));
786 l++;
787 }
788 k++;
789 }
790 }
791 else {
792 for ( i = pindex1U; i <= pindex2U; i++) {
793 l = 1;
794 for ( j = pindex1V; j <= pindex2V; j++) {
795 npoles->SetValue(k,l, poles->Value(i,j));
796 l++;
797 }
798 k++;
799 }
800 }
801
802 uknots = nuknots;
803 umults = numults;
804 vknots = nvknots;
805 vmults = nvmults;
806 poles = npoles;
807 if ( urational || vrational)
808 weights = nweights;
809 else
810 weights = new TColStd_HArray2OfReal (1,poles->ColLength(),
811 1,poles->RowLength(), 1.0);
812
813 maxderivinvok = 0;
814 UpdateUKnots();
815 UpdateVKnots();
816
817}
818
819//=======================================================================
820//function : CheckAndSegment
821//purpose :
822//=======================================================================
823
824void Geom_BSplineSurface::CheckAndSegment(const Standard_Real U1,
825 const Standard_Real U2,
826 const Standard_Real V1,
827 const Standard_Real V2)
828{
829
830 Standard_DomainError_Raise_if ( (U2 < U1) || (V2 < V1),
831 "Geom_BSplineCurve::Segment");
832 Standard_Real deltaU = Max(Abs(U2),Abs(U1));
833 Standard_Real EpsU = Epsilon(deltaU);
834 deltaU = U2 - U1;
835
836 Standard_Real deltaV = Max(Abs(V2),Abs(V1));
837 Standard_Real EpsV = Epsilon(deltaV);
838 deltaV = V2 - V1;
839
840 Standard_Real NewU1, NewU2, NewV1, NewV2;
841 Standard_Real U,V;
842 Standard_Integer indexU, indexV;
843
844 Standard_Boolean segment_in_U = Standard_True;
845 Standard_Boolean segment_in_V = Standard_True;
846 segment_in_U = ( Abs(U1 - uknots->Value(uknots->Lower())) > EpsU )
847 || ( Abs(U2 - uknots->Value(uknots->Upper())) > EpsU );
848 segment_in_V = ( Abs(V1 - vknots->Value(vknots->Lower())) > EpsV )
849 || ( Abs(V2 - vknots->Value(vknots->Upper())) > EpsV );
850
851 indexU = 0;
852 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
853 U1,uperiodic,uknots->Lower(),uknots->Upper(),
854 indexU,NewU1);
855 indexU = 0;
856 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
857 U2,uperiodic,uknots->Lower(),uknots->Upper(),
858 indexU,NewU2);
859 if (segment_in_U) {
860 // inserting the UKnots
861 TColStd_Array1OfReal UKnots(1,2);
862 TColStd_Array1OfInteger UMults(1,2);
863 UKnots( 1) = Min( NewU1, NewU2);
864 UKnots( 2) = Max( NewU1, NewU2);
865 UMults( 1) = UMults( 2) = udeg;
866
867 InsertUKnots( UKnots, UMults, EpsU);
868 }
869
870 indexV = 0;
871 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
872 V1,vperiodic,vknots->Lower(),vknots->Upper(),
873 indexV,NewV1);
874 indexV = 0;
875 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
876 V2,vperiodic,vknots->Lower(),vknots->Upper(),
877 indexV,NewV2);
878 if (segment_in_V) {
879 // Inserting the VKnots
880 TColStd_Array1OfReal VKnots(1,2);
881 TColStd_Array1OfInteger VMults(1,2);
882
883 VKnots( 1) = Min( NewV1, NewV2);
884 VKnots( 2) = Max( NewV1, NewV2);
885 VMults( 1) = VMults( 2) = vdeg;
886 InsertVKnots( VKnots, VMults, EpsV);
887 }
888
889 if (uperiodic && segment_in_U) { // set the origine at NewU1
890 Standard_Integer index = 0;
891 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
892 U1,uperiodic,uknots->Lower(),uknots->Upper(),
893 index,U);
894 if ( Abs(uknots->Value(index+1)-U) <= EpsU)
895 index++;
896 SetUOrigin(index);
897 SetUNotPeriodic();
898 }
899
900 // compute index1 and index2 to set the new knots and mults
901 Standard_Integer index1U = 0, index2U = 0;
902 Standard_Integer FromU1 = uknots->Lower();
903 Standard_Integer ToU2 = uknots->Upper();
904 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
905 NewU1,uperiodic,FromU1,ToU2,index1U,U);
906 BSplCLib::LocateParameter(udeg,uknots->Array1(),umults->Array1(),
907 NewU1 + deltaU,uperiodic,FromU1,ToU2,index2U,U);
908 if ( Abs(uknots->Value(index2U+1)-U) <= EpsU)
909 index2U++;
910
911 Standard_Integer nbuknots = index2U - index1U + 1;
912
913 Handle(TColStd_HArray1OfReal)
914 nuknots = new TColStd_HArray1OfReal(1,nbuknots);
915 Handle(TColStd_HArray1OfInteger)
916 numults = new TColStd_HArray1OfInteger(1,nbuknots);
917
918 Standard_Integer i , k = 1;
919 for ( i = index1U; i<= index2U; i++) {
920 nuknots->SetValue(k, uknots->Value(i));
921 numults->SetValue(k, umults->Value(i));
922 k++;
923 }
924 if (segment_in_U) {
925 numults->SetValue( 1, udeg + 1);
926 numults->SetValue(nbuknots, udeg + 1);
927 }
928
929 if (vperiodic&& segment_in_V) { // set the origine at NewV1
930 Standard_Integer index = 0;
931 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
932 V1,vperiodic,vknots->Lower(),vknots->Upper(),
933 index,V);
934 if ( Abs(vknots->Value(index+1)-V) <= EpsV)
935 index++;
936 SetVOrigin(index);
937 SetVNotPeriodic();
938 }
939
940 // compute index1 and index2 to set the new knots and mults
941 Standard_Integer index1V = 0, index2V = 0;
942 Standard_Integer FromV1 = vknots->Lower();
943 Standard_Integer ToV2 = vknots->Upper();
944 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
945 NewV1,vperiodic,FromV1,ToV2,index1V,V);
946 BSplCLib::LocateParameter(vdeg,vknots->Array1(),vmults->Array1(),
947 NewV1 + deltaV,vperiodic,FromV1,ToV2,index2V,V);
948 if ( Abs(vknots->Value(index2V+1)-V) <= EpsV)
949 index2V++;
950
951 Standard_Integer nbvknots = index2V - index1V + 1;
952
953 Handle(TColStd_HArray1OfReal)
954 nvknots = new TColStd_HArray1OfReal(1,nbvknots);
955 Handle(TColStd_HArray1OfInteger)
956 nvmults = new TColStd_HArray1OfInteger(1,nbvknots);
957
958 k = 1;
959 for ( i = index1V; i<= index2V; i++) {
960 nvknots->SetValue(k, vknots->Value(i));
961 nvmults->SetValue(k, vmults->Value(i));
962 k++;
963 }
964 if (segment_in_V) {
965 nvmults->SetValue( 1, vdeg + 1);
966 nvmults->SetValue(nbvknots, vdeg + 1);
967 }
968
969 // compute index1 and index2 to set the new poles and weights
970 Standard_Integer pindex1U
971 = BSplCLib::PoleIndex(udeg,index1U,uperiodic,umults->Array1());
972 Standard_Integer pindex2U
973 = BSplCLib::PoleIndex(udeg,index2U,uperiodic,umults->Array1());
974
975 pindex1U++;
976 pindex2U = Min( pindex2U+1, poles->ColLength());
977
978 Standard_Integer nbupoles = pindex2U - pindex1U + 1;
979
980 // compute index1 and index2 to set the new poles and weights
981 Standard_Integer pindex1V
982 = BSplCLib::PoleIndex(vdeg,index1V,vperiodic,vmults->Array1());
983 Standard_Integer pindex2V
984 = BSplCLib::PoleIndex(vdeg,index2V,vperiodic,vmults->Array1());
985
986 pindex1V++;
987 pindex2V = Min( pindex2V+1, poles->RowLength());
988
989 Standard_Integer nbvpoles = pindex2V - pindex1V + 1;
990
991
992 Handle(TColStd_HArray2OfReal) nweights;
993
994 Handle(TColgp_HArray2OfPnt)
995 npoles = new TColgp_HArray2OfPnt(1,nbupoles,1,nbvpoles);
996
997 k = 1;
998 Standard_Integer j, l;
999 if ( urational || vrational) {
1000 nweights = new TColStd_HArray2OfReal( 1,nbupoles,1,nbvpoles);
1001 for ( i = pindex1U; i <= pindex2U; i++) {
1002 l = 1;
1003 for ( j = pindex1V; j <= pindex2V; j++) {
1004 npoles->SetValue(k,l, poles->Value(i,j));
1005 nweights->SetValue(k,l, weights->Value(i,j));
1006 l++;
1007 }
1008 k++;
1009 }
1010 }
1011 else {
1012 for ( i = pindex1U; i <= pindex2U; i++) {
1013 l = 1;
1014 for ( j = pindex1V; j <= pindex2V; j++) {
1015 npoles->SetValue(k,l, poles->Value(i,j));
1016 l++;
1017 }
1018 k++;
1019 }
1020 }
1021
1022 uknots = nuknots;
1023 umults = numults;
1024 vknots = nvknots;
1025 vmults = nvmults;
1026 poles = npoles;
1027 if ( urational || vrational)
1028 weights = nweights;
1029 else
1030 weights = new TColStd_HArray2OfReal (1,poles->ColLength(),
1031 1,poles->RowLength(), 1.0);
1032
1033 maxderivinvok = 0;
1034 UpdateUKnots();
1035 UpdateVKnots();
1036
1037}
1038
1039//=======================================================================
1040//function : SetUKnot
1041//purpose :
1042//=======================================================================
1043
1044void Geom_BSplineSurface::SetUKnot
1045(const Standard_Integer UIndex,
1046 const Standard_Real K )
1047{
1048 if (UIndex < 1 || UIndex > uknots->Length()) Standard_OutOfRange::Raise();
1049
1050 Standard_Integer NewIndex = UIndex;
1051 Standard_Real DU = Abs(Epsilon (K));
1052 if (UIndex == 1) {
1053 if (K >= uknots->Value (2) - DU) Standard_ConstructionError::Raise();
1054 }
1055 else if (UIndex == uknots->Length()) {
1056 if (K <= uknots->Value (uknots->Length()-1) + DU) {
1057 Standard_ConstructionError::Raise();
1058 }
1059 }
1060 else {
1061 if (K <= uknots->Value (NewIndex-1) + DU ||
1062 K >= uknots->Value (NewIndex+1) - DU ) {
1063 Standard_ConstructionError::Raise();
1064 }
1065 }
1066
1067 if (K != uknots->Value (NewIndex)) {
1068 uknots->SetValue (NewIndex, K);
1069 maxderivinvok = 0;
1070 UpdateUKnots();
1071 }
1072}
1073
1074//=======================================================================
1075//function : SetUKnots
1076//purpose :
1077//=======================================================================
1078
1079void Geom_BSplineSurface::SetUKnots (const TColStd_Array1OfReal& UK) {
1080
1081 Standard_Integer Lower = UK.Lower();
1082 Standard_Integer Upper = UK.Upper();
1083 if (Lower < 1 || Lower > uknots->Length() ||
1084 Upper < 1 || Upper > uknots->Length() ) {
1085 Standard_OutOfRange::Raise();
1086 }
1087 Standard_Real Eps;
1088 if (Lower > 1) {
1089 Eps = Abs (Epsilon (uknots->Value (Lower-1)));
1090 if (Abs (UK (Lower) - uknots->Value (Lower-1)) <= gp::Resolution()) {
1091 Standard_ConstructionError::Raise();
1092 }
1093 }
1094 if (Upper < uknots->Length ()) {
1095 Eps = Abs (Epsilon (uknots->Value (Upper+1)));
1096 if (Abs (UK (Upper) - uknots->Value (Upper+1)) <= gp::Resolution()) {
1097 Standard_ConstructionError::Raise();
1098 }
1099 }
1100 Standard_Real K1 = UK (Lower);
1101 for (Standard_Integer i = Lower; i <= Upper; i++) {
1102 uknots->SetValue (i, UK(i));
1103 if (i != Lower) {
1104 Eps = Abs (Epsilon (K1));
1105 if (Abs (UK(i) - K1) <= gp::Resolution()) {
1106 Standard_ConstructionError::Raise();
1107 }
1108 K1 = UK (i);
1109 }
1110 }
1111
1112 maxderivinvok = 0;
1113 UpdateUKnots();
1114}
1115
1116//=======================================================================
1117//function : SetUKnot
1118//purpose :
1119//=======================================================================
1120
1121void Geom_BSplineSurface::SetUKnot
1122(const Standard_Integer UIndex,
1123 const Standard_Real K,
1124 const Standard_Integer M)
1125{
1126 IncreaseUMultiplicity (UIndex, M);
1127 SetUKnot (UIndex, K);
1128}
1129
1130//=======================================================================
1131//function : SetVKnot
1132//purpose :
1133//=======================================================================
1134
1135void Geom_BSplineSurface::SetVKnot
1136(const Standard_Integer VIndex,
1137 const Standard_Real K)
1138{
1139 if (VIndex < 1 || VIndex > vknots->Length()) Standard_OutOfRange::Raise();
1140 Standard_Integer NewIndex = VIndex + vknots->Lower() - 1;
1141 Standard_Real DV = Abs(Epsilon (K));
1142 if (VIndex == 1) {
1143 if (K >= vknots->Value (2) - DV) {
1144 Standard_ConstructionError::Raise();
1145 }
1146 }
1147 else if (VIndex == vknots->Length()) {
1148 if (K <= vknots->Value (vknots->Length()-1) + DV) {
1149 Standard_ConstructionError::Raise();
1150 }
1151 }
1152 else {
1153 if (K <= vknots->Value (NewIndex-1) + DV ||
1154 K >= vknots->Value (NewIndex+1) - DV ) {
1155 Standard_ConstructionError::Raise();
1156 }
1157 }
1158
1159 maxderivinvok = 0;
1160 UpdateVKnots();
1161}
1162
1163//=======================================================================
1164//function : SetVKnots
1165//purpose :
1166//=======================================================================
1167
1168void Geom_BSplineSurface::SetVKnots (const TColStd_Array1OfReal& VK) {
1169
1170 Standard_Integer Lower = VK.Lower();
1171 Standard_Integer Upper = VK.Upper();
1172 if (Lower < 1 || Lower > vknots->Length() ||
1173 Upper < 1 || Upper > vknots->Length() ) {
1174 Standard_OutOfRange::Raise();
1175 }
1176 Standard_Real Eps;
1177 if (Lower > 1) {
1178 Eps = Abs (Epsilon (vknots->Value (Lower-1)));
1179 if (Abs (VK (Lower) - vknots->Value (Lower-1)) <= gp::Resolution()) {
1180 Standard_ConstructionError::Raise();
1181 }
1182 }
1183 if (Upper < vknots->Length ()) {
1184 Eps = Abs (Epsilon (vknots->Value (Upper+1)));
1185 if (Abs (VK (Upper) - vknots->Value (Upper+1)) <= gp::Resolution()) {
1186 Standard_ConstructionError::Raise();
1187 }
1188 }
1189 Standard_Real K1 = VK (Lower);
1190 for (Standard_Integer i = Lower; i <= Upper; i++) {
1191 vknots->SetValue (i, VK(i));
1192 if (i != Lower) {
1193 Eps = Abs (Epsilon (K1));
1194 if (Abs (VK(i) - K1) <= gp::Resolution()) {
1195 Standard_ConstructionError::Raise();
1196 }
1197 K1 = VK (i);
1198 }
1199 }
1200
1201 maxderivinvok = 0;
1202 UpdateVKnots();
1203}
1204
1205//=======================================================================
1206//function : SetVKnot
1207//purpose :
1208//=======================================================================
1209
1210void Geom_BSplineSurface::SetVKnot
1211(const Standard_Integer VIndex,
1212 const Standard_Real K,
1213 const Standard_Integer M)
1214{
1215 IncreaseVMultiplicity (VIndex, M);
1216 SetVKnot (VIndex, K);
1217}
1218
1219//=======================================================================
1220//function : InsertUKnot
1221//purpose :
1222//=======================================================================
1223
1224void Geom_BSplineSurface::InsertUKnot
1225(const Standard_Real U,
1226 const Standard_Integer M,
1227 const Standard_Real ParametricTolerance,
1228 const Standard_Boolean Add)
1229{
1230 TColStd_Array1OfReal k(1,1);
1231 k(1) = U;
1232 TColStd_Array1OfInteger m(1,1);
1233 m(1) = M;
1234 InsertUKnots(k,m,ParametricTolerance,Add);
1235}
1236
1237//=======================================================================
1238//function : InsertVKnot
1239//purpose :
1240//=======================================================================
1241
1242void Geom_BSplineSurface::InsertVKnot
1243(const Standard_Real V,
1244 const Standard_Integer M,
1245 const Standard_Real ParametricTolerance,
1246 const Standard_Boolean Add)
1247{
1248 TColStd_Array1OfReal k(1,1);
1249 k(1) = V;
1250 TColStd_Array1OfInteger m(1,1);
1251 m(1) = M;
1252 InsertVKnots(k,m,ParametricTolerance,Add);
1253}
1254
1255//=======================================================================
1256//function : IncrementUMultiplicity
1257//purpose :
1258//=======================================================================
1259
1260void Geom_BSplineSurface::IncrementUMultiplicity
1261(const Standard_Integer FromI1,
1262 const Standard_Integer ToI2,
1263 const Standard_Integer Step)
1264{
1265 Handle(TColStd_HArray1OfReal) tk = uknots;
1266 TColStd_Array1OfReal k( (uknots->Array1())(FromI1), FromI1, ToI2);
1267 TColStd_Array1OfInteger m( FromI1, ToI2) ;
1268 m.Init(Step);
1269 InsertUKnots( k, m, Epsilon(1.));
1270}
1271
1272//=======================================================================
1273//function : IncrementVMultiplicity
1274//purpose :
1275//=======================================================================
1276
1277void Geom_BSplineSurface::IncrementVMultiplicity
1278(const Standard_Integer FromI1,
1279 const Standard_Integer ToI2,
1280 const Standard_Integer Step)
1281{
1282 Handle(TColStd_HArray1OfReal) tk = vknots;
1283 TColStd_Array1OfReal k( (vknots->Array1())(FromI1), FromI1, ToI2);
1284
1285 TColStd_Array1OfInteger m( FromI1, ToI2) ;
1286 m.Init(Step);
1287
1288 InsertVKnots( k, m, Epsilon(1.));
1289}
1290
1291//=======================================================================
1292//function : UpdateUKnots
1293//purpose :
1294//=======================================================================
1295
1296void Geom_BSplineSurface::UpdateUKnots()
1297{
1298
1299 Standard_Integer MaxKnotMult = 0;
1300 KnotAnalysis (udeg,
1301 uknots->Array1(),
1302 umults->Array1(),
1303 uknotSet, MaxKnotMult);
1304
1305 if (uknotSet == GeomAbs_Uniform && !uperiodic) {
1306 ufknots = uknots;
1307 }
1308 else {
1309 ufknots = new TColStd_HArray1OfReal
1310 (1, BSplCLib::KnotSequenceLength(umults->Array1(),udeg,uperiodic));
1311
1312 BSplCLib::KnotSequence (uknots->Array1(),
1313 umults->Array1(),
1314 udeg,uperiodic,
1315 ufknots->ChangeArray1());
1316 }
1317
1318 if (MaxKnotMult == 0) Usmooth = GeomAbs_CN;
1319 else {
1320 switch (udeg - MaxKnotMult) {
1321 case 0 : Usmooth = GeomAbs_C0; break;
1322 case 1 : Usmooth = GeomAbs_C1; break;
1323 case 2 : Usmooth = GeomAbs_C2; break;
1324 case 3 : Usmooth = GeomAbs_C3; break;
1325 default : Usmooth = GeomAbs_C3; break;
1326 }
1327 }
1328
1329 InvalidateCache() ;
1330}
1331
1332//=======================================================================
1333//function : UpdateVKnots
1334//purpose :
1335//=======================================================================
1336
1337void Geom_BSplineSurface::UpdateVKnots()
1338{
1339 Standard_Integer MaxKnotMult = 0;
1340 KnotAnalysis (vdeg,
1341 vknots->Array1(),
1342 vmults->Array1(),
1343 vknotSet, MaxKnotMult);
1344
1345 if (vknotSet == GeomAbs_Uniform && !vperiodic) {
1346 vfknots = vknots;
1347 }
1348 else {
1349 vfknots = new TColStd_HArray1OfReal
1350 (1, BSplCLib::KnotSequenceLength(vmults->Array1(),vdeg,vperiodic));
1351
1352 BSplCLib::KnotSequence (vknots->Array1(),
1353 vmults->Array1(),
1354 vdeg,vperiodic,
1355 vfknots->ChangeArray1());
1356 }
1357
1358 if (MaxKnotMult == 0) Vsmooth = GeomAbs_CN;
1359 else {
1360 switch (vdeg - MaxKnotMult) {
1361 case 0 : Vsmooth = GeomAbs_C0; break;
1362 case 1 : Vsmooth = GeomAbs_C1; break;
1363 case 2 : Vsmooth = GeomAbs_C2; break;
1364 case 3 : Vsmooth = GeomAbs_C3; break;
1365 default : Vsmooth = GeomAbs_C3; break;
1366 }
1367 }
1368 InvalidateCache() ;
1369}
1370
1371//=======================================================================
1372//function : InvalidateCache
1373//purpose : Invalidates the Cache of the surface
1374//=======================================================================
1375
1376void Geom_BSplineSurface::InvalidateCache()
1377{
1378 validcache = 0 ;
1379}
1380
1381//=======================================================================
1382//function : Normalizes the parameters if the curve is periodic
1383//purpose : that is compute the cache so that it is valid
1384//=======================================================================
1385
1386void Geom_BSplineSurface::PeriodicNormalization
1387(Standard_Real& Uparameter,
1388 Standard_Real& Vparameter) const
1389{
1390 Standard_Real Period, aMaxVal, aMinVal;
1391
1392 if (uperiodic) {
1393 aMaxVal = ufknots->Value(ufknots->Upper() - udeg);
1394 aMinVal = ufknots->Value (udeg + 1);
1395 Standard_Real eps = Abs(Epsilon(Uparameter));
1396 Period = aMaxVal - aMinVal;
1397
1398 if(Period <= eps)
1399 Standard_OutOfRange::Raise("Geom_BSplineSurface::PeriodicNormalization: Uparameter is too great number");
1400
1401 while (Uparameter > aMaxVal) {
1402 Uparameter -= Period ;
1403 }
1404
1405 while (Uparameter < aMinVal) {
1406 Uparameter += Period ;
1407 }
1408 }
1409 if (vperiodic) {
1410 aMaxVal = vfknots->Value(vfknots->Upper() - vdeg);
1411 aMinVal = vfknots->Value (vdeg + 1);
1412 Standard_Real eps = Abs(Epsilon(Vparameter));
1413 Period = aMaxVal - aMinVal;
1414
1415 if(Period <= eps)
1416 Standard_OutOfRange::Raise("Geom_BSplineSurface::PeriodicNormalization: Vparameter is too great number");
1417
1418 while (Vparameter > aMaxVal) {
1419 Vparameter -= Period ;
1420 }
1421 while (Vparameter < aMinVal) {
1422 Vparameter += Period ;
1423 }
1424 }
1425}
1426
1427//=======================================================================
1428//function : ValidateCache
1429//purpose : function that validates the cache of the surface
1430//=======================================================================
1431
1432void Geom_BSplineSurface::ValidateCache(const Standard_Real Uparameter,
1433 const Standard_Real Vparameter)
1434{
1435 Standard_Real NewParameter ;
1436 Standard_Integer LocalIndex = 0 ;
1437 Standard_Integer MinDegree,
1438 MaxDegree ;
1439 //
1440 // check if the degree did not change
1441 //
1442
1443 MinDegree = Min(udeg,vdeg) ;
1444 MaxDegree = Max(udeg,vdeg) ;
1445 if (cachepoles->ColLength() < MaxDegree + 1 ||
1446 cachepoles->RowLength() < MinDegree + 1) {
1447 cachepoles = new TColgp_HArray2OfPnt(1,MaxDegree + 1,
1448 1,MinDegree + 1);
1449 }
1450 //
1451 // Verif + poussee pour les poids
1452 //
1453 if (urational || vrational) {
1454 if (cacheweights.IsNull()) {
1455 cacheweights = new TColStd_HArray2OfReal(1,MaxDegree + 1,
1456 1,MinDegree + 1);
1457 }
1458 else {
1459 if (cacheweights->ColLength() < MaxDegree + 1 ||
1460 cacheweights->RowLength() < MinDegree + 1) {
1461 cacheweights = new TColStd_HArray2OfReal(1,MaxDegree + 1,
1462 1,MinDegree + 1);
1463 }
1464 }
1465 }
1466
1467 BSplCLib::LocateParameter(udeg,
1468 (ufknots->Array1()),
1469 (BSplCLib::NoMults()),
1470 Uparameter,
1471 uperiodic,
1472 LocalIndex,
1473 NewParameter);
1474 ucachespanindex = LocalIndex ;
1475 if (Uparameter == ufknots->Value(LocalIndex + 1)) {
1476
1477 LocalIndex += 1 ;
1478 ucacheparameter = ufknots->Value(LocalIndex) ;
1479 if (LocalIndex == ufknots->Upper() - udeg) {
1480 //
1481 // for the last span if the parameter is outside of
1482 // the domain of the curve than use the last knot
1483 // and normalize with the last span Still set the
1484 // cachespanindex to flatknots->Upper() - deg so that
1485 // the IsCacheValid will know for sure we are extending
1486 // the Bspline
1487 //
1488
1489 ucachespanlenght = ufknots->Value(LocalIndex - 1) - ucacheparameter ;
1490 }
1491 else {
1492 ucachespanlenght = ufknots->Value(LocalIndex + 1) - ucacheparameter ;
1493 }
1494 }
1495 else {
1496 ucacheparameter = ufknots->Value(LocalIndex) ;
1497 ucachespanlenght = ufknots->Value(LocalIndex + 1) - ucacheparameter ;
1498 }
1499
1500 LocalIndex = 0 ;
1501 BSplCLib::LocateParameter(vdeg,
1502 (vfknots->Array1()),
1503 (BSplCLib::NoMults()),
1504 Vparameter,
1505 vperiodic,
1506 LocalIndex,
1507 NewParameter);
1508 vcachespanindex = LocalIndex ;
1509 if (Vparameter == vfknots->Value(LocalIndex + 1)) {
1510 LocalIndex += 1 ;
1511 vcacheparameter = vfknots->Value(LocalIndex) ;
1512 if (LocalIndex == vfknots->Upper() - vdeg) {
1513 //
1514 // for the last span if the parameter is outside of
1515 // the domain of the curve than use the last knot
1516 // and normalize with the last span Still set the
1517 // cachespanindex to flatknots->Upper() - deg so that
1518 // the IsCacheValid will know for sure we are extending
1519 // the Bspline
1520 //
1521
1522 vcachespanlenght = vfknots->Value(LocalIndex - 1) - vcacheparameter ;
1523 }
1524 else {
1525 vcachespanlenght = vfknots->Value(LocalIndex + 1) - vcacheparameter ;
1526 }
1527 }
1528 else {
1529 vcacheparameter = vfknots->Value(LocalIndex) ;
1530 vcachespanlenght = vfknots->Value(LocalIndex + 1) - vcacheparameter ;
1531 }
1532
1533 Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
1534 uspanlenght_11 = ucachespanlenght/2,
1535 vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
1536 vspanlenght_11 = vcachespanlenght/2 ;
1537 if (urational || vrational) {
1538 BSplSLib::BuildCache(uparameter_11,
1539 vparameter_11,
1540 uspanlenght_11,
1541 vspanlenght_11,
1542 uperiodic,
1543 vperiodic,
1544 udeg,
1545 vdeg,
1546 ucachespanindex,
1547 vcachespanindex,
1548 (ufknots->Array1()),
1549 (vfknots->Array1()),
1550 poles->Array2(),
1551 weights->Array2(),
1552 cachepoles->ChangeArray2(),
1553 cacheweights->ChangeArray2()) ;
1554 }
1555 else {
1556 BSplSLib::BuildCache(uparameter_11,
1557 vparameter_11,
1558 uspanlenght_11,
1559 vspanlenght_11,
1560 uperiodic,
1561 vperiodic,
1562 udeg,
1563 vdeg,
1564 ucachespanindex,
1565 vcachespanindex,
1566 (ufknots->Array1()),
1567 (vfknots->Array1()),
1568 poles->Array2(),
1569 *((TColStd_Array2OfReal*) NULL),
1570 cachepoles->ChangeArray2(),
1571 *((TColStd_Array2OfReal*) NULL)) ;
1572 }
1573 validcache = 1 ;
1574}
1575
1576//=======================================================================
1577//function : IsCacheValid
1578//purpose : function that checks for the validity of the cache of the
1579// surface
1580//=======================================================================
1581Standard_Boolean Geom_BSplineSurface::IsCacheValid
1582(const Standard_Real U,
1583 const Standard_Real V) const
1584{
1585 //Roman Lygin 26.12.08, see comments in Geom_BSplineCurve::IsCacheValid()
1586 Standard_Real aDeltaU = U - ucacheparameter;
1587 Standard_Real aDeltaV = V - vcacheparameter;
1588
1589 return ( validcache &&
1590 (aDeltaU >= 0.0e0) &&
1591 ((aDeltaU < ucachespanlenght) || (ucachespanindex == ufknots->Upper() - udeg)) &&
1592 (aDeltaV >= 0.0e0) &&
1593 ((aDeltaV < vcachespanlenght) || (vcachespanindex == vfknots->Upper() - vdeg)) );
1594}
1595
1596//=======================================================================
1597//function : SetWeight
1598//purpose :
1599//=======================================================================
1600
1601void Geom_BSplineSurface::SetWeight (const Standard_Integer UIndex,
1602 const Standard_Integer VIndex,
1603 const Standard_Real Weight)
1604{
1605 if (Weight <= gp::Resolution()) Standard_ConstructionError::Raise();
1606 TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1607 if (UIndex < 1 || UIndex > Weights.ColLength() ||
1608 VIndex < 1 || VIndex > Weights.RowLength() ) {
1609 Standard_OutOfRange::Raise();
1610 }
1611 Weights (UIndex+Weights.LowerRow()-1, VIndex+Weights.LowerCol()-1) = Weight;
1612 Rational(Weights, urational, vrational);
1613 InvalidateCache();
1614}
1615
1616//=======================================================================
1617//function : SetWeightCol
1618//purpose :
1619//=======================================================================
1620
1621void Geom_BSplineSurface::SetWeightCol
1622(const Standard_Integer VIndex,
1623 const TColStd_Array1OfReal& CPoleWeights)
1624{
1625 TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1626 if (VIndex < 1 || VIndex > Weights.RowLength()) {
1627 Standard_OutOfRange::Raise();
1628 }
1629 if (CPoleWeights.Lower() < 1 ||
1630 CPoleWeights.Lower() > Weights.ColLength() ||
1631 CPoleWeights.Upper() < 1 ||
1632 CPoleWeights.Upper() > Weights.ColLength() ) {
1633 Standard_ConstructionError::Raise();
1634 }
1635 Standard_Integer I = CPoleWeights.Lower();
1636 while (I <= CPoleWeights.Upper()) {
1637 if (CPoleWeights(I) <= gp::Resolution()) {
1638 Standard_ConstructionError::Raise();
1639 }
1640 Weights (I+Weights.LowerRow()-1, VIndex+Weights.LowerCol()-1) =
1641 CPoleWeights (I);
1642 I++;
1643 }
1644 // Verifie si c'est rationnel
1645 Rational(Weights, urational, vrational);
1646
1647 InvalidateCache();
1648}
1649
1650//=======================================================================
1651//function : SetWeightRow
1652//purpose :
1653//=======================================================================
1654
1655void Geom_BSplineSurface::SetWeightRow
1656(const Standard_Integer UIndex,
1657 const TColStd_Array1OfReal& CPoleWeights)
1658{
1659 TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1660 if (UIndex < 1 || UIndex > Weights.ColLength()) {
1661 Standard_OutOfRange::Raise();
1662 }
1663 if (CPoleWeights.Lower() < 1 ||
1664 CPoleWeights.Lower() > Weights.RowLength() ||
1665 CPoleWeights.Upper() < 1 ||
1666 CPoleWeights.Upper() > Weights.RowLength() ) {
1667
1668 Standard_ConstructionError::Raise();
1669 }
1670 Standard_Integer I = CPoleWeights.Lower();
1671
1672 while (I <= CPoleWeights.Upper()) {
1673 if (CPoleWeights(I)<=gp::Resolution()) {
1674 Standard_ConstructionError::Raise();
1675 }
1676 Weights (UIndex+Weights.LowerRow()-1, I+Weights.LowerCol()-1) =
1677 CPoleWeights (I);
1678 I++;
1679 }
1680 // Verifie si c'est rationnel
1681 Rational(Weights, urational, vrational);
1682 InvalidateCache();
1683}
1684