home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
3D Color Clip Art
/
3D_Color_Clip_Art.bin
/
3d-progs
/
rad386
/
parse.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-15
|
14KB
|
542 lines
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include "preview.h"
float bound_min_x,bound_min_y,bound_min_z=LARGE;
float bound_max_x,bound_max_y,bound_max_z= -LARGE;
#if defined(RADFILTER)
float cum_area=0.;
#endif
#define MIN(a,b) (((a)>(b))?(b):(a))
#define MAX(a,b) (((a)>(b))?(a):(b))
#ifdef notdef
#if defined(RADFILTER)
double
#else
int
#endif
polygon_bound(),
sphere_bound(),
cylinder_bound(),
cone_bound(),
ring_bound(),
no_bound();
#endif
#if defined(RADFILTER)
void project_point(n,x,y,z,px,py)
int n;
double x,y,z,*px,*py;
{
switch(n){
case 0: *px = y; *py = z; break;
case 1: *px = z; *py = x; break;
case 2: *px = x; *py = y; break;
}
}
double trapez_area(n,f,nx,ny,nz)
int n;
double f[],nx,ny,nz;
{
double area=0.,lastx,lasty,curx,cury;
int i,dominant_axis;
if (fabs(nx) >= fabs(ny) && fabs(nx) >= fabs(nz))
dominant_axis=0;
else if (fabs(ny) >= fabs(nx) && fabs(ny) >= fabs(nz))
dominant_axis=1;
else dominant_axis=2;
project_point(dominant_axis,
f[(n-1)*3],f[(n-1)*3+1],f[(n-1)*3+2],&lastx,&lasty);
for(i=0;i<n;i++,lastx=curx,lasty=cury){
project_point(dominant_axis,
f[i*3],f[i*3+1],f[i*3+2],&curx,&cury);
area += (curx-lastx)*(cury+lasty);
}
area /= ((dominant_axis==0)?nx:((dominant_axis==1)?ny:nz));
return(0.5*fabs(area));
}
double
#endif
polygon_bound(fargs,name)
char *name;
FUNARGS *fargs;
{
int i,k,nv=fargs->nfargs/3;;
if (fargs->nfargs < 9)
error("wanted an > 3 for verticies",name);
for (i = k = 0; i < nv; i++,k+=3) {
double x,y,z;
x = fargs->farg[k],
y = fargs->farg[k+1];
z = fargs->farg[k+2];
bound_min_x = MIN(bound_min_x,x);
bound_max_x = MAX(bound_max_x,x);
bound_min_y = MIN(bound_min_y,y);
bound_max_y = MAX(bound_max_y,y);
bound_min_z = MIN(bound_min_z,z);
bound_max_z = MAX(bound_max_z,z);
}
#if defined(RADFILTER)
{
double area=0.,length;
int i,j;
double nx,ny,nz;
nx = ny = nz = 0.;
for(i=0,j=1;i<nv;i++,j++){
if (j==nv)j=0;
nx += (fargs->farg[i*3+1]-fargs->farg[j*3+1])*
(fargs->farg[i*3+2]+fargs->farg[j*3+2]);
ny += (fargs->farg[i*3+2]-fargs->farg[j*3+2])*
(fargs->farg[i*3]+fargs->farg[j*3]);
nz += (fargs->farg[i*3]-fargs->farg[j*3])*
(fargs->farg[i*3+1]+fargs->farg[j*3+1]);
}
length = sqrt(nx*nx+ny*ny+nz*nz);
if (length != 0.){
nx/=length; ny/=length; nz/=length;
}
else error("Zero Vector Normal",name);
area = trapez_area(nv,fargs->farg,nx,ny,nz);
cum_area += area;
return(area);
}
#endif
}
#if defined(RADFILTER)
double
#endif
sphere_bound(fargs,name)
char *name;
FUNARGS *fargs;
{
double x,y,z,r;
if (fargs->nfargs != 4)
error("Expected to read 4 numbers",name);
x = fargs->farg[0];
y = fargs->farg[1];
z = fargs->farg[2];
r = fargs->farg[3];
bound_min_x = MIN(bound_min_x,x-r);
bound_max_x = MAX(bound_max_x,x+r);
bound_min_y = MIN(bound_min_y,y-r);
bound_max_y = MAX(bound_max_y,y+r);
bound_min_z = MIN(bound_min_z,z-r);
bound_max_z = MAX(bound_max_z,z+r);
#if defined(RADFILTER)
{
double area= 4.*PI*r*r;
cum_area += area;
return(area);
}
#endif
}
static void disk_extents(r,cx,cy,cz,nx,ny,nz,name)
double r,cx,cy,cz,nx,ny,nz;
char *name;
{
double extent;
/* Normalize Normal */
double length=sqrt(nx*nx+ny*ny+nz*nz);
if (length != 0.){
nx /= length;
ny /= length;
nz /= length;
}
else error("Zero Vector",name);
extent = r*sqrt(1.-nx*nx);
bound_min_x = MIN(bound_min_x,cx-extent);
bound_max_x = MAX(bound_max_x,cx+extent);
extent = r*sqrt(1.-ny*ny);
bound_min_y = MIN(bound_min_y,cy-extent);
bound_max_y = MAX(bound_max_y,cy+extent);
extent = r*sqrt(1.-nz*nz);
bound_min_z = MIN(bound_min_z,cz-extent);
bound_max_z = MAX(bound_max_z,cz+extent);
}
#if defined(RADFILTER)
double
#endif
cylinder_bound(fargs,name)
char *name;
FUNARGS *fargs;
{
double height,area;
double hvector_x=fargs->farg[3]-fargs->farg[0],
hvector_y=fargs->farg[4]-fargs->farg[1],
hvector_z=fargs->farg[5]-fargs->farg[2];
if (fargs->nfargs != 7)
error("Expected to read 7 numbers",name);
disk_extents(fargs->farg[6],
fargs->farg[0],fargs->farg[1],fargs->farg[2],
hvector_x,hvector_y,hvector_z,name);
disk_extents(fargs->farg[6],
fargs->farg[3],fargs->farg[4],fargs->farg[5],
hvector_x,hvector_y,hvector_z,name);
height = sqrt(hvector_x*hvector_x+hvector_y*hvector_y
+hvector_z*hvector_z);
#if defined(RADFILTER)
{
float area= 2.*PI*fargs->farg[6]*height;
cum_area += area;
return(area);
}
#endif
}
#if defined(RADFILTER)
double
#endif
cone_bound(fargs,name)
char *name;
FUNARGS *fargs;
{
double hvector_x=fargs->farg[3]-fargs->farg[0],
hvector_y=fargs->farg[4]-fargs->farg[1],
hvector_z=fargs->farg[5]-fargs->farg[2];
double slant_height;
double delta_r=fabs(fargs->farg[6]-fargs->farg[7]);
if (fargs->nfargs != 8)
error("Expected to read 8 numbers",name);
disk_extents(fargs->farg[6],
fargs->farg[0],fargs->farg[1],fargs->farg[2],
hvector_x,hvector_y,hvector_z,name);
disk_extents(fargs->farg[7],
fargs->farg[3],fargs->farg[4],fargs->farg[5],
hvector_x,hvector_y,hvector_z,name);
slant_height = sqrt(hvector_x*hvector_x+hvector_y*hvector_y
+hvector_z*hvector_z + delta_r*delta_r);
#if defined(RADFILTER)
{
float area= PI*(fargs->farg[6]+fargs->farg[7])*slant_height;
cum_area += area;
return(area);
}
#endif
}
#if defined(RADFILTER)
double
#endif
ring_bound(fargs,name)
char *name;
FUNARGS *fargs;
{
double outer_radius,inner_radius;
if (fargs->nfargs != 8)
error("Expected to read 8 numbers",name);
outer_radius = (fargs->farg[7]>fargs->farg[6])
?fargs->farg[7]:fargs->farg[6];
inner_radius = (fargs->farg[7]>fargs->farg[6])
?fargs->farg[6]:fargs->farg[7];
disk_extents(outer_radius,
fargs->farg[0],fargs->farg[1],fargs->farg[2],
fargs->farg[3],fargs->farg[4],fargs->farg[5],name);
#if defined(RADFILTER)
{
float area=PI*(outer_radius*outer_radius
- inner_radius*inner_radius);
cum_area += area;
return(area);
}
#endif
}
#if defined(RADFILTER)
double
#endif
no_bound(fargs,name)
char *name;
FUNARGS *fargs;
{
#if defined(RADFILTER)
return (0.) ;
#endif
}
#if defined(RADFILTER)
double
#else
int
#endif
(*specific_object_bound[MAXPRIMITIVES])()={
polygon_bound,
sphere_bound,
sphere_bound,
cylinder_bound,
cylinder_bound,
cone_bound,
cone_bound,
ring_bound,
no_bound,
no_bound
};
fgetline(s, n, fp)
char *s;
int n;
FILE *fp;
{
register char *cp = s;
register int c = EOF;
while (--n > 0 && (c = getc(fp)) != EOF) {
if (c == '\n' && (cp == s || cp[-1] != '\\'))
break;
*cp++ = c;
}
*cp = '\0';
}
int readobj(input)
char *input;
{
FILE *infp;
char buf[MAXSTR];
register int c;
if (input == NULL) {
infp = stdin;
input = "standard input";
#ifndef __MSDOS__
} else if (input[0] == '!') {
if ((infp = popen(input+1, "r")) == NULL) {
error("cannot execute",input);
}
#endif
} else if ((infp = fopen(input, "r")) == NULL) {
return(0);
}
while ((c = getc(infp)) != EOF) {
if (isspace(c))
continue;
if (c == '#') { /* comment */
fgets(buf, sizeof(buf), infp);
} else if (c == '!') { /* command */
ungetc(c, infp);
fgetline(buf, sizeof(buf), infp);
readobj(buf);
} else { /* object */
ungetc(c, infp);
getobject(input, infp);
}
}
#ifndef __MSDOS__
if (input[0] == '!')
pclose(infp);
else
#endif
fclose(infp);
return(1);
}
/* Primary Type */
#define ALIAS -1
#define UNKNOWN 0
#define GEOMETRY 1
#define MATERIAL 2
#define TEXTURE 3
#define PATTERN 4
#define MIXTURE 5
int getindex(table,size,s)
char *table[];
int size;
char *s;
{
if (table==NULL) return(-1);
for(;size>0;) if (!strcmp(table[--size],s)) return(size);
return(-1);
}
char *surface_table[MAXPRIMITIVES]={
"polygon","sphere","bubble","cylinder","tube","cone","cup",
"ring","source","instance"
};
char *material_table[MAXMATERIALS]={
"light","illum","glow","spotlight","plastic","mirror",
"metal","trans","dielectric","interface",
"glass","plasfunc","metfunc","plasdata","metdata"
};
char *texture_table[MAXTEXTURES]={
"texfunc","texdata"
};
char *pattern_table[MAXPATTERNS]={
"colorfunc", "brightfunc", "colordata",
"brightdata", "colorpict", "colortext",
"brighttext"
};
char *mixture_table[MAXMIXTURES]={
"mixfunc", "mixdata", "mixtext"
};
char *savqstr(s)
char *s;
{
char *cp;
if ((cp = (char *)malloc(strlen(s)+1)) == NULL)
error("Cannot allocate memory for",s);
strcpy(cp,s);
return(cp);
}
MTable modifier_table;
int nmodifiers=0;
OBJ obj[MaxObjects];
int nobjects=0;
#define modifier(s) getindex(modifier_table.mnames,nmodifiers,s)
#define otype(s) getindex(surface_table,MAXPRIMITIVES,s)
#define mtype(s) getindex(material_table,MAXMATERIALS,s)
#define ttype(s) getindex(texture_table,MAXTEXTURES,s)
#define ptype(s) getindex(pattern_table,MAXPATTERNS,s)
#define xtype(s) getindex(mixture_table,MAXMIXTURES,s)
getobject(name, fp) /* read the next object */
char *name;
FILE *fp;
{
char sbuf[MAXSTR];
short omod, otyp=UNKNOWN, otindex;
char *onam;
FUNARGS fargs;
fscanf(fp, "%s", sbuf); /* Get Modifier */
if(!strcmp(sbuf,"void")) omod = -1;
else if((omod=modifier(sbuf))== -1)
error("Undefined Modeifier",sbuf);
fscanf(fp, "%s", sbuf); /* Get Object Type */
if (!strcmp(sbuf, "alias")) otyp = ALIAS;
else if ((otindex=otype(sbuf))!= -1){ /* GEOMETRY */
otyp = GEOMETRY;
}
else if ((otindex=mtype(sbuf))!= -1){ /* MATERIAL */
otyp = MATERIAL;
}
else if ((otindex=ttype(sbuf))!= -1){ /* Textures */
otyp = TEXTURE;
}
else if ((otindex=ptype(sbuf))!= -1){ /* Patterns */
otyp = PATTERN;
}
else if ((otindex=xtype(sbuf))!= -1){ /* Mixtures */
otyp = MIXTURE;
}
else error("Unknown material/surface",sbuf);
fscanf(fp, "%s", sbuf); /* Get identifier */
onam = savqstr(sbuf);
/* Get Arguments */
if(otyp == ALIAS){
short oldmod;
fscanf(fp, "%s", sbuf);
otyp = MATERIAL;
if ((oldmod = modifier(sbuf))== -1)
error("Bad alias reference",sbuf);
if (nmodifiers < MAXMODIFIERS){
modifier_table.mnames[nmodifiers]=onam;
modifier_table.omod[nmodifiers] = omod;
modifier_table.otyp[nmodifiers]
= modifier_table.otyp[oldmod];
modifier_table.margs[nmodifiers]
= modifier_table.margs[oldmod];
(nmodifiers)++;
}
else error("Many Modifiers",onam);
return;
}
if (readfargs(&fargs,fp)== -1)
error("Cannot read object arguments.","");
if (otyp == GEOMETRY){
if (nobjects < MaxObjects){
obj[nobjects].onam = onam;
obj[nobjects].omod = omod;
obj[nobjects].otyp = otindex;
obj[nobjects].oargs = fargs;
#if defined(RADFILTER)
obj[nobjects].area=
#endif
specific_object_bound[otindex](&fargs,onam);
nobjects++;
}
else error("Many Objects",onam);
}
else if (otyp == MATERIAL){
if (nmodifiers < MAXMODIFIERS){
modifier_table.omod[nmodifiers] = omod;
modifier_table.otyp[nmodifiers] = otindex;
modifier_table.mnames[nmodifiers]=onam;
modifier_table.margs[nmodifiers]=fargs;
nmodifiers++;
}
else error("Many Modifiers",onam);
}
else if (otyp == TEXTURE
||
otyp == PATTERN
||
otyp == MIXTURE){
if (omod != -1){
warn("Cannot really support texture. So ignores",
onam);
if (nmodifiers < MAXMODIFIERS){
modifier_table.mnames[nmodifiers]=onam;
modifier_table.omod[nmodifiers] = omod;
modifier_table.otyp[nmodifiers]
= modifier_table.otyp[omod];
modifier_table.margs[nmodifiers]
= modifier_table.margs[omod];
(nmodifiers)++;
}
else error("Many Modifiers",onam);
}
else error("Does not support this Modifier.",onam);
}
}
#undef ALIAS
#undef UNKNOWN
#undef GEOMETRY
#undef MATERIAL
int readfargs(fa,fp)
FUNARGS *fa;
FILE *fp;
{
char sbuf[MAXSTR];
int n;
register int i;
if (fscanf(fp, "%d", &n) != 1 || n < 0)
return(-1);
if (fa->nsargs = n) {
fa->sarg = (char **)malloc(n*sizeof(char *));
if (fa->sarg == NULL)
goto memerr;
for (i = 0; i < fa->nsargs; i++) {
if (fscanf(fp, "%s", sbuf) != 1)
return(-1);
fa->sarg[i] = savqstr(sbuf);
}
} else
fa->sarg = NULL;
if (fscanf(fp, "%d", &n) != 1 || n < 0)
return(-1);
if (fa->niargs = n) {
fa->iarg = (long *)malloc(n*sizeof(long));
if (fa->iarg == NULL)
goto memerr;
for (i = 0; i < fa->niargs; i++)
if (fscanf(fp, "%ld", &fa->iarg[i]) != 1)
return(-1);
} else
fa->iarg = NULL;
if (fscanf(fp, "%d", &n) != 1 || n < 0)return(-1);
if (fa->nfargs = n) {
fa->farg = (double *)malloc(n*sizeof(double));
if (fa->farg == NULL)
goto memerr;
for (i = 0; i < n; i++)
if (fscanf(fp, "%lf", &fa->farg[i]) != 1)
return(-1);
} else
fa->farg = NULL;
return(0);
memerr:
error("out of memory in readfargs","");
}