0026936: Drawbacks of inlining in new type system in OCCT 7.0 -- automatic
[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     Standard_ConstructionError::Raise();
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     Standard_ConstructionError::Raise();
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         Standard_ConstructionError::Raise();
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 = 
509     new TColgp_HArray2OfPnt (LC, UC, LR, UR);
510   Handle(TColStd_HArray2OfReal) nweights =
511     new TColStd_HArray2OfReal (LC, UC, LR, UR);
512
513   const TColgp_Array2OfPnt   & spoles   = poles->Array2();
514   const TColStd_Array2OfReal & sweights = weights->Array2();
515
516   TColgp_Array2OfPnt&   snpoles   = npoles->ChangeArray2();
517   TColStd_Array2OfReal& snweights = nweights->ChangeArray2();
518  
519   Standard_Integer i, j;
520   for (i = LC; i <= UC; i++) {
521     for (j = LR; j <= UR; j++) {
522       snpoles   (i,j) = spoles   (j,i);
523       snweights (i,j) = sweights (j,i);
524     }
525   }
526
527   poles   = npoles;
528   weights = nweights;
529
530   Standard_Boolean temp = urational;
531   urational = vrational;
532   vrational = temp;
533 }
534
535 //=======================================================================
536 //function : Increase
537 //purpose  : 
538 //=======================================================================
539
540 void Geom_BezierSurface::Increase (const Standard_Integer UDeg,
541                                    const Standard_Integer VDeg)
542 {
543   if (UDeg < UDegree() || UDeg > Geom_BezierSurface::MaxDegree() ||
544       VDeg < VDegree() || VDeg > Geom_BezierSurface::MaxDegree() )  {
545     Standard_ConstructionError::Raise();
546   }
547
548   Standard_Integer oldUDeg = UDegree();
549   Standard_Integer oldVDeg = VDegree();
550   Standard_Integer IncUDeg = UDeg - oldUDeg;
551   Standard_Integer IncVDeg = VDeg - oldVDeg;
552   if (IncUDeg == 0 && IncVDeg == 0) return;
553   
554   TColStd_Array1OfReal biduknots(1,2); biduknots(1) = 0.; biduknots(2) = 1.;
555   TColStd_Array1OfInteger bidumults(1,2); bidumults.Init(UDegree() + 1);
556   TColStd_Array1OfReal bidvknots(1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
557   TColStd_Array1OfInteger bidvmults(1,2); bidvmults.Init(VDegree() + 1);
558   Handle(TColgp_HArray2OfPnt) npoles;
559   Handle(TColStd_HArray2OfReal) nweights;
560
561   if(IncUDeg > 0){
562     npoles = new TColgp_HArray2OfPnt( 1, UDeg + 1, 1, oldVDeg + 1);
563     
564     if ( urational || vrational) {
565       nweights = new TColStd_HArray2OfReal( 1, UDeg + 1, 1, VDegree() + 1);
566       
567       BSplSLib::IncreaseDegree(1, oldUDeg, UDeg, 0,
568                                poles->Array2(),
569                                &weights->Array2(),
570                                biduknots, bidumults,
571                                npoles->ChangeArray2(), 
572                                &nweights->ChangeArray2(),
573                                biduknots, bidumults);
574       weights = nweights;
575     }
576     else {
577       BSplSLib::IncreaseDegree(1, oldUDeg, UDeg, 0,
578                                poles->Array2(),
579                                BSplSLib::NoWeights(),
580                                biduknots, bidumults,
581                                npoles->ChangeArray2(), 
582                                BSplSLib::NoWeights(),
583                                biduknots, bidumults);
584     }
585     poles   = npoles;
586   }
587   if(IncVDeg > 0){
588     npoles = new TColgp_HArray2OfPnt( 1, UDeg + 1, 1, VDeg + 1);
589     
590     if ( urational || vrational) {
591       nweights = new TColStd_HArray2OfReal( 1, UDeg + 1, 1, VDeg + 1);
592       
593       BSplSLib::IncreaseDegree(0, oldVDeg, VDeg, 0,
594                                poles->Array2(),
595                                &weights->Array2(),
596                                bidvknots, bidvmults,
597                                npoles->ChangeArray2(), 
598                                &nweights->ChangeArray2(),
599                                bidvknots, bidvmults);
600       weights = nweights;
601     }
602     else {
603       BSplSLib::IncreaseDegree(0, oldVDeg, VDeg, 0,
604                                poles->Array2(),
605                                BSplSLib::NoWeights(),
606                                bidvknots, bidvmults,
607                                npoles->ChangeArray2(), 
608                                BSplSLib::NoWeights(),
609                                bidvknots, bidvmults);
610       
611     }
612     poles   = npoles;
613   }
614   Init(npoles,nweights);
615 }
616
617 //=======================================================================
618 //function : InsertPoleColAfter
619 //purpose  : 
620 //=======================================================================
621
622 void Geom_BezierSurface::InsertPoleColAfter 
623   (const Standard_Integer    VIndex,
624    const TColgp_Array1OfPnt& CPoles)
625 {
626   const TColgp_Array2OfPnt & Poles = poles->Array2();
627   if (VIndex < 1 || VIndex > Poles.RowLength())  Standard_OutOfRange::Raise();
628   if (CPoles.Length() != Poles.ColLength()) {
629     Standard_ConstructionError::Raise();
630   }
631
632   Handle(TColgp_HArray2OfPnt) npoles =
633     new TColgp_HArray2OfPnt(1,poles->ColLength(),1,poles->RowLength()+1);
634
635   Handle(TColStd_HArray2OfReal) nweights;
636
637   if (urational || vrational) {
638     nweights = 
639       new TColStd_HArray2OfReal(1,poles->ColLength(),1,poles->RowLength()+1);
640
641     TColStd_Array1OfReal CWeights(nweights->LowerRow(),nweights->UpperRow());
642     CWeights.Init(1.);
643
644     AddRatPoleCol (poles->Array2(), weights->Array2(),
645                    CPoles, CWeights, VIndex,
646                    npoles->ChangeArray2(), nweights->ChangeArray2());
647   }
648   else {
649     AddPoleCol (poles->Array2(), 
650                 CPoles, VIndex,
651                 npoles->ChangeArray2());
652   }
653   poles   = npoles;
654   weights = nweights;
655 }
656
657 //=======================================================================
658 //function : InsertPoleColAfter
659 //purpose  : 
660 //=======================================================================
661
662 void Geom_BezierSurface::InsertPoleColAfter
663   (const Standard_Integer      VIndex,
664    const TColgp_Array1OfPnt&   CPoles,
665    const TColStd_Array1OfReal& CPoleWeights)
666 {
667   const TColgp_Array2OfPnt & Poles = poles->Array2();
668   if (VIndex < 1 || VIndex > Poles.RowLength())  Standard_OutOfRange::Raise();
669   if (CPoles.Length() != Poles.ColLength() ||
670       CPoleWeights.Length() != CPoles.Length()) {
671     Standard_ConstructionError::Raise();
672     }
673   Standard_Integer Index = CPoleWeights.Lower();
674   while (Index <= CPoleWeights.Upper()) {
675     if (CPoleWeights (Index) <= gp::Resolution()) {
676       Standard_ConstructionError::Raise();
677       }
678     Index++;
679   }
680
681   Handle(TColgp_HArray2OfPnt) npoles =
682     new TColgp_HArray2OfPnt(1,poles->ColLength(),1,poles->RowLength()+1);
683   
684   Handle(TColStd_HArray2OfReal) nweights = 
685     new TColStd_HArray2OfReal(1,poles->ColLength(),1,poles->RowLength()+1);
686   
687   AddRatPoleCol (poles->Array2(), weights->Array2(),
688                  CPoles, CPoleWeights, VIndex,
689                  npoles->ChangeArray2(), nweights->ChangeArray2());
690
691   poles   = npoles;
692   weights = nweights;
693
694   Rational(weights->Array2(), urational, vrational);
695 }
696
697 //=======================================================================
698 //function : InsertPoleColBefore
699 //purpose  : 
700 //=======================================================================
701
702 void Geom_BezierSurface::InsertPoleColBefore (const Standard_Integer VIndex,
703                                               const TColgp_Array1OfPnt& CPoles)
704 {
705   InsertPoleColAfter(VIndex - 1, CPoles);
706 }
707
708 //=======================================================================
709 //function : InsertPoleColBefore
710 //purpose  : 
711 //=======================================================================
712
713 void Geom_BezierSurface::InsertPoleColBefore
714   (const Standard_Integer      VIndex,
715    const TColgp_Array1OfPnt&   CPoles,
716    const TColStd_Array1OfReal& CPoleWeights)
717 {
718   InsertPoleColAfter( VIndex - 1, CPoles, CPoleWeights);
719 }
720
721 //=======================================================================
722 //function : InsertPoleRowAfter
723 //purpose  : 
724 //=======================================================================
725
726 void Geom_BezierSurface::InsertPoleRowAfter (const Standard_Integer UIndex,
727                                              const TColgp_Array1OfPnt& CPoles)
728 {
729   const TColgp_Array2OfPnt & Poles = poles->Array2();
730   if (UIndex < 1 || UIndex > Poles.ColLength())  Standard_OutOfRange::Raise();
731   if (CPoles.Length() != Poles.RowLength()) {
732     Standard_ConstructionError::Raise();
733   }
734
735   Handle(TColgp_HArray2OfPnt) npoles =
736     new TColgp_HArray2OfPnt(1,poles->ColLength()+1,1,poles->RowLength());
737
738   Handle(TColStd_HArray2OfReal) nweights;
739
740   if (urational || vrational) {
741     nweights = 
742       new TColStd_HArray2OfReal(1,poles->ColLength()+1,1,poles->RowLength());
743
744 //    TColStd_Array1OfReal CWeights(nweights->LowerCol(),nweights->UpperCol(),
745 //                                1.0); ???????????
746     TColStd_Array1OfReal CWeights(1.0,
747                                   nweights->LowerCol(),nweights->UpperCol());
748
749     AddRatPoleRow (poles->Array2(), weights->Array2(),
750                    CPoles, CWeights, UIndex,
751                    npoles->ChangeArray2(), nweights->ChangeArray2());
752   }
753   else {
754     AddPoleRow (poles->Array2(), 
755                 CPoles, UIndex,
756                 npoles->ChangeArray2());
757   }
758   poles   = npoles;
759   weights = nweights;
760 }
761
762 //=======================================================================
763 //function : InsertPoleRowAfter
764 //purpose  : 
765 //=======================================================================
766
767 void Geom_BezierSurface::InsertPoleRowAfter
768   (const Standard_Integer      UIndex,
769    const TColgp_Array1OfPnt&   CPoles,
770    const TColStd_Array1OfReal& CPoleWeights)
771 {
772   const TColgp_Array2OfPnt & Poles = poles->Array2();
773   if (UIndex < 1 || UIndex > Poles.ColLength())  Standard_OutOfRange::Raise();
774   if (CPoles.Length() != Poles.RowLength() ||
775       CPoleWeights.Length() != CPoles.Length()) {
776     Standard_ConstructionError::Raise();
777   }
778   Standard_Integer Index = CPoleWeights.Lower();
779   while (Index <= CPoleWeights.Upper()) {
780     if (CPoleWeights(Index) <= gp::Resolution()) {
781       Standard_ConstructionError::Raise();
782     }
783     Index++;
784   }
785
786   Handle(TColgp_HArray2OfPnt) npoles =
787     new TColgp_HArray2OfPnt(1,poles->ColLength()+1,1,poles->RowLength());
788   
789   Handle(TColStd_HArray2OfReal) nweights = 
790     new TColStd_HArray2OfReal(1,poles->ColLength()+1,1,poles->RowLength());
791   
792   AddRatPoleCol (poles->Array2(), weights->Array2(),
793                  CPoles, CPoleWeights, UIndex,
794                  npoles->ChangeArray2(), nweights->ChangeArray2());
795
796   poles   = npoles;
797   weights = nweights;
798
799   Rational(weights->Array2(), urational, vrational);
800 }
801
802 //=======================================================================
803 //function : InsertPoleRowBefore
804 //purpose  : 
805 //=======================================================================
806
807 void Geom_BezierSurface::InsertPoleRowBefore (const Standard_Integer UIndex,
808                                               const TColgp_Array1OfPnt& CPoles)
809 {
810   InsertPoleRowAfter( UIndex - 1, CPoles);
811 }
812
813 //=======================================================================
814 //function : InsertPoleRowBefore
815 //purpose  : 
816 //=======================================================================
817
818 void Geom_BezierSurface::InsertPoleRowBefore
819   (const Standard_Integer      UIndex, 
820    const TColgp_Array1OfPnt&   CPoles,
821    const TColStd_Array1OfReal& CPoleWeights)
822 {
823   InsertPoleRowAfter( UIndex - 1, CPoles, CPoleWeights);
824
825
826 //=======================================================================
827 //function : RemovePoleCol
828 //purpose  : 
829 //=======================================================================
830
831 void Geom_BezierSurface::RemovePoleCol (const Standard_Integer VIndex)
832 {
833   const TColgp_Array2OfPnt & Poles = poles->Array2();
834   if (VIndex < 1 || VIndex > Poles.RowLength())  Standard_OutOfRange::Raise(); 
835   if (Poles.RowLength() <= 2)             Standard_ConstructionError::Raise();
836
837   Handle(TColgp_HArray2OfPnt) npoles =
838     new TColgp_HArray2OfPnt(1,poles->ColLength(),1,poles->RowLength()-1);
839
840   Handle(TColStd_HArray2OfReal) nweights;
841
842   if (urational || vrational) {
843     nweights = 
844       new TColStd_HArray2OfReal(1,poles->ColLength(),1,poles->RowLength()-1);
845
846     DeleteRatPoleCol (poles->Array2(), weights->Array2(),
847                       VIndex,
848                       npoles->ChangeArray2(), nweights->ChangeArray2());
849     // Mise a jour de la rationalite
850     Rational(nweights->Array2(), urational, vrational);
851   }
852   else {
853     DeletePoleCol (poles->Array2(), 
854                    VIndex,
855                    npoles->ChangeArray2());
856   }
857   poles   = npoles;
858   weights = nweights;
859 }
860
861 //=======================================================================
862 //function : RemovePoleRow
863 //purpose  : 
864 //=======================================================================
865
866 void Geom_BezierSurface::RemovePoleRow (const Standard_Integer UIndex)
867 {
868   const TColgp_Array2OfPnt & Poles = poles->Array2();
869   if (UIndex < 1 || UIndex > Poles.ColLength()) Standard_OutOfRange::Raise();
870   if (Poles.ColLength() <= 2)            Standard_ConstructionError::Raise();
871
872   Handle(TColgp_HArray2OfPnt) npoles =
873     new TColgp_HArray2OfPnt(1,poles->ColLength()-1,1,poles->RowLength());
874
875   Handle(TColStd_HArray2OfReal) nweights;
876
877   if (urational || vrational) {
878     nweights = 
879       new TColStd_HArray2OfReal(1,poles->ColLength()-1,1,poles->RowLength());
880
881     DeleteRatPoleRow (poles->Array2(), weights->Array2(),
882                       UIndex,
883                       npoles->ChangeArray2(), nweights->ChangeArray2());
884
885     // Mise a jour de la rationalite
886     Rational(nweights->Array2(), urational, vrational);
887   }
888   else {
889     DeletePoleRow (poles->Array2(), 
890                    UIndex,
891                    npoles->ChangeArray2());
892   }
893   poles   = npoles;
894   weights = nweights;
895 }
896
897 //=======================================================================
898 //function : Segment
899 //purpose  : 
900 //=======================================================================
901
902 void Geom_BezierSurface::Segment
903   (const Standard_Real U1,
904    const Standard_Real U2,
905    const Standard_Real V1,
906    const Standard_Real V2)
907 {
908   Standard_Boolean rat = (urational || vrational);
909   Handle(TColgp_HArray2OfPnt)  Coefs;
910   Handle(TColStd_HArray2OfReal) WCoefs;
911   
912   Standard_Integer aMinDegree = UDegree() <= VDegree() ? UDegree() : VDegree();
913   Standard_Integer aMaxDegree = UDegree() >  VDegree() ? UDegree() : VDegree();
914   Coefs = new TColgp_HArray2OfPnt(1, aMaxDegree + 1, 1, aMinDegree + 1);
915   if (rat)
916     WCoefs = new TColStd_HArray2OfReal(1, aMaxDegree + 1, 1, aMinDegree + 1);
917
918   TColStd_Array1OfReal biduflatknots(BSplCLib::FlatBezierKnots(UDegree()), 1, 2 * (UDegree() + 1));
919   TColStd_Array1OfReal bidvflatknots(BSplCLib::FlatBezierKnots(VDegree()), 1, 2 * (VDegree() + 1));
920
921   Standard_Real uparameter_11 = 0.5;
922   Standard_Real uspanlenght_11 = 0.5;
923   Standard_Real vparameter_11 = 0.5;
924   Standard_Real vspanlenght_11 = 0.5;
925
926   if (urational || vrational) {
927     BSplSLib::BuildCache(uparameter_11, vparameter_11,
928       uspanlenght_11, vspanlenght_11, 0, 0,
929       UDegree(), VDegree(), 0, 0,
930       biduflatknots, bidvflatknots,
931       poles->Array2(),
932       &weights->Array2(),
933       Coefs->ChangeArray2(),
934       &WCoefs->ChangeArray2());
935   }
936   else {
937     BSplSLib::BuildCache(uparameter_11, vparameter_11,
938       uspanlenght_11, vspanlenght_11, 0, 0,
939       UDegree(), VDegree(), 0, 0,
940       biduflatknots, bidvflatknots,
941       poles->Array2(),
942       BSplSLib::NoWeights(),
943       Coefs->ChangeArray2(),
944       BSplSLib::NoWeights());
945   }
946
947   // Attention si udeg <= vdeg u et v sont intervertis 
948   // dans les coeffs, il faut donc tout transposer.
949   if(UDegree() <= VDegree()) {
950     Handle(TColgp_HArray2OfPnt)  coeffs = Coefs;
951     Handle(TColStd_HArray2OfReal) wcoeffs = WCoefs;
952     Standard_Integer ii, jj;
953     Coefs = new  (TColgp_HArray2OfPnt)(1,UDegree()+1,1,VDegree()+1);
954     if (rat) {
955       WCoefs = new  (TColStd_HArray2OfReal)(1,UDegree()+1,1,VDegree()+1);
956     }
957     for (ii=1; ii<=UDegree()+1; ii++)
958       for (jj=1; jj<=VDegree()+1; jj++) {
959         Coefs->SetValue(ii, jj, coeffs->Value(jj,ii));
960         if (rat)  WCoefs->SetValue(ii, jj, wcoeffs->Value(jj,ii));
961       }
962   }
963
964 // Trim dans la base cannonique et Update des Poles et Coeffs
965
966 // PMN : tranfo sur les parametres
967   Standard_Real ufirst = 2*(U1 - 0.5),
968                 ulast =  2*(U2 - 0.5),
969                 vfirst = 2*(V1 - 0.5),
970                 vlast  = 2*(V2 - 0.5);
971   if (rat) {
972     PLib::UTrimming (ufirst, ulast, Coefs->ChangeArray2(),
973                      &WCoefs->ChangeArray2());
974     PLib::VTrimming (vfirst, vlast, Coefs->ChangeArray2(),
975                      &WCoefs->ChangeArray2());
976     PLib::CoefficientsPoles(Coefs->Array2(),
977                             &WCoefs->Array2(),
978                             poles->ChangeArray2(),
979                             &weights->ChangeArray2());
980   }
981   else {
982     PLib::UTrimming (ufirst, ulast, Coefs->ChangeArray2(), PLib::NoWeights2());
983     PLib::VTrimming (vfirst, vlast, Coefs->ChangeArray2(), PLib::NoWeights2());
984     PLib::CoefficientsPoles (Coefs->Array2(), PLib::NoWeights2(),
985                                                poles->ChangeArray2(), PLib::NoWeights2());
986   }
987 }
988
989 //=======================================================================
990 //function : SetPole
991 //purpose  : 
992 //=======================================================================
993
994 void Geom_BezierSurface::SetPole
995   (const Standard_Integer UIndex,
996    const Standard_Integer VIndex,
997    const gp_Pnt&          P)
998 {
999   TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1000   if (UIndex < 1                 ||
1001       UIndex > Poles.ColLength() ||
1002       VIndex < 1                 ||
1003       VIndex > Poles.RowLength() )    Standard_OutOfRange::Raise();
1004   
1005   Poles (UIndex, VIndex) = P;
1006 }
1007
1008 //=======================================================================
1009 //function : SetPole
1010 //purpose  : 
1011 //=======================================================================
1012
1013 void Geom_BezierSurface::SetPole
1014   (const Standard_Integer UIndex,
1015    const Standard_Integer VIndex, 
1016    const gp_Pnt&          P,
1017    const Standard_Real    Weight)
1018 {
1019
1020   if (Weight <= gp::Resolution())     
1021     Standard_ConstructionError::Raise("Geom_BezierSurface::SetPole");
1022   if (UIndex < 1                 || 
1023       UIndex > poles->ColLength() ||
1024       VIndex < 1                 ||
1025       VIndex > poles->RowLength())    
1026     Standard_OutOfRange::Raise("Geom_BezierSurface::SetPole");
1027
1028   poles->SetValue(UIndex, VIndex, P);
1029   
1030   SetWeight(UIndex, VIndex,  Weight); //L'update des coeff est fait la dedans
1031 }
1032
1033 //=======================================================================
1034 //function : SetPoleCol
1035 //purpose  : 
1036 //=======================================================================
1037
1038 void Geom_BezierSurface::SetPoleCol
1039   (const Standard_Integer      VIndex,
1040    const TColgp_Array1OfPnt&   CPoles,
1041    const TColStd_Array1OfReal& CPoleWeights)
1042 {
1043   TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1044   if (VIndex < 1 || VIndex > Poles.RowLength()) Standard_OutOfRange::Raise();
1045
1046   if (CPoles.Lower() < 1                     || 
1047       CPoles.Lower() > Poles.ColLength()     || 
1048       CPoles.Upper() < 1                     || 
1049       CPoles.Upper() > Poles.ColLength()     ||
1050       CPoleWeights.Lower() != CPoles.Lower() ||
1051       CPoleWeights.Upper() != CPoles.Upper()) {
1052     Standard_ConstructionError::Raise();
1053   }
1054      
1055   Standard_Integer I;
1056   for (I = CPoles.Lower();  I <= CPoles.Upper(); I++) {
1057     Poles (I, VIndex) = CPoles (I);
1058   }
1059   SetWeightCol(VIndex, CPoleWeights); //Avec l'update
1060 }
1061
1062 //=======================================================================
1063 //function : SetPoleCol
1064 //purpose  : 
1065 //=======================================================================
1066
1067 void Geom_BezierSurface::SetPoleCol (const Standard_Integer      VIndex,
1068                                      const TColgp_Array1OfPnt&   CPoles)
1069 {
1070   TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1071   if (VIndex < 1 || VIndex > Poles.RowLength())  Standard_OutOfRange::Raise();
1072
1073   if (CPoles.Lower() < 1                 || 
1074       CPoles.Lower() > Poles.ColLength() || 
1075       CPoles.Upper() < 1                 ||
1076       CPoles.Upper() > Poles.ColLength()) {
1077     Standard_ConstructionError::Raise();
1078   }
1079   for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
1080     Poles (I, VIndex) = CPoles (I);
1081   }
1082 }
1083
1084 //=======================================================================
1085 //function : SetPoleRow
1086 //purpose  : 
1087 //=======================================================================
1088
1089 void Geom_BezierSurface::SetPoleRow (const Standard_Integer    UIndex,
1090                                      const TColgp_Array1OfPnt& CPoles)
1091 {
1092   TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1093   if (UIndex < 1 || UIndex > Poles.ColLength())  Standard_OutOfRange::Raise();
1094
1095   if (CPoles.Lower() < 1                 ||
1096       CPoles.Lower() > Poles.RowLength() || 
1097       CPoles.Upper() < 1                 || 
1098       CPoles.Upper() > Poles.RowLength())  Standard_ConstructionError::Raise();
1099
1100   for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
1101     Poles (UIndex, I) = CPoles (I);
1102   }
1103 }
1104
1105 //=======================================================================
1106 //function : SetPoleRow
1107 //purpose  : 
1108 //=======================================================================
1109
1110 void Geom_BezierSurface::SetPoleRow
1111   (const Standard_Integer      UIndex,
1112    const TColgp_Array1OfPnt&   CPoles,
1113    const TColStd_Array1OfReal& CPoleWeights)
1114 {
1115   TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1116   if (UIndex < 1 || UIndex > Poles.ColLength())   Standard_OutOfRange::Raise();
1117
1118   if (CPoles.Lower() < 1                     || 
1119       CPoles.Lower() > Poles.RowLength()     || 
1120       CPoles.Upper() < 1                     || 
1121       CPoles.Upper() > Poles.RowLength()     ||
1122       CPoleWeights.Lower() != CPoles.Lower() ||
1123       CPoleWeights.Upper() != CPoles.Upper()) {
1124     Standard_ConstructionError::Raise();
1125   }
1126
1127   Standard_Integer I;
1128
1129   for (I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
1130     Poles   (UIndex, I) = CPoles (I);
1131   }
1132   
1133   SetWeightRow(UIndex, CPoleWeights); //Avec l'update 
1134 }
1135
1136 //=======================================================================
1137 //function : SetWeight
1138 //purpose  : 
1139 //=======================================================================
1140
1141 void Geom_BezierSurface::SetWeight (const Standard_Integer UIndex,
1142                                     const Standard_Integer VIndex,
1143                                     const Standard_Real    Weight)
1144 {
1145    // compute new rationality
1146   Standard_Boolean wasrat = (urational||vrational);
1147   if (!wasrat) {
1148     // a weight of 1. does not turn to rational
1149     if (Abs(Weight - 1.) <= gp::Resolution())
1150       return;
1151
1152     // set weights of 1.
1153     weights = new TColStd_HArray2OfReal (1, poles->ColLength(),
1154                                          1, poles->RowLength(), 1.);
1155   }
1156
1157   TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1158   if (Weight <= gp::Resolution())      
1159     Standard_ConstructionError::Raise("Geom_BezierSurface::SetWeight");
1160
1161   if (UIndex < 1                   || 
1162       UIndex > Weights.ColLength() ||
1163       VIndex < 1                   || 
1164       VIndex > Weights.RowLength())    Standard_OutOfRange::Raise();
1165
1166   if (Abs (Weight - Weights (UIndex, VIndex)) > gp::Resolution()) {
1167     Weights (UIndex, VIndex) = Weight;
1168     Rational(Weights, urational, vrational);
1169   }
1170
1171  // is it turning into non rational
1172   if (wasrat && !(urational || vrational))
1173     weights.Nullify();
1174 }
1175
1176 //=======================================================================
1177 //function : SetWeightCol
1178 //purpose  : 
1179 //=======================================================================
1180
1181 void Geom_BezierSurface::SetWeightCol 
1182   (const Standard_Integer      VIndex,
1183    const TColStd_Array1OfReal& CPoleWeights)
1184 {
1185   Standard_Integer I;
1186    // compute new rationality
1187   Standard_Boolean wasrat = (urational||vrational);
1188   if (!wasrat) {   
1189     // set weights of 1.
1190     weights = new TColStd_HArray2OfReal (1, poles->ColLength(),
1191                                          1, poles->RowLength(), 1.);
1192   }
1193
1194   TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1195   if (VIndex < 1 || VIndex > Weights.RowLength()) Standard_OutOfRange::Raise();
1196
1197   if (CPoleWeights.Length() !=  Weights.ColLength())  {
1198     Standard_ConstructionError::Raise("Geom_BezierSurface::SetWeightCol");
1199   }
1200
1201   I = CPoleWeights.Lower();
1202   while (I <= CPoleWeights.Upper()) {
1203     if (CPoleWeights(I) <= gp::Resolution()) {
1204       Standard_ConstructionError::Raise();
1205     }
1206     Weights (I, VIndex) = CPoleWeights (I);
1207     I++;
1208   }
1209
1210  Rational(Weights, urational, vrational);
1211
1212  // is it turning into non rational
1213  if (wasrat && !(urational || vrational))
1214    weights.Nullify();
1215 }
1216
1217 //=======================================================================
1218 //function : SetWeightRow
1219 //purpose  : 
1220 //=======================================================================
1221
1222 void Geom_BezierSurface::SetWeightRow 
1223   (const Standard_Integer      UIndex,
1224    const TColStd_Array1OfReal& CPoleWeights)
1225 {
1226   Standard_Integer I;
1227    // compute new rationality
1228   Standard_Boolean wasrat = (urational||vrational);
1229   if (!wasrat) {    
1230     // set weights of 1.
1231     weights = new TColStd_HArray2OfReal (1, poles->ColLength(),
1232                                          1, poles->RowLength(), 1.);
1233   }
1234
1235   TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1236   if (UIndex < 1 || UIndex > Weights.ColLength()) 
1237     Standard_OutOfRange::Raise("Geom_BezierSurface::SetWeightRow");
1238   if (CPoleWeights.Lower() < 1 ||
1239       CPoleWeights.Lower() > Weights.RowLength() ||
1240       CPoleWeights.Upper() < 1 ||
1241       CPoleWeights.Upper() > Weights.RowLength()  ) {
1242     Standard_ConstructionError::Raise("Geom_BezierSurface::SetWeightRow");
1243   }
1244
1245   I = CPoleWeights.Lower();
1246   while (I <= CPoleWeights.Upper()) {
1247     if (CPoleWeights(I) <= gp::Resolution())  {
1248       Standard_ConstructionError::Raise();
1249     }
1250     Weights (UIndex, I) = CPoleWeights (I);
1251     I++;
1252   }
1253
1254   Rational(Weights, urational, vrational);
1255
1256  // is it turning into non rational
1257   if (wasrat && !(urational || vrational))
1258     weights.Nullify();
1259 }
1260
1261 //=======================================================================
1262 //function : UReverse
1263 //purpose  : 
1264 //=======================================================================
1265
1266 void Geom_BezierSurface::UReverse ()
1267 {
1268   gp_Pnt Pol;
1269   Standard_Integer Row,Col;
1270   TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1271   if (urational || vrational) {
1272     TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1273     Standard_Real W;
1274     for (Col = 1; Col <= Poles.RowLength(); Col++) {
1275       for (Row = 1; Row <= IntegerPart (Poles.ColLength() / 2); Row++) {
1276         W = Weights (Row, Col);
1277         Weights (Row, Col) = Weights (Poles.ColLength()- Row + 1, Col);
1278         Weights (Poles.ColLength() - Row + 1, Col) = W;
1279         Pol = Poles (Row, Col);
1280         Poles (Row, Col) = Poles (Poles.ColLength() - Row + 1, Col);
1281         Poles (Poles.ColLength() - Row + 1, Col) = Pol;
1282       }
1283     }
1284   }
1285   else {
1286     for (Col = 1; Col <= Poles.RowLength(); Col++) {
1287       for (Row = 1; Row <= IntegerPart (Poles.ColLength() / 2); Row++) {
1288         Pol = Poles (Row, Col);
1289         Poles (Row, Col) = Poles (Poles.ColLength() - Row + 1, Col);
1290         Poles (Poles.ColLength() - Row + 1, Col) = Pol;
1291       }
1292     }
1293   }
1294 }
1295
1296 //=======================================================================
1297 //function : UReversedParameter
1298 //purpose  : 
1299 //=======================================================================
1300
1301 Standard_Real Geom_BezierSurface::UReversedParameter
1302   ( const Standard_Real U) const 
1303 {
1304   return ( 1. - U);
1305 }
1306
1307 //=======================================================================
1308 //function : VReverse
1309 //purpose  : 
1310 //=======================================================================
1311
1312 void Geom_BezierSurface::VReverse ()
1313 {
1314   gp_Pnt Pol;
1315   Standard_Integer Row,Col;
1316   TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1317   if (urational || vrational) {
1318     TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1319     Standard_Real W;
1320     for (Row = 1; Row <= Poles.ColLength(); Row++) {
1321       for (Col = 1; Col <= IntegerPart (Poles.RowLength()/2); Col++) {
1322         W = Weights (Row, Col);
1323         Weights (Row, Col) = Weights (Row, Poles.RowLength() - Col + 1);
1324         Weights (Row, Poles.RowLength() - Col + 1) = W;
1325         Pol = Poles (Row, Col);
1326         Poles (Row, Col) = Poles (Row, Poles.RowLength() - Col + 1);
1327         Poles (Row, Poles.RowLength() - Col + 1) = Pol;
1328       }
1329     }
1330   }
1331   else {
1332     for (Row = 1; Row <= Poles.ColLength(); Row++) {
1333       for (Col = 1; Col <= IntegerPart(Poles.RowLength()/2); Col++) {
1334         Pol = Poles (Row, Col);
1335         Poles (Row, Col)= Poles (Row, Poles.RowLength() - Col + 1);
1336         Poles (Row, Poles.RowLength() - Col + 1) = Pol;
1337       }
1338     }
1339   }
1340 }
1341
1342 //=======================================================================
1343 //function : VReversedParameter
1344 //purpose  : 
1345 //=======================================================================
1346
1347 Standard_Real Geom_BezierSurface::VReversedParameter
1348   ( const Standard_Real V) const 
1349 {
1350   return ( 1. - V);
1351 }
1352
1353 //=======================================================================
1354 //function : Bounds
1355 //purpose  : 
1356 //=======================================================================
1357
1358 void Geom_BezierSurface::Bounds (Standard_Real& U1,
1359                                  Standard_Real& U2,
1360                                  Standard_Real& V1,
1361                                  Standard_Real& V2) const
1362 {
1363   U1 = 0.0;  
1364   U2 = 1.0; 
1365   V1 = 0.0;
1366   V2 = 1.0;
1367 }
1368
1369 //=======================================================================
1370 //function : Continuity
1371 //purpose  : 
1372 //=======================================================================
1373
1374 GeomAbs_Shape Geom_BezierSurface::Continuity () const
1375 {
1376   return GeomAbs_CN; 
1377 }
1378
1379 //=======================================================================
1380 //function : D0
1381 //purpose  : 
1382 //=======================================================================
1383
1384 void Geom_BezierSurface::D0 (const Standard_Real U,
1385                              const Standard_Real V,
1386                                    gp_Pnt&       P ) const
1387 {
1388   Standard_Real array_u[2];
1389   Standard_Real array_v[2];
1390   Standard_Integer mult_u[2];
1391   Standard_Integer mult_v[2];
1392   TColStd_Array1OfReal biduknots(array_u[0], 1, 2); biduknots(1) = 0.; biduknots(2) = 1.;
1393   TColStd_Array1OfInteger bidumults(mult_u[0], 1, 2); bidumults.Init(UDegree() + 1);
1394   TColStd_Array1OfReal bidvknots(array_v[0], 1, 2); bidvknots(1) = 0.; bidvknots(2) = 1.;
1395   TColStd_Array1OfInteger bidvmults(mult_v[0], 1, 2); bidvmults.Init(VDegree() + 1);
1396   if (urational || vrational) {
1397     BSplSLib::D0(U, V, 1, 1, poles->Array2(),
1398       &weights->Array2(),
1399       biduknots, bidvknots, &bidumults, &bidvmults,
1400       UDegree(), VDegree(),
1401       urational, vrational, Standard_False, Standard_False,
1402       P);
1403   }
1404   else {
1405
1406     BSplSLib::D0(U, V, 1, 1, poles->Array2(),
1407       BSplSLib::NoWeights(),
1408       biduknots, bidvknots, &bidumults, &bidvmults,
1409       UDegree(), VDegree(),
1410       urational, vrational, Standard_False, Standard_False,
1411       P);
1412   }
1413 }
1414
1415 //=======================================================================
1416 //function : D1
1417 //purpose  : 
1418 //=======================================================================
1419
1420 void Geom_BezierSurface::D1
1421   (const Standard_Real U,
1422    const Standard_Real V,
1423          gp_Pnt&       P,
1424          gp_Vec&       D1U,
1425          gp_Vec&       D1V ) const
1426 {
1427   Standard_Real array_u[2];
1428   Standard_Real array_v[2];
1429   Standard_Integer mult_u[2];
1430   Standard_Integer mult_v[2];
1431   TColStd_Array1OfReal biduknots(array_u[0], 1, 2); biduknots(1) = 0.; biduknots(2) = 1.;
1432   TColStd_Array1OfInteger bidumults(mult_u[0], 1, 2); bidumults.Init(UDegree() + 1);
1433   TColStd_Array1OfReal bidvknots(array_v[0], 1, 2); bidvknots(1) = 0.; bidvknots(2) = 1.;
1434   TColStd_Array1OfInteger bidvmults(mult_v[0], 1, 2); bidvmults.Init(VDegree() + 1);
1435   if (urational || vrational) {
1436     BSplSLib::D1(U, V, 1, 1, poles->Array2(),
1437       &weights->Array2(),
1438       biduknots, bidvknots, &bidumults, &bidvmults,
1439       UDegree(), VDegree(),
1440       urational, vrational, Standard_False, Standard_False,
1441       P, D1U, D1V);
1442   }
1443   else {
1444     BSplSLib::D1(U, V, 1, 1, poles->Array2(),
1445       BSplSLib::NoWeights(),
1446       biduknots, bidvknots, &bidumults, &bidvmults,
1447       UDegree(), VDegree(),
1448       urational, vrational, Standard_False, Standard_False,
1449       P, D1U, D1V);
1450   }
1451 }
1452
1453 //=======================================================================
1454 //function : D2
1455 //purpose  : 
1456 //=======================================================================
1457
1458 void Geom_BezierSurface::D2
1459   (const Standard_Real U,
1460    const Standard_Real V,
1461          gp_Pnt&       P,
1462          gp_Vec&       D1U, gp_Vec& D1V, 
1463          gp_Vec&       D2U, gp_Vec& D2V, gp_Vec& D2UV ) const
1464 {
1465   Standard_Real array_u[2];
1466   Standard_Real array_v[2];
1467   Standard_Integer mult_u[2];
1468   Standard_Integer mult_v[2];
1469   TColStd_Array1OfReal biduknots(array_u[0], 1, 2); biduknots(1) = 0.; biduknots(2) = 1.;
1470   TColStd_Array1OfInteger bidumults(mult_u[0], 1, 2); bidumults.Init(UDegree() + 1);
1471   TColStd_Array1OfReal bidvknots(array_v[0], 1, 2); bidvknots(1) = 0.; bidvknots(2) = 1.;
1472   TColStd_Array1OfInteger bidvmults(mult_v[0], 1, 2); bidvmults.Init(VDegree() + 1);
1473   if (urational || vrational) {
1474     //-- ATTENTION a l'ORDRE d'appel ds BSPLSLIB 
1475     BSplSLib::D2(U, V, 1, 1, poles->Array2(),
1476       &weights->Array2(),
1477       biduknots, bidvknots, &bidumults, &bidvmults,
1478       UDegree(), VDegree(),
1479       urational, vrational, Standard_False, Standard_False,
1480       P, D1U, D1V, D2U, D2V, D2UV);
1481   }
1482   else {
1483     //-- ATTENTION a l'ORDRE d'appel ds BSPLSLIB 
1484     BSplSLib::D2(U, V, 1, 1, poles->Array2(),
1485       BSplSLib::NoWeights(),
1486       biduknots, bidvknots, &bidumults, &bidvmults,
1487       UDegree(), VDegree(),
1488       urational, vrational, Standard_False, Standard_False,
1489       P, D1U, D1V, D2U, D2V, D2UV);
1490   }
1491 }
1492
1493 //=======================================================================
1494 //function : D3
1495 //purpose  : 
1496 //=======================================================================
1497
1498 void Geom_BezierSurface::D3
1499   (const Standard_Real U, const Standard_Real V,
1500    gp_Pnt& P,
1501    gp_Vec& D1U, gp_Vec& D1V, 
1502    gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV, 
1503    gp_Vec& D3U, gp_Vec& D3V, gp_Vec& D3UUV, gp_Vec& D3UVV) const
1504 {
1505   TColStd_Array1OfReal biduknots(1,2); biduknots(1) = 0.; biduknots(2) = 1.;
1506   TColStd_Array1OfInteger bidumults(1,2); bidumults.Init(UDegree() + 1);
1507   TColStd_Array1OfReal bidvknots(1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
1508   TColStd_Array1OfInteger bidvmults(1,2); bidvmults.Init(VDegree() + 1);
1509   if (urational || vrational) { 
1510     BSplSLib::D3 (U, V, 0, 0, poles->Array2(),
1511                   &weights->Array2(),
1512                   biduknots, bidvknots, &bidumults, &bidvmults,
1513                   UDegree(), VDegree(), urational, vrational, 0, 0,
1514                   P,
1515                   D1U, D1V,
1516                   D2U, D2V, D2UV,
1517                   D3U, D3V, D3UUV, D3UVV);
1518   }
1519   else { 
1520     BSplSLib::D3 (U, V, 0, 0, poles->Array2(),
1521                   BSplSLib::NoWeights(),
1522                   biduknots, bidvknots, &bidumults, &bidvmults,
1523                   UDegree(), VDegree(), urational, vrational, 0, 0,
1524                   P,
1525                   D1U, D1V,
1526                   D2U, D2V, D2UV,
1527                   D3U, D3V, D3UUV, D3UVV);
1528   }
1529 }
1530
1531 //=======================================================================
1532 //function : DN
1533 //purpose  : 
1534 //=======================================================================
1535
1536 gp_Vec Geom_BezierSurface::DN
1537   (const Standard_Real    U,
1538    const Standard_Real    V,
1539    const Standard_Integer Nu,
1540    const Standard_Integer Nv) const
1541 {
1542   Standard_RangeError_Raise_if (Nu + Nv < 1 || Nv < 0 || Nu <0, " ");
1543   gp_Vec Derivative;
1544   TColStd_Array1OfReal biduknots(1,2); biduknots(1) = 0.; biduknots(2) = 1.;
1545   TColStd_Array1OfInteger bidumults(1,2); bidumults.Init(UDegree() + 1);
1546   TColStd_Array1OfReal bidvknots(1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
1547   TColStd_Array1OfInteger bidvmults(1,2); bidvmults.Init(VDegree() + 1);
1548   if (urational || vrational) { 
1549     BSplSLib::DN (U, V, Nu, Nv, 0, 0, poles->Array2(),
1550                   &weights->Array2(),
1551                   biduknots, bidvknots, &bidumults, &bidvmults,
1552                   UDegree(), VDegree(), urational, vrational, 0, 0,
1553                   Derivative);
1554   }
1555   else { 
1556     BSplSLib::DN (U, V, Nu, Nv, 0, 0, poles->Array2(),
1557                   BSplSLib::NoWeights(),
1558                   biduknots, bidvknots, &bidumults, &bidvmults,
1559                   UDegree(), VDegree(), urational, vrational, 0, 0,
1560                   Derivative);
1561   }
1562   return Derivative;
1563 }
1564
1565 //=======================================================================
1566 //function : NbUPoles
1567 //purpose  : 
1568 //=======================================================================
1569
1570 Standard_Integer Geom_BezierSurface::NbUPoles () const
1571 {
1572   return poles->ColLength(); 
1573 }
1574
1575 //=======================================================================
1576 //function : NbVPoles
1577 //purpose  : 
1578 //=======================================================================
1579
1580 Standard_Integer Geom_BezierSurface::NbVPoles () const
1581 {
1582   return poles->RowLength(); 
1583 }
1584
1585 //=======================================================================
1586 //function : Pole
1587 //purpose  : 
1588 //=======================================================================
1589
1590 gp_Pnt Geom_BezierSurface::Pole (const Standard_Integer UIndex,
1591                                  const Standard_Integer VIndex) const
1592 {
1593   Standard_OutOfRange_Raise_if
1594     (UIndex < 1 || UIndex > poles->ColLength() ||
1595      VIndex < 1 || VIndex > poles->RowLength(), " ");
1596   return poles->Value (UIndex + poles->LowerRow() - 1,
1597                        VIndex + poles->LowerCol() - 1);
1598 }
1599
1600 //=======================================================================
1601 //function : Poles
1602 //purpose  : 
1603 //=======================================================================
1604
1605 void Geom_BezierSurface::Poles (TColgp_Array2OfPnt& P) const
1606 {
1607   Standard_DimensionError_Raise_if
1608     (P.RowLength() != poles->RowLength() ||
1609      P.ColLength() != poles->ColLength(), " ");
1610   P = poles->Array2();
1611 }
1612
1613 //=======================================================================
1614 //function : UDegree
1615 //purpose  : 
1616 //=======================================================================
1617
1618 Standard_Integer Geom_BezierSurface::UDegree () const
1619 {
1620   return poles->ColLength() - 1; 
1621 }
1622
1623 //=======================================================================
1624 //function : UIso
1625 //purpose  : 
1626 //=======================================================================
1627
1628 Handle(Geom_Curve) Geom_BezierSurface::UIso (const Standard_Real U) const
1629 {
1630   TColStd_Array1OfReal biduknots(1,2); biduknots(1) = 0.; biduknots(2) = 1.;
1631   TColStd_Array1OfInteger bidumults(1,2); bidumults.Init(UDegree() + 1);
1632
1633   Handle(Geom_BezierCurve) UIsoCurve;
1634   const TColgp_Array2OfPnt & Poles = poles->Array2();
1635   TColgp_Array1OfPnt VCurvePoles (Poles.LowerCol() , Poles.UpperCol());
1636   if (urational || vrational) {
1637     const TColStd_Array2OfReal & Weights = weights->Array2();
1638     TColStd_Array1OfReal VCurveWeights 
1639       (Weights.LowerCol() , Weights.UpperCol());
1640     BSplSLib::Iso (U, 1, Poles,
1641                    &Weights,
1642                    biduknots, &bidumults,
1643                    UDegree(), 0, VCurvePoles, &VCurveWeights);
1644     if (urational)
1645       UIsoCurve = new Geom_BezierCurve (VCurvePoles, VCurveWeights);
1646     else
1647       UIsoCurve = new Geom_BezierCurve (VCurvePoles);
1648   }
1649   else {
1650     BSplSLib::Iso (U, 1, Poles,
1651                    BSplSLib::NoWeights(),
1652                    biduknots, &bidumults,
1653                    UDegree(), 0, VCurvePoles, PLib::NoWeights());
1654     UIsoCurve = new Geom_BezierCurve (VCurvePoles);
1655   }
1656   return UIsoCurve;
1657 }
1658
1659 //=======================================================================
1660 //function : VDegree
1661 //purpose  : 
1662 //=======================================================================
1663
1664 Standard_Integer Geom_BezierSurface::VDegree () const
1665 {
1666   return poles->RowLength() - 1; 
1667 }
1668
1669 //=======================================================================
1670 //function : VIso
1671 //purpose  : 
1672 //=======================================================================
1673
1674 Handle(Geom_Curve) Geom_BezierSurface::VIso (const Standard_Real V) const
1675 {
1676   TColStd_Array1OfReal bidvknots(1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
1677   TColStd_Array1OfInteger bidvmults(1,2); bidvmults.Init(VDegree() + 1);
1678
1679   Handle(Geom_BezierCurve) VIsoCurve;
1680   const TColgp_Array2OfPnt & Poles = poles->Array2();
1681   TColgp_Array1OfPnt VCurvePoles (Poles.LowerRow() , Poles.UpperRow());
1682   if (vrational || urational) {
1683     const TColStd_Array2OfReal & Weights = weights->Array2();
1684     TColStd_Array1OfReal VCurveWeights 
1685       (Weights.LowerRow() , Weights.UpperRow());
1686     BSplSLib::Iso (V, 0, Poles,
1687                    &Weights,
1688                    bidvknots, &bidvmults,
1689                    VDegree(), 0, VCurvePoles, &VCurveWeights);
1690     if (vrational)
1691       VIsoCurve = new Geom_BezierCurve (VCurvePoles, VCurveWeights);
1692     else
1693       VIsoCurve = new Geom_BezierCurve (VCurvePoles);
1694   }
1695   else {
1696     BSplSLib::Iso (V, 0, Poles,
1697                    BSplSLib::NoWeights(),
1698                    bidvknots, &bidvmults,
1699                    VDegree(), 0, VCurvePoles, PLib::NoWeights());
1700     VIsoCurve = new Geom_BezierCurve (VCurvePoles);
1701   }
1702   return VIsoCurve;
1703 }
1704
1705 //=======================================================================
1706 //function : Weight
1707 //purpose  : 
1708 //=======================================================================
1709
1710 Standard_Real Geom_BezierSurface::Weight (const Standard_Integer UIndex,
1711                                           const Standard_Integer VIndex) const
1712 {
1713   Standard_OutOfRange_Raise_if (
1714            UIndex < 1 || UIndex > weights->ColLength() ||
1715            VIndex < 1 || VIndex > weights->RowLength(), " ");
1716
1717   if (urational || vrational) 
1718     return weights->Value (UIndex, VIndex);
1719   else 
1720     return 1;
1721 }
1722
1723 //=======================================================================
1724 //function : Weights
1725 //purpose  : 
1726 //=======================================================================
1727
1728 void Geom_BezierSurface::Weights (TColStd_Array2OfReal& W ) const
1729 {
1730   Standard_DimensionError_Raise_if (
1731            W.RowLength() != weights->RowLength() ||
1732            W.ColLength() != weights->ColLength(), " " );
1733   if (urational || vrational) 
1734     W = weights->Array2();
1735   else 
1736     W.Init(1.);
1737 }
1738
1739 //=======================================================================
1740 //function : IsCNu
1741 //purpose  : 
1742 //=======================================================================
1743
1744 Standard_Boolean Geom_BezierSurface::IsCNu (const Standard_Integer ) const
1745 {
1746   return Standard_True; 
1747 }
1748
1749 //=======================================================================
1750 //function : IsCNv
1751 //purpose  : 
1752 //=======================================================================
1753
1754 Standard_Boolean Geom_BezierSurface::IsCNv (const Standard_Integer ) const
1755 {
1756   return Standard_True; 
1757 }
1758
1759 //=======================================================================
1760 //function : IsURational
1761 //purpose  : 
1762 //=======================================================================
1763
1764 Standard_Boolean Geom_BezierSurface::IsURational () const
1765 {
1766   return urational; 
1767 }
1768
1769 //=======================================================================
1770 //function : IsVRational
1771 //purpose  : 
1772 //=======================================================================
1773
1774 Standard_Boolean Geom_BezierSurface::IsVRational () const
1775 {
1776   return vrational; 
1777 }
1778
1779 //=======================================================================
1780 //function : Transform
1781 //purpose  : 
1782 //=======================================================================
1783
1784 void Geom_BezierSurface::Transform (const gp_Trsf& T)
1785 {
1786   TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1787
1788   for (Standard_Integer I = 1; I <= Poles.ColLength(); I++) {
1789
1790     for (Standard_Integer J = 1; J <= Poles.RowLength(); J++) {
1791       Poles (I, J).Transform (T);
1792     }
1793   }
1794 }
1795
1796 //=======================================================================
1797 //function : IsUClosed
1798 //purpose  : 
1799 //=======================================================================
1800
1801 Standard_Boolean Geom_BezierSurface::IsUClosed () const
1802
1803   const TColgp_Array2OfPnt & Poles = poles->Array2();
1804   Standard_Boolean Closed = Standard_True;
1805   Standard_Integer Lower  = Poles.LowerRow();
1806   Standard_Integer Upper  = Poles.UpperRow();
1807   Standard_Integer Length = Poles.RowLength();
1808   Standard_Integer j      = Poles.LowerCol();
1809
1810   while (Closed && j <= Length) {
1811     Closed = (Poles (Lower,j).Distance (Poles (Upper,j)) <= Precision::Confusion());
1812     j++;
1813   }
1814   return Closed; 
1815 }
1816
1817 //=======================================================================
1818 //function : IsVClosed
1819 //purpose  : 
1820 //=======================================================================
1821
1822 Standard_Boolean Geom_BezierSurface::IsVClosed () const
1823
1824   const TColgp_Array2OfPnt & Poles = poles->Array2();
1825   Standard_Boolean Closed = Standard_True;
1826   Standard_Integer Lower  = Poles.LowerCol();
1827   Standard_Integer Upper  = Poles.UpperCol();
1828   Standard_Integer Length = Poles.ColLength();
1829   Standard_Integer i      = Poles.LowerRow();
1830   while (Closed && i <= Length) {
1831     Closed = (Poles (i,Lower).Distance (Poles (i,Upper)) <= Precision::Confusion());
1832     i++;
1833   }
1834   return Closed; 
1835 }
1836
1837 //=======================================================================
1838 //function : IsUPeriodic
1839 //purpose  : 
1840 //=======================================================================
1841
1842 Standard_Boolean Geom_BezierSurface::IsUPeriodic () const
1843 {
1844   return Standard_False; 
1845 }
1846
1847 //=======================================================================
1848 //function : IsVPeriodic
1849 //purpose  : 
1850 //=======================================================================
1851
1852 Standard_Boolean Geom_BezierSurface::IsVPeriodic () const
1853 {
1854   return Standard_False; 
1855 }
1856
1857 //=======================================================================
1858 //function : Resolution
1859 //purpose  : 
1860 //=======================================================================
1861
1862 void Geom_BezierSurface::Resolution(const Standard_Real  Tolerance3D,
1863                                     Standard_Real&       UTolerance,
1864                                     Standard_Real&       VTolerance) 
1865 {
1866   if(!maxderivinvok){
1867     TColStd_Array1OfReal biduknots(1,2); biduknots(1) = 0.; biduknots(2) = 1.;
1868     TColStd_Array1OfInteger bidumults(1,2); bidumults.Init(UDegree() + 1);
1869     TColStd_Array1OfReal bidvknots(1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
1870     TColStd_Array1OfInteger bidvmults(1,2); bidvmults.Init(VDegree() + 1);
1871     if(urational || vrational){
1872       BSplSLib::Resolution(poles->Array2(),
1873                            &weights->Array2(),
1874                            biduknots,
1875                            bidvknots,
1876                            bidumults,
1877                            bidvmults,
1878                            UDegree(),
1879                            VDegree(),
1880                            urational,
1881                            vrational,
1882                            0,
1883                            0,
1884                            1.,
1885                            umaxderivinv,
1886                            vmaxderivinv) ;
1887     }
1888     else{
1889       BSplSLib::Resolution(poles->Array2(),
1890                            BSplSLib::NoWeights(),
1891                            biduknots,
1892                            bidvknots,
1893                            bidumults,
1894                            bidvmults,
1895                            UDegree(),
1896                            VDegree(),
1897                            urational,
1898                            vrational,
1899                            0,
1900                            0,
1901                            1.,
1902                            umaxderivinv,
1903                            vmaxderivinv) ;
1904     }
1905     maxderivinvok = 1;
1906   }
1907   UTolerance = Tolerance3D * umaxderivinv;
1908   VTolerance = Tolerance3D * vmaxderivinv;
1909 }
1910
1911 //=======================================================================
1912 //function : Copy
1913 //purpose  : 
1914 //=======================================================================
1915
1916 Handle(Geom_Geometry) Geom_BezierSurface::Copy() const
1917 {
1918   Handle(Geom_BezierSurface) S = new Geom_BezierSurface
1919     (poles, weights, urational, vrational);
1920   return S;
1921 }
1922
1923 //=======================================================================
1924 //function : Init
1925 //purpose  : 
1926 //=======================================================================
1927
1928 void Geom_BezierSurface::Init
1929   (const Handle(TColgp_HArray2OfPnt)&   Poles, 
1930    const Handle(TColStd_HArray2OfReal)& Weights)
1931 {
1932   // set fields
1933   poles = Poles;
1934   if (urational || vrational)
1935     weights = Weights;
1936   else
1937     weights.Nullify();
1938 }
1939