This text file contains a C++ NURBS class. This acts as a very thin wrapper
for the Manchester NURBS library, which may be of use to someone. Report
any problems to m.preston@manchester.ac.uk


Martin Preston, 
Manchester

20/5/94

---------------------------------------


// The header file forms a wrapper for the C PR_Nurbs library
// so it can be used by C++

#include "ptk++.h"
#include "nurbtype++.h"
#include "nurbfns++.h"

class NURBS
{
protected:

  PR_nurb *surface;  // the actual surface

public:
  NURBS() { nrb_allocatenurb(&this->surface); }

      // Special constructors 

  NURBS(NURBS* cp) 
    { 
      nrb_allocatenurb(&this->surface);
      nrb_copy(cp->the_surface(), this->surface); 
    }

  NURBS(int kx, int ntx, int ky, int nty)
  { 
    nrb_allocatenurb(&this->surface);
    nrb_init(kx, ntx, ky, nty, this->surface); 
    nrb_makeknots((float) 0.0, (float) 1.0, &(surface->pf_u));
//    nrb_makeknots((float) 0.0, (float) 1.0, &(surface->pf_v));
  }

  ~NURBS() { nrb_deallocatenurb(&(this->surface)); }

      // Hack to make copy-ctor possible
  PR_nurb* the_surface() { return(this->surface); }

      // Definitions of the various C NURBS routines

      // void allocateknots

  void allocatepts(int nx)
  {
    nrb_allocatepts(nx, &surface->pf_ppp);
  }

  void boehmc(PR_dir *tnew)
  {
    PR_nurb tmp;

    nrb_boehmc(this->surface, tnew, &tmp);
    nrb_copy(&tmp, this->surface);
  }

  NURBS& bvalue(float x, int jderiv)
  {
    NURBS* tmp = new NURBS;

    nrb_bvalue(this->surface, x, jderiv, tmp->the_surface());
    return(*tmp);
  }
  
  void clear() { nrb_clear(this->surface); };

  NURBS& du(float x)
  {
    NURBS* tmp = new NURBS;
    PR_pts* the_pts = tmp->the_surface()->pf_ppp;

    nrb_du(this->surface,x, &the_pts);
    return(*tmp);
  }
  
  void dump(FILE *fp) { nrb_dump(fp, this->surface); }

  NURBS& elevate(int transpose)
  {
    NURBS* tmp = new NURBS;

    nrb_elevate(transpose, this->surface, tmp->the_surface());
    return(*tmp);
  }

  NURBS& evaluate(float x)
  {
    NURBS* tmp = new NURBS;

    nrb_evaluate(this->surface, x, tmp->the_surface());
    return(*tmp);
  }

  NURBS& extrude(Ppoint3 dirn)
  {
    NURBS* tmp = new NURBS;
    int temp_error;

    nrb_extrude(this->surface, dirn, tmp->the_surface(), &temp_error);
    return(*tmp);
  }
  
  void interchange() { nrb_interchange(this->surface); }
  
  void interpolate(float tol)
  {
    NURBS* tmp = new NURBS;

    nrb_interpolate(this->surface, tol, tmp->the_surface());
    this->surface = tmp->the_surface();

  }

  NURBS& osloc()
  {
    NURBS* tmp = new NURBS;

    nrb_osloc(this->surface, tmp->the_surface());
    return(*tmp);
  }

      // Can't work out what to do with nrb_partials
  
  int read(FILE *fp)  { return(nrb_read(fp, this->surface)); }
  void write(FILE *fp) { nrb_write(fp, this->surface); }

  NURBS& revolve()
  {
    NURBS* tmp = new NURBS;

    nrb_revolve(this->surface, tmp->the_surface());
    return(*tmp);
  }

  NURBS& ruled(NURBS& nrb2)
  {
    NURBS* tmp = new NURBS;
    int temp_error = 0;

    nrb_ruled(this->surface, nrb2.the_surface(), 
	      tmp->the_surface(), &temp_error);
    return(*tmp);
  }

  NURBS& tessalate(int nx)
  {
    NURBS* tmp = new NURBS();

    nrb_tessalate(this->surface, nx, tmp->the_surface());
    return(*tmp);
  }
  
  void transpose() { nrb_transpose(this->surface); }
  
  void xform(Pmatrix3 the_mat) { nrb_xform(this->surface, the_mat); }

      // Special creation routines
  
  void arc(float theta1, float theta2) 
    { nrb_arc(theta1, theta2, this->surface); }
  
  void circle()  { nrb_circle(this->surface); }

  void polyline(int npts, Ppoint3* pts)
    {  nrb_polyline(npts, pts, this->surface); }
  
  void torus() { nrb_torus(this->surface); }
  void triangle() { nrb_triangle(this->surface); }
  void square() { nrb_square(this->surface); }
  void sphere() { nrb_sphere(this->surface); }
  void vase() { nrb_vase(this->surface); }
};









