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