0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / Geom / Geom_BezierSurface.cxx
1 // Created on: 1993-03-09
2 // Created by: JCV
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 //Passage en classe persistante - 23/01/91
18 //Modif suite a la deuxieme revue de projet toolkit Geometry -23/01/91
19 // pmn : 21/10/95 ; Correction de la methode segment (PRO5853)
20 // pmn : 31-Dec-96; Bonne gestion des poids (bug PRO4622)
21 // xab : 07-Jul-97; le cache est instable en degree 21
22 //       a partir du degree 15 on ne l'utilise plus
23 // RBD : 15/10/98 ; Le cache est desormais defini sur [-1,1] (pro15537).
24 // pmn : 10/12/98 ; Update de la methode segment (suite a la modif de cache).
25
26 #define No_Standard_OutOfRange
27 #define No_Standard_DimensionError
28
29
30 #include <BSplCLib.hxx>
31 #include <Geom_BezierCurve.hxx>
32 #include <Geom_BezierSurface.hxx>
33 #include <Geom_Curve.hxx>
34 #include <Geom_Geometry.hxx>
35 #include <gp.hxx>
36 #include <gp_Pnt.hxx>
37 #include <gp_Trsf.hxx>
38 #include <gp_Vec.hxx>
39 #include <gp_XYZ.hxx>
40 #include <PLib.hxx>
41 #include <Precision.hxx>
42 #include <Standard_ConstructionError.hxx>
43 #include <Standard_DimensionError.hxx>
44 #include <Standard_OutOfRange.hxx>
45 #include <Standard_RangeError.hxx>
46 #include <Standard_Type.hxx>
47 #include <TColStd_Array1OfInteger.hxx>
48
49 IMPLEMENT_STANDARD_RTTIEXT(Geom_BezierSurface,Geom_BoundedSurface)
50
51 //=======================================================================
52 //function : Rational
53 //purpose  : check rationality of an array of weights
54 //=======================================================================
55 static void Rational(const TColStd_Array2OfReal& Weights,
56                      Standard_Boolean& Urational,
57                      Standard_Boolean& Vrational)
58 {
59   Standard_Integer I,J;
60   J = Weights.LowerCol ();
61   Vrational = Standard_False;
62   while (!Vrational && J <= Weights.UpperCol()) {
63     I = Weights.LowerRow();
64     while (!Vrational && I <= Weights.UpperRow() - 1) {
65       Vrational = (Abs(Weights (I, J) - Weights (I+1, J)) 
66                    > Epsilon (Abs(Weights (I, J))));
67       I++;
68     }
69     J++;
70   }
71
72   I = Weights.LowerRow ();
73   Urational = Standard_False;
74   while (!Urational && I <= Weights.UpperRow()) {
75     J = Weights.LowerCol();
76     while (!Urational && J <= Weights.UpperCol() - 1) {
77       Urational = (Abs(Weights (I, J) - Weights (I, J+1))
78                    > Epsilon (Abs(Weights (I, J))));
79       J++;
80     }
81     I++;
82   }
83 }
84
85 //=======================================================================
86 //function : AddPoleCol
87 //purpose  : Internal use only.
88 //=======================================================================
89
90 static void AddPoleCol
91   (const TColgp_Array2OfPnt& Poles,
92    const TColgp_Array1OfPnt& PoleCol,
93    const Standard_Integer    AfterIndex,
94          TColgp_Array2OfPnt& NewPoles)
95 {
96   Standard_Integer InsertIndex = AfterIndex + NewPoles.LowerCol();
97   Standard_Integer Offset = NewPoles.LowerRow() - PoleCol.Lower();
98   Standard_Integer ColIndex = NewPoles.LowerCol();
99   Standard_Integer RowIndex;
100   while (ColIndex < InsertIndex) {
101     RowIndex = NewPoles.LowerRow();
102     while (RowIndex <= NewPoles.UpperRow()){
103       NewPoles (RowIndex, ColIndex) =  Poles (RowIndex, ColIndex);
104       RowIndex++;
105     }
106     ColIndex++;
107   }
108   RowIndex = NewPoles.LowerRow();
109   while (RowIndex <= NewPoles.UpperRow()){
110     NewPoles (RowIndex, ColIndex) = PoleCol (RowIndex - Offset);
111     RowIndex++;
112   }
113   ColIndex++;
114   while (ColIndex <= NewPoles.UpperCol()) {
115     RowIndex = NewPoles.LowerRow();
116     while (RowIndex <= NewPoles.UpperRow()){
117       NewPoles (RowIndex, ColIndex) =  Poles (RowIndex, ColIndex - 1);
118       RowIndex++;
119     }
120     ColIndex++;
121   }
122 }
123
124 //=======================================================================
125 //function : AddRatPoleCol
126 //purpose  : Internal use only.
127 //=======================================================================
128
129 static void AddRatPoleCol
130   (const TColgp_Array2OfPnt&   Poles,
131    const TColStd_Array2OfReal& Weights,
132    const TColgp_Array1OfPnt&   PoleCol,
133    const TColStd_Array1OfReal& PoleWeightCol,
134    const Standard_Integer      AfterIndex,
135          TColgp_Array2OfPnt&   NewPoles,
136          TColStd_Array2OfReal& NewWeights)
137 {
138   Standard_Integer InsertIndex = AfterIndex + NewPoles.LowerCol();
139   Standard_Integer OffsetPol   = NewPoles.LowerRow() - PoleCol.Lower();
140   Standard_Integer OffsetW     = NewWeights.LowerRow() - PoleWeightCol.Lower();
141   
142   Standard_Integer ColIndex = NewPoles.LowerCol();
143   Standard_Integer RowIndex;
144   while (ColIndex < InsertIndex) {
145     RowIndex = NewPoles.LowerRow();
146     while (RowIndex <= NewPoles.UpperRow()){
147       NewPoles (RowIndex, ColIndex) = Poles (RowIndex, ColIndex);
148       NewWeights (RowIndex, ColIndex)  =  Weights (RowIndex, ColIndex);
149       RowIndex++;
150     }
151     ColIndex++;
152   }
153   RowIndex = NewPoles.LowerRow();
154   while (RowIndex <= NewPoles.UpperRow()){
155     NewPoles (RowIndex, ColIndex) = PoleCol (RowIndex - OffsetPol);
156     NewWeights (RowIndex, ColIndex) =  PoleWeightCol (RowIndex - OffsetW);
157     RowIndex++;
158   }
159   ColIndex++;
160   while (ColIndex <= NewPoles.UpperCol()) {
161     RowIndex = NewPoles.LowerRow();
162     while (RowIndex <= NewPoles.UpperRow()){
163       NewPoles (RowIndex, ColIndex) = Poles (RowIndex, ColIndex - 1);
164       RowIndex++;
165       NewWeights (RowIndex, ColIndex)  = Weights (RowIndex, ColIndex - 1);
166     }
167     ColIndex++;
168   }
169 }
170
171 //=======================================================================
172 //function : AddPoleRow
173 //purpose  : Internal use only.
174 //=======================================================================
175
176 static void AddPoleRow
177   (const TColgp_Array2OfPnt& Poles,
178    const TColgp_Array1OfPnt& PoleRow,
179    const Standard_Integer    AfterIndex,
180          TColgp_Array2OfPnt& NewPoles)
181 {
182   Standard_Integer InsertIndex = AfterIndex + NewPoles.LowerRow();
183   Standard_Integer Offset = NewPoles.LowerCol() - PoleRow.Lower();
184   Standard_Integer RowIndex = NewPoles.LowerRow();
185   Standard_Integer ColIndex;
186   while (RowIndex < InsertIndex) {
187     ColIndex = NewPoles.LowerCol();
188     while (ColIndex <= NewPoles.UpperCol()){
189       NewPoles (RowIndex, ColIndex) = Poles (RowIndex, ColIndex);
190       ColIndex++;
191     }
192     RowIndex++;
193   }
194   ColIndex = NewPoles.LowerCol();
195   while (ColIndex <= NewPoles.UpperCol()){
196     NewPoles (RowIndex, ColIndex) = PoleRow (ColIndex - Offset);
197     ColIndex++;
198   }
199   RowIndex++;
200   while (RowIndex <= NewPoles.UpperRow()) {
201     ColIndex = NewPoles.LowerCol();
202     while (ColIndex <= NewPoles.UpperCol()){
203       NewPoles (RowIndex, ColIndex) = Poles (RowIndex - 1, ColIndex);
204       ColIndex++;
205     }
206     RowIndex++;
207   }
208 }
209
210 //=======================================================================
211 //function : AddRatPoleRow
212 //purpose  : 
213 //=======================================================================
214
215 static void AddRatPoleRow
216   (const TColgp_Array2OfPnt&   Poles,
217    const TColStd_Array2OfReal& Weights,
218    const TColgp_Array1OfPnt&   PoleRow,
219    const TColStd_Array1OfReal& PoleWeightRow,
220    const Standard_Integer      AfterIndex,
221          TColgp_Array2OfPnt&   NewPoles,
222          TColStd_Array2OfReal& NewWeights)
223 {
224   Standard_Integer InsertIndex = AfterIndex + NewPoles.LowerRow();
225   Standard_Integer OffsetPol = NewPoles.LowerCol() - PoleRow.Lower();
226   Standard_Integer OffsetW = NewWeights.LowerCol() - PoleWeightRow.Lower();
227   
228   Standard_Integer ColIndex;
229   Standard_Integer RowIndex = NewPoles.LowerRow();
230   while (RowIndex < InsertIndex) {
231     ColIndex = NewPoles.LowerCol();
232     while (ColIndex <= NewPoles.UpperCol()){
233       NewPoles (RowIndex, ColIndex) =  Poles (RowIndex, ColIndex);
234       NewWeights (RowIndex, ColIndex)  =  Weights (RowIndex, ColIndex);
235       ColIndex++;
236     }
237     RowIndex++;
238   }
239   ColIndex = NewPoles.LowerCol();
240   while (ColIndex <= NewPoles.UpperCol()){
241     NewPoles (RowIndex, ColIndex) = PoleRow (ColIndex - OffsetPol);
242     NewWeights (RowIndex, ColIndex) = PoleWeightRow (ColIndex - OffsetW);
243     ColIndex++;
244   }
245   RowIndex++;
246   while (RowIndex <= NewPoles.UpperRow()) {
247     ColIndex = NewPoles.LowerCol();
248     while (ColIndex <= NewPoles.UpperCol()){
249       NewPoles (RowIndex, ColIndex) = Poles (RowIndex - 1, ColIndex);
250       NewWeights (RowIndex, ColIndex)  = Weights (RowIndex - 1, ColIndex);
251       ColIndex++;
252     }
253     RowIndex++;
254   }
255 }
256
257 //=======================================================================
258 //function : DeletePoleCol
259 //purpose  : 
260 //=======================================================================
261
262 static void DeletePoleCol
263   (const TColgp_Array2OfPnt& Poles,
264    const Standard_Integer    Index,
265          TColgp_Array2OfPnt& NewPoles)
266 {
267   Standard_Integer Offset = 0;
268   Standard_Integer RowIndex;
269   Standard_Integer ColIndex = NewPoles.LowerCol();
270   while (ColIndex <= NewPoles.UpperCol()) {
271     RowIndex = NewPoles.LowerRow();
272     if (ColIndex == Index)  Offset = 1;
273     while (RowIndex <= NewPoles.UpperRow()){
274       NewPoles (RowIndex, ColIndex) = Poles (RowIndex, ColIndex + Offset);
275       RowIndex++;
276     }
277     ColIndex++;
278   }
279 }
280
281 //=======================================================================
282 //function : DeleteRatPoleCol
283 //purpose  : 
284 //=======================================================================
285
286 static void DeleteRatPoleCol
287   (const TColgp_Array2OfPnt&   Poles,
288    const TColStd_Array2OfReal& Weights,
289    const Standard_Integer      Index,
290          TColgp_Array2OfPnt&   NewPoles,
291          TColStd_Array2OfReal& NewWeights)
292 {
293   Standard_Integer Offset = 0;
294   Standard_Integer RowIndex;
295   Standard_Integer ColIndex = NewPoles.LowerCol();
296   while (ColIndex <= NewPoles.UpperCol()) {
297     RowIndex = NewPoles.LowerRow();
298     if (ColIndex == Index) Offset = 1;
299     while (RowIndex <= NewPoles.UpperRow()){
300       NewPoles (RowIndex, ColIndex) = Poles (RowIndex, ColIndex + Offset);
301       NewWeights (RowIndex, ColIndex) = Weights (RowIndex, ColIndex+Offset);
302       RowIndex++;
303     }
304     ColIndex++;
305   }
306 }
307
308 //=======================================================================
309 //function : DeletePoleRow
310 //purpose  : 
311 //=======================================================================
312
313 static void DeletePoleRow
314   (const TColgp_Array2OfPnt& Poles,
315    const Standard_Integer    Index,
316          TColgp_Array2OfPnt& NewPoles)
317 {
318   Standard_Integer Offset = 0;
319   Standard_Integer ColIndex;
320   Standard_Integer RowIndex = NewPoles.LowerRow();
321   while (RowIndex <= NewPoles.UpperRow()) {
322     ColIndex = NewPoles.LowerCol();
323     if (RowIndex == Index)  Offset = 1;
324     while (ColIndex <= NewPoles.UpperCol()){
325       NewPoles (RowIndex, ColIndex) = Poles (RowIndex + Offset, ColIndex);
326       ColIndex++;
327     }
328     RowIndex++;
329   }
330 }
331
332 //=======================================================================
333 //function : DeleteRatPoleRow
334 //purpose  : 
335 //=======================================================================
336
337 static void DeleteRatPoleRow
338   (const TColgp_Array2OfPnt&   Poles,
339    const TColStd_Array2OfReal& Weights,
340    const Standard_Integer      Index,
341          TColgp_Array2OfPnt&   NewPoles,
342          TColStd_Array2OfReal& NewWeights)
343 {
344   Standard_Integer Offset = 0;
345   Standard_Integer ColIndex;
346   Standard_Integer RowIndex = NewPoles.LowerRow();
347   while (RowIndex <= NewPoles.UpperRow()) {
348     ColIndex = NewPoles.LowerCol();
349     if (RowIndex == Index)  Offset = 1;
350     while (ColIndex <= NewPoles.UpperCol()){
351       NewPoles (RowIndex, ColIndex) =  Poles (RowIndex +  Offset, ColIndex);
352       NewWeights (RowIndex, ColIndex) = Weights (RowIndex+Offset, ColIndex);
353       ColIndex++;
354     }
355     RowIndex++;
356   }
357 }
358
359 //=======================================================================
360 //function : Geom_BezierSurface
361 //purpose  : 
362 //=======================================================================
363
364 Geom_BezierSurface::Geom_BezierSurface 
365 (const TColgp_Array2OfPnt& SurfacePoles):
366  maxderivinvok(Standard_False)
367 {
368   Standard_Integer NbUPoles = SurfacePoles.ColLength();
369   Standard_Integer NbVPoles = SurfacePoles.RowLength();
370   if (NbUPoles < 2 || NbUPoles > MaxDegree()+1 ||
371       NbVPoles < 2 || NbVPoles > MaxDegree()+1) {
372     throw Standard_ConstructionError();
373   }
374   
375   Handle(TColgp_HArray2OfPnt) npoles = 
376     new TColgp_HArray2OfPnt   (1, NbUPoles, 1, NbVPoles);
377   
378   urational = 0;
379   vrational = 0;
380
381   npoles->ChangeArray2() = SurfacePoles;
382   
383   // Init non rational
384   Init(npoles,
385        Handle(TColStd_HArray2OfReal)());
386 }
387
388 //=======================================================================
389 //function : Geom_BezierSurface
390 //purpose  : 
391 //=======================================================================
392
393 Geom_BezierSurface::Geom_BezierSurface 
394   (const TColgp_Array2OfPnt&   SurfacePoles,
395    const TColStd_Array2OfReal& PoleWeights  ):
396  maxderivinvok(Standard_False)
397 {
398   Standard_Integer NbUPoles = SurfacePoles.ColLength();
399   Standard_Integer NbVPoles = SurfacePoles.RowLength();
400   if (NbUPoles < 2 || NbUPoles > MaxDegree()+1 ||
401       NbVPoles < 2 || NbVPoles > MaxDegree()+1 ||
402       NbVPoles != PoleWeights.RowLength()      ||
403       NbUPoles != PoleWeights.ColLength()      ) {
404     throw Standard_ConstructionError();
405   }
406   
407   Standard_Integer Row = PoleWeights.LowerRow();
408   Standard_Integer Col = PoleWeights.LowerCol();
409   while (Col <= PoleWeights.UpperCol()) {
410     Row = PoleWeights.LowerRow();
411     while (Row <= PoleWeights.UpperRow()) {
412       if (PoleWeights(Row, Col) <= gp::Resolution()) {
413         throw Standard_ConstructionError();
414       }
415       Row++;
416     }
417     Col++;
418   }
419   
420   Handle(TColgp_HArray2OfPnt) 
421     npoles = new TColgp_HArray2OfPnt   (1, NbUPoles, 1, NbVPoles);
422   npoles->ChangeArray2() = SurfacePoles;
423
424   Standard_Integer I, J;
425   urational = Standard_False;
426   vrational = Standard_False;
427   J = PoleWeights.LowerCol ();
428   while (!vrational && J <= PoleWeights.UpperCol()) {
429     I = PoleWeights.LowerRow();
430     while (!vrational && I <= PoleWeights.UpperRow() - 1) {
431       vrational = (Abs(PoleWeights (I, J) - PoleWeights (I+1, J)) 
432                    > Epsilon (Abs(PoleWeights (I, J))));
433       I++;
434     }
435     J++;
436   }
437   I = PoleWeights.LowerRow ();
438   while (!urational && I <= PoleWeights.UpperRow()) {
439     J = PoleWeights.LowerCol();
440     while (!urational && J <= PoleWeights.UpperCol() - 1) {
441       urational = (Abs(PoleWeights (I, J) - PoleWeights (I, J+1))
442                    > Epsilon (Abs(PoleWeights (I, J))));
443       J++;
444     }
445     I++;
446   }
447
448
449   Handle(TColStd_HArray2OfReal) nweights; 
450   if (urational || vrational) {
451     nweights = new TColStd_HArray2OfReal (1, NbUPoles, 1, NbVPoles);
452     nweights->ChangeArray2() = PoleWeights;
453   }
454
455   // Init
456   Init(npoles,nweights);
457 }
458
459 //=======================================================================
460 //function : Geom_BezierSurface
461 //purpose  : 
462 //=======================================================================
463
464 Geom_BezierSurface::Geom_BezierSurface
465   (const Handle(TColgp_HArray2OfPnt)&   SurfacePoles,
466    const Handle(TColStd_HArray2OfReal)& PoleWeights,
467    const Standard_Boolean               IsURational,
468    const Standard_Boolean               IsVRational)
469 :maxderivinvok(Standard_False)
470 {
471   urational = IsURational;
472   vrational = IsVRational;
473   Standard_Integer NbUPoles = SurfacePoles->ColLength();
474   Standard_Integer NbVPoles = SurfacePoles->RowLength();
475
476   poles    = new TColgp_HArray2OfPnt   (1,NbUPoles,
477                                         1,NbVPoles) ;
478   poles->ChangeArray2() = SurfacePoles->Array2();
479
480   if ( urational || vrational) {
481     weights  = new TColStd_HArray2OfReal (1,NbUPoles,1,NbVPoles);
482     weights->ChangeArray2() = PoleWeights->Array2();
483   }
484 }
485
486 //=======================================================================
487 //function : MaxDegree
488 //purpose  : 
489 //=======================================================================
490
491 Standard_Integer Geom_BezierSurface::MaxDegree () 
492
493   return BSplCLib::MaxDegree(); 
494 }
495
496 //=======================================================================
497 //function : ExchangeUV
498 //purpose  : 
499 //=======================================================================
500
501 void Geom_BezierSurface::ExchangeUV ()
502 {
503   Standard_Integer LC = poles->LowerCol();
504   Standard_Integer UC = poles->UpperCol();
505   Standard_Integer LR = poles->LowerRow();
506   Standard_Integer UR = poles->UpperRow();
507
508   Handle(TColgp_HArray2OfPnt) npoles = new TColgp_HArray2OfPnt (LC, UC, LR, UR);
509   Handle(TColStd_HArray2OfReal) nweights;
510   if (!weights.IsNull())
511   {
512     nweights = new TColStd_HArray2OfReal (LC, UC, LR, UR);
513   }
514
515   const TColgp_Array2OfPnt& spoles = poles->Array2();
516   const TColStd_Array2OfReal* sweights = !weights.IsNull() ? &weights->Array2() : NULL;
517
518   TColgp_Array2OfPnt& snpoles = npoles->ChangeArray2();
519   TColStd_Array2OfReal* snweights = !nweights.IsNull() ? &nweights->ChangeArray2() : NULL;
520   for (Standard_Integer i = LC; i <= UC; i++)
521   {
522     for (Standard_Integer j = LR; j <= UR; j++)
523     {
524       snpoles (i, j) = spoles (j, i);
525       if (snweights != NULL)
526       {
527         snweights->ChangeValue (i, j) = sweights->Value (j, i);
528       }
529     }
530   }
531   poles   = npoles;
532   weights = nweights;
533
534   std::swap (urational, vrational);
535 }
536
537 //=======================================================================
538 //function : Increase
539 //purpose  : 
540 //=======================================================================
541
542 void Geom_BezierSurface::Increase (const Standard_Integer UDeg,
543                                    const Standard_Integer VDeg)
544 {
545   if (UDeg < UDegree() || UDeg > Geom_BezierSurface::MaxDegree() ||
546       VDeg < VDegree() || VDeg > Geom_BezierSurface::MaxDegree() )  {
547     throw Standard_ConstructionError();
548   }
549
550   Standard_Integer oldUDeg = UDegree();
551   Standard_Integer oldVDeg = VDegree();
552   Standard_Integer IncUDeg = UDeg - oldUDeg;
553   Standard_Integer IncVDeg = VDeg - oldVDeg;
554   if (IncUDeg == 0 && IncVDeg == 0) return;
555   
556   TColStd_Array1OfReal biduknots(1,2); biduknots(1) = 0.; biduknots(2) = 1.;
557   TColStd_Array1OfInteger bidumults(1,2); bidumults.Init(UDegree() + 1);
558   TColStd_Array1OfReal bidvknots(1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
559   TColStd_Array1OfInteger bidvmults(1,2); bidvmults.Init(VDegree() + 1);
560   Handle(TColgp_HArray2OfPnt) npoles;
561   Handle(TColStd_HArray2OfReal) nweights;
562
563   if(IncUDeg > 0){
564     npoles = new TColgp_HArray2OfPnt( 1, UDeg + 1, 1, oldVDeg + 1);
565     
566     if ( urational || vrational) {
567       nweights = new TColStd_HArray2OfReal( 1, UDeg + 1, 1, VDegree() + 1);
568       
569       BSplSLib::IncreaseDegree(1, oldUDeg, UDeg, 0,
570                                poles->Array2(),
571                                &weights->Array2(),
572                                biduknots, bidumults,
573                                npoles->ChangeArray2(), 
574                                &nweights->ChangeArray2(),
575                                biduknots, bidumults);
576       weights = nweights;
577     }
578     else {
579       BSplSLib::IncreaseDegree(1, oldUDeg, UDeg, 0,
580                                poles->Array2(),
581                                BSplSLib::NoWeights(),
582                                biduknots, bidumults,
583                                npoles->ChangeArray2(), 
584                                BSplSLib::NoWeights(),
585                                biduknots, bidumults);
586     }
587     poles   = npoles;
588   }
589   if(IncVDeg > 0){
590     npoles = new TColgp_HArray2OfPnt( 1, UDeg + 1, 1, VDeg + 1);
591     
592     if ( urational || vrational) {
593       nweights = new TColStd_HArray2OfReal( 1, UDeg + 1, 1, VDeg + 1);
594       
595       BSplSLib::IncreaseDegree(0, oldVDeg, VDeg, 0,
596                                poles->Array2(),
597                                &weights->Array2(),
598                                bidvknots, bidvmults,
599                                npoles->ChangeArray2(), 
600                                &nweights->ChangeArray2(),
601                                bidvknots, bidvmults);
602       weights = nweights;
603     }
604     else {
605       BSplSLib::IncreaseDegree(0, oldVDeg, VDeg, 0,
606                                poles->Array2(),
607                                BSplSLib::NoWeights(),
608                                bidvknots, bidvmults,
609                                npoles->ChangeArray2(), 
610                                BSplSLib::NoWeights(),
611                                bidvknots, bidvmults);
612       
613     }
614     poles   = npoles;
615   }
616   Init(npoles,nweights);
617 }
618
619 //=======================================================================
620 //function : InsertPoleColAfter
621 //purpose  : 
622 //=======================================================================
623
624 void Geom_BezierSurface::InsertPoleColAfter 
625   (const Standard_Integer    VIndex,
626    const TColgp_Array1OfPnt& CPoles)
627 {
628   const TColgp_Array2OfPnt & Poles = poles->Array2();
629   if (VIndex < 1 || VIndex > Poles.RowLength())  throw Standard_OutOfRange();
630   if (CPoles.Length() != Poles.ColLength()) {
631     throw Standard_ConstructionError();
632   }
633
634   Handle(TColgp_HArray2OfPnt) npoles =
635     new TColgp_HArray2OfPnt(1,poles->ColLength(),1,poles->RowLength()+1);
636
637   Handle(TColStd_HArray2OfReal) nweights;
638
639   if (urational || vrational) {
640     nweights = 
641       new TColStd_HArray2OfReal(1,poles->ColLength(),1,poles->RowLength()+1);
642
643     TColStd_Array1OfReal CWeights(nweights->LowerRow(),nweights->UpperRow());
644     CWeights.Init(1.);
645
646     AddRatPoleCol (poles->Array2(), weights->Array2(),
647                    CPoles, CWeights, VIndex,
648                    npoles->ChangeArray2(), nweights->ChangeArray2());
649   }
650   else {
651     AddPoleCol (poles->Array2(), 
652                 CPoles, VIndex,
653                 npoles->ChangeArray2());
654   }
655   poles   = npoles;
656   weights = nweights;
657 }
658
659 //=======================================================================
660 //function : InsertPoleColAfter
661 //purpose  : 
662 //=======================================================================
663
664 void Geom_BezierSurface::InsertPoleColAfter
665   (const Standard_Integer      VIndex,
666    const TColgp_Array1OfPnt&   CPoles,
667    const TColStd_Array1OfReal& CPoleWeights)
668 {
669   const TColgp_Array2OfPnt & Poles = poles->Array2();
670   if (VIndex < 1 || VIndex > Poles.RowLength())  throw Standard_OutOfRange();
671   if (CPoles.Length() != Poles.ColLength() ||
672       CPoleWeights.Length() != CPoles.Length()) {
673     throw Standard_ConstructionError();
674     }
675   Standard_Integer Index = CPoleWeights.Lower();
676   while (Index <= CPoleWeights.Upper()) {
677     if (CPoleWeights (Index) <= gp::Resolution()) {
678       throw Standard_ConstructionError();
679       }
680     Index++;
681   }
682
683   Handle(TColgp_HArray2OfPnt) npoles =
684     new TColgp_HArray2OfPnt(1,poles->ColLength(),1,poles->RowLength()+1);
685   
686   Handle(TColStd_HArray2OfReal) nweights = 
687     new TColStd_HArray2OfReal(1,poles->ColLength(),1,poles->RowLength()+1);
688   
689   AddRatPoleCol (poles->Array2(), weights->Array2(),
690                  CPoles, CPoleWeights, VIndex,
691                  npoles->ChangeArray2(), nweights->ChangeArray2());
692
693   poles   = npoles;
694   weights = nweights;
695
696   Rational(weights->Array2(), urational, vrational);
697 }
698
699 //=======================================================================
700 //function : InsertPoleColBefore
701 //purpose  : 
702 //=======================================================================
703
704 void Geom_BezierSurface::InsertPoleColBefore (const Standard_Integer VIndex,
705                                               const TColgp_Array1OfPnt& CPoles)
706 {
707   InsertPoleColAfter(VIndex - 1, CPoles);
708 }
709
710 //=======================================================================
711 //function : InsertPoleColBefore
712 //purpose  : 
713 //=======================================================================
714
715 void Geom_BezierSurface::InsertPoleColBefore
716   (const Standard_Integer      VIndex,
717    const TColgp_Array1OfPnt&   CPoles,
718    const TColStd_Array1OfReal& CPoleWeights)
719 {
720   InsertPoleColAfter( VIndex - 1, CPoles, CPoleWeights);
721 }
722
723 //=======================================================================
724 //function : InsertPoleRowAfter
725 //purpose  : 
726 //=======================================================================
727
728 void Geom_BezierSurface::InsertPoleRowAfter (const Standard_Integer UIndex,
729                                              const TColgp_Array1OfPnt& CPoles)
730 {
731   const TColgp_Array2OfPnt & Poles = poles->Array2();
732   if (UIndex < 1 || UIndex > Poles.ColLength())  throw Standard_OutOfRange();
733   if (CPoles.Length() != Poles.RowLength()) {
734     throw Standard_ConstructionError();
735   }
736
737   Handle(TColgp_HArray2OfPnt) npoles =
738     new TColgp_HArray2OfPnt(1,poles->ColLength()+1,1,poles->RowLength());
739
740   Handle(TColStd_HArray2OfReal) nweights;
741
742   if (urational || vrational)
743   {
744     nweights = new TColStd_HArray2OfReal(1,poles->ColLength()+1,1,poles->RowLength());
745
746     TColStd_Array1OfReal CWeights (nweights->LowerCol(), nweights->UpperCol());
747     CWeights.Init (1.0);
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())  throw Standard_OutOfRange();
774   if (CPoles.Length() != Poles.RowLength() ||
775       CPoleWeights.Length() != CPoles.Length()) {
776     throw Standard_ConstructionError();
777   }
778   Standard_Integer Index = CPoleWeights.Lower();
779   while (Index <= CPoleWeights.Upper()) {
780     if (CPoleWeights(Index) <= gp::Resolution()) {
781       throw Standard_ConstructionError();
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())  throw Standard_OutOfRange();
835   if (Poles.RowLength() <= 2)             throw Standard_ConstructionError();
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()) throw Standard_OutOfRange();
870   if (Poles.ColLength() <= 2)            throw Standard_ConstructionError();
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() )    throw Standard_OutOfRange();
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     throw Standard_ConstructionError("Geom_BezierSurface::SetPole");
1022   if (UIndex < 1                 || 
1023       UIndex > poles->ColLength() ||
1024       VIndex < 1                 ||
1025       VIndex > poles->RowLength())    
1026     throw Standard_OutOfRange("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()) throw Standard_OutOfRange();
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     throw Standard_ConstructionError();
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())  throw Standard_OutOfRange();
1072
1073   if (CPoles.Lower() < 1                 || 
1074       CPoles.Lower() > Poles.ColLength() || 
1075       CPoles.Upper() < 1                 ||
1076       CPoles.Upper() > Poles.ColLength()) {
1077     throw Standard_ConstructionError();
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())  throw Standard_OutOfRange();
1094
1095   if (CPoles.Lower() < 1                 ||
1096       CPoles.Lower() > Poles.RowLength() || 
1097       CPoles.Upper() < 1                 || 
1098       CPoles.Upper() > Poles.RowLength())  throw Standard_ConstructionError();
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())   throw Standard_OutOfRange();
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     throw Standard_ConstructionError();
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     throw Standard_ConstructionError("Geom_BezierSurface::SetWeight");
1160
1161   if (UIndex < 1                   || 
1162       UIndex > Weights.ColLength() ||
1163       VIndex < 1                   || 
1164       VIndex > Weights.RowLength())    throw Standard_OutOfRange();
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()) throw Standard_OutOfRange();
1196
1197   if (CPoleWeights.Length() !=  Weights.ColLength())  {
1198     throw Standard_ConstructionError("Geom_BezierSurface::SetWeightCol");
1199   }
1200
1201   I = CPoleWeights.Lower();
1202   while (I <= CPoleWeights.Upper()) {
1203     if (CPoleWeights(I) <= gp::Resolution()) {
1204       throw Standard_ConstructionError();
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     throw Standard_OutOfRange("Geom_BezierSurface::SetWeightRow");
1238   if (CPoleWeights.Lower() < 1 ||
1239       CPoleWeights.Lower() > Weights.RowLength() ||
1240       CPoleWeights.Upper() < 1 ||
1241       CPoleWeights.Upper() > Weights.RowLength()  ) {
1242     throw Standard_ConstructionError("Geom_BezierSurface::SetWeightRow");
1243   }
1244
1245   I = CPoleWeights.Lower();
1246   while (I <= CPoleWeights.Upper()) {
1247     if (CPoleWeights(I) <= gp::Resolution())  {
1248       throw Standard_ConstructionError();
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] = { 0.0, 1.0 };
1389   Standard_Real array_v[2] = { 0.0, 1.0 };
1390   Standard_Integer mult_u[2] = { UDegree() + 1, UDegree() + 1 };
1391   Standard_Integer mult_v[2] = { VDegree() + 1, VDegree() + 1 };
1392   TColStd_Array1OfReal biduknots(array_u[0], 1, 2);
1393   TColStd_Array1OfInteger bidumults(mult_u[0], 1, 2);
1394   TColStd_Array1OfReal bidvknots(array_v[0], 1, 2);
1395   TColStd_Array1OfInteger bidvmults(mult_v[0], 1, 2);
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] = { 0.0, 1.0 };
1428   Standard_Real array_v[2] = { 0.0, 1.0 };
1429   Standard_Integer mult_u[2] = { UDegree() + 1, UDegree() + 1 };
1430   Standard_Integer mult_v[2] = { VDegree() + 1, VDegree() + 1 };
1431   TColStd_Array1OfReal biduknots(array_u[0], 1, 2);
1432   TColStd_Array1OfInteger bidumults(mult_u[0], 1, 2);
1433   TColStd_Array1OfReal bidvknots(array_v[0], 1, 2);
1434   TColStd_Array1OfInteger bidvmults(mult_v[0], 1, 2);
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] = { 0.0, 1.0 };
1466   Standard_Real array_v[2] = { 0.0, 1.0 };
1467   Standard_Integer mult_u[2] = { UDegree() + 1, UDegree() + 1 };
1468   Standard_Integer mult_v[2] = { VDegree() + 1, VDegree() + 1 };
1469   TColStd_Array1OfReal biduknots(array_u[0], 1, 2);
1470   TColStd_Array1OfInteger bidumults(mult_u[0], 1, 2);
1471   TColStd_Array1OfReal bidvknots(array_v[0], 1, 2);
1472   TColStd_Array1OfInteger bidvmults(mult_v[0], 1, 2);
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 const 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
1940 //=======================================================================
1941 //function : DumpJson
1942 //purpose  : 
1943 //=======================================================================
1944 void Geom_BezierSurface::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
1945 {
1946   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
1947
1948   OCCT_DUMP_BASE_CLASS (theOStream, theDepth, Geom_BoundedSurface)
1949
1950   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, urational)
1951   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, vrational)
1952   if (!poles.IsNull())
1953     OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, poles->Size())
1954   if (!weights.IsNull())
1955     OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, weights->Size())
1956   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, umaxderivinv)
1957   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, vmaxderivinv)
1958   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, maxderivinvok)
1959 }