| 1 |
greg |
1.1 |
/* Copyright (c) 1990 Regents of the University of California */ |
| 2 |
|
|
|
| 3 |
|
|
#ifndef lint |
| 4 |
|
|
static char SCCSid[] = "$SunId$ LBL"; |
| 5 |
|
|
#endif |
| 6 |
|
|
|
| 7 |
|
|
/* |
| 8 |
|
|
* Convert Neutral File Format input to Radiance scene description. |
| 9 |
|
|
* |
| 10 |
|
|
* 12/9/90 Greg Ward |
| 11 |
|
|
*/ |
| 12 |
|
|
|
| 13 |
|
|
/****************************************************************** |
| 14 |
|
|
|
| 15 |
|
|
Since Eric Haines wrote such excellent documentation of his |
| 16 |
|
|
Neutral File Format, I am just going to reprint it here with |
| 17 |
|
|
my added comments in braces {}. |
| 18 |
|
|
|
| 19 |
|
|
Neutral File Format (NFF), by Eric Haines |
| 20 |
|
|
|
| 21 |
|
|
Draft document #1, 10/3/88 |
| 22 |
|
|
|
| 23 |
|
|
The NFF (Neutral File Format) is designed as a minimal scene description |
| 24 |
|
|
language. The language was designed in order to test various rendering |
| 25 |
|
|
algorithms and efficiency schemes. It is meant to describe the geometry and |
| 26 |
|
|
basic surface characteristics of objects, the placement of lights, and the |
| 27 |
|
|
viewing frustum for the eye. Some additional information is provided for |
| 28 |
|
|
esthetic reasons (such as the color of the objects, which is not strictly |
| 29 |
|
|
necessary for testing rendering algorithms). |
| 30 |
|
|
|
| 31 |
|
|
Future enhancements include: circle and torus objects, spline surfaces |
| 32 |
|
|
with trimming curves, directional lights, characteristics for positional |
| 33 |
|
|
lights, CSG descriptions, and probably more by the time you read this. |
| 34 |
|
|
Comments, suggestions, and criticisms are all welcome. |
| 35 |
|
|
|
| 36 |
|
|
At present the NFF file format is used in conjunction with the SPD (Standard |
| 37 |
|
|
Procedural Database) software, a package designed to create a variety of |
| 38 |
|
|
databases for testing rendering schemes. The SPD package is available |
| 39 |
|
|
from Netlib and via ftp from drizzle.cs.uoregon.edu. For more information |
| 40 |
|
|
about SPD see "A Proposal for Standard Graphics Environments," IEEE Computer |
| 41 |
|
|
Graphics and Applications, vol. 7, no. 11, November 1987, pp. 3-5. |
| 42 |
|
|
|
| 43 |
|
|
By providing a minimal interface, NFF is meant to act as a simple format to |
| 44 |
|
|
allow the programmer to quickly write filters to move from NFF to the |
| 45 |
|
|
local file format. Presently the following entities are supported: |
| 46 |
|
|
A simple perspective frustum |
| 47 |
|
|
A positional (vs. directional) light source description |
| 48 |
|
|
A background color description |
| 49 |
|
|
A surface properties description |
| 50 |
|
|
Polygon, polygonal patch, cylinder/cone, and sphere descriptions |
| 51 |
|
|
|
| 52 |
|
|
Files are output as lines of text. For each entity, the first line |
| 53 |
|
|
defines its type. The rest of the first line and possibly other lines |
| 54 |
|
|
contain further information about the entity. Entities include: |
| 55 |
|
|
|
| 56 |
|
|
"v" - viewing vectors and angles { optionally creates view file } |
| 57 |
|
|
"l" - positional light location { it's there, but bad to use } |
| 58 |
|
|
"b" - background color { ditto } |
| 59 |
|
|
"f" - object material properties { this is flakey } |
| 60 |
|
|
"c" - cone or cylinder primitive |
| 61 |
|
|
"s" - sphere primitive |
| 62 |
|
|
"p" - polygon primitive |
| 63 |
|
|
"pp" - polygonal patch primitive { interpreted same as p for now } |
| 64 |
|
|
|
| 65 |
|
|
These are explained in depth below: { see conversion routines } |
| 66 |
|
|
|
| 67 |
|
|
***********************************************************************/ |
| 68 |
|
|
|
| 69 |
|
|
#include <stdio.h> |
| 70 |
|
|
|
| 71 |
|
|
char *viewfile = NULL; /* view parameters file */ |
| 72 |
|
|
|
| 73 |
|
|
char *progname; |
| 74 |
|
|
|
| 75 |
|
|
|
| 76 |
|
|
main(argc, argv) /* convert NFF file to Radiance */ |
| 77 |
|
|
int argc; |
| 78 |
|
|
char *argv[]; |
| 79 |
|
|
{ |
| 80 |
|
|
int i; |
| 81 |
|
|
|
| 82 |
|
|
progname = argv[0]; |
| 83 |
|
|
for (i = 1; i < argc; i++) |
| 84 |
|
|
if (argc-i > 1 && !strcmp(argv[i], "-vf")) |
| 85 |
|
|
viewfile = argv[++i]; |
| 86 |
|
|
else |
| 87 |
|
|
break; |
| 88 |
|
|
if (i-argc > 1) |
| 89 |
|
|
goto userr; |
| 90 |
|
|
if (i-argc == 1 && freopen(argv[i], "r", stdin) == NULL) { |
| 91 |
|
|
perror(argv[i]); |
| 92 |
|
|
exit(1); |
| 93 |
|
|
} |
| 94 |
|
|
init(); |
| 95 |
|
|
nff2rad(); |
| 96 |
|
|
exit(0); |
| 97 |
|
|
userr: |
| 98 |
|
|
fprintf(stderr, "Usage: %s [-vf viewfile] [input]\n", progname); |
| 99 |
|
|
exit(1); |
| 100 |
|
|
} |
| 101 |
|
|
|
| 102 |
|
|
|
| 103 |
|
|
init() /* spit out initial definitions */ |
| 104 |
|
|
{ |
| 105 |
|
|
printf("# File created by %s\n", progname); |
| 106 |
|
|
printf("\nvoid light light\n"); |
| 107 |
|
|
printf("0\n0\n3 1 1 1\n"); |
| 108 |
|
|
printf("\nvoid plastic fill\n"); |
| 109 |
|
|
printf("0\n0\n5 .5 .5 .5 0 0\n"); |
| 110 |
|
|
} |
| 111 |
|
|
|
| 112 |
|
|
|
| 113 |
|
|
nff2rad() /* convert NFF on stdin to Radiance on stdout */ |
| 114 |
|
|
{ |
| 115 |
|
|
register int c; |
| 116 |
|
|
|
| 117 |
|
|
while ((c = getchar()) != EOF) |
| 118 |
|
|
switch (c) { |
| 119 |
|
|
case ' ': /* white space */ |
| 120 |
|
|
case '\t': |
| 121 |
|
|
case '\n': |
| 122 |
|
|
case '\f': |
| 123 |
|
|
case '\r': |
| 124 |
|
|
continue; |
| 125 |
|
|
case '#': /* comment */ |
| 126 |
|
|
comment(); |
| 127 |
|
|
break; |
| 128 |
|
|
case 'v': /* view point */ |
| 129 |
|
|
view(); |
| 130 |
|
|
break; |
| 131 |
|
|
case 'l': /* light source */ |
| 132 |
|
|
light(); |
| 133 |
|
|
break; |
| 134 |
|
|
case 'b': /* background color */ |
| 135 |
|
|
background(); |
| 136 |
|
|
break; |
| 137 |
|
|
case 'f': /* fill material */ |
| 138 |
|
|
fill(); |
| 139 |
|
|
break; |
| 140 |
|
|
case 'c': /* cylinder or cone */ |
| 141 |
|
|
cone(); |
| 142 |
|
|
break; |
| 143 |
|
|
case 's': /* sphere */ |
| 144 |
|
|
sphere(); |
| 145 |
|
|
break; |
| 146 |
|
|
case 'p': /* polygon or patch */ |
| 147 |
|
|
poly(); |
| 148 |
|
|
break; |
| 149 |
|
|
default: /* unknown */ |
| 150 |
|
|
fprintf(stderr, "%c: unknown NFF primitive\n", c); |
| 151 |
|
|
exit(1); |
| 152 |
|
|
} |
| 153 |
|
|
} |
| 154 |
|
|
|
| 155 |
|
|
|
| 156 |
|
|
/******************************************* |
| 157 |
|
|
|
| 158 |
|
|
Comment. Description: |
| 159 |
|
|
"#" [ string ] |
| 160 |
|
|
|
| 161 |
|
|
Format: |
| 162 |
|
|
# [ string ] |
| 163 |
|
|
|
| 164 |
|
|
As soon as a "#" character is detected, the rest of the line is considered |
| 165 |
|
|
a comment. |
| 166 |
|
|
|
| 167 |
|
|
******************/ |
| 168 |
|
|
|
| 169 |
|
|
comment() |
| 170 |
|
|
{ |
| 171 |
|
|
register int c; |
| 172 |
|
|
|
| 173 |
|
|
putchar('#'); |
| 174 |
|
|
while ((c = getchar()) != EOF) { |
| 175 |
|
|
putchar(c); |
| 176 |
|
|
if (c == '\n') |
| 177 |
|
|
break; |
| 178 |
|
|
} |
| 179 |
|
|
} |
| 180 |
|
|
|
| 181 |
|
|
|
| 182 |
|
|
/*************************************************** |
| 183 |
|
|
|
| 184 |
|
|
Viewpoint location. Description: |
| 185 |
|
|
"v" |
| 186 |
|
|
"from" Fx Fy Fz |
| 187 |
|
|
"at" Ax Ay Az |
| 188 |
|
|
"up" Ux Uy Uz |
| 189 |
|
|
"angle" angle |
| 190 |
|
|
"hither" hither |
| 191 |
|
|
"resolution" xres yres |
| 192 |
|
|
|
| 193 |
|
|
Format: |
| 194 |
|
|
|
| 195 |
|
|
v |
| 196 |
|
|
from %g %g %g |
| 197 |
|
|
at %g %g %g |
| 198 |
|
|
up %g %g %g |
| 199 |
|
|
angle %g |
| 200 |
|
|
hither %g |
| 201 |
|
|
resolution %d %d |
| 202 |
|
|
|
| 203 |
|
|
The parameters are: |
| 204 |
|
|
|
| 205 |
|
|
From: the eye location in XYZ. |
| 206 |
|
|
At: a position to be at the center of the image, in XYZ world |
| 207 |
|
|
coordinates. A.k.a. "lookat". |
| 208 |
|
|
Up: a vector defining which direction is up, as an XYZ vector. |
| 209 |
|
|
Angle: in degrees, defined as from the center of top pixel row to |
| 210 |
|
|
bottom pixel row and left column to right column. |
| 211 |
|
|
Resolution: in pixels, in x and in y. |
| 212 |
|
|
|
| 213 |
|
|
Note that no assumptions are made about normalizing the data (e.g. the |
| 214 |
|
|
from-at distance does not have to be 1). Also, vectors are not |
| 215 |
|
|
required to be perpendicular to each other. |
| 216 |
|
|
|
| 217 |
|
|
For all databases some viewing parameters are always the same: |
| 218 |
|
|
Yon is "at infinity." |
| 219 |
|
|
Aspect ratio is 1.0. |
| 220 |
|
|
|
| 221 |
|
|
A view entity must be defined before any objects are defined (this |
| 222 |
|
|
requirement is so that NFF files can be used by hidden surface machines). |
| 223 |
|
|
|
| 224 |
|
|
***************/ |
| 225 |
|
|
|
| 226 |
|
|
view() |
| 227 |
|
|
{ |
| 228 |
|
|
static FILE *fp = NULL; |
| 229 |
|
|
float from[3], at[3], up[3], angle; |
| 230 |
|
|
|
| 231 |
|
|
if (scanf(" from %f %f %f", &from[0], &from[1], &from[2]) != 3) |
| 232 |
|
|
goto fmterr; |
| 233 |
|
|
if (scanf(" at %f %f %f", &at[0], &at[1], &at[2]) != 3) |
| 234 |
|
|
goto fmterr; |
| 235 |
|
|
if (scanf(" up %f %f %f", &up[0], &up[1], &up[2]) != 3) |
| 236 |
|
|
goto fmterr; |
| 237 |
|
|
if (scanf(" angle %f", &angle) != 1) |
| 238 |
|
|
goto fmterr; |
| 239 |
|
|
scanf(" hither %*f"); |
| 240 |
|
|
scanf(" resolution %*d %*d"); |
| 241 |
|
|
if (viewfile != NULL) { |
| 242 |
|
|
if (fp == NULL && (fp = fopen(viewfile, "a")) == NULL) { |
| 243 |
|
|
perror(viewfile); |
| 244 |
|
|
exit(1); |
| 245 |
|
|
} |
| 246 |
|
|
fprintf(fp, |
| 247 |
|
|
"VIEW= -vp %g %g %g -vd %g %g %g -vu %g %g %g -vh %g -vv %g\n", |
| 248 |
|
|
from[0], from[1], from[2], |
| 249 |
|
|
at[0]-from[0], at[1]-from[1], at[2]-from[2], |
| 250 |
|
|
up[0], up[1], up[2], |
| 251 |
|
|
angle, angle); |
| 252 |
|
|
} |
| 253 |
|
|
return; |
| 254 |
|
|
fmterr: |
| 255 |
|
|
fprintf(stderr, "%s: view syntax error\n", progname); |
| 256 |
|
|
exit(1); |
| 257 |
|
|
} |
| 258 |
|
|
|
| 259 |
|
|
|
| 260 |
|
|
/******************************** |
| 261 |
|
|
|
| 262 |
|
|
Positional light. A light is defined by XYZ position. Description: |
| 263 |
|
|
"l" X Y Z |
| 264 |
|
|
|
| 265 |
|
|
Format: |
| 266 |
|
|
l %g %g %g |
| 267 |
|
|
|
| 268 |
|
|
All light entities must be defined before any objects are defined (this |
| 269 |
|
|
requirement is so that NFF files can be used by hidden surface machines). |
| 270 |
|
|
Lights have a non-zero intensity of no particular value [this definition |
| 271 |
|
|
may change soon, with the addition of an intensity and/or color]. |
| 272 |
|
|
|
| 273 |
|
|
**************************/ |
| 274 |
|
|
|
| 275 |
|
|
light() |
| 276 |
|
|
{ |
| 277 |
|
|
static int nlights = 0; |
| 278 |
|
|
register int c; |
| 279 |
|
|
float x, y, z; |
| 280 |
|
|
|
| 281 |
|
|
if (scanf("%f %f %f", &x, &y, &z) != 3) { |
| 282 |
|
|
fprintf(stderr, "%s: light source syntax error\n", progname); |
| 283 |
|
|
exit(1); |
| 284 |
|
|
} |
| 285 |
|
|
while ((c = getchar()) != EOF && c != '\n') |
| 286 |
|
|
; |
| 287 |
|
|
printf("\nlight sphere l%d ", ++nlights); |
| 288 |
|
|
printf("0\n0\n4 %g %g %g 1\n", x, y, z); |
| 289 |
|
|
} |
| 290 |
|
|
|
| 291 |
|
|
|
| 292 |
|
|
/************************************************** |
| 293 |
|
|
|
| 294 |
|
|
Background color. A color is simply RGB with values between 0 and 1: |
| 295 |
|
|
"b" R G B |
| 296 |
|
|
|
| 297 |
|
|
Format: |
| 298 |
|
|
b %g %g %g |
| 299 |
|
|
|
| 300 |
|
|
If no background color is set, assume RGB = {0,0,0}. |
| 301 |
|
|
|
| 302 |
|
|
********************/ |
| 303 |
|
|
|
| 304 |
|
|
background() |
| 305 |
|
|
{ |
| 306 |
|
|
float r, g, b; |
| 307 |
|
|
|
| 308 |
|
|
if (scanf("%f %f %f", &r, &g, &b) != 3) { |
| 309 |
|
|
fprintf(stderr, "%s: background syntax error\n", progname); |
| 310 |
|
|
exit(1); |
| 311 |
|
|
} |
| 312 |
|
|
printf("\nvoid glow backg_color\n"); |
| 313 |
|
|
printf("0\n0\n4 %g %g %g 0\n", r, g, b); |
| 314 |
|
|
printf("\nbackg_color source background\n"); |
| 315 |
|
|
printf("0\n0\n4 0 0 1 360\n"); |
| 316 |
|
|
} |
| 317 |
|
|
|
| 318 |
|
|
|
| 319 |
|
|
/**************************************************** |
| 320 |
|
|
|
| 321 |
|
|
Fill color and shading parameters. Description: |
| 322 |
|
|
"f" red green blue Kd Ks Shine T index_of_refraction |
| 323 |
|
|
|
| 324 |
|
|
Format: |
| 325 |
|
|
f %g %g %g %g %g %g %g %g |
| 326 |
|
|
|
| 327 |
|
|
RGB is in terms of 0.0 to 1.0. |
| 328 |
|
|
|
| 329 |
|
|
Kd is the diffuse component, Ks the specular, Shine is the Phong cosine |
| 330 |
|
|
power for highlights, T is transmittance (fraction of light passed per |
| 331 |
|
|
unit). Usually, 0 <= Kd <= 1 and 0 <= Ks <= 1, though it is not required |
| 332 |
|
|
that Kd + Ks == 1. Note that transmitting objects ( T > 0 ) are considered |
| 333 |
|
|
to have two sides for algorithms that need these (normally objects have |
| 334 |
|
|
one side). |
| 335 |
|
|
|
| 336 |
|
|
The fill color is used to color the objects following it until a new color |
| 337 |
|
|
is assigned. |
| 338 |
|
|
|
| 339 |
|
|
*********************/ |
| 340 |
|
|
|
| 341 |
|
|
fill() |
| 342 |
|
|
{ |
| 343 |
|
|
float r, g, b, d, s, p, t, n; |
| 344 |
|
|
|
| 345 |
|
|
if (scanf("%f %f %f %f %f %f %f %f", &r, &g, &b, |
| 346 |
|
|
&d, &s, &p, &t, &n) != 8) { |
| 347 |
|
|
fprintf(stderr, "%s: fill material syntax error\n", progname); |
| 348 |
|
|
exit(1); |
| 349 |
|
|
} |
| 350 |
|
|
d /= 1.-s-t; |
| 351 |
|
|
r *= d; |
| 352 |
|
|
g *= d; |
| 353 |
|
|
b *= d; |
| 354 |
|
|
if (p > 1.) |
| 355 |
|
|
p = 1./p; |
| 356 |
|
|
if (t > .001) { /* has transmission */ |
| 357 |
|
|
printf("\nvoid trans fill\n"); |
| 358 |
greg |
1.2 |
printf("0\n0\n7 %g %g %g %g 0 %g 1\n", r, g, b, s, t); |
| 359 |
greg |
1.1 |
} else { /* no transmission */ |
| 360 |
|
|
printf("\nvoid plastic fill\n"); |
| 361 |
|
|
printf("0\n0\n5 %g %g %g %g %g\n", r, g, b, s, p); |
| 362 |
|
|
} |
| 363 |
|
|
} |
| 364 |
|
|
|
| 365 |
|
|
|
| 366 |
|
|
/***************************************************** |
| 367 |
|
|
|
| 368 |
|
|
Cylinder or cone. A cylinder is defined as having a radius and an axis |
| 369 |
|
|
defined by two points, which also define the top and bottom edge of the |
| 370 |
|
|
cylinder. A cone is defined similarly, the difference being that the apex |
| 371 |
|
|
and base radii are different. The apex radius is defined as being smaller |
| 372 |
|
|
than the base radius. Note that the surface exists without endcaps. The |
| 373 |
|
|
cone or cylinder description: |
| 374 |
|
|
|
| 375 |
|
|
"c" |
| 376 |
|
|
base.x base.y base.z base_radius |
| 377 |
|
|
apex.x apex.y apex.z apex_radius |
| 378 |
|
|
|
| 379 |
|
|
Format: |
| 380 |
|
|
c |
| 381 |
|
|
%g %g %g %g |
| 382 |
|
|
%g %g %g %g |
| 383 |
|
|
|
| 384 |
|
|
A negative value for both radii means that only the inside of the object is |
| 385 |
|
|
visible (objects are normally considered one sided, with the outside |
| 386 |
|
|
visible). Note that the base and apex cannot be coincident for a cylinder |
| 387 |
|
|
or cone. |
| 388 |
|
|
|
| 389 |
|
|
************************/ |
| 390 |
|
|
|
| 391 |
|
|
cone() |
| 392 |
|
|
{ |
| 393 |
|
|
static int ncs = 0; |
| 394 |
|
|
int invert; |
| 395 |
|
|
float x0, y0, z0, x1, y1, z1, r0, r1; |
| 396 |
|
|
|
| 397 |
|
|
if (scanf("%f %f %f %f %f %f %f %f", &x0, &y0, &z0, &r0, |
| 398 |
|
|
&x1, &y1, &z1, &r1) != 8) { |
| 399 |
|
|
fprintf(stderr, "%s: cylinder or cone syntax error\n", |
| 400 |
|
|
progname); |
| 401 |
|
|
exit(1); |
| 402 |
|
|
} |
| 403 |
|
|
if (invert = r0 < 0.) { |
| 404 |
|
|
r0 = -r0; |
| 405 |
|
|
r1 = -r1; |
| 406 |
|
|
} |
| 407 |
|
|
if (r0-r1 < .001 && r1-r0 < .001) { /* cylinder */ |
| 408 |
|
|
printf("\nfill %s c%d ", invert?"tube":"cylinder", ++ncs); |
| 409 |
|
|
printf("0\n0\n7\n"); |
| 410 |
|
|
printf("\t%g\t%g\t%g\n", x0, y0, z0); |
| 411 |
|
|
printf("\t%g\t%g\t%g\n", x1, y1, z1); |
| 412 |
|
|
printf("\t%g\n", r0); |
| 413 |
|
|
} else { /* cone */ |
| 414 |
|
|
printf("\nfill %s c%d ", invert?"cup":"cone", ++ncs); |
| 415 |
|
|
printf("0\n0\n8\n"); |
| 416 |
|
|
printf("\t%g\t%g\t%g\n", x0, y0, z0); |
| 417 |
|
|
printf("\t%g\t%g\t%g\n", x1, y1, z1); |
| 418 |
|
|
printf("\t%g\t%g\n", r0, r1); |
| 419 |
|
|
} |
| 420 |
|
|
} |
| 421 |
|
|
|
| 422 |
|
|
|
| 423 |
|
|
/***************************************** |
| 424 |
|
|
|
| 425 |
|
|
Sphere. A sphere is defined by a radius and center position: |
| 426 |
|
|
"s" center.x center.y center.z radius |
| 427 |
|
|
|
| 428 |
|
|
Format: |
| 429 |
|
|
s %g %g %g %g |
| 430 |
|
|
|
| 431 |
|
|
If the radius is negative, then only the sphere's inside is visible |
| 432 |
|
|
(objects are normally considered one sided, with the outside visible). |
| 433 |
|
|
|
| 434 |
|
|
******************/ |
| 435 |
|
|
|
| 436 |
|
|
sphere() |
| 437 |
|
|
{ |
| 438 |
|
|
static int nspheres = 0; |
| 439 |
|
|
float x, y, z, r; |
| 440 |
|
|
|
| 441 |
|
|
if (scanf("%f %f %f %f", &x, &y, &z, &r) != 4) { |
| 442 |
|
|
fprintf(stderr, "%s: sphere syntax error\n", progname); |
| 443 |
|
|
exit(1); |
| 444 |
|
|
} |
| 445 |
|
|
if (r < 0.) { |
| 446 |
|
|
printf("\nfill bubble s%d ", ++nspheres); |
| 447 |
|
|
printf("0\n0\n4 %g %g %g %g\n", x, y, z, -r); |
| 448 |
|
|
} else { |
| 449 |
|
|
printf("\nfill sphere s%d ", ++nspheres); |
| 450 |
|
|
printf("0\n0\n4 %g %g %g %g\n", x, y, z, r); |
| 451 |
|
|
} |
| 452 |
|
|
} |
| 453 |
|
|
|
| 454 |
|
|
|
| 455 |
|
|
/********************************************* |
| 456 |
|
|
|
| 457 |
|
|
Polygon. A polygon is defined by a set of vertices. With these databases, |
| 458 |
|
|
a polygon is defined to have all points coplanar. A polygon has only |
| 459 |
|
|
one side, with the order of the vertices being counterclockwise as you |
| 460 |
|
|
face the polygon (right-handed coordinate system). The first two edges |
| 461 |
|
|
must form a non-zero convex angle, so that the normal and side visibility |
| 462 |
|
|
can be determined. Description: |
| 463 |
|
|
|
| 464 |
|
|
"p" total_vertices |
| 465 |
|
|
vert1.x vert1.y vert1.z |
| 466 |
|
|
[etc. for total_vertices vertices] |
| 467 |
|
|
|
| 468 |
|
|
Format: |
| 469 |
|
|
p %d |
| 470 |
|
|
[ %g %g %g ] <-- for total_vertices vertices |
| 471 |
|
|
|
| 472 |
|
|
-------- |
| 473 |
|
|
|
| 474 |
|
|
Polygonal patch. A patch is defined by a set of vertices and their normals. |
| 475 |
|
|
With these databases, a patch is defined to have all points coplanar. |
| 476 |
|
|
A patch has only one side, with the order of the vertices being |
| 477 |
|
|
counterclockwise as you face the patch (right-handed coordinate system). |
| 478 |
|
|
The first two edges must form a non-zero convex angle, so that the normal |
| 479 |
|
|
and side visibility can be determined. Description: |
| 480 |
|
|
|
| 481 |
|
|
"pp" total_vertices |
| 482 |
|
|
vert1.x vert1.y vert1.z norm1.x norm1.y norm1.z |
| 483 |
|
|
[etc. for total_vertices vertices] |
| 484 |
|
|
|
| 485 |
|
|
Format: |
| 486 |
|
|
pp %d |
| 487 |
|
|
[ %g %g %g %g %g %g ] <-- for total_vertices vertices |
| 488 |
|
|
|
| 489 |
|
|
*******************/ |
| 490 |
|
|
|
| 491 |
|
|
poly() |
| 492 |
|
|
{ |
| 493 |
|
|
static int npolys = 0; |
| 494 |
|
|
int ispatch; |
| 495 |
|
|
int nverts; |
| 496 |
|
|
float x, y, z; |
| 497 |
|
|
|
| 498 |
|
|
ispatch = getchar(); |
| 499 |
|
|
if (ispatch != 'p') { |
| 500 |
|
|
ungetc(ispatch, stdin); |
| 501 |
|
|
ispatch = 0; |
| 502 |
|
|
} |
| 503 |
|
|
if (scanf("%d", &nverts) != 1) |
| 504 |
|
|
goto fmterr; |
| 505 |
|
|
printf("\nfill polygon p%d ", ++npolys); |
| 506 |
|
|
printf("0\n0\n%d\n", 3*nverts); |
| 507 |
|
|
while (nverts-- > 0) { |
| 508 |
|
|
if (scanf("%f %f %f", &x, &y, &z) != 3) |
| 509 |
|
|
goto fmterr; |
| 510 |
|
|
if (ispatch) |
| 511 |
|
|
scanf("%*f %*f %*f"); |
| 512 |
|
|
printf("\t%g\t%g\t%g\n", x, y, z); |
| 513 |
|
|
} |
| 514 |
|
|
return; |
| 515 |
|
|
fmterr: |
| 516 |
|
|
fprintf(stderr, "%s: polygon or patch syntax error\n", progname); |
| 517 |
|
|
exit(1); |
| 518 |
|
|
} |