// 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 __NSURFACE_H
#define __NSURFACE_H

#include "nutil.h"
#include "ncurve.h"



class nsurface
{
public:
  virtual void Display(data_container& data) const = 0 ;    // discretizes the surface into triangles or quads
  virtual void Discretize(std::vector<npoint3> &pts, double du=0., double ds=0., double eps=0., double epsr=0.) const {};    // discretizes the surface
  virtual int nb_CP(void) const {return 0;}    // returns the total number of control points
  virtual npoint CP(int which) const {return npoint();}    // returns a control point (const) (default impl)
  virtual void set_CP(int which,const npoint& pt) {} ;    // sets a control point
  virtual nsurface* clone() const =0 ;
};


class nparametricsurface : public nsurface
{
public:
  virtual int degree(void) const {return -1;};    // returns the degree in u and v or -1 if non polynomial
  virtual int degree_u(void) const {return -1;}    // returns the degree in u
  virtual int degree_v(void) const {return -1;}    // returnd the degree in v
  virtual int nb_CP_u(int iv=0) const {return 0;}    // number of control points in u
  virtual int nb_CP_v(int iu=0) const {return 0;}    // number of control points in v
  virtual double min_u() const =0; // minimal allowed value for u
  virtual double max_u() const =0; // maximal allowed value for u
  virtual double min_v() const =0; // minimal allowed value for v
  virtual double max_v() const =0; // maximal allowed value for v
  virtual void P(double u,double v, npoint& ret) const =0;    // point on the surface S(u,v)
  virtual void dPdu(double u,double v, npoint& ret) const ;    // first derivative /u (generic implementation) 
  virtual void dPdv(double u,double v, npoint& ret) const ;    // first derivative /v (generic implementation)
  virtual void d2Pdu2(double u,double v, npoint& ret) const ;    // second derivative /u (generic implementation) 
  virtual void d2Pdv2(double u,double v, npoint& ret) const ;    // second derivative /v (generic implementation)
  virtual void d2Pdudv(double u,double v, npoint& ret) const ;    // second derivative /u and /v (generic implementation)
  virtual void Display(data_container& data) const;    // discretizes the surface in triangle or quads
  virtual nsurface* clone() const =0 ; // clones the surface (allocated on the heap)
};

#endif //__NSURFACE_H
