Back to index

radiance  4R0+20100331
parser.h
Go to the documentation of this file.
00001 /* RCSid: $Id: parser.h,v 1.37 2003/11/15 17:54:06 schorsch Exp $ */
00002 /*
00003  * Header file for MGF interpreter
00004  */
00005 #ifndef _MGF_PARSER_H_
00006 #define _MGF_PARSER_H_
00007 #ifdef __cplusplus
00008 extern "C" {
00009 #endif
00010 
00011 
00012 #ifndef MG_VMAJOR
00013 
00014 /* must include stdio.h and stdlib.h before us */
00015 
00016 #define MG_VMAJOR    2             /* major version number */
00017 #define MG_VMINOR    0             /* minor version number */
00018 
00019                      /* Entities (list is only appended, never modified) */
00020 #define MG_E_COMMENT 0             /* #          */
00021 #define MG_E_COLOR   1             /* c          */
00022 #define MG_E_CCT     2             /* cct        */
00023 #define MG_E_CONE    3             /* cone              */
00024 #define MG_E_CMIX    4             /* cmix              */
00025 #define MG_E_CSPEC   5             /* cspec      */
00026 #define MG_E_CXY     6             /* cxy        */
00027 #define MG_E_CYL     7             /* cyl        */
00028 #define MG_E_ED             8             /* ed         */
00029 #define MG_E_FACE    9             /* f          */
00030 #define MG_E_INCLUDE 10            /* i          */
00031 #define MG_E_IES     11            /* ies        */
00032 #define MG_E_IR             12            /* ir         */
00033 #define MG_E_MATERIAL       13            /* m          */
00034 #define MG_E_NORMAL  14            /* n          */
00035 #define MG_E_OBJECT  15            /* o          */
00036 #define MG_E_POINT   16            /* p          */
00037 #define MG_E_PRISM   17            /* prism      */
00038 #define MG_E_RD             18            /* rd         */
00039 #define MG_E_RING    19            /* ring              */
00040 #define MG_E_RS             20            /* rs         */
00041 #define MG_E_SIDES   21            /* sides      */
00042 #define MG_E_SPH     22            /* sph        */
00043 #define MG_E_TD             23            /* td         */
00044 #define MG_E_TORUS   24            /* torus      */
00045 #define MG_E_TS             25            /* ts         */
00046 #define MG_E_VERTEX  26            /* v          */
00047 #define MG_E_XF             27            /* xf         */
00048                      /* end of Version 1 entities */
00049 #define MG_E_FACEH   28            /* fh         */
00050                      /* end of Version 2 entities */
00051 
00052 #define MG_NENTITIES 29            /* total # entities */
00053 
00054 #define MG_NELIST    {28,29}              /* entity count for version 1 and up */
00055 
00056 #define MG_NAMELIST  {"#","c","cct","cone","cmix","cspec","cxy","cyl","ed",\
00057                      "f","i","ies","ir","m","n","o","p","prism","rd",\
00058                      "ring","rs","sides","sph","td","torus","ts","v","xf",\
00059                      "fh"}
00060 
00061 #define MG_MAXELEN   6
00062 
00063 extern char   mg_ename[MG_NENTITIES][MG_MAXELEN];
00064 
00065                      /* Handler routines for each entity and unknown ones */
00066 extern int    (*mg_ehand[MG_NENTITIES])(int argc, char **argv);
00067 extern int    (*mg_uhand)(int argc, char **argv);
00068 extern int    mg_defuhand(int, char **);
00069 
00070 extern unsigned      mg_nunknown;         /* count of unknown entities */
00071 
00072                      /* Error codes */
00073 #define MG_OK        0             /* normal return value */
00074 #define MG_EUNK             1             /* unknown entity */
00075 #define MG_EARGC     2             /* wrong number of arguments */
00076 #define MG_ETYPE     3             /* argument type error */
00077 #define MG_EILL             4             /* illegal argument value */
00078 #define MG_EUNDEF    5             /* undefined reference */
00079 #define MG_ENOFILE   6             /* cannot open input file */
00080 #define MG_EINCL     7             /* error in included file */
00081 #define MG_EMEM             8             /* out of memory */
00082 #define MG_ESEEK     9             /* file seek error */
00083 #define MG_EBADMAT   10            /* bad material specification */
00084 #define MG_ELINE     11            /* input line too long */
00085 #define MG_ECNTXT    12            /* unmatched context close */
00086 
00087 #define MG_NERRS     13
00088 
00089 extern char   *mg_err[MG_NERRS];   /* list of error messages */
00090 
00091 /*
00092  * The general process for running the parser is to fill in the mg_ehand
00093  * array with handlers for each entity you know how to handle.
00094  * Then, call mg_init to fill in the rest.  This function will report
00095  * an error and quit if you try to support an inconsistent set of entities.
00096  * For each file you want to parse, call mg_load with the file name.
00097  * To read from standard input, use NULL as the file name.
00098  * For additional control over error reporting and file management,
00099  * use mg_open, mg_read, mg_parse and mg_close instead of mg_load.
00100  * To pass an entity of your own construction to the parser, use
00101  * the mg_handle function rather than the mg_ehand routines directly.
00102  * (The first argument to mg_handle is the entity #, or -1.)
00103  * To free any data structures and clear the parser, use mg_clear.
00104  * If there is an error, mg_load, mg_open, mg_parse, mg_handle and
00105  * mg_fgoto will return an error from the list above.  In addition,
00106  * mg_load will report the error to stderr.  The mg_read routine
00107  * returns 0 when the end of file has been reached.
00108  */
00109 
00110 #define MG_MAXLINE   4096          /* maximum input line length */
00111 #define MG_MAXARGC   (MG_MAXLINE/4)       /* maximum argument count */
00112 
00113 typedef struct mg_fctxt {
00114        char   fname[96];                  /* file name */
00115        FILE   *fp;                        /* stream pointer */
00116        int    fid;                        /* unique file context id */
00117        char   inpline[MG_MAXLINE];        /* input line */
00118        int    lineno;                            /* line number */
00119        struct mg_fctxt      *prev;               /* previous context */
00120 } MG_FCTXT;
00121 
00122 typedef struct {
00123        int    fid;                        /* file this position is for */
00124        int    lineno;                            /* line number in file */
00125        long   offset;                            /* offset from beginning */
00126 } MG_FPOS;
00127 
00128 extern MG_FCTXT      *mg_file;            /* current file context */
00129 
00130 extern void   mg_init(void);              /* fill in mg_ehand array */
00131 extern int    mg_load(char *);     /* parse a file */
00132 extern int    mg_open(MG_FCTXT *, char *);       /* open new input file */
00133 extern int    mg_read(void);              /* read next line */
00134 extern int    mg_parse(void);             /* parse current line */
00135 extern void   mg_fgetpos(MG_FPOS *);      /* get position on input file */
00136 extern int    mg_fgoto(MG_FPOS *); /* go to position on input file */
00137 extern void   mg_close(void);             /* close input file */
00138 extern void   mg_clear(void);             /* clear parser */
00139 extern int    mg_handle(int, int, char **);      /* handle an entity */
00140 
00141 #ifndef MG_NQCD
00142 #define MG_NQCD             5             /* default number of divisions */
00143 #endif
00144 
00145 extern int    mg_nqcdivs;          /* divisions per quarter circle */
00146 
00147 /*
00148  * The following library routines are included for your convenience:
00149  */
00150 
00151 extern int mg_entity(char *);             /* get entity number from its name */
00152 extern int isint(char *);          /* non-zero if integer format */
00153 extern int isintd(char *, char *); /* same with delimiter set */
00154 extern int isflt(char *);          /* non-zero if floating point format */
00155 extern int isfltd(char *, char *); /* same with delimiter set */
00156 extern int isname(char *);         /* non-zero if legal identifier name */
00157 extern int badarg(int, char **, char *);/* check argument format */
00158 extern int e_include(int, char **);       /* expand include entity */
00159 extern int e_pipe(int, char **);   /* expand piped command */
00160 extern int e_sph(int, char **);           /* expand sphere as other entities */
00161 extern int e_torus(int, char **);  /* expand torus as other entities */
00162 extern int e_cyl(int, char **);           /* expand cylinder as other entities */
00163 extern int e_ring(int, char **);   /* expand ring as other entities */
00164 extern int e_cone(int, char **);   /* expand cone as other entities */
00165 extern int e_prism(int, char **);  /* expand prism as other entities */
00166 extern int e_faceh(int, char **);  /* expand face w/ holes as face */
00167 
00168 /************************************************************************
00169  *     Definitions for 3-d vector manipulation functions
00170  */
00171 
00172 #ifdef  SMLFLT
00173 #define  RREAL              float
00174 #define  FTINY              (1e-3)
00175 #else
00176 #define  RREAL              double
00177 #define  FTINY              (1e-6)
00178 #endif
00179 #define  FHUGE              (1e10)
00180 
00181 typedef RREAL  FVECT[3];
00182 
00183 #define  VCOPY(v1,v2)       ((v1)[0]=(v2)[0],(v1)[1]=(v2)[1],(v1)[2]=(v2)[2])
00184 #define  DOT(v1,v2)  ((v1)[0]*(v2)[0]+(v1)[1]*(v2)[1]+(v1)[2]*(v2)[2])
00185 #define  VSUM(vr,v1,v2,f)   ((vr)[0]=(v1)[0]+(f)*(v2)[0], \
00186                             (vr)[1]=(v1)[1]+(f)*(v2)[1], \
00187                             (vr)[2]=(v1)[2]+(f)*(v2)[2])
00188 
00189 #define is0vect(v)   (DOT(v,v) <= FTINY*FTINY)
00190 
00191 #define round0(x)    if (x <= FTINY && x >= -FTINY) x = 0
00192 
00193 extern double normalize(FVECT);    /* normalize a vector */
00194 extern void   fcross(FVECT,FVECT,FVECT);/* cross product of two vectors */
00195 
00196 /************************************************************************
00197  *     Definitions for context handling routines
00198  *     (materials, colors, vectors)
00199  */
00200 
00201 #define C_CMINWL     380           /* minimum wavelength */
00202 #define C_CMAXWL     780           /* maximum wavelength */
00203 #define C_CNSS              41            /* number of spectral samples */
00204 #define C_CWLI              ((C_CMAXWL-C_CMINWL)/(C_CNSS-1))
00205 #define C_CMAXV             10000         /* nominal maximum sample value */
00206 #define C_CLPWM             (683./C_CMAXV)       /* peak lumens/watt multiplier */
00207 
00208 #define C_CSSPEC     01            /* flag if spectrum is set */
00209 #define C_CDSPEC     02            /* flag if defined w/ spectrum */
00210 #define C_CSXY              04            /* flag if xy is set */
00211 #define C_CDXY              010           /* flag if defined w/ xy */
00212 #define C_CSEFF             020           /* flag if efficacy set */
00213 
00214 typedef struct {
00215        int    clock;        /* incremented each change */
00216        char   *client_data; /* pointer to private client-owned data */
00217        short  flags;        /* what's been set */
00218        short  ssamp[C_CNSS];       /* spectral samples, min wl to max */
00219        long   ssum;         /* straight sum of spectral values */
00220        float  cx, cy;              /* xy chromaticity value */
00221        float  eff;          /* efficacy (lumens/watt) */
00222 } C_COLOR;
00223 
00224 #define C_DEFCOLOR   { 1, NULL, C_CDXY|C_CSXY|C_CSSPEC|C_CSEFF,\
00225                      {C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,\
00226                      C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,\
00227                      C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,\
00228                      C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,\
00229                      C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,\
00230                      C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,\
00231                      C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV,C_CMAXV},\
00232                      (long)C_CNSS*C_CMAXV, 1./3., 1./3., 178.006 }
00233 
00234 #define c_cval(c,l)  ((double)(c)->ssamp[((l)-C_MINWL)/C_CWLI] / (c)->ssum)
00235 
00236 #define C_1SIDEDTHICK       0.005         /* assumed thickness of 1-sided mat. */
00237 
00238 typedef struct {
00239        int    clock;        /* incremented each change -- resettable */
00240        char   *client_data; /* pointer to private client-owned data */
00241        int    sided;        /* 1 if surface is 1-sided, 0 for 2-sided */
00242        float  nr, ni;              /* index of refraction, real and imaginary */
00243        float  rd;           /* diffuse reflectance */
00244        C_COLOR       rd_c;         /* diffuse reflectance color */
00245        float  td;           /* diffuse transmittance */
00246        C_COLOR       td_c;         /* diffuse transmittance color */
00247        float  ed;           /* diffuse emittance */
00248        C_COLOR       ed_c;         /* diffuse emittance color */
00249        float  rs;           /* specular reflectance */
00250        C_COLOR       rs_c;         /* specular reflectance color */
00251        float  rs_a;         /* specular reflectance roughness */
00252        float  ts;           /* specular transmittance */
00253        C_COLOR       ts_c;         /* specular transmittance color */
00254        float  ts_a;         /* specular transmittance roughness */
00255 } C_MATERIAL;        /* material context */
00256 
00257 typedef struct {
00258        int    clock;        /* incremented each change -- resettable */
00259        char   *client_data; /* pointer to private client-owned data */
00260        FVECT  p, n;         /* point and normal */
00261 } C_VERTEX;          /* vertex context */
00262 
00263 #define C_DEFMATERIAL       {1,NULL,0,1.,0.,0.,C_DEFCOLOR,0.,C_DEFCOLOR,0.,\
00264                             C_DEFCOLOR,0.,C_DEFCOLOR,0.,0.,C_DEFCOLOR,0.}
00265 #define C_DEFVERTEX  {1,NULL,{0.,0.,0.},{0.,0.,0.}}
00266 
00267 extern C_COLOR              *c_ccolor;    /* the current color */
00268 extern char          *c_ccname;    /* current color name */
00269 extern C_MATERIAL    *c_cmaterial; /* the current material */
00270 extern char          *c_cmname;    /* current material name */
00271 extern C_VERTEX             *c_cvertex;   /* the current vertex */
00272 extern char          *c_cvname;    /* current vertex name */
00273 
00274 extern int    c_hcolor(int, char **);            /* handle color entity */
00275 extern int    c_hmaterial(int, char **);  /* handle material entity */
00276 extern int    c_hvertex(int, char **);    /* handle vertex entity */
00277 extern void   c_clearall(void);           /* clear context tables */
00278 extern C_MATERIAL    *c_getmaterial(char *);     /* get a named material */
00279 extern C_VERTEX      *c_getvert(char *);         /* get a named vertex */
00280 extern C_COLOR       *c_getcolor(char *);        /* get a named color */
00281 extern void   c_ccvt(C_COLOR *, int);            /* fix color representation */
00282 extern int    c_isgrey(C_COLOR *);        /* check if color is grey */
00283 
00284 /*************************************************************************
00285  *     Definitions for hierarchical object name handler
00286  */
00287 
00288 extern int    obj_nnames;          /* depth of name hierarchy */
00289 extern char   **obj_name;          /* names in hierarchy */
00290 
00291 extern int    obj_handler(int, char **);  /* handle an object entity */
00292 extern void   obj_clear(void);            /* clear object stack */
00293 
00294 /**************************************************************************
00295  *     Definitions for hierarchical transformation handler
00296  */
00297 
00298 typedef RREAL  MAT4[4][4];
00299 
00300 #define  copymat4(m4a,m4b)  (void)memcpy((char *)m4a,(char *)m4b,sizeof(MAT4))
00301 
00302 #define  MAT4IDENT          { {1.,0.,0.,0.}, {0.,1.,0.,0.}, \
00303                             {0.,0.,1.,0.}, {0.,0.,0.,1.} }
00304 
00305 extern MAT4  m4ident;
00306 
00307 #define  setident4(m4)             copymat4(m4, m4ident)
00308 
00309                             /* regular transformation */
00310 typedef struct {
00311        MAT4   xfm;                        /* transform matrix */
00312        RREAL  sca;                        /* scalefactor */
00313 }  XF;
00314 
00315 #define identxf(xp)         (void)(setident4((xp)->xfm),(xp)->sca=1.0)
00316 
00317 #define XF_MAXDIM    8             /* maximum array dimensions */
00318 
00319 struct xf_array {
00320        MG_FPOS       spos;                /* starting position on input */
00321        int    ndim;                /* number of array dimensions */
00322        struct {
00323               short  i, n;         /* current count and maximum */
00324               char   arg[8];              /* string argument value */
00325        } aarg[XF_MAXDIM];
00326 };
00327 
00328 typedef struct xf_spec {
00329        long   xid;                 /* unique transform id */
00330        short  xac;                 /* context argument count */
00331        short  rev;                 /* boolean true if vertices reversed */
00332        XF     xf;                  /* cumulative transformation */
00333        struct xf_array      *xarr;        /* transformation array pointer */
00334        struct xf_spec       *prev;        /* previous transformation context */
00335 } XF_SPEC;                  /* followed by argument buffer */
00336 
00337 extern XF_SPEC       *xf_context;                /* current transform context */
00338 extern char   **xf_argend;                /* last transform argument */
00339 
00340 #define xf_ac(xf)    ((xf)==NULL ? 0 : (xf)->xac)
00341 #define xf_av(xf)    (xf_argend - (xf)->xac)
00342 
00343 #define xf_argc             xf_ac(xf_context)
00344 #define xf_argv             xf_av(xf_context)
00345 
00346 /*
00347  * The transformation handler should do most of the work that needs
00348  * doing.  Just pass it any xf entities, then use the associated
00349  * functions to transform and translate points, transform vectors
00350  * (without translation), rotate vectors (without scaling) and scale
00351  * values appropriately.
00352  *
00353  * The routines xf_xfmpoint, xf_xfmvect and xf_rotvect take two
00354  * 3-D vectors (which may be identical), transforms the second and
00355  * puts the result into the first.
00356  */
00357 
00358 
00359 extern int    xf_handler(int, char **);   /* handle xf entity */
00360 extern void   xf_xfmpoint(FVECT, FVECT);  /* transform point */
00361 extern void   xf_xfmvect(FVECT, FVECT);   /* transform vector */
00362 extern void   xf_rotvect(FVECT, FVECT);   /* rotate vector */
00363 extern double xf_scale(double);           /* scale a value */
00364 extern void   xf_clear(void);                    /* clear xf stack */
00365 
00366 /* The following are support routines you probably won't call directly */
00367 
00368 XF_SPEC              *new_xf(int, char **);             /* allocate new transform */
00369 void          free_xf(XF_SPEC *);         /* free a transform */
00370 int           xf_aname(struct xf_array *);       /* name this instance */
00371 long          comp_xfid(MAT4);            /* compute unique ID */
00372 extern void   multmat4(MAT4, MAT4, MAT4); /* m4a = m4b X m4c */
00373 extern void   multv3(FVECT, FVECT, MAT4); /* v3a = v3b X m4 (vectors) */
00374 extern void   multp3(FVECT, FVECT, MAT4); /* p3a = p3b X m4 (points) */
00375 extern int    xf(XF *, int, char **);            /* interpret transform spec. */
00376 
00377        /* cvrgb.c */
00378 extern void mgf2rgb(C_COLOR *cin, double intensity, float cout[3]);
00379 
00380 
00381 /************************************************************************
00382  *     Miscellaneous definitions
00383  */
00384 
00385 #ifndef  PI
00386 #ifdef M_PI
00387 #define        PI           ((double)M_PI)
00388 #else
00389 #define        PI           3.14159265358979323846
00390 #endif
00391 #endif
00392 
00393 #ifndef MEM_PTR
00394 #define MEM_PTR             void *
00395 #endif
00396 
00397 #endif /*MG_VMAJOR*/
00398 
00399 
00400 #ifdef __cplusplus
00401 }
00402 #endif
00403 #endif /* _MGF_PARSER_H_ */
00404