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