ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rview.c
Revision: 2.33
Committed: Sat Dec 12 23:08:13 2009 UTC (14 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R0
Changes since 2.32: +4 -3 lines
Log Message:
Bug fixes and performance improvements to rtrace -n option

File Contents

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