home *** CD-ROM | disk | FTP | other *** search
/ 3D Color Clip Art / 3D_Color_Clip_Art.bin / 3d-progs / rad386 / parse.c < prev    next >
C/C++ Source or Header  |  1996-11-15  |  14KB  |  542 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <math.h>
  4. #include <ctype.h>
  5.  
  6. #include "preview.h"
  7. float bound_min_x,bound_min_y,bound_min_z=LARGE;
  8. float bound_max_x,bound_max_y,bound_max_z= -LARGE;
  9. #if defined(RADFILTER)
  10. float cum_area=0.;
  11. #endif
  12. #define MIN(a,b) (((a)>(b))?(b):(a))
  13. #define MAX(a,b) (((a)>(b))?(a):(b))
  14. #ifdef notdef
  15. #if defined(RADFILTER)
  16. double
  17. #else
  18. int
  19. #endif
  20.       polygon_bound(),
  21.       sphere_bound(),
  22.       cylinder_bound(),
  23.       cone_bound(),
  24.       ring_bound(),
  25.       no_bound();
  26. #endif
  27. #if defined(RADFILTER) 
  28. void project_point(n,x,y,z,px,py)
  29. int n;
  30. double x,y,z,*px,*py;
  31. {
  32.     switch(n){
  33.     case 0: *px = y; *py = z; break;
  34.     case 1: *px = z; *py = x; break;
  35.     case 2: *px = x; *py = y; break;
  36.     }
  37. }
  38. double trapez_area(n,f,nx,ny,nz)
  39. int n;
  40. double f[],nx,ny,nz;
  41. {
  42.     double area=0.,lastx,lasty,curx,cury;
  43.     int i,dominant_axis;
  44.     if (fabs(nx) >= fabs(ny) && fabs(nx) >= fabs(nz))
  45.         dominant_axis=0;
  46.     else if (fabs(ny) >= fabs(nx) && fabs(ny) >= fabs(nz))
  47.         dominant_axis=1;
  48.     else dominant_axis=2;
  49.     project_point(dominant_axis,
  50.         f[(n-1)*3],f[(n-1)*3+1],f[(n-1)*3+2],&lastx,&lasty);
  51.     for(i=0;i<n;i++,lastx=curx,lasty=cury){
  52.         project_point(dominant_axis,
  53.             f[i*3],f[i*3+1],f[i*3+2],&curx,&cury);
  54.         area += (curx-lastx)*(cury+lasty);
  55.     }
  56.     area /= ((dominant_axis==0)?nx:((dominant_axis==1)?ny:nz));
  57.     return(0.5*fabs(area));
  58. }
  59. double
  60. #endif
  61. polygon_bound(fargs,name)
  62. char *name;
  63. FUNARGS *fargs;
  64. {
  65.     int i,k,nv=fargs->nfargs/3;;
  66.     if (fargs->nfargs < 9)
  67.         error("wanted an > 3 for verticies",name);
  68.         for (i = k = 0; i < nv; i++,k+=3) {
  69.         double x,y,z;
  70.         x = fargs->farg[k],
  71.         y = fargs->farg[k+1]; 
  72.         z = fargs->farg[k+2];
  73.                 bound_min_x = MIN(bound_min_x,x);
  74.         bound_max_x = MAX(bound_max_x,x);
  75.                 bound_min_y = MIN(bound_min_y,y);
  76.         bound_max_y = MAX(bound_max_y,y);
  77.                 bound_min_z = MIN(bound_min_z,z);
  78.         bound_max_z = MAX(bound_max_z,z);
  79.         }
  80. #if defined(RADFILTER)
  81.     {
  82.     double area=0.,length;
  83.     int i,j;
  84.     double nx,ny,nz;
  85.     nx = ny = nz = 0.;
  86.         for(i=0,j=1;i<nv;i++,j++){
  87.                 if (j==nv)j=0;
  88.                 nx += (fargs->farg[i*3+1]-fargs->farg[j*3+1])*
  89.             (fargs->farg[i*3+2]+fargs->farg[j*3+2]);
  90.                 ny += (fargs->farg[i*3+2]-fargs->farg[j*3+2])*
  91.             (fargs->farg[i*3]+fargs->farg[j*3]);
  92.                 nz += (fargs->farg[i*3]-fargs->farg[j*3])*
  93.             (fargs->farg[i*3+1]+fargs->farg[j*3+1]);
  94.         }
  95.         length = sqrt(nx*nx+ny*ny+nz*nz);
  96.     if (length != 0.){
  97.         nx/=length; ny/=length; nz/=length;
  98.     }
  99.     else error("Zero Vector Normal",name);
  100.     area = trapez_area(nv,fargs->farg,nx,ny,nz);
  101.     cum_area += area;
  102.     return(area);
  103.     }
  104. #endif
  105. }
  106. #if defined(RADFILTER)
  107. double
  108. #endif 
  109. sphere_bound(fargs,name)
  110. char *name;
  111. FUNARGS *fargs;
  112. {
  113.     double x,y,z,r;
  114.         if (fargs->nfargs != 4)
  115.                 error("Expected to read 4 numbers",name);
  116.     x = fargs->farg[0];
  117.     y = fargs->farg[1];
  118.     z = fargs->farg[2];
  119.     r = fargs->farg[3];
  120.         bound_min_x = MIN(bound_min_x,x-r);
  121.         bound_max_x = MAX(bound_max_x,x+r);
  122.         bound_min_y = MIN(bound_min_y,y-r);
  123.         bound_max_y = MAX(bound_max_y,y+r);
  124.         bound_min_z = MIN(bound_min_z,z-r);
  125.         bound_max_z = MAX(bound_max_z,z+r);
  126. #if defined(RADFILTER)
  127.     {
  128.     double area= 4.*PI*r*r;
  129.     cum_area += area;
  130.     return(area);
  131.     }
  132. #endif
  133. }
  134. static void disk_extents(r,cx,cy,cz,nx,ny,nz,name)
  135. double r,cx,cy,cz,nx,ny,nz;
  136. char *name;
  137. {
  138.     double extent;
  139.     /* Normalize Normal */
  140.     double length=sqrt(nx*nx+ny*ny+nz*nz);
  141.     if (length != 0.){
  142.         nx /= length;
  143.         ny /= length;
  144.         nz /= length;
  145.     }
  146.     else error("Zero Vector",name);
  147.     extent = r*sqrt(1.-nx*nx);
  148.         bound_min_x = MIN(bound_min_x,cx-extent);
  149.     bound_max_x = MAX(bound_max_x,cx+extent);
  150.     extent = r*sqrt(1.-ny*ny);
  151.         bound_min_y = MIN(bound_min_y,cy-extent); 
  152.     bound_max_y = MAX(bound_max_y,cy+extent);
  153.     extent = r*sqrt(1.-nz*nz);
  154.         bound_min_z = MIN(bound_min_z,cz-extent); 
  155.     bound_max_z = MAX(bound_max_z,cz+extent);
  156. }
  157. #if defined(RADFILTER)
  158. double
  159. #endif
  160. cylinder_bound(fargs,name)
  161. char *name;
  162. FUNARGS *fargs;
  163. {
  164.     double height,area;
  165.     double hvector_x=fargs->farg[3]-fargs->farg[0],
  166.         hvector_y=fargs->farg[4]-fargs->farg[1],
  167.         hvector_z=fargs->farg[5]-fargs->farg[2];
  168.         if (fargs->nfargs != 7)
  169.                 error("Expected to read 7 numbers",name);
  170.     disk_extents(fargs->farg[6],
  171.         fargs->farg[0],fargs->farg[1],fargs->farg[2],
  172.         hvector_x,hvector_y,hvector_z,name);
  173.     disk_extents(fargs->farg[6],
  174.         fargs->farg[3],fargs->farg[4],fargs->farg[5],
  175.         hvector_x,hvector_y,hvector_z,name);
  176.     height = sqrt(hvector_x*hvector_x+hvector_y*hvector_y
  177.             +hvector_z*hvector_z);
  178. #if defined(RADFILTER)
  179.     {
  180.     float area= 2.*PI*fargs->farg[6]*height;
  181.     cum_area += area;
  182.     return(area);
  183.     }
  184. #endif
  185. }
  186. #if defined(RADFILTER) 
  187. double
  188. #endif
  189. cone_bound(fargs,name)
  190. char *name;
  191. FUNARGS *fargs;
  192. {
  193.     double hvector_x=fargs->farg[3]-fargs->farg[0],
  194.         hvector_y=fargs->farg[4]-fargs->farg[1],
  195.         hvector_z=fargs->farg[5]-fargs->farg[2];
  196.     double slant_height;
  197.     double delta_r=fabs(fargs->farg[6]-fargs->farg[7]);
  198.         if (fargs->nfargs != 8)
  199.                 error("Expected to read 8 numbers",name);
  200.     disk_extents(fargs->farg[6],
  201.         fargs->farg[0],fargs->farg[1],fargs->farg[2],
  202.         hvector_x,hvector_y,hvector_z,name);
  203.     disk_extents(fargs->farg[7],
  204.         fargs->farg[3],fargs->farg[4],fargs->farg[5],
  205.         hvector_x,hvector_y,hvector_z,name);
  206.     slant_height = sqrt(hvector_x*hvector_x+hvector_y*hvector_y
  207.             +hvector_z*hvector_z + delta_r*delta_r);
  208. #if defined(RADFILTER)
  209.     {
  210.     float area= PI*(fargs->farg[6]+fargs->farg[7])*slant_height;
  211.     cum_area += area;
  212.     return(area);
  213.     }
  214. #endif
  215. }
  216. #if defined(RADFILTER) 
  217. double
  218. #endif
  219. ring_bound(fargs,name)
  220. char *name;
  221. FUNARGS *fargs;
  222. {
  223.     double outer_radius,inner_radius;
  224.         if (fargs->nfargs != 8)
  225.                 error("Expected to read 8 numbers",name);
  226.     outer_radius = (fargs->farg[7]>fargs->farg[6])
  227.             ?fargs->farg[7]:fargs->farg[6];
  228.     inner_radius = (fargs->farg[7]>fargs->farg[6])
  229.             ?fargs->farg[6]:fargs->farg[7];
  230.     disk_extents(outer_radius,
  231.         fargs->farg[0],fargs->farg[1],fargs->farg[2],
  232.         fargs->farg[3],fargs->farg[4],fargs->farg[5],name);
  233. #if defined(RADFILTER)
  234.     {
  235.     float area=PI*(outer_radius*outer_radius
  236.             - inner_radius*inner_radius);
  237.     cum_area += area;
  238.     return(area);
  239.     }
  240. #endif
  241. }
  242. #if defined(RADFILTER) 
  243. double
  244. #endif
  245. no_bound(fargs,name)
  246. char *name;
  247. FUNARGS *fargs;
  248. {
  249. #if defined(RADFILTER) 
  250.     return (0.) ;
  251. #endif
  252. }
  253. #if defined(RADFILTER) 
  254. double
  255. #else
  256. int 
  257. #endif
  258. (*specific_object_bound[MAXPRIMITIVES])()={
  259.     polygon_bound,
  260.     sphere_bound,
  261.     sphere_bound,
  262.     cylinder_bound,
  263.     cylinder_bound,
  264.     cone_bound,
  265.     cone_bound,
  266.     ring_bound,
  267.     no_bound,
  268.     no_bound
  269. };
  270.  
  271. fgetline(s, n, fp)
  272. char  *s;
  273. int  n;
  274. FILE  *fp;
  275. {
  276.         register char  *cp = s;
  277.         register int  c = EOF;
  278.  
  279.         while (--n > 0 && (c = getc(fp)) != EOF) {
  280.                 if (c == '\n' && (cp == s || cp[-1] != '\\'))
  281.                         break;
  282.                 *cp++ = c;
  283.         }
  284.         *cp = '\0';
  285. }
  286.  
  287. int readobj(input)
  288. char  *input;
  289. {
  290.     FILE  *infp;
  291.     char  buf[MAXSTR];
  292.     register int  c;
  293.  
  294.     if (input == NULL) {
  295.         infp = stdin;
  296.         input = "standard input";
  297. #ifndef __MSDOS__
  298.     } else if (input[0] == '!') {
  299.         if ((infp = popen(input+1, "r")) == NULL) {
  300.             error("cannot execute",input);
  301.         }
  302. #endif
  303.     } else if ((infp = fopen(input, "r")) == NULL) {
  304.         return(0);
  305.     }
  306.     while ((c = getc(infp)) != EOF) {
  307.         if (isspace(c))
  308.             continue;
  309.         if (c == '#') {                /* comment */
  310.             fgets(buf, sizeof(buf), infp);
  311.         } else if (c == '!') {            /* command */
  312.             ungetc(c, infp);
  313.             fgetline(buf, sizeof(buf), infp);
  314.             readobj(buf);
  315.         } else {                /* object */
  316.             ungetc(c, infp);
  317.             getobject(input, infp);
  318.         }
  319.     }
  320. #ifndef __MSDOS__
  321.     if (input[0] == '!')
  322.         pclose(infp);
  323.     else
  324. #endif
  325.         fclose(infp);
  326.     return(1);
  327. }
  328.  
  329. /* Primary Type */
  330. #define ALIAS    -1
  331. #define UNKNOWN  0
  332. #define GEOMETRY 1
  333. #define MATERIAL 2
  334. #define TEXTURE  3
  335. #define PATTERN  4
  336. #define MIXTURE  5
  337.  
  338. int getindex(table,size,s)
  339. char *table[];
  340. int size;
  341. char *s;
  342. {
  343.     if (table==NULL) return(-1);
  344.     for(;size>0;) if (!strcmp(table[--size],s)) return(size);
  345.     return(-1);
  346. }
  347. char *surface_table[MAXPRIMITIVES]={
  348.     "polygon","sphere","bubble","cylinder","tube","cone","cup",
  349.     "ring","source","instance"
  350. };
  351. char *material_table[MAXMATERIALS]={
  352.     "light","illum","glow","spotlight","plastic","mirror",
  353.     "metal","trans","dielectric","interface",
  354.     "glass","plasfunc","metfunc","plasdata","metdata"
  355. };
  356. char *texture_table[MAXTEXTURES]={
  357.     "texfunc","texdata"
  358. };
  359. char *pattern_table[MAXPATTERNS]={
  360.     "colorfunc", "brightfunc", "colordata",
  361.     "brightdata", "colorpict", "colortext",
  362.     "brighttext"
  363. };
  364. char *mixture_table[MAXMIXTURES]={
  365.     "mixfunc", "mixdata", "mixtext"
  366. };
  367. char *savqstr(s)
  368. char *s;
  369. {
  370.     char *cp;
  371.     if ((cp = (char *)malloc(strlen(s)+1)) == NULL)
  372.         error("Cannot allocate memory for",s);
  373.     strcpy(cp,s);
  374.     return(cp);
  375. }
  376.  
  377. MTable modifier_table;
  378. int nmodifiers=0;
  379. OBJ obj[MaxObjects];
  380. int nobjects=0;
  381.  
  382. #define modifier(s) getindex(modifier_table.mnames,nmodifiers,s)
  383. #define otype(s) getindex(surface_table,MAXPRIMITIVES,s)
  384. #define mtype(s) getindex(material_table,MAXMATERIALS,s)
  385. #define ttype(s) getindex(texture_table,MAXTEXTURES,s)
  386. #define ptype(s) getindex(pattern_table,MAXPATTERNS,s)
  387. #define xtype(s) getindex(mixture_table,MAXMIXTURES,s)
  388.  
  389. getobject(name, fp)        /* read the next object */
  390. char  *name;
  391. FILE  *fp;
  392. {
  393.     char  sbuf[MAXSTR];
  394.     short omod, otyp=UNKNOWN, otindex;
  395.     char *onam;
  396.     FUNARGS fargs;
  397.  
  398.     fscanf(fp, "%s", sbuf);     /* Get Modifier */
  399.     if(!strcmp(sbuf,"void")) omod = -1;
  400.     else if((omod=modifier(sbuf))== -1)
  401.         error("Undefined Modeifier",sbuf);
  402.  
  403.     fscanf(fp, "%s", sbuf);     /* Get Object Type */
  404.     if (!strcmp(sbuf, "alias")) otyp = ALIAS;
  405.     else if ((otindex=otype(sbuf))!= -1){ /* GEOMETRY */
  406.         otyp = GEOMETRY;
  407.     }
  408.     else if ((otindex=mtype(sbuf))!= -1){ /* MATERIAL */
  409.         otyp = MATERIAL;
  410.     }
  411.     else if ((otindex=ttype(sbuf))!= -1){ /* Textures */
  412.         otyp = TEXTURE;
  413.     }
  414.     else if ((otindex=ptype(sbuf))!= -1){ /* Patterns */
  415.         otyp = PATTERN;
  416.     }
  417.     else if ((otindex=xtype(sbuf))!= -1){ /* Mixtures */
  418.         otyp = MIXTURE;
  419.     }
  420.     else error("Unknown material/surface",sbuf);
  421.  
  422.     fscanf(fp, "%s", sbuf);        /* Get identifier */
  423.     onam = savqstr(sbuf);
  424.                     /* Get Arguments */
  425.     if(otyp == ALIAS){
  426.         short oldmod;
  427.         fscanf(fp, "%s", sbuf);
  428.         otyp = MATERIAL;
  429.         if ((oldmod = modifier(sbuf))== -1)
  430.             error("Bad alias reference",sbuf);
  431.         if (nmodifiers < MAXMODIFIERS){
  432.             modifier_table.mnames[nmodifiers]=onam;
  433.             modifier_table.omod[nmodifiers] = omod;
  434.             modifier_table.otyp[nmodifiers]
  435.                 = modifier_table.otyp[oldmod];
  436.             modifier_table.margs[nmodifiers]
  437.                 = modifier_table.margs[oldmod];
  438.             (nmodifiers)++;
  439.         }
  440.         else error("Many Modifiers",onam);
  441.         return;
  442.     }
  443.     if (readfargs(&fargs,fp)== -1)
  444.         error("Cannot read object arguments.","");
  445.     if (otyp == GEOMETRY){
  446.         if (nobjects < MaxObjects){
  447.             obj[nobjects].onam = onam;
  448.             obj[nobjects].omod = omod;
  449.             obj[nobjects].otyp = otindex;
  450.             obj[nobjects].oargs = fargs;
  451. #if defined(RADFILTER)
  452.             obj[nobjects].area=
  453. #endif
  454.             specific_object_bound[otindex](&fargs,onam);
  455.             nobjects++;
  456.         }
  457.         else error("Many Objects",onam);
  458.     }
  459.     else if (otyp == MATERIAL){
  460.         if (nmodifiers < MAXMODIFIERS){
  461.         modifier_table.omod[nmodifiers] = omod;
  462.         modifier_table.otyp[nmodifiers] = otindex;
  463.         modifier_table.mnames[nmodifiers]=onam;
  464.         modifier_table.margs[nmodifiers]=fargs;
  465.         nmodifiers++;
  466.         }
  467.         else error("Many Modifiers",onam);
  468.     }
  469.     else if (otyp == TEXTURE
  470.          ||
  471.          otyp == PATTERN
  472.          ||
  473.          otyp == MIXTURE){
  474.         if (omod != -1){
  475.           warn("Cannot really support texture. So ignores",
  476.             onam);
  477.           if (nmodifiers < MAXMODIFIERS){
  478.             modifier_table.mnames[nmodifiers]=onam;
  479.             modifier_table.omod[nmodifiers] = omod;
  480.             modifier_table.otyp[nmodifiers]
  481.                 = modifier_table.otyp[omod];
  482.             modifier_table.margs[nmodifiers]
  483.                 = modifier_table.margs[omod];
  484.             (nmodifiers)++;
  485.           }
  486.           else error("Many Modifiers",onam);
  487.         }
  488.         else error("Does not support this Modifier.",onam);
  489.     }
  490. }
  491. #undef ALIAS   
  492. #undef UNKNOWN
  493. #undef GEOMETRY
  494. #undef MATERIAL
  495.  
  496. int readfargs(fa,fp)
  497. FUNARGS *fa;
  498. FILE *fp;
  499. {
  500.         char  sbuf[MAXSTR];
  501.         int  n;
  502.         register int  i;
  503.  
  504.         if (fscanf(fp, "%d", &n) != 1 || n < 0)
  505.                 return(-1);
  506.         if (fa->nsargs = n) {
  507.                 fa->sarg = (char **)malloc(n*sizeof(char *));
  508.                if (fa->sarg == NULL)
  509.                         goto memerr;
  510.                 for (i = 0; i < fa->nsargs; i++) {
  511.                         if (fscanf(fp, "%s", sbuf) != 1)
  512.                                 return(-1);
  513.                         fa->sarg[i] = savqstr(sbuf);
  514.                 }
  515.         } else
  516.                 fa->sarg = NULL;
  517.         if (fscanf(fp, "%d", &n) != 1 || n < 0)
  518.                 return(-1);
  519.         if (fa->niargs = n) {
  520.                 fa->iarg = (long *)malloc(n*sizeof(long));
  521.                if (fa->iarg == NULL)
  522.                         goto memerr;
  523.                 for (i = 0; i < fa->niargs; i++)
  524.                         if (fscanf(fp, "%ld", &fa->iarg[i]) != 1)
  525.                                 return(-1);
  526.         } else
  527.                 fa->iarg = NULL;
  528.     if (fscanf(fp, "%d", &n) != 1 || n < 0)return(-1);
  529.         if (fa->nfargs = n) {
  530.                 fa->farg = (double *)malloc(n*sizeof(double));
  531.                 if (fa->farg == NULL)
  532.                         goto memerr;
  533.                 for (i = 0; i < n; i++)
  534.                         if (fscanf(fp, "%lf", &fa->farg[i]) != 1)
  535.                                 return(-1);
  536.         } else
  537.                 fa->farg = NULL;
  538.         return(0);
  539. memerr:
  540.         error("out of memory in readfargs","");
  541. }
  542.