|
|
/*******************************************************************************
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 <stdio.h>
#include <stdlib.h>
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] <rows> [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"); }
|