Path: utzoo!attcan!uunet!cs.utexas.edu!ut-emx!ccwf.cc.utexas.edu From: blake@ccwf.cc.utexas.edu (Blake Freeburg) Newsgroups: comp.graphics Subject: C code for NURBS surface - Here it is, have fun Keywords: NURBS source C This is the source code that I used to generate nurbs surfaces. Since I Project: Nurbs curves and surfaces File: NURBS.H Programmer: Blake Freeburg Date: Feb 15, 1991 Message-ID: <44983@ut-emx.uucp> Date: 2 Mar 91 17:31:35 GMT Sender: news@ut-emx.uucp Reply-To: blake@ccwf.cc.utexas.edu (Blake Freeburg) Distribution: comp.graphics Organization: The University of Texas at Austin Lines: 317 Description: This file contains various things needed for the generation of nurbs curves and surfaces. Most of this is a copy of what may be found in the gl.h header file History 15 Feb. 1991: Original revision **************************************************************************/ #define XYZ 0x0001 /* 3D control point */ #define XYZW 0x0002 /* rational 4D control point */ typedef struct fvec2d { double x,y; } FVEC2D; typedef struct fvec3d { double x,y,z; } FVEC3D; typedef struct fvec4d { double x,y,z,w; } FVEC4D; -----------CUT HERE---------------------------CUT HERE---------CUT HERE----- /************************************************************************ NURBS surface generator Programmer: Blake Freeburg Description: A set of functions that will produce a mesh of points given the s and t knot vectors, the number of knots, the order of each axis, byte steps to take in the array, and the control points, in (x,y,z) or (x,y,z,w) format. ***************************************************************************/ #include #include #include #include "nurbs.h" #define TRIMESH /* turn on triangle generation */ long s_byte_length=0L;/* offset to next control point in s direction */ long t_byte_length=0L;/* offset to next control point in t direction */ long s_knot_count=0L; /* number of knots in knot vector in s directon */ long t_knot_count=0L; /* number of knots in knot vector in t directon */ /************************************************************************* double N(i,k,knot,t) long i - the index of the knot vector we are at long k - the order of the curve double knot[] - the knot vector or non-decreasing values double t - the point along the curve from tmin < t < tmax **************************************************************************/ double N(long i, long k, double knot[], double t) { /* temp variables, removed when finished */ double num1, num2, den1, den2, val1, val2; if(k == 1) { if((knot[i]<=t)&&(knot[i+1]>t)) { return 1.0; } else { return 0.0; } } else { num1 = (t-knot[i])*N(i,k-1,knot,t); den1 = knot[i+k-1] - knot[i]; num2 = (knot[i+k] - t)*N(i+1,k-1,knot,t); den2 = knot[i+k] - knot[i+1]; if ((num1==0.0)&&(den1==0.0)) val1 = 0.0; else val1 = num1/den1; if ((num2==0.0)&&(den2==0.0)) val2 = 0.0; else val2 = num2/den2; return(val1 + val2); } } /************************************************************************** double S(i,j,s_order,t_order,s_count,t_count,sknot,tknot,ctrlarray,s,t); long i - the index of the control point in the mesh long j - the index of the control point in the mesh long s_order - the order of the curve in s space long t_order - the order of the curve in t space long s_count - the number of control points in s space long t_count - the number of control points in t space double sknot[] - the knot vector of non-decreasing values in s space double tknot[] - the knot vector of non-decreasing values in t space double *ctrlarray - array of data points to be used double s - the point along the surface from umin < u < umax double t - the point along the surface from wmin < w < wmax ***************************************************************************/ double S(long i,long j,long s_order,long t_order,long s_count,long t_count, double sknot[],double tknot[],double *ctrlarray, double s,double t) { long x, y; double den=0.0, num=0.0; char *position; /* pointer to find values in array */ position = (char *)ctrlarray; /* compute the numerator first */ num = (*(FVEC4D *)(position+i*s_byte_length+j*t_byte_length)).w *N(i,s_order,sknot,s)*M(j,t_order,tknot,t); /* now compute the denominator */ for(x=0; x<=(s_count-s_order); x++) for(y=0; y<=(t_count-t_order); y++) den+= (*(FVEC4D *)(position+i*s_byte_length+j*t_byte_length)).w *N(i,s_order,sknot,s)*M(j,t_order,tknot,t); if((num == 0.0) && (den == 0.0)) return(0.0); else return (num/den); } /************************************************************************* void precomputebasis(order,x,count,knot,basis) long order the order of the curve in the s direction double x where we are along the knot vector long count the length of the knot vector double knot[] the knot vector itself double basis[] the array of precomputed knot vectors... **************************************************************************/ void precomputebasis(long order,double x,long count,double knot[],double basis[]) { int i; for(i=0;i<=count;i++) { basis[i] = N(i,order,knot,x); } } /************************************************************************* void sumbasis(position, s_basis, t_basis, s_count, t_count, sum) char *position where we are in the mesh double s_basis[] array of s precomputed mesh values double t_basis[] array of t precomputed mesh values long s_count[] points in s direction long t_count[] points in t direction double *sum the sum of the denominator; **************************************************************************/ void sumbasis(char *position, double s_basis[], double t_basis[], long s_count, long t_count, double *sum) { long i,j; *sum = 0.0; for(i=0;i