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. |
7fd59977 |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
b311480e |
16 | |
7fd59977 |
17 | // xab : 30-Mar-95 introduced cache mechanism for surfaces |
18 | // xab : 21-Jun-95 in remove knots sync size of weights and poles |
19 | // pmn : 28-Jun-96 Distinction entre la continuite en U et V (bug PRO4625) |
20 | // pmn : 07-Jan-97 Centralisation des verif rational (PRO6834) |
21 | // et ajout des InvalideCache() dans les SetPole* (PRO6833) |
22 | // pmn : 03-Feb-97 Prise en compte de la periode dans Locate(U/V) (PRO6963) |
23 | // + bon appel a LocateParameter (PRO6973). |
24 | // RBD : 15/10/98 ; Le cache est desormais defini sur [-1,1] (pro15537). |
7fd59977 |
25 | |
26 | #define No_Standard_OutOfRange |
27 | #define No_Standard_DimensionError |
28 | |
29 | #include <Geom_BSplineSurface.jxx> |
30 | |
31 | #include <gp.hxx> |
32 | #include <BSplSLib.hxx> |
33 | #include <BSplCLib.hxx> |
34 | #include <Precision.hxx> |
35 | #include <TColgp_Array1OfXYZ.hxx> |
36 | |
37 | #include <Geom_BSplineCurve.hxx> |
38 | |
39 | #include <Geom_UndefinedDerivative.hxx> |
40 | #include <Standard_OutOfRange.hxx> |
41 | #include <Standard_RangeError.hxx> |
42 | #include <Standard_DomainError.hxx> |
43 | #include <Standard_DimensionError.hxx> |
44 | #include <Standard_ConstructionError.hxx> |
45 | #include <Standard_NotImplemented.hxx> |
83ada95b |
46 | #include <Standard_Mutex.hxx> |
7fd59977 |
47 | |
48 | #define POLES (poles->Array2()) |
49 | #define WEIGHTS (weights->Array2()) |
50 | #define UKNOTS (uknots->Array1()) |
51 | #define VKNOTS (vknots->Array1()) |
52 | #define UFKNOTS (ufknots->Array1()) |
53 | #define VFKNOTS (vfknots->Array1()) |
54 | #define FMULTS (BSplCLib::NoMults()) |
55 | |
56 | //======================================================================= |
57 | //function : IsCNu |
58 | //purpose : |
59 | //======================================================================= |
60 | |
61 | Standard_Boolean Geom_BSplineSurface::IsCNu |
62 | (const Standard_Integer N) const |
63 | { |
64 | Standard_RangeError_Raise_if (N < 0, " "); |
65 | switch (Usmooth) { |
66 | case GeomAbs_CN : return Standard_True; |
67 | case GeomAbs_C0 : return N <= 0; |
68 | case GeomAbs_G1 : return N <= 0; |
69 | case GeomAbs_C1 : return N <= 1; |
70 | case GeomAbs_G2 : return N <= 1; |
71 | case GeomAbs_C2 : return N <= 2; |
72 | case GeomAbs_C3 : |
73 | return N <= 3 ? Standard_True : |
74 | N <= udeg - BSplCLib::MaxKnotMult (umults->Array1(), umults->Lower() + 1, umults->Upper() - 1); |
75 | default: |
76 | return Standard_False; |
77 | } |
78 | } |
79 | |
80 | //======================================================================= |
81 | //function : IsCNv |
82 | //purpose : |
83 | //======================================================================= |
84 | |
85 | Standard_Boolean Geom_BSplineSurface::IsCNv |
86 | (const Standard_Integer N) const |
87 | { |
88 | Standard_RangeError_Raise_if (N < 0, " "); |
89 | |
90 | switch (Vsmooth) { |
91 | case GeomAbs_CN : return Standard_True; |
92 | case GeomAbs_C0 : return N <= 0; |
93 | case GeomAbs_G1 : return N <= 0; |
94 | case GeomAbs_C1 : return N <= 1; |
95 | case GeomAbs_G2 : return N <= 1; |
96 | case GeomAbs_C2 : return N <= 2; |
97 | case GeomAbs_C3 : |
98 | return N <= 3 ? Standard_True : |
99 | N <= vdeg - BSplCLib::MaxKnotMult (vmults->Array1(), vmults->Lower() + 1, vmults->Upper() - 1); |
100 | default: |
101 | return Standard_False; |
102 | } |
103 | } |
104 | |
105 | //======================================================================= |
106 | //function : D0 |
107 | //purpose : |
108 | //======================================================================= |
109 | |
83ada95b |
110 | void Geom_BSplineSurface::D0(const Standard_Real U, |
111 | const Standard_Real V, |
112 | gp_Pnt& P) const |
7fd59977 |
113 | { |
83ada95b |
114 | Standard_Real new_u(U), new_v(V); |
115 | PeriodicNormalization(new_u, new_v); |
116 | |
117 | Geom_BSplineSurface* MySurface = (Geom_BSplineSurface *) this; |
118 | Standard_Mutex::Sentry aSentry(MySurface->myMutex); |
119 | |
120 | if(!IsCacheValid(new_u, new_v)) |
121 | MySurface->ValidateCache(new_u, new_v); |
122 | |
7fd59977 |
123 | Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2, |
124 | uspanlenght_11 = ucachespanlenght/2, |
125 | vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2, |
126 | vspanlenght_11 = vcachespanlenght/2 ; |
127 | if (cacheweights.IsNull()) { |
128 | |
129 | BSplSLib::CacheD0(new_u, |
130 | new_v, |
131 | udeg, |
132 | vdeg, |
133 | uparameter_11, |
134 | vparameter_11, |
135 | uspanlenght_11, |
136 | vspanlenght_11, |
137 | cachepoles->Array2(), |
138 | *((TColStd_Array2OfReal*) NULL), |
139 | P) ; |
140 | } |
141 | else { |
142 | BSplSLib::CacheD0(new_u, |
143 | new_v, |
144 | udeg, |
145 | vdeg, |
146 | uparameter_11, |
147 | vparameter_11, |
148 | uspanlenght_11, |
149 | vspanlenght_11, |
150 | cachepoles->Array2(), |
151 | cacheweights->Array2(), |
152 | P) ; |
153 | } |
154 | } |
155 | |
156 | //======================================================================= |
157 | //function : D1 |
158 | //purpose : |
159 | //======================================================================= |
160 | |
83ada95b |
161 | void Geom_BSplineSurface::D1(const Standard_Real U, |
162 | const Standard_Real V, |
163 | gp_Pnt& P, |
164 | gp_Vec& D1U, |
165 | gp_Vec& D1V) const |
7fd59977 |
166 | { |
83ada95b |
167 | Standard_Real new_u(U), new_v(V); |
168 | PeriodicNormalization(new_u, new_v); |
169 | |
170 | Geom_BSplineSurface* MySurface = (Geom_BSplineSurface *) this; |
171 | Standard_Mutex::Sentry aSentry(MySurface->myMutex); |
172 | |
173 | if(!IsCacheValid(new_u, new_v)) |
174 | MySurface->ValidateCache(new_u, new_v); |
7fd59977 |
175 | |
176 | Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2, |
177 | uspanlenght_11 = ucachespanlenght/2, |
178 | vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2, |
179 | vspanlenght_11 = vcachespanlenght/2 ; |
180 | |
181 | if (cacheweights.IsNull()) { |
182 | |
183 | BSplSLib::CacheD1(new_u, |
184 | new_v, |
185 | udeg, |
186 | vdeg, |
187 | uparameter_11, |
188 | vparameter_11, |
189 | uspanlenght_11, |
190 | vspanlenght_11, |
191 | cachepoles->Array2(), |
192 | *((TColStd_Array2OfReal*) NULL), |
193 | P, |
194 | D1U, |
195 | D1V) ; |
196 | } |
197 | else { |
198 | |
199 | BSplSLib::CacheD1(new_u, |
200 | new_v, |
201 | udeg, |
202 | vdeg, |
203 | uparameter_11, |
204 | vparameter_11, |
205 | uspanlenght_11, |
206 | vspanlenght_11, |
207 | cachepoles->Array2(), |
208 | cacheweights->Array2(), |
209 | P, |
210 | D1U, |
211 | D1V) ; |
212 | } |
213 | } |
214 | |
215 | //======================================================================= |
216 | //function : D2 |
217 | //purpose : |
218 | //======================================================================= |
219 | |
220 | void Geom_BSplineSurface::D2 (const Standard_Real U, |
221 | const Standard_Real V, |
222 | gp_Pnt& P, |
223 | gp_Vec& D1U, |
224 | gp_Vec& D1V, |
225 | gp_Vec& D2U, |
226 | gp_Vec& D2V, |
227 | gp_Vec& D2UV) const |
228 | { |
83ada95b |
229 | Standard_Real new_u(U), new_v(V); |
230 | PeriodicNormalization(new_u, new_v); |
231 | |
232 | Geom_BSplineSurface* MySurface = (Geom_BSplineSurface *) this; |
233 | Standard_Mutex::Sentry aSentry(MySurface->myMutex); |
7fd59977 |
234 | |
83ada95b |
235 | if(!IsCacheValid(new_u, new_v)) |
236 | MySurface->ValidateCache(new_u, new_v); |
7fd59977 |
237 | |
238 | Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2, |
239 | uspanlenght_11 = ucachespanlenght/2, |
240 | vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2, |
241 | vspanlenght_11 = vcachespanlenght/2 ; |
242 | if (cacheweights.IsNull()) { |
243 | BSplSLib::CacheD2(new_u, |
244 | new_v, |
245 | udeg, |
246 | vdeg, |
247 | uparameter_11, |
248 | vparameter_11, |
249 | uspanlenght_11, |
250 | vspanlenght_11, |
251 | cachepoles->Array2(), |
252 | *((TColStd_Array2OfReal*) NULL), |
253 | P, |
254 | D1U, |
255 | D1V, |
256 | D2U, |
257 | D2UV, |
258 | D2V); |
259 | } |
260 | else { |
261 | BSplSLib::CacheD2(new_u, |
262 | new_v, |
263 | udeg, |
264 | vdeg, |
265 | uparameter_11, |
266 | vparameter_11, |
267 | uspanlenght_11, |
268 | vspanlenght_11, |
269 | cachepoles->Array2(), |
270 | cacheweights->Array2(), |
271 | P, |
272 | D1U, |
273 | D1V, |
274 | D2U, |
275 | D2UV, |
276 | D2V); |
277 | } |
278 | } |
279 | |
280 | //======================================================================= |
281 | //function : D3 |
282 | //purpose : |
283 | //======================================================================= |
284 | |
285 | void Geom_BSplineSurface::D3 (const Standard_Real U, |
286 | const Standard_Real V, |
287 | gp_Pnt& P, |
288 | gp_Vec& D1U, |
289 | gp_Vec& D1V, |
290 | gp_Vec& D2U, |
291 | gp_Vec& D2V, |
292 | gp_Vec& D2UV, |
293 | gp_Vec& D3U, |
294 | gp_Vec& D3V, |
295 | gp_Vec& D3UUV, |
296 | gp_Vec& D3UVV) const |
297 | { |
298 | BSplSLib::D3(U,V,0,0,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS, |
299 | udeg,vdeg,urational,vrational,uperiodic,vperiodic, |
300 | P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); |
301 | } |
302 | |
303 | //======================================================================= |
304 | //function : DN |
305 | //purpose : |
306 | //======================================================================= |
307 | |
308 | gp_Vec Geom_BSplineSurface::DN (const Standard_Real U, |
309 | const Standard_Real V, |
310 | const Standard_Integer Nu, |
311 | const Standard_Integer Nv ) const |
312 | { |
313 | gp_Vec Vn; |
314 | BSplSLib::DN(U,V,Nu,Nv,0,0,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS, |
315 | udeg,vdeg,urational,vrational,uperiodic,vperiodic, |
316 | Vn); |
317 | return Vn; |
318 | } |
319 | |
320 | //======================================================================= |
321 | //function : LocalValue |
322 | //purpose : |
323 | //======================================================================= |
324 | |
325 | gp_Pnt Geom_BSplineSurface::LocalValue (const Standard_Real U, |
326 | const Standard_Real V, |
327 | const Standard_Integer FromUK1, |
328 | const Standard_Integer ToUK2, |
329 | const Standard_Integer FromVK1, |
330 | const Standard_Integer ToVK2) const |
331 | { |
332 | gp_Pnt P; |
333 | LocalD0(U,V,FromUK1,ToUK2,FromVK1,ToVK2,P); |
334 | return P; |
335 | } |
336 | |
337 | //======================================================================= |
338 | //function : LocalD0 |
339 | //purpose : |
340 | //======================================================================= |
341 | |
342 | void Geom_BSplineSurface::LocalD0 (const Standard_Real U, |
343 | const Standard_Real V, |
344 | const Standard_Integer FromUK1, |
345 | const Standard_Integer ToUK2, |
346 | const Standard_Integer FromVK1, |
347 | const Standard_Integer ToVK2, |
348 | gp_Pnt& P ) const |
349 | { |
350 | Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2, |
351 | "Geom_BSplineSurface::LocalD0"); |
352 | |
353 | Standard_Real u = U, v = V; |
354 | Standard_Integer uindex = 0, vindex = 0; |
355 | |
356 | BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2, |
357 | uindex,u); |
358 | uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic); |
359 | |
360 | BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2, |
361 | vindex,v); |
362 | vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic); |
363 | |
364 | // BSplSLib::D0(U,V,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS, |
365 | BSplSLib::D0(u,v,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS, |
366 | udeg,vdeg,urational,vrational,uperiodic,vperiodic, |
367 | P); |
368 | } |
369 | |
370 | //======================================================================= |
371 | //function : LocalD1 |
372 | //purpose : |
373 | //======================================================================= |
374 | |
375 | void Geom_BSplineSurface::LocalD1 (const Standard_Real U, |
376 | const Standard_Real V, |
377 | const Standard_Integer FromUK1, |
378 | const Standard_Integer ToUK2, |
379 | const Standard_Integer FromVK1, |
380 | const Standard_Integer ToVK2, |
381 | gp_Pnt& P, |
382 | gp_Vec& D1U, |
383 | gp_Vec& D1V) const |
384 | { |
385 | Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2, |
386 | "Geom_BSplineSurface::LocalD1"); |
387 | |
388 | Standard_Real u = U, v = V; |
389 | Standard_Integer uindex = 0, vindex = 0; |
390 | |
391 | BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2, |
392 | uindex,u); |
393 | uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic); |
394 | |
395 | BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2, |
396 | vindex,v); |
397 | vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic); |
398 | |
399 | BSplSLib::D1(u,v,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS, |
400 | udeg,vdeg,urational,vrational,uperiodic,vperiodic, |
401 | P,D1U,D1V); |
402 | } |
403 | |
404 | //======================================================================= |
405 | //function : LocalD2 |
406 | //purpose : |
407 | //======================================================================= |
408 | |
409 | void Geom_BSplineSurface::LocalD2 (const Standard_Real U, |
410 | const Standard_Real V, |
411 | const Standard_Integer FromUK1, |
412 | const Standard_Integer ToUK2, |
413 | const Standard_Integer FromVK1, |
414 | const Standard_Integer ToVK2, |
415 | gp_Pnt& P, |
416 | gp_Vec& D1U, |
417 | gp_Vec& D1V, |
418 | gp_Vec& D2U, |
419 | gp_Vec& D2V, |
420 | gp_Vec& D2UV) const |
421 | { |
422 | Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2, |
423 | "Geom_BSplineSurface::LocalD2"); |
424 | |
425 | Standard_Real u = U, v = V; |
426 | Standard_Integer uindex = 0, vindex = 0; |
427 | |
428 | BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2, |
429 | uindex,u); |
430 | uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic); |
431 | |
432 | BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2, |
433 | vindex,v); |
434 | vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic); |
435 | |
436 | BSplSLib::D2(u,v,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS, |
437 | udeg,vdeg,urational,vrational,uperiodic,vperiodic, |
438 | P,D1U,D1V,D2U,D2V,D2UV); |
439 | } |
440 | |
441 | //======================================================================= |
442 | //function : LocalD3 |
443 | //purpose : |
444 | //======================================================================= |
445 | |
446 | void Geom_BSplineSurface::LocalD3 (const Standard_Real U, |
447 | const Standard_Real V, |
448 | const Standard_Integer FromUK1, |
449 | const Standard_Integer ToUK2, |
450 | const Standard_Integer FromVK1, |
451 | const Standard_Integer ToVK2, |
452 | gp_Pnt& P, |
453 | gp_Vec& D1U, |
454 | gp_Vec& D1V, |
455 | gp_Vec& D2U, |
456 | gp_Vec& D2V, |
457 | gp_Vec& D2UV, |
458 | gp_Vec& D3U, |
459 | gp_Vec& D3V, |
460 | gp_Vec& D3UUV, |
461 | gp_Vec& D3UVV) const |
462 | { |
463 | Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2, |
464 | "Geom_BSplineSurface::LocalD3"); |
465 | |
466 | Standard_Real u = U, v = V; |
467 | Standard_Integer uindex = 0, vindex = 0; |
468 | |
469 | BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2, |
470 | uindex,u); |
471 | uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic); |
472 | |
473 | BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2, |
474 | vindex,v); |
475 | vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic); |
476 | |
477 | BSplSLib::D3(u,v,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS, |
478 | udeg,vdeg,urational,vrational,uperiodic,vperiodic, |
479 | P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV); |
480 | } |
481 | |
482 | //======================================================================= |
483 | //function : LocalDN |
484 | //purpose : |
485 | //======================================================================= |
486 | |
487 | gp_Vec Geom_BSplineSurface::LocalDN (const Standard_Real U, |
488 | const Standard_Real V, |
489 | const Standard_Integer FromUK1, |
490 | const Standard_Integer ToUK2, |
491 | const Standard_Integer FromVK1, |
492 | const Standard_Integer ToVK2, |
493 | const Standard_Integer Nu, |
494 | const Standard_Integer Nv) const |
495 | { |
496 | Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2, |
497 | "Geom_BSplineSurface::LocalDN"); |
498 | |
499 | Standard_Real u = U, v = V; |
500 | Standard_Integer uindex = 0, vindex = 0; |
501 | |
502 | BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2, |
503 | uindex,u); |
504 | uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic); |
505 | |
506 | BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2, |
507 | vindex,v); |
508 | vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic); |
509 | |
510 | gp_Vec Vn; |
511 | BSplSLib::DN(u,v,Nu,Nv,uindex,vindex, |
512 | POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS, |
513 | udeg,vdeg,urational,vrational,uperiodic,vperiodic, |
514 | Vn); |
515 | return Vn; |
516 | } |
517 | |
518 | //======================================================================= |
519 | //function : Pole |
520 | //purpose : |
521 | //======================================================================= |
522 | |
523 | gp_Pnt Geom_BSplineSurface::Pole (const Standard_Integer UIndex, |
524 | const Standard_Integer VIndex) const |
525 | { |
526 | Standard_OutOfRange_Raise_if |
527 | (UIndex < 1 || UIndex > poles->ColLength() || |
528 | VIndex < 1 || VIndex > poles->RowLength(), " "); |
529 | return poles->Value (UIndex, VIndex); |
530 | } |
531 | |
532 | //======================================================================= |
533 | //function : Poles |
534 | //purpose : |
535 | //======================================================================= |
536 | |
537 | void Geom_BSplineSurface::Poles (TColgp_Array2OfPnt& P) const |
538 | { |
539 | Standard_DimensionError_Raise_if |
540 | (P.ColLength() != poles->ColLength() || |
541 | P.RowLength() != poles->RowLength(), " "); |
542 | P = poles->Array2(); |
543 | } |
544 | |
545 | //======================================================================= |
546 | //function : UIso |
547 | //purpose : |
548 | //======================================================================= |
549 | |
550 | Handle(Geom_Curve) Geom_BSplineSurface::UIso (const Standard_Real U) const |
551 | { |
552 | TColgp_Array1OfPnt cpoles(1,poles->RowLength()); |
553 | TColStd_Array1OfReal cweights(1,poles->RowLength()); |
554 | |
555 | Handle(Geom_BSplineCurve) C; |
556 | |
557 | if ( urational || vrational) { |
558 | BSplSLib::Iso(U,Standard_True,POLES,WEIGHTS,UFKNOTS,FMULTS,udeg,uperiodic, |
559 | cpoles,cweights); |
560 | C = new Geom_BSplineCurve(cpoles,cweights, |
561 | vknots->Array1(), |
562 | vmults->Array1(), |
563 | vdeg,vperiodic); |
564 | } |
565 | else { |
566 | BSplSLib::Iso(U,Standard_True,POLES, |
567 | *((TColStd_Array2OfReal*) NULL), |
568 | UFKNOTS,FMULTS,udeg,uperiodic, |
569 | cpoles,cweights); |
570 | C = new Geom_BSplineCurve(cpoles, |
571 | vknots->Array1(), |
572 | vmults->Array1(), |
573 | vdeg,vperiodic); |
574 | } |
575 | |
576 | return C; |
577 | } |
578 | |
579 | //======================================================================= |
580 | //function : UIso |
581 | //purpose : If CheckRational=False, no try to make it non-rational |
582 | //======================================================================= |
583 | |
584 | Handle(Geom_Curve) Geom_BSplineSurface::UIso (const Standard_Real U, |
585 | const Standard_Boolean CheckRational) const |
586 | { |
587 | TColgp_Array1OfPnt cpoles(1,poles->RowLength()); |
588 | TColStd_Array1OfReal cweights(1,poles->RowLength()); |
589 | |
590 | Handle(Geom_BSplineCurve) C; |
591 | |
592 | if ( urational || vrational) { |
593 | BSplSLib::Iso(U,Standard_True,POLES,WEIGHTS,UFKNOTS,FMULTS,udeg,uperiodic, |
594 | cpoles,cweights); |
595 | C = new Geom_BSplineCurve(cpoles,cweights, |
596 | vknots->Array1(), |
597 | vmults->Array1(), |
598 | vdeg,vperiodic, |
599 | CheckRational); |
600 | } |
601 | else { |
602 | BSplSLib::Iso(U,Standard_True,POLES, |
603 | *((TColStd_Array2OfReal*) NULL), |
604 | UFKNOTS,FMULTS,udeg,uperiodic, |
605 | cpoles,cweights); |
606 | C = new Geom_BSplineCurve(cpoles, |
607 | vknots->Array1(), |
608 | vmults->Array1(), |
609 | vdeg,vperiodic); |
610 | } |
611 | |
612 | return C; |
613 | } |
614 | |
615 | //======================================================================= |
616 | //function : UKnot |
617 | //purpose : |
618 | //======================================================================= |
619 | |
620 | Standard_Real Geom_BSplineSurface::UKnot(const Standard_Integer UIndex) const |
621 | { |
622 | Standard_OutOfRange_Raise_if (UIndex < 1 || UIndex > uknots->Length(), " "); |
623 | return uknots->Value (UIndex); |
624 | } |
625 | |
626 | //======================================================================= |
627 | //function : VKnot |
628 | //purpose : |
629 | //======================================================================= |
630 | |
631 | Standard_Real Geom_BSplineSurface::VKnot(const Standard_Integer VIndex) const |
632 | { |
633 | Standard_OutOfRange_Raise_if (VIndex < 1 || VIndex > vknots->Length(), " "); |
634 | return vknots->Value (VIndex); |
635 | } |
636 | |
637 | //======================================================================= |
638 | //function : UKnots |
639 | //purpose : |
640 | //======================================================================= |
641 | |
642 | void Geom_BSplineSurface::UKnots (TColStd_Array1OfReal& Ku) const |
643 | { |
644 | Standard_DimensionError_Raise_if (Ku.Length() != uknots->Length(), " "); |
645 | Ku = uknots->Array1(); |
646 | } |
647 | |
648 | //======================================================================= |
649 | //function : VKnots |
650 | //purpose : |
651 | //======================================================================= |
652 | |
653 | void Geom_BSplineSurface::VKnots (TColStd_Array1OfReal& Kv) const |
654 | { |
655 | Standard_DimensionError_Raise_if (Kv.Length() != vknots->Length(), " "); |
656 | Kv = vknots->Array1(); |
657 | } |
658 | |
659 | //======================================================================= |
660 | //function : UKnotSequence |
661 | //purpose : |
662 | //======================================================================= |
663 | |
664 | void Geom_BSplineSurface::UKnotSequence (TColStd_Array1OfReal& Ku) const |
665 | { |
666 | Standard_DimensionError_Raise_if (Ku.Length() != ufknots->Length(), " "); |
667 | Ku = ufknots->Array1(); |
668 | } |
669 | |
670 | //======================================================================= |
671 | //function : VKnotSequence |
672 | //purpose : |
673 | //======================================================================= |
674 | |
675 | void Geom_BSplineSurface::VKnotSequence (TColStd_Array1OfReal& Kv) const |
676 | { |
677 | Standard_DimensionError_Raise_if (Kv.Length() != vfknots->Length(), " "); |
678 | Kv = vfknots->Array1(); |
679 | } |
680 | |
681 | //======================================================================= |
682 | //function : UMultiplicity |
683 | //purpose : |
684 | //======================================================================= |
685 | |
686 | Standard_Integer Geom_BSplineSurface::UMultiplicity |
687 | (const Standard_Integer UIndex) const |
688 | { |
689 | Standard_OutOfRange_Raise_if (UIndex < 1 || UIndex > umults->Length()," "); |
690 | return umults->Value (UIndex); |
691 | } |
692 | |
693 | //======================================================================= |
694 | //function : UMultiplicities |
695 | //purpose : |
696 | //======================================================================= |
697 | |
698 | void Geom_BSplineSurface::UMultiplicities (TColStd_Array1OfInteger& Mu) const |
699 | { |
700 | Standard_DimensionError_Raise_if (Mu.Length() != umults->Length(), " "); |
701 | Mu = umults->Array1(); |
702 | } |
703 | |
704 | //======================================================================= |
705 | //function : VIso |
706 | //purpose : |
707 | //======================================================================= |
708 | |
709 | Handle(Geom_Curve) Geom_BSplineSurface::VIso (const Standard_Real V) const |
710 | { |
711 | TColgp_Array1OfPnt cpoles(1,poles->ColLength()); |
712 | TColStd_Array1OfReal cweights(1,poles->ColLength()); |
713 | |
714 | Handle(Geom_BSplineCurve) C; |
715 | |
716 | if ( urational || vrational) { |
717 | BSplSLib::Iso(V,Standard_False,POLES, |
718 | WEIGHTS, |
719 | VFKNOTS,FMULTS,vdeg,vperiodic, |
720 | cpoles,cweights); |
721 | C = new Geom_BSplineCurve(cpoles,cweights, |
722 | uknots->Array1(), |
723 | umults->Array1(), |
724 | udeg,uperiodic); |
725 | } |
726 | else { |
727 | BSplSLib::Iso(V,Standard_False,POLES, |
728 | *((TColStd_Array2OfReal*) NULL), |
729 | VFKNOTS,FMULTS,vdeg,vperiodic, |
730 | cpoles,cweights); |
731 | C = new Geom_BSplineCurve(cpoles, |
732 | uknots->Array1(), |
733 | umults->Array1(), |
734 | udeg,uperiodic); |
735 | } |
736 | |
737 | return C; |
738 | } |
739 | |
740 | //======================================================================= |
741 | //function : VIso |
742 | //purpose : If CheckRational=False, no try to make it non-rational |
743 | //======================================================================= |
744 | |
745 | Handle(Geom_Curve) Geom_BSplineSurface::VIso (const Standard_Real V, |
746 | const Standard_Boolean CheckRational) const |
747 | { |
748 | TColgp_Array1OfPnt cpoles(1,poles->ColLength()); |
749 | TColStd_Array1OfReal cweights(1,poles->ColLength()); |
750 | |
751 | Handle(Geom_BSplineCurve) C; |
752 | |
753 | if ( urational || vrational) { |
754 | BSplSLib::Iso(V,Standard_False,POLES, |
755 | WEIGHTS, |
756 | VFKNOTS,FMULTS,vdeg,vperiodic, |
757 | cpoles,cweights); |
758 | C = new Geom_BSplineCurve(cpoles,cweights, |
759 | uknots->Array1(), |
760 | umults->Array1(), |
761 | udeg,uperiodic, |
762 | CheckRational); |
763 | } |
764 | else { |
765 | BSplSLib::Iso(V,Standard_False,POLES, |
766 | *((TColStd_Array2OfReal*) NULL), |
767 | VFKNOTS,FMULTS,vdeg,vperiodic, |
768 | cpoles,cweights); |
769 | C = new Geom_BSplineCurve(cpoles, |
770 | uknots->Array1(), |
771 | umults->Array1(), |
772 | udeg,uperiodic); |
773 | } |
774 | |
775 | return C; |
776 | } |
777 | |
778 | //======================================================================= |
779 | //function : VMultiplicity |
780 | //purpose : |
781 | //======================================================================= |
782 | |
783 | Standard_Integer Geom_BSplineSurface::VMultiplicity |
784 | (const Standard_Integer VIndex) const |
785 | { |
786 | Standard_OutOfRange_Raise_if (VIndex < 1 || VIndex > vmults->Length()," "); |
787 | return vmults->Value (VIndex); |
788 | } |
789 | |
790 | //======================================================================= |
791 | //function : VMultiplicities |
792 | //purpose : |
793 | //======================================================================= |
794 | |
795 | void Geom_BSplineSurface::VMultiplicities (TColStd_Array1OfInteger& Mv) const |
796 | { |
797 | Standard_DimensionError_Raise_if (Mv.Length() != vmults->Length(), " "); |
798 | Mv = vmults->Array1(); |
799 | } |
800 | |
801 | //======================================================================= |
802 | //function : Weight |
803 | //purpose : |
804 | //======================================================================= |
805 | |
806 | Standard_Real Geom_BSplineSurface::Weight |
807 | (const Standard_Integer UIndex, |
808 | const Standard_Integer VIndex ) const |
809 | { |
810 | Standard_OutOfRange_Raise_if |
811 | (UIndex < 1 || UIndex > weights->ColLength() || |
812 | VIndex < 1 || VIndex > weights->RowLength(), " "); |
813 | return weights->Value (UIndex, VIndex); |
814 | } |
815 | |
816 | //======================================================================= |
817 | //function : Weights |
818 | //purpose : |
819 | //======================================================================= |
820 | |
821 | void Geom_BSplineSurface::Weights (TColStd_Array2OfReal& W) const |
822 | { |
823 | Standard_DimensionError_Raise_if |
824 | (W.ColLength() != weights->ColLength() || |
825 | W.RowLength() != weights->RowLength(), " "); |
826 | W = weights->Array2(); |
827 | } |
828 | |
829 | //======================================================================= |
830 | //function : Transform |
831 | //purpose : |
832 | //======================================================================= |
833 | |
834 | void Geom_BSplineSurface::Transform (const gp_Trsf& T) |
835 | { |
836 | TColgp_Array2OfPnt & VPoles = poles->ChangeArray2(); |
837 | for (Standard_Integer j = VPoles.LowerCol(); j <= VPoles.UpperCol(); j++) { |
838 | for (Standard_Integer i = VPoles.LowerRow(); i <= VPoles.UpperRow(); i++) { |
839 | VPoles (i, j).Transform (T); |
840 | } |
841 | } |
842 | |
843 | InvalidateCache(); |
844 | } |
845 | |
846 | //======================================================================= |
847 | //function : SetUPeriodic |
848 | //purpose : |
849 | //======================================================================= |
850 | |
851 | void Geom_BSplineSurface::SetUPeriodic () |
852 | { |
853 | Standard_Integer i,j; |
854 | |
855 | Standard_Integer first = FirstUKnotIndex(); |
856 | Standard_Integer last = LastUKnotIndex(); |
857 | |
858 | Handle(TColStd_HArray1OfReal) tk = uknots; |
859 | TColStd_Array1OfReal cknots((uknots->Array1())(first),first,last); |
860 | uknots = new TColStd_HArray1OfReal(1,cknots.Length()); |
861 | uknots->ChangeArray1() = cknots; |
862 | |
863 | Handle(TColStd_HArray1OfInteger) tm = umults; |
864 | TColStd_Array1OfInteger cmults((umults->Array1())(first),first,last); |
865 | // Modified by Sergey KHROMOV - Mon Feb 10 10:59:00 2003 Begin |
866 | // cmults(first) = cmults(last) = Max( cmults(first), cmults(last)); |
867 | cmults(first) = cmults(last) = Min(udeg, Max( cmults(first), cmults(last))); |
868 | // Modified by Sergey KHROMOV - Mon Feb 10 10:59:00 2003 End |
869 | umults = new TColStd_HArray1OfInteger(1,cmults.Length()); |
870 | umults->ChangeArray1() = cmults; |
871 | |
872 | // compute new number of poles; |
873 | Standard_Integer nbp = BSplCLib::NbPoles(udeg,Standard_True,cmults); |
874 | |
875 | TColgp_Array2OfPnt cpoles(1,nbp,poles->LowerCol(),poles->UpperCol()); |
876 | for (i = 1; i <= nbp; i++) { |
877 | for (j = poles->LowerCol(); j <= poles->UpperCol(); j++) { |
878 | cpoles(i,j) = poles->Value(i,j); |
879 | } |
880 | } |
881 | poles = |
882 | new TColgp_HArray2OfPnt(1,nbp,cpoles.LowerCol(),cpoles.UpperCol()); |
883 | poles->ChangeArray2() = cpoles; |
884 | |
885 | TColStd_Array2OfReal |
886 | cweights(1,nbp,weights->LowerCol(),weights->UpperCol()); |
887 | if (urational || vrational) { |
888 | for (i = 1; i <= nbp; i++) { |
889 | for (j = weights->LowerCol(); j <= weights->UpperCol(); j++) { |
890 | cweights(i,j) = weights->Value(i,j); |
891 | } |
892 | } |
893 | } |
894 | else { |
895 | for (i = 1; i <= nbp; i++) { |
896 | for (j = weights->LowerCol(); j <= weights->UpperCol(); j++) { |
897 | cweights(i,j) = 1; |
898 | } |
899 | } |
900 | } |
901 | weights = new |
902 | TColStd_HArray2OfReal(1,nbp,cweights.LowerCol(),cweights.UpperCol()); |
903 | weights->ChangeArray2() = cweights; |
904 | |
905 | |
906 | uperiodic = Standard_True; |
907 | |
908 | maxderivinvok = 0; |
909 | UpdateUKnots(); |
910 | } |
911 | |
912 | //======================================================================= |
913 | //function : SetVPeriodic |
914 | //purpose : |
915 | //======================================================================= |
916 | |
917 | void Geom_BSplineSurface::SetVPeriodic () |
918 | { |
919 | Standard_Integer i,j; |
920 | |
921 | Standard_Integer first = FirstVKnotIndex(); |
922 | Standard_Integer last = LastVKnotIndex(); |
923 | |
924 | Handle(TColStd_HArray1OfReal) tk = vknots; |
925 | TColStd_Array1OfReal cknots((vknots->Array1())(first),first,last); |
926 | vknots = new TColStd_HArray1OfReal(1,cknots.Length()); |
927 | vknots->ChangeArray1() = cknots; |
928 | |
929 | |
930 | Handle(TColStd_HArray1OfInteger) tm = vmults; |
931 | TColStd_Array1OfInteger cmults((vmults->Array1())(first),first,last); |
932 | // Modified by Sergey KHROMOV - Mon Feb 10 11:00:33 2003 Begin |
933 | // cmults(first) = cmults(last) = Max( cmults(first), cmults(last)); |
934 | cmults(first) = cmults(last) = Min(vdeg, Max( cmults(first), cmults(last))); |
935 | // Modified by Sergey KHROMOV - Mon Feb 10 11:00:34 2003 End |
936 | vmults = new TColStd_HArray1OfInteger(1,cmults.Length()); |
937 | vmults->ChangeArray1() = cmults; |
938 | |
939 | // compute new number of poles; |
940 | Standard_Integer nbp = BSplCLib::NbPoles(vdeg,Standard_True,cmults); |
941 | |
942 | TColgp_Array2OfPnt cpoles(poles->LowerRow(),poles->UpperRow(),1,nbp); |
943 | for (i = poles->LowerRow(); i <= poles->UpperRow(); i++) { |
944 | for (j = 1; j <= nbp; j++) { |
945 | cpoles(i,j) = poles->Value(i,j); |
946 | } |
947 | } |
948 | poles = |
949 | new TColgp_HArray2OfPnt(cpoles.LowerRow(),cpoles.UpperRow(),1,nbp); |
950 | poles->ChangeArray2() = cpoles; |
951 | |
952 | if (urational || vrational) { |
953 | TColStd_Array2OfReal |
954 | cweights(weights->LowerRow(),weights->UpperRow(),1,nbp); |
955 | for (i = weights->LowerRow(); i <= weights->UpperRow(); i++) { |
956 | for (j = 1; j <= nbp; j++) { |
957 | cweights(i,j) = weights->Value(i,j); |
958 | } |
959 | } |
960 | weights = new |
961 | TColStd_HArray2OfReal(cweights.LowerRow(),cweights.UpperRow(),1,nbp); |
962 | weights->ChangeArray2() = cweights; |
963 | } |
964 | |
965 | vperiodic = Standard_True; |
966 | |
967 | maxderivinvok = 0; |
968 | UpdateVKnots(); |
969 | } |
970 | |
971 | //======================================================================= |
972 | //function : SetUOrigin |
973 | //purpose : |
974 | //======================================================================= |
975 | |
976 | void Geom_BSplineSurface::SetUOrigin(const Standard_Integer Index) |
977 | { |
978 | Standard_NoSuchObject_Raise_if( !uperiodic, |
979 | "Geom_BSplineSurface::SetUOrigin"); |
980 | |
981 | Standard_Integer i,j,k; |
982 | Standard_Integer first = FirstUKnotIndex(); |
983 | Standard_Integer last = LastUKnotIndex(); |
984 | |
985 | Standard_DomainError_Raise_if( (Index < first) || (Index > last), |
986 | "Geom_BSplineCurve::SetUOrigine"); |
987 | |
988 | Standard_Integer nbknots = uknots->Length(); |
989 | Standard_Integer nbpoles = poles->ColLength(); |
990 | |
991 | Handle(TColStd_HArray1OfReal) nknots = |
992 | new TColStd_HArray1OfReal(1,nbknots); |
993 | TColStd_Array1OfReal& newknots = nknots->ChangeArray1(); |
994 | |
995 | Handle(TColStd_HArray1OfInteger) nmults = |
996 | new TColStd_HArray1OfInteger(1,nbknots); |
997 | TColStd_Array1OfInteger& newmults = nmults->ChangeArray1(); |
998 | |
999 | // set the knots and mults |
1000 | Standard_Real period = uknots->Value(last) - uknots->Value(first); |
1001 | k = 1; |
1002 | for ( i = Index; i <= last ; i++) { |
1003 | newknots(k) = uknots->Value(i); |
1004 | newmults(k) = umults->Value(i); |
1005 | k++; |
1006 | } |
1007 | for ( i = first+1; i <= Index; i++) { |
1008 | newknots(k) = uknots->Value(i) + period; |
1009 | newmults(k) = umults->Value(i); |
1010 | k++; |
1011 | } |
1012 | |
1013 | Standard_Integer index = 1; |
1014 | for (i = first+1; i <= Index; i++) |
1015 | index += umults->Value(i); |
1016 | |
1017 | // set the poles and weights |
1018 | Standard_Integer nbvp = poles->RowLength(); |
1019 | Handle(TColgp_HArray2OfPnt) npoles = |
1020 | new TColgp_HArray2OfPnt(1,nbpoles,1,nbvp); |
1021 | Handle(TColStd_HArray2OfReal) nweights = |
1022 | new TColStd_HArray2OfReal(1,nbpoles,1,nbvp); |
1023 | TColgp_Array2OfPnt & newpoles = npoles->ChangeArray2(); |
1024 | TColStd_Array2OfReal & newweights = nweights->ChangeArray2(); |
1025 | first = poles->LowerRow(); |
1026 | last = poles->UpperRow(); |
1027 | if ( urational || vrational) { |
1028 | k = 1; |
1029 | for ( i = index; i <= last; i++) { |
1030 | for ( j = 1; j <= nbvp; j++) { |
1031 | newpoles(k,j) = poles->Value(i,j); |
1032 | newweights(k,j) = weights->Value(i,j); |
1033 | } |
1034 | k++; |
1035 | } |
1036 | for ( i = first; i < index; i++) { |
1037 | for ( j = 1; j <= nbvp; j++) { |
1038 | newpoles(k,j) = poles->Value(i,j); |
1039 | newweights(k,j) = weights->Value(i,j); |
1040 | } |
1041 | k++; |
1042 | } |
1043 | } |
1044 | else { |
1045 | k = 1; |
1046 | for ( i = index; i <= last; i++) { |
1047 | for ( j = 1; j <= nbvp; j++) { |
1048 | newpoles(k,j) = poles->Value(i,j); |
1049 | } |
1050 | k++; |
1051 | } |
1052 | for ( i = first; i < index; i++) { |
1053 | for ( j = 1; j <= nbvp; j++) { |
1054 | newpoles(k,j) = poles->Value(i,j); |
1055 | } |
1056 | k++; |
1057 | } |
1058 | } |
1059 | |
1060 | poles = npoles; |
1061 | uknots = nknots; |
1062 | umults = nmults; |
1063 | if (urational || vrational) |
1064 | weights = nweights; |
1065 | UpdateUKnots(); |
1066 | |
1067 | } |
1068 | |
1069 | //======================================================================= |
1070 | //function : SetVOrigin |
1071 | //purpose : |
1072 | //======================================================================= |
1073 | |
1074 | void Geom_BSplineSurface::SetVOrigin(const Standard_Integer Index) |
1075 | { |
1076 | Standard_NoSuchObject_Raise_if( !vperiodic, |
1077 | "Geom_BSplineSurface::SetVOrigin"); |
1078 | |
1079 | Standard_Integer i,j,k; |
1080 | Standard_Integer first = FirstVKnotIndex(); |
1081 | Standard_Integer last = LastVKnotIndex(); |
1082 | |
1083 | Standard_DomainError_Raise_if( (Index < first) || (Index > last), |
1084 | "Geom_BSplineCurve::SetVOrigine"); |
1085 | |
1086 | Standard_Integer nbknots = vknots->Length(); |
1087 | Standard_Integer nbpoles = poles->RowLength(); |
1088 | |
1089 | Handle(TColStd_HArray1OfReal) nknots = |
1090 | new TColStd_HArray1OfReal(1,nbknots); |
1091 | TColStd_Array1OfReal& newknots = nknots->ChangeArray1(); |
1092 | |
1093 | Handle(TColStd_HArray1OfInteger) nmults = |
1094 | new TColStd_HArray1OfInteger(1,nbknots); |
1095 | TColStd_Array1OfInteger& newmults = nmults->ChangeArray1(); |
1096 | |
1097 | // set the knots and mults |
1098 | Standard_Real period = vknots->Value(last) - vknots->Value(first); |
1099 | k = 1; |
1100 | for ( i = Index; i <= last ; i++) { |
1101 | newknots(k) = vknots->Value(i); |
1102 | newmults(k) = vmults->Value(i); |
1103 | k++; |
1104 | } |
1105 | for ( i = first+1; i <= Index; i++) { |
1106 | newknots(k) = vknots->Value(i) + period; |
1107 | newmults(k) = vmults->Value(i); |
1108 | k++; |
1109 | } |
1110 | |
1111 | Standard_Integer index = 1; |
1112 | for (i = first+1; i <= Index; i++) |
1113 | index += vmults->Value(i); |
1114 | |
1115 | // set the poles and weights |
1116 | Standard_Integer nbup = poles->ColLength(); |
1117 | Handle(TColgp_HArray2OfPnt) npoles = |
1118 | new TColgp_HArray2OfPnt(1,nbup,1,nbpoles); |
1119 | Handle(TColStd_HArray2OfReal) nweights = |
1120 | new TColStd_HArray2OfReal(1,nbup,1,nbpoles); |
1121 | TColgp_Array2OfPnt & newpoles = npoles->ChangeArray2(); |
1122 | TColStd_Array2OfReal & newweights = nweights->ChangeArray2(); |
1123 | first = poles->LowerCol(); |
1124 | last = poles->UpperCol(); |
1125 | if ( urational || vrational) { |
1126 | k = 1; |
1127 | for ( j = index; j <= last; j++) { |
1128 | for ( i = 1; i <= nbup; i++) { |
1129 | newpoles(i,k) = poles->Value(i,j); |
1130 | newweights(i,k) = weights->Value(i,j); |
1131 | } |
1132 | k++; |
1133 | } |
1134 | for ( j = first; j < index; j++) { |
1135 | for ( i = 1; i <= nbup; i++) { |
1136 | newpoles(i,k) = poles->Value(i,j); |
1137 | newweights(i,k) = weights->Value(i,j); |
1138 | } |
1139 | k++; |
1140 | } |
1141 | } |
1142 | else { |
1143 | k = 1; |
1144 | for ( j = index; j <= last; j++) { |
1145 | for ( i = 1; i <= nbup; i++) { |
1146 | newpoles(i,k) = poles->Value(i,j); |
1147 | } |
1148 | k++; |
1149 | } |
1150 | for ( j = first; j < index; j++) { |
1151 | for ( i = 1; i <= nbup; i++) { |
1152 | newpoles(i,k) = poles->Value(i,j); |
1153 | } |
1154 | k++; |
1155 | } |
1156 | } |
1157 | |
1158 | poles = npoles; |
1159 | vknots = nknots; |
1160 | vmults = nmults; |
1161 | if (urational || vrational) |
1162 | weights = nweights; |
1163 | UpdateVKnots(); |
1164 | |
1165 | } |
1166 | |
1167 | //======================================================================= |
1168 | //function : SetUNotPeriodic |
1169 | //purpose : |
1170 | //======================================================================= |
1171 | |
1172 | void Geom_BSplineSurface::SetUNotPeriodic () |
1173 | { |
1174 | if ( uperiodic) { |
1175 | Standard_Integer NbKnots, NbPoles; |
1176 | BSplCLib::PrepareUnperiodize( udeg, umults->Array1(), NbKnots, NbPoles); |
1177 | |
1178 | Handle(TColgp_HArray2OfPnt) npoles = |
1179 | new TColgp_HArray2OfPnt(1,NbPoles, 1, poles->RowLength()); |
1180 | |
1181 | Handle(TColStd_HArray1OfReal) nknots |
1182 | = new TColStd_HArray1OfReal(1,NbKnots); |
1183 | |
1184 | Handle(TColStd_HArray1OfInteger) nmults |
1185 | = new TColStd_HArray1OfInteger(1,NbKnots); |
1186 | |
1187 | Handle(TColStd_HArray2OfReal) nweights = new TColStd_HArray2OfReal(1,NbPoles, 1, poles->RowLength(), 0); |
1188 | |
1189 | if ( urational || vrational) { |
1190 | |
1191 | BSplSLib::Unperiodize(Standard_True , udeg, |
1192 | umults->Array1() , uknots->Array1(), |
1193 | poles->Array2() , weights->Array2(), |
1194 | nmults->ChangeArray1(), nknots->ChangeArray1(), |
1195 | npoles->ChangeArray2(), |
1196 | nweights->ChangeArray2()); |
1197 | } |
1198 | else { |
1199 | |
1200 | BSplSLib::Unperiodize(Standard_True , udeg, |
1201 | umults->Array1() , uknots->Array1(), |
1202 | poles->Array2() , BSplSLib::NoWeights(), |
1203 | nmults->ChangeArray1(), nknots->ChangeArray1(), |
1204 | npoles->ChangeArray2(), |
1205 | *((TColStd_Array2OfReal*) NULL)); |
1206 | } |
1207 | poles = npoles; |
1208 | weights = nweights; |
1209 | umults = nmults; |
1210 | uknots = nknots; |
1211 | uperiodic = Standard_False; |
1212 | |
1213 | maxderivinvok = 0; |
1214 | UpdateUKnots(); |
1215 | |
1216 | } |
1217 | } |
1218 | |
1219 | //======================================================================= |
1220 | //function : SetVNotPeriodic |
1221 | //purpose : |
1222 | //======================================================================= |
1223 | |
1224 | void Geom_BSplineSurface::SetVNotPeriodic () |
1225 | { |
1226 | if ( vperiodic) { |
1227 | Standard_Integer NbKnots, NbPoles; |
1228 | BSplCLib::PrepareUnperiodize( vdeg, vmults->Array1(), NbKnots, NbPoles); |
1229 | |
1230 | Handle(TColgp_HArray2OfPnt) npoles = |
1231 | new TColgp_HArray2OfPnt(1, poles->ColLength(), 1, NbPoles); |
1232 | |
1233 | Handle(TColStd_HArray1OfReal) nknots |
1234 | = new TColStd_HArray1OfReal(1,NbKnots); |
1235 | |
1236 | Handle(TColStd_HArray1OfInteger) nmults |
1237 | = new TColStd_HArray1OfInteger(1,NbKnots) ; |
1238 | |
1239 | Handle(TColStd_HArray2OfReal) nweights = new TColStd_HArray2OfReal(1, poles->ColLength(), 1, NbPoles, 0); |
1240 | |
1241 | if ( urational || vrational) { |
1242 | |
1243 | BSplSLib::Unperiodize(Standard_False , vdeg, |
1244 | vmults->Array1() , vknots->Array1(), |
1245 | poles->Array2() , weights->Array2(), |
1246 | nmults->ChangeArray1(), nknots->ChangeArray1(), |
1247 | npoles->ChangeArray2(), |
1248 | nweights->ChangeArray2()); |
1249 | } |
1250 | else { |
1251 | |
1252 | BSplSLib::Unperiodize(Standard_False , vdeg, |
1253 | vmults->Array1() , vknots->Array1(), |
1254 | poles->Array2() , BSplSLib::NoWeights(), |
1255 | nmults->ChangeArray1(), nknots->ChangeArray1(), |
1256 | npoles->ChangeArray2(), |
1257 | *((TColStd_Array2OfReal*) NULL)); |
1258 | } |
1259 | poles = npoles; |
1260 | weights = nweights; |
1261 | vmults = nmults; |
1262 | vknots = nknots; |
1263 | vperiodic = Standard_False; |
1264 | |
1265 | maxderivinvok = 0; |
1266 | UpdateVKnots(); |
1267 | |
1268 | } |
1269 | } |
1270 | |
1271 | //======================================================================= |
1272 | //function : IsUClosed |
1273 | //purpose : |
1274 | //======================================================================= |
1275 | |
1276 | Standard_Boolean Geom_BSplineSurface::IsUClosed () const |
1277 | { |
1278 | if (uperiodic) |
1279 | return Standard_True; |
1280 | |
a7493ad4 |
1281 | Standard_Real aU1, aU2, aV1, aV2; |
1282 | Bounds( aU1, aU2, aV1, aV2 ); |
1283 | Handle(Geom_Curve) aCUF = UIso( aU1 ); |
1284 | Handle(Geom_Curve) aCUL = UIso( aU2 ); |
1285 | if(aCUF.IsNull() || aCUL.IsNull()) |
1286 | return Standard_False; |
1287 | Handle(Geom_BSplineCurve) aBsF = Handle(Geom_BSplineCurve)::DownCast(aCUF); |
1288 | Handle(Geom_BSplineCurve) aBsL = Handle(Geom_BSplineCurve)::DownCast(aCUL); |
1289 | return (!aBsF.IsNull() && !aBsL.IsNull() && aBsF->IsEqual( aBsL, Precision::Confusion()) ); |
7fd59977 |
1290 | } |
1291 | |
1292 | //======================================================================= |
1293 | //function : IsVClosed |
1294 | //purpose : |
1295 | //======================================================================= |
1296 | |
1297 | Standard_Boolean Geom_BSplineSurface::IsVClosed () const |
1298 | { |
1299 | if (vperiodic) |
1300 | return Standard_True; |
a7493ad4 |
1301 | |
1302 | Standard_Real aU1, aU2, aV1, aV2; |
1303 | Bounds( aU1, aU2, aV1, aV2 ); |
1304 | Handle(Geom_Curve) aCVF = VIso( aV1 ); |
1305 | Handle(Geom_Curve) aCVL = VIso( aV2 ); |
1306 | if(aCVF.IsNull() || aCVL.IsNull()) |
1307 | return Standard_False; |
1308 | Handle(Geom_BSplineCurve) aBsF = Handle(Geom_BSplineCurve)::DownCast(aCVF); |
1309 | Handle(Geom_BSplineCurve) aBsL = Handle(Geom_BSplineCurve)::DownCast(aCVL); |
1310 | return (!aBsF.IsNull() && !aBsL.IsNull() && aBsF->IsEqual(aBsL, Precision::Confusion())); |
7fd59977 |
1311 | } |
1312 | |
1313 | //======================================================================= |
1314 | //function : IsUPeriodic |
1315 | //purpose : |
1316 | //======================================================================= |
1317 | |
1318 | Standard_Boolean Geom_BSplineSurface::IsUPeriodic () const |
1319 | { |
1320 | return uperiodic; |
1321 | } |
1322 | |
1323 | //======================================================================= |
1324 | //function : IsVPeriodic |
1325 | //purpose : |
1326 | //======================================================================= |
1327 | |
1328 | Standard_Boolean Geom_BSplineSurface::IsVPeriodic () const |
1329 | { |
1330 | return vperiodic; |
1331 | } |
1332 | |
1333 | //======================================================================= |
1334 | //function : FirstUKnotIndex |
1335 | //purpose : |
1336 | //======================================================================= |
1337 | |
1338 | Standard_Integer Geom_BSplineSurface::FirstUKnotIndex () const |
1339 | { |
1340 | if (uperiodic) return 1; |
1341 | else return BSplCLib::FirstUKnotIndex(udeg,umults->Array1()); |
1342 | } |
1343 | |
1344 | //======================================================================= |
1345 | //function : FirstVKnotIndex |
1346 | //purpose : |
1347 | //======================================================================= |
1348 | |
1349 | Standard_Integer Geom_BSplineSurface::FirstVKnotIndex () const |
1350 | { |
1351 | if (vperiodic) return 1; |
1352 | else return BSplCLib::FirstUKnotIndex(vdeg,vmults->Array1()); |
1353 | } |
1354 | |
1355 | //======================================================================= |
1356 | //function : LastUKnotIndex |
1357 | //purpose : |
1358 | //======================================================================= |
1359 | |
1360 | Standard_Integer Geom_BSplineSurface::LastUKnotIndex() const |
1361 | { |
1362 | if (uperiodic) return uknots->Length(); |
1363 | else return BSplCLib::LastUKnotIndex(udeg,umults->Array1()); |
1364 | } |
1365 | |
1366 | //======================================================================= |
1367 | //function : LastVKnotIndex |
1368 | //purpose : |
1369 | //======================================================================= |
1370 | |
1371 | Standard_Integer Geom_BSplineSurface::LastVKnotIndex() const |
1372 | { |
1373 | if (vperiodic) return vknots->Length(); |
1374 | else return BSplCLib::LastUKnotIndex(vdeg,vmults->Array1()); |
1375 | } |
1376 | |
1377 | //======================================================================= |
1378 | //function : LocateU |
1379 | //purpose : |
1380 | //======================================================================= |
1381 | |
1382 | void Geom_BSplineSurface::LocateU |
1383 | (const Standard_Real U, |
1384 | const Standard_Real ParametricTolerance, |
1385 | Standard_Integer& I1, |
1386 | Standard_Integer& I2, |
1387 | const Standard_Boolean WithKnotRepetition ) const |
1388 | { |
1389 | Standard_Real NewU =U, vbid = vknots->Value(1); |
1390 | Handle(TColStd_HArray1OfReal) TheKnots; |
1391 | if (WithKnotRepetition) TheKnots = ufknots; |
1392 | else TheKnots = uknots; |
1393 | |
1394 | PeriodicNormalization(NewU, vbid); //Attention a la periode |
1395 | |
1396 | const TColStd_Array1OfReal & Knots = TheKnots->Array1(); |
1397 | Standard_Real UFirst = Knots (1); |
1398 | Standard_Real ULast = Knots (Knots.Length()); |
41c52af3 |
1399 | Standard_Real PParametricTolerance = Abs(ParametricTolerance); |
1400 | if (Abs (NewU - UFirst) <= PParametricTolerance) { |
7fd59977 |
1401 | I1 = I2 = 1; |
1402 | } |
41c52af3 |
1403 | else if (Abs (NewU - ULast) <= PParametricTolerance) { |
7fd59977 |
1404 | I1 = I2 = Knots.Length(); |
1405 | } |
41c52af3 |
1406 | else if (NewU < UFirst) { |
7fd59977 |
1407 | I2 = 1; |
1408 | I1 = 0; |
1409 | } |
41c52af3 |
1410 | else if (NewU > ULast) { |
7fd59977 |
1411 | I1 = Knots.Length(); |
1412 | I2 = I1 + 1; |
1413 | } |
1414 | else { |
1415 | I1 = 1; |
1416 | BSplCLib::Hunt (Knots, NewU, I1); |
41c52af3 |
1417 | while ( Abs( Knots(I1+1) - NewU) <= PParametricTolerance) I1++; |
1418 | if ( Abs( Knots(I1) - NewU) <= PParametricTolerance) { |
7fd59977 |
1419 | I2 = I1; |
1420 | } |
1421 | else { |
1422 | I2 = I1 + 1; |
1423 | } |
1424 | } |
1425 | } |
1426 | |
1427 | //======================================================================= |
1428 | //function : LocateV |
1429 | //purpose : |
1430 | //======================================================================= |
1431 | |
1432 | void Geom_BSplineSurface::LocateV |
1433 | (const Standard_Real V, |
1434 | const Standard_Real ParametricTolerance, |
1435 | Standard_Integer& I1, |
1436 | Standard_Integer& I2, |
1437 | const Standard_Boolean WithKnotRepetition ) const |
1438 | { |
1439 | Standard_Real NewV =V, ubid = uknots->Value(1); |
1440 | Handle(TColStd_HArray1OfReal) TheKnots; |
1441 | if (WithKnotRepetition) TheKnots = vfknots; |
1442 | else TheKnots = vknots; |
1443 | |
1444 | PeriodicNormalization(ubid, NewV); //Attention a la periode |
1445 | |
1446 | const TColStd_Array1OfReal & Knots = TheKnots->Array1(); |
1447 | Standard_Real VFirst = Knots (1); |
1448 | Standard_Real VLast = Knots (Knots.Length()); |
41c52af3 |
1449 | Standard_Real PParametricTolerance = Abs(ParametricTolerance); |
1450 | if (Abs (NewV - VFirst) <= PParametricTolerance) { I1 = I2 = 1; } |
1451 | else if (Abs (NewV - VLast) <= PParametricTolerance) { |
7fd59977 |
1452 | I1 = I2 = Knots.Length(); |
1453 | } |
41c52af3 |
1454 | else if (NewV < VFirst - PParametricTolerance) { |
7fd59977 |
1455 | I2 = 1; |
1456 | I1 = 0; |
1457 | } |
41c52af3 |
1458 | else if (NewV > VLast + PParametricTolerance) { |
7fd59977 |
1459 | I1 = Knots.Length(); |
1460 | I2 = I1 + 1; |
1461 | } |
1462 | else { |
1463 | I1 = 1; |
1464 | BSplCLib::Hunt (Knots, NewV, I1); |
41c52af3 |
1465 | while ( Abs( Knots(I1+1) - NewV) <= PParametricTolerance) I1++; |
1466 | if ( Abs( Knots(I1) - NewV) <= PParametricTolerance) { |
7fd59977 |
1467 | I2 = I1; |
1468 | } |
1469 | else { |
1470 | I2 = I1 + 1; |
1471 | } |
1472 | } |
1473 | } |
1474 | |
1475 | //======================================================================= |
1476 | //function : UReverse |
1477 | //purpose : |
1478 | //======================================================================= |
1479 | |
1480 | void Geom_BSplineSurface::UReverse () |
1481 | { |
1482 | BSplCLib::Reverse(umults->ChangeArray1()); |
1483 | BSplCLib::Reverse(uknots->ChangeArray1()); |
1484 | Standard_Integer last; |
1485 | if (uperiodic) |
1486 | last = ufknots->Upper() - udeg -1; |
1487 | else |
1488 | last = poles->UpperRow(); |
1489 | BSplSLib::Reverse(poles->ChangeArray2(),last,Standard_True); |
1490 | if (urational || vrational) |
1491 | BSplSLib::Reverse(weights->ChangeArray2(),last,Standard_True); |
1492 | UpdateUKnots(); |
1493 | } |
1494 | |
1495 | //======================================================================= |
1496 | //function : UReversedParameter |
1497 | //purpose : |
1498 | //======================================================================= |
1499 | |
1500 | Standard_Real Geom_BSplineSurface::UReversedParameter |
1501 | ( const Standard_Real U) const |
1502 | { |
1503 | return ( uknots->Value( 1) + uknots->Value( uknots->Length()) - U); |
1504 | } |
1505 | |
1506 | //======================================================================= |
1507 | //function : VReverse |
1508 | //purpose : |
1509 | //======================================================================= |
1510 | |
1511 | void Geom_BSplineSurface::VReverse () |
1512 | { |
1513 | BSplCLib::Reverse(vmults->ChangeArray1()); |
1514 | BSplCLib::Reverse(vknots->ChangeArray1()); |
1515 | Standard_Integer last; |
1516 | if (vperiodic) |
1517 | last = vfknots->Upper() - vdeg -1; |
1518 | else |
1519 | last = poles->UpperCol(); |
1520 | BSplSLib::Reverse(poles->ChangeArray2(),last,Standard_False); |
1521 | if (urational || vrational) |
1522 | BSplSLib::Reverse(weights->ChangeArray2(),last,Standard_False); |
1523 | UpdateVKnots(); |
1524 | } |
1525 | |
1526 | //======================================================================= |
1527 | //function : VReversedParameter |
1528 | //purpose : |
1529 | //======================================================================= |
1530 | |
1531 | Standard_Real Geom_BSplineSurface::VReversedParameter |
1532 | ( const Standard_Real V) const |
1533 | { |
1534 | return ( vknots->Value( 1) + vknots->Value( vknots->Length()) - V); |
1535 | } |
1536 | |
1537 | //======================================================================= |
1538 | //function : SetPoleCol |
1539 | //purpose : |
1540 | //======================================================================= |
1541 | |
1542 | void Geom_BSplineSurface::SetPoleCol (const Standard_Integer VIndex, |
1543 | const TColgp_Array1OfPnt& CPoles) |
1544 | { |
1545 | if (VIndex < 1 || VIndex > poles->RowLength()) { |
1546 | Standard_OutOfRange::Raise(); |
1547 | } |
1548 | if (CPoles.Lower() < 1 || CPoles.Lower() > poles->ColLength() || |
1549 | CPoles.Upper() < 1 || CPoles.Upper() > poles->ColLength()) { |
1550 | Standard_ConstructionError::Raise(); |
1551 | } |
1552 | |
1553 | TColgp_Array2OfPnt & Poles = poles->ChangeArray2(); |
1554 | |
1555 | for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) { |
1556 | Poles (I+Poles.LowerRow()-1, VIndex+Poles.LowerCol()-1) = CPoles(I); |
1557 | } |
1558 | |
1559 | InvalidateCache(); |
1560 | } |
1561 | |
1562 | //======================================================================= |
1563 | //function : SetPoleCol |
1564 | //purpose : |
1565 | //======================================================================= |
1566 | |
1567 | void Geom_BSplineSurface::SetPoleCol (const Standard_Integer VIndex, |
1568 | const TColgp_Array1OfPnt& CPoles, |
1569 | const TColStd_Array1OfReal& CPoleWeights) |
1570 | { |
1571 | SetPoleCol (VIndex, CPoles); |
1572 | SetWeightCol(VIndex, CPoleWeights); |
1573 | } |
1574 | |
1575 | //======================================================================= |
1576 | //function : SetPoleRow |
1577 | //purpose : |
1578 | //======================================================================= |
1579 | |
1580 | void Geom_BSplineSurface::SetPoleRow (const Standard_Integer UIndex, |
1581 | const TColgp_Array1OfPnt& CPoles) |
1582 | { |
1583 | if (UIndex < 1 || UIndex > poles->ColLength() ) { |
1584 | Standard_OutOfRange::Raise(); |
1585 | } |
1586 | if (CPoles.Lower() < 1 || CPoles.Lower() > poles->RowLength() || |
1587 | CPoles.Upper() < 1 || CPoles.Upper() > poles->RowLength() ) { |
1588 | Standard_ConstructionError::Raise(); |
1589 | } |
1590 | |
1591 | TColgp_Array2OfPnt & Poles = poles->ChangeArray2(); |
1592 | |
1593 | for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) { |
1594 | Poles (UIndex+Poles.LowerRow()-1, I+Poles.LowerCol()-1) = CPoles (I); |
1595 | } |
1596 | |
1597 | InvalidateCache(); |
1598 | } |
1599 | |
1600 | //======================================================================= |
1601 | //function : SetPoleRow |
1602 | //purpose : |
1603 | //======================================================================= |
1604 | |
1605 | void Geom_BSplineSurface::SetPoleRow(const Standard_Integer UIndex, |
1606 | const TColgp_Array1OfPnt & CPoles, |
1607 | const TColStd_Array1OfReal& CPoleWeights) |
1608 | { |
1609 | SetPoleRow (UIndex, CPoles); |
1610 | SetWeightRow(UIndex, CPoleWeights); |
1611 | } |
1612 | |
1613 | //======================================================================= |
1614 | //function : SetPole |
1615 | //purpose : |
1616 | //======================================================================= |
1617 | |
1618 | void Geom_BSplineSurface::SetPole (const Standard_Integer UIndex, |
1619 | const Standard_Integer VIndex, |
1620 | const gp_Pnt& P) |
1621 | { |
1622 | poles->SetValue (UIndex+poles->LowerRow()-1, VIndex+poles->LowerCol()-1, P); |
1623 | InvalidateCache(); |
1624 | } |
1625 | |
1626 | //======================================================================= |
1627 | //function : SetPole |
1628 | //purpose : |
1629 | //======================================================================= |
1630 | |
1631 | void Geom_BSplineSurface::SetPole (const Standard_Integer UIndex, |
1632 | const Standard_Integer VIndex, |
1633 | const gp_Pnt& P, |
1634 | const Standard_Real Weight) |
1635 | { |
1636 | SetWeight(UIndex, VIndex, Weight); |
1637 | SetPole (UIndex, VIndex, P); |
1638 | } |
1639 | |
1640 | //======================================================================= |
1641 | //function : MovePoint |
1642 | //purpose : |
1643 | //======================================================================= |
1644 | |
1645 | void Geom_BSplineSurface::MovePoint(const Standard_Real U, |
1646 | const Standard_Real V, |
1647 | const gp_Pnt& P, |
1648 | const Standard_Integer UIndex1, |
1649 | const Standard_Integer UIndex2, |
1650 | const Standard_Integer VIndex1, |
1651 | const Standard_Integer VIndex2, |
1652 | Standard_Integer& UFirstModifiedPole, |
1653 | Standard_Integer& ULastmodifiedPole, |
1654 | Standard_Integer& VFirstModifiedPole, |
1655 | Standard_Integer& VLastmodifiedPole) |
1656 | { |
1657 | if (UIndex1 < 1 || UIndex1 > poles->UpperRow() || |
1658 | UIndex2 < 1 || UIndex2 > poles->UpperRow() || UIndex1 > UIndex2 || |
1659 | VIndex1 < 1 || VIndex1 > poles->UpperCol() || |
1660 | VIndex2 < 1 || VIndex2 > poles->UpperCol() || VIndex1 > VIndex2) { |
1661 | Standard_OutOfRange::Raise(); |
1662 | } |
1663 | |
1664 | TColgp_Array2OfPnt npoles(1, poles->UpperRow(), 1, poles->UpperCol()); |
1665 | gp_Pnt P0; |
1666 | D0(U, V, P0); |
1667 | gp_Vec Displ(P0, P); |
1668 | Standard_Boolean rational = (urational || vrational); |
1669 | BSplSLib::MovePoint(U, V, Displ, UIndex1, UIndex2, VIndex1, VIndex2, udeg, vdeg, |
1670 | rational, poles->Array2(), weights->Array2(), |
1671 | ufknots->Array1(), vfknots->Array1(), |
1672 | UFirstModifiedPole, ULastmodifiedPole, |
1673 | VFirstModifiedPole, VLastmodifiedPole, |
1674 | npoles); |
1675 | if (UFirstModifiedPole) { |
1676 | poles->ChangeArray2() = npoles; |
1677 | } |
1678 | maxderivinvok = 0; |
1679 | InvalidateCache() ; |
1680 | } |
1681 | |
1682 | //======================================================================= |
1683 | //function : Bounds |
1684 | //purpose : |
1685 | //======================================================================= |
1686 | |
1687 | void Geom_BSplineSurface::Bounds (Standard_Real& U1, |
1688 | Standard_Real& U2, |
1689 | Standard_Real& V1, |
1690 | Standard_Real& V2) const |
1691 | { |
1692 | U1 = ufknots->Value (udeg+1); |
1693 | U2 = ufknots->Value (ufknots->Upper()-udeg); |
1694 | V1 = vfknots->Value (vdeg+1); |
1695 | V2 = vfknots->Value (vfknots->Upper()-vdeg); |
1696 | } |
1697 | |
1698 | //======================================================================= |
1699 | //function : MaxDegree |
1700 | //purpose : |
1701 | //======================================================================= |
1702 | |
1703 | Standard_Integer Geom_BSplineSurface::MaxDegree () |
1704 | { |
1705 | return BSplCLib::MaxDegree(); |
1706 | } |
1707 | |
1708 | //======================================================================= |
1709 | //function : IsURational |
1710 | //purpose : |
1711 | //======================================================================= |
1712 | |
1713 | Standard_Boolean Geom_BSplineSurface::IsURational () const |
1714 | { |
1715 | return urational; |
1716 | } |
1717 | |
1718 | //======================================================================= |
1719 | //function : IsVRational |
1720 | //purpose : |
1721 | //======================================================================= |
1722 | |
1723 | Standard_Boolean Geom_BSplineSurface::IsVRational () const |
1724 | { |
1725 | return vrational; |
1726 | } |
1727 | |
1728 | //======================================================================= |
1729 | //function : Continuity |
1730 | //purpose : |
1731 | //======================================================================= |
1732 | |
1733 | GeomAbs_Shape Geom_BSplineSurface::Continuity () const |
1734 | { |
1735 | return ((Usmooth < Vsmooth) ? Usmooth : Vsmooth) ; |
1736 | } |
1737 | |
1738 | //======================================================================= |
1739 | //function : NbUKnots |
1740 | //purpose : |
1741 | //======================================================================= |
1742 | |
1743 | Standard_Integer Geom_BSplineSurface::NbUKnots () const |
1744 | { |
1745 | return uknots->Length(); |
1746 | } |
1747 | |
1748 | //======================================================================= |
1749 | //function : NbUPoles |
1750 | //purpose : |
1751 | //======================================================================= |
1752 | |
1753 | Standard_Integer Geom_BSplineSurface::NbUPoles () const |
1754 | { |
1755 | return poles->ColLength(); |
1756 | } |
1757 | |
1758 | //======================================================================= |
1759 | //function : NbVKnots |
1760 | //purpose : |
1761 | //======================================================================= |
1762 | |
1763 | Standard_Integer Geom_BSplineSurface::NbVKnots () const |
1764 | { |
1765 | return vknots->Length(); |
1766 | } |
1767 | |
1768 | //======================================================================= |
1769 | //function : NbVPoles |
1770 | //purpose : |
1771 | //======================================================================= |
1772 | |
1773 | Standard_Integer Geom_BSplineSurface::NbVPoles () const |
1774 | { |
1775 | return poles->RowLength(); |
1776 | } |
1777 | |
1778 | //======================================================================= |
1779 | //function : UDegree |
1780 | //purpose : |
1781 | //======================================================================= |
1782 | |
1783 | Standard_Integer Geom_BSplineSurface::UDegree () const |
1784 | { |
1785 | return udeg; |
1786 | } |
1787 | |
1788 | //======================================================================= |
1789 | //function : VDegree |
1790 | //purpose : |
1791 | //======================================================================= |
1792 | |
1793 | Standard_Integer Geom_BSplineSurface::VDegree () const |
1794 | { |
1795 | return vdeg; |
1796 | } |
1797 | |
1798 | //======================================================================= |
1799 | //function : UKnotDistribution |
1800 | //purpose : |
1801 | //======================================================================= |
1802 | |
1803 | GeomAbs_BSplKnotDistribution Geom_BSplineSurface::UKnotDistribution() const |
1804 | { |
1805 | return uknotSet; |
1806 | } |
1807 | |
1808 | |
1809 | //======================================================================= |
1810 | //function : VKnotDistribution |
1811 | //purpose : |
1812 | //======================================================================= |
1813 | |
1814 | GeomAbs_BSplKnotDistribution Geom_BSplineSurface::VKnotDistribution() const |
1815 | { |
1816 | return vknotSet; |
1817 | } |
1818 | |
1819 | //======================================================================= |
1820 | //function : InsertUKnots |
1821 | //purpose : |
1822 | //======================================================================= |
1823 | |
1824 | void Geom_BSplineSurface::InsertUKnots |
1825 | (const TColStd_Array1OfReal& Knots, |
1826 | const TColStd_Array1OfInteger& Mults, |
1827 | const Standard_Real ParametricTolerance, |
1828 | const Standard_Boolean Add) |
1829 | { |
1830 | // Check and compute new sizes |
1831 | Standard_Integer nbpoles, nbknots; |
1832 | |
1833 | if ( !BSplCLib::PrepareInsertKnots(udeg,uperiodic, |
1834 | uknots->Array1(),umults->Array1(), |
1835 | Knots,Mults,nbpoles,nbknots, |
1836 | ParametricTolerance,Add)) |
1837 | Standard_ConstructionError::Raise("Geom_BSplineSurface::InsertUKnots"); |
1838 | |
1839 | if ( nbpoles == poles->ColLength()) return; |
1840 | |
1841 | Handle(TColgp_HArray2OfPnt) npoles |
1842 | = new TColgp_HArray2OfPnt(1,nbpoles, 1,poles->RowLength()); |
1843 | Handle(TColStd_HArray2OfReal) nweights = |
1844 | new TColStd_HArray2OfReal(1,nbpoles, |
1845 | 1,poles->RowLength(), |
1846 | 1.0); |
1847 | Handle(TColStd_HArray1OfReal) nknots = uknots; |
1848 | Handle(TColStd_HArray1OfInteger) nmults = umults; |
1849 | |
1850 | if ( nbknots != uknots->Length()) { |
1851 | nknots = new TColStd_HArray1OfReal(1,nbknots); |
1852 | nmults = new TColStd_HArray1OfInteger(1,nbknots); |
1853 | } |
1854 | |
1855 | if ( urational || vrational) { |
1856 | BSplSLib::InsertKnots(Standard_True, |
1857 | udeg, uperiodic, |
1858 | poles->Array2() , weights->Array2(), |
1859 | uknots->Array1(), umults->Array1(), |
1860 | Knots, Mults, |
1861 | npoles->ChangeArray2(), |
1862 | nweights->ChangeArray2(), |
1863 | nknots->ChangeArray1(), nmults->ChangeArray1(), |
1864 | ParametricTolerance, Add); |
1865 | } |
1866 | else { |
1867 | BSplSLib::InsertKnots(Standard_True, |
1868 | udeg, uperiodic, |
1869 | poles->Array2() , BSplSLib::NoWeights(), |
1870 | uknots->Array1(), umults->Array1(), |
1871 | Knots, Mults, |
1872 | npoles->ChangeArray2(), |
1873 | *((TColStd_Array2OfReal*) NULL), |
1874 | nknots->ChangeArray1(), nmults->ChangeArray1(), |
1875 | ParametricTolerance, Add); |
1876 | } |
1877 | |
1878 | poles = npoles; |
1879 | weights = nweights; |
1880 | uknots = nknots; |
1881 | umults = nmults; |
1882 | UpdateUKnots(); |
1883 | |
1884 | } |
1885 | |
1886 | //======================================================================= |
1887 | //function : InsertVKnots |
1888 | //purpose : |
1889 | //======================================================================= |
1890 | |
1891 | void Geom_BSplineSurface::InsertVKnots |
1892 | (const TColStd_Array1OfReal& Knots, |
1893 | const TColStd_Array1OfInteger& Mults, |
1894 | const Standard_Real ParametricTolerance, |
1895 | const Standard_Boolean Add) |
1896 | { |
1897 | // Check and compute new sizes |
1898 | Standard_Integer nbpoles, nbknots; |
1899 | |
1900 | if ( !BSplCLib::PrepareInsertKnots(vdeg,vperiodic, |
1901 | vknots->Array1(),vmults->Array1(), |
1902 | Knots,Mults,nbpoles,nbknots, |
1903 | ParametricTolerance, Add)) |
1904 | Standard_ConstructionError::Raise("Geom_BSplineSurface::InsertVKnots"); |
1905 | |
1906 | if ( nbpoles == poles->RowLength()) return; |
1907 | |
1908 | Handle(TColgp_HArray2OfPnt) npoles |
1909 | = new TColgp_HArray2OfPnt(1,poles->ColLength(), 1,nbpoles); |
1910 | Handle(TColStd_HArray2OfReal) nweights = |
1911 | new TColStd_HArray2OfReal(1,poles->ColLength(), |
1912 | 1,nbpoles, |
1913 | 1.0); |
1914 | Handle(TColStd_HArray1OfReal) nknots = vknots; |
1915 | Handle(TColStd_HArray1OfInteger) nmults = vmults; |
1916 | |
1917 | if ( nbknots != vknots->Length()) { |
1918 | nknots = new TColStd_HArray1OfReal(1,nbknots); |
1919 | nmults = new TColStd_HArray1OfInteger(1,nbknots); |
1920 | } |
1921 | |
1922 | if ( urational || vrational) { |
1923 | BSplSLib::InsertKnots(Standard_False, |
1924 | vdeg, vperiodic, |
1925 | poles->Array2() , weights->Array2(), |
1926 | vknots->Array1(), vmults->Array1(), |
1927 | Knots, Mults, |
1928 | npoles->ChangeArray2(), |
1929 | nweights->ChangeArray2(), |
1930 | nknots->ChangeArray1(), nmults->ChangeArray1(), |
1931 | ParametricTolerance, Add); |
1932 | } |
1933 | else { |
1934 | BSplSLib::InsertKnots(Standard_False, |
1935 | vdeg, vperiodic, |
1936 | poles->Array2() , BSplSLib::NoWeights(), |
1937 | vknots->Array1(), vmults->Array1(), |
1938 | Knots, Mults, |
1939 | npoles->ChangeArray2(), |
1940 | *((TColStd_Array2OfReal*) NULL), |
1941 | nknots->ChangeArray1(), nmults->ChangeArray1(), |
1942 | ParametricTolerance, Add); |
1943 | } |
1944 | |
1945 | poles = npoles; |
1946 | weights = nweights; |
1947 | vknots = nknots; |
1948 | vmults = nmults; |
1949 | UpdateVKnots(); |
1950 | |
1951 | } |
1952 | |
1953 | //======================================================================= |
1954 | //function : RemoveUKnot |
1955 | //purpose : |
1956 | //======================================================================= |
1957 | |
1958 | Standard_Boolean Geom_BSplineSurface::RemoveUKnot |
1959 | (const Standard_Integer Index, |
1960 | const Standard_Integer M, |
1961 | const Standard_Real Tolerance) |
1962 | { |
1963 | if ( M < 0 ) return Standard_True; |
1964 | |
1965 | Standard_Integer I1 = FirstUKnotIndex (); |
1966 | Standard_Integer I2 = LastUKnotIndex (); |
1967 | |
1968 | if ( !uperiodic && (Index <= I1 || Index >= I2) ) { |
1969 | Standard_OutOfRange::Raise(); |
1970 | } |
1971 | else if ( uperiodic && (Index < I1 || Index > I2)) { |
1972 | Standard_OutOfRange::Raise(); |
1973 | } |
1974 | |
1975 | const TColgp_Array2OfPnt & oldpoles = poles->Array2(); |
1976 | |
1977 | Standard_Integer step = umults->Value(Index) - M; |
1978 | if (step <= 0 ) return Standard_True; |
1979 | |
1980 | Handle(TColgp_HArray2OfPnt) npoles = |
1981 | new TColgp_HArray2OfPnt( 1, oldpoles.ColLength() - step, |
1982 | 1, oldpoles.RowLength()); |
1983 | Handle(TColStd_HArray1OfReal) nknots = uknots; |
1984 | Handle(TColStd_HArray1OfInteger) nmults = umults; |
1985 | |
1986 | if ( M == 0) { |
1987 | nknots = new TColStd_HArray1OfReal(1,uknots->Length()-1); |
1988 | nmults = new TColStd_HArray1OfInteger(1,uknots->Length()-1); |
1989 | } |
1990 | Handle(TColStd_HArray2OfReal) nweights ; |
1991 | if (urational || vrational) { |
1992 | nweights = |
1993 | new TColStd_HArray2OfReal( 1, npoles->ColLength(), |
1994 | 1, npoles->RowLength()); |
1995 | if (!BSplSLib::RemoveKnot(Standard_True, |
1996 | Index,M,udeg,uperiodic, |
1997 | poles->Array2(),weights->Array2(), |
1998 | uknots->Array1(),umults->Array1(), |
1999 | npoles->ChangeArray2(), |
2000 | nweights->ChangeArray2(), |
2001 | nknots->ChangeArray1(),nmults->ChangeArray1(), |
2002 | Tolerance)) |
2003 | return Standard_False; |
2004 | } |
2005 | else { |
2006 | // |
2007 | // sync the size of the weights |
2008 | // |
2009 | nweights = |
2010 | new TColStd_HArray2OfReal(1, npoles->ColLength(), |
2011 | 1, npoles->RowLength(), |
2012 | 1.0e0 ); |
2013 | if (!BSplSLib::RemoveKnot(Standard_True, |
2014 | Index,M,udeg,uperiodic, |
2015 | poles->Array2(),BSplSLib::NoWeights(), |
2016 | uknots->Array1(),umults->Array1(), |
2017 | npoles->ChangeArray2(), |
2018 | *((TColStd_Array2OfReal*) NULL), |
2019 | nknots->ChangeArray1(),nmults->ChangeArray1(), |
2020 | Tolerance)) |
2021 | return Standard_False; |
2022 | } |
2023 | |
2024 | poles = npoles; |
2025 | weights = nweights; |
2026 | uknots = nknots; |
2027 | umults = nmults; |
2028 | |
2029 | maxderivinvok = 0; |
2030 | UpdateUKnots(); |
2031 | return Standard_True; |
2032 | } |
2033 | |
2034 | //======================================================================= |
2035 | //function : RemoveVKnot |
2036 | //purpose : |
2037 | //======================================================================= |
2038 | |
2039 | Standard_Boolean Geom_BSplineSurface::RemoveVKnot |
2040 | (const Standard_Integer Index, |
2041 | const Standard_Integer M, |
2042 | const Standard_Real Tolerance) |
2043 | { |
2044 | if ( M < 0 ) return Standard_True; |
2045 | |
2046 | Standard_Integer I1 = FirstVKnotIndex (); |
2047 | Standard_Integer I2 = LastVKnotIndex (); |
2048 | |
2049 | if ( !vperiodic && (Index <= I1 || Index >= I2) ) { |
2050 | Standard_OutOfRange::Raise(); |
2051 | } |
2052 | else if ( vperiodic && (Index < I1 || Index > I2)) { |
2053 | Standard_OutOfRange::Raise(); |
2054 | } |
2055 | |
2056 | const TColgp_Array2OfPnt & oldpoles = poles->Array2(); |
2057 | |
2058 | Standard_Integer step = vmults->Value(Index) - M; |
2059 | if (step <= 0 ) return Standard_True; |
2060 | |
2061 | Handle(TColgp_HArray2OfPnt) npoles = |
2062 | new TColgp_HArray2OfPnt( 1, oldpoles.ColLength(), |
2063 | 1, oldpoles.RowLength() - step); |
2064 | Handle(TColStd_HArray1OfReal) nknots = vknots; |
2065 | Handle(TColStd_HArray1OfInteger) nmults = vmults; |
2066 | |
2067 | if ( M == 0) { |
2068 | nknots = new TColStd_HArray1OfReal(1,vknots->Length()-1); |
2069 | nmults = new TColStd_HArray1OfInteger(1,vknots->Length()-1); |
2070 | } |
2071 | Handle(TColStd_HArray2OfReal) nweights ; |
2072 | if (urational || vrational) { |
2073 | nweights = |
2074 | new TColStd_HArray2OfReal( 1, npoles->ColLength(), |
2075 | 1, npoles->RowLength()) ; |
2076 | |
2077 | |
2078 | if (!BSplSLib::RemoveKnot(Standard_False, |
2079 | Index,M,vdeg,vperiodic, |
2080 | poles->Array2(),weights->Array2(), |
2081 | vknots->Array1(),vmults->Array1(), |
2082 | npoles->ChangeArray2(), |
2083 | nweights->ChangeArray2(), |
2084 | nknots->ChangeArray1(),nmults->ChangeArray1(), |
2085 | Tolerance)) |
2086 | return Standard_False; |
2087 | } |
2088 | else { |
2089 | // |
2090 | // sync the size of the weights array |
2091 | // |
2092 | nweights = |
2093 | new TColStd_HArray2OfReal(1, npoles->ColLength(), |
2094 | 1, npoles->RowLength(), |
2095 | 1.0e0 ); |
2096 | if (!BSplSLib::RemoveKnot(Standard_False, |
2097 | Index,M,vdeg,vperiodic, |
2098 | poles->Array2(),BSplSLib::NoWeights(), |
2099 | vknots->Array1(),vmults->Array1(), |
2100 | npoles->ChangeArray2(), |
2101 | *((TColStd_Array2OfReal*) NULL), |
2102 | nknots->ChangeArray1(),nmults->ChangeArray1(), |
2103 | Tolerance)) |
2104 | return Standard_False; |
2105 | } |
2106 | |
2107 | poles = npoles; |
2108 | vknots = nknots; |
2109 | vmults = nmults; |
2110 | weights = nweights; |
2111 | maxderivinvok = 0; |
2112 | UpdateVKnots(); |
2113 | return Standard_True; |
2114 | } |
2115 | |
2116 | //======================================================================= |
2117 | //function : Resolution |
2118 | //purpose : |
2119 | //======================================================================= |
2120 | |
2121 | void Geom_BSplineSurface::Resolution( const Standard_Real Tolerance3D, |
2122 | Standard_Real& UTolerance, |
2123 | Standard_Real& VTolerance) |
2124 | { |
2125 | if(!maxderivinvok){ |
2126 | BSplSLib::Resolution(poles ->Array2(), |
2127 | weights->Array2(), |
2128 | uknots ->Array1(), |
2129 | vknots ->Array1(), |
2130 | umults ->Array1(), |
2131 | vmults ->Array1(), |
2132 | udeg, |
2133 | vdeg, |
2134 | urational, |
2135 | vrational, |
2136 | uperiodic, |
2137 | vperiodic, |
2138 | 1., |
2139 | umaxderivinv, |
2140 | vmaxderivinv) ; |
2141 | maxderivinvok = 1; |
2142 | } |
2143 | UTolerance = Tolerance3D * umaxderivinv; |
2144 | VTolerance = Tolerance3D * vmaxderivinv; |
2145 | } |
2146 | |
2147 | |
2148 | |
2149 | |