ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rview.c
Revision: 1.20
Committed: Mon Aug 26 12:53:17 1991 UTC (32 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.19: +4 -4 lines
Log Message:
improved memory handing

File Contents

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