/******************************************************************************* This program generates a gridded quadrilateral of given dimensions, and writes the result as a VRML 1.0 or X-file formatted output stream. The resultant quadrilateral is in the XY plane, going from [-1,-1] to [+1,+1]. *******************************************************************************/ #include #include void WriteVRML1 (int nrows, int ncols); void WriteXFILE (int nrows, int ncols); inline void print (char *string) { fputs (string, stdout); } /***************************************************************************** *****************************************************************************/ int main (int argc, char *argv[]) { enum { VRML, XFILE } filetype = VRML; int nrows = 0, ncols = 0; int argi; for (argi=1; argi < argc; ++argi) { if ((argv[argi][0] == '-') && (tolower(argv[argi][1]) == 'x')) { filetype = XFILE; continue; } if (nrows == 0) nrows = atoi (argv[argi]); else ncols = atoi (argv[argi]); } if (nrows <= 0) { fputs ( "quadgrid: Generates VRML1 or X-file gridded quadrilateral\n" "Usage: quadgrid [-x] [columns]\n" "\n" "If [columns] is omitted, quadgrid uses the number of rows.\n" "Use the -x option to generate X files.\n\n", stderr ); exit (-1); } if (ncols == 0) ncols = nrows; if (filetype == VRML) WriteVRML1 (nrows, ncols); else WriteXFILE (nrows, ncols); return 0; } /***************************************************************************** This procedure writes out a grid in VRML 1.0 format. *****************************************************************************/ void WriteVRML1 (int nrows, int ncols) { // VRML 1.0 Header printf ( "#VRML V1.0 ascii\n\n" "Separator {\n" "Info { string " "\"%d x %d gridded quadrilateral generated by quadgrid.\"" " }\n", nrows, ncols ); // Write out the vertex coordinates. print ("\nCoordinate3 { point [\n"); // N 2N 3N ... (N+1)(M+1)-1 This is the vertex indexing // : : : : for the generated grid layout. // 3 (N+1)+3 2(N+1)+3 ... M(N+1)+3 This contains (N+1)(M+1) // 2 (N+1)+2 2(N+1)+2 ... M(N+1)+2 vertices, NM quadrilaterals, // 1 (N+1)+1 2(N+1)+1 M(N+1)+1 and 2NM triangles. // 0 (N+1) 2(N+1) ... M(N+1) int row, col; for (col=0; col <= ncols; ++col) { for (row=0; row <= nrows; ++row) { printf ("\t% g\t% g\t0,\n", (((col / double(ncols)) * 2) - 1), (((row / double(nrows)) * 2) - 1)); } } print ("] } # Coordinate3\n"); // Write out the texture coordinates. print ("\nTextureCoordinate2 { point [\n"); for (col=0; col <= ncols; ++col) { for (row=0; row <= nrows; ++row) { printf ("\t%g\t%g,\n", (col / double (ncols)), (row / double (nrows))); } } print ("] } # TextureCoordinate2\n"); // Write out the normal vectors. print ( "\nNormal { vector [0 0 1] }\n" "NormalBinding { value OVERALL }\n" ); // Lay out triangles column by column. print ("\nIndexedFaceSet { coordIndex [\n"); int left = 0; // Lower Left Vertex Index int right = 1+nrows; // Lower Right Vertex Index for (col=0; col < ncols; ++col, ++left, ++right) { for (row=0; row < nrows; ++row, ++left, ++right) { printf ("\t%d,\t%d,\t%d,\t-1,\n", left, right, right+1); printf ("\t%d,\t%d,\t%d,\t-1,\n", left, right+1, left+1); } } // Epilogue print ( "] } # IndexedFaceSet\n" "\n} # Separator\n" ); } /***************************************************************************** This procedure writes out a grid in X-file format. *****************************************************************************/ void WriteXFILE (int nrows, int ncols) { int nverts = (nrows+1) * (ncols+1); // Header printf ( "xof 0302txt 0032\n\n" "# %d x %d gridded quadrilateral generated by 'quadgrid'\n\n" "Header { 1;0;1; }\n\n" "Mesh {\n\n", nrows, ncols ); // Write out the vertex coordinates. print ("# Vertex Coordinates\n\n"); // N 2N 3N ... (N+1)(M+1)-1 This is the vertex indexing // : : : : for the generated grid layout. // 3 (N+1)+3 2(N+1)+3 ... M(N+1)+3 This contains (N+1)(M+1) // 2 (N+1)+2 2(N+1)+2 ... M(N+1)+2 vertices, NM quadrilaterals, // 1 (N+1)+1 2(N+1)+1 M(N+1)+1 and 2NM triangles. // 0 (N+1) 2(N+1) ... M(N+1) printf ("%d;\n", nverts); int row, col; for (col=0; col <= ncols; ++col) { for (row=0; row <= nrows; ++row) { if (col || row) print (",\n"); printf ("% f; % f; 0.0;", (((col / double(ncols)) * 2) - 1), (((row / double(nrows)) * 2) - 1)); } } print (";\n\n"); // Face Coordinate Indices printf ("# Faces\n\n%d;\n", 2 * nrows * ncols); int left = 0; // Lower Left Vertex Index int right = 1+nrows; // Lower Right Vertex Index for (col=0; col < ncols; ++col, ++left, ++right) { for (row=0; row < nrows; ++row, ++left, ++right) { if (row || col) print (",\n"); printf ("3;%4d,%4d,%4d;,\n", left, right+1, right); printf ("3;%4d,%4d,%4d;", left, left+1, right+1); } } print (";\n\n"); // Write out the texture coordinates. printf ("MeshTextureCoords { \n\t%d;\n", nverts); for (col=0; col <= ncols; ++col) { for (row=0; row <= nrows; ++row) { printf ("%s\t%.4f; %.4f;", ((row || col) ? ",\n" : ""), (col / double (ncols)), (row / double (nrows))); } } print (";\n}\n\n"); // Write out default material print ( "MeshMaterialList {\n" " # Diffuse White\n" " 1;1;0;;\n" " Material {\n" " 1.0; 1.0; 1.0; 1.0;;\n" " 1.0;\n" " 0.0; 0.0; 0.0;\n" " 0.0; 0.0; 0.0;\n" " }\n" "}\n\n" ); // Write out the normal vectors. print ("MeshNormals {\n\t1;\n\t0.0; 0.0; -1.0;;\n\n"); // Face Normal Indices printf ("\t%d;\n", 2 * nrows * ncols); int i; for (i=0; i < (2*nrows*ncols); ++i) printf ("%s\t3;0,0,0;", (i ? ",\n" : "")); print (";\n}\n"); // Epilogue print ("\n}\n"); }