| 5 | 
  | 
 *      G. Ward | 
| 6 | 
  | 
 */ | 
| 7 | 
  | 
 | 
| 8 | 
+ | 
#ifndef _BSDFREP_H_ | 
| 9 | 
+ | 
#define _BSDFREP_H_ | 
| 10 | 
+ | 
 | 
| 11 | 
  | 
#include "bsdf.h" | 
| 12 | 
  | 
 | 
| 13 | 
< | 
#define DEBUG           1 | 
| 13 | 
> | 
#ifdef __cplusplus | 
| 14 | 
> | 
extern "C" { | 
| 15 | 
> | 
#endif | 
| 16 | 
  | 
 | 
| 17 | 
  | 
#ifndef GRIDRES | 
| 18 | 
< | 
#define GRIDRES         200             /* grid resolution per side */ | 
| 18 | 
> | 
#define GRIDRES         (1<<8)          /* grid resolution per side */ | 
| 19 | 
  | 
#endif | 
| 20 | 
  | 
                                        /* convert to/from coded radians */ | 
| 21 | 
  | 
#define ANG2R(r)        (int)((r)*((1<<16)/M_PI)) | 
| 22 | 
  | 
#define R2ANG(c)        (((c)+.5)*(M_PI/(1<<16))) | 
| 23 | 
  | 
 | 
| 24 | 
< | 
typedef struct { | 
| 25 | 
< | 
        float           vsum;           /* DSF sum */ | 
| 26 | 
< | 
        unsigned short  nval;           /* number of values in sum */ | 
| 27 | 
< | 
        unsigned short  crad;           /* radius (coded angle) */ | 
| 24 | 
> | 
                                        /* moderated cosine factor */ | 
| 25 | 
> | 
#define COSF(z)         (fabs(z)*0.98 + 0.02) | 
| 26 | 
> | 
 | 
| 27 | 
> | 
typedef union { | 
| 28 | 
> | 
        struct { | 
| 29 | 
> | 
                float           v;              /* DSF sum */ | 
| 30 | 
> | 
                unsigned int    n;              /* number of values in sum */ | 
| 31 | 
> | 
        }       sum;                    /* sum for averaging */ | 
| 32 | 
> | 
        float   val[2];                 /* comparison values */ | 
| 33 | 
  | 
} GRIDVAL;                      /* grid value */ | 
| 34 | 
  | 
 | 
| 35 | 
  | 
typedef struct { | 
| 67 | 
  | 
#define INP_QUAD3       4               /* 180-270 degree quadrant */ | 
| 68 | 
  | 
#define INP_QUAD4       8               /* 270-360 degree quadrant */ | 
| 69 | 
  | 
 | 
| 70 | 
+ | 
                                /* name and manufacturer if known */ | 
| 71 | 
+ | 
extern char             bsdf_name[]; | 
| 72 | 
+ | 
extern char             bsdf_manuf[]; | 
| 73 | 
+ | 
                                /* active grid resolution */ | 
| 74 | 
+ | 
extern int              grid_res; | 
| 75 | 
+ | 
                                /* coverage/symmetry using INP_QUAD? flags */ | 
| 76 | 
  | 
extern int              inp_coverage; | 
| 77 | 
  | 
 | 
| 78 | 
  | 
                                /* all incident angles in-plane so far? */ | 
| 82 | 
  | 
extern int              input_orient; | 
| 83 | 
  | 
extern int              output_orient; | 
| 84 | 
  | 
 | 
| 85 | 
+ | 
                                /* log BSDF histogram */ | 
| 86 | 
+ | 
#define HISTLEN         256 | 
| 87 | 
+ | 
#define BSDF2BIG        (1./M_PI) | 
| 88 | 
+ | 
#define BSDF2SML        1e-8 | 
| 89 | 
+ | 
#define HISTLNR         17.2759509              /* log(BSDF2BIG/BSDF2SML) */ | 
| 90 | 
+ | 
extern unsigned long    bsdf_hist[HISTLEN]; | 
| 91 | 
+ | 
#define histndx(v)      (int)(log((v)*(1./BSDF2SML))*(HISTLEN/HISTLNR)) | 
| 92 | 
+ | 
#define histval(i)      (exp(((i)+.5)*(HISTLNR/HISTLEN))*BSDF2SML) | 
| 93 | 
+ | 
 | 
| 94 | 
+ | 
                                /* BSDF value for boundary regions */ | 
| 95 | 
+ | 
extern double           bsdf_min; | 
| 96 | 
+ | 
extern double           bsdf_spec_peak; | 
| 97 | 
+ | 
extern double           bsdf_spec_rad; | 
| 98 | 
+ | 
 | 
| 99 | 
  | 
                                /* processed incident DSF measurements */ | 
| 100 | 
  | 
extern RBFNODE          *dsf_list; | 
| 101 | 
  | 
 | 
| 102 | 
  | 
                                /* RBF-linking matrices (edges) */ | 
| 103 | 
  | 
extern MIGRATION        *mig_list; | 
| 104 | 
  | 
 | 
| 105 | 
< | 
                                /* migration edges drawn in raster fashion */ | 
| 106 | 
< | 
extern MIGRATION        *mig_grid[GRIDRES][GRIDRES]; | 
| 107 | 
< | 
 | 
| 78 | 
< | 
#define mtx_nrows(m)    ((m)->rbfv[0]->nrbf) | 
| 79 | 
< | 
#define mtx_ncols(m)    ((m)->rbfv[1]->nrbf) | 
| 80 | 
< | 
#define mtx_ndx(m,i,j)  ((i)*mtx_ncols(m) + (j)) | 
| 105 | 
> | 
#define mtx_nrows(m)    (m)->rbfv[0]->nrbf | 
| 106 | 
> | 
#define mtx_ncols(m)    (m)->rbfv[1]->nrbf | 
| 107 | 
> | 
#define mtx_coef(m,i,j) (m)->mtx[(i)*mtx_ncols(m) + (j)] | 
| 108 | 
  | 
#define is_src(rbf,m)   ((rbf) == (m)->rbfv[0]) | 
| 109 | 
  | 
#define is_dest(rbf,m)  ((rbf) == (m)->rbfv[1]) | 
| 110 | 
  | 
#define nextedge(rbf,m) (m)->enxt[is_dest(rbf,m)] | 
| 112 | 
  | 
 | 
| 113 | 
  | 
#define round(v)        (int)((v) + .5 - ((v) < -.5)) | 
| 114 | 
  | 
 | 
| 115 | 
< | 
#define BSDFREP_FMT     "binary_RBF_BSDF_mesh" | 
| 115 | 
> | 
#define BSDFREP_FMT     "BSDF_RBFmesh" | 
| 116 | 
  | 
 | 
| 117 | 
  | 
                                /* global argv[0] */ | 
| 118 | 
  | 
extern char             *progname; | 
| 119 | 
  | 
 | 
| 120 | 
  | 
                                /* get theta value in degrees [0,180) range */ | 
| 121 | 
< | 
#define get_theta180(v) (180./M_PI)*acos((v)[2]) | 
| 121 | 
> | 
#define get_theta180(v) ((180./M_PI)*Acos((v)[2])) | 
| 122 | 
  | 
                                /* get phi value in degrees, [0,360) range */ | 
| 123 | 
< | 
#define get_phi360(v)   ((180./M_PI)*atan2((v)[1],(v)[0]) + 180.) | 
| 123 | 
> | 
#define get_phi360(v)   ((180./M_PI)*atan2((v)[1],(v)[0]) + 360.*((v)[1]<0)) | 
| 124 | 
  | 
 | 
| 125 | 
  | 
                                /* our loaded grid for this incident angle */ | 
| 126 | 
  | 
extern double           theta_in_deg, phi_in_deg; | 
| 141 | 
  | 
/* Reverse symmetry for an RBF distribution */ | 
| 142 | 
  | 
extern void             rev_rbf_symmetry(RBFNODE *rbf, int sym); | 
| 143 | 
  | 
 | 
| 144 | 
+ | 
/* Rotate RBF to correspond to given incident vector */ | 
| 145 | 
+ | 
extern void             rotate_rbf(RBFNODE *rbf, const FVECT invec); | 
| 146 | 
+ | 
 | 
| 147 | 
  | 
/* Compute volume associated with Gaussian lobe */ | 
| 148 | 
  | 
extern double           rbf_volume(const RBFVAL *rbfp); | 
| 149 | 
  | 
 | 
| 153 | 
  | 
/* Compute grid position from normalized input/output vector */ | 
| 154 | 
  | 
extern void             pos_from_vec(int pos[2], const FVECT vec); | 
| 155 | 
  | 
 | 
| 156 | 
< | 
/* Evaluate RBF for DSF at the given normalized outgoing direction */ | 
| 156 | 
> | 
/* Evaluate BSDF at the given normalized outgoing direction */ | 
| 157 | 
  | 
extern double           eval_rbfrep(const RBFNODE *rp, const FVECT outvec); | 
| 158 | 
  | 
 | 
| 159 | 
  | 
/* Insert a new directional scattering function in our global list */ | 
| 173 | 
  | 
/* Find vertices completing triangles on either side of the given edge */ | 
| 174 | 
  | 
extern int              get_triangles(RBFNODE *rbfv[2], const MIGRATION *mig); | 
| 175 | 
  | 
 | 
| 176 | 
+ | 
/* Clear our BSDF representation and free memory */ | 
| 177 | 
+ | 
extern void             clear_bsdf_rep(void); | 
| 178 | 
+ | 
 | 
| 179 | 
  | 
/* Write our BSDF mesh interpolant out to the given binary stream */ | 
| 180 | 
  | 
extern void             save_bsdf_rep(FILE *ofp); | 
| 181 | 
  | 
 | 
| 195 | 
  | 
/* Build our triangle mesh from recorded RBFs */ | 
| 196 | 
  | 
extern void             build_mesh(void); | 
| 197 | 
  | 
 | 
| 165 | 
– | 
/* Draw edge list into mig_grid array */ | 
| 166 | 
– | 
extern void             draw_edges(void); | 
| 167 | 
– | 
 | 
| 198 | 
  | 
/* Find edge(s) for interpolating the given vector, applying symmetry */ | 
| 199 | 
  | 
extern int              get_interp(MIGRATION *miga[3], FVECT invec); | 
| 200 | 
  | 
 | 
| 201 | 
+ | 
/* Return single-lobe specular RBF for the given incident direction */ | 
| 202 | 
+ | 
extern RBFNODE *        def_rbf_spec(const FVECT invec); | 
| 203 | 
+ | 
 | 
| 204 | 
+ | 
/* Advect and allocate new RBF along edge (internal call) */ | 
| 205 | 
+ | 
extern RBFNODE *        e_advect_rbf(const MIGRATION *mig, | 
| 206 | 
+ | 
                                        const FVECT invec, int lobe_lim); | 
| 207 | 
+ | 
 | 
| 208 | 
+ | 
/* Compute distance between two RBF lobes (internal call) */ | 
| 209 | 
+ | 
extern double           lobe_distance(RBFVAL *rbf1, RBFVAL *rbf2); | 
| 210 | 
+ | 
 | 
| 211 | 
+ | 
/* Compute mass transport plan (internal call) */ | 
| 212 | 
+ | 
extern void             plan_transport(MIGRATION *mig); | 
| 213 | 
+ | 
 | 
| 214 | 
  | 
/* Partially advect between recorded incident angles and allocate new RBF */ | 
| 215 | 
< | 
extern RBFNODE *        advect_rbf(const FVECT invec); | 
| 215 | 
> | 
extern RBFNODE *        advect_rbf(const FVECT invec, int lobe_lim); | 
| 216 | 
> | 
 | 
| 217 | 
> | 
#ifdef __cplusplus | 
| 218 | 
> | 
} | 
| 219 | 
> | 
#endif | 
| 220 | 
> | 
#endif  /* _BSDFREP_H_ */ |