264 lines
6.8 KiB
C++
264 lines
6.8 KiB
C++
|
/*******************************************************************************
|
||
|
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");
|
||
|
}
|