#include #include #include #include #include "utility.h" #include "init.h" #include "globals.h" #include "render.h" #include "geom_menu.h" #include "geom.h" #include "output.h" #define SPECS 0 /* save_mode */ #define PS_BOARDS 1 #define UG_SLICE 2 #define UG 3 #define UGO 11 #define STL 4 #define PPHIGS 5 #define BIQUAD 6 #define PS_SLICE 7 #define SIF_3D 8 #define SIF_2D 9 #define VRML 10 #define Q Y /* the coordinate axis in which slicing is done */ #define BOARDS 13 /* number of boards from which the sculpture is built */ /* hardcoded default -- read interactively from slider scherk_tex_tiles */ #define PROFILES 5 /* number of height lines shown in survey composite */ #define BOARDTHICKNESS 1.0 /* 0.875 * the kind of boards Brent plans to use */ #define AUTOSCALE 1 /* if 1: scale blueprints to fill page size below */ #define PAGESIZEH 8.5 /* full width on the print-out page -- 1 in. margin will be subtracted */ #define PAGESIZEV 11.0 /* full height on the print-out page */ /* ADJUST these above constants to obtain the desired type of output */ /* The area actually used is only (2d+2) by (2d). */ /* global variables from geom.c */ extern int ring, vanes; extern int d, D, dd, Dd, DD; extern float n[DMAX+DMAX+3][DMAX+DMAX+1][3]; /*final vertex normals*/ extern float o[DMAX+DMAX+3][DMAX+DMAX+1][3]; /*offset vertices*/ extern float lid[DMAX+DMAX+3][9][3]; /* points to close of end-storeys */ int total_biquads, total_trias; float SPEC[3][3][3]; /* ctrl pnt array for special biquad Bezier patch */ float S[MAXDET][MAXDET][3]; /*patch_surface pts*/ /*derived or modified global variables*/ static int cuts, cutnum, boardnum; /* vertex and face data for printing to a file */ float xmin, xmax, ymin, ymax, zmin, zmax; /* for bounding box */ int out_data; /* save shape to output file */ int b_count; /* count branches processed */ int bbase; /* base of unique integer for branch vertex identifier */ int p_count; /* count patches processed */ int pbase; /* base of unique integer for patch vertex identifier */ static float outscale; /* scale factor to produce integer output */ static float fab; /* scale factor applied to STL file for fabrication */ static int pnt_count; /* unique number for contour vertices */ static float cutpos; /* position of current slicing cut */ static FILE *myfile; /* this is the output file */ /*======================================================== ROUTINES FOR THE CONSTRUCTION OF VARIOUS OUTPUT FILES __________________________________________________________ We can either output the complete object as a UniGrafix file or we can slice the objcet and output individual contours. ---------------------------------------------------------*/ /*---------------------MK INTERSECTION LINE----------------------*/ /* compute and output an intersection point -- plus line-element */ static void mkipoint(int head, int iA, int jA, int iB, int jB) { float Px, Py, Pz, fract; pnt_count ++ ; /* make unique vertex numbers */ /* 2nd point should be LESS than cutpos; no division by zero ! */ fract = (cutpos - o[iB][jB][Q]) / (o[iA][jA][Q] - o[iB][jB][Q]); /* But just in case ... fract = (fract<0.0 ? 0.0 : fract ); fract = (fract>1.0 ? 1.0 : fract ); */ if (DEBUG) { if (fract<0.0) { fprintf(myfile, "%%{fract < 0 encountered}\n" ); fract = 0.0; } else if (fract>1.0) { fprintf(myfile, "%%{fract > 1 encountered}\n" ); fract = 1.0; } } Px = o[iB][jB][X] + fract * (o[iA][jA][X] - o[iB][jB][X]); Py = o[iB][jB][Y] + fract * (o[iA][jA][Y] - o[iB][jB][Y]); Pz = o[iB][jB][Z] + fract * (o[iA][jA][Z] - o[iB][jB][Z]); if (scherk_save_mode==UG_SLICE) { fprintf(myfile, "v p_%d %f %f %f;\n", pnt_count, Px, Py, Pz ); if (head==2) fprintf(myfile, "w (p_%d p_%d);\n", pnt_count - 1, pnt_count); /* drawline from point1 to point2 */ } else if ((scherk_save_mode==PS_BOARDS)||(scherk_save_mode==PS_SLICE)) { if (Q==Z) { if (head==1) fprintf(myfile, " %f %f moveto ", 100.0*Px, 100.0*Py ); else fprintf(myfile, " %f %f lineto \n", 100.0*Px, 100.0*Py ); } else { if (head==1) fprintf(myfile, " %f %f moveto ", 100.0*Px, 100.0*Pz ); else fprintf(myfile, " %f %f lineto \n", 100.0*Px, 100.0*Pz ); } } } /*end mkipoint ---------------------------------------------*/ /*------------------------------- FACECUT -----------------------*/ /* cut one triangle with the current cutpos value, and output a corresponding cut line to output file */ static void facecut(int i1, int j1, int i2, int j2, int i3, int j3) { int done=0; if ( o[i1][j1][Q] >= cutpos ) { if ( o[i2][j2][Q] >= cutpos ) { if ( o[i3][j3][Q] >= cutpos ) done = 1; else { mkipoint(1, i1, j1, i3, j3 ); mkipoint(2, i2, j2, i3, j3 ); }; } else { mkipoint(1, i1, j1, i2, j2 ); if ( o[i3][j3][Q] >= cutpos ) mkipoint(2, i3, j3, i2, j2 ); else mkipoint(2, i1, j1, i3, j3 ); } } else { if ( o[i2][j2][Q] < cutpos ) { if ( o[i3][j3][Q] < cutpos ) done = 1; else { mkipoint(1, i3, j3, i1, j1 ); mkipoint(2, i3, j3, i2, j2 ); }; } else { mkipoint(1, i2, j2, i1, j1 ); if ( o[i3][j3][Q] < cutpos ) mkipoint(2, i2, j2, i3, j3 ); else mkipoint(2, i3, j3, i1, j1 ); } } } /*end facecut ---------------------------------------------*/ /*------------------------DO TWO TRIANGLES -------------------------- Process one quadrilateral face: split into 2 triangles; Output into a file the whole triangle or just a cut at cutpos. Output can be in a variety of formats: PS, UG, STL. ---------------------------------------------------------*/ static void do2triangles(int inner, int i, int j, int diag, int face) { int id, ib, j0, j1; float fnormal[3]; if(inner) diag = 1-diag; j0=(inner ? j-1 : j); j1=(inner ? j : j-1); ib=(diag ? i : i-1); id=(diag ? i-1 : i); if ((scherk_save_mode==UG)||(scherk_save_mode==STL)||(scherk_save_mode==PPHIGS)||(scherk_save_mode==SIF_3D)) /* output whole object */ { if (scherk_save_mode==UG) { fprintf(myfile, "f (v%d v%d v%d) C%d;\n", bbase+j0*(DD+1)+i, bbase+j0*(DD+1)+i-1, bbase+j1*(DD+1)+ib, face); fprintf(myfile, "f (v%d v%d v%d) C%d;\n", bbase+j0*(DD+1)+id, bbase+j1*(DD+1)+i-1, bbase+j1*(DD+1)+i, face); } else if (scherk_save_mode==SIF_3D) { fprintf(myfile, "(f %d %d %d)\n", bbase+j0*(DD+1)+i, bbase+j0*(DD+1)+i-1, bbase+(j1)*(DD+1)+ib); fprintf(myfile, "(f %d %d %d)\n", bbase+j0*(DD+1)+id, bbase+(j1)*(DD+1)+i-1, bbase+(j1)*(DD+1)+i); } else if (scherk_save_mode==PPHIGS) { fprintf(myfile, " polygon 3 { \n"); fprintf(myfile, " %f %f %f ", o[i][j0][X], o[i][j0][Y], o[i][j0][Z] ); fprintf(myfile, "%f %f %f;\n", n[i][j0][X], n[i][j0][Y], n[i][j0][Z] ); fprintf(myfile, " %f %f %f ", o[i-1][j0][X], o[i-1][j0][Y], o[i-1][j0][Z] ); fprintf(myfile, "%f %f %f;\n", n[i-1][j0][X], n[i-1][j0][Y], n[i-1][j0][Z] ); fprintf(myfile, " %f %f %f ", o[ib][j1][X], o[ib][j1][Y], o[ib][j1][Z] ); fprintf(myfile, "%f %f %f;\n", n[ib][j1][X], n[ib][j1][Y], n[ib][j1][Z] ); fprintf(myfile, " }; \n"); fprintf(myfile, " polygon 3 { \n"); fprintf(myfile, " %f %f %f ", o[id][j0][X], o[id][j0][Y], o[id][j0][Z] ); fprintf(myfile, "%f %f %f;\n", n[id][j0][X], n[id][j0][Y], n[id][j0][Z] ); fprintf(myfile, " %f %f %f ", o[i-1][j1][X], o[i-1][j1][Y], o[i-1][j1][Z] ); fprintf(myfile, "%f %f %f;\n", n[i-1][j1][X], n[i-1][j1][Y], n[i-1][j1][Z] ); fprintf(myfile, " %f %f %f ", o[i][j1][X], o[i][j1][Y], o[i][j1][Z] ); fprintf(myfile, "%f %f %f;\n", n[i][j1][X], n[i][j1][Y], n[i][j1][Z] ); fprintf(myfile, " }; \n"); } else if (scherk_save_mode==STL) { /* calc facet normal */ fnormal[X] = (o[i][j0][Y]-o[i-1][j0][Y])*(o[i][j0][Z]+o[i-1][j0][Z]) +(o[i-1][j0][Y]-o[ib][j1][Y])*(o[i-1][j0][Z]+o[ib][j1][Z]) +(o[ib][j1][Y]-o[i][j0][Y])*(o[ib][j1][Z]+o[i][j0][Z]); fnormal[Y] = (o[i][j0][Z]-o[i-1][j0][Z])*(o[i][j0][X]+o[i-1][j0][X]) +(o[i-1][j0][Z]-o[ib][j1][Z])*(o[i-1][j0][X]+o[ib][j1][X]) +(o[ib][j1][Z]-o[i][j0][Z])*(o[ib][j1][X]+o[i][j0][X]); fnormal[Z] = (o[i][j0][X]-o[i-1][j0][X])*(o[i][j0][Y]+o[i-1][j0][Y]) +(o[i-1][j0][X]-o[ib][j1][X])*(o[i-1][j0][Y]+o[ib][j1][Y]) +(o[ib][j1][X]-o[i][j0][X])*(o[ib][j1][Y]+o[i][j0][Y]); normalize(fnormal); fprintf(myfile, "facet normal %.2f %.2f %.2f \n", fnormal[X], fnormal[Y], fnormal[Z] ); fprintf(myfile, "outer loop\n"); fprintf(myfile, "vertex %.4f %.4f %.4f \n", fab*o[i][j0][X], fab*o[i][j0][Y], fab*o[i][j0][Z] ); fprintf(myfile, "vertex %.4f %.4f %.4f \n", fab*o[i-1][j0][X], fab*o[i-1][j0][Y], fab*o[i-1][j0][Z] ); fprintf(myfile, "vertex %.4f %.4f %.4f \n", fab*o[ib][j1][X], fab*o[ib][j1][Y], fab*o[ib][j1][Z] ); fprintf(myfile, "endloop\n"); fprintf(myfile, "endfacet\n"); /* calc facet normal */ fnormal[X] = (o[id][j0][Y]-o[i-1][j1][Y])*(o[id][j0][Z]+o[i-1][j1][Z]) +(o[i-1][j1][Y]-o[i][j1][Y])*(o[i-1][j1][Z]+o[i][j1][Z]) +(o[i][j1][Y]-o[id][j0][Y])*(o[i][j1][Z]+o[id][j0][Z]); fnormal[Y] = (o[id][j0][Z]-o[i-1][j1][Z])*(o[id][j0][X]+o[i-1][j1][X]) +(o[i-1][j1][Z]-o[i][j1][Z])*(o[i-1][j1][X]+o[i][j1][X]) +(o[i][j1][Z]-o[id][j0][Z])*(o[i][j1][X]+o[id][j0][X]); fnormal[Z] = (o[id][j0][X]-o[i-1][j1][X])*(o[id][j0][Y]+o[i-1][j1][Y]) +(o[i-1][j1][X]-o[i][j1][X])*(o[i-1][j1][Y]+o[i][j1][Y]) +(o[i][j1][X]-o[id][j0][X])*(o[i][j1][Y]+o[id][j0][Y]); normalize(fnormal); fprintf(myfile, "facet normal %.2f %.2f %.2f \n", fnormal[X], fnormal[Y], fnormal[Z] ); fprintf(myfile, "outer loop\n"); fprintf(myfile, "vertex %.4f %.4f %.4f \n", fab*o[id][j0][X], fab*o[id][j0][Y], fab*o[id][j0][Z] ); fprintf(myfile, "vertex %.4f %.4f %.4f \n", fab*o[i-1][j1][X], fab*o[i-1][j1][Y], fab*o[i-1][j1][Z] ); fprintf(myfile, "vertex %.4f %.4f %.4f \n", fab*o[i][j1][X], fab*o[i][j1][Y], fab*o[i][j1][Z] ); fprintf(myfile, "endloop\n"); fprintf(myfile, "endfacet\n"); } } else if (cutnum>=0) /* make contours; except for pass1, which is for bbox */ { facecut( i,j0, i-1,j0, ib,j1 ); facecut( id,j0, i-1,j1, i,j1 ); } } /*end do2triangles --------------------------------------------------- */ /*---------------------WRITE TRIANGULATED MAIN SURFACE----------------------*/ void output_surface(int inner, int upper, int face) /* face= some id, e.g. for coloring */ { int i, j, jlo, jhi, bbj; if(upper) { jlo=d; jhi=dd; } else { jlo=0; jhi=d; } if (scherk_save_mode==UGO) /* old */ { if(inner) fprintf(myfile, "{ Inner patch mesh }\n" ); else fprintf(myfile, "{ Outer patch mesh }\n" ); for (j=jlo; j<=jhi; j++) /* write all vertices */ for (i=0; i<=DD; i++) fprintf(myfile, "v o%d_%d_%d %f %f %f;\n", b_count, i, j, o[i][j][X], o[i][j][Y], o[i][j][Z] ); } if (scherk_save_mode==UG) { if(inner) fprintf(myfile, "{ Inner patch mesh; face = %d }\n", face ); else fprintf(myfile, "{ Outer patch mesh; face = %d }\n", face ); for (j=jlo; j<=jhi; j++) /* write all vertices */ { bbj = bbase + j*(DD+1); for (i=1; i>>> S[] array of data points for the biquads, and it counts patches (p_count) rather than branches. ---------------------------------------------------------*/ static void make2triangles(int det, int inner, int i, int j, int diag, int face) { /*float fnormal[3];*/ /* output whole object */ if (scherk_save_mode==UGO) { fprintf(myfile, "f (v%d_%d_%d v%d_%d_%d v%d_%d_%d) C%d;\n", p_count,i,j, p_count,i+1,j, p_count,i+1,j+1, face); fprintf(myfile, "f (v%d_%d_%d v%d_%d_%d v%d_%d_%d) C%d;\n", p_count,i,j, p_count,i+1,j+1, p_count,i,j+1, face); } else if (scherk_save_mode==UG) { fprintf(myfile, "f (v%d v%d v%d) C%d;\n", pbase+j*(det+1)+i, pbase+j*(det+1)+i+1, pbase+(j+1)*(det+1)+i+1, face); fprintf(myfile, "f (v%d v%d v%d) C%d;\n", pbase+j*(det+1)+i, pbase+(j+1)*(det+1)+i+1, pbase+(j+1)*(det+1)+i, face); } else if (scherk_save_mode==SIF_3D) { fprintf(myfile, "(f %d %d %d)\n", pbase+j*(det+1)+i, pbase+j*(det+1)+i+1, pbase+(j+1)*(det+1)+i+1); fprintf(myfile, "(f %d %d %d)\n", pbase+j*(det+1)+i, pbase+(j+1)*(det+1)+i+1, pbase+(j+1)*(det+1)+i); } } /*end make2triangles for biquad patches -------------------------------- */ /*---------------------WRITE BIQUAD PARAMETERS for Manocha--------------*/ /* Output Format for each of the biquad Bezier patches used in Manocha's group 2 2 {for biquad} This is followed by (udeg+1)(vdeg+1) control points each given as X Y Z W -----------e.g. ---------------- 2 2 1.400000 0.000000 2.400000 1.0 1.400000 -0.784000 2.400000 1.0 0.784000 -1.400000 2.400000 1.0 1.337500 0.000000 2.531250 1.0 1.337500 -0.749000 2.531250 1.0 0.749000 -1.337500 2.531250 1.0 1.437500 0.000000 2.531250 1.0 1.437500 -0.805000 2.531250 1.0 0.805000 -1.437500 2.531250 1.0 0 {indicating no trim curve} ---------------------------------------------------------------*/ void write_biquad_params(int det, int face) { int i, j, id, ib, j1, bbj; float fnormal[3]; if (scherk_save_mode==BIQUAD) /* Output parameters of one patch */ { fprintf(myfile, "2 2 \n" ); for (j=0; j<3; j++ ) for (i=0; i<3; i++ ) fprintf(myfile, "%f %f %f 1.0\n", SPEC[i][j][0], SPEC[i][j][1], SPEC[i][j][2] ); fprintf(myfile, "0 \n\n" ); } /* biquad params */ else if (scherk_save_mode==UGO) { if (det==1) fprintf(myfile, "{ biquad mini-patch %d }\n", p_count ); else fprintf(myfile, "{ biquad patch %d }\n", p_count ); /* write all vertices */ for (j=0; j<=det; j++ ) for (i=0; i<=det; i++ ) /*fprintf(myfile, "v v%d_%d_%d %f %f %f;\n", p_count, i, j, */ /* 6 decimals */ fprintf(myfile, "v v%d_%d_%d %.4f %.4f %.4f;\n", p_count, i, j, S[i][j][X], S[i][j][Y], S[i][j][Z] ); for (j=0; j xmax ) xmax = o[i][j][X]; if ( o[i][j][Y] < ymin ) ymin = o[i][j][Y]; else if ( o[i][j][Y] > ymax ) ymax = o[i][j][Y]; if ( o[i][j][Z] < zmin ) zmin = o[i][j][Z]; else if ( o[i][j][Z] > zmax ) zmax = o[i][j][Z]; } } /*calc_bbox-------------------------------------------------------------*/ /* ===================================FILE OUTPUT=============================== SAVE stuff to an OUTPUT FILE. When the user clicks the "SAVE" button this function is called. It sets the various flags into the proper state and it governs the looping through the various cutpos values if slices through the sculpture are needed. It also calls render() once for every output file or slice. The slider variable scherk_save_mode governs the type of output we get: 0 --> output just the slider settings in a text file; 1 --> output stacked slices in PostScript; 2 --> output stacked slices in Unigrafix; 3 --> output whole solid in UniGrafix; 4 --> output whole solid in .STL format; 5 --> output whole solid in PPHIGS for IVE; -------------------------------------------------------------------*/ void output_newscherk_data(FILE *fp) { float cutbot, cuttop, cutinc; float scale, inchscale, Hscale, Vscale, Hoffset, Voffset; fab = scherk_scale; /* default FABRICATION SCALE */ outscale = 10000.0; myfile = fp; xmin = 0.0; ymin = 0.0; zmin = 0.0; xmax = 0.0; ymax = 0.0; zmax = 0.0; out_data = 1; b_count = 0; bbase = 0; p_count = 0; pbase = 0; cutnum = -1; /* to provide unique labels */ cutbot = 0.0; cuttop = 0.0; cutinc = 0.0; /* ==== Output HEADER stuff for various output files */ switch(scherk_save_mode) { case UG: /* 3D radial-edge model */ { /* write header info for UniGrafix file */ fprintf(myfile, "{ UniGrafix file of Scherk/Collins Generator }\n" ); fprintf(myfile, "c C0 0.5 200 1.0; {cyan faces}\n" ); fprintf(myfile, "c C1 0.5 60 1.0; {yellow faces}\n" ); fprintf(myfile, "c C2 0.5 340 1.0; {red rims}\n" ); break; } case SIF_3D: /* for SFF implementation */ { fprintf(myfile, "(SIF_SFF 1 0 (** -- tentative syntax **) \n" ); /* fprintf(myfile, " (coord_units (e 1 -4) ) \n" ); fprintf(myfile, " (coord_precision 2 ) \n" ); */ fprintf(myfile, " (body \n" ); fprintf(myfile, " (lump \n" ); fprintf(myfile, " (shell \n" ); break; } case STL: /* for SFF implementation */ { fprintf(myfile, "solid ascii \n" ); break; } case PPHIGS: /* format used at UNC for virtual environments */ { fprintf(myfile, "structure ScherkCollinsObject posted { \n" ); fprintf(myfile, "texture polygon dummy ; \n" ); break; } case UG_SLICE: /* interactive visualization of slices */ { fprintf(myfile, "{ UniGrafix slice contours from sculpture generator}\n" ); break; } case PS_BOARDS: /* color slices in postscript for Brent Collins*/ { fprintf(myfile, "%%!\n" ); fprintf(myfile, "%%%% Postscript board contours from sculpture generator\n" ); break; } case PS_SLICE: /* BW slices for making stackes of transparencies */ { fprintf(myfile, "%%!\n" ); fprintf(myfile, "%%%% Postscript slice contours from sculpture generator\n" ); break; } case SPECS: /* just to save neat designs */ { break; } } /* === DO at least ONE LOOP to output whole geometry or to calculate BBOX */ /* suppress slicing on this pass by testing cutnum in facecut */ render(); /* >>> THIS DOES THE WORK */ if (scherk_save_mode==SPECS) { /* print a listing of all current sculpture parameters */ fprintf(myfile, "SCHERK-COLLINS SCULPTURE\n" ); fprintf(myfile, "branches = %d\n", scherk_branches ); fprintf(myfile, "storeys = %d\n", scherk_storeys ); fprintf(myfile, "height = %.2f\n", scherk_height ); fprintf(myfile, "flange = %.2f\n", scherk_flange ); fprintf(myfile, "thickness = %.2f\n", scherk_thickness ); fprintf(myfile, "rim_bulge = %.2f\n", scherk_rim_bulge ); fprintf(myfile, "warp = %.2f\n", scherk_warp ); fprintf(myfile, "twist = %.2f\n", scherk_twist ); fprintf(myfile, "azimuth = %.2f\n", scherk_azimuth ); fprintf(myfile, "mesh_tiles = %d\n", scherk_mesh_tiles ); fprintf(myfile, "textr_tiles = %d\n", scherk_tex_tiles ); fprintf(myfile, "detail = %d\n", scherk_detail ); fprintf(myfile, "total patches = %d\n", total_biquads ); fprintf(myfile, "total triangles = %d\n", total_trias ); fprintf(myfile, "fabrication scale = %.2f\n", scherk_scale ); fprintf(myfile, "Initial, generated bounding box\n in arbitrary generator units:\n" ); fprintf(myfile, " xmax= %.2f, ymax= %.2f, zmax= %.2f,\n xmin= %.2f, ymin= %.2f, zmin= %.2f \n", xmax, ymax, zmax, xmin, ymin, zmin ); fprintf(myfile, "Scaled bounding box\n for fabrication via STL file:\n" ); fprintf(myfile, " xmax= %.2f, ymax= %.2f, zmax= %.2f,\n xmin= %.2f, ymin= %.2f, zmin= %.2f \n", fab*xmax, fab*ymax, fab*zmax, fab*xmin, fab*ymin, fab*zmin ); } else { /* Slightly enlarge 3D BBOX to separate from sculpture for better visibility */ /* since this sets the global scale for output of slices, a slightly larger box also gives non-zero top and bottom slices */ xmin = 1.01*xmin; ymin = 1.01*ymin; zmin = 1.01*zmin; xmax = 1.01*xmax; ymax = 1.01*ymax; zmax = 1.01*zmax; } if (scherk_save_mode==UG_SLICE) { /* create a BBOX {with thick walls ?} to obtain uniform scaling when individual slices are displayed with the animator */ /* inner wall vertices */ fprintf(myfile, "{ Bounding Box enlarged by 1 percent }\n" ); fprintf(myfile, "v xyz %f %f %f;\n", xmin, ymin, zmin ); fprintf(myfile, "v xyZ %f %f %f;\n", xmin, ymin, zmax ); fprintf(myfile, "v xYz %f %f %f;\n", xmin, ymax, zmin ); fprintf(myfile, "v xYZ %f %f %f;\n", xmin, ymax, zmax ); fprintf(myfile, "v Xyz %f %f %f;\n", xmax, ymin, zmin ); fprintf(myfile, "v XyZ %f %f %f;\n", xmax, ymin, zmax ); fprintf(myfile, "v XYz %f %f %f;\n", xmax, ymax, zmin ); fprintf(myfile, "v XYZ %f %f %f;\n", xmax, ymax, zmax ); /* six inward faces */ fprintf(myfile, "f (XYZ XyZ xyZ xYZ);\n"); fprintf(myfile, "f (XYZ XYz Xyz XyZ);\n"); fprintf(myfile, "f (XyZ Xyz xyz xyZ);\n"); fprintf(myfile, "f (xyZ xyz xYz xYZ);\n"); fprintf(myfile, "f (xYZ xYz XYz XYZ);\n"); fprintf(myfile, "f (xyz Xyz XYz xYz);\n"); } /* == SLICING LOOP: If we do slices, we need to do multiple rendering loops */ /* Make all the major and minor slicing cuts here in sequence. We want to have BOARDS number of separate print outs, and on each PROFILES contour lines, where the last profile on one board is the same as the first on the next. */ /* All these decisions and parameters hard-coded here, need eventually be put on a menu, so they can be easily adjusted. */ if ((scherk_save_mode==UG_SLICE)||(scherk_save_mode==PS_BOARDS)||(scherk_save_mode==PS_SLICE)) /* any kind of SLICING */ { if (Q==Z) { cutbot = zmin; /* fix this as below, if you ever need it ... */ cutbot = zmax; } else { cutbot = 0.99*ymin; /* or 0.0 --- from middle out for symm obj */ cuttop = 0.99*ymax; /* cut just sligthly inside the extrema 1.01*0.99=0.9999, to see top and bottom points on the slices printed out for Brent Collins. */ } /* determine how many cutting contours have to be calculated: */ /* currently: # BOARDS controlled interactively by: "scherk_tex_tiles" slider */ if (scherk_save_mode==PS_BOARDS) { cuts = scherk_tex_tiles * (PROFILES -1) +1; } else { cuts = scherk_tex_tiles + 1 ; } cutinc = (cuttop-cutbot)/(float)( cuts - 1 ); /* SLICING LOOP */ for (cutpos=cutbot; cutnum=0) { if (scherk_save_mode==UG_SLICE) { /* Make a DEF; first draw UG bounding frame */ fprintf(myfile, "def Slice%d ;\n", cutnum ); if (Q==Z) { fprintf(myfile, "v xyz %f %f %f;\n", xmin, ymin, cutpos ); fprintf(myfile, "v xYz %f %f %f;\n", xmin, ymax, cutpos ); fprintf(myfile, "v XYz %f %f %f;\n", xmax, ymax, cutpos ); fprintf(myfile, "v Xyz %f %f %f;\n", xmax, ymin, cutpos ); fprintf(myfile, "w (xyz xYz XYz Xyz xyz);\n"); } else { fprintf(myfile, "v xyz %f %f %f;\n", xmin, cutpos, zmin ); fprintf(myfile, "v xyZ %f %f %f;\n", xmin, cutpos, zmax ); fprintf(myfile, "v XyZ %f %f %f;\n", xmax, cutpos, zmax ); fprintf(myfile, "v Xyz %f %f %f;\n", xmax, cutpos, zmin ); fprintf(myfile, "w (xyz xyZ XyZ Xyz xyz);\n"); } } else /* any kind of PS output */ fprintf(myfile, "/SliceContour%d { newpath \n", cutnum ); } render(); /* >>>> THAT IS WHERE ALL THE SLICING HAPPENS */ if (cutnum >=0) { if (scherk_save_mode==UG_SLICE) fprintf(myfile, "end; { Slice%d }\n", cutnum ); else fprintf(myfile, "closepath stroke } def \n" ); cutpos+= cutinc; /* move to next slicing position */ } } /* for */ } /* === TRAILER stuff closing off the file after all slices have been done */ switch(scherk_save_mode) { case UG: { /* write trailer info for UniGrafix file */ fprintf(myfile, "{End of UniGrafix file} \n" ); break; } case SIF_3D: { fprintf(myfile, " ) (* /shell *) \n" ); fprintf(myfile, " ) (* /lump *) \n" ); fprintf(myfile, " ) (* /body *) \n" ); fprintf(myfile, ") (* /SIF-file *) \n" ); break; } case STL: { fprintf(myfile, "end solid \n" ); break; } case PPHIGS: { fprintf(myfile, "}; \n" ); break; } case UG_SLICE: { /* Put it all together by making instance calls on all the contours */ /* FIX start cutnum one lower for Unigrafix slices */ for ( ; cutnum>0; cutnum-- ) /* OUTPUT and PAGE COMPOSITION LOOP */ fprintf(myfile, "i i%d (Slice%d);\n", cutnum-1, cutnum-1 ); break; } case PS_SLICE: /* single BW slices on separate pages */ { fprintf(myfile, "\n%% -- main program \n" ); /* Set SCALE for output automatically to fit 8.5by11'' pages */ if (Q==Z) { Hscale = 0.72*(8.0)/(xmax-xmin); Vscale = 0.72*(10.0)/(ymax-ymin); Hoffset = -50.0*(xmax+xmin); Voffset = -50.0*(ymax+ymin); } else { Hscale = 0.72*(8.0)/(xmax-xmin); Vscale = 0.72*(10.0)/(zmax-zmin); Hoffset = -50.0*(xmax+xmin); Voffset = -50.0*(zmax+zmin); } if (Hscale <= Vscale) scale = Hscale; else scale = Vscale; inchscale = scale*100.0/72.0; /* fprintf(myfile, "0.5 setlinewidth \n" ); fprintf(myfile, "[] 0 setdash \n" ); fprintf(myfile, "0.0 setgray \n" ); */ /* Step through all the generated profiles and output each page */ boardnum = 1; for ( ; boardnum < scherk_tex_tiles; boardnum++ ) { fprintf(myfile, "%f %f translate %% -- Center to 0,0 \n", 8.5*36, 11.0*36 ); fprintf(myfile, "%f %f translate %% -- Center to 0,0 \n", Hoffset, Voffset ); fprintf(myfile, "%f %f scale %% -- to fill page \n", scale, scale ); cutnum = boardnum ; fprintf(myfile, "SliceContour%d \n", cutnum ); fprintf(myfile, "showpage \n \n" ); /* the composite survey */ } break; } case PS_BOARDS: /* color slices on multiple pages in postscript */ { fprintf(myfile, "%% -- main program \n" ); /* Set SCALE for blueprints, either AUTOmatic to fit 8.5by11'' pages */ if (AUTOSCALE) { if (Q==Z) { Hscale = 0.72*(PAGESIZEH-2.0)/(xmax-xmin); Vscale = 0.72*(PAGESIZEV-2.0)/(ymax-ymin); Hoffset = -50.0*(xmax+xmin); Voffset = -50.0*(ymax+ymin); } else { Hscale = 0.72*(PAGESIZEH-2.0)/(xmax-xmin); Vscale = 0.72*(PAGESIZEV-2.0)/(zmax-zmin); Hoffset = -50.0*(xmax+xmin); Voffset = -50.0*(zmax+zmin); } if (Hscale <= Vscale) scale = Hscale; else scale = Vscale; inchscale = scale*100.0/72.0; } else /* ABSOLUTE SCALE to make 1:1 blueprints for Brent Collins */ /* choose so that each board (=PROFILES-1)*cutinc's becomes equal to the chosen board thickness, i.e. 0.875 in. */ { scale = BOARDTHICKNESS*0.72/( cutinc * (PROFILES-1)); inchscale = scale*100.0/72.0; /* a factor of 100 is already included in the geom routine */ if (Q==Z) { Hoffset = -50.0*(xmax+xmin); Voffset = -50.0*(ymax+ymin); } else { Hoffset = -50.0*(xmax+xmin); Voffset = -50.0*(zmax+zmin); } } /* Output a HEADER PAGE for the set of slice blueprints */ fprintf(myfile, "/Times-Roman findfont 10 scalefont setfont \n" ); fprintf(myfile, "80 3380 moveto (SCHERK-COLLINS SCULPTURE) show \n" ); fprintf(myfile, "80 3360 moveto (branches = %d) show \n", scherk_branches ); fprintf(myfile, "80 3340 moveto (storeys = %d) show \n", scherk_storeys ); fprintf(myfile, "80 3320 moveto (height = %f) show \n", scherk_height ); fprintf(myfile, "80 3300 moveto (flange = %f) show \n", scherk_flange ); fprintf(myfile, "80 3280 moveto (thickness = %f) show \n", scherk_thickness ); fprintf(myfile, "80 3260 moveto (rim_bulge = %f) show \n", scherk_rim_bulge ); fprintf(myfile, "80 3240 moveto (warp = %f) show \n", scherk_warp ); fprintf(myfile, "80 3220 moveto (twist = %f) show \n", scherk_twist ); fprintf(myfile, "80 3200 moveto (azimuth = %f) show \n", scherk_azimuth ); fprintf(myfile, "80 3180 moveto (mesh_tiles = %d) show \n", scherk_mesh_tiles ); fprintf(myfile, "80 3160 moveto (textr_tiles = %d) show \n", scherk_tex_tiles ); fprintf(myfile, "80 3120 moveto (detail = %d) show \n", scherk_detail ); fprintf(myfile, "80 3080 moveto (initial, generated bounding box in arbitrary generator units:) show \n" ); fprintf(myfile, "80 3060 moveto ( xmin= %.2f, xmax= %.2f, ymin = %.2f, ymax = %.2f, zmin = %.2f, zmax = %.2f) show \n", xmin, xmax, ymin, ymax, zmin, zmax ); if (Q==Z) fprintf(myfile, "80 3020 moveto (Z-Slicing:) show \n" ); else fprintf(myfile, "80 3020 moveto (Y-Slicing:) show \n" ); fprintf(myfile, "80 3000 moveto (BOARDS = %d) show \n", scherk_tex_tiles ); fprintf(myfile, "80 2980 moveto (BOARDTHICKNESS = %f) show \n", BOARDTHICKNESS ); fprintf(myfile, "80 2960 moveto (PROFILES = %d) show \n", PROFILES ); fprintf(myfile, "80 2940 moveto (height increment between profile lines = %f generator units) show \n", cutinc ); fprintf(myfile, " ( or %f inches) show \n", cutinc * inchscale ); fprintf(myfile, "80 2920 moveto (scalefactor = %6.4f) show \n", inchscale ); fprintf(myfile, "80 2900 moveto (scaled, final bounding box in inches:) show \n" ); fprintf(myfile, "80 2880 moveto ( xmin= %.2f, xmax= %.2f, ymin = %.2f, ymax = %.2f, zmin = %.2f, zmax = %.2f) show \n", inchscale*xmin, inchscale*xmax, inchscale*ymin, inchscale*ymax, inchscale*zmin, inchscale*zmax ); fprintf(myfile, "showpage \n \n" ); /* output cover page */ /* OUTPUT and PAGE COMPOSITION LOOP */ /* Step through a subset of the generated profiles and make COMPOSITE SDURVEY*/ boardnum = 1; /* put some INFO at bottom of page */ fprintf(myfile, "72 72 moveto"); if (Q==Z) fprintf(myfile, "(Z-Slicing: ) show \n" ); else fprintf(myfile, "(Y-Slicing: ) show \n" ); fprintf(myfile, "( Composite survey ) show \n" ); fprintf(myfile, "%f %f translate %% -- Center to 0,0 \n", PAGESIZEH*36, PAGESIZEV*36 ); fprintf(myfile, "%f %f translate %% -- Center to 0,0 \n", Hoffset, Voffset ); fprintf(myfile, "%f %f scale %% -- to fill page \n", scale, scale ); /* include cut through overall BOUNDING BOX with each slice */ fprintf(myfile, "0.5 setlinewidth \n" ); fprintf(myfile, "[4 2 1 2] 0 setdash \n" ); fprintf(myfile, "0.5 setgray \n" ); fprintf(myfile, "newpath \n" ); /* prescale coordinates to get around PS linewitdth problems */ if (Q==Z) { /* cross-hair and bounding box */ fprintf(myfile, "%f %f moveto \n", 0.0, 100.0*ymin ); fprintf(myfile, "%f %f lineto \n", 0.0, 100.0*ymax ); fprintf(myfile, "%f %f moveto \n", 100.0*xmin, 0.0 ); fprintf(myfile, "%f %f lineto \n", 100.0*xmax, 0.0 ); fprintf(myfile, "%f %f moveto \n", 100.0*xmin, 100.0*ymin ); fprintf(myfile, "%f %f lineto \n", 100.0*xmin, 100.0*ymax ); fprintf(myfile, "%f %f lineto \n", 100.0*xmax, 100.0*ymax ); fprintf(myfile, "%f %f lineto \n", 100.0*xmax, 100.0*ymin ); fprintf(myfile, "closepath stroke \n" ); } else { fprintf(myfile, "%f %f moveto \n", 0.0, 100.0*zmin ); fprintf(myfile, "%f %f lineto \n", 0.0, 100.0*zmax ); fprintf(myfile, "%f %f moveto \n", 100.0*xmin, 0.0 ); fprintf(myfile, "%f %f lineto \n", 100.0*xmax, 0.0 ); fprintf(myfile, "%f %f moveto \n", 100.0*xmin, 100.0*zmin ); fprintf(myfile, "%f %f lineto \n", 100.0*xmin, 100.0*zmax ); fprintf(myfile, "%f %f lineto \n", 100.0*xmax, 100.0*zmax ); fprintf(myfile, "%f %f lineto \n", 100.0*xmax, 100.0*zmin ); fprintf(myfile, "closepath stroke \n" ); } /* stepped coloring for composite survey overlay */ fprintf(myfile, "0.5 setlinewidth \n" ); fprintf(myfile, "[] 0 setdash \n" ); fprintf(myfile, "0.0 setgray \n" ); boardnum = 0; for ( ; boardnum<=scherk_tex_tiles; boardnum++ ) { cutnum = (boardnum )*(PROFILES-1); fprintf(myfile, "%f 1.0 1.0 sethsbcolor \n", (boardnum*0.16 - trunc(boardnum*0.16)) ); fprintf(myfile, "SliceContour%d \n", cutnum ); } fprintf(myfile, "[2 2] 0 setdash \n" ); boardnum = 0; for ( ; boardnum