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