1 |
– |
/* Copyright (c) 1995 Regents of the University of California */ |
2 |
– |
|
1 |
|
#ifndef lint |
2 |
< |
static char SCCSid[] = "$SunId$ LBL"; |
2 |
> |
static const char RCSid[] = "$Id$"; |
3 |
|
#endif |
6 |
– |
|
4 |
|
/* |
5 |
|
* Parse an MGF file, converting or discarding unsupported entities |
6 |
|
*/ |
7 |
|
|
8 |
|
#include <stdio.h> |
9 |
+ |
#include <stdlib.h> |
10 |
|
#include <math.h> |
11 |
|
#include <ctype.h> |
12 |
|
#include <string.h> |
61 |
|
|
62 |
|
static int e_any_toss(), /* discard unneeded entity */ |
63 |
|
e_ies(), /* IES luminaire file */ |
66 |
– |
e_include(), /* include file */ |
67 |
– |
e_sph(), /* sphere */ |
64 |
|
e_cct(), /* color temperature */ |
65 |
|
e_cmix(), /* color mixtures */ |
66 |
< |
e_cspec(), /* color spectra */ |
71 |
< |
e_cyl(), /* cylinder */ |
72 |
< |
e_cone(), /* cone */ |
73 |
< |
e_prism(), /* prism */ |
74 |
< |
e_ring(), /* ring */ |
75 |
< |
e_torus(); /* torus */ |
66 |
> |
e_cspec(); /* color spectra */ |
67 |
|
|
68 |
|
/* alternate handler support functions */ |
69 |
|
|
114 |
|
ineed |= 1L<<MG_E_POINT|1L<<MG_E_NORMAL|1L<<MG_E_VERTEX; |
115 |
|
} else |
116 |
|
uneed |= 1L<<MG_E_POINT|1L<<MG_E_NORMAL|1L<<MG_E_VERTEX|1L<<MG_E_XF; |
117 |
+ |
if (mg_ehand[MG_E_FACE] == NULL) |
118 |
+ |
mg_ehand[MG_E_FACE] = mg_ehand[MG_E_FACEH]; |
119 |
+ |
else if (mg_ehand[MG_E_FACEH] == NULL) |
120 |
+ |
mg_ehand[MG_E_FACEH] = e_faceh; |
121 |
|
if (mg_ehand[MG_E_COLOR] != NULL) { |
122 |
|
if (mg_ehand[MG_E_CMIX] == NULL) { |
123 |
|
mg_ehand[MG_E_CMIX] = e_cmix; |
235 |
|
return(MG_OK); |
236 |
|
} |
237 |
|
/* get name relative to this context */ |
238 |
< |
if (mg_file != NULL && (cp = strrchr(mg_file->fname, '/')) != NULL) { |
238 |
> |
if (fn[0] != '/' && mg_file != NULL && |
239 |
> |
(cp = strrchr(mg_file->fname, '/')) != NULL) { |
240 |
|
strcpy(ctx->fname, mg_file->fname); |
241 |
|
strcpy(ctx->fname+(cp-mg_file->fname+1), fn); |
242 |
|
} else |
256 |
|
register MG_FCTXT *ctx = mg_file; |
257 |
|
|
258 |
|
mg_file = ctx->prev; /* restore enclosing context */ |
259 |
< |
if (ctx->fp == stdin) |
260 |
< |
return; /* don't close standard input */ |
265 |
< |
fclose(ctx->fp); |
259 |
> |
if (ctx->fp != stdin) /* close file if it's a file */ |
260 |
> |
fclose(ctx->fp); |
261 |
|
} |
262 |
|
|
263 |
|
|
265 |
|
mg_fgetpos(pos) /* get current position in input file */ |
266 |
|
register MG_FPOS *pos; |
267 |
|
{ |
273 |
– |
extern long ftell(); |
274 |
– |
|
268 |
|
pos->fid = mg_file->fid; |
269 |
|
pos->lineno = mg_file->lineno; |
270 |
|
pos->offset = ftell(mg_file->fp); |
297 |
|
if (fgets(mg_file->inpline+len, |
298 |
|
MG_MAXLINE-len, mg_file->fp) == NULL) |
299 |
|
return(len); |
307 |
– |
mg_file->lineno++; |
300 |
|
len += strlen(mg_file->inpline+len); |
301 |
< |
if (len > 1 && mg_file->inpline[len-2] == '\\') |
302 |
< |
mg_file->inpline[--len-1] = ' '; |
303 |
< |
} while (mg_file->inpline[len]); |
301 |
> |
if (len >= MG_MAXLINE-1) |
302 |
> |
return(len); |
303 |
> |
mg_file->lineno++; |
304 |
> |
} while (len > 1 && mg_file->inpline[len-2] == '\\'); |
305 |
|
|
306 |
|
return(len); |
307 |
|
} |
312 |
|
{ |
313 |
|
char abuf[MG_MAXLINE]; |
314 |
|
char *argv[MG_MAXARGC]; |
315 |
< |
int en; |
316 |
< |
register char *cp, **ap; |
317 |
< |
|
318 |
< |
strcpy(cp=abuf, mg_file->inpline); |
319 |
< |
ap = argv; /* break into words */ |
315 |
> |
register char *cp, *cp2, **ap; |
316 |
> |
/* copy line, removing escape chars */ |
317 |
> |
cp = abuf; cp2 = mg_file->inpline; |
318 |
> |
while ((*cp++ = *cp2++)) |
319 |
> |
if (cp2[0] == '\n' && cp2[-1] == '\\') |
320 |
> |
cp--; |
321 |
> |
cp = abuf; ap = argv; /* break into words */ |
322 |
|
for ( ; ; ) { |
323 |
|
while (isspace(*cp)) |
324 |
|
*cp++ = '\0'; |
344 |
|
{ |
345 |
|
MG_FCTXT cntxt; |
346 |
|
int rval; |
347 |
+ |
register int nbr; |
348 |
|
|
349 |
|
if ((rval = mg_open(&cntxt, fn)) != MG_OK) { |
350 |
|
fprintf(stderr, "%s: %s\n", fn, mg_err[rval]); |
351 |
|
return(rval); |
352 |
|
} |
353 |
< |
while (mg_read()) /* parse each line */ |
353 |
> |
while ((nbr = mg_read()) > 0) { /* parse each line */ |
354 |
> |
if (nbr >= MG_MAXLINE-1) { |
355 |
> |
fprintf(stderr, "%s: %d: %s\n", cntxt.fname, |
356 |
> |
cntxt.lineno, mg_err[rval=MG_ELINE]); |
357 |
> |
break; |
358 |
> |
} |
359 |
|
if ((rval = mg_parse()) != MG_OK) { |
360 |
|
fprintf(stderr, "%s: %d: %s:\n%s", cntxt.fname, |
361 |
|
cntxt.lineno, mg_err[rval], |
362 |
|
cntxt.inpline); |
363 |
|
break; |
364 |
|
} |
365 |
+ |
} |
366 |
|
mg_close(); |
367 |
|
return(rval); |
368 |
|
} |
384 |
|
mg_clear() /* clear parser history */ |
385 |
|
{ |
386 |
|
c_clearall(); /* clear context tables */ |
387 |
< |
mg_file = NULL; /* reset our context */ |
387 |
> |
while (mg_file != NULL) /* reset our file context */ |
388 |
> |
mg_close(); |
389 |
|
} |
390 |
|
|
391 |
|
|
403 |
|
} |
404 |
|
|
405 |
|
|
406 |
< |
static int |
406 |
> |
int |
407 |
|
e_include(ac, av) /* include file */ |
408 |
|
int ac; |
409 |
|
char **av; |
411 |
|
char *xfarg[MG_MAXARGC]; |
412 |
|
MG_FCTXT ictx; |
413 |
|
XF_SPEC *xf_orig = xf_context; |
414 |
< |
int rv; |
414 |
> |
register int rv; |
415 |
|
|
416 |
|
if (ac < 2) |
417 |
|
return(MG_EARGC); |
424 |
|
for (i = 1; i < ac-1; i++) |
425 |
|
xfarg[i] = av[i+1]; |
426 |
|
xfarg[ac-1] = NULL; |
427 |
< |
if ((rv = mg_handle(MG_E_XF, ac-1, xfarg)) != MG_OK) |
427 |
> |
if ((rv = mg_handle(MG_E_XF, ac-1, xfarg)) != MG_OK) { |
428 |
> |
mg_close(); |
429 |
|
return(rv); |
430 |
+ |
} |
431 |
|
} |
432 |
|
do { |
433 |
< |
while (mg_read()) |
433 |
> |
while ((rv = mg_read()) > 0) { |
434 |
> |
if (rv >= MG_MAXLINE-1) { |
435 |
> |
fprintf(stderr, "%s: %d: %s\n", ictx.fname, |
436 |
> |
ictx.lineno, mg_err[MG_ELINE]); |
437 |
> |
mg_close(); |
438 |
> |
return(MG_EINCL); |
439 |
> |
} |
440 |
|
if ((rv = mg_parse()) != MG_OK) { |
441 |
|
fprintf(stderr, "%s: %d: %s:\n%s", ictx.fname, |
442 |
|
ictx.lineno, mg_err[rv], |
444 |
|
mg_close(); |
445 |
|
return(MG_EINCL); |
446 |
|
} |
447 |
+ |
} |
448 |
|
if (ac > 2) |
449 |
< |
if ((rv = mg_handle(MG_E_XF, 1, xfarg)) != MG_OK) |
449 |
> |
if ((rv = mg_handle(MG_E_XF, 1, xfarg)) != MG_OK) { |
450 |
> |
mg_close(); |
451 |
|
return(rv); |
452 |
+ |
} |
453 |
|
} while (xf_context != xf_orig); |
454 |
|
mg_close(); |
455 |
|
return(MG_OK); |
456 |
|
} |
457 |
|
|
458 |
|
|
459 |
+ |
int |
460 |
+ |
e_faceh(ac, av) /* replace face+holes with single contour */ |
461 |
+ |
int ac; |
462 |
+ |
char **av; |
463 |
+ |
{ |
464 |
+ |
char *newav[MG_MAXARGC]; |
465 |
+ |
int lastp = 0; |
466 |
+ |
register int i, j; |
467 |
+ |
|
468 |
+ |
newav[0] = mg_ename[MG_E_FACE]; |
469 |
+ |
for (i = 1; i < ac; i++) |
470 |
+ |
if (av[i][0] == '-') { |
471 |
+ |
if (i < 4) |
472 |
+ |
return(MG_EARGC); |
473 |
+ |
if (i >= ac-1) |
474 |
+ |
break; |
475 |
+ |
if (!lastp) |
476 |
+ |
lastp = i-1; |
477 |
+ |
for (j = i+1; j < ac-1 && av[j+1][0] != '-'; j++) |
478 |
+ |
; |
479 |
+ |
if (j - i < 3) |
480 |
+ |
return(MG_EARGC); |
481 |
+ |
newav[i] = av[j]; /* connect hole loop */ |
482 |
+ |
} else |
483 |
+ |
newav[i] = av[i]; /* hole or perimeter vertex */ |
484 |
+ |
if (lastp) |
485 |
+ |
newav[i++] = av[lastp]; /* finish seam to outside */ |
486 |
+ |
newav[i] = NULL; |
487 |
+ |
return(mg_handle(MG_E_FACE, i, newav)); |
488 |
+ |
} |
489 |
+ |
|
490 |
+ |
|
491 |
|
static void |
492 |
|
make_axes(u, v, w) /* compute u and v given w (normalized) */ |
493 |
|
FVECT u, v, w; |
505 |
|
} |
506 |
|
|
507 |
|
|
508 |
< |
static int |
508 |
> |
int |
509 |
|
e_sph(ac, av) /* expand a sphere into cones */ |
510 |
|
int ac; |
511 |
|
char **av; |
557 |
|
} |
558 |
|
|
559 |
|
|
560 |
< |
static int |
560 |
> |
int |
561 |
|
e_torus(ac, av) /* expand a torus into cones */ |
562 |
|
int ac; |
563 |
|
char **av; |
649 |
|
} |
650 |
|
|
651 |
|
|
652 |
< |
static int |
652 |
> |
int |
653 |
|
e_cyl(ac, av) /* replace a cylinder with equivalent cone */ |
654 |
|
int ac; |
655 |
|
char **av; |
666 |
|
} |
667 |
|
|
668 |
|
|
669 |
< |
static int |
669 |
> |
int |
670 |
|
e_ring(ac, av) /* turn a ring into polygons */ |
671 |
|
int ac; |
672 |
|
char **av; |
764 |
|
} |
765 |
|
|
766 |
|
|
767 |
< |
static int |
767 |
> |
int |
768 |
|
e_cone(ac, av) /* turn a cone into polygons */ |
769 |
|
int ac; |
770 |
|
char **av; |
806 |
|
if (rad2 == 0.) |
807 |
|
return(MG_EILL); |
808 |
|
} else if (rad2 != 0.) { |
809 |
< |
if (rad1 < 0. ^ rad2 < 0.) |
809 |
> |
if ((rad1 < 0.) ^ (rad2 < 0.)) |
810 |
|
return(MG_EILL); |
811 |
|
} else { /* swap */ |
812 |
|
C_VERTEX *cv; |
934 |
|
} |
935 |
|
|
936 |
|
|
937 |
< |
static int |
937 |
> |
int |
938 |
|
e_prism(ac, av) /* turn a prism into polygons */ |
939 |
|
int ac; |
940 |
|
char **av; |
1046 |
|
{ |
1047 |
|
static char xbuf[24], ybuf[24]; |
1048 |
|
static char *ccom[4] = {mg_ename[MG_E_CXY], xbuf, ybuf}; |
1003 |
– |
int rv; |
1049 |
|
|
1050 |
|
sprintf(xbuf, "%.4f", c_ccolor->cx); |
1051 |
|
sprintf(ybuf, "%.4f", c_ccolor->cy); |
1052 |
< |
if ((rv = mg_handle(MG_E_CXY, 3, ccom)) != MG_OK) |
1008 |
< |
return(rv); |
1009 |
< |
return(MG_OK); |
1052 |
> |
return(mg_handle(MG_E_CXY, 3, ccom)); |
1053 |
|
} |
1054 |
|
|
1055 |
|
|