| 1 |
greg |
2.1 |
#ifndef lint
|
| 2 |
greg |
2.36 |
static const char RCSid[] = "$Id: mgf2rad.c,v 2.35 2024/01/17 00:43:45 greg Exp $";
|
| 3 |
greg |
2.1 |
#endif
|
| 4 |
|
|
/*
|
| 5 |
|
|
* Convert MGF (Materials and Geometry Format) to Radiance
|
| 6 |
|
|
*/
|
| 7 |
|
|
|
| 8 |
|
|
#include <stdio.h>
|
| 9 |
greg |
2.25 |
#include <stdlib.h>
|
| 10 |
greg |
2.1 |
#include <math.h>
|
| 11 |
|
|
#include <string.h>
|
| 12 |
schorsch |
2.28 |
|
| 13 |
|
|
#include "platform.h"
|
| 14 |
greg |
2.29 |
#include "mgf_parser.h"
|
| 15 |
greg |
2.1 |
#include "color.h"
|
| 16 |
|
|
#include "tmesh.h"
|
| 17 |
greg |
2.33 |
#include "lookup.h"
|
| 18 |
greg |
2.1 |
|
| 19 |
|
|
#define putv(v) printf("%18.12g %18.12g %18.12g\n",(v)[0],(v)[1],(v)[2])
|
| 20 |
|
|
|
| 21 |
greg |
2.9 |
#define invert (xf_context != NULL && xf_context->rev)
|
| 22 |
|
|
|
| 23 |
greg |
2.36 |
#define SGEN_DEF "spec*"
|
| 24 |
|
|
#define SGEN_RS "rs_spec*"
|
| 25 |
|
|
#define SGEN_TD "td_spec*"
|
| 26 |
|
|
#define SGEN_TS "ts_spec*"
|
| 27 |
|
|
|
| 28 |
|
|
char void_str[] = "void"; /* global VOIDID */
|
| 29 |
|
|
char sgen_str[16] = SGEN_DEF; /* generic specular */
|
| 30 |
|
|
|
| 31 |
greg |
2.2 |
double glowdist = FHUGE; /* glow test distance */
|
| 32 |
greg |
2.1 |
|
| 33 |
greg |
2.8 |
double emult = 1.; /* emitter multiplier */
|
| 34 |
greg |
2.1 |
|
| 35 |
gwlarson |
2.24 |
FILE *matfp; /* material output file */
|
| 36 |
greg |
2.11 |
|
| 37 |
greg |
2.35 |
int dospectra = 0; /* output spectral colors? */
|
| 38 |
|
|
|
| 39 |
schorsch |
2.28 |
|
| 40 |
greg |
2.30 |
extern int r_comment(int ac, char **av);
|
| 41 |
greg |
2.33 |
extern int r_color(int ac, char **av);
|
| 42 |
greg |
2.30 |
extern int r_cone(int ac, char **av);
|
| 43 |
|
|
extern int r_cyl(int ac, char **av);
|
| 44 |
|
|
extern int r_sph(int ac, char **av);
|
| 45 |
|
|
extern int r_ring(int ac, char **av);
|
| 46 |
|
|
extern int r_face(int ac, char **av);
|
| 47 |
|
|
extern int r_ies(int ac, char **av);
|
| 48 |
|
|
extern void putsided(char *mname);
|
| 49 |
|
|
extern char * material(void);
|
| 50 |
|
|
extern char * object(void);
|
| 51 |
|
|
extern char * addarg(char *op, char *arg);
|
| 52 |
|
|
extern void do_tri(char *mat, C_VERTEX *cv1, C_VERTEX *cv2, C_VERTEX *cv3, int iv);
|
| 53 |
greg |
2.33 |
extern void cvtcolor(COLOR radrgb, C_COLOR *ciec, double intensity);
|
| 54 |
greg |
2.36 |
extern int color_clash(int e1, int e2);
|
| 55 |
|
|
extern int isgrey(COLOR rgb);
|
| 56 |
|
|
extern void putrgbpat(char *pnm, COLOR rgb);
|
| 57 |
greg |
2.33 |
extern char * specolor(COLOR radrgb, C_COLOR *ciec, double intensity);
|
| 58 |
greg |
2.1 |
|
| 59 |
|
|
|
| 60 |
schorsch |
2.28 |
int
|
| 61 |
|
|
main(
|
| 62 |
|
|
int argc,
|
| 63 |
|
|
char *argv[]
|
| 64 |
|
|
)
|
| 65 |
greg |
2.1 |
{
|
| 66 |
greg |
2.20 |
int i;
|
| 67 |
gwlarson |
2.24 |
|
| 68 |
|
|
matfp = stdout;
|
| 69 |
greg |
2.19 |
/* print out parser version */
|
| 70 |
|
|
printf("## Translated from MGF Version %d.%d\n", MG_VMAJOR, MG_VMINOR);
|
| 71 |
greg |
2.1 |
/* initialize dispatch table */
|
| 72 |
greg |
2.16 |
mg_ehand[MG_E_COMMENT] = r_comment; /* we pass comments */
|
| 73 |
|
|
mg_ehand[MG_E_COLOR] = c_hcolor; /* they get color */
|
| 74 |
|
|
mg_ehand[MG_E_CONE] = r_cone; /* we do cones */
|
| 75 |
|
|
mg_ehand[MG_E_CMIX] = c_hcolor; /* they mix colors */
|
| 76 |
|
|
mg_ehand[MG_E_CXY] = c_hcolor; /* they get chromaticities */
|
| 77 |
greg |
2.33 |
mg_ehand[MG_E_CSPEC] = r_color; /* we get spectra */
|
| 78 |
|
|
mg_ehand[MG_E_CCT] = r_color; /* we get color temp's */
|
| 79 |
greg |
2.16 |
mg_ehand[MG_E_CYL] = r_cyl; /* we do cylinders */
|
| 80 |
|
|
mg_ehand[MG_E_ED] = c_hmaterial; /* they get emission */
|
| 81 |
|
|
mg_ehand[MG_E_FACE] = r_face; /* we do faces */
|
| 82 |
|
|
mg_ehand[MG_E_IES] = r_ies; /* we do IES files */
|
| 83 |
|
|
mg_ehand[MG_E_IR] = c_hmaterial; /* they get refractive index */
|
| 84 |
|
|
mg_ehand[MG_E_MATERIAL] = c_hmaterial; /* they get materials */
|
| 85 |
|
|
mg_ehand[MG_E_NORMAL] = c_hvertex; /* they get normals */
|
| 86 |
|
|
mg_ehand[MG_E_OBJECT] = obj_handler; /* they track object names */
|
| 87 |
|
|
mg_ehand[MG_E_POINT] = c_hvertex; /* they get points */
|
| 88 |
|
|
mg_ehand[MG_E_RD] = c_hmaterial; /* they get diffuse refl. */
|
| 89 |
|
|
mg_ehand[MG_E_RING] = r_ring; /* we do rings */
|
| 90 |
|
|
mg_ehand[MG_E_RS] = c_hmaterial; /* they get specular refl. */
|
| 91 |
|
|
mg_ehand[MG_E_SIDES] = c_hmaterial; /* they get # sides */
|
| 92 |
|
|
mg_ehand[MG_E_SPH] = r_sph; /* we do spheres */
|
| 93 |
|
|
mg_ehand[MG_E_TD] = c_hmaterial; /* they get diffuse trans. */
|
| 94 |
|
|
mg_ehand[MG_E_TS] = c_hmaterial; /* they get specular trans. */
|
| 95 |
|
|
mg_ehand[MG_E_VERTEX] = c_hvertex; /* they get vertices */
|
| 96 |
|
|
mg_ehand[MG_E_XF] = xf_handler; /* they track transforms */
|
| 97 |
greg |
2.1 |
mg_init(); /* initialize the parser */
|
| 98 |
greg |
2.16 |
/* get our options & print header */
|
| 99 |
greg |
2.1 |
printf("## %s", argv[0]);
|
| 100 |
|
|
for (i = 1; i < argc && argv[i][0] == '-'; i++) {
|
| 101 |
|
|
printf(" %s", argv[i]);
|
| 102 |
|
|
switch (argv[i][1]) {
|
| 103 |
|
|
case 'g': /* glow distance (meters) */
|
| 104 |
greg |
2.10 |
if (argv[i][2] || badarg(argc-i-1, argv+i+1, "f"))
|
| 105 |
greg |
2.1 |
goto userr;
|
| 106 |
|
|
glowdist = atof(argv[++i]);
|
| 107 |
|
|
printf(" %s", argv[i]);
|
| 108 |
|
|
break;
|
| 109 |
|
|
case 'e': /* emitter multiplier */
|
| 110 |
greg |
2.10 |
if (argv[i][2] || badarg(argc-i-1, argv+i+1, "f"))
|
| 111 |
greg |
2.1 |
goto userr;
|
| 112 |
|
|
emult = atof(argv[++i]);
|
| 113 |
|
|
printf(" %s", argv[i]);
|
| 114 |
|
|
break;
|
| 115 |
greg |
2.11 |
case 'm': /* materials file */
|
| 116 |
|
|
matfp = fopen(argv[++i], "a");
|
| 117 |
|
|
if (matfp == NULL) {
|
| 118 |
|
|
fprintf(stderr, "%s: cannot append\n", argv[i]);
|
| 119 |
|
|
exit(1);
|
| 120 |
|
|
}
|
| 121 |
|
|
printf(" %s", argv[i]);
|
| 122 |
|
|
break;
|
| 123 |
greg |
2.35 |
case 's': /* spectral color output? */
|
| 124 |
|
|
dospectra = !dospectra;
|
| 125 |
|
|
break;
|
| 126 |
greg |
2.1 |
default:
|
| 127 |
|
|
goto userr;
|
| 128 |
|
|
}
|
| 129 |
|
|
}
|
| 130 |
|
|
putchar('\n');
|
| 131 |
|
|
if (i == argc) { /* convert stdin */
|
| 132 |
greg |
2.20 |
if (mg_load(NULL) != MG_OK)
|
| 133 |
greg |
2.1 |
exit(1);
|
| 134 |
greg |
2.18 |
if (mg_nunknown)
|
| 135 |
|
|
printf("## %s: %u unknown entities\n",
|
| 136 |
|
|
argv[0], mg_nunknown);
|
| 137 |
greg |
2.1 |
} else /* convert each file */
|
| 138 |
|
|
for ( ; i < argc; i++) {
|
| 139 |
|
|
printf("## %s %s ##############################\n",
|
| 140 |
|
|
argv[0], argv[i]);
|
| 141 |
greg |
2.20 |
if (mg_load(argv[i]) != MG_OK)
|
| 142 |
greg |
2.1 |
exit(1);
|
| 143 |
greg |
2.18 |
if (mg_nunknown) {
|
| 144 |
|
|
printf("## %s %s: %u unknown entities\n",
|
| 145 |
|
|
argv[0], argv[i], mg_nunknown);
|
| 146 |
|
|
mg_nunknown = 0;
|
| 147 |
|
|
}
|
| 148 |
greg |
2.1 |
}
|
| 149 |
|
|
exit(0);
|
| 150 |
|
|
userr:
|
| 151 |
greg |
2.35 |
fprintf(stderr, "Usage: %s [-s][-g dist][-e mult][-m matf] [file.mgf] ..\n",
|
| 152 |
greg |
2.1 |
argv[0]);
|
| 153 |
|
|
exit(1);
|
| 154 |
|
|
}
|
| 155 |
|
|
|
| 156 |
|
|
|
| 157 |
|
|
int
|
| 158 |
schorsch |
2.28 |
r_comment( /* repeat a comment verbatim */
|
| 159 |
greg |
2.33 |
int ac,
|
| 160 |
|
|
char **av
|
| 161 |
schorsch |
2.28 |
)
|
| 162 |
greg |
2.1 |
{
|
| 163 |
greg |
2.7 |
putchar('#'); /* use Radiance comment character */
|
| 164 |
greg |
2.16 |
while (--ac) { /* pass through verbatim */
|
| 165 |
greg |
2.1 |
putchar(' ');
|
| 166 |
|
|
fputs(*++av, stdout);
|
| 167 |
|
|
}
|
| 168 |
|
|
putchar('\n');
|
| 169 |
|
|
return(MG_OK);
|
| 170 |
|
|
}
|
| 171 |
|
|
|
| 172 |
|
|
|
| 173 |
|
|
int
|
| 174 |
greg |
2.33 |
r_color( /* call color handler & remember name */
|
| 175 |
|
|
int ac,
|
| 176 |
|
|
char **av
|
| 177 |
|
|
)
|
| 178 |
|
|
{
|
| 179 |
|
|
int rval = c_hcolor(ac, av);
|
| 180 |
|
|
|
| 181 |
|
|
if (rval == MG_OK)
|
| 182 |
|
|
c_ccolor->client_data = c_ccname;
|
| 183 |
|
|
|
| 184 |
|
|
return(rval);
|
| 185 |
|
|
}
|
| 186 |
|
|
|
| 187 |
|
|
|
| 188 |
|
|
int
|
| 189 |
schorsch |
2.28 |
r_cone( /* put out a cone */
|
| 190 |
|
|
int ac,
|
| 191 |
|
|
char **av
|
| 192 |
|
|
)
|
| 193 |
greg |
2.1 |
{
|
| 194 |
|
|
static int ncones;
|
| 195 |
|
|
char *mat;
|
| 196 |
|
|
double r1, r2;
|
| 197 |
|
|
C_VERTEX *cv1, *cv2;
|
| 198 |
|
|
FVECT p1, p2;
|
| 199 |
|
|
int inv;
|
| 200 |
greg |
2.16 |
/* check argument count and type */
|
| 201 |
greg |
2.1 |
if (ac != 5)
|
| 202 |
|
|
return(MG_EARGC);
|
| 203 |
|
|
if (!isflt(av[2]) || !isflt(av[4]))
|
| 204 |
|
|
return(MG_ETYPE);
|
| 205 |
greg |
2.16 |
/* get the endpoint vertices */
|
| 206 |
greg |
2.1 |
if ((cv1 = c_getvert(av[1])) == NULL ||
|
| 207 |
|
|
(cv2 = c_getvert(av[3])) == NULL)
|
| 208 |
|
|
return(MG_EUNDEF);
|
| 209 |
greg |
2.16 |
xf_xfmpoint(p1, cv1->p); /* transform endpoints */
|
| 210 |
greg |
2.1 |
xf_xfmpoint(p2, cv2->p);
|
| 211 |
greg |
2.16 |
r1 = xf_scale(atof(av[2])); /* scale radii */
|
| 212 |
greg |
2.1 |
r2 = xf_scale(atof(av[4]));
|
| 213 |
greg |
2.16 |
inv = r1 < 0.; /* check for inverted cone */
|
| 214 |
|
|
if (r1 == 0.) { /* check for illegal radii */
|
| 215 |
greg |
2.1 |
if (r2 == 0.)
|
| 216 |
|
|
return(MG_EILL);
|
| 217 |
|
|
inv = r2 < 0.;
|
| 218 |
schorsch |
2.27 |
} else if (r2 != 0. && inv ^ (r2 < 0.))
|
| 219 |
greg |
2.1 |
return(MG_EILL);
|
| 220 |
|
|
if (inv) {
|
| 221 |
|
|
r1 = -r1;
|
| 222 |
|
|
r2 = -r2;
|
| 223 |
|
|
}
|
| 224 |
greg |
2.16 |
if ((mat = material()) == NULL) /* get material */
|
| 225 |
greg |
2.1 |
return(MG_EBADMAT);
|
| 226 |
greg |
2.16 |
/* spit the sucker out */
|
| 227 |
greg |
2.1 |
printf("\n%s %s %sc%d\n", mat, inv ? "cup" : "cone",
|
| 228 |
|
|
object(), ++ncones);
|
| 229 |
|
|
printf("0\n0\n8\n");
|
| 230 |
|
|
putv(p1);
|
| 231 |
|
|
putv(p2);
|
| 232 |
|
|
printf("%18.12g %18.12g\n", r1, r2);
|
| 233 |
|
|
return(MG_OK);
|
| 234 |
|
|
}
|
| 235 |
|
|
|
| 236 |
|
|
|
| 237 |
|
|
int
|
| 238 |
schorsch |
2.28 |
r_cyl( /* put out a cylinder */
|
| 239 |
|
|
int ac,
|
| 240 |
|
|
char **av
|
| 241 |
|
|
)
|
| 242 |
greg |
2.1 |
{
|
| 243 |
|
|
static int ncyls;
|
| 244 |
|
|
char *mat;
|
| 245 |
|
|
double rad;
|
| 246 |
|
|
C_VERTEX *cv1, *cv2;
|
| 247 |
|
|
FVECT p1, p2;
|
| 248 |
|
|
int inv;
|
| 249 |
greg |
2.16 |
/* check argument count and type */
|
| 250 |
greg |
2.1 |
if (ac != 4)
|
| 251 |
|
|
return(MG_EARGC);
|
| 252 |
|
|
if (!isflt(av[2]))
|
| 253 |
|
|
return(MG_ETYPE);
|
| 254 |
greg |
2.16 |
/* get the endpoint vertices */
|
| 255 |
greg |
2.1 |
if ((cv1 = c_getvert(av[1])) == NULL ||
|
| 256 |
|
|
(cv2 = c_getvert(av[3])) == NULL)
|
| 257 |
|
|
return(MG_EUNDEF);
|
| 258 |
greg |
2.16 |
xf_xfmpoint(p1, cv1->p); /* transform endpoints */
|
| 259 |
greg |
2.1 |
xf_xfmpoint(p2, cv2->p);
|
| 260 |
greg |
2.16 |
rad = xf_scale(atof(av[2])); /* scale radius */
|
| 261 |
|
|
if ((inv = rad < 0.)) /* check for inverted cylinder */
|
| 262 |
greg |
2.1 |
rad = -rad;
|
| 263 |
greg |
2.16 |
if ((mat = material()) == NULL) /* get material */
|
| 264 |
greg |
2.1 |
return(MG_EBADMAT);
|
| 265 |
greg |
2.16 |
/* spit out the primitive */
|
| 266 |
greg |
2.1 |
printf("\n%s %s %scy%d\n", mat, inv ? "tube" : "cylinder",
|
| 267 |
|
|
object(), ++ncyls);
|
| 268 |
|
|
printf("0\n0\n7\n");
|
| 269 |
|
|
putv(p1);
|
| 270 |
|
|
putv(p2);
|
| 271 |
|
|
printf("%18.12g\n", rad);
|
| 272 |
|
|
return(MG_OK);
|
| 273 |
|
|
}
|
| 274 |
|
|
|
| 275 |
|
|
|
| 276 |
|
|
int
|
| 277 |
schorsch |
2.28 |
r_sph( /* put out a sphere */
|
| 278 |
|
|
int ac,
|
| 279 |
|
|
char **av
|
| 280 |
|
|
)
|
| 281 |
greg |
2.1 |
{
|
| 282 |
|
|
static int nsphs;
|
| 283 |
|
|
char *mat;
|
| 284 |
|
|
double rad;
|
| 285 |
|
|
C_VERTEX *cv;
|
| 286 |
|
|
FVECT cent;
|
| 287 |
|
|
int inv;
|
| 288 |
greg |
2.16 |
/* check argument count and type */
|
| 289 |
greg |
2.1 |
if (ac != 3)
|
| 290 |
|
|
return(MG_EARGC);
|
| 291 |
|
|
if (!isflt(av[2]))
|
| 292 |
|
|
return(MG_ETYPE);
|
| 293 |
greg |
2.16 |
if ((cv = c_getvert(av[1])) == NULL) /* get center vertex */
|
| 294 |
greg |
2.1 |
return(MG_EUNDEF);
|
| 295 |
greg |
2.16 |
xf_xfmpoint(cent, cv->p); /* transform center */
|
| 296 |
|
|
rad = xf_scale(atof(av[2])); /* scale radius */
|
| 297 |
|
|
if ((inv = rad < 0.)) /* check for inversion */
|
| 298 |
greg |
2.1 |
rad = -rad;
|
| 299 |
greg |
2.16 |
if ((mat = material()) == NULL) /* get material */
|
| 300 |
greg |
2.1 |
return(MG_EBADMAT);
|
| 301 |
greg |
2.16 |
/* spit out primitive */
|
| 302 |
greg |
2.1 |
printf("\n%s %s %ss%d\n", mat, inv ? "bubble" : "sphere",
|
| 303 |
|
|
object(), ++nsphs);
|
| 304 |
|
|
printf("0\n0\n4 %18.12g %18.12g %18.12g %18.12g\n",
|
| 305 |
|
|
cent[0], cent[1], cent[2], rad);
|
| 306 |
|
|
return(MG_OK);
|
| 307 |
|
|
}
|
| 308 |
|
|
|
| 309 |
|
|
|
| 310 |
|
|
int
|
| 311 |
schorsch |
2.28 |
r_ring( /* put out a ring */
|
| 312 |
|
|
int ac,
|
| 313 |
|
|
char **av
|
| 314 |
|
|
)
|
| 315 |
greg |
2.1 |
{
|
| 316 |
|
|
static int nrings;
|
| 317 |
|
|
char *mat;
|
| 318 |
|
|
double r1, r2;
|
| 319 |
|
|
C_VERTEX *cv;
|
| 320 |
|
|
FVECT cent, norm;
|
| 321 |
greg |
2.16 |
/* check argument count and type */
|
| 322 |
greg |
2.1 |
if (ac != 4)
|
| 323 |
|
|
return(MG_EARGC);
|
| 324 |
|
|
if (!isflt(av[2]) || !isflt(av[3]))
|
| 325 |
|
|
return(MG_ETYPE);
|
| 326 |
greg |
2.16 |
if ((cv = c_getvert(av[1])) == NULL) /* get center vertex */
|
| 327 |
greg |
2.1 |
return(MG_EUNDEF);
|
| 328 |
greg |
2.16 |
if (is0vect(cv->n)) /* make sure we have normal */
|
| 329 |
greg |
2.1 |
return(MG_EILL);
|
| 330 |
greg |
2.16 |
xf_xfmpoint(cent, cv->p); /* transform center */
|
| 331 |
|
|
xf_rotvect(norm, cv->n); /* rotate normal */
|
| 332 |
|
|
r1 = xf_scale(atof(av[2])); /* scale radii */
|
| 333 |
greg |
2.1 |
r2 = xf_scale(atof(av[3]));
|
| 334 |
schorsch |
2.27 |
if ((r1 < 0.) | (r2 <= r1))
|
| 335 |
greg |
2.1 |
return(MG_EILL);
|
| 336 |
greg |
2.16 |
if ((mat = material()) == NULL) /* get material */
|
| 337 |
greg |
2.1 |
return(MG_EBADMAT);
|
| 338 |
greg |
2.16 |
/* spit out primitive */
|
| 339 |
greg |
2.1 |
printf("\n%s ring %sr%d\n", mat, object(), ++nrings);
|
| 340 |
|
|
printf("0\n0\n8\n");
|
| 341 |
|
|
putv(cent);
|
| 342 |
|
|
putv(norm);
|
| 343 |
|
|
printf("%18.12g %18.12g\n", r1, r2);
|
| 344 |
|
|
return(MG_OK);
|
| 345 |
|
|
}
|
| 346 |
|
|
|
| 347 |
|
|
|
| 348 |
|
|
int
|
| 349 |
schorsch |
2.28 |
r_face( /* convert a face */
|
| 350 |
|
|
int ac,
|
| 351 |
|
|
char **av
|
| 352 |
|
|
)
|
| 353 |
greg |
2.1 |
{
|
| 354 |
|
|
static int nfaces;
|
| 355 |
greg |
2.25 |
int myi = invert;
|
| 356 |
greg |
2.1 |
char *mat;
|
| 357 |
greg |
2.33 |
int i;
|
| 358 |
|
|
C_VERTEX *cv;
|
| 359 |
greg |
2.1 |
FVECT v;
|
| 360 |
schorsch |
2.28 |
|
| 361 |
greg |
2.16 |
/* check argument count and type */
|
| 362 |
greg |
2.1 |
if (ac < 4)
|
| 363 |
|
|
return(MG_EARGC);
|
| 364 |
greg |
2.16 |
if ((mat = material()) == NULL) /* get material */
|
| 365 |
greg |
2.1 |
return(MG_EBADMAT);
|
| 366 |
greg |
2.16 |
if (ac <= 5) { /* check for smoothing */
|
| 367 |
greg |
2.23 |
C_VERTEX *cva[5];
|
| 368 |
greg |
2.1 |
for (i = 1; i < ac; i++) {
|
| 369 |
greg |
2.23 |
if ((cva[i-1] = c_getvert(av[i])) == NULL)
|
| 370 |
greg |
2.1 |
return(MG_EUNDEF);
|
| 371 |
greg |
2.23 |
if (is0vect(cva[i-1]->n))
|
| 372 |
greg |
2.1 |
break;
|
| 373 |
|
|
}
|
| 374 |
greg |
2.25 |
if (i < ac)
|
| 375 |
|
|
i = ISFLAT;
|
| 376 |
|
|
else
|
| 377 |
greg |
2.23 |
i = flat_tri(cva[0]->p, cva[1]->p, cva[2]->p,
|
| 378 |
|
|
cva[0]->n, cva[1]->n, cva[2]->n);
|
| 379 |
greg |
2.25 |
if (i == DEGEN)
|
| 380 |
|
|
return(MG_OK); /* degenerate (error?) */
|
| 381 |
|
|
if (i == RVBENT) {
|
| 382 |
|
|
myi = !myi;
|
| 383 |
|
|
i = ISBENT;
|
| 384 |
|
|
} else if (i == RVFLAT) {
|
| 385 |
|
|
myi = !myi;
|
| 386 |
|
|
i = ISFLAT;
|
| 387 |
greg |
2.23 |
}
|
| 388 |
greg |
2.25 |
if (i == ISBENT) { /* smoothed triangles */
|
| 389 |
|
|
do_tri(mat, cva[0], cva[1], cva[2], myi);
|
| 390 |
greg |
2.1 |
if (ac == 5)
|
| 391 |
greg |
2.25 |
do_tri(mat, cva[2], cva[3], cva[0], myi);
|
| 392 |
greg |
2.1 |
return(MG_OK);
|
| 393 |
|
|
}
|
| 394 |
|
|
}
|
| 395 |
greg |
2.16 |
/* spit out unsmoothed primitive */
|
| 396 |
greg |
2.1 |
printf("\n%s polygon %sf%d\n", mat, object(), ++nfaces);
|
| 397 |
|
|
printf("0\n0\n%d\n", 3*(ac-1));
|
| 398 |
greg |
2.16 |
for (i = 1; i < ac; i++) { /* get, transform, print each vertex */
|
| 399 |
greg |
2.25 |
if ((cv = c_getvert(av[myi ? ac-i : i])) == NULL)
|
| 400 |
greg |
2.1 |
return(MG_EUNDEF);
|
| 401 |
|
|
xf_xfmpoint(v, cv->p);
|
| 402 |
|
|
putv(v);
|
| 403 |
|
|
}
|
| 404 |
|
|
return(MG_OK);
|
| 405 |
|
|
}
|
| 406 |
|
|
|
| 407 |
|
|
|
| 408 |
greg |
2.15 |
int
|
| 409 |
schorsch |
2.28 |
r_ies( /* convert an IES luminaire file */
|
| 410 |
|
|
int ac,
|
| 411 |
|
|
char **av
|
| 412 |
|
|
)
|
| 413 |
greg |
2.1 |
{
|
| 414 |
|
|
int xa0 = 2;
|
| 415 |
greg |
2.15 |
char combuf[128];
|
| 416 |
greg |
2.1 |
char fname[48];
|
| 417 |
|
|
char *oname;
|
| 418 |
greg |
2.33 |
char *op;
|
| 419 |
|
|
int i;
|
| 420 |
greg |
2.16 |
/* check argument count */
|
| 421 |
greg |
2.1 |
if (ac < 2)
|
| 422 |
|
|
return(MG_EARGC);
|
| 423 |
greg |
2.16 |
/* construct output file name */
|
| 424 |
greg |
2.22 |
if ((op = strrchr(av[1], '/')) != NULL)
|
| 425 |
|
|
op++;
|
| 426 |
|
|
else
|
| 427 |
greg |
2.1 |
op = av[1];
|
| 428 |
|
|
(void)strcpy(fname, op);
|
| 429 |
|
|
if ((op = strrchr(fname, '.')) == NULL)
|
| 430 |
|
|
op = fname + strlen(fname);
|
| 431 |
|
|
(void)strcpy(op, ".rad");
|
| 432 |
greg |
2.16 |
/* see if we need to run ies2rad */
|
| 433 |
greg |
2.17 |
if (access(fname, 0) == -1) {
|
| 434 |
greg |
2.16 |
(void)strcpy(combuf, "ies2rad");/* build ies2rad command */
|
| 435 |
|
|
op = combuf + 7; /* get -m option (first) */
|
| 436 |
|
|
if (ac-xa0 >= 2 && !strcmp(av[xa0], "-m")) {
|
| 437 |
|
|
if (!isflt(av[xa0+1]))
|
| 438 |
|
|
return(MG_ETYPE);
|
| 439 |
|
|
op = addarg(addarg(op, "-m"), av[xa0+1]);
|
| 440 |
|
|
xa0 += 2;
|
| 441 |
|
|
}
|
| 442 |
|
|
*op++ = ' '; /* build IES filename */
|
| 443 |
|
|
i = 0;
|
| 444 |
|
|
if (mg_file != NULL &&
|
| 445 |
|
|
(oname = strrchr(mg_file->fname,'/')) != NULL) {
|
| 446 |
|
|
i = oname - mg_file->fname + 1;
|
| 447 |
|
|
(void)strcpy(op, mg_file->fname);
|
| 448 |
|
|
}
|
| 449 |
|
|
(void)strcpy(op+i, av[1]);
|
| 450 |
|
|
if (access(op, 0) == -1) /* check for file existence */
|
| 451 |
|
|
return(MG_ENOFILE);
|
| 452 |
|
|
system(combuf); /* run ies2rad */
|
| 453 |
|
|
if (access(fname, 0) == -1) /* check success */
|
| 454 |
|
|
return(MG_EINCL);
|
| 455 |
|
|
}
|
| 456 |
|
|
printf("\n!xform"); /* put out xform command */
|
| 457 |
greg |
2.1 |
oname = object();
|
| 458 |
greg |
2.4 |
if (*oname) {
|
| 459 |
|
|
printf(" -n ");
|
| 460 |
|
|
for (op = oname; op[1]; op++) /* remove trailing separator */
|
| 461 |
|
|
putchar(*op);
|
| 462 |
|
|
}
|
| 463 |
greg |
2.1 |
for (i = xa0; i < ac; i++)
|
| 464 |
|
|
printf(" %s", av[i]);
|
| 465 |
|
|
if (ac > xa0 && xf_argc > 0)
|
| 466 |
|
|
printf(" -i 1");
|
| 467 |
|
|
for (i = 0; i < xf_argc; i++)
|
| 468 |
|
|
printf(" %s", xf_argv[i]);
|
| 469 |
|
|
printf(" %s\n", fname);
|
| 470 |
|
|
return(MG_OK);
|
| 471 |
|
|
}
|
| 472 |
|
|
|
| 473 |
|
|
|
| 474 |
schorsch |
2.28 |
void
|
| 475 |
|
|
do_tri( /* put out smoothed triangle */
|
| 476 |
|
|
char *mat,
|
| 477 |
|
|
C_VERTEX *cv1,
|
| 478 |
|
|
C_VERTEX *cv2,
|
| 479 |
|
|
C_VERTEX *cv3,
|
| 480 |
|
|
int iv
|
| 481 |
|
|
)
|
| 482 |
greg |
2.1 |
{
|
| 483 |
|
|
static int ntris;
|
| 484 |
|
|
BARYCCM bvecs;
|
| 485 |
schorsch |
2.26 |
RREAL bcoor[3][3];
|
| 486 |
greg |
2.23 |
C_VERTEX *cvt;
|
| 487 |
greg |
2.1 |
FVECT v1, v2, v3;
|
| 488 |
|
|
FVECT n1, n2, n3;
|
| 489 |
greg |
2.33 |
int i;
|
| 490 |
greg |
2.23 |
|
| 491 |
greg |
2.25 |
if (iv) { /* swap vertex order if inverted */
|
| 492 |
greg |
2.23 |
cvt = cv1;
|
| 493 |
|
|
cv1 = cv3;
|
| 494 |
|
|
cv3 = cvt;
|
| 495 |
greg |
2.9 |
}
|
| 496 |
greg |
2.1 |
xf_xfmpoint(v1, cv1->p);
|
| 497 |
|
|
xf_xfmpoint(v2, cv2->p);
|
| 498 |
|
|
xf_xfmpoint(v3, cv3->p);
|
| 499 |
greg |
2.16 |
/* compute barycentric coords. */
|
| 500 |
greg |
2.2 |
if (comp_baryc(&bvecs, v1, v2, v3) < 0)
|
| 501 |
|
|
return; /* degenerate triangle! */
|
| 502 |
greg |
2.16 |
printf("\n%s texfunc T-nor\n", mat); /* put out texture */
|
| 503 |
greg |
2.2 |
printf("4 dx dy dz %s\n0\n", TCALNAME);
|
| 504 |
|
|
xf_rotvect(n1, cv1->n);
|
| 505 |
|
|
xf_rotvect(n2, cv2->n);
|
| 506 |
|
|
xf_rotvect(n3, cv3->n);
|
| 507 |
|
|
for (i = 0; i < 3; i++) {
|
| 508 |
|
|
bcoor[i][0] = n1[i];
|
| 509 |
|
|
bcoor[i][1] = n2[i];
|
| 510 |
|
|
bcoor[i][2] = n3[i];
|
| 511 |
greg |
2.1 |
}
|
| 512 |
greg |
2.32 |
fput_baryc(&bvecs, bcoor, 3, stdout);
|
| 513 |
greg |
2.16 |
/* put out triangle */
|
| 514 |
greg |
2.2 |
printf("\nT-nor polygon %st%d\n", object(), ++ntris);
|
| 515 |
greg |
2.1 |
printf("0\n0\n9\n");
|
| 516 |
|
|
putv(v1);
|
| 517 |
|
|
putv(v2);
|
| 518 |
|
|
putv(v3);
|
| 519 |
|
|
}
|
| 520 |
|
|
|
| 521 |
|
|
|
| 522 |
greg |
2.30 |
void
|
| 523 |
|
|
putsided(char *mname) /* print out mixfunc for sided material */
|
| 524 |
|
|
{
|
| 525 |
|
|
fprintf(matfp, "\nvoid mixfunc %s\n", mname);
|
| 526 |
|
|
fprintf(matfp, "4 %s void if(Rdot,1,0) .\n0\n0\n", mname);
|
| 527 |
|
|
}
|
| 528 |
|
|
|
| 529 |
|
|
|
| 530 |
greg |
2.1 |
char *
|
| 531 |
schorsch |
2.28 |
material(void) /* get (and print) current material */
|
| 532 |
greg |
2.1 |
{
|
| 533 |
|
|
char *mname = "mat";
|
| 534 |
greg |
2.36 |
C_COLOR *refclr = NULL;
|
| 535 |
greg |
2.33 |
char *pname;
|
| 536 |
greg |
2.1 |
COLOR radrgb, c2;
|
| 537 |
|
|
double d;
|
| 538 |
|
|
|
| 539 |
greg |
2.5 |
if (c_cmname != NULL)
|
| 540 |
|
|
mname = c_cmname;
|
| 541 |
greg |
2.1 |
if (!c_cmaterial->clock)
|
| 542 |
|
|
return(mname); /* already current */
|
| 543 |
|
|
/* else update output */
|
| 544 |
|
|
c_cmaterial->clock = 0;
|
| 545 |
|
|
if (c_cmaterial->ed > .1) { /* emitter */
|
| 546 |
greg |
2.33 |
pname = specolor(radrgb, &c_cmaterial->ed_c,
|
| 547 |
greg |
2.12 |
emult*c_cmaterial->ed/(PI*WHTEFFICACY));
|
| 548 |
greg |
2.2 |
if (glowdist < FHUGE) { /* do a glow */
|
| 549 |
greg |
2.33 |
fprintf(matfp, "\n%s glow %s\n0\n0\n", pname, mname);
|
| 550 |
greg |
2.11 |
fprintf(matfp, "4 %f %f %f %f\n", colval(radrgb,RED),
|
| 551 |
greg |
2.1 |
colval(radrgb,GRN),
|
| 552 |
|
|
colval(radrgb,BLU), glowdist);
|
| 553 |
|
|
} else {
|
| 554 |
greg |
2.33 |
fprintf(matfp, "\n%s light %s\n0\n0\n", pname, mname);
|
| 555 |
greg |
2.11 |
fprintf(matfp, "3 %f %f %f\n", colval(radrgb,RED),
|
| 556 |
greg |
2.1 |
colval(radrgb,GRN),
|
| 557 |
|
|
colval(radrgb,BLU));
|
| 558 |
|
|
}
|
| 559 |
|
|
return(mname);
|
| 560 |
|
|
}
|
| 561 |
|
|
d = c_cmaterial->rd + c_cmaterial->td +
|
| 562 |
|
|
c_cmaterial->rs + c_cmaterial->ts;
|
| 563 |
schorsch |
2.27 |
if ((d < 0.) | (d > 1.))
|
| 564 |
greg |
2.1 |
return(NULL);
|
| 565 |
greg |
2.14 |
/* check for glass/dielectric */
|
| 566 |
|
|
if (c_cmaterial->nr > 1.1 &&
|
| 567 |
|
|
c_cmaterial->ts > .25 && c_cmaterial->rs <= .125 &&
|
| 568 |
|
|
c_cmaterial->td <= .01 && c_cmaterial->rd <= .01 &&
|
| 569 |
|
|
c_cmaterial->rs_a <= .01 && c_cmaterial->ts_a <= .01) {
|
| 570 |
|
|
cvtcolor(radrgb, &c_cmaterial->ts_c,
|
| 571 |
|
|
c_cmaterial->ts + c_cmaterial->rs);
|
| 572 |
|
|
if (c_cmaterial->sided) { /* dielectric */
|
| 573 |
|
|
colval(radrgb,RED) = pow(colval(radrgb,RED),
|
| 574 |
|
|
1./C_1SIDEDTHICK);
|
| 575 |
|
|
colval(radrgb,GRN) = pow(colval(radrgb,GRN),
|
| 576 |
|
|
1./C_1SIDEDTHICK);
|
| 577 |
|
|
colval(radrgb,BLU) = pow(colval(radrgb,BLU),
|
| 578 |
|
|
1./C_1SIDEDTHICK);
|
| 579 |
|
|
fprintf(matfp, "\nvoid dielectric %s\n0\n0\n", mname);
|
| 580 |
|
|
fprintf(matfp, "5 %g %g %g %f 0\n", colval(radrgb,RED),
|
| 581 |
|
|
colval(radrgb,GRN), colval(radrgb,BLU),
|
| 582 |
|
|
c_cmaterial->nr);
|
| 583 |
|
|
return(mname);
|
| 584 |
|
|
}
|
| 585 |
|
|
/* glass */
|
| 586 |
|
|
fprintf(matfp, "\nvoid glass %s\n0\n0\n", mname);
|
| 587 |
|
|
fprintf(matfp, "4 %f %f %f %f\n", colval(radrgb,RED),
|
| 588 |
|
|
colval(radrgb,GRN), colval(radrgb,BLU),
|
| 589 |
|
|
c_cmaterial->nr);
|
| 590 |
|
|
return(mname);
|
| 591 |
greg |
2.33 |
}
|
| 592 |
greg |
2.36 |
/* check for WGMDfunc */
|
| 593 |
|
|
if (((c_cmaterial->rs > .02) & (c_cmaterial->ts > .02) &&
|
| 594 |
|
|
fabs(c_cmaterial->rs_a - c_cmaterial->ts_a) > .02) ||
|
| 595 |
|
|
((c_cmaterial->rs > .05) & (c_cmaterial->rd > .05) &&
|
| 596 |
|
|
!c_isgrey(&c_cmaterial->rs_c) &&
|
| 597 |
|
|
!c_equiv(&c_cmaterial->rd_c, &c_cmaterial->rs_c)) ||
|
| 598 |
|
|
color_clash(MG_E_TS, MG_E_TD) ||
|
| 599 |
|
|
color_clash(MG_E_TD, MG_E_RD) ||
|
| 600 |
|
|
color_clash(MG_E_RD, MG_E_TS)) {
|
| 601 |
|
|
COLOR rs_rgb, ts_rgb, td_rgb; /* separate modifier paths */
|
| 602 |
|
|
char rs_pname[128], ts_pname[128], td_pname[128];
|
| 603 |
|
|
strcpy(sgen_str, SGEN_RS);
|
| 604 |
|
|
strcpy(rs_pname, specolor(rs_rgb, &c_cmaterial->rs_c, c_cmaterial->rs));
|
| 605 |
|
|
strcpy(sgen_str, SGEN_TS);
|
| 606 |
|
|
strcpy(ts_pname, specolor(ts_rgb, &c_cmaterial->ts_c, c_cmaterial->ts));
|
| 607 |
|
|
strcpy(sgen_str, SGEN_TD);
|
| 608 |
|
|
strcpy(td_pname, specolor(td_rgb, &c_cmaterial->td_c, c_cmaterial->td));
|
| 609 |
|
|
strcpy(sgen_str, SGEN_DEF);
|
| 610 |
|
|
pname = specolor(radrgb, &c_cmaterial->rd_c, c_cmaterial->rd);
|
| 611 |
|
|
if (!strcmp(rs_pname, void_str) && !isgrey(rs_rgb)) {
|
| 612 |
|
|
putrgbpat(strcpy(rs_pname,"rs_rgb*"), rs_rgb);
|
| 613 |
|
|
colval(rs_rgb,GRN) = 1;
|
| 614 |
|
|
}
|
| 615 |
|
|
if (!strcmp(ts_pname, void_str) && !isgrey(ts_rgb)) {
|
| 616 |
|
|
putrgbpat(strcpy(ts_pname,"ts_rgb*"), ts_rgb);
|
| 617 |
|
|
colval(ts_rgb,GRN) = 1;
|
| 618 |
|
|
}
|
| 619 |
|
|
fprintf(matfp, "\n%s WGMDfunc %s\n", pname, mname);
|
| 620 |
|
|
fprintf(matfp, "13\t%s %f %f %f\n", rs_pname, colval(rs_rgb,GRN),
|
| 621 |
|
|
c_cmaterial->rs_a, c_cmaterial->rs_a);
|
| 622 |
|
|
fprintf(matfp, "\t%s %f %f %f\n", ts_pname, colval(ts_rgb,GRN),
|
| 623 |
|
|
c_cmaterial->ts_a, c_cmaterial->ts_a);
|
| 624 |
|
|
fprintf(matfp, "\t%s\n\t0 0 1 .\n0\n", td_pname);
|
| 625 |
|
|
fprintf(matfp, "9\t%f %f %f\n", colval(radrgb,RED),
|
| 626 |
|
|
colval(radrgb,GRN), colval(radrgb,BLU));
|
| 627 |
|
|
fprintf(matfp, "\t%f %f %f\n", colval(radrgb,RED),
|
| 628 |
|
|
colval(radrgb,GRN), colval(radrgb,BLU));
|
| 629 |
|
|
fprintf(matfp, "\t%f %f %f\n", colval(td_rgb,RED),
|
| 630 |
|
|
colval(td_rgb,GRN), colval(td_rgb,BLU));
|
| 631 |
|
|
if (c_cmaterial->sided)
|
| 632 |
|
|
putsided(mname);
|
| 633 |
|
|
return(mname);
|
| 634 |
|
|
}
|
| 635 |
greg |
2.3 |
/* check for trans */
|
| 636 |
greg |
2.36 |
if (c_cmaterial->td + c_cmaterial->ts > .01) {
|
| 637 |
greg |
2.30 |
double a5, a6;
|
| 638 |
greg |
2.1 |
/* average colors */
|
| 639 |
greg |
2.30 |
d = c_cmaterial->rd + c_cmaterial->td + c_cmaterial->ts;
|
| 640 |
greg |
2.1 |
cvtcolor(radrgb, &c_cmaterial->rd_c, c_cmaterial->rd/d);
|
| 641 |
|
|
cvtcolor(c2, &c_cmaterial->td_c, c_cmaterial->td/d);
|
| 642 |
|
|
addcolor(radrgb, c2);
|
| 643 |
greg |
2.30 |
cvtcolor(c2, &c_cmaterial->ts_c, c_cmaterial->ts/d);
|
| 644 |
greg |
2.1 |
addcolor(radrgb, c2);
|
| 645 |
greg |
2.30 |
if (c_cmaterial->rs + c_cmaterial->ts > .0001)
|
| 646 |
greg |
2.1 |
a5 = (c_cmaterial->rs*c_cmaterial->rs_a +
|
| 647 |
greg |
2.30 |
c_cmaterial->ts*c_cmaterial->ts_a) /
|
| 648 |
|
|
(c_cmaterial->rs + c_cmaterial->ts);
|
| 649 |
|
|
a6 = (c_cmaterial->td + c_cmaterial->ts) /
|
| 650 |
|
|
(c_cmaterial->rd + c_cmaterial->td + c_cmaterial->ts);
|
| 651 |
greg |
2.7 |
if (a6 < .999)
|
| 652 |
greg |
2.1 |
d = c_cmaterial->rd/(1. - c_cmaterial->rs)/(1. - a6);
|
| 653 |
greg |
2.7 |
else
|
| 654 |
greg |
2.30 |
d = c_cmaterial->td + c_cmaterial->ts;
|
| 655 |
greg |
2.7 |
scalecolor(radrgb, d);
|
| 656 |
greg |
2.11 |
fprintf(matfp, "\nvoid trans %s\n0\n0\n", mname);
|
| 657 |
|
|
fprintf(matfp, "7 %f %f %f\n", colval(radrgb,RED),
|
| 658 |
greg |
2.1 |
colval(radrgb,GRN), colval(radrgb,BLU));
|
| 659 |
greg |
2.11 |
fprintf(matfp, "\t%f %f %f %f\n", c_cmaterial->rs, a5, a6,
|
| 660 |
greg |
2.30 |
c_cmaterial->ts/(c_cmaterial->ts + c_cmaterial->td));
|
| 661 |
|
|
if (c_cmaterial->sided)
|
| 662 |
|
|
putsided(mname);
|
| 663 |
greg |
2.1 |
return(mname);
|
| 664 |
|
|
}
|
| 665 |
greg |
2.3 |
/* check for plastic */
|
| 666 |
greg |
2.33 |
if (c_cmaterial->rs < .1 && (c_cmaterial->rs < .1*c_cmaterial->rd ||
|
| 667 |
greg |
2.31 |
c_isgrey(&c_cmaterial->rs_c))) {
|
| 668 |
greg |
2.33 |
pname = specolor(radrgb, &c_cmaterial->rd_c,
|
| 669 |
greg |
2.1 |
c_cmaterial->rd/(1.-c_cmaterial->rs));
|
| 670 |
greg |
2.33 |
fprintf(matfp, "\n%s plastic %s\n0\n0\n", pname, mname);
|
| 671 |
greg |
2.11 |
fprintf(matfp, "5 %f %f %f %f %f\n", colval(radrgb,RED),
|
| 672 |
greg |
2.1 |
colval(radrgb,GRN), colval(radrgb,BLU),
|
| 673 |
|
|
c_cmaterial->rs, c_cmaterial->rs_a);
|
| 674 |
greg |
2.30 |
if (c_cmaterial->sided)
|
| 675 |
|
|
putsided(mname);
|
| 676 |
greg |
2.1 |
return(mname);
|
| 677 |
|
|
}
|
| 678 |
|
|
/* else it's metal */
|
| 679 |
greg |
2.33 |
/* compute color */
|
| 680 |
|
|
if (c_equiv(&c_cmaterial->rd_c, &c_cmaterial->rs_c)) {
|
| 681 |
|
|
pname = specolor(radrgb, &c_cmaterial->rs_c, c_cmaterial->rs+c_cmaterial->rd);
|
| 682 |
|
|
} else if (c_cmaterial->rd <= .05f) {
|
| 683 |
|
|
pname = specolor(radrgb, &c_cmaterial->rs_c, c_cmaterial->rs);
|
| 684 |
|
|
cvtcolor(c2, &c_cmaterial->rd_c, c_cmaterial->rd);
|
| 685 |
|
|
addcolor(radrgb, c2);
|
| 686 |
|
|
} else {
|
| 687 |
|
|
pname = "void";
|
| 688 |
|
|
cvtcolor(radrgb, &c_cmaterial->rd_c, c_cmaterial->rd);
|
| 689 |
|
|
cvtcolor(c2, &c_cmaterial->rs_c, c_cmaterial->rs);
|
| 690 |
|
|
addcolor(radrgb, c2);
|
| 691 |
|
|
}
|
| 692 |
|
|
fprintf(matfp, "\n%s metal %s\n0\n0\n", pname, mname);
|
| 693 |
greg |
2.11 |
fprintf(matfp, "5 %f %f %f %f %f\n", colval(radrgb,RED),
|
| 694 |
greg |
2.1 |
colval(radrgb,GRN), colval(radrgb,BLU),
|
| 695 |
greg |
2.7 |
c_cmaterial->rs/(c_cmaterial->rd + c_cmaterial->rs),
|
| 696 |
|
|
c_cmaterial->rs_a);
|
| 697 |
greg |
2.30 |
if (c_cmaterial->sided)
|
| 698 |
|
|
putsided(mname);
|
| 699 |
greg |
2.1 |
return(mname);
|
| 700 |
|
|
}
|
| 701 |
|
|
|
| 702 |
|
|
|
| 703 |
schorsch |
2.28 |
void
|
| 704 |
|
|
cvtcolor( /* convert a CIE XYZ color to RGB */
|
| 705 |
|
|
COLOR radrgb,
|
| 706 |
greg |
2.33 |
C_COLOR *ciec,
|
| 707 |
schorsch |
2.28 |
double intensity
|
| 708 |
|
|
)
|
| 709 |
greg |
2.1 |
{
|
| 710 |
greg |
2.33 |
COLOR ciexyz;
|
| 711 |
greg |
2.1 |
|
| 712 |
greg |
2.36 |
if (intensity <= 0) {
|
| 713 |
|
|
setcolor(radrgb, 0, 0, 0);
|
| 714 |
|
|
return;
|
| 715 |
|
|
}
|
| 716 |
greg |
2.4 |
c_ccvt(ciec, C_CSXY); /* get xy representation */
|
| 717 |
greg |
2.1 |
ciexyz[1] = intensity;
|
| 718 |
|
|
ciexyz[0] = ciec->cx/ciec->cy*ciexyz[1];
|
| 719 |
|
|
ciexyz[2] = ciexyz[1]*(1./ciec->cy - 1.) - ciexyz[0];
|
| 720 |
|
|
cie_rgb(radrgb, ciexyz);
|
| 721 |
|
|
}
|
| 722 |
|
|
|
| 723 |
|
|
|
| 724 |
greg |
2.36 |
int color_clash( /* do non-zero material components clash? */
|
| 725 |
|
|
int e1,
|
| 726 |
|
|
int e2
|
| 727 |
|
|
)
|
| 728 |
|
|
{
|
| 729 |
|
|
C_COLOR *c1;
|
| 730 |
|
|
|
| 731 |
|
|
if (e1 == e2)
|
| 732 |
|
|
return(0);
|
| 733 |
|
|
switch (e1) {
|
| 734 |
|
|
case MG_E_RD:
|
| 735 |
|
|
if (c_cmaterial->rd <= .01) return(0);
|
| 736 |
|
|
c1 = &c_cmaterial->rd_c;
|
| 737 |
|
|
break;
|
| 738 |
|
|
case MG_E_RS:
|
| 739 |
|
|
if (c_cmaterial->rs <= .01) return(0);
|
| 740 |
|
|
c1 = &c_cmaterial->rs_c;
|
| 741 |
|
|
break;
|
| 742 |
|
|
case MG_E_TD:
|
| 743 |
|
|
if (c_cmaterial->td <= .01) return(0);
|
| 744 |
|
|
c1 = &c_cmaterial->td_c;
|
| 745 |
|
|
break;
|
| 746 |
|
|
case MG_E_TS:
|
| 747 |
|
|
if (c_cmaterial->ts <= .01) return(0);
|
| 748 |
|
|
c1 = &c_cmaterial->ts_c;
|
| 749 |
|
|
break;
|
| 750 |
|
|
default:
|
| 751 |
|
|
return(0);
|
| 752 |
|
|
}
|
| 753 |
|
|
switch (e2) {
|
| 754 |
|
|
case MG_E_RD:
|
| 755 |
|
|
if (c_cmaterial->rd <= .01) return(0);
|
| 756 |
|
|
return(!c_equiv(c1, &c_cmaterial->rd_c));
|
| 757 |
|
|
case MG_E_RS:
|
| 758 |
|
|
if (c_cmaterial->rs <= .01) return(0);
|
| 759 |
|
|
return(!c_equiv(c1, &c_cmaterial->rs_c));
|
| 760 |
|
|
case MG_E_TD:
|
| 761 |
|
|
if (c_cmaterial->td <= .01) return(0);
|
| 762 |
|
|
return(!c_equiv(c1, &c_cmaterial->td_c));
|
| 763 |
|
|
case MG_E_TS:
|
| 764 |
|
|
if (c_cmaterial->ts <= .01) return(0);
|
| 765 |
|
|
return(!c_equiv(c1, &c_cmaterial->ts_c));
|
| 766 |
|
|
}
|
| 767 |
|
|
return(0);
|
| 768 |
|
|
}
|
| 769 |
|
|
|
| 770 |
|
|
|
| 771 |
greg |
2.33 |
static int /* new spectrum definition? */
|
| 772 |
|
|
newspecdef(C_COLOR *spc)
|
| 773 |
|
|
{
|
| 774 |
|
|
static LUTAB spc_tab = LU_SINIT(NULL,free);
|
| 775 |
|
|
LUENT *lp = lu_find(&spc_tab, (const char *)spc->client_data);
|
| 776 |
|
|
|
| 777 |
|
|
if (lp == NULL) /* should never happen */
|
| 778 |
|
|
return(1);
|
| 779 |
|
|
if (lp->data == NULL) { /* new entry */
|
| 780 |
|
|
lp->key = (char *)spc->client_data;
|
| 781 |
|
|
lp->data = (char *)malloc(sizeof(C_COLOR));
|
| 782 |
|
|
} else if (c_equiv(spc, (C_COLOR *)lp->data))
|
| 783 |
|
|
return(0); /* unchanged */
|
| 784 |
|
|
|
| 785 |
|
|
if (lp->data != NULL) /* else remember if we can */
|
| 786 |
|
|
*(C_COLOR *)lp->data = *spc;
|
| 787 |
|
|
return(1); /* good as new */
|
| 788 |
|
|
}
|
| 789 |
|
|
|
| 790 |
|
|
|
| 791 |
|
|
char *
|
| 792 |
|
|
specolor( /* check if color has spectra and output accordingly */
|
| 793 |
|
|
COLOR radrgb,
|
| 794 |
|
|
C_COLOR *clr,
|
| 795 |
|
|
double intensity
|
| 796 |
|
|
)
|
| 797 |
|
|
{
|
| 798 |
|
|
static char spname[128];
|
| 799 |
|
|
double mult;
|
| 800 |
greg |
2.34 |
int cbeg, cend, i;
|
| 801 |
greg |
2.33 |
|
| 802 |
greg |
2.36 |
if (!dospectra | !(clr->flags & C_CDSPEC) | (intensity <= FTINY)) {
|
| 803 |
greg |
2.33 |
cvtcolor(radrgb, clr, intensity);
|
| 804 |
greg |
2.36 |
return(void_str); /* just use RGB */
|
| 805 |
greg |
2.33 |
}
|
| 806 |
|
|
setcolor(radrgb, intensity, intensity, intensity);
|
| 807 |
greg |
2.34 |
for (cbeg = 0; cbeg < C_CNSS; cbeg++) /* trim zeros off beginning */
|
| 808 |
|
|
if (clr->ssamp[cbeg])
|
| 809 |
|
|
break;
|
| 810 |
|
|
if (cbeg >= C_CNSS) /* should never happen! */
|
| 811 |
greg |
2.36 |
return(void_str);
|
| 812 |
greg |
2.33 |
if (clr->client_data != NULL) { /* get name if available */
|
| 813 |
|
|
strcpy(spname, (char *)clr->client_data);
|
| 814 |
|
|
strcat(spname, "*"); /* make sure it's special */
|
| 815 |
|
|
if (!newspecdef(clr)) /* output already? */
|
| 816 |
|
|
return(spname);
|
| 817 |
|
|
} else
|
| 818 |
greg |
2.36 |
strcpy(spname, sgen_str);
|
| 819 |
greg |
2.33 |
c_ccvt(clr, C_CSEFF); /* else output spectrum prim */
|
| 820 |
greg |
2.34 |
for (cend = 0; !clr->ssamp[C_CNSS-1-cend]; cend++)
|
| 821 |
|
|
; /* trim zeros off end */
|
| 822 |
greg |
2.33 |
fprintf(matfp, "\nvoid spectrum %s\n0\n0\n", spname);
|
| 823 |
greg |
2.34 |
fprintf(matfp, "%d %d %d", C_CNSS+2-cbeg-cend,
|
| 824 |
|
|
C_CMINWL+cbeg*C_CWLI, C_CMAXWL-cend*C_CWLI);
|
| 825 |
greg |
2.33 |
mult = (C_CNSS*c_dfcolor.eff)/(clr->ssum*clr->eff);
|
| 826 |
greg |
2.34 |
for (i = cbeg; i < C_CNSS-cend; i++) {
|
| 827 |
|
|
if (!((i-cbeg+1)%6)) fputc('\n', matfp);
|
| 828 |
greg |
2.33 |
fprintf(matfp, "\t%.5f", clr->ssamp[i]*mult);
|
| 829 |
|
|
}
|
| 830 |
|
|
fputc('\n', matfp);
|
| 831 |
|
|
return(spname);
|
| 832 |
|
|
}
|
| 833 |
|
|
|
| 834 |
|
|
|
| 835 |
greg |
2.36 |
int
|
| 836 |
|
|
isgrey( /* is RGB close match to grey? */
|
| 837 |
|
|
COLOR rgb
|
| 838 |
|
|
)
|
| 839 |
|
|
{
|
| 840 |
|
|
const double yv = bright(rgb);
|
| 841 |
|
|
double diff2 = 0;
|
| 842 |
|
|
int i;
|
| 843 |
|
|
|
| 844 |
|
|
for (i = 3; i--; ) {
|
| 845 |
|
|
double d = yv - colval(rgb,i);
|
| 846 |
|
|
diff2 += d*d;
|
| 847 |
|
|
}
|
| 848 |
|
|
return(diff2 <= yv*yv*0.0025);
|
| 849 |
|
|
}
|
| 850 |
|
|
|
| 851 |
|
|
|
| 852 |
|
|
void
|
| 853 |
|
|
putrgbpat( /* put out RGB pattern with given name */
|
| 854 |
|
|
char *pnm,
|
| 855 |
|
|
COLOR rgb
|
| 856 |
|
|
)
|
| 857 |
|
|
{
|
| 858 |
|
|
fprintf(matfp, "\nvoid colorfunc %s\n", pnm);
|
| 859 |
|
|
fprintf(matfp, "4 %f %f %f .\n0\n0\n", colval(rgb,RED),
|
| 860 |
|
|
colval(rgb,GRN), colval(rgb,BLU));
|
| 861 |
|
|
}
|
| 862 |
|
|
|
| 863 |
|
|
|
| 864 |
greg |
2.1 |
char *
|
| 865 |
schorsch |
2.28 |
object(void) /* return current object name */
|
| 866 |
greg |
2.1 |
{
|
| 867 |
|
|
static char objbuf[64];
|
| 868 |
greg |
2.33 |
int i;
|
| 869 |
|
|
char *cp;
|
| 870 |
greg |
2.1 |
int len;
|
| 871 |
greg |
2.16 |
/* tracked by obj_handler */
|
| 872 |
greg |
2.1 |
i = obj_nnames - sizeof(objbuf)/16;
|
| 873 |
|
|
if (i < 0)
|
| 874 |
|
|
i = 0;
|
| 875 |
|
|
for (cp = objbuf; i < obj_nnames &&
|
| 876 |
|
|
cp + (len=strlen(obj_name[i])) < objbuf+sizeof(objbuf)-1;
|
| 877 |
|
|
i++, *cp++ = '.') {
|
| 878 |
|
|
strcpy(cp, obj_name[i]);
|
| 879 |
|
|
cp += len;
|
| 880 |
|
|
}
|
| 881 |
|
|
*cp = '\0';
|
| 882 |
|
|
return(objbuf);
|
| 883 |
|
|
}
|
| 884 |
|
|
|
| 885 |
|
|
|
| 886 |
|
|
char *
|
| 887 |
schorsch |
2.28 |
addarg( /* add argument and advance pointer */
|
| 888 |
greg |
2.33 |
char *op,
|
| 889 |
|
|
char *arg
|
| 890 |
schorsch |
2.28 |
)
|
| 891 |
greg |
2.1 |
{
|
| 892 |
|
|
*op = ' ';
|
| 893 |
schorsch |
2.27 |
while ( (*++op = *arg++) )
|
| 894 |
greg |
2.1 |
;
|
| 895 |
|
|
return(op);
|
| 896 |
|
|
}
|