Logo Search packages:      
Sourcecode: opencascade version File versions  Download package

Geom_BezierSurface.cxx

// File:    Geom_BezierSurface.cxx
// Created: Tue Mar  9 19:52:37 1993
// Author:  JCV
//          <fid@phylox>
// Copyright:     Matra Datavision 1993

//File Geom_BezierSurface.cxx  Septembre 1990
//Passage en classe persistante - 23/01/91
//Modif suite a la deuxieme revue de projet toolkit Geometry -23/01/91
// pmn : 21/10/95 ; Correction de la methode segment (PRO5853)
// pmn : 31-Dec-96; Bonne gestion des poids (bug PRO4622)
// xab : 07-Jul-97; le cache est instable en degree 21
//       a partir du degree 15 on ne l'utilise plus
// RBD : 15/10/98 ; Le cache est desormais defini sur [-1,1] (pro15537).
// pmn : 10/12/98 ; Update de la methode segment (suite a la modif de cache).

#define No_Standard_OutOfRange
#define No_Standard_DimensionError

#include <Geom_BezierSurface.ixx>
#include <Geom_BezierCurve.hxx>

#include <gp.hxx>
#include <gp_XYZ.hxx>
#include <PLib.hxx>
#include <BSplCLib.hxx>
#include <BSplSLib.hxx>
#include <Precision.hxx>

#include <Standard_OutOfRange.hxx>
#include <Standard_RangeError.hxx>
#include <Standard_DimensionError.hxx>
#include <Standard_ConstructionError.hxx>
#include <TColStd_Array1OfInteger.hxx>

//=======================================================================
//function : Rational
//purpose  : check rationality of an array of weights
//=======================================================================

static void Rational(const TColStd_Array2OfReal& Weights,
                 Standard_Boolean& Urational,
                 Standard_Boolean& Vrational)
{
  Standard_Integer I,J;
  J = Weights.LowerCol ();
  Vrational = Standard_False;
  while (!Vrational && J <= Weights.UpperCol()) {
    I = Weights.LowerRow();
    while (!Vrational && I <= Weights.UpperRow() - 1) {
      Vrational = (Abs(Weights (I, J) - Weights (I+1, J)) 
                   > Epsilon (Abs(Weights (I, J))));
      I++;
    }
    J++;
  }

  I = Weights.LowerRow ();
  Urational = Standard_False;
  while (!Urational && I <= Weights.UpperRow()) {
    J = Weights.LowerCol();
    while (!Urational && J <= Weights.UpperCol() - 1) {
      Urational = (Abs(Weights (I, J) - Weights (I, J+1))
                   > Epsilon (Abs(Weights (I, J))));
      J++;
    }
    I++;
  }
}

//=======================================================================
//function : AddPoleCol
//purpose  : Internal use only.
//=======================================================================

static void AddPoleCol
  (const TColgp_Array2OfPnt& Poles,
   const TColgp_Array1OfPnt& PoleCol,
   const Standard_Integer    AfterIndex,
         TColgp_Array2OfPnt& NewPoles)
{
  Standard_Integer InsertIndex = AfterIndex + NewPoles.LowerCol();
  Standard_Integer Offset = NewPoles.LowerRow() - PoleCol.Lower();
  Standard_Integer ColIndex = NewPoles.LowerCol();
  Standard_Integer RowIndex;
  while (ColIndex < InsertIndex) {
    RowIndex = NewPoles.LowerRow();
    while (RowIndex <= NewPoles.UpperRow()){
      NewPoles (RowIndex, ColIndex) =  Poles (RowIndex, ColIndex);
      RowIndex++;
    }
    ColIndex++;
  }
  RowIndex = NewPoles.LowerRow();
  while (RowIndex <= NewPoles.UpperRow()){
    NewPoles (RowIndex, ColIndex) = PoleCol (RowIndex - Offset);
    RowIndex++;
  }
  ColIndex++;
  while (ColIndex <= NewPoles.UpperCol()) {
    RowIndex = NewPoles.LowerRow();
    while (RowIndex <= NewPoles.UpperRow()){
      NewPoles (RowIndex, ColIndex) =  Poles (RowIndex, ColIndex - 1);
      RowIndex++;
    }
    ColIndex++;
  }
}

//=======================================================================
//function : AddRatPoleCol
//purpose  : Internal use only.
//=======================================================================

static void AddRatPoleCol
  (const TColgp_Array2OfPnt&   Poles,
   const TColStd_Array2OfReal& Weights,
   const TColgp_Array1OfPnt&   PoleCol,
   const TColStd_Array1OfReal& PoleWeightCol,
   const Standard_Integer      AfterIndex,
         TColgp_Array2OfPnt&   NewPoles,
         TColStd_Array2OfReal& NewWeights)
{
  Standard_Integer InsertIndex = AfterIndex + NewPoles.LowerCol();
  Standard_Integer OffsetPol   = NewPoles.LowerRow() - PoleCol.Lower();
  Standard_Integer OffsetW     = NewWeights.LowerRow() - PoleWeightCol.Lower();
  
  Standard_Integer ColIndex = NewPoles.LowerCol();
  Standard_Integer RowIndex;
  while (ColIndex < InsertIndex) {
    RowIndex = NewPoles.LowerRow();
    while (RowIndex <= NewPoles.UpperRow()){
      NewPoles (RowIndex, ColIndex) = Poles (RowIndex, ColIndex);
      NewWeights (RowIndex, ColIndex)  =  Weights (RowIndex, ColIndex);
      RowIndex++;
    }
    ColIndex++;
  }
  RowIndex = NewPoles.LowerRow();
  while (RowIndex <= NewPoles.UpperRow()){
    NewPoles (RowIndex, ColIndex) = PoleCol (RowIndex - OffsetPol);
    NewWeights (RowIndex, ColIndex) =  PoleWeightCol (RowIndex - OffsetW);
    RowIndex++;
  }
  ColIndex++;
  while (ColIndex <= NewPoles.UpperCol()) {
    RowIndex = NewPoles.LowerRow();
    while (RowIndex <= NewPoles.UpperRow()){
      NewPoles (RowIndex, ColIndex) = Poles (RowIndex, ColIndex - 1);
      RowIndex++;
      NewWeights (RowIndex, ColIndex)  = Weights (RowIndex, ColIndex - 1);
    }
    ColIndex++;
  }
}

//=======================================================================
//function : AddPoleRow
//purpose  : Internal use only.
//=======================================================================

static void AddPoleRow
  (const TColgp_Array2OfPnt& Poles,
   const TColgp_Array1OfPnt& PoleRow,
   const Standard_Integer    AfterIndex,
         TColgp_Array2OfPnt& NewPoles)
{
  Standard_Integer InsertIndex = AfterIndex + NewPoles.LowerRow();
  Standard_Integer Offset = NewPoles.LowerCol() - PoleRow.Lower();
  Standard_Integer RowIndex = NewPoles.LowerRow();
  Standard_Integer ColIndex;
  while (RowIndex < InsertIndex) {
    ColIndex = NewPoles.LowerCol();
    while (ColIndex <= NewPoles.UpperCol()){
      NewPoles (RowIndex, ColIndex) = Poles (RowIndex, ColIndex);
      ColIndex++;
    }
    RowIndex++;
  }
  ColIndex = NewPoles.LowerCol();
  while (ColIndex <= NewPoles.UpperCol()){
    NewPoles (RowIndex, ColIndex) = PoleRow (ColIndex - Offset);
    ColIndex++;
  }
  RowIndex++;
  while (RowIndex <= NewPoles.UpperRow()) {
    ColIndex = NewPoles.LowerCol();
    while (ColIndex <= NewPoles.UpperCol()){
      NewPoles (RowIndex, ColIndex) = Poles (RowIndex - 1, ColIndex);
      ColIndex++;
    }
    RowIndex++;
  }
}

//=======================================================================
//function : AddRatPoleRow
//purpose  : 
//=======================================================================

static void AddRatPoleRow
  (const TColgp_Array2OfPnt&   Poles,
   const TColStd_Array2OfReal& Weights,
   const TColgp_Array1OfPnt&   PoleRow,
   const TColStd_Array1OfReal& PoleWeightRow,
   const Standard_Integer      AfterIndex,
         TColgp_Array2OfPnt&   NewPoles,
         TColStd_Array2OfReal& NewWeights)
{
  Standard_Integer InsertIndex = AfterIndex + NewPoles.LowerRow();
  Standard_Integer OffsetPol = NewPoles.LowerCol() - PoleRow.Lower();
  Standard_Integer OffsetW = NewWeights.LowerCol() - PoleWeightRow.Lower();
  
  Standard_Integer ColIndex;
  Standard_Integer RowIndex = NewPoles.LowerRow();
  while (RowIndex < InsertIndex) {
    ColIndex = NewPoles.LowerCol();
    while (ColIndex <= NewPoles.UpperCol()){
      NewPoles (RowIndex, ColIndex) =  Poles (RowIndex, ColIndex);
      NewWeights (RowIndex, ColIndex)  =  Weights (RowIndex, ColIndex);
      ColIndex++;
    }
    RowIndex++;
  }
  ColIndex = NewPoles.LowerCol();
  while (ColIndex <= NewPoles.UpperCol()){
    NewPoles (RowIndex, ColIndex) = PoleRow (ColIndex - OffsetPol);
    NewWeights (RowIndex, ColIndex) = PoleWeightRow (ColIndex - OffsetW);
    ColIndex++;
  }
  RowIndex++;
  while (RowIndex <= NewPoles.UpperRow()) {
    ColIndex = NewPoles.LowerCol();
    while (ColIndex <= NewPoles.UpperCol()){
      NewPoles (RowIndex, ColIndex) = Poles (RowIndex - 1, ColIndex);
      NewWeights (RowIndex, ColIndex)  = Weights (RowIndex - 1, ColIndex);
      ColIndex++;
    }
    RowIndex++;
  }
}

//=======================================================================
//function : DeletePoleCol
//purpose  : 
//=======================================================================

static void DeletePoleCol
  (const TColgp_Array2OfPnt& Poles,
   const Standard_Integer    Index,
         TColgp_Array2OfPnt& NewPoles)
{
  Standard_Integer Offset = 0;
  Standard_Integer RowIndex;
  Standard_Integer ColIndex = NewPoles.LowerCol();
  while (ColIndex <= NewPoles.UpperCol()) {
    RowIndex = NewPoles.LowerRow();
    if (ColIndex == Index)  Offset = 1;
    while (RowIndex <= NewPoles.UpperRow()){
      NewPoles (RowIndex, ColIndex) = Poles (RowIndex, ColIndex + Offset);
      RowIndex++;
    }
    ColIndex++;
  }
}

//=======================================================================
//function : DeleteRatPoleCol
//purpose  : 
//=======================================================================

static void DeleteRatPoleCol
  (const TColgp_Array2OfPnt&   Poles,
   const TColStd_Array2OfReal& Weights,
   const Standard_Integer      Index,
         TColgp_Array2OfPnt&   NewPoles,
         TColStd_Array2OfReal& NewWeights)
{
  Standard_Integer Offset = 0;
  Standard_Integer RowIndex;
  Standard_Integer ColIndex = NewPoles.LowerCol();
  while (ColIndex <= NewPoles.UpperCol()) {
    RowIndex = NewPoles.LowerRow();
    if (ColIndex == Index) Offset = 1;
    while (RowIndex <= NewPoles.UpperRow()){
      NewPoles (RowIndex, ColIndex) = Poles (RowIndex, ColIndex + Offset);
      NewWeights (RowIndex, ColIndex) = Weights (RowIndex, ColIndex+Offset);
      RowIndex++;
    }
    ColIndex++;
  }
}

//=======================================================================
//function : DeletePoleRow
//purpose  : 
//=======================================================================

static void DeletePoleRow
  (const TColgp_Array2OfPnt& Poles,
   const Standard_Integer    Index,
         TColgp_Array2OfPnt& NewPoles)
{
  Standard_Integer Offset = 0;
  Standard_Integer ColIndex;
  Standard_Integer RowIndex = NewPoles.LowerRow();
  while (RowIndex <= NewPoles.UpperRow()) {
    ColIndex = NewPoles.LowerCol();
    if (RowIndex == Index)  Offset = 1;
    while (ColIndex <= NewPoles.UpperCol()){
      NewPoles (RowIndex, ColIndex) = Poles (RowIndex + Offset, ColIndex);
      ColIndex++;
    }
    RowIndex++;
  }
}

//=======================================================================
//function : DeleteRatPoleRow
//purpose  : 
//=======================================================================

static void DeleteRatPoleRow
  (const TColgp_Array2OfPnt&   Poles,
   const TColStd_Array2OfReal& Weights,
   const Standard_Integer      Index,
         TColgp_Array2OfPnt&   NewPoles,
         TColStd_Array2OfReal& NewWeights)
{
  Standard_Integer Offset = 0;
  Standard_Integer ColIndex;
  Standard_Integer RowIndex = NewPoles.LowerRow();
  while (RowIndex <= NewPoles.UpperRow()) {
    ColIndex = NewPoles.LowerCol();
    if (RowIndex == Index)  Offset = 1;
    while (ColIndex <= NewPoles.UpperCol()){
      NewPoles (RowIndex, ColIndex) =  Poles (RowIndex +  Offset, ColIndex);
      NewWeights (RowIndex, ColIndex) = Weights (RowIndex+Offset, ColIndex);
      ColIndex++;
    }
    RowIndex++;
  }
}

//=======================================================================
//function : Geom_BezierSurface
//purpose  : 
//=======================================================================

Geom_BezierSurface::Geom_BezierSurface 
00351 (const TColgp_Array2OfPnt& SurfacePoles):
 ucacheparameter(0.),
 vcacheparameter(0.),
 ucachespanlenght(1.),
 vcachespanlenght(1.),
 validcache(0),
 maxderivinvok(Standard_False)
{
  Standard_Integer NbUPoles = SurfacePoles.ColLength();
  Standard_Integer NbVPoles = SurfacePoles.RowLength();
  if (NbUPoles < 2 || NbUPoles > MaxDegree()+1 ||
      NbVPoles < 2 || NbVPoles > MaxDegree()+1) {
    Standard_ConstructionError::Raise();
  }
  
  Handle(TColgp_HArray2OfPnt) npoles = 
    new TColgp_HArray2OfPnt   (1, NbUPoles, 1, NbVPoles);
  
  urational = 0;
  vrational = 0;

  npoles->ChangeArray2() = SurfacePoles;
  
  // Init non rational
  Init(npoles,
       Handle(TColStd_HArray2OfReal)());
}

//=======================================================================
//function : Geom_BezierSurface
//purpose  : 
//=======================================================================

Geom_BezierSurface::Geom_BezierSurface 
00385   (const TColgp_Array2OfPnt&   SurfacePoles,
   const TColStd_Array2OfReal& PoleWeights  ):
 ucacheparameter(0.),
 vcacheparameter(0.),
 ucachespanlenght(1.),
 vcachespanlenght(1.),
 validcache(0),
 maxderivinvok(Standard_False)
{
  Standard_Integer NbUPoles = SurfacePoles.ColLength();
  Standard_Integer NbVPoles = SurfacePoles.RowLength();
  if (NbUPoles < 2 || NbUPoles > MaxDegree()+1 ||
      NbVPoles < 2 || NbVPoles > MaxDegree()+1 ||
      NbVPoles != PoleWeights.RowLength()      ||
      NbUPoles != PoleWeights.ColLength()      ) {
    Standard_ConstructionError::Raise();
  }
  
  Standard_Integer Row = PoleWeights.LowerRow();
  Standard_Integer Col = PoleWeights.LowerCol();
  while (Col <= PoleWeights.UpperCol()) {
    Row = PoleWeights.LowerRow();
    while (Row <= PoleWeights.UpperRow()) {
      if (PoleWeights(Row, Col) <= gp::Resolution()) {
        Standard_ConstructionError::Raise();
      }
      Row++;
    }
    Col++;
  }
  
  Handle(TColgp_HArray2OfPnt) 
    npoles = new TColgp_HArray2OfPnt   (1, NbUPoles, 1, NbVPoles);
  npoles->ChangeArray2() = SurfacePoles;

  Standard_Integer I, J;
  urational = Standard_False;
  vrational = Standard_False;
  J = PoleWeights.LowerCol ();
  while (!vrational && J <= PoleWeights.UpperCol()) {
    I = PoleWeights.LowerRow();
    while (!vrational && I <= PoleWeights.UpperRow() - 1) {
      vrational = (Abs(PoleWeights (I, J) - PoleWeights (I+1, J)) 
                   > Epsilon (Abs(PoleWeights (I, J))));
      I++;
    }
    J++;
  }
  I = PoleWeights.LowerRow ();
  while (!urational && I <= PoleWeights.UpperRow()) {
    J = PoleWeights.LowerCol();
    while (!urational && J <= PoleWeights.UpperCol() - 1) {
      urational = (Abs(PoleWeights (I, J) - PoleWeights (I, J+1))
                   > Epsilon (Abs(PoleWeights (I, J))));
      J++;
    }
    I++;
  }


  Handle(TColStd_HArray2OfReal) nweights; 
  if (urational || vrational) {
    nweights = new TColStd_HArray2OfReal (1, NbUPoles, 1, NbVPoles);
    nweights->ChangeArray2() = PoleWeights;
  }

  // Init
  Init(npoles,nweights);
}

//=======================================================================
//function : Geom_BezierSurface
//purpose  : 
//=======================================================================

Geom_BezierSurface::Geom_BezierSurface
  (const Handle(TColgp_HArray2OfPnt)&   SurfacePoles,
   const Handle(TColgp_HArray2OfPnt)&   SurfaceCoefs,
   const Handle(TColStd_HArray2OfReal)& PoleWeights,
   const Handle(TColStd_HArray2OfReal)& CoefWeights,
   const Standard_Boolean               IsURational,
   const Standard_Boolean               IsVRational)
:maxderivinvok(Standard_False)
{
  urational = IsURational;
  vrational = IsVRational;
  ucachespanlenght = 1.;
  vcachespanlenght = 1.;
  validcache = 1;
  ucacheparameter =0.; 
  vcacheparameter = 0.;
  Standard_Integer NbUPoles = SurfacePoles->ColLength();
  Standard_Integer NbVPoles = SurfacePoles->RowLength();

  poles    = new TColgp_HArray2OfPnt   (1,NbUPoles,
                              1,NbVPoles) ;
  poles->ChangeArray2() = SurfacePoles->Array2();

  coeffs   = new TColgp_HArray2OfPnt   (1,SurfaceCoefs->ColLength(),
                              1,SurfaceCoefs->RowLength()) ;
  coeffs->ChangeArray2() = SurfaceCoefs->Array2();

  if ( urational || vrational) {
    weights  = new TColStd_HArray2OfReal (1,NbUPoles,1,NbVPoles);
    weights->ChangeArray2() = PoleWeights->Array2();
    
    wcoeffs  = new TColStd_HArray2OfReal (1,SurfaceCoefs->ColLength(),
                                1,SurfaceCoefs->RowLength()) ;
    wcoeffs->ChangeArray2() = CoefWeights->Array2();
  }
}

//=======================================================================
//function : MaxDegree
//purpose  : 
//=======================================================================

00502 Standard_Integer Geom_BezierSurface::MaxDegree () 
{ 
  return BSplCLib::MaxDegree(); 
}

//=======================================================================
//function : ExchangeUV
//purpose  : 
//=======================================================================

00512 void Geom_BezierSurface::ExchangeUV ()
{
  Standard_Integer LC = poles->LowerCol();
  Standard_Integer UC = poles->UpperCol();
  Standard_Integer LR = poles->LowerRow();
  Standard_Integer UR = poles->UpperRow();

  Handle(TColgp_HArray2OfPnt) npoles = 
    new TColgp_HArray2OfPnt (LC, UC, LR, UR);
  Handle(TColStd_HArray2OfReal) nweights =
    new TColStd_HArray2OfReal (LC, UC, LR, UR);

  const TColgp_Array2OfPnt   & spoles   = poles->Array2();
  const TColStd_Array2OfReal & sweights = weights->Array2();

  TColgp_Array2OfPnt&   snpoles   = npoles->ChangeArray2();
  TColStd_Array2OfReal& snweights = nweights->ChangeArray2();
 
  Standard_Integer i, j;
  for (i = LC; i <= UC; i++) {
    for (j = LR; j <= UR; j++) {
      snpoles   (i,j) = spoles   (j,i);
      snweights (i,j) = sweights (j,i);
    }
  }

  poles   = npoles;
  weights = nweights;

  Standard_Boolean temp = urational;
  urational = vrational;
  vrational = temp;
  coeffs  = new TColgp_HArray2OfPnt   (LC, UC, LR, UR);
  wcoeffs = new TColStd_HArray2OfReal (LC, UC, LR, UR);

  UpdateCoefficients();
}

//=======================================================================
//function : Increase
//purpose  : 
//=======================================================================

00555 void Geom_BezierSurface::Increase (const Standard_Integer UDeg,
                           const Standard_Integer VDeg)
{
  if (UDeg < UDegree() || UDeg > Geom_BezierSurface::MaxDegree() ||
      VDeg < VDegree() || VDeg > Geom_BezierSurface::MaxDegree() )  {
    Standard_ConstructionError::Raise();
  }

  Standard_Integer oldUDeg = UDegree();
  Standard_Integer oldVDeg = VDegree();
  Standard_Integer IncUDeg = UDeg - oldUDeg;
  Standard_Integer IncVDeg = VDeg - oldVDeg;
  if (IncUDeg == 0 && IncVDeg == 0) return;
  
  TColStd_Array1OfReal biduknots(1,2); biduknots(1) = 0.; biduknots(2) = 1.;
  TColStd_Array1OfInteger bidumults(1,2); bidumults.Init(UDegree() + 1);
  TColStd_Array1OfReal bidvknots(1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
  TColStd_Array1OfInteger bidvmults(1,2); bidvmults.Init(VDegree() + 1);
  Handle(TColgp_HArray2OfPnt) npoles;
  Handle(TColStd_HArray2OfReal) nweights;

  if(IncUDeg > 0){
    npoles = new TColgp_HArray2OfPnt( 1, UDeg + 1, 1, oldVDeg + 1);
    
    if ( urational || vrational) {
      nweights = new TColStd_HArray2OfReal( 1, UDeg + 1, 1, VDegree() + 1);
      
      BSplSLib::IncreaseDegree(1, oldUDeg, UDeg, 0,
                         poles->Array2(),
                         weights->Array2(),
                         biduknots, bidumults,
                         npoles->ChangeArray2(), 
                         nweights->ChangeArray2(),
                         biduknots, bidumults);
      weights = nweights;
    }
    else {
      BSplSLib::IncreaseDegree(1, oldUDeg, UDeg, 0,
                         poles->Array2(),
                         *((TColStd_Array2OfReal*) NULL),
                         biduknots, bidumults,
                         npoles->ChangeArray2(), 
                         *((TColStd_Array2OfReal*) NULL),
                         biduknots, bidumults);
    }
    poles   = npoles;
  }
  if(IncVDeg > 0){
    npoles = new TColgp_HArray2OfPnt( 1, UDeg + 1, 1, VDeg + 1);
    
    if ( urational || vrational) {
      nweights = new TColStd_HArray2OfReal( 1, UDeg + 1, 1, VDeg + 1);
      
      BSplSLib::IncreaseDegree(0, oldVDeg, VDeg, 0,
                         poles->Array2(),
                         weights->Array2(),
                         bidvknots, bidvmults,
                         npoles->ChangeArray2(), 
                         nweights->ChangeArray2(),
                         bidvknots, bidvmults);
      weights = nweights;
    }
    else {
      BSplSLib::IncreaseDegree(0, oldVDeg, VDeg, 0,
                         poles->Array2(),
                         *((TColStd_Array2OfReal*) NULL),
                         bidvknots, bidvmults,
                         npoles->ChangeArray2(), 
                         *((TColStd_Array2OfReal*) NULL),
                         bidvknots, bidvmults);
      
    }
    poles   = npoles;
  }
  Init(npoles,nweights);
}

//=======================================================================
//function : InsertPoleColAfter
//purpose  : 
//=======================================================================

void Geom_BezierSurface::InsertPoleColAfter 
00638   (const Standard_Integer    VIndex,
   const TColgp_Array1OfPnt& CPoles)
{
  const TColgp_Array2OfPnt & Poles = poles->Array2();
  if (VIndex < 1 || VIndex > Poles.RowLength())  Standard_OutOfRange::Raise();
  if (CPoles.Length() != Poles.ColLength()) {
    Standard_ConstructionError::Raise();
  }

  Handle(TColgp_HArray2OfPnt) npoles =
    new TColgp_HArray2OfPnt(1,poles->ColLength(),1,poles->RowLength()+1);

  Handle(TColStd_HArray2OfReal) nweights;

  if (urational || vrational) {
    nweights = 
      new TColStd_HArray2OfReal(1,poles->ColLength(),1,poles->RowLength()+1);

    TColStd_Array1OfReal CWeights(nweights->LowerRow(),nweights->UpperRow());
    CWeights.Init(1.);

    AddRatPoleCol (poles->Array2(), weights->Array2(),
               CPoles, CWeights, VIndex,
               npoles->ChangeArray2(), nweights->ChangeArray2());
  }
  else {
    AddPoleCol (poles->Array2(), 
            CPoles, VIndex,
            npoles->ChangeArray2());
  }
  poles   = npoles;
  weights = nweights;
  coeffs  = new TColgp_HArray2OfPnt(1,poles->ColLength(),
                            1,poles->RowLength());
  wcoeffs = new TColStd_HArray2OfReal(1,poles->ColLength(),
                              1,poles->RowLength());
  UpdateCoefficients();
}

//=======================================================================
//function : InsertPoleColAfter
//purpose  : 
//=======================================================================

void Geom_BezierSurface::InsertPoleColAfter
00683   (const Standard_Integer      VIndex,
   const TColgp_Array1OfPnt&   CPoles,
   const TColStd_Array1OfReal& CPoleWeights)
{
  const TColgp_Array2OfPnt & Poles = poles->Array2();
  if (VIndex < 1 || VIndex > Poles.RowLength())  Standard_OutOfRange::Raise();
  if (CPoles.Length() != Poles.ColLength() ||
      CPoleWeights.Length() != CPoles.Length()) {
    Standard_ConstructionError::Raise();
    }
  Standard_Integer Index = CPoleWeights.Lower();
  while (Index <= CPoleWeights.Upper()) {
    if (CPoleWeights (Index) <= gp::Resolution()) {
      Standard_ConstructionError::Raise();
      }
    Index++;
  }

  Handle(TColgp_HArray2OfPnt) npoles =
    new TColgp_HArray2OfPnt(1,poles->ColLength(),1,poles->RowLength()+1);
  
  Handle(TColStd_HArray2OfReal) nweights = 
    new TColStd_HArray2OfReal(1,poles->ColLength(),1,poles->RowLength()+1);
  
  AddRatPoleCol (poles->Array2(), weights->Array2(),
             CPoles, CPoleWeights, VIndex,
             npoles->ChangeArray2(), nweights->ChangeArray2());

  poles   = npoles;
  weights = nweights;
  coeffs  = new TColgp_HArray2OfPnt(1,poles->ColLength(),
                            1,poles->RowLength());
  wcoeffs = new TColStd_HArray2OfReal(1,poles->ColLength(),
                              1,poles->RowLength());

  Rational(weights->Array2(), urational, vrational);

  UpdateCoefficients();
}

//=======================================================================
//function : InsertPoleColBefore
//purpose  : 
//=======================================================================

00728 void Geom_BezierSurface::InsertPoleColBefore (const Standard_Integer VIndex,
                                    const TColgp_Array1OfPnt& CPoles)
{
  InsertPoleColAfter(VIndex - 1, CPoles);
}

//=======================================================================
//function : InsertPoleColBefore
//purpose  : 
//=======================================================================

void Geom_BezierSurface::InsertPoleColBefore
00740   (const Standard_Integer      VIndex,
   const TColgp_Array1OfPnt&   CPoles,
   const TColStd_Array1OfReal& CPoleWeights)
{
  InsertPoleColAfter( VIndex - 1, CPoles, CPoleWeights);
}

//=======================================================================
//function : InsertPoleRowAfter
//purpose  : 
//=======================================================================

00752 void Geom_BezierSurface::InsertPoleRowAfter (const Standard_Integer UIndex,
                                   const TColgp_Array1OfPnt& CPoles)
{
  const TColgp_Array2OfPnt & Poles = poles->Array2();
  if (UIndex < 1 || UIndex > Poles.ColLength())  Standard_OutOfRange::Raise();
  if (CPoles.Length() != Poles.RowLength()) {
    Standard_ConstructionError::Raise();
  }

  Handle(TColgp_HArray2OfPnt) npoles =
    new TColgp_HArray2OfPnt(1,poles->ColLength()+1,1,poles->RowLength());

  Handle(TColStd_HArray2OfReal) nweights;

  if (urational || vrational) {
    nweights = 
      new TColStd_HArray2OfReal(1,poles->ColLength()+1,1,poles->RowLength());

//    TColStd_Array1OfReal CWeights(nweights->LowerCol(),nweights->UpperCol(),
//                        1.0); ???????????
    TColStd_Array1OfReal CWeights(1.0,
                                  nweights->LowerCol(),nweights->UpperCol());

    AddRatPoleRow (poles->Array2(), weights->Array2(),
               CPoles, CWeights, UIndex,
               npoles->ChangeArray2(), nweights->ChangeArray2());
  }
  else {
    AddPoleRow (poles->Array2(), 
            CPoles, UIndex,
            npoles->ChangeArray2());
  }
  poles   = npoles;
  weights = nweights;
  coeffs  = new TColgp_HArray2OfPnt(1,poles->ColLength(),
                            1,poles->RowLength());
  wcoeffs = new TColStd_HArray2OfReal(1,poles->ColLength(),
                              1,poles->RowLength());

  UpdateCoefficients();
}

//=======================================================================
//function : InsertPoleRowAfter
//purpose  : 
//=======================================================================

void Geom_BezierSurface::InsertPoleRowAfter
00800   (const Standard_Integer      UIndex,
   const TColgp_Array1OfPnt&   CPoles,
   const TColStd_Array1OfReal& CPoleWeights)
{
  const TColgp_Array2OfPnt & Poles = poles->Array2();
  if (UIndex < 1 || UIndex > Poles.ColLength())  Standard_OutOfRange::Raise();
  if (CPoles.Length() != Poles.RowLength() ||
      CPoleWeights.Length() != CPoles.Length()) {
    Standard_ConstructionError::Raise();
  }
  Standard_Integer Index = CPoleWeights.Lower();
  while (Index <= CPoleWeights.Upper()) {
    if (CPoleWeights(Index) <= gp::Resolution()) {
      Standard_ConstructionError::Raise();
    }
    Index++;
  }

  Handle(TColgp_HArray2OfPnt) npoles =
    new TColgp_HArray2OfPnt(1,poles->ColLength()+1,1,poles->RowLength());
  
  Handle(TColStd_HArray2OfReal) nweights = 
    new TColStd_HArray2OfReal(1,poles->ColLength()+1,1,poles->RowLength());
  
  AddRatPoleCol (poles->Array2(), weights->Array2(),
             CPoles, CPoleWeights, UIndex,
             npoles->ChangeArray2(), nweights->ChangeArray2());

  poles   = npoles;
  weights = nweights;
  coeffs  = new TColgp_HArray2OfPnt(1,poles->ColLength(),
                            1,poles->RowLength());
  wcoeffs = new TColStd_HArray2OfReal(1,poles->ColLength(),
                              1,poles->RowLength());  

  Rational(weights->Array2(), urational, vrational);

  UpdateCoefficients();
}

//=======================================================================
//function : InsertPoleRowBefore
//purpose  : 
//=======================================================================

00845 void Geom_BezierSurface::InsertPoleRowBefore (const Standard_Integer UIndex,
                                    const TColgp_Array1OfPnt& CPoles)
{
  InsertPoleRowAfter( UIndex - 1, CPoles);
}

//=======================================================================
//function : InsertPoleRowBefore
//purpose  : 
//=======================================================================

void Geom_BezierSurface::InsertPoleRowBefore
00857   (const Standard_Integer      UIndex, 
   const TColgp_Array1OfPnt&   CPoles,
   const TColStd_Array1OfReal& CPoleWeights)
{
  InsertPoleRowAfter( UIndex - 1, CPoles, CPoleWeights);
} 

//=======================================================================
//function : RemovePoleCol
//purpose  : 
//=======================================================================

00869 void Geom_BezierSurface::RemovePoleCol (const Standard_Integer VIndex)
{
  const TColgp_Array2OfPnt & Poles = poles->Array2();
  if (VIndex < 1 || VIndex > Poles.RowLength())  Standard_OutOfRange::Raise(); 
  if (Poles.RowLength() <= 2)             Standard_ConstructionError::Raise();

  Handle(TColgp_HArray2OfPnt) npoles =
    new TColgp_HArray2OfPnt(1,poles->ColLength(),1,poles->RowLength()-1);

  Handle(TColStd_HArray2OfReal) nweights;

  if (urational || vrational) {
    nweights = 
      new TColStd_HArray2OfReal(1,poles->ColLength(),1,poles->RowLength()-1);

    DeleteRatPoleCol (poles->Array2(), weights->Array2(),
                  VIndex,
                  npoles->ChangeArray2(), nweights->ChangeArray2());
    // Mise a jour de la rationalite
    Rational(nweights->Array2(), urational, vrational);
  }
  else {
    DeletePoleCol (poles->Array2(), 
               VIndex,
               npoles->ChangeArray2());
  }
  poles   = npoles;
  weights = nweights;
  coeffs  = new TColgp_HArray2OfPnt(1,poles->ColLength(),
                            1,poles->RowLength());
  wcoeffs = new TColStd_HArray2OfReal(1,poles->ColLength(),
                              1,poles->RowLength());
  UpdateCoefficients(); 
}

//=======================================================================
//function : RemovePoleRow
//purpose  : 
//=======================================================================

00909 void Geom_BezierSurface::RemovePoleRow (const Standard_Integer UIndex)
{
  const TColgp_Array2OfPnt & Poles = poles->Array2();
  if (UIndex < 1 || UIndex > Poles.ColLength()) Standard_OutOfRange::Raise();
  if (Poles.ColLength() <= 2)            Standard_ConstructionError::Raise();

  Handle(TColgp_HArray2OfPnt) npoles =
    new TColgp_HArray2OfPnt(1,poles->ColLength()-1,1,poles->RowLength());

  Handle(TColStd_HArray2OfReal) nweights;

  if (urational || vrational) {
    nweights = 
      new TColStd_HArray2OfReal(1,poles->ColLength()-1,1,poles->RowLength());

    DeleteRatPoleRow (poles->Array2(), weights->Array2(),
                  UIndex,
                  npoles->ChangeArray2(), nweights->ChangeArray2());

    // Mise a jour de la rationalite
    Rational(nweights->Array2(), urational, vrational);
  }
  else {
    DeletePoleRow (poles->Array2(), 
               UIndex,
               npoles->ChangeArray2());
  }
  poles   = npoles;
  weights = nweights;
  coeffs  = new TColgp_HArray2OfPnt(1,poles->ColLength(),
                            1,poles->RowLength());
  wcoeffs = new TColStd_HArray2OfReal(1,poles->ColLength(),
                              1,poles->RowLength());
  UpdateCoefficients();
}

//=======================================================================
//function : Segment
//purpose  : 
//=======================================================================

void Geom_BezierSurface::Segment
00951   (const Standard_Real U1,
   const Standard_Real U2,
   const Standard_Real V1,
   const Standard_Real V2)
{
  Standard_Boolean rat = (urational || vrational);
  Handle(TColgp_HArray2OfPnt)  Coefs;
  Handle(TColStd_HArray2OfReal) WCoefs;
  
  if (validcache == 0) UpdateCoefficients(0., 0.);

  // Attention si udeg <= vdeg u et v sont intervertis 
  // dans les coeffs, il faut donc tout transposer.
  if(UDegree() <= VDegree()) {
    Standard_Integer ii, jj;
    Coefs = new  (TColgp_HArray2OfPnt)(1,UDegree()+1,1,VDegree()+1);
    if (rat) {
      WCoefs = new  (TColStd_HArray2OfReal)(1,UDegree()+1,1,VDegree()+1);
    }
    for (ii=1; ii<=UDegree()+1; ii++)
      for (jj=1; jj<=VDegree()+1; jj++) {
      Coefs->SetValue(ii, jj, coeffs->Value(jj,ii));
      if (rat)  WCoefs->SetValue(ii, jj, wcoeffs->Value(jj,ii));
      }
  }
  else {
   Coefs = coeffs;
   if (rat)  {WCoefs =  wcoeffs;}
 }

// Trim dans la base cannonique et Update des Poles et Coeffs

// PMN : tranfo sur les parametres
  Standard_Real ufirst = 2*(U1 - 0.5),
                ulast =  2*(U2 - 0.5),
                vfirst = 2*(V1 - 0.5),
                vlast  = 2*(V2 - 0.5);
  if (rat) {
    PLib::UTrimming (ufirst, ulast, Coefs->ChangeArray2(),
                 WCoefs->ChangeArray2());
    PLib::VTrimming (vfirst, vlast, Coefs->ChangeArray2(),
                 WCoefs->ChangeArray2());
    PLib::CoefficientsPoles(Coefs->Array2(),
                      WCoefs->Array2(),
                      poles->ChangeArray2(),
                      weights->ChangeArray2());
  }
  else {
    PLib::UTrimming (ufirst, ulast, Coefs->ChangeArray2(),
                 *((TColStd_Array2OfReal*) NULL));
    PLib::VTrimming (vfirst, vlast, Coefs->ChangeArray2(),
                 *((TColStd_Array2OfReal*) NULL));
    PLib::CoefficientsPoles (Coefs->Array2(),
                       *((TColStd_Array2OfReal*) NULL),
                       poles->ChangeArray2(),
                       *((TColStd_Array2OfReal*) NULL));
  }
  UpdateCoefficients();
}

//=======================================================================
//function : SetPole
//purpose  : 
//=======================================================================

void Geom_BezierSurface::SetPole
01017   (const Standard_Integer UIndex,
   const Standard_Integer VIndex,
   const gp_Pnt&          P)
{
  TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
  if (UIndex < 1                 ||
      UIndex > Poles.ColLength() ||
      VIndex < 1                 ||
      VIndex > Poles.RowLength() )    Standard_OutOfRange::Raise();
  
#ifdef DEB
  TColgp_Array2OfPnt & Coefs = coeffs->ChangeArray2();
#else
  coeffs->ChangeArray2();
#endif
  Poles (UIndex, VIndex) = P;
  UpdateCoefficients();
}

//=======================================================================
//function : SetPole
//purpose  : 
//=======================================================================

void Geom_BezierSurface::SetPole
01042   (const Standard_Integer UIndex,
   const Standard_Integer VIndex, 
   const gp_Pnt&          P,
   const Standard_Real    Weight)
{

  if (Weight <= gp::Resolution())     
    Standard_ConstructionError::Raise("Geom_BezierSurface::SetPole");
  if (UIndex < 1                 || 
      UIndex > poles->ColLength() ||
      VIndex < 1                 ||
      VIndex > poles->RowLength())    
    Standard_OutOfRange::Raise("Geom_BezierSurface::SetPole");

  poles->SetValue(UIndex, VIndex, P);
  
  SetWeight(UIndex, VIndex,  Weight); //L'update des coeff est fait la dedans
}

//=======================================================================
//function : SetPoleCol
//purpose  : 
//=======================================================================

void Geom_BezierSurface::SetPoleCol
01067   (const Standard_Integer      VIndex,
   const TColgp_Array1OfPnt&   CPoles,
   const TColStd_Array1OfReal& CPoleWeights)
{
  TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
  if (VIndex < 1 || VIndex > Poles.RowLength()) Standard_OutOfRange::Raise();

  if (CPoles.Lower() < 1                     || 
      CPoles.Lower() > Poles.ColLength()     || 
      CPoles.Upper() < 1                     || 
      CPoles.Upper() > Poles.ColLength()     ||
      CPoleWeights.Lower() != CPoles.Lower() ||
      CPoleWeights.Upper() != CPoles.Upper()) {
    Standard_ConstructionError::Raise();
  }
     
  Standard_Integer I;
  for (I = CPoles.Lower();  I <= CPoles.Upper(); I++) {
    Poles (I, VIndex) = CPoles (I);
  }
  SetWeightCol(VIndex, CPoleWeights); //Avec l'update
}

//=======================================================================
//function : SetPoleCol
//purpose  : 
//=======================================================================

01095 void Geom_BezierSurface::SetPoleCol (const Standard_Integer      VIndex,
                             const TColgp_Array1OfPnt&   CPoles)
{
  TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
  if (VIndex < 1 || VIndex > Poles.RowLength())  Standard_OutOfRange::Raise();

  if (CPoles.Lower() < 1                 || 
      CPoles.Lower() > Poles.ColLength() || 
      CPoles.Upper() < 1                 ||
      CPoles.Upper() > Poles.ColLength()) {
    Standard_ConstructionError::Raise();
  }
#ifdef DEB
  TColgp_Array2OfPnt & Coefs = coeffs->ChangeArray2();
#else
  coeffs->ChangeArray2();
#endif
  for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
    Poles (I, VIndex) = CPoles (I);
  }

  UpdateCoefficients();
}

//=======================================================================
//function : SetPoleRow
//purpose  : 
//=======================================================================

01124 void Geom_BezierSurface::SetPoleRow (const Standard_Integer    UIndex,
                             const TColgp_Array1OfPnt& CPoles)
{
  TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
  if (UIndex < 1 || UIndex > Poles.ColLength())  Standard_OutOfRange::Raise();

  if (CPoles.Lower() < 1                 ||
      CPoles.Lower() > Poles.RowLength() || 
      CPoles.Upper() < 1                 || 
      CPoles.Upper() > Poles.RowLength())  Standard_ConstructionError::Raise();

#ifdef DEB
  TColgp_Array2OfPnt & Coefs = coeffs->ChangeArray2();
#else
  coeffs->ChangeArray2();
#endif
  for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
    Poles (UIndex, I) = CPoles (I);
  }
  UpdateCoefficients();
}

//=======================================================================
//function : SetPoleRow
//purpose  : 
//=======================================================================

void Geom_BezierSurface::SetPoleRow
01152   (const Standard_Integer      UIndex,
   const TColgp_Array1OfPnt&   CPoles,
   const TColStd_Array1OfReal& CPoleWeights)
{
  TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
  if (UIndex < 1 || UIndex > Poles.ColLength())   Standard_OutOfRange::Raise();

  if (CPoles.Lower() < 1                     || 
      CPoles.Lower() > Poles.RowLength()     || 
      CPoles.Upper() < 1                     || 
      CPoles.Upper() > Poles.RowLength()     ||
      CPoleWeights.Lower() != CPoles.Lower() ||
      CPoleWeights.Upper() != CPoles.Upper()) {
    Standard_ConstructionError::Raise();
  }

  Standard_Integer I;

  for (I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
    Poles   (UIndex, I) = CPoles (I);
  }
  
  SetWeightRow(UIndex, CPoleWeights); //Avec l'update 
}

//=======================================================================
//function : SetWeight
//purpose  : 
//=======================================================================

01182 void Geom_BezierSurface::SetWeight (const Standard_Integer UIndex,
                            const Standard_Integer VIndex,
                            const Standard_Real    Weight)
{
   // compute new rationality
  Standard_Boolean wasrat = (urational||vrational);
  if (!wasrat) {
    // a weight of 1. does not turn to rational
    if (Abs(Weight - 1.) <= gp::Resolution()) {
      UpdateCoefficients(); //Pour l'appel via SetPole 
      return;
    }
    
    // set weights of 1.
    weights = new TColStd_HArray2OfReal (1, poles->ColLength(),
                               1, poles->RowLength(), 1.);
    wcoeffs = new TColStd_HArray2OfReal (1, poles->ColLength(),
                               1, poles->RowLength());
  }

  TColStd_Array2OfReal & Weights = weights->ChangeArray2();
  if (Weight <= gp::Resolution())      
    Standard_ConstructionError::Raise("Geom_BezierSurface::SetWeight");

  if (UIndex < 1                   || 
      UIndex > Weights.ColLength() ||
      VIndex < 1                   || 
      VIndex > Weights.RowLength())    Standard_OutOfRange::Raise();

#ifdef DEB
  const TColgp_Array2OfPnt & Poles  = poles->Array2();
#else
  poles->Array2();
#endif
#ifdef DEB
  TColgp_Array2OfPnt       & Coefs  = coeffs->ChangeArray2();
#else
  coeffs->ChangeArray2();
#endif
#ifdef DEB
  TColStd_Array2OfReal     & WCoefs = wcoeffs->ChangeArray2();
#else
  wcoeffs->ChangeArray2();
#endif

  if (Abs (Weight - Weights (UIndex, VIndex)) > gp::Resolution()) {
    Weights (UIndex, VIndex) = Weight;
    Rational(Weights, urational, vrational);
    }

 // is it turning into non rational
  if (wasrat) {
    if (!(urational || vrational)) {
      weights.Nullify();
      wcoeffs.Nullify();
    }
  }

  UpdateCoefficients(); //Dans tous cas :Attention a SetPoleCol !
}

//=======================================================================
//function : SetWeightCol
//purpose  : 
//=======================================================================

void Geom_BezierSurface::SetWeightCol 
01249   (const Standard_Integer      VIndex,
   const TColStd_Array1OfReal& CPoleWeights)
{
  Standard_Integer I;
   // compute new rationality
  Standard_Boolean wasrat = (urational||vrational);
  if (!wasrat) {   
    // set weights of 1.
    weights = new TColStd_HArray2OfReal (1, poles->ColLength(),
                               1, poles->RowLength(), 1.);
    wcoeffs = new TColStd_HArray2OfReal (1, poles->ColLength(),
                               1, poles->RowLength());
  }

  TColStd_Array2OfReal & Weights = weights->ChangeArray2();
  if (VIndex < 1 || VIndex > Weights.RowLength()) Standard_OutOfRange::Raise();

  if (CPoleWeights.Length() !=  Weights.ColLength())  {
    Standard_ConstructionError::Raise("Geom_BezierSurface::SetWeightCol");
  }

#ifdef DEB
  const TColgp_Array2OfPnt & Poles  = poles->Array2();
#else
  poles->Array2();
#endif
#ifdef DEB
  TColgp_Array2OfPnt       & Coefs  = coeffs->ChangeArray2();
#else
  coeffs->ChangeArray2();
#endif
#ifdef DEB
  TColStd_Array2OfReal     & WCoefs = wcoeffs->ChangeArray2();
#else
  wcoeffs->ChangeArray2();
#endif

  I = CPoleWeights.Lower();
  while (I <= CPoleWeights.Upper()) {
    if (CPoleWeights(I) <= gp::Resolution()) {
      Standard_ConstructionError::Raise();
    }
    Weights (I, VIndex) = CPoleWeights (I);
    I++;
  }

 Rational(Weights, urational, vrational);

 // is it turning into non rational
  if (wasrat) {
    if (!(urational || vrational)) {
      weights.Nullify();
      wcoeffs.Nullify();
    }
  }

  UpdateCoefficients();
}

//=======================================================================
//function : SetWeightRow
//purpose  : 
//=======================================================================

void Geom_BezierSurface::SetWeightRow 
01314   (const Standard_Integer      UIndex,
   const TColStd_Array1OfReal& CPoleWeights)
{
  Standard_Integer I;
   // compute new rationality
  Standard_Boolean wasrat = (urational||vrational);
  if (!wasrat) {    
    // set weights of 1.
    weights = new TColStd_HArray2OfReal (1, poles->ColLength(),
                               1, poles->RowLength(), 1.);
    wcoeffs = new TColStd_HArray2OfReal (1, poles->ColLength(),
                               1, poles->RowLength());
  }

  TColStd_Array2OfReal & Weights = weights->ChangeArray2();
  if (UIndex < 1 || UIndex > Weights.ColLength()) 
    Standard_OutOfRange::Raise("Geom_BezierSurface::SetWeightRow");
  if (CPoleWeights.Lower() < 1 ||
      CPoleWeights.Lower() > Weights.RowLength() ||
      CPoleWeights.Upper() < 1 ||
      CPoleWeights.Upper() > Weights.RowLength()  ) {
    Standard_ConstructionError::Raise("Geom_BezierSurface::SetWeightRow");
  }

#ifdef DEB
  const TColgp_Array2OfPnt & Poles  = poles->Array2();
#else
  poles->Array2();
#endif
#ifdef DEB
  TColgp_Array2OfPnt       & Coefs  = coeffs->ChangeArray2();
#else
  coeffs->ChangeArray2();
#endif
#ifdef DEB
  TColStd_Array2OfReal     & WCoefs = wcoeffs->ChangeArray2();
#else
  wcoeffs->ChangeArray2();
#endif

  I = CPoleWeights.Lower();
  while (I <= CPoleWeights.Upper()) {
    if (CPoleWeights(I) <= gp::Resolution())  {
      Standard_ConstructionError::Raise();
    }
    Weights (UIndex, I) = CPoleWeights (I);
    I++;
  }

  Rational(Weights, urational, vrational);

 // is it turning into non rational
  if (wasrat) {
    if (!(urational || vrational)) {
      weights.Nullify();
      wcoeffs.Nullify();
    }
  }

  UpdateCoefficients();
}

//=======================================================================
//function : UReverse
//purpose  : 
//=======================================================================

01381 void Geom_BezierSurface::UReverse ()
{
  gp_Pnt Pol;
  Standard_Integer Row,Col;
  TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
#ifdef DEB
  TColgp_Array2OfPnt & Coefs = coeffs->ChangeArray2();
#else
  coeffs->ChangeArray2();
#endif
  if (urational || vrational) {
    TColStd_Array2OfReal & Weights = weights->ChangeArray2();
#ifdef DEB
    TColStd_Array2OfReal & WCoefs  = wcoeffs->ChangeArray2();
#else
    wcoeffs->ChangeArray2();
#endif
    Standard_Real W;
    for (Col = 1; Col <= Poles.RowLength(); Col++) {
      for (Row = 1; Row <= IntegerPart (Poles.ColLength() / 2); Row++) {
        W = Weights (Row, Col);
        Weights (Row, Col) = Weights (Poles.ColLength()- Row + 1, Col);
        Weights (Poles.ColLength() - Row + 1, Col) = W;
        Pol = Poles (Row, Col);
        Poles (Row, Col) = Poles (Poles.ColLength() - Row + 1, Col);
        Poles (Poles.ColLength() - Row + 1, Col) = Pol;
      }
    }
  }
  else {
    for (Col = 1; Col <= Poles.RowLength(); Col++) {
      for (Row = 1; Row <= IntegerPart (Poles.ColLength() / 2); Row++) {
        Pol = Poles (Row, Col);
        Poles (Row, Col) = Poles (Poles.ColLength() - Row + 1, Col);
        Poles (Poles.ColLength() - Row + 1, Col) = Pol;
      }
    }
  }
  UpdateCoefficients();
}

//=======================================================================
//function : UReversedParameter
//purpose  : 
//=======================================================================

Standard_Real Geom_BezierSurface::UReversedParameter
01428   ( const Standard_Real U) const 
{
  return ( 1. - U);
}

//=======================================================================
//function : VReverse
//purpose  : 
//=======================================================================

01438 void Geom_BezierSurface::VReverse ()
{
  gp_Pnt Pol;
  Standard_Integer Row,Col;
  TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
#ifdef DEB
  TColgp_Array2OfPnt & Coefs = coeffs->ChangeArray2();
#else
  coeffs->ChangeArray2();
#endif
  if (urational || vrational) {
    TColStd_Array2OfReal & Weights = weights->ChangeArray2();
#ifdef DEB
    TColStd_Array2OfReal & WCoefs  = wcoeffs->ChangeArray2();
#else
    wcoeffs->ChangeArray2();
#endif
    Standard_Real W;
    for (Row = 1; Row <= Poles.ColLength(); Row++) {
      for (Col = 1; Col <= IntegerPart (Poles.RowLength()/2); Col++) {
        W = Weights (Row, Col);
        Weights (Row, Col) = Weights (Row, Poles.RowLength() - Col + 1);
        Weights (Row, Poles.RowLength() - Col + 1) = W;
        Pol = Poles (Row, Col);
        Poles (Row, Col) = Poles (Row, Poles.RowLength() - Col + 1);
        Poles (Row, Poles.RowLength() - Col + 1) = Pol;
      }
    }
  }
  else {
    for (Row = 1; Row <= Poles.ColLength(); Row++) {
      for (Col = 1; Col <= IntegerPart(Poles.RowLength()/2); Col++) {
        Pol = Poles (Row, Col);
        Poles (Row, Col)= Poles (Row, Poles.RowLength() - Col + 1);
        Poles (Row, Poles.RowLength() - Col + 1) = Pol;
      }
    }
  }
  UpdateCoefficients();
}

//=======================================================================
//function : VReversedParameter
//purpose  : 
//=======================================================================

Standard_Real Geom_BezierSurface::VReversedParameter
01485   ( const Standard_Real V) const 
{
  return ( 1. - V);
}

//=======================================================================
//function : Bounds
//purpose  : 
//=======================================================================

01495 void Geom_BezierSurface::Bounds (Standard_Real& U1,
                         Standard_Real& U2,
                         Standard_Real& V1,
                         Standard_Real& V2) const
{
  U1 = 0.0;  
  U2 = 1.0; 
  V1 = 0.0;
  V2 = 1.0;
}

//=======================================================================
//function : Continuity
//purpose  : 
//=======================================================================

01511 GeomAbs_Shape Geom_BezierSurface::Continuity () const
{
  return GeomAbs_CN; 
}

//=======================================================================
//function : D0
//purpose  : 
//=======================================================================

01521 void Geom_BezierSurface::D0 (const Standard_Real U,
                       const Standard_Real V,
                             gp_Pnt&       P ) const
{

  if (validcache == 1) {
    //
    // XAB : cet algorithme devient instable pour les hauts degres
    // RBD : Beaucoup moins maintenant avec le calcul d'un nouveau cache
    //       sur [-1,1].
    //
    Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
                  uspanlenght_11 = ucachespanlenght/2,
                  vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
                  vspanlenght_11 = vcachespanlenght/2 ;
    if (urational || vrational) { 
      BSplSLib::CacheD0(U, V, UDegree(), VDegree(), 
                  uparameter_11, vparameter_11,
                  uspanlenght_11, vspanlenght_11,
                  coeffs->Array2(),
                  wcoeffs->Array2(),
                  P);
    }
    else { 
      BSplSLib::CacheD0(U, V, UDegree(), VDegree(), 
                  uparameter_11, vparameter_11,
                  uspanlenght_11, vspanlenght_11,
                  coeffs->Array2(),
                  *((TColStd_Array2OfReal*) NULL),
                  P);
    }
  }
  else {
    Standard_Real array_u[2] ;
    Standard_Real array_v[2] ;
    Standard_Integer mult_u[2] ;
    Standard_Integer mult_v[2] ;
    TColStd_Array1OfReal biduknots(array_u[0],1,2); biduknots(1) = 0.; biduknots(2) = 1.;
    TColStd_Array1OfInteger bidumults(mult_u[0],1,2); bidumults.Init(UDegree() + 1);
    TColStd_Array1OfReal bidvknots(array_v[0],1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
    TColStd_Array1OfInteger bidvmults(mult_v[0],1,2); bidvmults.Init(VDegree() + 1);
    if (urational || vrational) { 
        BSplSLib::D0(U, V, 1,1,poles->Array2(),
                 weights->Array2(),
                 biduknots,bidvknots,bidumults,bidvmults,
                 UDegree(),VDegree(),
                 urational,vrational,Standard_False,Standard_False,
                 P) ;
    }
    else {
      
      BSplSLib::D0(U, V, 1,1,poles->Array2(),
               *((TColStd_Array2OfReal*) NULL),
               biduknots,bidvknots,bidumults,bidvmults,
               UDegree(),VDegree(),
               urational,vrational,Standard_False,Standard_False,
               P) ;
    }
  }
}

//=======================================================================
//function : D1
//purpose  : 
//=======================================================================

void Geom_BezierSurface::D1
01588   (const Standard_Real U,
   const Standard_Real V,
         gp_Pnt&       P,
         gp_Vec&       D1U,
         gp_Vec&       D1V ) const
{

  if (validcache == 1) {
    //
    // XAB : cet algorithme devient instable pour les hauts degres
    // RBD : Beaucoup moins maintenant avec le calcul d'un nouveau cache
    //       sur [-1,1].
    //
    Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
                  uspanlenght_11 = ucachespanlenght/2,
                  vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
                  vspanlenght_11 = vcachespanlenght/2 ;
   if (urational || vrational) { 
     BSplSLib::CacheD1(U, V, UDegree(), VDegree(), 
                   uparameter_11, vparameter_11,
                   uspanlenght_11, vspanlenght_11,
                   coeffs->Array2(),
                   wcoeffs->Array2(), 
                   P, D1U, D1V);
   }
   else { 
     BSplSLib::CacheD1(U, V, UDegree(), VDegree(), 
                   uparameter_11, vparameter_11,
                   uspanlenght_11, vspanlenght_11,
                   coeffs->Array2(),
                   *((TColStd_Array2OfReal*) NULL), 
                   P, D1U, D1V);
   }
  }
  else {
    Standard_Real array_u[2] ;
    Standard_Real array_v[2] ;
    Standard_Integer mult_u[2] ;
    Standard_Integer mult_v[2] ;
    TColStd_Array1OfReal biduknots(array_u[0],1,2); biduknots(1) = 0.; biduknots(2) = 1.;
    TColStd_Array1OfInteger bidumults(mult_u[0],1,2); bidumults.Init(UDegree() + 1);
    TColStd_Array1OfReal bidvknots(array_v[0],1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
    TColStd_Array1OfInteger bidvmults(mult_v[0],1,2); bidvmults.Init(VDegree() + 1);
    if (urational || vrational) { 
      BSplSLib::D1(U, V, 1,1,poles->Array2(),
               weights->Array2(),
               biduknots,bidvknots,bidumults,bidvmults,
               UDegree(),VDegree(),
               urational,vrational,Standard_False,Standard_False,
               P,D1U, D1V) ;
    }
    else {
      BSplSLib::D1(U, V, 1,1,poles->Array2(),
               *((TColStd_Array2OfReal*) NULL),
               biduknots,bidvknots,bidumults,bidvmults,
               UDegree(),VDegree(),
               urational,vrational,Standard_False,Standard_False,
               P,D1U, D1V) ;
    }
  }
}

//=======================================================================
//function : D2
//purpose  : 
//=======================================================================

void Geom_BezierSurface::D2
01656   (const Standard_Real U,
   const Standard_Real V,
         gp_Pnt&       P,
         gp_Vec&       D1U, gp_Vec& D1V, 
         gp_Vec&       D2U, gp_Vec& D2V, gp_Vec& D2UV ) const
{

  if (validcache == 1) {
    //
    // XAB : cet algorithme devient instable pour les hauts degres
    // RBD : Beaucoup moins maintenant avec le calcul d'un nouveau cache
    //       sur [-1,1].
    //
    Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
                  uspanlenght_11 = ucachespanlenght/2,
                  vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
                  vspanlenght_11 = vcachespanlenght/2 ;
    if (urational || vrational) { 
      //-- ATTENTION a l'ORDRE d'appel ds BSPLSLIB 
      BSplSLib::CacheD2(U, V, UDegree(), VDegree(), 
                  uparameter_11, vparameter_11,
                  uspanlenght_11, vspanlenght_11,
                  coeffs->Array2(),
                  wcoeffs->Array2(), 
                  P, D1U, D1V, D2U, D2UV , D2V);
    }
    else { 
      //-- ATTENTION a l'ORDRE d'appel ds BSPLSLIB 
      BSplSLib::CacheD2(U, V, UDegree(), VDegree(), 
                  uparameter_11, vparameter_11,
                  uspanlenght_11, vspanlenght_11,
                  coeffs->Array2(),
                  *((TColStd_Array2OfReal*) NULL), 
                  P, D1U, D1V, D2U, D2UV , D2V);
    }
  }
  else {
    Standard_Real array_u[2] ;
    Standard_Real array_v[2] ;
    Standard_Integer mult_u[2] ;
    Standard_Integer mult_v[2] ;
    TColStd_Array1OfReal biduknots(array_u[0],1,2); biduknots(1) = 0.; biduknots(2) = 1.;
    TColStd_Array1OfInteger bidumults(mult_u[0],1,2); bidumults.Init(UDegree() + 1);
    TColStd_Array1OfReal bidvknots(array_v[0],1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
    TColStd_Array1OfInteger bidvmults(mult_v[0],1,2); bidvmults.Init(VDegree() + 1);
    if (urational || vrational) { 
      //-- ATTENTION a l'ORDRE d'appel ds BSPLSLIB 
      BSplSLib::D2(U, V, 1,1,poles->Array2(),
               weights->Array2(),
               biduknots,bidvknots,bidumults,bidvmults,
               UDegree(),VDegree(),
               urational,vrational,Standard_False,Standard_False,
               P,D1U, D1V, D2U, D2V , D2UV) ;
    }
    else {
      //-- ATTENTION a l'ORDRE d'appel ds BSPLSLIB 
      BSplSLib::D2(U, V, 1,1,poles->Array2(),
               *((TColStd_Array2OfReal*) NULL),
               biduknots,bidvknots,bidumults,bidvmults,
               UDegree(),VDegree(),
               urational,vrational,Standard_False,Standard_False,
               P,D1U, D1V, D2U, D2V, D2UV ) ;
    }
  }
}

//=======================================================================
//function : D3
//purpose  : 
//=======================================================================

void Geom_BezierSurface::D3
01728   (const Standard_Real U, const Standard_Real V,
   gp_Pnt& P,
   gp_Vec& D1U, gp_Vec& D1V, 
   gp_Vec& D2U, gp_Vec& D2V, gp_Vec& D2UV, 
   gp_Vec& D3U, gp_Vec& D3V, gp_Vec& D3UUV, gp_Vec& D3UVV) const
{
  TColStd_Array1OfReal biduknots(1,2); biduknots(1) = 0.; biduknots(2) = 1.;
  TColStd_Array1OfInteger bidumults(1,2); bidumults.Init(UDegree() + 1);
  TColStd_Array1OfReal bidvknots(1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
  TColStd_Array1OfInteger bidvmults(1,2); bidvmults.Init(VDegree() + 1);
  if (urational || vrational) { 
    BSplSLib::D3 (U, V, 0, 0, poles->Array2(),
              weights->Array2(),
              biduknots, bidvknots, bidumults, bidvmults,
              UDegree(), VDegree(), urational, vrational, 0, 0,
              P,
              D1U, D1V,
              D2U, D2V, D2UV,
              D3U, D3V, D3UUV, D3UVV);
  }
  else { 
    BSplSLib::D3 (U, V, 0, 0, poles->Array2(),
              *((TColStd_Array2OfReal*) NULL),
              biduknots, bidvknots, bidumults, bidvmults,
              UDegree(), VDegree(), urational, vrational, 0, 0,
              P,
              D1U, D1V,
              D2U, D2V, D2UV,
              D3U, D3V, D3UUV, D3UVV);
  }
}

//=======================================================================
//function : DN
//purpose  : 
//=======================================================================

gp_Vec Geom_BezierSurface::DN
01766   (const Standard_Real    U,
   const Standard_Real    V,
   const Standard_Integer Nu,
   const Standard_Integer Nv) const
{
  Standard_RangeError_Raise_if (Nu + Nv < 1 || Nv < 0 || Nu <0, " ");
  gp_Vec Derivative;
  TColStd_Array1OfReal biduknots(1,2); biduknots(1) = 0.; biduknots(2) = 1.;
  TColStd_Array1OfInteger bidumults(1,2); bidumults.Init(UDegree() + 1);
  TColStd_Array1OfReal bidvknots(1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
  TColStd_Array1OfInteger bidvmults(1,2); bidvmults.Init(VDegree() + 1);
  if (urational || vrational) { 
    BSplSLib::DN (U, V, Nu, Nv, 0, 0, poles->Array2(),
              weights->Array2(),
              biduknots, bidvknots, bidumults, bidvmults,
              UDegree(), VDegree(), urational, vrational, 0, 0,
              Derivative);
  }
  else { 
    BSplSLib::DN (U, V, Nu, Nv, 0, 0, poles->Array2(),
              *((TColStd_Array2OfReal*) NULL),
              biduknots, bidvknots, bidumults, bidvmults,
              UDegree(), VDegree(), urational, vrational, 0, 0,
              Derivative);
  }
  return Derivative;
}

//=======================================================================
//function : NbUPoles
//purpose  : 
//=======================================================================

01799 Standard_Integer Geom_BezierSurface::NbUPoles () const
{
  return poles->ColLength(); 
}

//=======================================================================
//function : NbVPoles
//purpose  : 
//=======================================================================

01809 Standard_Integer Geom_BezierSurface::NbVPoles () const
{
  return poles->RowLength(); 
}

//=======================================================================
//function : Pole
//purpose  : 
//=======================================================================

01819 gp_Pnt Geom_BezierSurface::Pole (const Standard_Integer UIndex,
                         const Standard_Integer VIndex) const
{
  Standard_OutOfRange_Raise_if
    (UIndex < 1 || UIndex > poles->ColLength() ||
     VIndex < 1 || VIndex > poles->RowLength(), " ");
  return poles->Value (UIndex + poles->LowerRow() - 1,
                   VIndex + poles->LowerCol() - 1);
}

//=======================================================================
//function : Poles
//purpose  : 
//=======================================================================

01834 void Geom_BezierSurface::Poles (TColgp_Array2OfPnt& P) const
{
  Standard_DimensionError_Raise_if
    (P.RowLength() != poles->RowLength() ||
     P.ColLength() != poles->ColLength(), " ");
  P = poles->Array2();
}

//=======================================================================
//function : UDegree
//purpose  : 
//=======================================================================

01847 Standard_Integer Geom_BezierSurface::UDegree () const
{
  return poles->ColLength() - 1; 
}

//=======================================================================
//function : UIso
//purpose  : 
//=======================================================================

Handle(Geom_Curve) Geom_BezierSurface::UIso (const Standard_Real U) const
{
  TColStd_Array1OfReal biduknots(1,2); biduknots(1) = 0.; biduknots(2) = 1.;
  TColStd_Array1OfInteger bidumults(1,2); bidumults.Init(UDegree() + 1);

  Handle(Geom_BezierCurve) UIsoCurve;
  const TColgp_Array2OfPnt & Poles = poles->Array2();
  TColgp_Array1OfPnt VCurvePoles (Poles.LowerCol() , Poles.UpperCol());
  if (urational || vrational) {
    const TColStd_Array2OfReal & Weights = weights->Array2();
    TColStd_Array1OfReal VCurveWeights 
      (Weights.LowerCol() , Weights.UpperCol());
    BSplSLib::Iso (U, 1, Poles,
               Weights,
               biduknots, bidumults,
               UDegree(), 0, VCurvePoles, VCurveWeights);
    if (urational)
      UIsoCurve = new Geom_BezierCurve (VCurvePoles, VCurveWeights);
    else
      UIsoCurve = new Geom_BezierCurve (VCurvePoles);
  }
  else {
    BSplSLib::Iso (U, 1, Poles,
               *((TColStd_Array2OfReal*) NULL),
               biduknots, bidumults,
               UDegree(), 0, VCurvePoles, PLib::NoWeights());
    UIsoCurve = new Geom_BezierCurve (VCurvePoles);
  }
  return UIsoCurve;
}

//=======================================================================
//function : VDegree
//purpose  : 
//=======================================================================

01893 Standard_Integer Geom_BezierSurface::VDegree () const
{
  return poles->RowLength() - 1; 
}

//=======================================================================
//function : VIso
//purpose  : 
//=======================================================================

Handle(Geom_Curve) Geom_BezierSurface::VIso (const Standard_Real V) const
{
  TColStd_Array1OfReal bidvknots(1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
  TColStd_Array1OfInteger bidvmults(1,2); bidvmults.Init(VDegree() + 1);

  Handle(Geom_BezierCurve) VIsoCurve;
  const TColgp_Array2OfPnt & Poles = poles->Array2();
  TColgp_Array1OfPnt VCurvePoles (Poles.LowerRow() , Poles.UpperRow());
  if (vrational || urational) {
    const TColStd_Array2OfReal & Weights = weights->Array2();
    TColStd_Array1OfReal VCurveWeights 
      (Weights.LowerRow() , Weights.UpperRow());
    BSplSLib::Iso (V, 0, Poles,
               Weights,
               bidvknots, bidvmults,
               VDegree(), 0, VCurvePoles, VCurveWeights);
    if (vrational)
      VIsoCurve = new Geom_BezierCurve (VCurvePoles, VCurveWeights);
    else
      VIsoCurve = new Geom_BezierCurve (VCurvePoles);
  }
  else {
    BSplSLib::Iso (V, 0, Poles,
               *((TColStd_Array2OfReal*) NULL),
               bidvknots, bidvmults,
               VDegree(), 0, VCurvePoles, PLib::NoWeights());
    VIsoCurve = new Geom_BezierCurve (VCurvePoles);
  }
  return VIsoCurve;
}

//=======================================================================
//function : Weight
//purpose  : 
//=======================================================================

01939 Standard_Real Geom_BezierSurface::Weight (const Standard_Integer UIndex,
                                const Standard_Integer VIndex) const
{
  Standard_OutOfRange_Raise_if (
           UIndex < 1 || UIndex > weights->ColLength() ||
           VIndex < 1 || VIndex > weights->RowLength(), " ");

  if (urational || vrational) 
    return weights->Value (UIndex, VIndex);
  else 
    return 1;
}

//=======================================================================
//function : Weights
//purpose  : 
//=======================================================================

01957 void Geom_BezierSurface::Weights (TColStd_Array2OfReal& W ) const
{
  Standard_DimensionError_Raise_if (
           W.RowLength() != weights->RowLength() ||
           W.ColLength() != weights->ColLength(), " " );
  if (urational || vrational) 
    W = weights->Array2();
  else 
    W.Init(1.);
}

//=======================================================================
//function : IsCNu
//purpose  : 
//=======================================================================

01973 Standard_Boolean Geom_BezierSurface::IsCNu (const Standard_Integer ) const
{
  return Standard_True; 
}

//=======================================================================
//function : IsCNv
//purpose  : 
//=======================================================================

01983 Standard_Boolean Geom_BezierSurface::IsCNv (const Standard_Integer ) const
{
  return Standard_True; 
}

//=======================================================================
//function : IsURational
//purpose  : 
//=======================================================================

01993 Standard_Boolean Geom_BezierSurface::IsURational () const
{
  return urational; 
}

//=======================================================================
//function : IsVRational
//purpose  : 
//=======================================================================

02003 Standard_Boolean Geom_BezierSurface::IsVRational () const
{
  return vrational; 
}

//=======================================================================
//function : Transform
//purpose  : 
//=======================================================================

02013 void Geom_BezierSurface::Transform (const gp_Trsf& T)
{
  TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
#ifdef DEB
  TColgp_Array2OfPnt & Coefs = coeffs->ChangeArray2();
#else
  coeffs->ChangeArray2();
#endif

  for (Standard_Integer I = 1; I <= Poles.ColLength(); I++) {

    for (Standard_Integer J = 1; J <= Poles.RowLength(); J++) {
      Poles (I, J).Transform (T);
    }
  }
  UpdateCoefficients();
}

//=======================================================================
//function : IsUClosed
//purpose  : 
//=======================================================================

02036 Standard_Boolean Geom_BezierSurface::IsUClosed () const
{ 
  const TColgp_Array2OfPnt & Poles = poles->Array2();
  Standard_Boolean Closed = Standard_True;
  Standard_Integer Lower  = Poles.LowerRow();
  Standard_Integer Upper  = Poles.UpperRow();
  Standard_Integer Length = Poles.RowLength();
  Standard_Integer j      = Poles.LowerCol();

  while (Closed && j <= Length) {
    Closed = (Poles (Lower,j).Distance (Poles (Upper,j)) <= Precision::Confusion());
    j++;
  }
  return Closed; 
}

//=======================================================================
//function : IsVClosed
//purpose  : 
//=======================================================================

02057 Standard_Boolean Geom_BezierSurface::IsVClosed () const
{ 
  const TColgp_Array2OfPnt & Poles = poles->Array2();
  Standard_Boolean Closed = Standard_True;
  Standard_Integer Lower  = Poles.LowerCol();
  Standard_Integer Upper  = Poles.UpperCol();
  Standard_Integer Length = Poles.ColLength();
  Standard_Integer i      = Poles.LowerRow();
  while (Closed && i <= Length) {
    Closed = (Poles (i,Lower).Distance (Poles (i,Upper)) <= Precision::Confusion());
    i++;
  }
  return Closed; 
}

//=======================================================================
//function : IsUPeriodic
//purpose  : 
//=======================================================================

02077 Standard_Boolean Geom_BezierSurface::IsUPeriodic () const
{
  return Standard_False; 
}

//=======================================================================
//function : IsVPeriodic
//purpose  : 
//=======================================================================

02087 Standard_Boolean Geom_BezierSurface::IsVPeriodic () const
{
  return Standard_False; 
}

//=======================================================================
//function : Resolution
//purpose  : 
//=======================================================================

02097 void Geom_BezierSurface::Resolution(const Standard_Real  Tolerance3D,
                            Standard_Real&       UTolerance,
                            Standard_Real&       VTolerance) 
{
  if(!maxderivinvok){
    TColStd_Array1OfReal biduknots(1,2); biduknots(1) = 0.; biduknots(2) = 1.;
    TColStd_Array1OfInteger bidumults(1,2); bidumults.Init(UDegree() + 1);
    TColStd_Array1OfReal bidvknots(1,2); bidvknots(1) = 0.; bidvknots(2) = 1.;
    TColStd_Array1OfInteger bidvmults(1,2); bidvmults.Init(VDegree() + 1);
    if(urational || vrational){
      BSplSLib::Resolution(poles->Array2(),
                     weights->Array2(),
                     biduknots,
                     bidvknots,
                     bidumults,
                     bidvmults,
                     UDegree(),
                     VDegree(),
                     urational,
                     vrational,
                     0,
                     0,
                     1.,
                     umaxderivinv,
                     vmaxderivinv) ;
    }
    else{
      BSplSLib::Resolution(poles->Array2(),
                     *((TColStd_Array2OfReal*) NULL),
                     biduknots,
                     bidvknots,
                     bidumults,
                     bidvmults,
                     UDegree(),
                     VDegree(),
                     urational,
                     vrational,
                     0,
                     0,
                     1.,
                     umaxderivinv,
                     vmaxderivinv) ;
    }
    maxderivinvok = 1;
  }
  UTolerance = Tolerance3D * umaxderivinv;
  VTolerance = Tolerance3D * vmaxderivinv;
}

//=======================================================================
//function : Copy
//purpose  : 
//=======================================================================

Handle(Geom_Geometry) Geom_BezierSurface::Copy() const
{
  Handle(Geom_BezierSurface) S = new Geom_BezierSurface
    (poles, coeffs, weights, wcoeffs, urational, vrational);
  return S;
}

//=======================================================================
//function : Init
//purpose  : 
//=======================================================================

void Geom_BezierSurface::Init
02164   (const Handle(TColgp_HArray2OfPnt)&   Poles, 
   const Handle(TColStd_HArray2OfReal)& Weights)
{
  Standard_Integer NbUPoles = Poles->ColLength();
  Standard_Integer NbVPoles = Poles->RowLength();

  Standard_Integer maxcls = Max(NbUPoles, NbVPoles);
  Standard_Integer mincls = Min(NbUPoles, NbVPoles);

  // set fields
  poles   = Poles;
  coeffs  = new TColgp_HArray2OfPnt  (1,maxcls,1,mincls);

  if (urational || vrational) {
    weights = Weights;
    wcoeffs = new TColStd_HArray2OfReal (1,maxcls,1,mincls);
  }
  else {
    weights.Nullify();
    wcoeffs.Nullify();
  }

  UpdateCoefficients();
}


//=======================================================================
//function : UpdateCoefficients
//purpose  : 
//=======================================================================

02195 void  Geom_BezierSurface::UpdateCoefficients(const Standard_Real ,
                                   const Standard_Real )
{
  Standard_Integer i ;
  maxderivinvok = Standard_False;
  ucacheparameter = 0.;
  TColStd_Array1OfReal biduflatknots(1, 2*(UDegree()+1));
  for( i = 1; i <= UDegree()+1; i++){
    biduflatknots(i) = 0.;
    biduflatknots(i + UDegree() +1) = 1.;
  }
  vcacheparameter = 0.;
  TColStd_Array1OfReal bidvflatknots(1, 2*(VDegree()+1));
  for(i = 1; i <= VDegree()+1; i++){
    bidvflatknots(i) = 0.;
    bidvflatknots(i + VDegree() +1) = 1.;
  }

  Standard_Real uparameter_11 = (2*ucacheparameter + ucachespanlenght)/2,
                uspanlenght_11 = ucachespanlenght/2,
                vparameter_11 = (2*vcacheparameter + vcachespanlenght)/2,
                vspanlenght_11 = vcachespanlenght/2 ;

  if ( urational || vrational ) {
    BSplSLib::BuildCache(uparameter_11,vparameter_11,
                   uspanlenght_11,vspanlenght_11,0,0,
                   UDegree(),VDegree(),0,0,
                   biduflatknots,bidvflatknots,
                   poles->Array2(),
                   weights->Array2(),
                   coeffs->ChangeArray2(),
                   wcoeffs->ChangeArray2());
  }
  else {
    BSplSLib::BuildCache(uparameter_11,vparameter_11,
                   uspanlenght_11,vspanlenght_11,0,0,
                   UDegree(),VDegree(),0,0,
                   biduflatknots,bidvflatknots,
                   poles->Array2(),
                   *((TColStd_Array2OfReal*) NULL),
                   coeffs->ChangeArray2(),
                   *((TColStd_Array2OfReal*) NULL));
  }
  validcache = 1;
}


Generated by  Doxygen 1.6.0   Back to index