ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rview.c
Revision: 2.12
Committed: Tue Sep 7 16:11:12 1993 UTC (30 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.11: +2 -2 lines
Log Message:
bug fix for 16-bit integers in psample()

File Contents

# Content
1 /* Copyright (c) 1992 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * rview.c - routines and variables for interactive view generation.
9 *
10 * 3/24/87
11 */
12
13 #include "ray.h"
14
15 #include "rpaint.h"
16
17 #include <signal.h>
18
19 #include <ctype.h>
20
21 VIEW ourview = STDVIEW; /* viewing parameters */
22 int hresolu, vresolu; /* image resolution */
23
24 int dimlist[MAXDIM]; /* sampling dimensions */
25 int ndims = 0; /* number of sampling dimensions */
26 int samplendx = 0; /* index for this sample */
27
28 int psample = 8; /* pixel sample size */
29 double maxdiff = .15; /* max. sample difference */
30
31 double exposure = 1.0; /* exposure for scene */
32
33 double dstrsrc = 0.0; /* square source distribution */
34 double shadthresh = .1; /* shadow threshold */
35 double shadcert = .25; /* shadow certainty */
36 int directrelay = 0; /* number of source relays */
37 int vspretest = 128; /* virtual source pretest density */
38 int directvis = 1; /* sources visible? */
39 double srcsizerat = 0.; /* maximum ratio source size/dist. */
40
41 double specthresh = .3; /* specular sampling threshold */
42 double specjitter = 1.; /* specular sampling jitter */
43
44 int maxdepth = 4; /* maximum recursion depth */
45 double minweight = 1e-2; /* minimum ray weight */
46
47 COLOR ambval = BLKCOLOR; /* ambient value */
48 double ambacc = 0.2; /* ambient accuracy */
49 int ambres = 8; /* ambient resolution */
50 int ambdiv = 32; /* ambient divisions */
51 int ambssamp = 0; /* ambient super-samples */
52 int ambounce = 0; /* ambient bounces */
53 char *amblist[128]; /* ambient include/exclude list */
54 int ambincl = -1; /* include == 1, exclude == 0 */
55
56 int greyscale = 0; /* map colors to brightness? */
57 char *devname = dev_default; /* output device name */
58
59 struct driver *dev = NULL; /* driver functions */
60
61 char rifname[128]; /* rad input file name */
62
63 VIEW oldview; /* previous view parameters */
64
65 PNODE ptrunk; /* the base of our image */
66 RECT pframe; /* current frame boundaries */
67 int pdepth; /* image depth in current frame */
68
69 static char *reserve_mem = NULL; /* pre-allocated reserve memory */
70
71 #define RESERVE_AMT 32768 /* amount of memory to reserve */
72
73 #define CTRL(c) ((c)-'@')
74
75
76 quit(code) /* quit program */
77 int code;
78 {
79 #ifdef MSTATS
80 if (code == 2 && errno == ENOMEM)
81 printmemstats(stderr);
82 #endif
83 devclose();
84 exit(code);
85 }
86
87
88 devopen(dname) /* open device driver */
89 char *dname;
90 {
91 extern char *progname, *octname;
92 char *id;
93 register int i;
94
95 id = octname!=NULL ? octname : progname;
96 /* check device table */
97 for (i = 0; devtable[i].name; i++)
98 if (!strcmp(dname, devtable[i].name))
99 if ((dev = (*devtable[i].init)(dname, id)) == NULL) {
100 sprintf(errmsg, "cannot initialize %s", dname);
101 error(USER, errmsg);
102 } else
103 return;
104 #ifndef NIX
105 /* not there, try exec */
106 if ((dev = comm_init(dname, id)) == NULL) {
107 sprintf(errmsg, "cannot start device \"%s\"", dname);
108 error(USER, errmsg);
109 }
110 #endif
111 }
112
113
114 devclose() /* close our device */
115 {
116 if (dev != NULL)
117 (*dev->close)();
118 dev = NULL;
119 }
120
121
122 printdevices() /* print list of output devices */
123 {
124 register int i;
125
126 for (i = 0; devtable[i].name; i++)
127 printf("%-16s # %s\n", devtable[i].name, devtable[i].descrip);
128 }
129
130
131 rview() /* do a view */
132 {
133 char buf[32];
134
135 devopen(devname); /* open device */
136 newimage(); /* start image (calls fillreserves) */
137
138 for ( ; ; ) { /* quit in command() */
139 while (hresolu <= 1<<pdepth && vresolu <= 1<<pdepth)
140 command("done: ");
141 while (reserve_mem == NULL)
142 command("out of memory: ");
143 errno = 0;
144 if (hresolu <= psample<<pdepth && vresolu <= psample<<pdepth) {
145 sprintf(buf, "%d sampling...\n", 1<<pdepth);
146 (*dev->comout)(buf);
147 rsample();
148 } else {
149 sprintf(buf, "%d refining...\n", 1<<pdepth);
150 (*dev->comout)(buf);
151 refine(&ptrunk, 0, 0, hresolu, vresolu, pdepth+1);
152 }
153 if (errno == ENOMEM) /* ran out of memory */
154 freereserves();
155 else if (dev->inpready) /* noticed some input */
156 command(": ");
157 else /* finished this depth */
158 pdepth++;
159 }
160 }
161
162
163 fillreserves() /* fill memory reserves */
164 {
165 if (reserve_mem != NULL)
166 return;
167 reserve_mem = malloc(RESERVE_AMT);
168 }
169
170
171 freereserves() /* free memory reserves */
172 {
173 if (reserve_mem == NULL)
174 return;
175 free(reserve_mem);
176 reserve_mem = NULL;
177 }
178
179
180 command(prompt) /* get/execute command */
181 char *prompt;
182 {
183 #define badcom(s) strncmp(s, inpbuf, args-inpbuf-1)
184 char inpbuf[256];
185 char *args;
186 again:
187 (*dev->comin)(inpbuf, prompt); /* get command + arguments */
188 for (args = inpbuf; *args && *args != ' '; args++)
189 ;
190 if (*args) *args++ = '\0';
191 else *++args = '\0';
192
193 switch (inpbuf[0]) {
194 case 'f': /* new frame (or free mem.) */
195 if (badcom("frame")) {
196 if (badcom("free"))
197 goto commerr;
198 free_objmem();
199 break;
200 }
201 getframe(args);
202 break;
203 case 'v': /* view */
204 if (badcom("view"))
205 goto commerr;
206 getview(args);
207 break;
208 case 'l': /* last view */
209 if (badcom("last"))
210 goto commerr;
211 lastview(args);
212 break;
213 case 'V': /* save view */
214 if (badcom("V"))
215 goto commerr;
216 saveview(args);
217 break;
218 case 'L': /* load view */
219 if (badcom("L"))
220 goto commerr;
221 loadview(args);
222 break;
223 case 'e': /* exposure */
224 if (badcom("exposure"))
225 goto commerr;
226 getexposure(args);
227 break;
228 case 's': /* set a parameter */
229 if (badcom("set"))
230 goto commerr;
231 setparam(args);
232 break;
233 case 'n': /* new picture */
234 if (badcom("new"))
235 goto commerr;
236 newimage();
237 break;
238 case 't': /* trace a ray */
239 if (badcom("trace"))
240 goto commerr;
241 traceray(args);
242 break;
243 case 'a': /* aim camera */
244 if (badcom("aim"))
245 goto commerr;
246 getaim(args);
247 break;
248 case 'm': /* move camera (or memstats) */
249 if (badcom("move"))
250 #ifdef MSTATS
251 {
252 if (badcom("memory"))
253 goto commerr;
254 printmemstats(stderr);
255 break;
256 }
257 #else
258 goto commerr;
259 #endif
260 getmove(args);
261 break;
262 case 'r': /* rotate/repaint */
263 if (badcom("rotate")) {
264 if (badcom("repaint"))
265 goto commerr;
266 getrepaint(args);
267 break;
268 }
269 getrotate(args);
270 break;
271 case 'p': /* pivot view */
272 if (badcom("pivot"))
273 goto commerr;
274 getpivot(args);
275 break;
276 case CTRL('R'): /* redraw */
277 redraw();
278 break;
279 case 'w': /* write */
280 if (badcom("write"))
281 goto commerr;
282 writepict(args);
283 break;
284 case 'q': /* quit */
285 if (badcom("quit"))
286 goto commerr;
287 quit(0);
288 case CTRL('C'): /* interrupt */
289 goto again;
290 #ifdef SIGTSTP
291 case CTRL('Z'): /* stop */
292 devclose();
293 kill(0, SIGTSTP);
294 /* pc stops here */
295 devopen(devname);
296 redraw();
297 break;
298 #endif
299 case '\0': /* continue */
300 break;
301 default:;
302 commerr:
303 if (iscntrl(inpbuf[0]))
304 sprintf(errmsg, "^%c: unknown control",
305 inpbuf[0]|0100);
306 else
307 sprintf(errmsg, "%s: unknown command", inpbuf);
308 error(COMMAND, errmsg);
309 break;
310 }
311 #undef badcom
312 }
313
314
315 rsample() /* sample the image */
316 {
317 int xsiz, ysiz, y;
318 RECT r;
319 PNODE *p;
320 register RECT *rl;
321 register PNODE **pl;
322 register int x;
323 /*
324 * We initialize the bottom row in the image at our current
325 * resolution. During sampling, we check super-pixels to the
326 * right and above by calling bigdiff(). If there is a significant
327 * difference, we subsample the super-pixels. The testing process
328 * includes initialization of the next row.
329 */
330 xsiz = (((long)(pframe.r-pframe.l)<<pdepth)+hresolu-1) / hresolu;
331 ysiz = (((long)(pframe.u-pframe.d)<<pdepth)+vresolu-1) / vresolu;
332 rl = (RECT *)malloc(xsiz*sizeof(RECT));
333 if (rl == NULL)
334 return;
335 pl = (PNODE **)malloc(xsiz*sizeof(PNODE *));
336 if (pl == NULL) {
337 free((char *)rl);
338 return;
339 }
340 /*
341 * Initialize the bottom row.
342 */
343 rl[0].l = rl[0].d = 0;
344 rl[0].r = hresolu; rl[0].u = vresolu;
345 pl[0] = findrect(pframe.l, pframe.d, &ptrunk, rl, pdepth);
346 for (x = 1; x < xsiz; x++) {
347 rl[x].l = rl[x].d = 0;
348 rl[x].r = hresolu; rl[x].u = vresolu;
349 pl[x] = findrect(pframe.l+((x*hresolu)>>pdepth),
350 pframe.d, &ptrunk, rl+x, pdepth);
351 }
352 /* sample the image */
353 for (y = 0; /* y < ysiz */ ; y++) {
354 for (x = 0; x < xsiz-1; x++) {
355 if (dev->inpready || errno == ENOMEM)
356 goto escape;
357 /*
358 * Test super-pixel to the right.
359 */
360 if (pl[x] != pl[x+1] && bigdiff(pl[x]->v,
361 pl[x+1]->v, maxdiff)) {
362 refine(pl[x], rl[x].l, rl[x].d,
363 rl[x].r, rl[x].u, 1);
364 refine(pl[x+1], rl[x+1].l, rl[x+1].d,
365 rl[x+1].r, rl[x+1].u, 1);
366 }
367 }
368 if (y >= ysiz-1)
369 break;
370 for (x = 0; x < xsiz; x++) {
371 if (dev->inpready || errno == ENOMEM)
372 goto escape;
373 /*
374 * Find super-pixel at this position in next row.
375 */
376 r.l = r.d = 0;
377 r.r = hresolu; r.u = vresolu;
378 p = findrect(pframe.l+((x*hresolu)>>pdepth),
379 pframe.d+(((y+1)*vresolu)>>pdepth),
380 &ptrunk, &r, pdepth);
381 /*
382 * Test super-pixel in next row.
383 */
384 if (pl[x] != p && bigdiff(pl[x]->v, p->v, maxdiff)) {
385 refine(pl[x], rl[x].l, rl[x].d,
386 rl[x].r, rl[x].u, 1);
387 refine(p, r.l, r.d, r.r, r.u, 1);
388 }
389 /*
390 * Copy into super-pixel array.
391 */
392 rl[x].l = r.l; rl[x].d = r.d;
393 rl[x].r = r.r; rl[x].u = r.u;
394 pl[x] = p;
395 }
396 }
397 escape:
398 free((char *)rl);
399 free((char *)pl);
400 }
401
402
403 int
404 refine(p, xmin, ymin, xmax, ymax, pd) /* refine a node */
405 register PNODE *p;
406 int xmin, ymin, xmax, ymax;
407 int pd;
408 {
409 int growth;
410 int mx, my;
411 int i;
412
413 if (dev->inpready) /* quit for input */
414 return(0);
415
416 if (pd <= 0) /* depth limit */
417 return(0);
418
419 mx = (xmin + xmax) >> 1;
420 my = (ymin + ymax) >> 1;
421 growth = 0;
422
423 if (p->kid == NULL) { /* subdivide */
424
425 if ((p->kid = newptree()) == NULL)
426 return(0);
427 /*
428 * The following paint order can leave a black pixel
429 * if redraw() is called in (*dev->paintr)().
430 */
431 if (p->x >= mx && p->y >= my)
432 pcopy(p, p->kid+UR);
433 else
434 paint(p->kid+UR, mx, my, xmax, ymax);
435 if (p->x < mx && p->y >= my)
436 pcopy(p, p->kid+UL);
437 else
438 paint(p->kid+UL, xmin, my, mx, ymax);
439 if (p->x >= mx && p->y < my)
440 pcopy(p, p->kid+DR);
441 else
442 paint(p->kid+DR, mx, ymin, xmax, my);
443 if (p->x < mx && p->y < my)
444 pcopy(p, p->kid+DL);
445 else
446 paint(p->kid+DL, xmin, ymin, mx, my);
447
448 growth++;
449 }
450 /* do children */
451 if (mx > pframe.l) {
452 if (my > pframe.d)
453 growth += refine(p->kid+DL, xmin, ymin, mx, my, pd-1);
454 if (my < pframe.u)
455 growth += refine(p->kid+UL, xmin, my, mx, ymax, pd-1);
456 }
457 if (mx < pframe.r) {
458 if (my > pframe.d)
459 growth += refine(p->kid+DR, mx, ymin, xmax, my, pd-1);
460 if (my < pframe.u)
461 growth += refine(p->kid+UR, mx, my, xmax, ymax, pd-1);
462 }
463 /* recompute sum */
464 if (growth) {
465 setcolor(p->v, 0.0, 0.0, 0.0);
466 for (i = 0; i < 4; i++)
467 addcolor(p->v, p->kid[i].v);
468 scalecolor(p->v, 0.25);
469 }
470 return(growth);
471 }