664fd90495ca83fe3dc174dfb6cd6e8ce18ae4d0
[occt.git] / src / Geom / Geom_BezierSurface.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 //Passage en classe persistante - 23/01/91
18 //Modif suite a la deuxieme revue de projet toolkit Geometry -23/01/91
19 // pmn : 21/10/95 ; Correction de la methode segment (PRO5853)
20 // pmn : 31-Dec-96; Bonne gestion des poids (bug PRO4622)
21 // xab : 07-Jul-97; le cache est instable en degree 21
22 //       a partir du degree 15 on ne l'utilise plus
23 // RBD : 15/10/98 ; Le cache est desormais defini sur [-1,1] (pro15537).
24 // pmn : 10/12/98 ; Update de la methode segment (suite a la modif de cache).
25
26 #define No_Standard_OutOfRange
27 #define No_Standard_DimensionError
28
29
30 #include <BSplCLib.hxx>
31 #include <Geom_BezierCurve.hxx>
32 #include <Geom_BezierSurface.hxx>
33 #include <Geom_Curve.hxx>
34 #include <Geom_Geometry.hxx>
35 #include <gp.hxx>
36 #include <gp_Pnt.hxx>
37 #include <gp_Trsf.hxx>
38 #include <gp_Vec.hxx>
39 #include <gp_XYZ.hxx>
40 #include <PLib.hxx>
41 #include <Precision.hxx>
42 #include <Standard_ConstructionError.hxx>
43 #include <Standard_DimensionError.hxx>
44 #include <Standard_OutOfRange.hxx>
45 #include <Standard_RangeError.hxx>
46 #include <Standard_Type.hxx>
47 #include <TColStd_Array1OfInteger.hxx>
48
49 IMPLEMENT_STANDARD_RTTIEXT(Geom_BezierSurface,Geom_BoundedSurface)
50
51 //=======================================================================
52 //function : Rational
53 //purpose  : check rationality of an array of weights
54 //=======================================================================
55 static void Rational(const TColStd_Array2OfReal& Weights,
56                      Standard_Boolean& Urational,
57                      Standard_Boolean& Vrational)
58 {
59   Standard_Integer I,J;
60   J = Weights.LowerCol ();
61   Vrational = Standard_False;
62   while (!Vrational && J <= Weights.UpperCol()) {
63     I = Weights.LowerRow();
64     while (!Vrational && I <= Weights.UpperRow() - 1) {
65       Vrational = (Abs(Weights (I, J) - Weights (I+1, J)) 
66                    > Epsilon (Abs(Weights (I, J))));
67       I++;
68     }
69     J++;
70   }
71
72   I = Weights.LowerRow ();
73   Urational = Standard_False;
74   while (!Urational && I <= Weights.UpperRow()) {
75     J = Weights.LowerCol();
76     while (!Urational && J <= Weights.UpperCol() - 1) {
77       Urational = (Abs(Weights (I, J) - Weights (I, J+1))
78                    > Epsilon (Abs(Weights (I, J))));
79       J++;
80     }
81     I++;
82   }
83 }
84
85 //=======================================================================
86 //function : AddPoleCol
87 //purpose  : Internal use only.
88 //=======================================================================
89
90 static void AddPoleCol
91   (const TColgp_Array2OfPnt& Poles,
92    const TColgp_Array1OfPnt& PoleCol,
93    const Standard_Integer    AfterIndex,
94          TColgp_Array2OfPnt& NewPoles)
95 {
96   Standard_Integer InsertIndex = AfterIndex + NewPoles.LowerCol();
97   Standard_Integer Offset = NewPoles.LowerRow() - PoleCol.Lower();
98   Standard_Integer ColIndex = NewPoles.LowerCol();
99   Standard_Integer RowIndex;
100   while (ColIndex < InsertIndex) {
101     RowIndex = NewPoles.LowerRow();
102     while (RowIndex <= NewPoles.UpperRow()){
103       NewPoles (RowIndex, ColIndex) =  Poles (RowIndex, ColIndex);
104       RowIndex++;
105     }
106     ColIndex++;
107   }
108   RowIndex = NewPoles.LowerRow();
109   while (RowIndex <= NewPoles.UpperRow()){
110     NewPoles (RowIndex, ColIndex) = PoleCol (RowIndex - Offset);
111     RowIndex++;
112   }
113   ColIndex++;
114   while (ColIndex <= NewPoles.UpperCol()) {
115     RowIndex = NewPoles.LowerRow();
116     while (RowIndex <= NewPoles.UpperRow()){
117       NewPoles (RowIndex, ColIndex) =  Poles (RowIndex, ColIndex - 1);
118       RowIndex++;
119     }
120     ColIndex++;
121   }
122 }
123
124 //=======================================================================
125 //function : AddRatPoleCol
126 //purpose  : Internal use only.
127 //=======================================================================
128
129 static void AddRatPoleCol
130   (const TColgp_Array2OfPnt&   Poles,
131    const TColStd_Array2OfReal& Weights,
132    const TColgp_Array1OfPnt&   PoleCol,
133    const TColStd_Array1OfReal& PoleWeightCol,
134    const Standard_Integer      AfterIndex,
135          TColgp_Array2OfPnt&   NewPoles,
136          TColStd_Array2OfReal& NewWeights)
137 {
138   Standard_Integer InsertIndex = AfterIndex + NewPoles.LowerCol();
139   Standard_Integer OffsetPol   = NewPoles.LowerRow() - PoleCol.Lower();
140   Standard_Integer OffsetW     = NewWeights.LowerRow() - PoleWeightCol.Lower();
141   
142   Standard_Integer ColIndex = NewPoles.LowerCol();
143   Standard_Integer RowIndex;
144   while (ColIndex < InsertIndex) {
145     RowIndex = NewPoles.LowerRow();
146     while (RowIndex <= NewPoles.UpperRow()){
147       NewPoles (RowIndex, ColIndex) = Poles (RowIndex, ColIndex);
148       NewWeights (RowIndex, ColIndex)  =  Weights (RowIndex, ColIndex);
149       RowIndex++;
150     }
151     ColIndex++;
152   }
153   RowIndex = NewPoles.LowerRow();
154   while (RowIndex <= NewPoles.UpperRow()){
155     NewPoles (RowIndex, ColIndex) = PoleCol (RowIndex - OffsetPol);
156     NewWeights (RowIndex, ColIndex) =  PoleWeightCol (RowIndex - OffsetW);
157     RowIndex++;
158   }
159   ColIndex++;
160   while (ColIndex <= NewPoles.UpperCol()) {
161     RowIndex = NewPoles.LowerRow();
162     while (RowIndex <= NewPoles.UpperRow()){
163       NewPoles (RowIndex, ColIndex) = Poles (RowIndex, ColIndex - 1);
164       RowIndex++;
165       NewWeights (RowIndex, ColIndex)  = Weights (RowIndex, ColIndex - 1);
166     }
167     ColIndex++;
168   }
169 }
170
171 //=======================================================================
172 //function : AddPoleRow
173 //purpose  : Internal use only.
174 //=======================================================================
175
176 static void AddPoleRow
177   (const TColgp_Array2OfPnt& Poles,
178    const TColgp_Array1OfPnt& PoleRow,
179    const Standard_Integer    AfterIndex,
180          TColgp_Array2OfPnt& NewPoles)
181 {
182   Standard_Integer InsertIndex = AfterIndex + NewPoles.LowerRow();
183   Standard_Integer Offset = NewPoles.LowerCol() - PoleRow.Lower();
184   Standard_Integer RowIndex = NewPoles.LowerRow();
185   Standard_Integer ColIndex;
186   while (RowIndex < InsertIndex) {
187     ColIndex = NewPoles.LowerCol();
188     while (ColIndex <= NewPoles.UpperCol()){
189       NewPoles (RowIndex, ColIndex) = Poles (RowIndex, ColIndex);
190       ColIndex++;
191     }
192     RowIndex++;
193   }
194   ColIndex = NewPoles.LowerCol();
195   while (ColIndex <= NewPoles.UpperCol()){
196     NewPoles (RowIndex, ColIndex) = PoleRow (ColIndex - Offset);
197     ColIndex++;
198   }
199   RowIndex++;
200   while (RowIndex <= NewPoles.UpperRow()) {
201     ColIndex = NewPoles.LowerCol();
202     while (ColIndex <= NewPoles.UpperCol()){
203       NewPoles (RowIndex, ColIndex) = Poles (RowIndex - 1, ColIndex);
204       ColIndex++;
205     }
206     RowIndex++;
207   }
208 }
209
210 //=======================================================================
211 //function : AddRatPoleRow
212 //purpose  : 
213 //=======================================================================
214
215 static void AddRatPoleRow
216   (const TColgp_Array2OfPnt&   Poles,
217    const TColStd_Array2OfReal& Weights,
218    const TColgp_Array1OfPnt&   PoleRow,
219    const TColStd_Array1OfReal& PoleWeightRow,
220    const Standard_Integer      AfterIndex,
221          TColgp_Array2OfPnt&   NewPoles,
222          TColStd_Array2OfReal& NewWeights)
223 {
224   Standard_Integer InsertIndex = AfterIndex + NewPoles.LowerRow();
225   Standard_Integer OffsetPol = NewPoles.LowerCol() - PoleRow.Lower();
226   Standard_Integer OffsetW = NewWeights.LowerCol() - PoleWeightRow.Lower();
227   
228   Standard_Integer ColIndex;
229   Standard_Integer RowIndex = NewPoles.LowerRow();
230   while (RowIndex < InsertIndex) {
231     ColIndex = NewPoles.LowerCol();
232     while (ColIndex <= NewPoles.UpperCol()){
233       NewPoles (RowIndex, ColIndex) =  Poles (RowIndex, ColIndex);
234       NewWeights (RowIndex, ColIndex)  =  Weights (RowIndex, ColIndex);
235       ColIndex++;
236     }
237     RowIndex++;
238   }
239   ColIndex = NewPoles.LowerCol();
240   while (ColIndex <= NewPoles.UpperCol()){
241     NewPoles (RowIndex, ColIndex) = PoleRow (ColIndex - OffsetPol);
242     NewWeights (RowIndex, ColIndex) = PoleWeightRow (ColIndex - OffsetW);
243     ColIndex++;
244   }
245   RowIndex++;
246   while (RowIndex <= NewPoles.UpperRow()) {
247     ColIndex = NewPoles.LowerCol();
248     while (ColIndex <= NewPoles.UpperCol()){
249       NewPoles (RowIndex, ColIndex) = Poles (RowIndex - 1, ColIndex);
250       NewWeights (RowIndex, ColIndex)  = Weights (RowIndex - 1, ColIndex);
251       ColIndex++;
252     }
253     RowIndex++;
254   }
255 }
256
257 //=======================================================================
258 //function : DeletePoleCol
259 //purpose  : 
260 //=======================================================================
261
262 static void DeletePoleCol
263   (const TColgp_Array2OfPnt& Poles,
264    const Standard_Integer    Index,
265          TColgp_Array2OfPnt& NewPoles)
266 {
267   Standard_Integer Offset = 0;
268   Standard_Integer RowIndex;
269   Standard_Integer ColIndex = NewPoles.LowerCol();
270   while (ColIndex <= NewPoles.UpperCol()) {
271     RowIndex = NewPoles.LowerRow();
272     if (ColIndex == Index)  Offset = 1;
273     while (RowIndex <= NewPoles.UpperRow()){
274       NewPoles (RowIndex, ColIndex) = Poles (RowIndex, ColIndex + Offset);
275       RowIndex++;
276     }
277     ColIndex++;
278   }
279 }
280
281 //=======================================================================
282 //function : DeleteRatPoleCol
283 //purpose  : 
284 //=======================================================================
285
286 static void DeleteRatPoleCol
287   (const TColgp_Array2OfPnt&   Poles,
288    const TColStd_Array2OfReal& Weights,
289    const Standard_Integer      Index,
290          TColgp_Array2OfPnt&   NewPoles,
291          TColStd_Array2OfReal& NewWeights)
292 {
293   Standard_Integer Offset = 0;
294   Standard_Integer RowIndex;
295   Standard_Integer ColIndex = NewPoles.LowerCol();
296   while (ColIndex <= NewPoles.UpperCol()) {
297     RowIndex = NewPoles.LowerRow();
298     if (ColIndex == Index) Offset = 1;
299     while (RowIndex <= NewPoles.UpperRow()){
300       NewPoles (RowIndex, ColIndex) = Poles (RowIndex, ColIndex + Offset);
301       NewWeights (RowIndex, ColIndex) = Weights (RowIndex, ColIndex+Offset);
302       RowIndex++;
303     }
304     ColIndex++;
305   }
306 }
307
308 //=======================================================================
309 //function : DeletePoleRow
310 //purpose  : 
311 //=======================================================================
312
313 static void DeletePoleRow
314   (const TColgp_Array2OfPnt& Poles,
315    const Standard_Integer    Index,
316          TColgp_Array2OfPnt& NewPoles)
317 {
318   Standard_Integer Offset = 0;
319   Standard_Integer ColIndex;
320   Standard_Integer RowIndex = NewPoles.LowerRow();
321   while (RowIndex <= NewPoles.UpperRow()) {
322     ColIndex = NewPoles.LowerCol();
323     if (RowIndex == Index)  Offset = 1;
324     while (ColIndex <= NewPoles.UpperCol()){
325       NewPoles (RowIndex, ColIndex) = Poles (RowIndex + Offset, ColIndex);
326       ColIndex++;
327     }
328     RowIndex++;
329   }
330 }
331
332 //=======================================================================
333 //function : DeleteRatPoleRow
334 //purpose  : 
335 //=======================================================================
336
337 static void DeleteRatPoleRow
338   (const TColgp_Array2OfPnt&   Poles,
339    const TColStd_Array2OfReal& Weights,
340    const Standard_Integer      Index,
341          TColgp_Array2OfPnt&   NewPoles,
342          TColStd_Array2OfReal& NewWeights)
343 {
344   Standard_Integer Offset = 0;
345   Standard_Integer ColIndex;
346   Standard_Integer RowIndex = NewPoles.LowerRow();
347   while (RowIndex <= NewPoles.UpperRow()) {
348     ColIndex = NewPoles.LowerCol();
349     if (RowIndex == Index)  Offset = 1;
350     while (ColIndex <= NewPoles.UpperCol()){
351       NewPoles (RowIndex, ColIndex) =  Poles (RowIndex +  Offset, ColIndex);
352       NewWeights (RowIndex, ColIndex) = Weights (RowIndex+Offset, ColIndex);
353       ColIndex++;
354     }
355     RowIndex++;
356   }
357 }
358
359 //=======================================================================
360 //function : Geom_BezierSurface
361 //purpose  : 
362 //=======================================================================
363
364 Geom_BezierSurface::Geom_BezierSurface 
365 (const TColgp_Array2OfPnt& SurfacePoles):
366  maxderivinvok(Standard_False)
367 {
368   Standard_Integer NbUPoles = SurfacePoles.ColLength();
369   Standard_Integer NbVPoles = SurfacePoles.RowLength();
370   if (NbUPoles < 2 || NbUPoles > MaxDegree()+1 ||
371       NbVPoles < 2 || NbVPoles > MaxDegree()+1) {
372     throw Standard_ConstructionError();
373   }
374   
375   Handle(TColgp_HArray2OfPnt) npoles = 
376     new TColgp_HArray2OfPnt   (1, NbUPoles, 1, NbVPoles);
377   
378   urational = 0;
379   vrational = 0;
380
381   npoles->ChangeArray2() = SurfacePoles;
382   
383   // Init non rational
384   Init(npoles,
385        Handle(TColStd_HArray2OfReal)());
386 }
387
388 //=======================================================================
389 //function : Geom_BezierSurface
390 //purpose  : 
391 //=======================================================================
392
393 Geom_BezierSurface::Geom_BezierSurface 
394   (const TColgp_Array2OfPnt&   SurfacePoles,
395    const TColStd_Array2OfReal& PoleWeights  ):
396  maxderivinvok(Standard_False)
397 {
398   Standard_Integer NbUPoles = SurfacePoles.ColLength();
399   Standard_Integer NbVPoles = SurfacePoles.RowLength();
400   if (NbUPoles < 2 || NbUPoles > MaxDegree()+1 ||
401       NbVPoles < 2 || NbVPoles > MaxDegree()+1 ||
402       NbVPoles != PoleWeights.RowLength()      ||
403       NbUPoles != PoleWeights.ColLength()      ) {
404     throw Standard_ConstructionError();
405   }
406   
407   Standard_Integer Row = PoleWeights.LowerRow();
408   Standard_Integer Col = PoleWeights.LowerCol();
409   while (Col <= PoleWeights.UpperCol()) {
410     Row = PoleWeights.LowerRow();
411     while (Row <= PoleWeights.UpperRow()) {
412       if (PoleWeights(Row, Col) <= gp::Resolution()) {
413         throw Standard_ConstructionError();
414       }
415       Row++;
416     }
417     Col++;
418   }
419   
420   Handle(TColgp_HArray2OfPnt) 
421     npoles = new TColgp_HArray2OfPnt   (1, NbUPoles, 1, NbVPoles);
422   npoles->ChangeArray2() = SurfacePoles;
423
424   Standard_Integer I, J;
425   urational = Standard_False;
426   vrational = Standard_False;
427   J = PoleWeights.LowerCol ();
428   while (!vrational && J <= PoleWeights.UpperCol()) {
429     I = PoleWeights.LowerRow();
430     while (!vrational && I <= PoleWeights.UpperRow() - 1) {
431       vrational = (Abs(PoleWeights (I, J) - PoleWeights (I+1, J)) 
432                    > Epsilon (Abs(PoleWeights (I, J))));
433       I++;
434     }
435     J++;
436   }
437   I = PoleWeights.LowerRow ();
438   while (!urational && I <= PoleWeights.UpperRow()) {
439     J = PoleWeights.LowerCol();
440     while (!urational && J <= PoleWeights.UpperCol() - 1) {
441       urational = (Abs(PoleWeights (I, J) - PoleWeights (I, J+1))
442                    > Epsilon (Abs(PoleWeights (I, J))));
443       J++;
444     }
445     I++;
446   }
447
448
449   Handle(TColStd_HArray2OfReal) nweights; 
450   if (urational || vrational) {
451     nweights = new TColStd_HArray2OfReal (1, NbUPoles, 1, NbVPoles);
452     nweights->ChangeArray2() = PoleWeights;
453   }
454
455   // Init
456   Init(npoles,nweights);
457 }
458
459 //=======================================================================
460 //function : Geom_BezierSurface
461 //purpose  : 
462 //=======================================================================
463
464 Geom_BezierSurface::Geom_BezierSurface
465   (const Handle(TColgp_HArray2OfPnt)&   SurfacePoles,
466    const Handle(TColStd_HArray2OfReal)& PoleWeights,
467    const Standard_Boolean               IsURational,
468    const Standard_Boolean               IsVRational)
469 :maxderivinvok(Standard_False)
470 {
471   urational = IsURational;
472   vrational = IsVRational;
473   Standard_Integer NbUPoles = SurfacePoles->ColLength();
474   Standard_Integer NbVPoles = SurfacePoles->RowLength();
475
476   poles    = new TColgp_HArray2OfPnt   (1,NbUPoles,
477                                         1,NbVPoles) ;
478   poles->ChangeArray2() = SurfacePoles->Array2();
479
480   if ( urational || vrational) {
481     weights  = new TColStd_HArray2OfReal (1,NbUPoles,1,NbVPoles);
482     weights->ChangeArray2() = PoleWeights->Array2();
483   }
484 }
485
486 //=======================================================================
487 //function : MaxDegree
488 //purpose  : 
489 //=======================================================================
490
491 Standard_Integer Geom_BezierSurface::MaxDegree () 
492
493   return BSplCLib::MaxDegree(); 
494 }
495
496 //=======================================================================
497 //function : ExchangeUV
498 //purpose  : 
499 //=======================================================================
500
501 void Geom_BezierSurface::ExchangeUV ()
502 {
503   Standard_Integer LC = poles->LowerCol();
504   Standard_Integer UC = poles->UpperCol();
505   Standard_Integer LR = poles->LowerRow();
506   Standard_Integer UR = poles->UpperRow();
507
508   Handle(TColgp_HArray2OfPnt) npoles = new TColgp_HArray2OfPnt (LC, UC, LR, UR);
509   Handle(TColStd_HArray2OfReal) nweights;
510   if (!weights.IsNull())
511   {
512     nweights = new TColStd_HArray2OfReal (LC, UC, LR, UR);
513   }
514
515   const TColgp_Array2OfPnt& spoles = poles->Array2();
516   const TColStd_Array2OfReal* sweights = !weights.IsNull() ? &weights->Array2() : NULL;
517
518   TColgp_Array2OfPnt& snpoles = npoles->ChangeArray2();
519   TColStd_Array2OfReal* snweights = !nweights.IsNull() ? &nweights->ChangeArray2() : NULL;
520   for (Standard_Integer i = LC; i <= UC; i++)
521   {
522     for (Standard_Integer j = LR; j <= UR; j++)
523     {
524       snpoles (i, j) = spoles (j, i);
525       if (snweights != NULL)
526       {
527         snweights->ChangeValue (i, j) = sweights->Value (j, i);
528       }
529     }
530   }
531   poles   = npoles;
532   weights = nweights;
533
534   std::swap (urational, vrational);
535 }
536
537 //=======================================================================
538 //function : Increase
539 //purpose  : 
540 //=======================================================================
541
542 void Geom_BezierSurface::Increase (const Standard_Integer UDeg,
543                                    const Standard_Integer VDeg)
544 {
545   if (UDeg < UDegree() || UDeg > Geom_BezierSurface::MaxDegree() ||
546       VDeg < VDegree() || VDeg > Geom_BezierSurface::MaxDegree() )  {
547     throw Standard_ConstructionError();
548   }
549
550   Standard_Integer oldUDeg = UDegree();
551   Standard_Integer oldVDeg = VDegree();
552   Standard_Integer IncUDeg = UDeg - oldUDeg;
553   Standard_Integer IncVDeg = VDeg - oldVDeg;
554   if (IncUDeg == 0 && IncVDeg == 0) return;
555   
556   TColStd_Array1OfReal biduknots(1,2); biduknots(1) = 0.; biduknots(2) = 1.;
557   TColStd_Array1OfInteger bidumults(1,2); bidumults.Init(UDegree() + 1);
558   TColStd_Array1OfReal bidvknots(1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
559   TColStd_Array1OfInteger bidvmults(1,2); bidvmults.Init(VDegree() + 1);
560   Handle(TColgp_HArray2OfPnt) npoles;
561   Handle(TColStd_HArray2OfReal) nweights;
562
563   if(IncUDeg > 0){
564     npoles = new TColgp_HArray2OfPnt( 1, UDeg + 1, 1, oldVDeg + 1);
565     
566     if ( urational || vrational) {
567       nweights = new TColStd_HArray2OfReal( 1, UDeg + 1, 1, VDegree() + 1);
568       
569       BSplSLib::IncreaseDegree(1, oldUDeg, UDeg, 0,
570                                poles->Array2(),
571                                &weights->Array2(),
572                                biduknots, bidumults,
573                                npoles->ChangeArray2(), 
574                                &nweights->ChangeArray2(),
575                                biduknots, bidumults);
576       weights = nweights;
577     }
578     else {
579       BSplSLib::IncreaseDegree(1, oldUDeg, UDeg, 0,
580                                poles->Array2(),
581                                BSplSLib::NoWeights(),
582                                biduknots, bidumults,
583                                npoles->ChangeArray2(), 
584                                BSplSLib::NoWeights(),
585                                biduknots, bidumults);
586     }
587     poles   = npoles;
588   }
589   if(IncVDeg > 0){
590     npoles = new TColgp_HArray2OfPnt( 1, UDeg + 1, 1, VDeg + 1);
591     
592     if ( urational || vrational) {
593       nweights = new TColStd_HArray2OfReal( 1, UDeg + 1, 1, VDeg + 1);
594       
595       BSplSLib::IncreaseDegree(0, oldVDeg, VDeg, 0,
596                                poles->Array2(),
597                                &weights->Array2(),
598                                bidvknots, bidvmults,
599                                npoles->ChangeArray2(), 
600                                &nweights->ChangeArray2(),
601                                bidvknots, bidvmults);
602       weights = nweights;
603     }
604     else {
605       BSplSLib::IncreaseDegree(0, oldVDeg, VDeg, 0,
606                                poles->Array2(),
607                                BSplSLib::NoWeights(),
608                                bidvknots, bidvmults,
609                                npoles->ChangeArray2(), 
610                                BSplSLib::NoWeights(),
611                                bidvknots, bidvmults);
612       
613     }
614     poles   = npoles;
615   }
616   Init(npoles,nweights);
617 }
618
619 //=======================================================================
620 //function : InsertPoleColAfter
621 //purpose  : 
622 //=======================================================================
623
624 void Geom_BezierSurface::InsertPoleColAfter 
625   (const Standard_Integer    VIndex,
626    const TColgp_Array1OfPnt& CPoles)
627 {
628   const TColgp_Array2OfPnt & Poles = poles->Array2();
629   if (VIndex < 1 || VIndex > Poles.RowLength())  throw Standard_OutOfRange();
630   if (CPoles.Length() != Poles.ColLength()) {
631     throw Standard_ConstructionError();
632   }
633
634   Handle(TColgp_HArray2OfPnt) npoles =
635     new TColgp_HArray2OfPnt(1,poles->ColLength(),1,poles->RowLength()+1);
636
637   Handle(TColStd_HArray2OfReal) nweights;
638
639   if (urational || vrational) {
640     nweights = 
641       new TColStd_HArray2OfReal(1,poles->ColLength(),1,poles->RowLength()+1);
642
643     TColStd_Array1OfReal CWeights(nweights->LowerRow(),nweights->UpperRow());
644     CWeights.Init(1.);
645
646     AddRatPoleCol (poles->Array2(), weights->Array2(),
647                    CPoles, CWeights, VIndex,
648                    npoles->ChangeArray2(), nweights->ChangeArray2());
649   }
650   else {
651     AddPoleCol (poles->Array2(), 
652                 CPoles, VIndex,
653                 npoles->ChangeArray2());
654   }
655   poles   = npoles;
656   weights = nweights;
657 }
658
659 //=======================================================================
660 //function : InsertPoleColAfter
661 //purpose  : 
662 //=======================================================================
663
664 void Geom_BezierSurface::InsertPoleColAfter
665   (const Standard_Integer      VIndex,
666    const TColgp_Array1OfPnt&   CPoles,
667    const TColStd_Array1OfReal& CPoleWeights)
668 {
669   const TColgp_Array2OfPnt & Poles = poles->Array2();
670   if (VIndex < 1 || VIndex > Poles.RowLength())  throw Standard_OutOfRange();
671   if (CPoles.Length() != Poles.ColLength() ||
672       CPoleWeights.Length() != CPoles.Length()) {
673     throw Standard_ConstructionError();
674     }
675   Standard_Integer Index = CPoleWeights.Lower();
676   while (Index <= CPoleWeights.Upper()) {
677     if (CPoleWeights (Index) <= gp::Resolution()) {
678       throw Standard_ConstructionError();
679       }
680     Index++;
681   }
682
683   Handle(TColgp_HArray2OfPnt) npoles =
684     new TColgp_HArray2OfPnt(1,poles->ColLength(),1,poles->RowLength()+1);
685   
686   Handle(TColStd_HArray2OfReal) nweights = 
687     new TColStd_HArray2OfReal(1,poles->ColLength(),1,poles->RowLength()+1);
688   
689   AddRatPoleCol (poles->Array2(), weights->Array2(),
690                  CPoles, CPoleWeights, VIndex,
691                  npoles->ChangeArray2(), nweights->ChangeArray2());
692
693   poles   = npoles;
694   weights = nweights;
695
696   Rational(weights->Array2(), urational, vrational);
697 }
698
699 //=======================================================================
700 //function : InsertPoleColBefore
701 //purpose  : 
702 //=======================================================================
703
704 void Geom_BezierSurface::InsertPoleColBefore (const Standard_Integer VIndex,
705                                               const TColgp_Array1OfPnt& CPoles)
706 {
707   InsertPoleColAfter(VIndex - 1, CPoles);
708 }
709
710 //=======================================================================
711 //function : InsertPoleColBefore
712 //purpose  : 
713 //=======================================================================
714
715 void Geom_BezierSurface::InsertPoleColBefore
716   (const Standard_Integer      VIndex,
717    const TColgp_Array1OfPnt&   CPoles,
718    const TColStd_Array1OfReal& CPoleWeights)
719 {
720   InsertPoleColAfter( VIndex - 1, CPoles, CPoleWeights);
721 }
722
723 //=======================================================================
724 //function : InsertPoleRowAfter
725 //purpose  : 
726 //=======================================================================
727
728 void Geom_BezierSurface::InsertPoleRowAfter (const Standard_Integer UIndex,
729                                              const TColgp_Array1OfPnt& CPoles)
730 {
731   const TColgp_Array2OfPnt & Poles = poles->Array2();
732   if (UIndex < 1 || UIndex > Poles.ColLength())  throw Standard_OutOfRange();
733   if (CPoles.Length() != Poles.RowLength()) {
734     throw Standard_ConstructionError();
735   }
736
737   Handle(TColgp_HArray2OfPnt) npoles =
738     new TColgp_HArray2OfPnt(1,poles->ColLength()+1,1,poles->RowLength());
739
740   Handle(TColStd_HArray2OfReal) nweights;
741
742   if (urational || vrational) {
743     nweights = 
744       new TColStd_HArray2OfReal(1,poles->ColLength()+1,1,poles->RowLength());
745
746 //    TColStd_Array1OfReal CWeights(nweights->LowerCol(),nweights->UpperCol(),
747 //                                1.0); ???????????
748     TColStd_Array1OfReal CWeights(1.0,
749                                   nweights->LowerCol(),nweights->UpperCol());
750
751     AddRatPoleRow (poles->Array2(), weights->Array2(),
752                    CPoles, CWeights, UIndex,
753                    npoles->ChangeArray2(), nweights->ChangeArray2());
754   }
755   else {
756     AddPoleRow (poles->Array2(), 
757                 CPoles, UIndex,
758                 npoles->ChangeArray2());
759   }
760   poles   = npoles;
761   weights = nweights;
762 }
763
764 //=======================================================================
765 //function : InsertPoleRowAfter
766 //purpose  : 
767 //=======================================================================
768
769 void Geom_BezierSurface::InsertPoleRowAfter
770   (const Standard_Integer      UIndex,
771    const TColgp_Array1OfPnt&   CPoles,
772    const TColStd_Array1OfReal& CPoleWeights)
773 {
774   const TColgp_Array2OfPnt & Poles = poles->Array2();
775   if (UIndex < 1 || UIndex > Poles.ColLength())  throw Standard_OutOfRange();
776   if (CPoles.Length() != Poles.RowLength() ||
777       CPoleWeights.Length() != CPoles.Length()) {
778     throw Standard_ConstructionError();
779   }
780   Standard_Integer Index = CPoleWeights.Lower();
781   while (Index <= CPoleWeights.Upper()) {
782     if (CPoleWeights(Index) <= gp::Resolution()) {
783       throw Standard_ConstructionError();
784     }
785     Index++;
786   }
787
788   Handle(TColgp_HArray2OfPnt) npoles =
789     new TColgp_HArray2OfPnt(1,poles->ColLength()+1,1,poles->RowLength());
790   
791   Handle(TColStd_HArray2OfReal) nweights = 
792     new TColStd_HArray2OfReal(1,poles->ColLength()+1,1,poles->RowLength());
793   
794   AddRatPoleCol (poles->Array2(), weights->Array2(),
795                  CPoles, CPoleWeights, UIndex,
796                  npoles->ChangeArray2(), nweights->ChangeArray2());
797
798   poles   = npoles;
799   weights = nweights;
800
801   Rational(weights->Array2(), urational, vrational);
802 }
803
804 //=======================================================================
805 //function : InsertPoleRowBefore
806 //purpose  : 
807 //=======================================================================
808
809 void Geom_BezierSurface::InsertPoleRowBefore (const Standard_Integer UIndex,
810                                               const TColgp_Array1OfPnt& CPoles)
811 {
812   InsertPoleRowAfter( UIndex - 1, CPoles);
813 }
814
815 //=======================================================================
816 //function : InsertPoleRowBefore
817 //purpose  : 
818 //=======================================================================
819
820 void Geom_BezierSurface::InsertPoleRowBefore
821   (const Standard_Integer      UIndex, 
822    const TColgp_Array1OfPnt&   CPoles,
823    const TColStd_Array1OfReal& CPoleWeights)
824 {
825   InsertPoleRowAfter( UIndex - 1, CPoles, CPoleWeights);
826
827
828 //=======================================================================
829 //function : RemovePoleCol
830 //purpose  : 
831 //=======================================================================
832
833 void Geom_BezierSurface::RemovePoleCol (const Standard_Integer VIndex)
834 {
835   const TColgp_Array2OfPnt & Poles = poles->Array2();
836   if (VIndex < 1 || VIndex > Poles.RowLength())  throw Standard_OutOfRange();
837   if (Poles.RowLength() <= 2)             throw Standard_ConstructionError();
838
839   Handle(TColgp_HArray2OfPnt) npoles =
840     new TColgp_HArray2OfPnt(1,poles->ColLength(),1,poles->RowLength()-1);
841
842   Handle(TColStd_HArray2OfReal) nweights;
843
844   if (urational || vrational) {
845     nweights = 
846       new TColStd_HArray2OfReal(1,poles->ColLength(),1,poles->RowLength()-1);
847
848     DeleteRatPoleCol (poles->Array2(), weights->Array2(),
849                       VIndex,
850                       npoles->ChangeArray2(), nweights->ChangeArray2());
851     // Mise a jour de la rationalite
852     Rational(nweights->Array2(), urational, vrational);
853   }
854   else {
855     DeletePoleCol (poles->Array2(), 
856                    VIndex,
857                    npoles->ChangeArray2());
858   }
859   poles   = npoles;
860   weights = nweights;
861 }
862
863 //=======================================================================
864 //function : RemovePoleRow
865 //purpose  : 
866 //=======================================================================
867
868 void Geom_BezierSurface::RemovePoleRow (const Standard_Integer UIndex)
869 {
870   const TColgp_Array2OfPnt & Poles = poles->Array2();
871   if (UIndex < 1 || UIndex > Poles.ColLength()) throw Standard_OutOfRange();
872   if (Poles.ColLength() <= 2)            throw Standard_ConstructionError();
873
874   Handle(TColgp_HArray2OfPnt) npoles =
875     new TColgp_HArray2OfPnt(1,poles->ColLength()-1,1,poles->RowLength());
876
877   Handle(TColStd_HArray2OfReal) nweights;
878
879   if (urational || vrational) {
880     nweights = 
881       new TColStd_HArray2OfReal(1,poles->ColLength()-1,1,poles->RowLength());
882
883     DeleteRatPoleRow (poles->Array2(), weights->Array2(),
884                       UIndex,
885                       npoles->ChangeArray2(), nweights->ChangeArray2());
886
887     // Mise a jour de la rationalite
888     Rational(nweights->Array2(), urational, vrational);
889   }
890   else {
891     DeletePoleRow (poles->Array2(), 
892                    UIndex,
893                    npoles->ChangeArray2());
894   }
895   poles   = npoles;
896   weights = nweights;
897 }
898
899 //=======================================================================
900 //function : Segment
901 //purpose  : 
902 //=======================================================================
903
904 void Geom_BezierSurface::Segment
905   (const Standard_Real U1,
906    const Standard_Real U2,
907    const Standard_Real V1,
908    const Standard_Real V2)
909 {
910   Standard_Boolean rat = (urational || vrational);
911   Handle(TColgp_HArray2OfPnt)  Coefs;
912   Handle(TColStd_HArray2OfReal) WCoefs;
913   
914   Standard_Integer aMinDegree = UDegree() <= VDegree() ? UDegree() : VDegree();
915   Standard_Integer aMaxDegree = UDegree() >  VDegree() ? UDegree() : VDegree();
916   Coefs = new TColgp_HArray2OfPnt(1, aMaxDegree + 1, 1, aMinDegree + 1);
917   if (rat)
918     WCoefs = new TColStd_HArray2OfReal(1, aMaxDegree + 1, 1, aMinDegree + 1);
919
920   TColStd_Array1OfReal biduflatknots(BSplCLib::FlatBezierKnots(UDegree()), 1, 2 * (UDegree() + 1));
921   TColStd_Array1OfReal bidvflatknots(BSplCLib::FlatBezierKnots(VDegree()), 1, 2 * (VDegree() + 1));
922
923   Standard_Real uparameter_11 = 0.5;
924   Standard_Real uspanlenght_11 = 0.5;
925   Standard_Real vparameter_11 = 0.5;
926   Standard_Real vspanlenght_11 = 0.5;
927
928   if (urational || vrational) {
929     BSplSLib::BuildCache(uparameter_11, vparameter_11,
930       uspanlenght_11, vspanlenght_11, 0, 0,
931       UDegree(), VDegree(), 0, 0,
932       biduflatknots, bidvflatknots,
933       poles->Array2(),
934       &weights->Array2(),
935       Coefs->ChangeArray2(),
936       &WCoefs->ChangeArray2());
937   }
938   else {
939     BSplSLib::BuildCache(uparameter_11, vparameter_11,
940       uspanlenght_11, vspanlenght_11, 0, 0,
941       UDegree(), VDegree(), 0, 0,
942       biduflatknots, bidvflatknots,
943       poles->Array2(),
944       BSplSLib::NoWeights(),
945       Coefs->ChangeArray2(),
946       BSplSLib::NoWeights());
947   }
948
949   // Attention si udeg <= vdeg u et v sont intervertis 
950   // dans les coeffs, il faut donc tout transposer.
951   if(UDegree() <= VDegree()) {
952     Handle(TColgp_HArray2OfPnt)  coeffs = Coefs;
953     Handle(TColStd_HArray2OfReal) wcoeffs = WCoefs;
954     Standard_Integer ii, jj;
955     Coefs = new  (TColgp_HArray2OfPnt)(1,UDegree()+1,1,VDegree()+1);
956     if (rat) {
957       WCoefs = new  (TColStd_HArray2OfReal)(1,UDegree()+1,1,VDegree()+1);
958     }
959     for (ii=1; ii<=UDegree()+1; ii++)
960       for (jj=1; jj<=VDegree()+1; jj++) {
961         Coefs->SetValue(ii, jj, coeffs->Value(jj,ii));
962         if (rat)  WCoefs->SetValue(ii, jj, wcoeffs->Value(jj,ii));
963       }
964   }
965
966 // Trim dans la base cannonique et Update des Poles et Coeffs
967
968 // PMN : tranfo sur les parametres
969   Standard_Real ufirst = 2*(U1 - 0.5),
970                 ulast =  2*(U2 - 0.5),
971                 vfirst = 2*(V1 - 0.5),
972                 vlast  = 2*(V2 - 0.5);
973   if (rat) {
974     PLib::UTrimming (ufirst, ulast, Coefs->ChangeArray2(),
975                      &WCoefs->ChangeArray2());
976     PLib::VTrimming (vfirst, vlast, Coefs->ChangeArray2(),
977                      &WCoefs->ChangeArray2());
978     PLib::CoefficientsPoles(Coefs->Array2(),
979                             &WCoefs->Array2(),
980                             poles->ChangeArray2(),
981                             &weights->ChangeArray2());
982   }
983   else {
984     PLib::UTrimming (ufirst, ulast, Coefs->ChangeArray2(), PLib::NoWeights2());
985     PLib::VTrimming (vfirst, vlast, Coefs->ChangeArray2(), PLib::NoWeights2());
986     PLib::CoefficientsPoles (Coefs->Array2(), PLib::NoWeights2(),
987                                                poles->ChangeArray2(), PLib::NoWeights2());
988   }
989 }
990
991 //=======================================================================
992 //function : SetPole
993 //purpose  : 
994 //=======================================================================
995
996 void Geom_BezierSurface::SetPole
997   (const Standard_Integer UIndex,
998    const Standard_Integer VIndex,
999    const gp_Pnt&          P)
1000 {
1001   TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1002   if (UIndex < 1                 ||
1003       UIndex > Poles.ColLength() ||
1004       VIndex < 1                 ||
1005       VIndex > Poles.RowLength() )    throw Standard_OutOfRange();
1006   
1007   Poles (UIndex, VIndex) = P;
1008 }
1009
1010 //=======================================================================
1011 //function : SetPole
1012 //purpose  : 
1013 //=======================================================================
1014
1015 void Geom_BezierSurface::SetPole
1016   (const Standard_Integer UIndex,
1017    const Standard_Integer VIndex, 
1018    const gp_Pnt&          P,
1019    const Standard_Real    Weight)
1020 {
1021
1022   if (Weight <= gp::Resolution())     
1023     throw Standard_ConstructionError("Geom_BezierSurface::SetPole");
1024   if (UIndex < 1                 || 
1025       UIndex > poles->ColLength() ||
1026       VIndex < 1                 ||
1027       VIndex > poles->RowLength())    
1028     throw Standard_OutOfRange("Geom_BezierSurface::SetPole");
1029
1030   poles->SetValue(UIndex, VIndex, P);
1031   
1032   SetWeight(UIndex, VIndex,  Weight); //L'update des coeff est fait la dedans
1033 }
1034
1035 //=======================================================================
1036 //function : SetPoleCol
1037 //purpose  : 
1038 //=======================================================================
1039
1040 void Geom_BezierSurface::SetPoleCol
1041   (const Standard_Integer      VIndex,
1042    const TColgp_Array1OfPnt&   CPoles,
1043    const TColStd_Array1OfReal& CPoleWeights)
1044 {
1045   TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1046   if (VIndex < 1 || VIndex > Poles.RowLength()) throw Standard_OutOfRange();
1047
1048   if (CPoles.Lower() < 1                     || 
1049       CPoles.Lower() > Poles.ColLength()     || 
1050       CPoles.Upper() < 1                     || 
1051       CPoles.Upper() > Poles.ColLength()     ||
1052       CPoleWeights.Lower() != CPoles.Lower() ||
1053       CPoleWeights.Upper() != CPoles.Upper()) {
1054     throw Standard_ConstructionError();
1055   }
1056      
1057   Standard_Integer I;
1058   for (I = CPoles.Lower();  I <= CPoles.Upper(); I++) {
1059     Poles (I, VIndex) = CPoles (I);
1060   }
1061   SetWeightCol(VIndex, CPoleWeights); //Avec l'update
1062 }
1063
1064 //=======================================================================
1065 //function : SetPoleCol
1066 //purpose  : 
1067 //=======================================================================
1068
1069 void Geom_BezierSurface::SetPoleCol (const Standard_Integer      VIndex,
1070                                      const TColgp_Array1OfPnt&   CPoles)
1071 {
1072   TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1073   if (VIndex < 1 || VIndex > Poles.RowLength())  throw Standard_OutOfRange();
1074
1075   if (CPoles.Lower() < 1                 || 
1076       CPoles.Lower() > Poles.ColLength() || 
1077       CPoles.Upper() < 1                 ||
1078       CPoles.Upper() > Poles.ColLength()) {
1079     throw Standard_ConstructionError();
1080   }
1081   for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
1082     Poles (I, VIndex) = CPoles (I);
1083   }
1084 }
1085
1086 //=======================================================================
1087 //function : SetPoleRow
1088 //purpose  : 
1089 //=======================================================================
1090
1091 void Geom_BezierSurface::SetPoleRow (const Standard_Integer    UIndex,
1092                                      const TColgp_Array1OfPnt& CPoles)
1093 {
1094   TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1095   if (UIndex < 1 || UIndex > Poles.ColLength())  throw Standard_OutOfRange();
1096
1097   if (CPoles.Lower() < 1                 ||
1098       CPoles.Lower() > Poles.RowLength() || 
1099       CPoles.Upper() < 1                 || 
1100       CPoles.Upper() > Poles.RowLength())  throw Standard_ConstructionError();
1101
1102   for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
1103     Poles (UIndex, I) = CPoles (I);
1104   }
1105 }
1106
1107 //=======================================================================
1108 //function : SetPoleRow
1109 //purpose  : 
1110 //=======================================================================
1111
1112 void Geom_BezierSurface::SetPoleRow
1113   (const Standard_Integer      UIndex,
1114    const TColgp_Array1OfPnt&   CPoles,
1115    const TColStd_Array1OfReal& CPoleWeights)
1116 {
1117   TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1118   if (UIndex < 1 || UIndex > Poles.ColLength())   throw Standard_OutOfRange();
1119
1120   if (CPoles.Lower() < 1                     || 
1121       CPoles.Lower() > Poles.RowLength()     || 
1122       CPoles.Upper() < 1                     || 
1123       CPoles.Upper() > Poles.RowLength()     ||
1124       CPoleWeights.Lower() != CPoles.Lower() ||
1125       CPoleWeights.Upper() != CPoles.Upper()) {
1126     throw Standard_ConstructionError();
1127   }
1128
1129   Standard_Integer I;
1130
1131   for (I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
1132     Poles   (UIndex, I) = CPoles (I);
1133   }
1134   
1135   SetWeightRow(UIndex, CPoleWeights); //Avec l'update 
1136 }
1137
1138 //=======================================================================
1139 //function : SetWeight
1140 //purpose  : 
1141 //=======================================================================
1142
1143 void Geom_BezierSurface::SetWeight (const Standard_Integer UIndex,
1144                                     const Standard_Integer VIndex,
1145                                     const Standard_Real    Weight)
1146 {
1147    // compute new rationality
1148   Standard_Boolean wasrat = (urational||vrational);
1149   if (!wasrat) {
1150     // a weight of 1. does not turn to rational
1151     if (Abs(Weight - 1.) <= gp::Resolution())
1152       return;
1153
1154     // set weights of 1.
1155     weights = new TColStd_HArray2OfReal (1, poles->ColLength(),
1156                                          1, poles->RowLength(), 1.);
1157   }
1158
1159   TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1160   if (Weight <= gp::Resolution())      
1161     throw Standard_ConstructionError("Geom_BezierSurface::SetWeight");
1162
1163   if (UIndex < 1                   || 
1164       UIndex > Weights.ColLength() ||
1165       VIndex < 1                   || 
1166       VIndex > Weights.RowLength())    throw Standard_OutOfRange();
1167
1168   if (Abs (Weight - Weights (UIndex, VIndex)) > gp::Resolution()) {
1169     Weights (UIndex, VIndex) = Weight;
1170     Rational(Weights, urational, vrational);
1171   }
1172
1173  // is it turning into non rational
1174   if (wasrat && !(urational || vrational))
1175     weights.Nullify();
1176 }
1177
1178 //=======================================================================
1179 //function : SetWeightCol
1180 //purpose  : 
1181 //=======================================================================
1182
1183 void Geom_BezierSurface::SetWeightCol 
1184   (const Standard_Integer      VIndex,
1185    const TColStd_Array1OfReal& CPoleWeights)
1186 {
1187   Standard_Integer I;
1188    // compute new rationality
1189   Standard_Boolean wasrat = (urational||vrational);
1190   if (!wasrat) {   
1191     // set weights of 1.
1192     weights = new TColStd_HArray2OfReal (1, poles->ColLength(),
1193                                          1, poles->RowLength(), 1.);
1194   }
1195
1196   TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1197   if (VIndex < 1 || VIndex > Weights.RowLength()) throw Standard_OutOfRange();
1198
1199   if (CPoleWeights.Length() !=  Weights.ColLength())  {
1200     throw Standard_ConstructionError("Geom_BezierSurface::SetWeightCol");
1201   }
1202
1203   I = CPoleWeights.Lower();
1204   while (I <= CPoleWeights.Upper()) {
1205     if (CPoleWeights(I) <= gp::Resolution()) {
1206       throw Standard_ConstructionError();
1207     }
1208     Weights (I, VIndex) = CPoleWeights (I);
1209     I++;
1210   }
1211
1212  Rational(Weights, urational, vrational);
1213
1214  // is it turning into non rational
1215  if (wasrat && !(urational || vrational))
1216    weights.Nullify();
1217 }
1218
1219 //=======================================================================
1220 //function : SetWeightRow
1221 //purpose  : 
1222 //=======================================================================
1223
1224 void Geom_BezierSurface::SetWeightRow 
1225   (const Standard_Integer      UIndex,
1226    const TColStd_Array1OfReal& CPoleWeights)
1227 {
1228   Standard_Integer I;
1229    // compute new rationality
1230   Standard_Boolean wasrat = (urational||vrational);
1231   if (!wasrat) {    
1232     // set weights of 1.
1233     weights = new TColStd_HArray2OfReal (1, poles->ColLength(),
1234                                          1, poles->RowLength(), 1.);
1235   }
1236
1237   TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1238   if (UIndex < 1 || UIndex > Weights.ColLength()) 
1239     throw Standard_OutOfRange("Geom_BezierSurface::SetWeightRow");
1240   if (CPoleWeights.Lower() < 1 ||
1241       CPoleWeights.Lower() > Weights.RowLength() ||
1242       CPoleWeights.Upper() < 1 ||
1243       CPoleWeights.Upper() > Weights.RowLength()  ) {
1244     throw Standard_ConstructionError("Geom_BezierSurface::SetWeightRow");
1245   }
1246
1247   I = CPoleWeights.Lower();
1248   while (I <= CPoleWeights.Upper()) {
1249     if (CPoleWeights(I) <= gp::Resolution())  {
1250       throw Standard_ConstructionError();
1251     }
1252     Weights (UIndex, I) = CPoleWeights (I);
1253     I++;
1254   }
1255
1256   Rational(Weights, urational, vrational);
1257
1258  // is it turning into non rational
1259   if (wasrat && !(urational || vrational))
1260     weights.Nullify();
1261 }
1262
1263 //=======================================================================
1264 //function : UReverse
1265 //purpose  : 
1266 //=======================================================================
1267
1268 void Geom_BezierSurface::UReverse ()
1269 {
1270   gp_Pnt Pol;
1271   Standard_Integer Row,Col;
1272   TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1273   if (urational || vrational) {
1274     TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1275     Standard_Real W;
1276     for (Col = 1; Col <= Poles.RowLength(); Col++) {
1277       for (Row = 1; Row <= IntegerPart (Poles.ColLength() / 2); Row++) {
1278         W = Weights (Row, Col);
1279         Weights (Row, Col) = Weights (Poles.ColLength()- Row + 1, Col);
1280         Weights (Poles.ColLength() - Row + 1, Col) = W;
1281         Pol = Poles (Row, Col);
1282         Poles (Row, Col) = Poles (Poles.ColLength() - Row + 1, Col);
1283         Poles (Poles.ColLength() - Row + 1, Col) = Pol;
1284       }
1285     }
1286   }
1287   else {
1288     for (Col = 1; Col <= Poles.RowLength(); Col++) {
1289       for (Row = 1; Row <= IntegerPart (Poles.ColLength() / 2); Row++) {
1290         Pol = Poles (Row, Col);
1291         Poles (Row, Col) = Poles (Poles.ColLength() - Row + 1, Col);
1292         Poles (Poles.ColLength() - Row + 1, Col) = Pol;
1293       }
1294     }
1295   }
1296 }
1297
1298 //=======================================================================
1299 //function : UReversedParameter
1300 //purpose  : 
1301 //=======================================================================
1302
1303 Standard_Real Geom_BezierSurface::UReversedParameter
1304   ( const Standard_Real U) const 
1305 {
1306   return ( 1. - U);
1307 }
1308
1309 //=======================================================================
1310 //function : VReverse
1311 //purpose  : 
1312 //=======================================================================
1313
1314 void Geom_BezierSurface::VReverse ()
1315 {
1316   gp_Pnt Pol;
1317   Standard_Integer Row,Col;
1318   TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1319   if (urational || vrational) {
1320     TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1321     Standard_Real W;
1322     for (Row = 1; Row <= Poles.ColLength(); Row++) {
1323       for (Col = 1; Col <= IntegerPart (Poles.RowLength()/2); Col++) {
1324         W = Weights (Row, Col);
1325         Weights (Row, Col) = Weights (Row, Poles.RowLength() - Col + 1);
1326         Weights (Row, Poles.RowLength() - Col + 1) = W;
1327         Pol = Poles (Row, Col);
1328         Poles (Row, Col) = Poles (Row, Poles.RowLength() - Col + 1);
1329         Poles (Row, Poles.RowLength() - Col + 1) = Pol;
1330       }
1331     }
1332   }
1333   else {
1334     for (Row = 1; Row <= Poles.ColLength(); Row++) {
1335       for (Col = 1; Col <= IntegerPart(Poles.RowLength()/2); Col++) {
1336         Pol = Poles (Row, Col);
1337         Poles (Row, Col)= Poles (Row, Poles.RowLength() - Col + 1);
1338         Poles (Row, Poles.RowLength() - Col + 1) = Pol;
1339       }
1340     }
1341   }
1342 }
1343
1344 //=======================================================================
1345 //function : VReversedParameter
1346 //purpose  : 
1347 //=======================================================================
1348
1349 Standard_Real Geom_BezierSurface::VReversedParameter
1350   ( const Standard_Real V) const 
1351 {
1352   return ( 1. - V);
1353 }
1354
1355 //=======================================================================
1356 //function : Bounds
1357 //purpose  : 
1358 //=======================================================================
1359
1360 void Geom_BezierSurface::Bounds (Standard_Real& U1,
1361                                  Standard_Real& U2,
1362                                  Standard_Real& V1,
1363                                  Standard_Real& V2) const
1364 {
1365   U1 = 0.0;  
1366   U2 = 1.0; 
1367   V1 = 0.0;
1368   V2 = 1.0;
1369 }
1370
1371 //=======================================================================
1372 //function : Continuity
1373 //purpose  : 
1374 //=======================================================================
1375
1376 GeomAbs_Shape Geom_BezierSurface::Continuity () const
1377 {
1378   return GeomAbs_CN; 
1379 }
1380
1381 //=======================================================================
1382 //function : D0
1383 //purpose  : 
1384 //=======================================================================
1385
1386 void Geom_BezierSurface::D0 (const Standard_Real U,
1387                              const Standard_Real V,
1388                                    gp_Pnt&       P ) const
1389 {
1390   Standard_Real array_u[2];
1391   Standard_Real array_v[2];
1392   Standard_Integer mult_u[2];
1393   Standard_Integer mult_v[2];
1394   TColStd_Array1OfReal biduknots(array_u[0], 1, 2); biduknots(1) = 0.; biduknots(2) = 1.;
1395   TColStd_Array1OfInteger bidumults(mult_u[0], 1, 2); bidumults.Init(UDegree() + 1);
1396   TColStd_Array1OfReal bidvknots(array_v[0], 1, 2); bidvknots(1) = 0.; bidvknots(2) = 1.;
1397   TColStd_Array1OfInteger bidvmults(mult_v[0], 1, 2); bidvmults.Init(VDegree() + 1);
1398   if (urational || vrational) {
1399     BSplSLib::D0(U, V, 1, 1, poles->Array2(),
1400       &weights->Array2(),
1401       biduknots, bidvknots, &bidumults, &bidvmults,
1402       UDegree(), VDegree(),
1403       urational, vrational, Standard_False, Standard_False,
1404       P);
1405   }
1406   else {
1407
1408     BSplSLib::D0(U, V, 1, 1, poles->Array2(),
1409       BSplSLib::NoWeights(),
1410       biduknots, bidvknots, &bidumults, &bidvmults,
1411       UDegree(), VDegree(),
1412       urational, vrational, Standard_False, Standard_False,
1413       P);
1414   }
1415 }
1416
1417 //=======================================================================
1418 //function : D1
1419 //purpose  : 
1420 //=======================================================================
1421
1422 void Geom_BezierSurface::D1
1423   (const Standard_Real U,
1424    const Standard_Real V,
1425          gp_Pnt&       P,
1426          gp_Vec&       D1U,
1427          gp_Vec&       D1V ) const
1428 {
1429   Standard_Real array_u[2];
1430   Standard_Real array_v[2];
1431   Standard_Integer mult_u[2];
1432   Standard_Integer mult_v[2];
1433   TColStd_Array1OfReal biduknots(array_u[0], 1, 2); biduknots(1) = 0.; biduknots(2) = 1.;
1434   TColStd_Array1OfInteger bidumults(mult_u[0], 1, 2); bidumults.Init(UDegree() + 1);
1435   TColStd_Array1OfReal bidvknots(array_v[0], 1, 2); bidvknots(1) = 0.; bidvknots(2) = 1.;
1436   TColStd_Array1OfInteger bidvmults(mult_v[0], 1, 2); bidvmults.Init(VDegree() + 1);
1437   if (urational || vrational) {
1438     BSplSLib::D1(U, V, 1, 1, poles->Array2(),
1439       &weights->Array2(),
1440       biduknots, bidvknots, &bidumults, &bidvmults,
1441       UDegree(), VDegree(),
1442       urational, vrational, Standard_False, Standard_False,
1443       P, D1U, D1V);
1444   }
1445   else {
1446     BSplSLib::D1(U, V, 1, 1, poles->Array2(),
1447       BSplSLib::NoWeights(),
1448       biduknots, bidvknots, &bidumults, &bidvmults,
1449       UDegree(), VDegree(),
1450       urational, vrational, Standard_False, Standard_False,
1451       P, D1U, D1V);
1452   }
1453 }
1454
1455 //=======================================================================
1456 //function : D2
1457 //purpose  : 
1458 //=======================================================================
1459
1460 void Geom_BezierSurface::D2
1461   (const Standard_Real U,
1462    const Standard_Real V,
1463          gp_Pnt&       P,
1464          gp_Vec&       D1U, gp_Vec& D1V, 
1465          gp_Vec&       D2U, gp_Vec& D2V, gp_Vec& D2UV ) const
1466 {
1467   Standard_Real array_u[2];
1468   Standard_Real array_v[2];
1469   Standard_Integer mult_u[2];
1470   Standard_Integer mult_v[2];
1471   TColStd_Array1OfReal biduknots(array_u[0], 1, 2); biduknots(1) = 0.; biduknots(2) = 1.;
1472   TColStd_Array1OfInteger bidumults(mult_u[0], 1, 2); bidumults.Init(UDegree() + 1);
1473   TColStd_Array1OfReal bidvknots(array_v[0], 1, 2); bidvknots(1) = 0.; bidvknots(2) = 1.;
1474   TColStd_Array1OfInteger bidvmults(mult_v[0], 1, 2); bidvmults.Init(VDegree() + 1);
1475   if (urational || vrational) {
1476     //-- ATTENTION a l'ORDRE d'appel ds BSPLSLIB 
1477     BSplSLib::D2(U, V, 1, 1, poles->Array2(),
1478       &weights->Array2(),
1479       biduknots, bidvknots, &bidumults, &bidvmults,
1480       UDegree(), VDegree(),
1481       urational, vrational, Standard_False, Standard_False,
1482       P, D1U, D1V, D2U, D2V, D2UV);
1483   }
1484   else {
1485     //-- ATTENTION a l'ORDRE d'appel ds BSPLSLIB 
1486     BSplSLib::D2(U, V, 1, 1, poles->Array2(),
1487       BSplSLib::NoWeights(),
1488       biduknots, bidvknots, &bidumults, &bidvmults,
1489       UDegree(), VDegree(),
1490       urational, vrational, Standard_False, Standard_False,
1491       P, D1U, D1V, D2U, D2V, D2UV);
1492   }
1493 }
1494
1495 //=======================================================================
1496 //function : D3
1497 //purpose  : 
1498 //=======================================================================
1499
1500 void Geom_BezierSurface::D3
1501   (const Standard_Real U, const Standard_Real V,
1502    gp_Pnt& P,
1503    gp_Vec& D1U, gp_Vec& D1V, 
1504    gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV, 
1505    gp_Vec& D3U, gp_Vec& D3V, gp_Vec& D3UUV, gp_Vec& D3UVV) const
1506 {
1507   TColStd_Array1OfReal biduknots(1,2); biduknots(1) = 0.; biduknots(2) = 1.;
1508   TColStd_Array1OfInteger bidumults(1,2); bidumults.Init(UDegree() + 1);
1509   TColStd_Array1OfReal bidvknots(1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
1510   TColStd_Array1OfInteger bidvmults(1,2); bidvmults.Init(VDegree() + 1);
1511   if (urational || vrational) { 
1512     BSplSLib::D3 (U, V, 0, 0, poles->Array2(),
1513                   &weights->Array2(),
1514                   biduknots, bidvknots, &bidumults, &bidvmults,
1515                   UDegree(), VDegree(), urational, vrational, 0, 0,
1516                   P,
1517                   D1U, D1V,
1518                   D2U, D2V, D2UV,
1519                   D3U, D3V, D3UUV, D3UVV);
1520   }
1521   else { 
1522     BSplSLib::D3 (U, V, 0, 0, poles->Array2(),
1523                   BSplSLib::NoWeights(),
1524                   biduknots, bidvknots, &bidumults, &bidvmults,
1525                   UDegree(), VDegree(), urational, vrational, 0, 0,
1526                   P,
1527                   D1U, D1V,
1528                   D2U, D2V, D2UV,
1529                   D3U, D3V, D3UUV, D3UVV);
1530   }
1531 }
1532
1533 //=======================================================================
1534 //function : DN
1535 //purpose  : 
1536 //=======================================================================
1537
1538 gp_Vec Geom_BezierSurface::DN
1539   (const Standard_Real    U,
1540    const Standard_Real    V,
1541    const Standard_Integer Nu,
1542    const Standard_Integer Nv) const
1543 {
1544   Standard_RangeError_Raise_if (Nu + Nv < 1 || Nv < 0 || Nu <0, " ");
1545   gp_Vec Derivative;
1546   TColStd_Array1OfReal biduknots(1,2); biduknots(1) = 0.; biduknots(2) = 1.;
1547   TColStd_Array1OfInteger bidumults(1,2); bidumults.Init(UDegree() + 1);
1548   TColStd_Array1OfReal bidvknots(1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
1549   TColStd_Array1OfInteger bidvmults(1,2); bidvmults.Init(VDegree() + 1);
1550   if (urational || vrational) { 
1551     BSplSLib::DN (U, V, Nu, Nv, 0, 0, poles->Array2(),
1552                   &weights->Array2(),
1553                   biduknots, bidvknots, &bidumults, &bidvmults,
1554                   UDegree(), VDegree(), urational, vrational, 0, 0,
1555                   Derivative);
1556   }
1557   else { 
1558     BSplSLib::DN (U, V, Nu, Nv, 0, 0, poles->Array2(),
1559                   BSplSLib::NoWeights(),
1560                   biduknots, bidvknots, &bidumults, &bidvmults,
1561                   UDegree(), VDegree(), urational, vrational, 0, 0,
1562                   Derivative);
1563   }
1564   return Derivative;
1565 }
1566
1567 //=======================================================================
1568 //function : NbUPoles
1569 //purpose  : 
1570 //=======================================================================
1571
1572 Standard_Integer Geom_BezierSurface::NbUPoles () const
1573 {
1574   return poles->ColLength(); 
1575 }
1576
1577 //=======================================================================
1578 //function : NbVPoles
1579 //purpose  : 
1580 //=======================================================================
1581
1582 Standard_Integer Geom_BezierSurface::NbVPoles () const
1583 {
1584   return poles->RowLength(); 
1585 }
1586
1587 //=======================================================================
1588 //function : Pole
1589 //purpose  : 
1590 //=======================================================================
1591
1592 const gp_Pnt& Geom_BezierSurface::Pole (const Standard_Integer UIndex,
1593                                  const Standard_Integer VIndex) const
1594 {
1595   Standard_OutOfRange_Raise_if
1596     (UIndex < 1 || UIndex > poles->ColLength() ||
1597      VIndex < 1 || VIndex > poles->RowLength(), " ");
1598   return poles->Value (UIndex + poles->LowerRow() - 1,
1599                        VIndex + poles->LowerCol() - 1);
1600 }
1601
1602 //=======================================================================
1603 //function : Poles
1604 //purpose  : 
1605 //=======================================================================
1606
1607 void Geom_BezierSurface::Poles (TColgp_Array2OfPnt& P) const
1608 {
1609   Standard_DimensionError_Raise_if
1610     (P.RowLength() != poles->RowLength() ||
1611      P.ColLength() != poles->ColLength(), " ");
1612   P = poles->Array2();
1613 }
1614
1615 //=======================================================================
1616 //function : UDegree
1617 //purpose  : 
1618 //=======================================================================
1619
1620 Standard_Integer Geom_BezierSurface::UDegree () const
1621 {
1622   return poles->ColLength() - 1; 
1623 }
1624
1625 //=======================================================================
1626 //function : UIso
1627 //purpose  : 
1628 //=======================================================================
1629
1630 Handle(Geom_Curve) Geom_BezierSurface::UIso (const Standard_Real U) const
1631 {
1632   TColStd_Array1OfReal biduknots(1,2); biduknots(1) = 0.; biduknots(2) = 1.;
1633   TColStd_Array1OfInteger bidumults(1,2); bidumults.Init(UDegree() + 1);
1634
1635   Handle(Geom_BezierCurve) UIsoCurve;
1636   const TColgp_Array2OfPnt & Poles = poles->Array2();
1637   TColgp_Array1OfPnt VCurvePoles (Poles.LowerCol() , Poles.UpperCol());
1638   if (urational || vrational) {
1639     const TColStd_Array2OfReal & Weights = weights->Array2();
1640     TColStd_Array1OfReal VCurveWeights 
1641       (Weights.LowerCol() , Weights.UpperCol());
1642     BSplSLib::Iso (U, 1, Poles,
1643                    &Weights,
1644                    biduknots, &bidumults,
1645                    UDegree(), 0, VCurvePoles, &VCurveWeights);
1646     if (urational)
1647       UIsoCurve = new Geom_BezierCurve (VCurvePoles, VCurveWeights);
1648     else
1649       UIsoCurve = new Geom_BezierCurve (VCurvePoles);
1650   }
1651   else {
1652     BSplSLib::Iso (U, 1, Poles,
1653                    BSplSLib::NoWeights(),
1654                    biduknots, &bidumults,
1655                    UDegree(), 0, VCurvePoles, PLib::NoWeights());
1656     UIsoCurve = new Geom_BezierCurve (VCurvePoles);
1657   }
1658   return UIsoCurve;
1659 }
1660
1661 //=======================================================================
1662 //function : VDegree
1663 //purpose  : 
1664 //=======================================================================
1665
1666 Standard_Integer Geom_BezierSurface::VDegree () const
1667 {
1668   return poles->RowLength() - 1; 
1669 }
1670
1671 //=======================================================================
1672 //function : VIso
1673 //purpose  : 
1674 //=======================================================================
1675
1676 Handle(Geom_Curve) Geom_BezierSurface::VIso (const Standard_Real V) const
1677 {
1678   TColStd_Array1OfReal bidvknots(1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
1679   TColStd_Array1OfInteger bidvmults(1,2); bidvmults.Init(VDegree() + 1);
1680
1681   Handle(Geom_BezierCurve) VIsoCurve;
1682   const TColgp_Array2OfPnt & Poles = poles->Array2();
1683   TColgp_Array1OfPnt VCurvePoles (Poles.LowerRow() , Poles.UpperRow());
1684   if (vrational || urational) {
1685     const TColStd_Array2OfReal & Weights = weights->Array2();
1686     TColStd_Array1OfReal VCurveWeights 
1687       (Weights.LowerRow() , Weights.UpperRow());
1688     BSplSLib::Iso (V, 0, Poles,
1689                    &Weights,
1690                    bidvknots, &bidvmults,
1691                    VDegree(), 0, VCurvePoles, &VCurveWeights);
1692     if (vrational)
1693       VIsoCurve = new Geom_BezierCurve (VCurvePoles, VCurveWeights);
1694     else
1695       VIsoCurve = new Geom_BezierCurve (VCurvePoles);
1696   }
1697   else {
1698     BSplSLib::Iso (V, 0, Poles,
1699                    BSplSLib::NoWeights(),
1700                    bidvknots, &bidvmults,
1701                    VDegree(), 0, VCurvePoles, PLib::NoWeights());
1702     VIsoCurve = new Geom_BezierCurve (VCurvePoles);
1703   }
1704   return VIsoCurve;
1705 }
1706
1707 //=======================================================================
1708 //function : Weight
1709 //purpose  : 
1710 //=======================================================================
1711
1712 Standard_Real Geom_BezierSurface::Weight (const Standard_Integer UIndex,
1713                                           const Standard_Integer VIndex) const
1714 {
1715   Standard_OutOfRange_Raise_if (
1716            UIndex < 1 || UIndex > weights->ColLength() ||
1717            VIndex < 1 || VIndex > weights->RowLength(), " ");
1718
1719   if (urational || vrational) 
1720     return weights->Value (UIndex, VIndex);
1721   else 
1722     return 1;
1723 }
1724
1725 //=======================================================================
1726 //function : Weights
1727 //purpose  : 
1728 //=======================================================================
1729
1730 void Geom_BezierSurface::Weights (TColStd_Array2OfReal& W ) const
1731 {
1732   Standard_DimensionError_Raise_if (
1733            W.RowLength() != weights->RowLength() ||
1734            W.ColLength() != weights->ColLength(), " " );
1735   if (urational || vrational) 
1736     W = weights->Array2();
1737   else 
1738     W.Init(1.);
1739 }
1740
1741 //=======================================================================
1742 //function : IsCNu
1743 //purpose  : 
1744 //=======================================================================
1745
1746 Standard_Boolean Geom_BezierSurface::IsCNu (const Standard_Integer ) const
1747 {
1748   return Standard_True; 
1749 }
1750
1751 //=======================================================================
1752 //function : IsCNv
1753 //purpose  : 
1754 //=======================================================================
1755
1756 Standard_Boolean Geom_BezierSurface::IsCNv (const Standard_Integer ) const
1757 {
1758   return Standard_True; 
1759 }
1760
1761 //=======================================================================
1762 //function : IsURational
1763 //purpose  : 
1764 //=======================================================================
1765
1766 Standard_Boolean Geom_BezierSurface::IsURational () const
1767 {
1768   return urational; 
1769 }
1770
1771 //=======================================================================
1772 //function : IsVRational
1773 //purpose  : 
1774 //=======================================================================
1775
1776 Standard_Boolean Geom_BezierSurface::IsVRational () const
1777 {
1778   return vrational; 
1779 }
1780
1781 //=======================================================================
1782 //function : Transform
1783 //purpose  : 
1784 //=======================================================================
1785
1786 void Geom_BezierSurface::Transform (const gp_Trsf& T)
1787 {
1788   TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1789
1790   for (Standard_Integer I = 1; I <= Poles.ColLength(); I++) {
1791
1792     for (Standard_Integer J = 1; J <= Poles.RowLength(); J++) {
1793       Poles (I, J).Transform (T);
1794     }
1795   }
1796 }
1797
1798 //=======================================================================
1799 //function : IsUClosed
1800 //purpose  : 
1801 //=======================================================================
1802
1803 Standard_Boolean Geom_BezierSurface::IsUClosed () const
1804
1805   const TColgp_Array2OfPnt & Poles = poles->Array2();
1806   Standard_Boolean Closed = Standard_True;
1807   Standard_Integer Lower  = Poles.LowerRow();
1808   Standard_Integer Upper  = Poles.UpperRow();
1809   Standard_Integer Length = Poles.RowLength();
1810   Standard_Integer j      = Poles.LowerCol();
1811
1812   while (Closed && j <= Length) {
1813     Closed = (Poles (Lower,j).Distance (Poles (Upper,j)) <= Precision::Confusion());
1814     j++;
1815   }
1816   return Closed; 
1817 }
1818
1819 //=======================================================================
1820 //function : IsVClosed
1821 //purpose  : 
1822 //=======================================================================
1823
1824 Standard_Boolean Geom_BezierSurface::IsVClosed () const
1825
1826   const TColgp_Array2OfPnt & Poles = poles->Array2();
1827   Standard_Boolean Closed = Standard_True;
1828   Standard_Integer Lower  = Poles.LowerCol();
1829   Standard_Integer Upper  = Poles.UpperCol();
1830   Standard_Integer Length = Poles.ColLength();
1831   Standard_Integer i      = Poles.LowerRow();
1832   while (Closed && i <= Length) {
1833     Closed = (Poles (i,Lower).Distance (Poles (i,Upper)) <= Precision::Confusion());
1834     i++;
1835   }
1836   return Closed; 
1837 }
1838
1839 //=======================================================================
1840 //function : IsUPeriodic
1841 //purpose  : 
1842 //=======================================================================
1843
1844 Standard_Boolean Geom_BezierSurface::IsUPeriodic () const
1845 {
1846   return Standard_False; 
1847 }
1848
1849 //=======================================================================
1850 //function : IsVPeriodic
1851 //purpose  : 
1852 //=======================================================================
1853
1854 Standard_Boolean Geom_BezierSurface::IsVPeriodic () const
1855 {
1856   return Standard_False; 
1857 }
1858
1859 //=======================================================================
1860 //function : Resolution
1861 //purpose  : 
1862 //=======================================================================
1863
1864 void Geom_BezierSurface::Resolution(const Standard_Real  Tolerance3D,
1865                                     Standard_Real&       UTolerance,
1866                                     Standard_Real&       VTolerance) 
1867 {
1868   if(!maxderivinvok){
1869     TColStd_Array1OfReal biduknots(1,2); biduknots(1) = 0.; biduknots(2) = 1.;
1870     TColStd_Array1OfInteger bidumults(1,2); bidumults.Init(UDegree() + 1);
1871     TColStd_Array1OfReal bidvknots(1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
1872     TColStd_Array1OfInteger bidvmults(1,2); bidvmults.Init(VDegree() + 1);
1873     if(urational || vrational){
1874       BSplSLib::Resolution(poles->Array2(),
1875                            &weights->Array2(),
1876                            biduknots,
1877                            bidvknots,
1878                            bidumults,
1879                            bidvmults,
1880                            UDegree(),
1881                            VDegree(),
1882                            urational,
1883                            vrational,
1884                            0,
1885                            0,
1886                            1.,
1887                            umaxderivinv,
1888                            vmaxderivinv) ;
1889     }
1890     else{
1891       BSplSLib::Resolution(poles->Array2(),
1892                            BSplSLib::NoWeights(),
1893                            biduknots,
1894                            bidvknots,
1895                            bidumults,
1896                            bidvmults,
1897                            UDegree(),
1898                            VDegree(),
1899                            urational,
1900                            vrational,
1901                            0,
1902                            0,
1903                            1.,
1904                            umaxderivinv,
1905                            vmaxderivinv) ;
1906     }
1907     maxderivinvok = 1;
1908   }
1909   UTolerance = Tolerance3D * umaxderivinv;
1910   VTolerance = Tolerance3D * vmaxderivinv;
1911 }
1912
1913 //=======================================================================
1914 //function : Copy
1915 //purpose  : 
1916 //=======================================================================
1917
1918 Handle(Geom_Geometry) Geom_BezierSurface::Copy() const
1919 {
1920   Handle(Geom_BezierSurface) S = new Geom_BezierSurface
1921     (poles, weights, urational, vrational);
1922   return S;
1923 }
1924
1925 //=======================================================================
1926 //function : Init
1927 //purpose  : 
1928 //=======================================================================
1929
1930 void Geom_BezierSurface::Init
1931   (const Handle(TColgp_HArray2OfPnt)&   Poles, 
1932    const Handle(TColStd_HArray2OfReal)& Weights)
1933 {
1934   // set fields
1935   poles = Poles;
1936   if (urational || vrational)
1937     weights = Weights;
1938   else
1939     weights.Nullify();
1940 }
1941
1942 //=======================================================================
1943 //function : DumpJson
1944 //purpose  : 
1945 //=======================================================================
1946 void Geom_BezierSurface::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
1947 {
1948   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
1949
1950   OCCT_DUMP_BASE_CLASS (theOStream, theDepth, Geom_BoundedSurface)
1951
1952   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, urational)
1953   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, vrational)
1954   if (!poles.IsNull())
1955     OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, poles->Size())
1956   if (!weights.IsNull())
1957     OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, weights->Size())
1958   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, umaxderivinv)
1959   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, vmaxderivinv)
1960   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, maxderivinvok)
1961 }