ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rview.c
Revision: 2.29
Committed: Thu Aug 21 07:05:59 2008 UTC (15 years, 8 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.28: +64 -172 lines
Log Message:
Added -n option to rvu for multiple rendering processes

File Contents

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