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