// Gnurbs - A curve and surface library
// Copyright (C) 2008-2026 Eric Bechet
//
// See the LICENSE file for contributions and license information.
// Please report all bugs and problems to <bechet@cadxfem.org>.
//

#ifndef __NBEZIERTRIANGLE_H
#define __NBEZIERTRIANGLE_H


#include "nsurface.h"
#include <vector>

class nbeziertriangle : public nparametricsurface
{
protected:
  std::vector<npoint> val; // control points
  int nCP; // number of control points
  int deg;
public:
  nbeziertriangle(int degree_) : nCP(((degree_+2) * (degree_+1)) /2),val(((degree_+2) * (degree_+1)) /2),deg(degree_) {}
  virtual ~nbeziertriangle() {}
  virtual int degree(void) const
  {
    return deg;
  }; 
  virtual int degree_u(void) const
  {
    return deg;
  }
  virtual int degree_v(void) const
  {
    return deg;
  }
  virtual int nb_CP(void) const
  {
    return nCP;
  }
  virtual int nb_CP_u(int iv=0) const
  {
    return deg+1;
  }
  virtual int nb_CP_v(int iu=0) const
  {
    return deg+1;
  }
  virtual double min_u() const
  {
    return 0.;
  }
  virtual double max_u() const
  {
    return 1.;
  }
  virtual double min_v() const
  {
    return 0.;
  }
  virtual double max_v() const
  {
    return 1.;
  }
  virtual void P(double u,double v, npoint& ret) const ;
  virtual void dPdu(double u,double v, npoint& ret) const {}
  virtual void dPdv(double u,double v, npoint& ret) const {}
  virtual const npoint& CP(int whichu,int whichv,int whichw) const
  {
    return val[whichu+ (whichv*(2*deg+3-whichv)) /2];
  }
  virtual npoint CP(int whichu,int whichv) const
  {
    return val[whichu+ (whichv*(2*deg+3-whichv)) /2];
  }
  virtual npoint CP(int which) const
  {
    return val[which];
  }
  virtual npoint& CP(int whichu,int whichv,int whichw)
  {
    int ndx=whichu+ (whichv* (2*deg+3-whichv)) /2;
    return val[ndx];
  }
  virtual npoint& CP(int whichu,int whichv)
  {
    return val[whichu+ (whichv*(2*deg+3-whichv)) /2] ;
  }
  virtual npoint& CP(int which)
  {
    return val[which];
  }
  virtual void set_CP(int whichu,int whichv,const npoint& pt)
  {
    val[whichu+ (whichv*(deg+1-whichv)) /2]=pt;
  }
  virtual void set_CP(int which,const npoint& pt)
  {
    val[which]=pt;
  }
  virtual nsurface* clone() const
  {
    return new nbeziertriangle(*this);
  }
private:
  void curvepoint(double u, double v, double w, npoint &C) const ;    // u+v+w=1
};

#endif // __NBEZIERTRIANGLE_H
