f538442cf17c9d89a536fb91a47df3e607edaa8d
[occt.git] / src / Geom / Geom_BSplineSurface.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 // 14-Mar-96 : xab  portage hp
18 // pmn : 28-Jun-96 Distinction entre la continuite en U et V (bug PRO4625)
19 // pmn : 07-Jan-97 Centralisation des verif rational (PRO6834)
20 //       et ajout des InvalideCache() dans les SetWeight*(PRO6833)
21 // RBD : 15-10-98 ; Le cache est maintenant calcule sur [-1,1] (pro15537).
22 // jct : 19-01-99 ; permutation de urational et vrational dans Rational.
23 #define No_Standard_OutOfRange
24
25
26 #include <BSplCLib.hxx>
27 #include <BSplSLib.hxx>
28 #include <Geom_BSplineSurface.hxx>
29 #include <Geom_Curve.hxx>
30 #include <Geom_Geometry.hxx>
31 #include <Geom_UndefinedDerivative.hxx>
32 #include <gp.hxx>
33 #include <gp_Pnt.hxx>
34 #include <gp_Trsf.hxx>
35 #include <gp_Vec.hxx>
36 #include <Precision.hxx>
37 #include <Standard_ConstructionError.hxx>
38 #include <Standard_DimensionError.hxx>
39 #include <Standard_DomainError.hxx>
40 #include <Standard_NoSuchObject.hxx>
41 #include <Standard_NotImplemented.hxx>
42 #include <Standard_OutOfRange.hxx>
43 #include <Standard_RangeError.hxx>
44 #include <Standard_Type.hxx>
45
46 IMPLEMENT_STANDARD_RTTIEXT(Geom_BSplineSurface,Geom_BoundedSurface)
47
48 //=======================================================================
49 //function : CheckSurfaceData
50 //purpose  : Internal use only.
51 //=======================================================================
52 static void CheckSurfaceData
53 (const TColgp_Array2OfPnt&      SPoles,
54  const TColStd_Array1OfReal&    SUKnots,
55  const TColStd_Array1OfReal&    SVKnots,
56  const TColStd_Array1OfInteger& SUMults,
57  const TColStd_Array1OfInteger& SVMults,
58  const Standard_Integer         UDegree,
59  const Standard_Integer         VDegree,
60  const Standard_Boolean         UPeriodic,
61  const Standard_Boolean         VPeriodic)
62 {
63   if (UDegree < 1 || UDegree > Geom_BSplineSurface::MaxDegree () || 
64       VDegree < 1 || VDegree > Geom_BSplineSurface::MaxDegree ()) {
65     throw Standard_ConstructionError("Geom_BSplineSurface");
66   }
67   if (SPoles.ColLength () < 2 || SPoles.RowLength () < 2) {
68     throw Standard_ConstructionError("Geom_BSplineSurface");
69   }
70
71   if (SUKnots.Length() != SUMults.Length() ||
72       SVKnots.Length() != SVMults.Length()) {
73     throw Standard_ConstructionError("Geom_BSplineSurface");
74   }
75
76   Standard_Integer i;
77   for (i = SUKnots.Lower(); i < SUKnots.Upper(); i++) {
78     if (SUKnots(i+1) - SUKnots(i) <= Epsilon(Abs(SUKnots(i)))) {
79       throw Standard_ConstructionError("Geom_BSplineSurface");
80     }
81   }
82
83   for (i = SVKnots.Lower(); i < SVKnots.Upper(); i++) {
84     if (SVKnots(i+1) - SVKnots(i) <= Epsilon(Abs(SVKnots(i)))) {
85       throw Standard_ConstructionError("Geom_BSplineSurface");
86     }
87   }
88   
89   if (SPoles.ColLength() != BSplCLib::NbPoles(UDegree,UPeriodic,SUMults))
90     throw Standard_ConstructionError("Geom_BSplineSurface");
91
92   if (SPoles.RowLength() != BSplCLib::NbPoles(VDegree,VPeriodic,SVMults))
93     throw Standard_ConstructionError("Geom_BSplineSurface");
94 }
95
96 //=======================================================================
97 //function : Rational
98 //purpose  : Internal use only.
99 //=======================================================================
100
101 static void Rational(const TColStd_Array2OfReal& Weights,
102                      Standard_Boolean& Urational,
103                      Standard_Boolean& Vrational)
104 {
105   Standard_Integer I,J;
106   J = Weights.LowerCol ();
107   Vrational = Standard_False;
108   while (!Vrational && J <= Weights.UpperCol()) {
109     I = Weights.LowerRow();
110     while (!Vrational && I <= Weights.UpperRow() - 1) {
111       Vrational = (Abs(Weights (I, J) - Weights (I+1, J)) 
112                    > Epsilon (Abs(Weights (I, J))));
113       I++;
114     }
115     J++;
116   }
117
118   I = Weights.LowerRow ();
119   Urational = Standard_False;
120   while (!Urational && I <= Weights.UpperRow()) {
121     J = Weights.LowerCol();
122     while (!Urational && J <= Weights.UpperCol() - 1) {
123       Urational = (Abs(Weights (I, J) - Weights (I, J+1))
124                    > Epsilon (Abs(Weights (I, J))));
125       J++;
126     }
127     I++;
128   }
129 }
130
131 //=======================================================================
132 //function : Copy
133 //purpose  : 
134 //=======================================================================
135
136 Handle(Geom_Geometry) Geom_BSplineSurface::Copy () const
137 {
138   Handle(Geom_BSplineSurface) S;
139   if (urational || vrational) 
140     S = new Geom_BSplineSurface (poles->Array2() , weights->Array2(), 
141                                  uknots->Array1(), vknots->Array1(), 
142                                  umults->Array1(), vmults->Array1(), 
143                                  udeg     , vdeg, 
144                                  uperiodic, vperiodic);
145   else
146     S = new Geom_BSplineSurface (poles->Array2(),
147                                  uknots->Array1(), vknots->Array1(), 
148                                  umults->Array1(), vmults->Array1(), 
149                                  udeg     , vdeg, 
150                                  uperiodic, vperiodic);
151   return S;
152 }
153
154 //=======================================================================
155 //function : Geom_BSplineSurface
156 //purpose  : 
157 //=======================================================================
158
159 Geom_BSplineSurface::Geom_BSplineSurface
160 (const TColgp_Array2OfPnt&      Poles, 
161  const TColStd_Array1OfReal&    UKnots, 
162  const TColStd_Array1OfReal&    VKnots,
163  const TColStd_Array1OfInteger& UMults, 
164  const TColStd_Array1OfInteger& VMults,
165  const Standard_Integer         UDegree, 
166  const Standard_Integer         VDegree,
167  const Standard_Boolean         UPeriodic,
168  const Standard_Boolean         VPeriodic
169  ) :
170  urational(Standard_False),
171  vrational(Standard_False),
172  uperiodic(UPeriodic),
173  vperiodic(VPeriodic),
174  udeg(UDegree),
175  vdeg(VDegree),
176  maxderivinvok(0)
177
178 {
179
180   // check
181   
182   CheckSurfaceData(Poles,
183                    UKnots   , VKnots,
184                    UMults   , VMults,
185                    UDegree  , VDegree,
186                    UPeriodic, VPeriodic);
187
188   // copy arrays
189
190   poles   = new TColgp_HArray2OfPnt(1,Poles.ColLength(),
191                                     1,Poles.RowLength());
192   poles->ChangeArray2() = Poles;
193
194   weights = new TColStd_HArray2OfReal (1,Poles.ColLength(),
195                                        1,Poles.RowLength(), 1.0);
196
197   uknots  = new TColStd_HArray1OfReal    (1,UKnots.Length());
198   uknots->ChangeArray1() = UKnots;
199
200   umults  = new TColStd_HArray1OfInteger (1,UMults.Length());
201   umults->ChangeArray1() = UMults;
202
203   vknots  = new TColStd_HArray1OfReal    (1,VKnots.Length());
204   vknots->ChangeArray1() = VKnots;
205
206   vmults  = new TColStd_HArray1OfInteger (1,VMults.Length());
207   vmults->ChangeArray1() = VMults;
208
209   UpdateUKnots();
210   UpdateVKnots();
211 }
212
213 //=======================================================================
214 //function : Geom_BSplineSurface
215 //purpose  : 
216 //=======================================================================
217
218 Geom_BSplineSurface::Geom_BSplineSurface
219 (const TColgp_Array2OfPnt&      Poles,
220  const TColStd_Array2OfReal&    Weights,
221  const TColStd_Array1OfReal&    UKnots,
222  const TColStd_Array1OfReal&    VKnots,
223  const TColStd_Array1OfInteger& UMults, 
224  const TColStd_Array1OfInteger& VMults,
225  const Standard_Integer         UDegree,
226  const Standard_Integer         VDegree,
227  const Standard_Boolean         UPeriodic,
228  const Standard_Boolean         VPeriodic) :
229  urational(Standard_False),
230  vrational(Standard_False),
231  uperiodic(UPeriodic),
232  vperiodic(VPeriodic),
233  udeg(UDegree),
234  vdeg(VDegree),
235  maxderivinvok(0)
236 {
237   // check weights
238
239   if (Weights.ColLength() != Poles.ColLength())
240     throw Standard_ConstructionError("Geom_BSplineSurface");
241
242   if (Weights.RowLength() != Poles.RowLength())
243     throw Standard_ConstructionError("Geom_BSplineSurface");
244
245   Standard_Integer i,j;
246   for (i = Weights.LowerRow(); i <= Weights.UpperRow(); i++) {
247     for (j = Weights.LowerCol(); j <= Weights.UpperCol(); j++) {
248       if (Weights(i,j) <= gp::Resolution())  
249         throw Standard_ConstructionError("Geom_BSplineSurface");
250     }
251   }
252   
253   // check really rational
254   
255   Rational(Weights, urational, vrational);
256
257   // check
258   
259   CheckSurfaceData(Poles,
260                    UKnots   , VKnots,
261                    UMults   , VMults,
262                    UDegree  , VDegree,
263                    UPeriodic, VPeriodic);
264
265   // copy arrays
266
267   poles   = new TColgp_HArray2OfPnt(1,Poles.ColLength(),
268                                     1,Poles.RowLength());
269   poles->ChangeArray2() = Poles;
270
271   weights = new TColStd_HArray2OfReal (1,Poles.ColLength(),
272                                        1,Poles.RowLength());
273   weights->ChangeArray2() = Weights;
274
275   uknots  = new TColStd_HArray1OfReal    (1,UKnots.Length());
276   uknots->ChangeArray1() = UKnots;
277
278   umults  = new TColStd_HArray1OfInteger (1,UMults.Length());
279   umults->ChangeArray1() = UMults;
280
281   vknots  = new TColStd_HArray1OfReal    (1,VKnots.Length());
282   vknots->ChangeArray1() = VKnots;
283
284   vmults  = new TColStd_HArray1OfInteger (1,VMults.Length());
285   vmults->ChangeArray1() = VMults;
286
287   UpdateUKnots();
288   UpdateVKnots();
289 }
290
291 //=======================================================================
292 //function : ExchangeUV
293 //purpose  : 
294 //=======================================================================
295
296 void Geom_BSplineSurface::ExchangeUV ()
297 {
298   Standard_Integer LC = poles->LowerCol();
299   Standard_Integer UC = poles->UpperCol();
300   Standard_Integer LR = poles->LowerRow();
301   Standard_Integer UR = poles->UpperRow();
302
303   Handle(TColgp_HArray2OfPnt)   npoles   = 
304     new TColgp_HArray2OfPnt  (LC, UC, LR, UR);
305   Handle(TColStd_HArray2OfReal) nweights = 
306     new TColStd_HArray2OfReal (LC, UC, LR, UR);
307
308   const TColgp_Array2OfPnt   & spoles   = poles->Array2();
309   const TColStd_Array2OfReal & sweights = weights->Array2();
310   
311   TColgp_Array2OfPnt&   snpoles   = npoles->ChangeArray2();
312   TColStd_Array2OfReal& snweights = nweights->ChangeArray2();
313   
314   Standard_Integer i, j;
315   for (i = LC; i <= UC; i++) {
316     for (j = LR; j <= UR; j++) {
317       snpoles   (i,j) = spoles   (j,i);
318       snweights (i,j) = sweights (j,i);
319     }
320   }
321
322   poles   = npoles;
323   weights = nweights;
324
325   Standard_Boolean temp = urational;
326   urational = vrational;
327   vrational = temp;
328
329   temp = uperiodic;
330   uperiodic = vperiodic;
331   vperiodic = temp;
332
333   Standard_Integer tempdeg = udeg;
334   udeg = vdeg;
335   vdeg = tempdeg;
336   
337
338   Handle(TColStd_HArray1OfReal) tempknots = uknots;
339   uknots = vknots;
340   vknots = tempknots;
341
342   Handle(TColStd_HArray1OfInteger) tempmults = umults;
343   umults = vmults;
344   vmults = tempmults;
345
346   UpdateUKnots();
347   UpdateVKnots();
348 }
349
350 //=======================================================================
351 //function : IncreaseDegree
352 //purpose  : 
353 //=======================================================================
354
355 void Geom_BSplineSurface::IncreaseDegree (const Standard_Integer UDegree,
356                                           const Standard_Integer VDegree)
357
358   if (UDegree != udeg) {
359     if ( UDegree < udeg || UDegree > Geom_BSplineSurface::MaxDegree())
360       throw Standard_ConstructionError();
361     
362     Standard_Integer FromK1 = FirstUKnotIndex();
363     Standard_Integer ToK2   = LastUKnotIndex();
364
365     Standard_Integer Step   = UDegree - udeg;
366
367     Handle(TColgp_HArray2OfPnt) npoles = new
368       TColgp_HArray2OfPnt( 1, poles->ColLength() + Step * (ToK2 - FromK1),
369                           1, poles->RowLength());
370
371     Standard_Integer nbknots = BSplCLib::IncreaseDegreeCountKnots
372       (udeg,UDegree,uperiodic,umults->Array1());
373
374     Handle(TColStd_HArray1OfReal) nknots = 
375       new TColStd_HArray1OfReal(1,nbknots);
376     
377     Handle(TColStd_HArray1OfInteger) nmults = 
378       new TColStd_HArray1OfInteger(1,nbknots);
379
380     Handle(TColStd_HArray2OfReal) nweights 
381       = new TColStd_HArray2OfReal(1,npoles->ColLength(),
382                                   1,npoles->RowLength(), 1.);
383
384     if (urational || vrational) {
385       
386       BSplSLib::IncreaseDegree
387         (Standard_True, udeg, UDegree, uperiodic,
388          poles->Array2(),&weights->Array2(),
389          uknots->Array1(),umults->Array1(),
390          npoles->ChangeArray2(),&nweights->ChangeArray2(),
391          nknots->ChangeArray1(),nmults->ChangeArray1());
392     }
393     else {
394
395       BSplSLib::IncreaseDegree
396         (Standard_True, udeg, UDegree, uperiodic,
397          poles->Array2(),BSplSLib::NoWeights(),
398          uknots->Array1(),umults->Array1(),
399          npoles->ChangeArray2(),BSplSLib::NoWeights(),
400          nknots->ChangeArray1(),nmults->ChangeArray1());
401     }
402     udeg    = UDegree;
403     poles   = npoles;
404     weights = nweights;
405     uknots  = nknots;
406     umults  = nmults;
407     UpdateUKnots();
408   }
409
410   if (VDegree != vdeg) {
411     if ( VDegree < vdeg || VDegree > Geom_BSplineSurface::MaxDegree())
412       throw Standard_ConstructionError();
413     
414     Standard_Integer FromK1 = FirstVKnotIndex();
415     Standard_Integer ToK2   = LastVKnotIndex();
416
417     Standard_Integer Step   = VDegree - vdeg;
418
419     Handle(TColgp_HArray2OfPnt) npoles = new
420       TColgp_HArray2OfPnt( 1, poles->ColLength(),
421                           1, poles->RowLength() + Step * (ToK2 - FromK1));
422
423     Standard_Integer nbknots = BSplCLib::IncreaseDegreeCountKnots
424       (vdeg,VDegree,vperiodic,vmults->Array1());
425
426     Handle(TColStd_HArray1OfReal) nknots = 
427       new TColStd_HArray1OfReal(1,nbknots);
428     
429     Handle(TColStd_HArray1OfInteger) nmults = 
430       new TColStd_HArray1OfInteger(1,nbknots);
431
432     Handle(TColStd_HArray2OfReal) nweights
433       = new TColStd_HArray2OfReal(1,npoles->ColLength(),
434                                   1,npoles->RowLength(), 1.);
435
436     if (urational || vrational) {
437       
438       BSplSLib::IncreaseDegree
439         (Standard_False, vdeg, VDegree, vperiodic,
440          poles->Array2(),&weights->Array2(),
441          vknots->Array1(),vmults->Array1(),
442          npoles->ChangeArray2(),&nweights->ChangeArray2(),
443          nknots->ChangeArray1(),nmults->ChangeArray1());
444     }
445     else {
446
447       BSplSLib::IncreaseDegree
448         (Standard_False, vdeg, VDegree, vperiodic,
449          poles->Array2(),BSplSLib::NoWeights(),
450          vknots->Array1(),vmults->Array1(),
451          npoles->ChangeArray2(),BSplSLib::NoWeights(),
452          nknots->ChangeArray1(),nmults->ChangeArray1());
453     }
454     vdeg    = VDegree;
455     poles   = npoles;
456     weights = nweights;
457     vknots  = nknots;
458     vmults  = nmults;
459     UpdateVKnots();
460   }
461 }
462
463 //=======================================================================
464 //function : IncreaseUMultiplicity
465 //purpose  : 
466 //=======================================================================
467
468 void Geom_BSplineSurface::IncreaseUMultiplicity
469 (const Standard_Integer UIndex, 
470  const Standard_Integer M)
471 {
472   TColStd_Array1OfReal k(1,1);
473   k(1) = uknots->Value(UIndex);
474   TColStd_Array1OfInteger m(1,1);
475   m(1) = M - umults->Value(UIndex);
476   InsertUKnots(k,m,Epsilon(1.),Standard_True);
477 }
478
479 //=======================================================================
480 //function : IncreaseUMultiplicity
481 //purpose  : 
482 //=======================================================================
483
484 void Geom_BSplineSurface::IncreaseUMultiplicity
485 (const Standard_Integer FromI1, 
486  const Standard_Integer ToI2,
487  const Standard_Integer M)
488 {
489   Handle(TColStd_HArray1OfReal) tk = uknots;
490   TColStd_Array1OfReal k((uknots->Array1())(FromI1),FromI1,ToI2);
491   TColStd_Array1OfInteger m(FromI1, ToI2);
492   for (Standard_Integer i = FromI1; i <= ToI2; i++) 
493     m(i) = M - umults->Value(i);
494   InsertUKnots(k,m,Epsilon(1.),Standard_True);
495 }
496
497 //=======================================================================
498 //function : IncreaseVMultiplicity
499 //purpose  : 
500 //=======================================================================
501
502 void Geom_BSplineSurface::IncreaseVMultiplicity
503 (const Standard_Integer VIndex, 
504  const Standard_Integer M)
505 {
506   TColStd_Array1OfReal k(1,1);
507   k(1) = vknots->Value(VIndex);
508   TColStd_Array1OfInteger m(1,1);
509   m(1) = M - vmults->Value(VIndex);
510   InsertVKnots(k,m,Epsilon(1.),Standard_True);
511 }
512
513 //=======================================================================
514 //function : IncreaseVMultiplicity
515 //purpose  : 
516 //=======================================================================
517
518 void Geom_BSplineSurface::IncreaseVMultiplicity
519 (const Standard_Integer FromI1,
520  const Standard_Integer ToI2,
521  const Standard_Integer M)
522 {
523   Handle(TColStd_HArray1OfReal) tk = vknots;
524   TColStd_Array1OfReal k((vknots->Array1())(FromI1),FromI1,ToI2);
525   TColStd_Array1OfInteger m(FromI1,ToI2);
526   for (Standard_Integer i = FromI1; i <= ToI2; i++)
527     m(i) = M - vmults->Value(i);
528   InsertVKnots(k,m,Epsilon(1.),Standard_True);
529 }
530
531 //=======================================================================
532 //function : segment
533 //purpose  : 
534 //=======================================================================
535
536 void Geom_BSplineSurface::segment(const Standard_Real U1,
537                                   const Standard_Real U2,
538                                   const Standard_Real V1,
539                                   const Standard_Real V2,
540                                   const Standard_Real EpsU,
541                                   const Standard_Real EpsV,
542                                   const Standard_Boolean SegmentInU,
543                                   const Standard_Boolean SegmentInV)
544 {
545   Standard_Real deltaU = U2 - U1;
546   if (uperiodic) {
547     Standard_Real aUPeriod = uknots->Last() - uknots->First();
548     if (deltaU - aUPeriod > Precision::PConfusion())
549       throw Standard_DomainError("Geom_BSplineSurface::Segment");
550     if (deltaU > aUPeriod)
551       deltaU = aUPeriod;
552   }
553
554   Standard_Real deltaV = V2 - V1;
555   if (vperiodic) {
556     Standard_Real aVPeriod = vknots->Last() - vknots->First();
557     if (deltaV - aVPeriod > Precision::PConfusion())
558       throw Standard_DomainError("Geom_BSplineSurface::Segment");
559     if (deltaV > aVPeriod)
560       deltaV = aVPeriod;
561   }
562
563   Standard_Real NewU1, NewU2, NewV1, NewV2;
564   Standard_Real U, V;
565   Standard_Integer indexU, indexV;
566
567   indexU = 0;
568   BSplCLib::LocateParameter(udeg, uknots->Array1(), umults->Array1(),
569                             U1, uperiodic, uknots->Lower(), uknots->Upper(),
570                             indexU, NewU1);
571   indexU = 0;
572   BSplCLib::LocateParameter(udeg, uknots->Array1(), umults->Array1(),
573                             U2, uperiodic, uknots->Lower(), uknots->Upper(),
574                             indexU, NewU2);
575   if (SegmentInU) {
576     // inserting the UKnots
577     TColStd_Array1OfReal    UKnots(1, 2);
578     TColStd_Array1OfInteger UMults(1, 2);
579     UKnots(1) = Min(NewU1, NewU2);
580     UKnots(2) = Max(NewU1, NewU2);
581     UMults(1) = UMults(2) = udeg;
582
583     InsertUKnots(UKnots, UMults, EpsU);
584   }
585
586   indexV = 0;
587   BSplCLib::LocateParameter(vdeg, vknots->Array1(), vmults->Array1(),
588                             V1, vperiodic, vknots->Lower(), vknots->Upper(),
589                             indexV, NewV1);
590   indexV = 0;
591   BSplCLib::LocateParameter(vdeg, vknots->Array1(), vmults->Array1(),
592                             V2, vperiodic, vknots->Lower(), vknots->Upper(),
593                             indexV, NewV2);
594   if (SegmentInV) {
595     // Inserting the VKnots
596     TColStd_Array1OfReal    VKnots(1, 2);
597     TColStd_Array1OfInteger VMults(1, 2);
598
599     VKnots(1) = Min(NewV1, NewV2);
600     VKnots(2) = Max(NewV1, NewV2);
601     VMults(1) = VMults(2) = vdeg;
602     InsertVKnots(VKnots, VMults, EpsV);
603   }
604
605   if (uperiodic && SegmentInU) { // set the origine at NewU1
606     Standard_Integer index = 0;
607     BSplCLib::LocateParameter(udeg, uknots->Array1(), umults->Array1(),
608       U1, uperiodic, uknots->Lower(), uknots->Upper(),
609       index, U);
610     if (Abs(uknots->Value(index + 1) - U) <= EpsU)
611       index++;
612     SetUOrigin(index);
613     SetUNotPeriodic();
614   }
615
616   // compute index1 and index2 to set the new knots and mults 
617   Standard_Integer index1U = 0, index2U = 0;
618   Standard_Integer FromU1 = uknots->Lower();
619   Standard_Integer ToU2 = uknots->Upper();
620   BSplCLib::LocateParameter(udeg, uknots->Array1(), umults->Array1(),
621                             NewU1, uperiodic, FromU1, ToU2, index1U, U);
622   BSplCLib::LocateParameter(udeg, uknots->Array1(), umults->Array1(),
623                             NewU1 + deltaU, uperiodic, FromU1, ToU2, index2U, U);
624   if (Abs(uknots->Value(index2U + 1) - U) <= EpsU)
625     index2U++;
626
627   Standard_Integer nbuknots = index2U - index1U + 1;
628
629   Handle(TColStd_HArray1OfReal)
630     nuknots = new TColStd_HArray1OfReal(1, nbuknots);
631   Handle(TColStd_HArray1OfInteger)
632     numults = new TColStd_HArray1OfInteger(1, nbuknots);
633
634   Standard_Integer i, k = 1;
635   for (i = index1U; i <= index2U; i++) {
636     nuknots->SetValue(k, uknots->Value(i));
637     numults->SetValue(k, umults->Value(i));
638     k++;
639   }
640   if (SegmentInU) {
641     numults->SetValue(1, udeg + 1);
642     numults->SetValue(nbuknots, udeg + 1);
643   }
644
645   if (vperiodic&& SegmentInV) { // set the origine at NewV1
646     Standard_Integer index = 0;
647     BSplCLib::LocateParameter(vdeg, vknots->Array1(), vmults->Array1(),
648       V1, vperiodic, vknots->Lower(), vknots->Upper(),
649       index, V);
650     if (Abs(vknots->Value(index + 1) - V) <= EpsV)
651       index++;
652     SetVOrigin(index);
653     SetVNotPeriodic();
654   }
655
656   // compute index1 and index2 to set the new knots and mults 
657   Standard_Integer index1V = 0, index2V = 0;
658   Standard_Integer FromV1 = vknots->Lower();
659   Standard_Integer ToV2 = vknots->Upper();
660   BSplCLib::LocateParameter(vdeg, vknots->Array1(), vmults->Array1(),
661                             NewV1, vperiodic, FromV1, ToV2, index1V, V);
662   BSplCLib::LocateParameter(vdeg, vknots->Array1(), vmults->Array1(),
663                             NewV1 + deltaV, vperiodic, FromV1, ToV2, index2V, V);
664   if (Abs(vknots->Value(index2V + 1) - V) <= EpsV)
665     index2V++;
666
667   Standard_Integer nbvknots = index2V - index1V + 1;
668
669   Handle(TColStd_HArray1OfReal)
670     nvknots = new TColStd_HArray1OfReal(1, nbvknots);
671   Handle(TColStd_HArray1OfInteger)
672     nvmults = new TColStd_HArray1OfInteger(1, nbvknots);
673
674   k = 1;
675   for (i = index1V; i <= index2V; i++) {
676     nvknots->SetValue(k, vknots->Value(i));
677     nvmults->SetValue(k, vmults->Value(i));
678     k++;
679   }
680   if (SegmentInV) {
681     nvmults->SetValue(1, vdeg + 1);
682     nvmults->SetValue(nbvknots, vdeg + 1);
683   }
684
685
686   // compute index1 and index2 to set the new poles and weights
687   Standard_Integer pindex1U
688     = BSplCLib::PoleIndex(udeg, index1U, uperiodic, umults->Array1());
689   Standard_Integer pindex2U
690     = BSplCLib::PoleIndex(udeg, index2U, uperiodic, umults->Array1());
691
692   pindex1U++;
693   pindex2U = Min(pindex2U + 1, poles->ColLength());
694
695   Standard_Integer nbupoles = pindex2U - pindex1U + 1;
696
697   // compute index1 and index2 to set the new poles and weights
698   Standard_Integer pindex1V
699     = BSplCLib::PoleIndex(vdeg, index1V, vperiodic, vmults->Array1());
700   Standard_Integer pindex2V
701     = BSplCLib::PoleIndex(vdeg, index2V, vperiodic, vmults->Array1());
702
703   pindex1V++;
704   pindex2V = Min(pindex2V + 1, poles->RowLength());
705
706   Standard_Integer nbvpoles = pindex2V - pindex1V + 1;
707
708
709   Handle(TColStd_HArray2OfReal) nweights;
710
711   Handle(TColgp_HArray2OfPnt)
712     npoles = new TColgp_HArray2OfPnt(1, nbupoles, 1, nbvpoles);
713   k = 1;
714   Standard_Integer j, l;
715   if (urational || vrational) {
716     nweights = new TColStd_HArray2OfReal(1, nbupoles, 1, nbvpoles);
717     for (i = pindex1U; i <= pindex2U; i++) {
718       l = 1;
719       for (j = pindex1V; j <= pindex2V; j++) {
720         npoles->SetValue(k, l, poles->Value(i, j));
721         nweights->SetValue(k, l, weights->Value(i, j));
722         l++;
723       }
724       k++;
725     }
726   }
727   else {
728     for (i = pindex1U; i <= pindex2U; i++) {
729       l = 1;
730       for (j = pindex1V; j <= pindex2V; j++) {
731         npoles->SetValue(k, l, poles->Value(i, j));
732         l++;
733       }
734       k++;
735     }
736   }
737
738   uknots = nuknots;
739   umults = numults;
740   vknots = nvknots;
741   vmults = nvmults;
742   poles = npoles;
743   if (urational || vrational)
744     weights = nweights;
745   else
746     weights = new TColStd_HArray2OfReal(1, poles->ColLength(),
747                                         1, poles->RowLength(), 1.0);
748
749   maxderivinvok = 0;
750   UpdateUKnots();
751   UpdateVKnots();
752 }
753
754 //=======================================================================
755 //function : Segment
756 //purpose  : 
757 //=======================================================================
758
759 void Geom_BSplineSurface::Segment(const Standard_Real U1, 
760                                   const Standard_Real U2,
761                                   const Standard_Real V1,
762                                   const Standard_Real V2,
763                                   const Standard_Real theUTolerance,
764                                   const Standard_Real theVTolerance)
765 {
766   if ((U2 < U1) || (V2 < V1))
767     throw Standard_DomainError("Geom_BSplineSurface::Segment");
768
769   Standard_Real aMaxU = Max(Abs(U2), Abs(U1));
770   Standard_Real EpsU = Max(Epsilon(aMaxU), theUTolerance);
771   
772   Standard_Real aMaxV = Max(Abs(V2), Abs(V1));
773   Standard_Real EpsV = Max(Epsilon(aMaxV), theVTolerance);
774
775   segment(U1, U2, V1, V2, EpsU, EpsV, Standard_True, Standard_True);
776 }
777
778 //=======================================================================
779 //function : CheckAndSegment
780 //purpose  : 
781 //=======================================================================
782
783 void Geom_BSplineSurface::CheckAndSegment(const Standard_Real U1, 
784                                           const Standard_Real U2,
785                                           const Standard_Real V1,
786                                           const Standard_Real V2,
787                                           const Standard_Real theUTolerance,
788                                           const Standard_Real theVTolerance)
789 {
790
791   if ((U2 < U1) || (V2 < V1))
792     throw Standard_DomainError("Geom_BSplineSurface::CheckAndSegment");
793
794   Standard_Real aMaxU = Max(Abs(U2), Abs(U1));
795   Standard_Real EpsU = Max(Epsilon(aMaxU), theUTolerance);
796   
797   Standard_Real aMaxV = Max(Abs(V2), Abs(V1));
798   Standard_Real EpsV = Max(Epsilon(aMaxV), theVTolerance);
799
800   Standard_Boolean segment_in_U = Standard_True;
801   Standard_Boolean segment_in_V = Standard_True;
802   segment_in_U = ( Abs(U1 - uknots->Value(uknots->Lower())) > EpsU )
803                         || ( Abs(U2 - uknots->Value(uknots->Upper())) > EpsU );
804   segment_in_V = ( Abs(V1 - vknots->Value(vknots->Lower())) > EpsV )
805                         || ( Abs(V2 - vknots->Value(vknots->Upper())) > EpsV );
806
807   segment(U1, U2, V1, V2, EpsU, EpsV, segment_in_U, segment_in_V);
808 }
809
810 //=======================================================================
811 //function : SetUKnot
812 //purpose  : 
813 //=======================================================================
814
815 void Geom_BSplineSurface::SetUKnot
816 (const Standard_Integer UIndex,
817  const Standard_Real    K      )
818 {
819   if (UIndex < 1 || UIndex > uknots->Length()) throw Standard_OutOfRange();
820
821   Standard_Integer NewIndex = UIndex;
822   Standard_Real DU = Abs(Epsilon (K));
823   if (UIndex == 1) {
824     if (K >= uknots->Value (2) - DU) throw Standard_ConstructionError();
825   }
826   else if (UIndex == uknots->Length()) {
827     if (K <= uknots->Value (uknots->Length()-1) + DU)  {
828       throw Standard_ConstructionError();
829     }
830   }
831   else {
832     if (K <= uknots->Value (NewIndex-1) + DU || 
833         K >= uknots->Value (NewIndex+1) - DU ) { 
834       throw Standard_ConstructionError();
835     } 
836   }
837   
838   if (K != uknots->Value (NewIndex)) {
839     uknots->SetValue (NewIndex, K);
840     maxderivinvok = 0;
841     UpdateUKnots();
842   }
843 }
844
845 //=======================================================================
846 //function : SetUKnots
847 //purpose  : 
848 //=======================================================================
849
850 void Geom_BSplineSurface::SetUKnots (const TColStd_Array1OfReal& UK) {
851
852   Standard_Integer Lower = UK.Lower();
853   Standard_Integer Upper = UK.Upper();
854   if (Lower < 1 || Lower > uknots->Length() ||
855       Upper < 1 || Upper > uknots->Length() ) {
856     throw Standard_OutOfRange();
857   }
858   if (Lower > 1) {
859     if (Abs (UK (Lower) - uknots->Value (Lower-1)) <= gp::Resolution()) {
860       throw Standard_ConstructionError();
861     }
862   }
863   if (Upper < uknots->Length ()) {
864     if (Abs (UK (Upper) - uknots->Value (Upper+1)) <= gp::Resolution()) {
865       throw Standard_ConstructionError();
866     }
867   }
868   Standard_Real K1 = UK (Lower);
869   for (Standard_Integer i = Lower; i <= Upper; i++) {
870     uknots->SetValue (i, UK(i));
871     if (i != Lower) {
872       if (Abs (UK(i) - K1) <= gp::Resolution()) {
873         throw Standard_ConstructionError();
874       }
875       K1 = UK (i);
876     }
877   }
878
879   maxderivinvok = 0;
880   UpdateUKnots();
881 }
882
883 //=======================================================================
884 //function : SetUKnot
885 //purpose  : 
886 //=======================================================================
887
888 void Geom_BSplineSurface::SetUKnot
889 (const Standard_Integer UIndex,
890  const Standard_Real    K,
891  const Standard_Integer M)
892 {
893   IncreaseUMultiplicity (UIndex, M);
894   SetUKnot (UIndex, K);
895 }
896
897 //=======================================================================
898 //function : SetVKnot
899 //purpose  : 
900 //=======================================================================
901
902 void Geom_BSplineSurface::SetVKnot
903 (const Standard_Integer VIndex,
904  const Standard_Real    K)
905 {
906   if (VIndex < 1 || VIndex > vknots->Length())  throw Standard_OutOfRange();
907   Standard_Integer NewIndex = VIndex + vknots->Lower() - 1;
908   Standard_Real DV = Abs(Epsilon (K));
909   if (VIndex == 1) {
910     if (K >=  vknots->Value (2) - DV) {
911       throw Standard_ConstructionError();
912     }
913   }
914   else if (VIndex == vknots->Length()) {
915     if (K <= vknots->Value (vknots->Length()-1) + DV)  {
916       throw Standard_ConstructionError();
917     }
918   }
919   else {
920     if (K <= vknots->Value (NewIndex-1) + DV || 
921         K >= vknots->Value (NewIndex+1) - DV ) { 
922       throw Standard_ConstructionError();
923     } 
924   }
925   
926   if (K != vknots->Value (NewIndex)) {
927     vknots->SetValue (NewIndex, K);
928     maxderivinvok = 0;
929     UpdateVKnots();
930   }
931 }
932
933 //=======================================================================
934 //function : SetVKnots
935 //purpose  : 
936 //=======================================================================
937
938 void Geom_BSplineSurface::SetVKnots (const TColStd_Array1OfReal& VK) {
939
940   Standard_Integer Lower = VK.Lower();
941   Standard_Integer Upper = VK.Upper();
942   if (Lower < 1 || Lower > vknots->Length() ||
943       Upper < 1 || Upper > vknots->Length() ) {
944     throw Standard_OutOfRange();
945   }
946   if (Lower > 1) {
947     if (Abs (VK (Lower) - vknots->Value (Lower-1)) <= gp::Resolution()) {
948       throw Standard_ConstructionError();
949     }
950   }
951   if (Upper < vknots->Length ()) {
952     if (Abs (VK (Upper) - vknots->Value (Upper+1)) <= gp::Resolution()) {
953       throw Standard_ConstructionError();
954     }
955   }
956   Standard_Real K1 = VK (Lower);
957   for (Standard_Integer i = Lower; i <= Upper; i++) {
958     vknots->SetValue (i, VK(i));
959     if (i != Lower) {
960       if (Abs (VK(i) - K1) <= gp::Resolution()) {
961         throw Standard_ConstructionError();
962       }
963       K1 = VK (i);
964     }
965   }
966
967   maxderivinvok = 0;
968   UpdateVKnots();
969 }
970
971 //=======================================================================
972 //function : SetVKnot
973 //purpose  : 
974 //=======================================================================
975
976 void Geom_BSplineSurface::SetVKnot
977 (const Standard_Integer VIndex,
978  const Standard_Real    K,
979  const Standard_Integer M)
980 {
981   IncreaseVMultiplicity (VIndex, M);
982   SetVKnot (VIndex, K);
983 }
984
985 //=======================================================================
986 //function : InsertUKnot
987 //purpose  : 
988 //=======================================================================
989
990 void Geom_BSplineSurface::InsertUKnot
991 (const Standard_Real    U,
992  const Standard_Integer M,
993  const Standard_Real    ParametricTolerance,
994  const Standard_Boolean Add)
995 {
996   TColStd_Array1OfReal k(1,1);
997   k(1) = U;
998   TColStd_Array1OfInteger m(1,1);
999   m(1) = M;
1000   InsertUKnots(k,m,ParametricTolerance,Add);
1001 }
1002
1003 //=======================================================================
1004 //function : InsertVKnot
1005 //purpose  : 
1006 //=======================================================================
1007
1008 void Geom_BSplineSurface::InsertVKnot
1009 (const Standard_Real    V,
1010  const Standard_Integer M,
1011  const Standard_Real    ParametricTolerance,
1012  const Standard_Boolean Add)
1013 {
1014   TColStd_Array1OfReal k(1,1);
1015   k(1) = V;
1016   TColStd_Array1OfInteger m(1,1);
1017   m(1) = M;
1018   InsertVKnots(k,m,ParametricTolerance,Add);
1019 }
1020
1021 //=======================================================================
1022 //function : IncrementUMultiplicity
1023 //purpose  : 
1024 //=======================================================================
1025
1026 void  Geom_BSplineSurface::IncrementUMultiplicity
1027 (const Standard_Integer FromI1,
1028  const Standard_Integer ToI2,
1029  const Standard_Integer Step)
1030 {
1031   Handle(TColStd_HArray1OfReal) tk = uknots;
1032   TColStd_Array1OfReal k( (uknots->Array1())(FromI1), FromI1, ToI2);
1033   TColStd_Array1OfInteger m( FromI1, ToI2) ;
1034   m.Init(Step);
1035   InsertUKnots( k, m, Epsilon(1.));
1036 }
1037
1038 //=======================================================================
1039 //function : IncrementVMultiplicity
1040 //purpose  : 
1041 //=======================================================================
1042
1043 void  Geom_BSplineSurface::IncrementVMultiplicity
1044 (const Standard_Integer FromI1,
1045  const Standard_Integer ToI2,
1046  const Standard_Integer Step)
1047 {
1048   Handle(TColStd_HArray1OfReal) tk = vknots;
1049   TColStd_Array1OfReal k( (vknots->Array1())(FromI1), FromI1, ToI2);
1050
1051   TColStd_Array1OfInteger m( FromI1, ToI2) ;
1052   m.Init(Step);
1053   
1054   InsertVKnots( k, m, Epsilon(1.));
1055 }
1056
1057 //=======================================================================
1058 //function : UpdateUKnots
1059 //purpose  : 
1060 //=======================================================================
1061
1062 void Geom_BSplineSurface::UpdateUKnots()
1063 {
1064
1065   Standard_Integer MaxKnotMult = 0;
1066   BSplCLib::KnotAnalysis (udeg, uperiodic,
1067                 uknots->Array1(), 
1068                 umults->Array1(), 
1069                 uknotSet, MaxKnotMult);
1070   
1071   if (uknotSet == GeomAbs_Uniform && !uperiodic)  {
1072     ufknots = uknots;
1073   }
1074   else {
1075     ufknots = new TColStd_HArray1OfReal 
1076       (1, BSplCLib::KnotSequenceLength(umults->Array1(),udeg,uperiodic));
1077
1078     BSplCLib::KnotSequence (uknots->Array1(), 
1079                             umults->Array1(),
1080                             udeg,uperiodic,
1081                             ufknots->ChangeArray1());
1082   }
1083   
1084   if (MaxKnotMult == 0)  Usmooth = GeomAbs_CN;
1085   else {
1086     switch (udeg - MaxKnotMult) {
1087     case 0 :   Usmooth = GeomAbs_C0;   break;
1088     case 1 :   Usmooth = GeomAbs_C1;   break;
1089     case 2 :   Usmooth = GeomAbs_C2;   break;
1090     case 3 :   Usmooth = GeomAbs_C3;   break;
1091       default :  Usmooth = GeomAbs_C3;   break;
1092     }
1093   }
1094 }
1095
1096 //=======================================================================
1097 //function : UpdateVKnots
1098 //purpose  : 
1099 //=======================================================================
1100
1101 void Geom_BSplineSurface::UpdateVKnots()
1102 {
1103   Standard_Integer MaxKnotMult = 0;
1104   BSplCLib::KnotAnalysis (vdeg, vperiodic,
1105                 vknots->Array1(), 
1106                 vmults->Array1(), 
1107                 vknotSet, MaxKnotMult);
1108   
1109   if (vknotSet == GeomAbs_Uniform && !vperiodic)  {
1110     vfknots = vknots;
1111   }
1112   else {
1113     vfknots = new TColStd_HArray1OfReal 
1114       (1, BSplCLib::KnotSequenceLength(vmults->Array1(),vdeg,vperiodic));
1115
1116     BSplCLib::KnotSequence (vknots->Array1(), 
1117                             vmults->Array1(),
1118                             vdeg,vperiodic,
1119                             vfknots->ChangeArray1());
1120   }
1121   
1122   if (MaxKnotMult == 0)  Vsmooth = GeomAbs_CN;
1123   else {
1124     switch (vdeg - MaxKnotMult) {
1125     case 0 :   Vsmooth = GeomAbs_C0;   break;
1126     case 1 :   Vsmooth = GeomAbs_C1;   break;
1127     case 2 :   Vsmooth = GeomAbs_C2;   break;
1128     case 3 :   Vsmooth = GeomAbs_C3;   break;
1129       default :  Vsmooth = GeomAbs_C3;   break;
1130     }
1131   }
1132 }
1133
1134
1135 //=======================================================================
1136 //function : Normalizes the parameters if the curve is periodic
1137 //purpose  : that is compute the cache so that it is valid
1138 //=======================================================================
1139
1140 void Geom_BSplineSurface::PeriodicNormalization
1141 (Standard_Real&  Uparameter, 
1142  Standard_Real&  Vparameter) const 
1143 {
1144   Standard_Real Period, aMaxVal, aMinVal;
1145   
1146   if (uperiodic) {
1147     aMaxVal = ufknots->Value(ufknots->Upper() - udeg);
1148     aMinVal = ufknots->Value (udeg + 1);
1149     Standard_Real eps = Abs(Epsilon(Uparameter));
1150     Period =  aMaxVal - aMinVal;
1151
1152     if(Period <= eps) 
1153       throw Standard_OutOfRange("Geom_BSplineSurface::PeriodicNormalization: Uparameter is too great number");
1154
1155     Standard_Boolean isLess, isGreater;
1156     isLess = aMinVal - Uparameter > 0;
1157     isGreater = Uparameter - aMaxVal > 0;
1158     if (isLess || isGreater) {
1159       Standard_Real aDPar, aNbPer;
1160       aDPar = (isLess) ? (aMaxVal - Uparameter) : (aMinVal - Uparameter);
1161       modf(aDPar / Period, &aNbPer);
1162       Uparameter += aNbPer * Period;
1163     }
1164   }
1165   if (vperiodic) {
1166     aMaxVal = vfknots->Value(vfknots->Upper() - vdeg);
1167     aMinVal = vfknots->Value (vdeg + 1);
1168     Standard_Real eps = Abs(Epsilon(Vparameter));
1169     Period = aMaxVal - aMinVal;
1170
1171     if(Period <= eps) 
1172       throw Standard_OutOfRange("Geom_BSplineSurface::PeriodicNormalization: Vparameter is too great number");
1173
1174     Standard_Boolean isLess, isGreater;
1175     isLess = aMinVal - Vparameter > 0;
1176     isGreater = Vparameter - aMaxVal > 0;
1177     if (isLess || isGreater) {
1178       Standard_Real aDPar, aNbPer;
1179       aDPar = (isLess) ? (aMaxVal - Vparameter) : (aMinVal - Vparameter);
1180       modf(aDPar / Period, &aNbPer);
1181       Vparameter += aNbPer * Period;
1182     }
1183   }
1184 }
1185
1186 //=======================================================================
1187 //function : SetWeight
1188 //purpose  : 
1189 //=======================================================================
1190
1191 void Geom_BSplineSurface::SetWeight (const Standard_Integer UIndex,
1192                                      const Standard_Integer VIndex,
1193                                      const Standard_Real    Weight)
1194 {
1195   if (Weight <= gp::Resolution())  throw Standard_ConstructionError();
1196   TColStd_Array2OfReal & Weights = weights->ChangeArray2();
1197   if (UIndex < 1 || UIndex > Weights.ColLength() ||
1198       VIndex < 1 || VIndex > Weights.RowLength() ) {
1199     throw Standard_OutOfRange();
1200   }
1201   Weights (UIndex+Weights.LowerRow()-1, VIndex+Weights.LowerCol()-1) = Weight;
1202   Rational(Weights, urational, vrational);
1203 }
1204
1205 //=======================================================================
1206 //function : SetWeightCol
1207 //purpose  : 
1208 //=======================================================================
1209
1210 void Geom_BSplineSurface::SetWeightCol
1211 (const Standard_Integer       VIndex, 
1212  const TColStd_Array1OfReal&  CPoleWeights)
1213 {
1214   TColStd_Array2OfReal & Weights = weights->ChangeArray2();   
1215   if (VIndex < 1 || VIndex > Weights.RowLength()) {
1216     throw Standard_OutOfRange();
1217   }
1218   if (CPoleWeights.Lower() < 1 || 
1219       CPoleWeights.Lower() > Weights.ColLength() ||
1220       CPoleWeights.Upper() < 1 ||
1221       CPoleWeights.Upper() > Weights.ColLength()  ) {
1222     throw Standard_ConstructionError();
1223   }
1224   Standard_Integer I = CPoleWeights.Lower();
1225   while (I <= CPoleWeights.Upper()) {
1226     if (CPoleWeights(I) <= gp::Resolution()) { 
1227       throw Standard_ConstructionError();
1228     }
1229     Weights (I+Weights.LowerRow()-1, VIndex+Weights.LowerCol()-1) = 
1230       CPoleWeights (I);
1231     I++;
1232   }
1233   // Verifie si c'est rationnel
1234   Rational(Weights, urational, vrational);
1235 }
1236
1237 //=======================================================================
1238 //function : SetWeightRow
1239 //purpose  : 
1240 //=======================================================================
1241
1242 void Geom_BSplineSurface::SetWeightRow
1243 (const Standard_Integer       UIndex, 
1244  const TColStd_Array1OfReal&  CPoleWeights)
1245 {
1246   TColStd_Array2OfReal & Weights = weights->ChangeArray2();   
1247   if (UIndex < 1 || UIndex > Weights.ColLength()) {
1248     throw Standard_OutOfRange();
1249   }
1250   if (CPoleWeights.Lower() < 1 ||
1251       CPoleWeights.Lower() > Weights.RowLength() ||
1252       CPoleWeights.Upper() < 1 ||
1253       CPoleWeights.Upper() > Weights.RowLength()  ) {
1254     
1255     throw Standard_ConstructionError();
1256   }
1257   Standard_Integer I = CPoleWeights.Lower();
1258
1259   while (I <= CPoleWeights.Upper()) {
1260     if (CPoleWeights(I)<=gp::Resolution()) {
1261       throw Standard_ConstructionError();
1262     }
1263     Weights (UIndex+Weights.LowerRow()-1, I+Weights.LowerCol()-1) = 
1264       CPoleWeights (I);
1265     I++;
1266   }
1267   // Verifie si c'est rationnel
1268   Rational(Weights, urational, vrational);
1269 }
1270