ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rview.c
Revision: 2.31
Committed: Fri Sep 5 19:45:42 2008 UTC (15 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.30: +1 -8 lines
Log Message:
Fixed bug that broke "exposure" command

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rview.c,v 2.30 2008/08/22 17:39:26 greg Exp $";
3 #endif
4 /*
5 * rview.c - routines and variables for interactive view generation.
6 *
7 * External symbols declared in rpaint.h
8 */
9
10 #include "copyright.h"
11
12 #include <signal.h>
13 #include <ctype.h>
14
15 #include "ray.h"
16 #include "rpaint.h"
17
18 #define CTRL(c) ((c)-'@')
19
20
21 void
22 devopen( /* open device driver */
23 char *dname
24 )
25 {
26 extern char *progname, *octname;
27 char *id;
28 int i;
29
30 id = octname!=NULL ? octname : progname;
31 /* check device table */
32 for (i = 0; devtable[i].name; i++)
33 if (!strcmp(dname, devtable[i].name)) {
34 if ((dev = (*devtable[i].init)(dname, id)) == NULL) {
35 sprintf(errmsg, "cannot initialize %s", dname);
36 error(USER, errmsg);
37 } else
38 return;
39 }
40 /* not there, try exec */
41 if ((dev = comm_init(dname, id)) == NULL) {
42 sprintf(errmsg, "cannot start device \"%s\"", dname);
43 error(USER, errmsg);
44 }
45 }
46
47
48 void
49 devclose(void) /* close our device */
50 {
51 if (dev != NULL)
52 (*dev->close)();
53 dev = NULL;
54 }
55
56
57 void
58 printdevices(void) /* print list of output devices */
59 {
60 int i;
61
62 for (i = 0; devtable[i].name; i++)
63 printf("%-16s # %s\n", devtable[i].name, devtable[i].descrip);
64 }
65
66
67 void
68 rview(void) /* do a view */
69 {
70 char buf[32];
71
72 devopen(dvcname); /* open device */
73 newimage(NULL); /* start image */
74
75 for ( ; ; ) { /* quit in command() */
76 while (hresolu <= 1<<pdepth && vresolu <= 1<<pdepth)
77 command("done: ");
78 errno = 0;
79 if (hresolu <= psample<<pdepth && vresolu <= psample<<pdepth) {
80 sprintf(buf, "%d sampling...\n", 1<<pdepth);
81 (*dev->comout)(buf);
82 rsample();
83 } else {
84 sprintf(buf, "%d refining...\n", 1<<pdepth);
85 (*dev->comout)(buf);
86 refine(&ptrunk, pdepth+1);
87 }
88 if (dev->inpready) /* noticed some input */
89 command(": ");
90 else /* finished this depth */
91 pdepth++;
92 }
93 }
94
95
96 void
97 command( /* get/execute command */
98 char *prompt
99 )
100 {
101 #define badcom(s) strncmp(s, inpbuf, args-inpbuf-1)
102 char inpbuf[256];
103 char *args;
104 again:
105 (*dev->comin)(inpbuf, prompt); /* get command + arguments */
106 for (args = inpbuf; *args && *args != ' '; args++)
107 ;
108 if (*args) *args++ = '\0';
109 else *++args = '\0';
110
111 if (waitrays() < 0) /* clear ray queue */
112 quit(1);
113
114 switch (inpbuf[0]) {
115 case 'f': /* new frame (|focus|free) */
116 if (badcom("frame")) {
117 if (badcom("focus")) {
118 if (badcom("free"))
119 goto commerr;
120 free_objmem();
121 break;
122 }
123 getfocus(args);
124 break;
125 }
126 getframe(args);
127 break;
128 case 'v': /* view */
129 if (badcom("view"))
130 goto commerr;
131 getview(args);
132 break;
133 case 'l': /* last view */
134 if (badcom("last"))
135 goto commerr;
136 lastview(args);
137 break;
138 case 'V': /* save view */
139 if (badcom("V"))
140 goto commerr;
141 saveview(args);
142 break;
143 case 'L': /* load view */
144 if (badcom("L"))
145 goto commerr;
146 loadview(args);
147 break;
148 case 'e': /* exposure */
149 if (badcom("exposure"))
150 goto commerr;
151 getexposure(args);
152 break;
153 case 's': /* set a parameter */
154 if (badcom("set")) {
155 #ifdef SIGTSTP
156 if (!badcom("stop"))
157 goto dostop;
158 #endif
159 goto commerr;
160 }
161 setparam(args);
162 break;
163 case 'n': /* new picture */
164 if (badcom("new"))
165 goto commerr;
166 newimage(args);
167 break;
168 case 't': /* trace a ray */
169 if (badcom("trace"))
170 goto commerr;
171 traceray(args);
172 break;
173 case 'a': /* aim camera */
174 if (badcom("aim"))
175 goto commerr;
176 getaim(args);
177 break;
178 case 'm': /* move camera (or memstats) */
179 if (badcom("move"))
180 #ifdef MSTATS
181 {
182 if (badcom("memory"))
183 goto commerr;
184 printmemstats(stderr);
185 break;
186 }
187 #else
188 goto commerr;
189 #endif
190 getmove(args);
191 break;
192 case 'r': /* rotate/repaint */
193 if (badcom("rotate")) {
194 if (badcom("repaint")) {
195 if (badcom("redraw"))
196 goto commerr;
197 redraw();
198 break;
199 }
200 getrepaint(args);
201 break;
202 }
203 getrotate(args);
204 break;
205 case 'p': /* pivot view */
206 if (badcom("pivot")) {
207 if (badcom("pause"))
208 goto commerr;
209 goto again;
210 }
211 getpivot(args);
212 break;
213 case CTRL('R'): /* redraw */
214 redraw();
215 break;
216 case 'w': /* write */
217 if (badcom("write"))
218 goto commerr;
219 writepict(args);
220 break;
221 case 'q': /* quit */
222 if (badcom("quit"))
223 goto commerr;
224 quit(0);
225 case CTRL('C'): /* interrupt */
226 goto again;
227 #ifdef SIGTSTP
228 case CTRL('Z'):; /* stop */
229 dostop:
230 devclose();
231 kill(0, SIGTSTP);
232 /* pc stops here */
233 devopen(dvcname);
234 redraw();
235 break;
236 #endif
237 case '\0': /* continue */
238 break;
239 default:;
240 commerr:
241 if (iscntrl(inpbuf[0]))
242 sprintf(errmsg, "^%c: unknown control",
243 inpbuf[0]|0100);
244 else
245 sprintf(errmsg, "%s: unknown command", inpbuf);
246 error(COMMAND, errmsg);
247 break;
248 }
249 #undef badcom
250 }
251
252
253 void
254 rsample(void) /* sample the image */
255 {
256 int xsiz, ysiz, y;
257 PNODE *p;
258 PNODE **pl;
259 int x;
260 /*
261 * We initialize the bottom row in the image at our current
262 * resolution. During sampling, we check super-pixels to the
263 * right and above by calling bigdiff(). If there is a significant
264 * difference, we subsample the super-pixels. The testing process
265 * includes initialization of the next row.
266 */
267 xsiz = (((long)(pframe.r-pframe.l)<<pdepth)+hresolu-1) / hresolu;
268 ysiz = (((long)(pframe.u-pframe.d)<<pdepth)+vresolu-1) / vresolu;
269 pl = (PNODE **)malloc(xsiz*sizeof(PNODE *));
270 if (pl == NULL)
271 return;
272 /*
273 * Initialize the bottom row.
274 */
275 pl[0] = findrect(pframe.l, pframe.d, &ptrunk, pdepth);
276 for (x = 1; x < xsiz; x++) {
277 pl[x] = findrect(pframe.l+((x*hresolu)>>pdepth),
278 pframe.d, &ptrunk, pdepth);
279 }
280 /* sample the image */
281 for (y = 0; /* y < ysiz */ ; y++) {
282 for (x = 0; x < xsiz-1; x++) {
283 if (dev->inpready || errno == ENOMEM)
284 goto escape;
285 /*
286 * Test super-pixel to the right.
287 */
288 if (pl[x] != pl[x+1] && bigdiff(pl[x]->v,
289 pl[x+1]->v, maxdiff)) {
290 refine(pl[x], 1);
291 refine(pl[x+1], 1);
292 }
293 }
294 if (y >= ysiz-1)
295 break;
296 for (x = 0; x < xsiz; x++) {
297 if (dev->inpready || errno == ENOMEM)
298 goto escape;
299 /*
300 * Find super-pixel at this position in next row.
301 */
302 p = findrect(pframe.l+((x*hresolu)>>pdepth),
303 pframe.d+(((y+1)*vresolu)>>pdepth),
304 &ptrunk, pdepth);
305 /*
306 * Test super-pixel in next row.
307 */
308 if (pl[x] != p && bigdiff(pl[x]->v, p->v, maxdiff)) {
309 refine(pl[x], 1);
310 refine(p, 1);
311 }
312 /*
313 * Copy into super-pixel array.
314 */
315 pl[x] = p;
316 }
317 }
318 escape:
319 free((void *)pl);
320 }
321
322
323 int
324 refine( /* refine a node */
325 PNODE *p,
326 int pd
327 )
328 {
329 int growth;
330 int mx, my;
331 int i;
332
333 if (dev->inpready) /* quit for input */
334 return(0);
335
336 if (pd <= 0) /* depth limit */
337 return(0);
338
339 mx = (p->xmin + p->xmax) >> 1;
340 my = (p->ymin + p->ymax) >> 1;
341 growth = 0;
342
343 if (p->kid == NULL) { /* subdivide */
344
345 if ((p->kid = newptree()) == NULL)
346 return(0);
347
348 p->kid[UR].xmin = mx;
349 p->kid[UR].ymin = my;
350 p->kid[UR].xmax = p->xmax;
351 p->kid[UR].ymax = p->ymax;
352 p->kid[UL].xmin = p->xmin;
353 p->kid[UL].ymin = my;
354 p->kid[UL].xmax = mx;
355 p->kid[UL].ymax = p->ymax;
356 p->kid[DR].xmin = mx;
357 p->kid[DR].ymin = p->ymin;
358 p->kid[DR].xmax = p->xmax;
359 p->kid[DR].ymax = my;
360 p->kid[DL].xmin = p->xmin;
361 p->kid[DL].ymin = p->ymin;
362 p->kid[DL].xmax = mx;
363 p->kid[DL].ymax = my;
364 /*
365 * The following paint order can leave a black pixel
366 * if redraw() is called in (*dev->paintr)().
367 */
368 if (p->x >= mx && p->y >= my)
369 pcopy(p, p->kid+UR);
370 else if (paint(p->kid+UR) < 0)
371 quit(1);
372 if (p->x < mx && p->y >= my)
373 pcopy(p, p->kid+UL);
374 else if (paint(p->kid+UL) < 0)
375 quit(1);
376 if (p->x >= mx && p->y < my)
377 pcopy(p, p->kid+DR);
378 else if (paint(p->kid+DR) < 0)
379 quit(1);
380 if (p->x < mx && p->y < my)
381 pcopy(p, p->kid+DL);
382 else if (paint(p->kid+DL) < 0)
383 quit(1);
384
385 growth++;
386 }
387 /* do children */
388 if (mx > pframe.l) {
389 if (my > pframe.d)
390 growth += refine(p->kid+DL, pd-1);
391 if (my < pframe.u)
392 growth += refine(p->kid+UL, pd-1);
393 }
394 if (mx < pframe.r) {
395 if (my > pframe.d)
396 growth += refine(p->kid+DR, pd-1);
397 if (my < pframe.u)
398 growth += refine(p->kid+UR, pd-1);
399 }
400 return(growth);
401 }