Appendix A: Source Code
117
//============================================================================= // File Name:shade_1.C //============================================================================= // // USAGE : shade_1 // // Routine for displaying the Nurbs surface given the control point array, the // knot vector and the order of the polynomial basis //============================================================================= // Karthik Bindiganavle, June 29th, 1999 //============================================================================= #include
#include #include #include /* To accommodate "strlen" */ #include // Motif PushButton widget #include // Motif Scale (slider) widget #include /* Motif Form widget */ #include /* Motif Frame widget */ #include #include #include /* For XA_RGB_DEFAULT_MAP */ #include /* For XmuLookupStandardColormap */ #include /* To access fonts */ #include #include #include #include #include /* Motif OpenGL drawing area */ #include // For Motif widgets #include // For Motif message dialog #include // For Motif Push button #include #include // For Motif sepeartor bar #include // For Motif cascade button #include #include // For sin, cos, and M_pi function #include // For Motif text field widgets #include // For Motif widgets #include // Motif Cascade Button Widget #include // For Motif label #include // For paned window #include #include // For Motif widget to indicate action area #include #include #include
#ifndef CALLBACK #define CALLBACK #endif #define pi 3.1412 /*-----------------------------------------------------------------------------Appendix A: Source Code 118
* Wrapper functions for the malloc and calloc functions * * -Pads each allocation with a specified padsize to avoid overwriting data/program * (void *__malloc(int n) and void *__calloc(int n, int s) * * -frees memory * (void __free(void * ___ptr_) * *-----------------------------------------------------------------------------*/ #define USE_MALLOC 1 #define PADSIZE 15000 #define NUMALLOC 2000 static int __number = 0; static unsigned long __address[NUMALLOC]; static int __length[NUMALLOC]; static int __eof[NUMALLOC];
#if USE_MALLOC void * __malloc (int n) { char * ___ptr_; int m, i; m = n + PADSIZE; ___ptr_ = (char *) malloc (m); if (__number < NUMALLOC) { __address[__number] = (unsigned long) ___ptr_; __length[__number] = n; for (i=0; iwidth, callData->height); glMatrixMode (GL_PROJECTION); glLoadIdentity(); if(callData->width <= callData->height) glOrtho (-5.0, 5.0, -5.0 * (GLfloat)callData->height/(GLfloat)callData>width, 5.0 * (GLfloat)callData->height/(GLfloat)callData->width, 0.0, 20.0); else glOrtho (-5.0 * (GLfloat)callData->width/(GLfloat)callData->height, 5.0 * (GLfloat)callData->width/(GLfloat)callData->height, -5.0, 5.0, 0.0, 20.0); Appendix A: Source Code 131
} /* end-of-resized */ //========================================================================= // input -- GLwNinputCallback // This callback function is activated each time the drawing area gets // a mouse of keyboard event. // // Parameters // w -- glxarea // clientData -- NULL ( 4th parameter in XtAddCallback ) // call -- reason / event / width / height // // Returns // nothing //========================================================================= static void input (Widget w, XtPointer clientData, XtPointer call) { GLwDrawingAreaCallbackStruct *callData; callData = (GLwDrawingAreaCallbackStruct *) call; XEvent *event = callData->event;
} //end-of-input //========================================================================= // intervalTimer -// This function is called at regular intervals, defined at a // resolution of 1 msec (1/1000 second). // // Parameters // clientData -- XtPointer -- (XtAppContext) App // id -- XtIntervalID // // Returns // nothing //========================================================================= //static void intervalTimer (XtPointer clientData, XtIntervalId *id) //{ // // Insert here code to be execute at regular intervals. // // Then, rearm the interval time; in this particular case, revisit // this function in 1,000 msec (1 second). Note that the interval // is specified as an unsigned long, hence the appended "L".
//(void) XtAppAddTimeOut ((XtAppContext)clientData, // 1000L, intervalTimer, clientData); //}end-of-intervalTimer //========================================================================= // idleTime -// This function is called whenever the X server has no pending // events. Make certain that your calls here are brief to prevent // deteriorated response. Appendix A: Source Code 132
// // Parameters // clientData -- XtPointer (glxarea) // // Returns // nothing //========================================================================= //static Boolean idleTime (XtPointer clientData) //{ // // Insert here code to be execute when X is idle. // //return (FALSE); //}end-of-idleTime // Rearm: FALSE=continue to call, TRUE=do not call again
//========================================================================= // initCustomized -// This function creates additional widgets, registers their callbacks, // and located them relative to each other. // // Parameters // form -- this is the main widget // glxarea -- this widget if a child of the form widget // // Returns // nothing //========================================================================= static void initCustomized (Widget form, Widget glxarea) { area = glxarea; // Create menubar Widget menubar = XmVaCreateSimpleMenuBar (form, "menubar", NULL, 0); XtManageChild (menubar); XmString Exit; Exit
= XmStringCreateLocalized ("Exit");
// Create and locate the EXIT button Widget exitButton = XtVaCreateManagedWidget ("Exit", xmCascadeButtonWidgetClass, menubar, XmNlabelString, Exit, XmNmnemonic, 'E', NULL); XtAddCallback (exitButton, XmNactivateCallback, buttonCallback, (XtPointer) 1); // Free string XmStringFree (Exit); Appendix A: Source Code 133
// Create the UP arrow Widget up = XtVaCreateManagedWidget ( "arrowUp", xmArrowButtonGadgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 35, XmNarrowDirection, XmARROW_UP, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 40, NULL ); XtAddCallback ( up, XmNarmCallback, buttonCallback, ( XtPointer ) 2); // Create the RIGHT arrow Widget right = XtVaCreateManagedWidget ( "arrowRight", xmArrowButtonGadgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, up, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, up, XmNarrowDirection, XmARROW_RIGHT, NULL ); XtAddCallback ( right, XmNarmCallback, buttonCallback, ( XtPointer ) 3); // Create the LEFT arrow Widget left = XtVaCreateManagedWidget ( "arrowLeft", xmArrowButtonGadgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, up, XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget, right, XmNrightOffset, 20, XmNarrowDirection, XmARROW_LEFT, NULL ); XtAddCallback ( left, XmNarmCallback, buttonCallback, ( XtPointer ) 4); // Create the DOWN arrow Widget down = XtVaCreateManagedWidget ( "arrowDown", xmArrowButtonGadgetClass, form, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, left, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, left, XmNarrowDirection, XmARROW_DOWN, NULL ); XtAddCallback ( down, XmNarmCallback, buttonCallback, ( XtPointer ) 5); // Create and locate the Zoom slider Widget zoomslider = XtVaCreateManagedWidget ("Zoom slider", xmScaleWidgetClass, form, XtVaTypedArg, XmNtitleString, XmRString, "Zoom +", 10, XmNmaximum, -10, XmNminimum, -90, XmNvalue, -50, XmNshowValue, False, Appendix A: Source Code 134
XmNorientation, XmHORIZONTAL, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, menubar, NULL); XtAddCallback (zoomslider, XmNdragCallback,sliderCallback, (XtPointer) 6); XtAddCallback (zoomslider, XmNvalueChangedCallback, sliderCallback, (XtPointer) 6); // Update location of Motif / OpenGLEXIT drawing area XtVaSetValues (glxarea, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, menubar, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, zoomslider, NULL); } //end-of-initCustomized //========================================================================= // buttonCallback -// This callback function is activated each time a button is hit. // // Parameters // w -- exitButton or redButton // clientData -- button ID ( 4th parameter in XtAddCallback ) // call -- reason / event / click_count // // Returns // nothing //========================================================================= void buttonCallback (Widget w, XtPointer clientData, XtPointer call) { switch ((int)clientData) { case 1: // Process the "EXIT" button being hit. exit (0); break;
case 2: // process the "UP_ARROW" button being hit phi = phi + 2.0; if( phi >= 88.0 ) phi = 88.0; if( phi <= -88.0 ) phi = -88.0; isometric (phi, theta, r); glScalef(7.0,7.0,7.0); draw ( XtDisplay ( area ), XtWindow ( area ), int (identifier)); break; case 3: // process the "RIGHT_ARROW" button being hit theta = theta - 2.0; isometric (phi, theta, r); Appendix A: Source Code 135
glScalef(7.0,7.0,7.0); draw ( XtDisplay ( area ), XtWindow ( area ), int (identifier)); break; case 4: // process the "LEFT_ARROW" button being hit theta = theta + 2.0; isometric (phi, theta, r); glScalef(7.0,7.0,7.0); draw ( XtDisplay ( area ), XtWindow ( area ), int (identifier)); break; case 5: // process the "DOWN_ARROW" button being hit phi = phi - 2.0; if( phi >= 88.0 ) phi = 88.0; if( phi <= -88.0 ) phi = -88.0; isometric (phi, theta, r); glScalef(7.0,7.0,7.0); draw ( XtDisplay ( area ), XtWindow ( area ), int (identifier)); break; } // This should never happen... cout << "WARNING : unknown callBack\n"; } // end-of-button-callBack
//========================================================================= // sliderCallback -// This callback function is activated each time the slider is moved // // Parameters // dpy -- XtDisplay (glxarea) // win -- XtWindow (glxarea) // mode -- Render mode in this case // index -- Counter that tells the program option selected by user // // Returns // nothing //========================================================================= static void sliderCallback( Widget w, XtPointer clientData, XtPointer call) { XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct*) call; if (cbs->reason == XmCR_DRAG) { //process the slider for zoom value being changed if(((int)clientData) == 6) { r = (cbs->value/1.0); glScalef(5.0,5.0,5.0 +5*r); draw(XtDisplay(area), XtWindow(area), int (identifier)); return; } } if (cbs->reason == XmCR_VALUE_CHANGED) Appendix A: Source Code 136
{ return; } } //end-of-sliderback
//=================================================================== // isometric -// function which defines the viewport settings // // parameters // phi -- angle to effect the up and down movement // theta -- angle to effect the left and right mevement // r -- variable for storing the zoom value increments // // returns // nothing //================================================================== void isometric(float phi, float theta, float r) { int x = 1000; int y = 1000; //Define the viewport for isometric view glColor3f (1.0, 1.0, 1.0); //glViewport (0, 0, x, y); //Define view direction and orientation for the isometric view glMatrixMode(GL_MODELVIEW); glLoadIdentity(); a = cos(phi/180*pi) * sin(theta/180.0*pi) * (3+r); b = sin(phi/180*pi) * (3+r); c = cos(phi/180*pi) * cos(theta/180.0*pi) * (3+r); gluLookAt( a, b, c, 0.0, 2.0, 1.0, 0.0, 1.0, 0.0); } // end-of-isometric
//==================================================================== // Initializes the control points on the surfaces //==================================================================== void init_surface(void) { //-----------------------------------------------------------------//read in the data for the surface and the trim curve //-----------------------------------------------------------------fp = fopen("datasurf_01", "r"); fp1 = fopen("datatrim_06", "r"); //param = 1; param = 2; fscanf(fp, "%d", &numpts[0]); Appendix A: Source Code 137
fscanf(fp, "%d", &numpts[1]); fscanf(fp1,"%d", &trimnum); data_points = new float[3*numpts[0]*numpts[1]]; trim_data = new float[2*trimnum];
for (i=0; i<=numpts[0]*numpts[1]*3; i++) fscanf(fp, "%f", &data_points[i]); for (i=0; i<=numpts[0]*numpts[1]*3; i++) data_points[i] = data_points[i]*1; for (i=0; i<=2*trimnum; i++) fscanf (fp1,"%f",&trim_data[i]); fclose(fp); fclose(fp1);
/* close files */
//--------------------------------------------------------------------//Calculate the knot vector and the control points for defining //original surface //--------------------------------------------------------------------//identifier = 1; u_continuities = new int[numpts[0]]; v_continuities = new int[numpts[1]]; for (i=0; i #include #include #include #include
void bspline_diff_geo(int, float [],float [], int, float[], float [], float [], float [], float [], float [], float [], int&, int []); //-----------------------------------------------------------------------------// bspline_diff_geo : // Routine for calculating the Curvature, Torsion, Tangent, Normal and Bi// Normal of a B-Spline curve (Can be extended to a surface also) // // input : // curv_newnum – number of knots in the knot vector // curv_newknots - knot vector for the curve // curv_contrlpts - control point vector of the curve // Output: // tangent(T), Normal(N), bi_normal(B_N) and the datapoints on the // curve at curvature optimas(datapoint_at_new_id) and the new knot // sequence (new_id) whose knot values are values at which curvature // optima occur //-----------------------------------------------------------------------------void bspline_diff_geo(int curv_newnum, float curv_newknots[], float curv_contrlpts[], int sampling_rate, float s_x[], float s_y[], float s_z[], float T[], float N[], float B_N[], float datapoint_at_new_id[], int &icount, int new_id[]) { FILE *fp, *fp1, *fp2; float *ctrlpts_x, *ctrlpts_y, *ctrlpts_z; float u,increment; //parameter value between a pair of knots float *knots; float c_x[25000], c_y[25000], c_z[25000]; //x, y, z variables for the center //of the osculating circle float x[25000], x_new[25000], y_new[25000], y[25000], z_new[25000], z[25000]; float diff_s_x[25000], diff_s_y[25000], diff_s_z[25000]; //dx, dy, dz arrays for a b-spline curve float diff2_s_x[25000], diff2_s_y[25000], diff2_s_z[25000]; //d(sqr)x, d(sqr)y, d(sqr)z arrays float diff3_s_x[25000], diff3_s_y[25000], diff3_s_z[25000]; //d(cub)x, d(cub)y, d(cub)z arrays float diff_vector[25000]; //vector of first derivatives float diff2_vector[25000]; //vector of second derivatives float diff3_vector[25000]; //vector of third derivatives Appendix A: Source Code 163
//variables used while calculating the //cross product of two vectors float mod_crs_prdt, mod_fir_der; //mod_crs_prdt = modulus of the X product // of two vectors //mod_fir_der = modulus of the vector of // first derivatives float tripl_prod; //vector triple product variable float kappa[25000], rho[25000]; //Curvature and radius of //curvature variable float tau[25000]; //torsion variable int n = 4; //degree of spline int id, count, i, j, k, final_count; //id = interval id. float new_B_N[500], alpha[5000], beta[5000], gamma[5000]; float d[100], avg_d, sum; int L; //no_of_active_intervals/no_of_domain_intervals int start_int_id, end_int_id, u_counter; //start and end of the domain knots float A, B, C, D;
float det_i, det_j, det_k;
L = curv_newnum-7; knots = new float[curv_newnum]; /*knots[0]=curv_newknots[3]; knots[1]=knots[0]; knots[2]=knots[0];*/ for(i=0; i0)&&((kappa[j+1]-kappa[j])<=0)|| ((kappa[j]-kappa[j-1])<0)&&((kappa[j+1]-kappa[j])>=0)) { new_id[i] = j; datapoint_at_new_id[3*i+0]=s_x[j]; datapoint_at_new_id[3*i+1]=s_y[j]; datapoint_at_new_id[3*i+2]=s_z[j]; i++; } }
datapoint_at_new_id[3*i+0]=s_x[j]; datapoint_at_new_id[3*i+1]=s_y[j]; datapoint_at_new_id[3*i+2]=s_z[j]; new_id[i]= j; icount = i+1; count = 0; for (i=1; i
extern void basis(float u, int interval, float knots[], float N[]); extern void dbasis(float u, int interval, float knots[], float dN[]); extern void map_point(int num,float Nu[],float Nv[],float *ctrlpt,int intU,int intV, float *coordinate); void constraintu(int num, int trimnum, float *u_knots, float *v_knots, float *control_x, float *control_y, float *control_z, float *data, float *derivative); void constraintv(int num, int trimnum, float *u_knots, float *v_knots, float *control_x, float *control_y, float *control_z, float *data, float *derivative); //-------------------------------------------------------------------------// function: // constraintu - computes an array of derivatives in v-direction at the // trimming curve. // Input: // num - u direction number of points; // trimnum- no. of points defining trimming curve.also v direction no. of " // new datapoints" // u and v new_knots so that basis can be used to compute N // control x ands y to be used with n to map points on the original surface // using map-point // data – array of original surface data points // // Output: // Array of derivatives which represents constraints in either u or v // direction //-------------------------------------------------------------------------void constraintu(int num, int trimnum, float *u_knots, float *v_knots, float *control_x, float *control_y, float *control_z, float *data, float *derivative) { int j; int intU,intV; float u,v; float x,y,z; float dNu[4],Nv[4]; for(j=0;j #include /* To accommodate "exit" */ #include /* To accommodate "strlen" */ #include #include /* Motif Form widget */ #include /* Motif Frame widget */ #include #include #include /* For XA_RGB_DEFAULT_MAP */ #include /* For XmuLookupStandardColormap */ #include /* To access fonts */ #include #include #include #include /* Motif OpenGL drawing area */
//------------------------------------------------------------// subroutines defined in this file (in order) //------------------------------------------------------------void curv_display_1(float curv_newknots[], float curv_contrlpts[], int curv_newnum, float s_x[], float s_y[], float s_z[], float T[], float N[], Display *dpy, Window win, GLXContext glxcontext); static void MakeRasterFont (Display *dpy, Window win, GLXContext glxcontext); static void PrintString (char *); //------------------------------------------------------------// Global variables local to this file //------------------------------------------------------------int showPointscurv = 0; int showTriad = 0; static GLuint FontOffset; GLuint nub; FILE *fp, *fp2; //-----------------------------------------------------------------------------// curv_display_1 -- gluNurbsCurve // // This routine uses the Nurbs interface provided by GLU for rendering a b// spline curve // // Parameters // knots -- knot sequence // ctlpoints -- control point array // dpy -- XtDisplay (glxarea) Appendix A: Source Code 179
// win -- XtWindow (glxarea) // glxcontext -- OpenGL rendering context // // Returns // nothing //-----------------------------------------------------------------------------void curv_display_1(float curv_newknots[], float curv_contrlpts[], int curv_newnum, float s_x[], float s_y[], float s_z[], float T[], float N[], float B_N[], Display *dpy, Window win, GLXContext glxcontext) { float curv_ctlpoints[1][43][3]; //float ctlpts[69]; int i, j, k; GLint curv_numctrl, count, stride; char *A[100] = { "1", "2", "3", "4", "5", "6", "7", "8", "9","10", "11","12","13","14","15","16","17","18","19","20", "21","22","23","24","25","26","27","28","29","30", "31","32","33","34","35","36","37","38","39","40", "41","42","43","44","45","46","47","48","49","50", "51","52","53","54","55","56","57","58","59","60", "61","62","63","64","65","66","67","68","69","70", "71","72","73","74","75","76","77","78","79","80", "81","82","83","84","85","86","87","88","89","90", "91","92","93","94","95","96","97","98","99","100"}; //Array of number strings used to //number points on the screen curv_numctrl = curv_newnum - 4; /*curv_ctlpoints = new Type2[1]; for(i=0; i<1; i++) curv_ctlpoints[i] = new Type1[curv_numctrl]; for(i=0; i<1; i++) for(j=0; jfid; first = fontInfo->min_char_or_byte2; last = fontInfo->max_char_or_byte2; FontOffset = glGenLists ((GLuint) last+1); if (FontOffset == 0) { printf ("out of display lists\n"); exit (0); } glXMakeCurrent (dpy, win, glxcontext); glXUseXFont (id, first, last-first+1, FontOffset+first); } // end-of-MakeRasterFont
static void PrintString (char *s) { glPushAttrib (GL_LIST_BIT); glListBase (FontOffset); glCallLists (strlen(s), GL_UNSIGNED_BYTE, (GLubyte *) s); glPopAttrib (); }
Appendix A: Source Code
183
//============================================================================== // File Name:curv_knot_constraint_1.C // // Contains routines to add continuity constraints to the knot vector // // by: Steven Fleming // modified by: Karthik Bindiganavle, June 29th, 1999 //============================================================================= #include #define OPEN 0 #define CLOSED 1 int curv_new_knot_num(int numpts, int *continuities); void curv_add_knot_const(int numpts,float knots[],int opcl,int continuities[], int newnum,float newknots[]);
//-----------------------------------------------------------------------------// curv_new_knot_num - Calculates no. of new knots // // input: // numpts – number of xyz points given // continuities – array of continuity constraints // output: // none // // Returns // number of knots //-----------------------------------------------------------------------------int curv_new_knot_num(int numpts, int *continuities) { int newnum,i,j,continuity; j=4; for(i=1;i=1;j--) { newknots[k] = newknots[k-1] + newknots[j] - newknots[j-1]; k++; } } }
Appendix A: Source Code
186
//================================================================ // Filename: curv_parametrize_1.C // Author: Steven fleming // modified by Karthik Bindiganavle // // Description: contains parametrization routines for // Cubic B-spline curves. //================================================================ #include #include #include void curv_parametrize(int numpts, float datpts[], int opcl, int param, float knots[]); float curv_pt_dist(int num1, float first[],int num2, float last[]); #define OPEN 0 #define CLOSED 1 //---------------------------------------------------------------// Function: curv_parametrize // // Author: Steven Fleming // // Description: To parametrize a cubic B-spline curve based on chord length // Method // // Inputs: number of points, array of data points, open or closed, // type of parametrization // // Outputs: Knot vector //---------------------------------------------------------------void curv_parametrize(int numpts, float datpts[], int opcl, int param, float knots[]) { float ratio; /*ratio of knot spacing to point dist*/ float distance; float first[3], last[3]; int i; float tol = 0.01; /* initialize first knot interval */ knots[3] = 0.0; knots[4] = 1.0; /* perform correct type of parametrization */ switch(param) { /* uniform parametrization */ case(1): for ( i = 5; i <= numpts+2; i++) knots[i] = knots[i-1] + 1; break; Appendix A: Source Code 187
/*chord length parametrization*/ case(2): distance = curv_pt_dist(1,datpts,2,datpts); ratio = 1/distance; /* calculate domain knots */ for (i = 5; i <= numpts+2; i++) { distance = curv_pt_dist(i-3, datpts, i-2, datpts); knots[i] = distance * ratio + knots[i-1]; } break; /*centripetal parametrization*/ case(3): distance = curv_pt_dist(1, datpts, 2, datpts); ratio = 1/sqrt(distance); /*calculate domain knots*/ for (i = 5; i <= numpts + 2; i++) { distance = sqrt(curv_pt_dist(i-3, datpts, i-2, datpts)); knots[i] = distance*ratio + knots[i-1]; } break; default: for (i=5; i <= numpts+2; i++) knots[i] = knots[i-1] + 1; } if (opcl == OPEN) { distance = knots[3] - knots[4]; for (i = 3; i >= 1; i--) knots[i-1] = knots[i]+distance; distance = knots[numpts+2] - knots[numpts+1]; for (i = 2; i <= 4; i++) knots[numpts+i+1] = knots[numpts+i]+distance; } else { for (i=2; i >= 0; i--) knots[i] = knots[i+1] + (knots[numpts+i-1] - knots[numpts+i]); for (i=3; i <=5; i++) knots[numpts+i] = knots[numpts+i-1] + (knots[i+1] - knots[i]); } } //------------------------------------------------------------------// module name: curv_pt_dist // // Description: calculates the actual distance between two 3-D points // // Input: point arrays for first and last points, point numbers in array // Appendix A: Source Code 188
// Output: distance between points //-------------------------------------------------------------------float curv_pt_dist(int num1, float first[],int num2, float last[]) { float distance; /* distance between points*/ distance = sqrt ((last[3*(num2-1)] - first[3*(num1-1)])* (last[3*(num2-1)] - first[3*(num1-1)])+ (last[3*(num2-1)+1] - first[3*(num1-1)+1])* (last[3*(num2-1)+1] - first[3*(num1-1)+1])+ (last[3*(num2-1)+2] - first[3*(num1-1)+2])* (last[3*(num2-1)+2] - first[3*(num1-1)+2])); return (distance); }
Appendix A: Source Code
189
//============================================================================== // File Name:display_1.C //============================================================================== // // Routine for displaying the Nurbs surface given the control point array, the // knot vector and the order of the polynomial basis //============================================================================== // Karthik Bindiganavle, June 29th, 1999 //============================================================================== #include #include /* To accommodate "exit" */ #include /* To accommodate "strlen" */ #include #include /* Motif Form widget */ #include /* Motif Frame widget */ #include #include #include /* For XA_RGB_DEFAULT_MAP */ #include /* For XmuLookupStandardColormap */ #include /* To access fonts */ #include #include #include #include /* Motif OpenGL drawing area */
//------------------------------------------------------------// subroutines defined in this file (in order) //------------------------------------------------------------void surf_display_1(float u_newknots[], float v_newknots[], float contrlpts[], int newnum[], Display *dpy, Window win, GLXContext glxcontext); static void MakeRasterFont (Display *dpy, Window win, GLXContext glxcontext); static void PrintString (char *); //------------------------------------------------------------// Global variables local to this file //------------------------------------------------------------int showPoints = 0; static GLuint FontOffset; GLuint nub;
//----------------------------------------------------------------------------// surf_display_1 -- gluNurbsSurface // // This routine uses the Nurbs interface provided by GLU for rendering a Nurbs // surface // // Parameters // knots -- knot sequence // ctlpoints -- control point array // dpy -- XtDisplay (glxarea) // win -- XtWindow (glxarea) // glxcontext -- OpenGL rendering context Appendix A: Source Code 190
// // Returns // nothing //----------------------------------------------------------------------------void surf_display_1(float u_newknots[], float v_newknots[], float contrlpts[], int newnum[], Display *dpy, Window win, GLXContext glxcontext) { GLint num_ctrl[2], count, ustride, vstride; int i, j, k; float ctlpoints[7][7][3]; char *A[200] = {"1", "2", "3", "4", "5", "6", "7", "8", "9","10", "11","12","13","14","15","16","17","18","19","20", "21","22","23","24","25","26","27","28","29","30", "31","32","33","34","35","36","37","38","39","40", "41","42","43","44","45","46","47","48","49","50", "51","52","53","54","55","56","57","58","59","60", "61","62","63","64","65","66","67","68","69","70", "71","72","73","74","75","76","77","78","79","80", "81","82","83","84","85","86","87","88","89","90", "91","92","93","94","95","96","97","98","99","100", "101","102","103","104","105","106","107","108","109","110", "111","112","113","114","115","116","117","118","119","120", "121","122","123","124","125","126","127","128","129","130", "131","132","133","134","135","136","137","138","139","140", "141","142","143","144","145","146","147","148","149","150", "151","152","153","154","155","156","157","158","159","160", "161","162","163","164","165","166","167","168","169","170", "171","172","173","174","175","176","177","178","179","180", "181","182","183","184","185","186","187","188","189","190", "191","192","193","194","195","196","197","198","199","200"}; num_ctrl[0] = newnum[0] - 4; num_ctrl[1] = newnum[1] - 4; ustride = num_ctrl[0]*3; vstride = 3; /* get the control points in the x, y, z format 3d array*/ count = 0; for (i=0; ifid; first = fontInfo->min_char_or_byte2; last = fontInfo->max_char_or_byte2; FontOffset = glGenLists ((GLuint) last+1); if (FontOffset == 0) { printf ("out of display lists\n"); exit (0); } glXMakeCurrent (dpy, win, glxcontext); glXUseXFont (id, first, last-first+1, FontOffset+first); } // end-of-MakeRasterFont
static void PrintString (char *s) { glPushAttrib (GL_LIST_BIT); glListBase (FontOffset); glCallLists (strlen(s), GL_UNSIGNED_BYTE, (GLubyte *) s); glPopAttrib (); }
Appendix A: Source Code
193
//============================================================================= // File Name:initX_1.C // Karthik Bindiganavle, June 29th, 1999 //============================================================================= #include #include #include #include /* Motif Form widget */ #include /* Motif Frame widget */ #include #include #include /* For XA_RGB_DEFAULT_MAP */ #include /* For XmuLookupStandardColormap */ #include #include #include #include /* Motif OpenGL drawing area */ /*---------------------------------------------------------------// Define and initiate the X fallback resources (default values). // These variables global to this file only. //----------------------------------------------------------------*/ static String fallbackResources[] = { "*glxarea*width: 1000", "*glxarea*height: 1000", "*frame*x: 20", "*frame*y: 20", "*frame*topOffset: 40", "*frame*rightOffset: 100", "*frame*bottomOffset: 20", "*frame*leftOffset: 50", "*frame*shadowType: SHADOW_IN", NULL }; /*---------------------------------------------------------------// Define and initiate global variables //----------------------------------------------------------------*/ Bool doubleBuffer = True; /*---------------------------------------------------------------// Subroutines defined in this file (in order) //----------------------------------------------------------------*/ void initX (int, char**, // argc, argv void(*)(Widget,XtPointer,XtPointer), // init() void(*)(Widget,XtPointer,XtPointer), // expose() void(*)(Widget,XtPointer,XtPointer), // resize() void(*)(Widget,XtPointer,XtPointer), // input() void(*)(XtPointer,XtIntervalId*), // intervalTimer() unsigned long interval, // seconds Boolean(*) (XtPointer), // idletime XtAppContext*, // app Widget*, // toplevel Widget*, // form Widget*); // glxarea Appendix A: Source Code 194
static Colormap getShareableColormap (Display*, XVisualInfo*, XtAppContext);
/*------------------------------------------------------------------------// initX -// Initialize X and Motif. Define all the widgets that will be in use, // including the OpenGL drawing area widget. At this point the window // only contains a single OpenGL drawing area. The basic callback // functions are passed through at runtime. // // Parameters // argc -- the command line is passed onto X and Motif in case... // argv[] -- ...any resources have been defined // funcInit() -- callback function for OpenGL initialization // funcExpose() -- callback function for drawing OpenGL area // funcResize() -- callback function for handling a window resize // funcInput() -- callback function for handling a input event // funcInterval() -- callback function executed at regular intervals // interval -- initial interval length in msec (1/1000 seconds) // funcIdle() -- callback function executed when X is idle // app -- application context // toplevel -- toplevel Motif Widget // form -- Motif form widget controlling widget locations // glxarea -- Motif/OpenGL drawing area widget // // Returns // nothing //--------------------------------------------------------------------------void initX (int argc, char **argv, void (*funcInit) (Widget, XtPointer, XtPointer), void (*funcExpose) (Widget, XtPointer, XtPointer), void (*funcResize) (Widget, XtPointer, XtPointer), void (*funcInput) (Widget, XtPointer, XtPointer), //void (*funcInterval)(XtPointer,XtIntervalId*), //unsigned long interval, //Boolean(*funcIdle) (XtPointer), XtAppContext *app, Widget *toplevel, Widget *form, Widget *glxarea) { Display *dpy; Widget frame; XVisualInfo *visinfo; Colormap cmap; static int snglBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 12, GLX_RED_SIZE, 1, None}; static int dblBuf[] = {GLX_RGBA, GLX_DEPTH_SIZE, 12, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 1, None}; /*----------------------------------------------------------------------// Initialize the X toolkit and return a top-level widget for the // program. This also starts a connection to the X server. //-----------------------------------------------------------------------*/ *toplevel = XtAppInitialize (app, argv[0], NULL, 0, &argc, argv, fallbackResources, NULL, 0); /*----------------------------------------------------------------------Appendix A: Source Code 195
// Try to open as window in double buffer mode; then single buffer mode. //-----------------------------------------------------------------------*/ dpy = XtDisplay (*toplevel); visinfo = glXChooseVisual (dpy, DefaultScreen(dpy), dblBuf); //cout << visinfo; if (visinfo == NULL) { visinfo = glXChooseVisual (dpy, DefaultScreen(dpy), snglBuf); if (visinfo == NULL) XtAppError (*app, "no good visual"); doubleBuffer = False; } /*----------------------------------------------------------------------// Embed a Motif frame widget in a Motif form widget. //-----------------------------------------------------------------------*/ *form = XmCreateForm (*toplevel, "form", NULL, 0); XtManageChild (*form); frame = XmCreateFrame (*form, "frame", NULL, 0); XtVaSetValues (frame, XmNbottomAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL); XtManageChild (frame); /*----------------------------------------------------------------------// Obtain a colormap for the OpenGL-specific widget. Then create the // OpenGL-specific Motif drawing area widget using this colormap and the // visual information determined earlier. //-----------------------------------------------------------------------*/ cmap = getShareableColormap (dpy, visinfo, *app); *glxarea = XtVaCreateManagedWidget ("glxarea", glwMDrawingAreaWidgetClass, frame, GLwNvisualInfo, visinfo, XtNcolormap, cmap, NULL); /*----------------------------------------------------------------------// Register callbacks for OpenGL initialization & widget expose/resize. // There are a number of other callbacks that can be added. //-----------------------------------------------------------------------*/ XtAddCallback (*glxarea, GLwNginitCallback, funcInit, NULL); XtAddCallback (*glxarea, GLwNexposeCallback, funcExpose, NULL); XtAddCallback (*glxarea, GLwNresizeCallback, funcResize, NULL); XtAddCallback (*glxarea, GLwNresizeCallback, funcInput, NULL); //(void) XtAppAddTimeOut (*app, interval, funcInterval, app); //(void) XtAppAddWorkProc (*app, funcIdle, NULL); } /* end-of-initX */
//------------------------------------------------------------------------// getShareableColormap -// Look through the current color maps to see if there is one that can // be shared with the current application. If none can be found, then // create a new colormap for the application. // See pages 48-51 (section 2.1.1.1) of "OpenGL Programming for the X Appendix A: Source Code 196
// Windowing System". // // Parameters // dpy -- current display // vi -- information about the window (single/double) // // Returns // Colormap //------------------------------------------------------------------------static Colormap getShareableColormap (Display *dpy, XVisualInfo *vi, XtAppContext app) { Status status; XStandardColormap *standardCmaps; Colormap cmap; int i, numCmaps; /* Be lazy; using DirectColor too involved for this example. */ #if defined(__cplusplus) || defined(c_plusplus) if (vi->c_class != TrueColor) /* C++ */ #else if (vi->class != TrueColor) /* regular C */ #endif XtAppError(app, "no support for non-TrueColor visual"); /* If no standard colormap but TrueColor, just make an unshared one. */ status = XmuLookupStandardColormap (dpy, vi->screen, vi->visualid, vi->depth, XA_RGB_DEFAULT_MAP, False, /* Replace */ True); /* Retain */ cout << status; if (status == 1) { status = XGetRGBColormaps (dpy, RootWindow(dpy, vi->screen), &standardCmaps, &numCmaps, XA_RGB_DEFAULT_MAP); cout << status; cout << numCmaps; if (status == 1) for (i = 0; i < numCmaps; i++) if (standardCmaps[i].visualid == vi->visualid) { cmap = standardCmaps[i].colormap; XFree (standardCmaps); return cmap; } } cmap = XCreateColormap (dpy, RootWindow (dpy, vi->screen), vi->visual, AllocNone); return cmap; } /* end-of-getShareableColormap */
Appendix A: Source Code
197
//============================================================================= // File Name:knot_constraint_1.C // // Description: Contains routines to add continuity constraints to the knot // vector // // By: Steven Fleming // Modified by : Karthik Bindiganavle, June 29th, 1999 //============================================================================= #include #define OPEN 0 #define CLOSED 1 int new_knot_num(int numpts, int *continuities); void add_knot_const(int numpts,float knots[],int opcl,int continuities[], int newnum,float newknots[]);
//-----------------------------------------------------------------------------// new_knot_num - Calculates no. of new knots // // input: // numpts – number of xyz points given // continuities – array of continuity constraints // output: // none // // Returns // number of knots //-----------------------------------------------------------------------------int new_knot_num(int numpts, int *continuities) { int newnum,i,j,continuity; j=4; for(i=1;i=1;j--) { newknots[k] = newknots[k-1] + newknots[j] - newknots[j-1]; k++; } } }
Appendix A: Source Code
200
//============================================================================= // File Name:map_point_1.C // // By : Roberto Rohas, Karthik Bindiganavle, June 29th, 1999 //============================================================================= /* Function Prototype */ void map_point(int num,float Nu[],float Nv[],float *ctrlpt, int intU, int intV, float *coordinate); //-----------------------------------------------------------------------------// map_point - computes a single point on a NUBS.One coordinate at a time. // // input: // No. of points in u- direction:numpts[0] // B-spline basis functions:Nu & Nv; // Control points in one coordinate: contrl_x(or y or z) // Interval on the parametric space: IntU & Int V // output: // the value of the coordinate x(or y or z) specified by the parametric // mapping using variables u & v // // Returns // nothing //---------------------------------------------------------------------------void map_point(int num,float Nu[],float Nv[],float *ctrlpt,int intU,int intV, float *coordinate) { int i,j; *coordinate=0.0; for(i=0;i<4;i++) for (j=0;j<4;j++) *coordinate =*coordinate+ ctrlpt[num*(i+intV-3)+(j+intU-3)]*Nu[j]*Nv[i]; }
Appendix A: Source Code
201
//============================================================================= // File Name:model_curve_1.C // // By : Steven Fleming, Karthik Bindiganavle, June 29th, 1999 //============================================================================= #include #include #include #include #include #define OPEN 0 #define CLOSED 1 /*Function Prototypes*/ void Create_NUBS3_Curve(int, float[], int, int[], float [], float [], float[], int&);
extern void curv_parametrize(int, float[], int, int, float[]); extern void curv_add_knot_const(int, float[], int, int[], int, float[]); extern int curv_new_knot_num(int, int*); extern void setup_system(int, float [], int, int [], int, float []); extern void solve_system(int, float [], int, int, int [], float [], float [], float []);
//-----------------------------------------------------------------------------// Create_NUBS3_Curve – computes the curve control points // // input: // No. of points in u(v)- direction // data points to be interpolated // Type of parametrization // Continuity conditions // knot constraints // knot vector // output: // the control point array // Number of knots in the knot sequence // Returns: // nothing //---------------------------------------------------------------------------void Create_NUBS3_Curve(int numpts, float datpts[], int param, int continuities[],float constraints[], float curv_newknots[], float curv_contrlpts[], int &curv_newnum) { float tol = 0.01; float *curv_knots, *Nmat; int opcl,i,j,curv_numctrl; int order = 4; FILE *fp; Appendix A: Source Code 202
/*determine if open or closed*/ if((fabs(datpts[0]-datpts[(numpts-1)*3] ) <=tol)&& (fabs(datpts[1]-datpts[(numpts-1)*3 + 1] ) <=tol) && (fabs(datpts[2]-datpts[(numpts-1)*3 + 2] ) <=tol)) opcl = CLOSED; else opcl = OPEN; if (opcl == CLOSED) curv_knots = new float[numpts + 16]; else curv_knots = new float[numpts + 14]; curv_parametrize(numpts, datpts, opcl,param,curv_knots); curv_newnum = curv_new_knot_num(numpts, continuities); curv_add_knot_const(numpts, curv_knots, opcl, continuities, curv_newnum, curv_newknots); curv_numctrl = curv_newnum - 4; Nmat = new float[(curv_numctrl+1)*(curv_numctrl)]; setup_system(numpts,curv_newknots,opcl,continuities,curv_numctrl,Nmat);
solve_system(numpts,datpts,curv_numctrl,opcl,continuities,constraints,Nmat,curv_ contrlpts); }
Appendix A: Source Code
203
//============================================================================= // File Name:model_surface_1.C // // Description: contains routines to run Model Surface Modelling routine to // allow the user to easily create a cubic NURBS surface on the // NURBS surface function // By : Steven Fleming, Karthik Bindiganavle, June 29th, 1999 //============================================================================= #include #include #include /* Function Prototypes */ void Create_NUBS3_Surface(int numpts[], float datpts[], int param, int u_continuities[], int v_continuities[], float u_constraints[], float v_constraints[], float u_newknots[], float v_newknots[], float contrlpts[], int newnum[]); extern void average_parametrization(int numpts[], float datpts[],int opcl[], int param,float u_knots[],float v_knots[]); extern void add_knot_const(int numpts,float knots[],int opcl,int continuities[], int newnum,float newknots[]); extern int new_knot_num(int numpts, int *continuities); extern void setup_system(int numpts, float knots[], int opcl,int continuities[], int numctrl,float Nmat[]); extern void setup_constraint_matrix(int numpts[],int numctrl[], float datpts[], int opcl[], int u_continuities[], int v_continuities[], float u_constraints[], float v_constraints[], float constraint_matrix[]); extern void solve_systems(int numctrl[], float Amat[], float Bmat[], float constraint_matrix[], float ctrlpts[]);
#define OPEN 0 #define CLOSED 1 //-----------------------------------------------------------------------------// Create_NUBS3_Surface – driver routine to create a cubic NURBS Surface // // input: // No. of points in uv- direction // data points to be interpolated // Type of parametrization // Continuity conditions // knot constraints in U and V directions // knot vector in U and V directions // output: // the control point array // Number of knots in the knot sequence in U and V directions // Returns: // nothing //---------------------------------------------------------------------------Appendix A: Source Code 204
void Create_NUBS3_Surface(int numpts[], float datpts[], int param, int u_continuities[], int v_continuities[], float u_constraints[], float v_constraints[], float u_newknots[], float v_newknots[], float contrlpts[], int newnum[]) { float tol = 0.01; float *u_knots, *v_knots; int opcl[2],i,j,k; int numctrl[2]; float *Amat,*Bmat; float *constraint_matrix;
/*determine if open or closed*/ i=0; opcl[0] = CLOSED; opcl[1] = CLOSED; while((opcl[0] == CLOSED)&&(i #include /* To accommodate "exit" */ #include /* To accommodate "strlen" */ #include #include /* Motif Form widget */ #include /* Motif Frame widget */ #include #include #include /* For XA_RGB_DEFAULT_MAP */ #include /* For XmuLookupStandardColormap */ #include /* To access fonts */ #include #include #include #include /* Motif OpenGL drawing area */
//------------------------------------------------------------// subroutines defined in this file (in order) //------------------------------------------------------------void new_display_1(float new_newknots[], float new_contrlpts[], int new_newnum, Display *dpy, Window win, GLXContext glxcontext); static void MakeRasterFont (Display *dpy, Window win, GLXContext glxcontext); static void PrintString (char *); //------------------------------------------------------------// Global variables local to this file //------------------------------------------------------------int showPointsnew = 1; static GLuint FontOffset; GLuint nub; FILE *fp, *fp2; //-----------------------------------------------------------------------------// new_display_1 -- gluNurbsSurface // // This routine uses the Nurbs interface provided by GLU for rendering a Nurbs // surface // // Parameters // knots -- knot sequence // ctlpoints -- control point array // dpy -- XtDisplay (glxarea) // win -- XtWindow (glxarea) Appendix A: Source Code 207
// glxcontext -- OpenGL rendering context // // Returns // nothing //----------------------------------------------------------------------------void new_display_1(float new_newknots[], float new_contrlpts[], int new_newnum, Display *dpy, Window win, GLXContext glxcontext) { float new_ctlpoints[1][50][3]; //float ctlpts[69]; int i, j, k; GLint new_numctrl, count, stride; char *A[100] = { "1", "2", "3", "4", "5", "6", "7", "8", "9","10", "11","12","13","14","15","16","17","18","19","20", "21","22","23","24","25","26","27","28","29","30", "31","32","33","34","35","36","37","38","39","40", "41","42","43","44","45","46","47","48","49","50", "51","52","53","54","55","56","57","58","59","60", "61","62","63","64","65","66","67","68","69","70", "71","72","73","74","75","76","77","78","79","80", "81","82","83","84","85","86","87","88","89","90", "91","92","93","94","95","96","97","98","99","100"}; new_numctrl = new_newnum - 4; stride = 3; /* get the control points in the x, y, z format 3d array*/ count = 0; for (i=0; i<1; i++) { for (j=0; jfid; first = fontInfo->min_char_or_byte2; last = fontInfo->max_char_or_byte2; FontOffset = glGenLists ((GLuint) last+1); if (FontOffset == 0) { printf ("out of display lists\n"); exit (0); } glXMakeCurrent (dpy, win, glxcontext); glXUseXFont (id, first, last-first+1, FontOffset+first); } // end-of-MakeRasterFont
static void PrintString (char *s) { glPushAttrib (GL_LIST_BIT); glListBase (FontOffset); glCallLists (strlen(s), GL_UNSIGNED_BYTE, (GLubyte *) s); glPopAttrib (); }
Appendix A: Source Code
210
//==================================================================== // Name: new_point_and_derivative_1.c // // By: Roberto Rojas // Modified by: Karthik Bindiganavle // //==================================================================== #include void new_point(int num, int num1, int trimnum, float u_newknots[], float v_newknots[], float control_x[], float control_y[], float control_z[], float trim_data[], int sampling_rate, int v_final_new_id[],float trim_points[]); extern void basis(float, int, float*, float[]); extern void map_point(int, float[], float[], float*, int, int, float*); //-----------------------------------------------------------------------------// new_point – Computes new "data" points and derivatives // on the trimmed patch // // input: // num : number of u direction points, // num1 : number of u direction points // trimnum : number of points defining the trimming curve // which are also the number of "data points" in the v // direction. // u and v _newknots : so that the basis can be used to compute N. // control_x // and control_y : To be used with N to map points on the original // surface using map_point. // trim_data : pointer to the array containing uv trim data // points // sampling_rate : the number of times the data is sampled // between each interval // v_final_new_id : the new knot sequence with the knots at points where // curvature optima occurred in the original knot // sequence. // output: // trim_points : pointer to array containing data points pertaining to // trimmed surface , to be used when calling // Model_surface. // Returns: // nothing //---------------------------------------------------------------------------void new_point (int num, int num1, int trimnum, float u_newknots[], float v_newknots[], float control_x[], float control_y[], float control_z[], float trim_data[], int sampling_rate, int v_final_new_id[], float trim_points[]) { int i,j,k,l,flag; int intU, intV; float u,v,ratio; float x,y,z; float Nu[4], Nv[4]; Appendix A: Source Code 211
for (j=0; j=u_newknots[k] && u=v_newknots[l] && v #include /* To accommodate "exit" */ #include /* To accommodate "strlen" */ #include #include /* Motif Form widget */ #include /* Motif Frame widget */ #include #include #include /* For XA_RGB_DEFAULT_MAP */ #include /* For XmuLookupStandardColormap */ #include /* To access fonts */ #include #include #include #include /* Motif OpenGL drawing area */
//------------------------------------------------------------// subroutines defined in this file (in order) //------------------------------------------------------------void new_trim_surf_display_1(float new_ut_newknots[], float new_vt_newknots[], float new_t_contrlpts[], int new_t_newnum[], Display *dpy, Window win, GLXContext glxcontext); static void MakeRasterFont (Display *dpy, Window win, GLXContext glxcontext); static void PrintString (char *); //------------------------------------------------------------// Global variables local to this file //------------------------------------------------------------int showPoints_new_trim = 0; static GLuint FontOffset; GLuint nub; //-----------------------------------------------------------------------------// new_trim_surf_display_1 -- gluNurbsSurface // // This routine uses the Nurbs interface provided by GLU for rendering a Nurbs // surface // // Parameters // knots -- knot sequence // ctlpoints -- control point array // dpy -- XtDisplay (glxarea) // win -- XtWindow (glxarea) // glxcontext -- OpenGL rendering context Appendix A: Source Code 213
// // Returns // nothing //----------------------------------------------------------------------------void new_trim_surf_display_1(float new_ut_newknots[], float new_vt_newknots[], float new_t_contrlpts[], int new_t_newnum[], Display *dpy, Window win, GLXContext glxcontext) { GLint num_ctrl[2], count, ustride, vstride; int i, j, k; float new_t_ctlpoints[7][37][3]; char *A[180] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99","100", "101","102","103","104","105","106","107","108","109","110", "111","112","113","114","115","116","117","118","119","120", "121","122","123","124","125","126","127","128","129","130", "131","132","133","134","135","136","137","138","139","140", "141","142","143","144","145","146","147","148","149","150", "151","152","153","154","155","156","157","158","159","160", "161","162","163","164","165","166","167","168","169","170", "171","172","173","174","175","176","177","178","179","180"}; num_ctrl[0] = new_t_newnum[0] - 4; num_ctrl[1] = new_t_newnum[1] - 4; ustride = num_ctrl[0]*3; vstride = 3; /* get the control points in the x, y, z format 3d array*/ count = 0; for (i=0; ifid; first = fontInfo->min_char_or_byte2; last = fontInfo->max_char_or_byte2; FontOffset = glGenLists ((GLuint) last+1); if (FontOffset == 0) { printf ("out of display lists\n"); exit (0); } glXMakeCurrent (dpy, win, glxcontext); glXUseXFont (id, first, last-first+1, FontOffset+first); } // end-of-MakeRasterFont
static void PrintString (char *s) { glPushAttrib (GL_LIST_BIT); glListBase (FontOffset); glCallLists (strlen(s), GL_UNSIGNED_BYTE, (GLubyte *) s); glPopAttrib (); }
Appendix A: Source Code
216
//================================================================ // Filename: parametrize_1.C // Author: Steven fleming // modified by Karthik Bindiganavle // // Description: contains parametrization routines for // Cubic B-spline curves. //================================================================ #include #include #include void parametrize(int numpts, float datpts[], int opcl, int param, float knots[]); float pt_dist(int num1, float first[],int num2, float last[]); #define OPEN 0 #define CLOSED 1 //---------------------------------------------------------------// Function: curv_parametrize // // Author: Steven Fleming // // Description: To parametrize a cubic B-spline curve based on chord length // Method // // Inputs: number of points, array of data points, open or closed, // type of parametrization // // Outputs: Knot vector //---------------------------------------------------------------void parametrize(int numpts, float datpts[], int opcl, int param, float knots[]) { float ratio; /*ratio of knot spacing to point dist*/ float distance; float first[3], last[3]; int i; float tol = 0.01; /* initialize first knot interval */ knots[3] = 0.0; knots[4] = 1.0; /* perform correct type of parametrization */ switch(param) { /* uniform parametrization */ case(1): for ( i = 5; i <= numpts+2; i++) knots[i] = knots[i-1] + 1; break;
/*chord length parametrization*/ Appendix A: Source Code 217
case(2): distance = pt_dist(1,datpts,2,datpts); ratio = 1/distance; /* calculate domain knots */ for (i = 5; i <= numpts+2; i++) { distance = pt_dist(i-3, datpts, i-2, datpts); knots[i] = distance * ratio + knots[i-1]; } break; /*centripetal parametrization*/ case(3): distance = pt_dist(1, datpts, 2, datpts); ratio = 1/sqrt(distance); /*calculate domain knots*/ for (i = 5; i <= numpts + 2; i++) { distance = sqrt(pt_dist(i-3, datpts, i-2, datpts)); knots[i] = distance*ratio + knots[i-1]; } break; default: for (i=5; i <= numpts+2; i++) knots[i] = knots[i-1] + 1; } if (opcl == OPEN) { distance = knots[3] - knots[4]; for (i = 3; i >= 1; i--) knots[i-1] = knots[i] + distance; distance = knots[numpts+2] - knots[numpts+1]; for (i = 2; i <= 4; i++) knots[numpts+i+1] = knots[numpts+i] + distance; } else { for (i=2; i >= 0; i--) knots[i] = knots[i+1] + (knots[numpts+i-1] - knots[numpts+i]); for (i=3; i <=5; i++) knots[numpts+i] = knots[numpts+i-1] + (knots[i+1] - knots[i]); } /* calculate the end knots for open and closed curves */ /*if (opcl == OPEN) { distance = knots[3] - knots[4]; for (i = 3; i >= 1; i--) knots[i-1] = knots[i] + distance; distance = knots[numpts+2] - knots[numpts+1]; for (i = 2; i <= 4; i++) knots[numpts+i+1] = knots[numpts+i] + distance; } Appendix A: Source Code 218
else { for (i=2; i >= 0; i--) knots[i] = knots[i+1] + (knots[numpts+i-1] - knots[numpts+i]); for (i=3; i <=5; i++) knots[numpts+i] = knots[numpts+i-1] + (knots[i+1] - knots[i]); }*/ } //------------------------------------------------------------------// module name: pt_dist // // Description: calculates the actual distance between two 3-D points // // Input: point arrays for first and last points, point numbers in array // // Output: distance between points //-------------------------------------------------------------------float pt_dist(int num1, float first[],int num2, float last[]) { float distance; /* distance between points*/ distance = sqrt ((last[3*(num2-1)] - first[3*(num1-1)])* (last[3*(num2-1)] - first[3*(num1-1)])+ (last[3*(num2-1)+1] - first[3*(num1-1)+1])* (last[3*(num2-1)+1] - first[3*(num1-1)+1])+ (last[3*(num2-1)+2] - first[3*(num1-1)+2])* (last[3*(num2-1)+2] - first[3*(num1-1)+2])); return (distance); }
Appendix A: Source Code
219
//==================================================================== // Name: new_point_and_derivative_1.c // // By: Roberto Rojas // Modified by: Karthik Bindiganavle // //==================================================================== #include void point(int num, int trimnum, float u_newknots[], float v_newknots[], float control_x[], float control_y[], float control_z[], float trim_data[], float trim_points[]); extern void basis(float, int, float*, float[]); extern void map_point(int, float[], float[], float*, int, int, float*); //-----------------------------------------------------------------------------// point – Computes new "data" points and derivatives // on the trimmed patch // // input: // num : number of u direction points, // num1 : number of u direction points // trimnum : number of points defining the trimming curve // which are also the number of "data points" in the v // direction. // u and v _newknots : so that the basis can be used to compute N. // control_x // and control_y : To be used with N to map points on the original // surface using map_point. // trim_data : pointer to the array containing uv trim data // points // output: // trim_points : pointer to array containing data points pertaining to // trimmed surface , to be used when calling // Model_surface. // Returns: // nothing //---------------------------------------------------------------------------void point (int num, int trimnum, float u_newknots[], float v_newknots[], float control_x[], float control_y[], float control_z[], float trim_data[], float trim_points[]) { int i,j,k,l,flag; int intU, intV; float u,v; float x,y,z; float Nu[4], Nv[4]; for (j=0; j=u_newknots[k] && u=v_newknots[l] && v #include void setup_system(int numpts, float knots[], int opcl,int continuities[], int numctrl,float Nmat[]); extern void basis(float u, int interval, float knots[], float N[]); extern void dbasis(float u, int interval, float knots[], float dN[]); #define OPEN 0 #define CLOSED 1 //-----------------------------------------------------------------------// Function: setup_system - Basically sets up basis function matrix // // input: // number of data points // array of continuities // open/closed flag // new knot vector // number of control points // // output: // basis function matrix (nxn part of nxn+1 matrix) // //-----------------------------------------------------------------------void setup_system(int numpts, float knots[], int opcl,int continuities[], int numctrl,float Nmat[]) { int continuity, i, j, n; int interval = 0; float N[4], dN[4], count; n = numctrl; continuity = continuities[0]; switch(continuity) { case(0): case(1): interval = 3; dbasis(knots[3], interval , knots, dN); Nmat[0] = dN[0]; Nmat[1] = dN[1]; break; default: if ( opcl == OPEN) { Appendix A: Source Code 222
Nmat[0] = 1; Nmat[1] = -1; } else { Nmat[0] = 1; Nmat[n-3] = -1; } } interval = 3; basis(knots[3], interval , knots, N); Nmat[n+1] = N[0]; Nmat[n+2] = N[1]; Nmat[n+3] = N[2]; j = 2; count = numpts-1; for (i=1; i #include void solve_lin_syst(int n, float Mat[], int *error, float x[]); //-----------------------------------------------------------------// solve_lin_syst - Solves a linear system of equations given an augmented // matrix of size n x n + 1 // // Input: // number of equations, // augmented matrix (n x n + 1) // // Output: // error flag (checks for unique solution) // column vector of soultion values //-----------------------------------------------------------------void solve_lin_syst(int n, float Mat[], int *error, float x[]) { int i, *nrow, j, k, p, flag = 1, ncopy; float *scale, *A, factor, nextfact, sum, absA; A = new float[(n+1)*n]; for (i=0; iscale[i]) scale[i] = absA; } if (scale[i] == 0) {flag = 0; i= n-1;} nrow[i] = i; } if (flag) { for (i=0; i factor) { p = j; factor = nextfact; } } if (A[(n+1)*nrow[p]+i] ==0) {flag = 0; i = n-2;} if (flag) { if (nrow[i] != nrow[p]) { ncopy = nrow[i]; nrow[i] = nrow[p]; nrow[p] = ncopy; } for (j = i+1; j=0; i--) { sum = 0; for (j = i+1; j extern void solve_lin_syst(int, float [], int *, float []); void solve_system(int numpts, float datpts[], int numctrl, int opcl, int continuities[], float constraints[], float Nmat[], float ctrlpts[]); #define OPEN 0 #define CLOSED 1 //-----------------------------------------------------------------// solve_system - Adds constraints to system and solves for the control // points of the B-spline curve // // inputs: // number of data points // array of data points // no of control points // open/closed flag // continuities // Nmat // constraints // // Outputs: // control point array //-----------------------------------------------------------------void solve_system(int numpts, float datpts[], int numctrl, int opcl, int continuities[], float constraints[], float Nmat[], float ctrlpts[]) { int continuity,i,j,k,l,m,n,a,b,error; int x,y; float *xpts,*ypts,*zpts; n = numctrl; xpts = new float[n]; ypts = new float[n]; zpts = new float[n]; for (i=0;i<3;i++) { continuity = continuities[0]; switch(continuity) { Appendix A: Source Code 228
case(0): Nmat[n] = constraints[3+i]; k=2; break; case(1): Nmat[n] = constraints[i]; k=1; break; default: Nmat[n] = 0; k=0; } Nmat[(n+1)+n] = datpts[i]; l=1; m=2; for (j=1;j #include
void setup_constraint_matrix(int numpts[],int numctrl[], float datpts[], int opcl[], int u_continuities[], int v_continuities[], float u_constraints[], float v_constraints[], float constraint_matrix[]); void u_tan_pt_constraints(int row, int crow, int numpts, float datpts[], int numctrl, int opcl,int continuities[], float constraints[], float constraint_matrix[]); void v_tan_pt_constraints(int row, int crow, int numpts, float datpts[], int numctrl, int opcl,int continuities[], float constraints[], float constraint_matrix[]); void solve_systems(int numctrl[], float Amat[], float Bmat[], float constraint_matrix[], float ctrlpts[]);
extern void solve_lin_syst(int n, float Mat[], int *error, float x[]);
#define OPEN 0 #define CLOSED 1
//----------------------------------------------------------------------------// setup_constraint_matrix - Driver for assembling B-spline surface // constraint matrix (CS = Amat*Ctrl*Bmat ) // // Inputs: // number of data points // array of data points // no of control points // open/closed flag // (uv) continuities // (uv) constraints // // Outputs: // constraint matrix //---------------------------------------------------------------------------void setup_constraint_matrix(int numpts[],int numctrl[], float datpts[], int opcl[], int u_continuities[], int v_continuities[], float u_constraints[], float v_constraints[], float constraint_matrix[]) Appendix A: Source Code 231
{ int i,row,crow,column,continuity; /* load constraints for each u row */ row = 1; crow = 0; u_tan_pt_constraints(row,crow,numpts[0],datpts,numctrl[0],opcl[0], u_continuities, u_constraints,constraint_matrix); crow++; for (i=2;i #include #include #include #include void sort(int, int [], int, int [], int, int [], int, int [], int, int [], int&, int []); //-----------------------------------------------------------------------// Function: sort - Basically sets up optimized knot sequence // // input: // number of knots on each curve // array of locations of curvature optima on each curve // // output: // knot count of the new knot vector // refined knot sequence // //-----------------------------------------------------------------------void sort(int icount_begin, int new_id_at_begin_curve[], int icount_one, int new_id_at_one_curve[], int icount_two, int new_id_at_two_curve[], int icount_three, int new_id_at_three_curve[], int icount_end, int new_id_at_end_curve[], int &final_count, int new_id[]) { int i, j, flag; int temp = 0; final_count = 0; for (i=0; inew_id[i+1]) { temp = new_id[i]; new_id[i] = new_id[i+1]; new_id[i+1] = temp; } } } }
Appendix A: Source Code
242
//===================================================================== // File Name: sort1_1.C // By: Karthik Bindiganavle // // Description: sorts and sieves the knot sequence to obtain a unique // knot sequence having knot values which correspond to occurance // of curvature optima //===================================================================== #include #include #include #include #include void sort1(int, int [], int, int [], int, int [], int, int [], int, int [], int, int [], int, int [], int, int [], int, int [], int, int [], int, int [], int, int [], int, int [], int, int [], int, int [], int, int [], int, int [], int, int [], int, int [], int, int [], int, int [], int&, int []); //-----------------------------------------------------------------------// Function: sort1 - Basically sets up optimized knot sequence // // input: // number of knots on each curve // array of locations of curvature optima on each curve // // output: // knot count of the new knot vector // refined knot sequence // //-----------------------------------------------------------------------void sort1(int v_icount_one, int v_new_id_at_one_curve[], int v_icount_two, int v_new_id_at_two_curve[], int v_icount_three, int v_new_id_at_three_curve[], int v_icount_four, int v_new_id_at_four_curve[], int v_icount_five, int v_new_id_at_five_curve[], int v_icount_six, int v_new_id_at_six_curve[], int v_icount_seven, int v_new_id_at_seven_curve[], int v_icount_eight, int v_new_id_at_eight_curve[], int v_icount_nine, int v_new_id_at_nine_curve[], int v_icount_ten, int v_new_id_at_ten_curve[], int v_icount_eleven, int v_new_id_at_eleven_curve[], int v_icount_twelve, int v_new_id_at_twelve_curve[], int v_icount_thirteen, int v_new_id_at_thirteen_curve[], int v_icount_fourteen, int v_new_id_at_fourteen_curve[], int v_icount_fifteen, int v_new_id_at_fifteen_curve[], int v_icount_sixteen, int v_new_id_at_sixteen_curve[], int v_icount_seventeen, int v_new_id_at_seventeen_curve[], int v_icount_eighteen, int v_new_id_at_eighteen_curve[], int v_icount_nineteen, int v_new_id_at_nineteen_curve[], int v_icount_twenty, int v_new_id_at_twenty_curve[], int v_icount_twentyone, int v_new_id_at_twentyone_curve[], Appendix A: Source Code 243
int &final_count, int new_id[]) { int i, j, flag; int temp = 0; final_count = 0; for (i=0; inew_id[i+1]) { temp = new_id[i]; new_id[i] = new_id[i+1]; new_id[i+1] = temp; } } } }
Appendix A: Source Code
252
//============================================================================ // Name: sur_knots.c // By: Steven Fleming // Modified by: Karthik Bindiganavle // // Description: Calculates the u & v knot vectors for a non-uniform B-spline // surface // // Note: Adapted from code by Robert Jones //============================================================================ #include #define OPEN 0 #define CLOSED 1 void average_parametrization(int numpts[], float datpts[],int opcl[], int param,float u_knots[],float v_knots[]); void calc_u_knots(int numpts[],float datpts[],int opcl[],int param, float u_knots[]); void calc_v_knots(int numpts[],float datpts[],int opcl[],int param, float v_knots[]); float average_u_distance(int numpts[], float datpts[], int n1, int n2); float average_v_distance(int numpts[], float datpts[], int n1, int n2); float point_distance(float first[] ,float last[]); //--------------------------------------------------------------------------// average_parametrization - driver to calculate u & v surface knots based on // chord length parametrization // // Inputs: // array of number of data points in both parametric directions, // array of data pts // array of open/closed flags (u,v) // // Outputs: // u_knots,v_knots // //--------------------------------------------------------------------------void average_parametrization(int numpts[], float datpts[],int opcl[],int param,float u_knots[],float v_knots[]) { calc_u_knots(numpts, datpts, opcl, param, u_knots); calc_v_knots(numpts, datpts, opcl, param, v_knots); } //--------------------------------------------------------------------------// calc_u_knots - calculates the chord length u_knots for a NURB surface // // Inputs: // array of number of points in each direction // array of data pts // array of open/closed flags // type of parametrization // // Outputs: // u_knots Appendix A: Source Code 253
//--------------------------------------------------------------------------void calc_u_knots(int numpts[],float datpts[],int opcl[],int param,float u_knots[]) { int npts,i; float ratio; /* ratio of knot spacing to pt distance */ float distance; /* knot distance */ /* --- initialize knot spacing --- */ u_knots[3] = 0.0; u_knots[4] = 1.0; /* perform correct type of parametrization */ switch(param) { /* uniform parametrization */ case(1): for ( i = 5; i<= numpts[0]+2;i++ ) u_knots[i] = u_knots[i-1] + 1; break; /* chord length parametrization */ case(2): ratio = average_u_distance(numpts,datpts,0,1); /* calculate interior knots */ for ( i = 5; i <= numpts[0] + 2;i++ ) { u_knots[i] = average_u_distance(numpts,datpts,i-4,i-3)/ratio + u_knots[i1]; } break; /* centripetal parametrization */ case 3: ratio = sqrt(average_u_distance(numpts,datpts,1,2)); /* calculate interior knots */ for (i=5; i<=numpts[0]+2; i++) { u_knots[i] = sqrt(average_u_distance(numpts,datpts,i-3,i-2))/ratio + u_knots[i-1]; } break; default: for ( i=5; i<=numpts[0]+2;i++ ) u_knots[i] = u_knots[i-1] + 1; break; } /* --- Calculate End Knots based on open or closed curves --- */ npts = numpts[0]; if (opcl[0] == OPEN ) /* open curve */ { distance = u_knots[3] - u_knots[4]; u_knots[2] = u_knots[3] + distance; u_knots[1] = u_knots[2] + distance; Appendix A: Source Code 254
u_knots[0] = u_knots[1] + distance; distance = u_knots[npts+2] - u_knots[npts+1]; u_knots[npts+3] = u_knots[npts+2] + distance; u_knots[npts+4] = u_knots[npts+3] + distance; u_knots[npts+5] = u_knots[npts+4] + distance; } else
/* closed curve */
{ u_knots[2] = u_knots[3] + ( u_knots[npts+1] - u_knots[npts+2]); u_knots[1] = u_knots[2] + ( u_knots[npts] - u_knots[npts+1]); u_knots[0] = u_knots[1] + ( u_knots[npts-1] - u_knots[npts]); u_knots[npts+3] = u_knots[npts+2] + ( u_knots[4] - u_knots[3]); u_knots[npts+4] = u_knots[npts+3] + ( u_knots[5] - u_knots[4]); u_knots[npts+5] = u_knots[npts+4] + ( u_knots[6] - u_knots[5]); } }
//--------------------------------------------------------------------------// calc_v_knots - calculates the chord length u_knots for a NURB surface // // Inputs: // array of number of points in each direction // array of data pts // array of open/closed flags // type of parametrization // // Outputs: // v_knots //--------------------------------------------------------------------------void calc_v_knots(int numpts[],float datpts[],int opcl[],int param, float v_knots[]) { int npts,i; /* no of pts per c/s , for loop values */ float ratio; /* ratio of knot spacing to pt distance */ float distance; /* knot distance */ /* --- initialize knot spacing --- */ v_knots[3] = 0.0; v_knots[4] = 1.0; /* perform correct type of parametrization */ switch(param) { /* uniform parametrization */ case(1): for (i=5;i<=numpts[1]+2;i++) v_knots[i] = v_knots[i-1] + 1; break; /* chord length parametrization */ case(2): ratio = average_v_distance(numpts,datpts,0,1); Appendix A: Source Code 255
/* calculate interior knots */ for (i=5;i<=numpts[1]+2;i++) { v_knots[i] = average_v_distance(numpts,datpts,i-4,i-3)/ratio + v_knots[i-1]; } break; /* centripetal parametrization */ case 3: ratio = sqrt(average_v_distance(numpts,datpts,1,2)); /* calculate interior knots */ for (i=5; i<=numpts[1]+2; i++) { v_knots[i] = sqrt(average_v_distance(numpts,datpts,i-3,i-2))/ratio + v_knots[i-1]; } break; default: for ( i=5; i<=numpts[0]+2;i++ ) v_knots[i] = v_knots[i-1] + 1; break; } /* --- Calculate End Knots npts = numpts[1]; if (opcl[1] == OPEN ) { distance = v_knots[3] v_knots[2] = v_knots[3] v_knots[1] = v_knots[2] v_knots[0] = v_knots[1] based on open or closed curves --- */ /* open curve */ v_knots[4]; + distance; + distance; + distance;
distance = v_knots[npts+2] - v_knots[npts+1]; v_knots[npts+3] = v_knots[npts+2] + distance; v_knots[npts+4] = v_knots[npts+3] + distance; v_knots[npts+5] = v_knots[npts+4] + distance; } else /* { v_knots[2] = v_knots[1] = v_knots[0] =
closed curve */ v_knots[3] + ( v_knots[npts+1] - v_knots[npts+2]); v_knots[2] + ( v_knots[npts] - v_knots[npts+1]); v_knots[1] + ( v_knots[npts-1] - v_knots[npts]);
v_knots[npts+3] = v_knots[npts+2] + ( v_knots[4] - v_knots[3]); v_knots[npts+4] = v_knots[npts+3] + ( v_knots[5] - v_knots[4]); v_knots[npts+5] = v_knots[npts+4] + ( v_knots[6] - v_knots[5]); } }
//------------------------------------------------------------------------// average_u_distance - computes the average distance between two u values Appendix A: Source Code 256
// // Inputs: // array of number of points in u and v // array of data points // n1, n2 (data point sequence numbers in u direction) // // Outputs: // Average distance between data points in u interval //------------------------------------------------------------------------float average_u_distance(int numpts[], float datpts[], int n1, int n2) { int i; float distance, sum, average; float first[3],last[3]; int count; /* number of distances */ sum = count = 0; /* initialize sum */ for ( i = 0; i < numpts[1]; i++ ) { first[0] = datpts[3*numpts[0]*i+3*n1]; first[1] = datpts[3*numpts[0]*i+3*n1+1]; first[2] = datpts[3*numpts[0]*i+3*n1+2]; last[0] = datpts[3*numpts[0]*i+3*n2]; last[1] = datpts[3*numpts[0]*i+3*n2+1]; last[2] = datpts[3*numpts[0]*i+3*n2+2]; distance = point_distance(first,last); /* calculate distance */ count++; sum = sum + distance; /* sum up distances */ } average = sum/count; return(average); } //------------------------------------------------------------------------// average_v_distance - computes the average distance between two v values // // Inputs: // array of number of points in u and v // array of data points // n1, n2 (data point sequence numbers in v direction) // // Outputs: // Average distance between data points in v interval //------------------------------------------------------------------------float average_v_distance(int numpts[], float datpts[], int n1, int n2) { int i; float distance, sum, average; float first[3],last[3]; int count; /* number of distances */ sum = count = 0; /* initialize sum */ for ( i = 0; i < numpts[0]; i++ ) Appendix A: Source Code 257
{ first[0] = datpts[3*numpts[0]*n1+3*i]; first[1] = datpts[3*numpts[0]*n1+3*i+1]; first[2] = datpts[3*numpts[0]*n1+3*i+2]; last[0] = datpts[3*numpts[0]*n2+3*i]; last[1] = datpts[3*numpts[0]*n2+3*i+1]; last[2] = datpts[3*numpts[0]*n2+3*i+2]; distance = point_distance(first,last); /* calculate distance */ count++; sum = sum + distance; /* sum up distances */ } average = sum/count; return(average); }
//---------------------------------------------------------------------// point_distance - Calculates the actual distance between the two 3-d points // // Inputs: // point arrays for first and last points // // Outputs: // distance between points //---------------------------------------------------------------------float point_distance(float first[] ,float last[]) { float distance; distance = sqrt((last[0] - first[0]) * (last[0] - first[0]) + (last[1] - first[1]) * (last[1] first[1]) + (last[2] - first[2]) * (last[2] - first[2])); return(distance); }
Appendix A: Source Code
258
//============================================================================== // File Name:trim_display_1.C // // Routine for displaying the Nurbs surface given the control point array, the // knot vector and the order of the polynomial basis // // Karthik Bindiganavle, June 29th, 1999 //============================================================================== #include #include /* To accommodate "exit" */ #include /* To accommodate "strlen" */ #include #include /* Motif Form widget */ #include /* Motif Frame widget */ #include #include #include /* For XA_RGB_DEFAULT_MAP */ #include /* For XmuLookupStandardColormap */ #include /* To access fonts */ #include #include #include #include /* Motif OpenGL drawing area */
//------------------------------------------------------------// subroutines defined in this file (in order) //------------------------------------------------------------void trim_surf_display_1(float ut_newknots[], float vt_newknots[], float t_contrlpts[], int t_newnum[], int t_numctrl[], Display *dpy, Window win, GLXContext glxcontext); static void MakeRasterFont (Display *dpy, Window win, GLXContext glxcontext); static void PrintString (char *); //------------------------------------------------------------// Global variables local to this file //------------------------------------------------------------int showPoints_trim = 0; static GLuint FontOffset; GLuint nub; //-----------------------------------------------------------------------------// trim_surf_display_1 -- gluNurbsCurve // // This routine uses the Nurbs interface provided by GLU for rendering a b// spline curve // // Parameters // knots -- knot sequence // ctlpoints -- control point array // dpy -- XtDisplay (glxarea) // win -- XtWindow (glxarea) // glxcontext -- OpenGL rendering context // Appendix A: Source Code 259
// Returns // nothing //-----------------------------------------------------------------------------void trim_surf_display_1(float ut_newknots[], float vt_newknots[], float t_contrlpts[], int t_newnum[], int t_numctrl[], Display *dpy, Window win, GLXContext glxcontext) { GLint num_ctrl[2], count, ustride, vstride; int i, j, k; float t_ctlpoints[43][7][3]; char *A[180] = {"1", "2", "3", "4", "5", "6", "7", "8", "9","10", "11","12","13","14","15","16","17","18","19","20", "21","22","23","24","25","26","27","28","29","30", "31","32","33","34","35","36","37","38","39","40", "41","42","43","44","45","46","47","48","49","50", "51","52","53","54","55","56","57","58","59","60", "61","62","63","64","65","66","67","68","69","70", "71","72","73","74","75","76","77","78","79","80", "81","82","83","84","85","86","87","88","89","90", "91","92","93","94","95","96","97","98","99","100", "101","102","103","104","105","106","107","108","109","110", "111","112","113","114","115","116","117","118","119","120", "121","122","123","124","125","126","127","128","129","130", "131","132","133","134","135","136","137","138","139","140", "141","142","143","144","145","146","147","148","149","150", "151","152","153","154","155","156","157","158","159","160", "161","162","163","164","165","166","167","168","169","170", "171","172","173","174","175","176","177","178","179","180", "181","182","183","184","185","186","187","188","189","190", "191","192","193","194","195","196","197","198","199","200"};
num_ctrl[0] = t_newnum[0] - 4; num_ctrl[1] = t_newnum[1] - 4; ustride = num_ctrl[0]*3; vstride = 3; /* get the control points in the x, y, z format 3d array*/ count = 0; for (i=0; ifid; first = fontInfo->min_char_or_byte2; last = fontInfo->max_char_or_byte2; FontOffset = glGenLists ((GLuint) last+1); if (FontOffset == 0) { printf ("out of display lists\n"); exit (0); } glXMakeCurrent (dpy, win, glxcontext); glXUseXFont (id, first, last-first+1, FontOffset+first); } // end-of-MakeRasterFont
static void PrintString (char *s) { glPushAttrib (GL_LIST_BIT); glListBase (FontOffset); glCallLists (strlen(s), GL_UNSIGNED_BYTE, (GLubyte *) s); glPopAttrib (); }
Appendix A: Source Code
262
//============================================================================== // File Name: v_bspline_diff_geo_1.C // Karthik Bindiganavle, June 29th, 1999 //============================================================================== #include #include #include #include #include void v_bspline_diff_geo(int, float [], float [], float[], float [], float [], float [], float [], float [], float [], int&, int []); //-----------------------------------------------------------------------------// v_bspline_diff_geo : // Routine for calculating the Curvature, Torsion, Tangent, Normal and Bi// Normal of a B-Spline curve (Can be extended to a surface also) // // input : // curv_newnum – number of knots in the knot vector // curv_newknots - knot vector for the curve // curv_contrlpts - control point vector of the curve // Output: // tangent(T), Normal(N), bi_normal(B_N) and the datapoints on the // curve at curvature optimas(datapoint_at_new_id) and the new knot // sequence (new_id) whose knot values are values at which curvature // optima occur //-----------------------------------------------------------------------------void v_bspline_diff_geo(int curv_newnum, float curv_newknots[], float curv_contrlpts[], float s_x[], float s_y[], float s_z[], float T[], float N[], float B_N[], float datapoint_at_new_id[], int &icount, int new_id[]) { FILE *fp, *fp1, *fp2; float *ctrlpts_x, *ctrlpts_y, *ctrlpts_z; float u, x, y, increment; //parameter value between a pair of knots float *knots; float c_x[25000], c_y[25000], c_z[25000]; //x, y, z variables for the center //of the osculating circle float diff_s_x[25000], diff_s_y[25000], diff_s_z[25000]; //dx, dy, dz arrays for a b-spline // curve float diff2_s_x[25000], diff2_s_y[25000], diff2_s_z[25000]; //d(sqr)x, d(sqr)y, d(sqr)z arrays float diff3_s_x[25000], diff3_s_y[25000], diff3_s_z[25000]; //d(cub)x, d(cub)y, d(cub)z arrays float diff_vector[25000]; //vector of first derivatives float diff2_vector[25000]; //vector of second derivatives float diff3_vector[25000]; //vector of third derivatives float det_i, det_j, det_k; //variables used while calculating the //cross product of two vectors float mod_crs_prdt, mod_fir_der; //mod_crs_prdt = modulus of the X product // of two vectors Appendix A: Source Code 263
//mod_fir_der = modulus of the vector of // first derivatives float tripl_prod; //vector triple product variable float kappa[25000], rho[25000]; //Curvature and radius of //curvature variable float tau[25000]; //torsion variable int n = 4; //degree of spline int id, count, i, j, k, h, final_count; //id = interval id. int L = 4; //no_of_active_intervals/no_of_domain_intervals int start_int_id, end_int_id, u_counter; //start and end of the domain knots float A, B, C, D;
knots = new float[curv_newnum]; for(i=0; i0)&&((kappa[j+1]-kappa[j])<=0)|| ((kappa[j]-kappa[j-1])<0)&&((kappa[j+1]-kappa[j])>=0)) { new_id[i] = j; datapoint_at_new_id[3*i+0]=s_x[j]; datapoint_at_new_id[3*i+1]=s_y[j]; datapoint_at_new_id[3*i+2]=s_z[j]; i++; } }
datapoint_at_new_id[3*i+0]=s_x[j]; datapoint_at_new_id[3*i+1]=s_y[j]; datapoint_at_new_id[3*i+2]=s_z[j]; Appendix A: Source Code 273
new_id[i]= j; icount = i+1; }
Appendix A: Source Code
274
//============================================================================= // Name: volume_grid_1.C // By: Roberto Rojas // Modified by Karthik Bindiganavle // // Description: Creates a grid of datapoints to be later used to create // differential volumes // Note: The higher the grid, the better the accuracy //============================================================================ #include extern void basis(float, int, float*, float[]); extern void map_point(int, float[], float[], float*, int, int, float*); void get_orig_points(int num, int trimnum, int grid_u, int grid_v, float *trim_data, float *u_newknots, float *v_newknots, float *control_x, float *control_y, float *control_z, float *points); void get_orig_points1(int num, int num1, int trimnum, int grid_u, int grid_v,float *trim_data, float *u_newknots, float *v_newknots, float *control_x, float *control_y, float *control_z, float *points); void get_trim_points(int num, int trimnum, int grid_u, int grid_v, float *u_newknots, float *v_newknots, float *control_x, float *control_y, float *control_z, float *points); //---------------------------------------------------------------------------// Input: // num - u direction number of points // trimnum - number of points defining trimming curve, also v direction // number of "new data points" // u and v new_knots so that basis can be used to compute N control x & // y to be used with N to map points on the original surface using // map_point // Array trim_data // original surface data points // // Output: // Array of trimmed surface points //---------------------------------------------------------------------------void get_orig_points(int num, int trimnum, int grid_u, int grid_v, float *trim_data, float *u_newknots, float *v_newknots, float *control_x, float *control_y, float *control_z, float *points) { int i,j,k,l,intU,intV,variable1,variable2, flag; float u1,u2,u,v; float x,y,z; float Nu[4],Nv[4]; for (j=0;j=u_newknots[k] && u=v_newknots[l] && v=u_newknots[k] && u=v_newknots[l] && v=u_newknots[k] && u=v_newknots[l] && v 0.05*max_error_pts(n) cc(i,j) = 0.1; else cc(i,j) = 0.0; end end end
%------------------------------------------------------------------------------% u parametric direction % This section calculates the correlation between the ordinate intercept values % and the maximum error values. The correlation data is used to predict the % maximum error based on the values of the maximum ordinate intercept. %-------------------------------------------------------------------------------
fp5 = fopen('z:\karthik\matlab_stuff\case_1\output.txt','w'); fprintf(fp5,' u parametric direction
\n\n');
% find correlation coefficient between the n points of maximum error and ordinate intercept values ord_corr_coef = corrcoef(max_error_pts,sorted_ordinate_total); fprintf(fp5,'Correlation coefficient between n maximum values of error and ordinate intercept values = %g \n',ord_corr_coef(1,2)) ; Appendix A: Source Code 284
error_values = max_error_pts'; % calculate the slope and ordinate intercept of linear least squares best fit line for above data best_fit_data = polyfit(sorted_ordinate_total(1:n),error_values(1:n),1); fprintf(fp5,'The actual value of maximum error = %g \n',max_error_pts(n)); % predict the maximum error based on maximum value of ordinate intercept and line fit data max_predicted_error = best_fit_data(1)* sorted_ordinate_total(n) + best_fit_data(2); fprintf(fp5,'The predicted value of maximum error = %g \n',max_predicted_error); % calculate the percentage error between the predicted and actual value of error max_per_error = (max_error_pts(n) - max_predicted_error)*100/max_error_pts(n); fprintf(fp5,'The percentage error is %g \n',max_per_error); fclose('all');
Appendix A: Source Code
285