ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rview.c
Revision: 2.32
Committed: Sat Dec 12 19:01:00 2009 UTC (14 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.31: +16 -1 lines
Log Message:
Added -n option to rtrace and moved quit() funciton out of raypcalls

File Contents

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