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