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

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.33 static const char RCSid[] = "$Id: rview.c,v 2.32 2009/12/12 19:01:00 greg Exp $";
3 greg 1.1 #endif
4     /*
5     * rview.c - routines and variables for interactive view generation.
6     *
7 greg 2.18 * External symbols declared in rpaint.h
8     */
9    
10 greg 2.19 #include "copyright.h"
11 greg 1.1
12 schorsch 2.20 #include <signal.h>
13     #include <ctype.h>
14    
15 greg 1.15 #include "ray.h"
16 greg 1.1 #include "rpaint.h"
17    
18 greg 2.8 #define CTRL(c) ((c)-'@')
19 greg 1.1
20    
21 greg 2.18 void
22 greg 2.32 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 greg 2.33 ray_pclose(0);
31     else if (!ray_pnprocs) /* in parent */
32     devclose();
33 greg 2.32 exit(code);
34     }
35    
36    
37     void
38 greg 2.29 devopen( /* open device driver */
39     char *dname
40     )
41 greg 1.1 {
42 greg 1.6 extern char *progname, *octname;
43 greg 1.7 char *id;
44 greg 2.29 int i;
45 greg 1.6
46 greg 1.7 id = octname!=NULL ? octname : progname;
47 greg 1.1 /* check device table */
48     for (i = 0; devtable[i].name; i++)
49 schorsch 2.23 if (!strcmp(dname, devtable[i].name)) {
50 greg 1.7 if ((dev = (*devtable[i].init)(dname, id)) == NULL) {
51 greg 1.1 sprintf(errmsg, "cannot initialize %s", dname);
52     error(USER, errmsg);
53     } else
54     return;
55 schorsch 2.23 }
56 greg 1.1 /* not there, try exec */
57 greg 1.7 if ((dev = comm_init(dname, id)) == NULL) {
58 greg 1.1 sprintf(errmsg, "cannot start device \"%s\"", dname);
59     error(USER, errmsg);
60     }
61     }
62    
63    
64 greg 2.18 void
65 greg 2.29 devclose(void) /* close our device */
66 greg 1.1 {
67     if (dev != NULL)
68     (*dev->close)();
69     dev = NULL;
70     }
71    
72    
73 greg 2.18 void
74 greg 2.29 printdevices(void) /* print list of output devices */
75 greg 1.1 {
76 greg 2.29 int i;
77 greg 1.1
78     for (i = 0; devtable[i].name; i++)
79     printf("%-16s # %s\n", devtable[i].name, devtable[i].descrip);
80     }
81    
82    
83 greg 2.18 void
84 greg 2.29 rview(void) /* do a view */
85 greg 1.1 {
86     char buf[32];
87    
88 greg 2.18 devopen(dvcname); /* open device */
89 greg 2.29 newimage(NULL); /* start image */
90 greg 1.14
91 greg 1.1 for ( ; ; ) { /* quit in command() */
92 greg 1.14 while (hresolu <= 1<<pdepth && vresolu <= 1<<pdepth)
93 greg 1.1 command("done: ");
94 greg 1.14 errno = 0;
95     if (hresolu <= psample<<pdepth && vresolu <= psample<<pdepth) {
96 greg 1.1 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 greg 2.29 refine(&ptrunk, pdepth+1);
103 greg 1.1 }
104 greg 2.29 if (dev->inpready) /* noticed some input */
105 greg 1.1 command(": ");
106 greg 1.14 else /* finished this depth */
107 greg 1.1 pdepth++;
108     }
109     }
110    
111    
112 greg 2.18 void
113 greg 2.29 command( /* get/execute command */
114     char *prompt
115     )
116 greg 1.1 {
117 greg 2.8 #define badcom(s) strncmp(s, inpbuf, args-inpbuf-1)
118 greg 1.1 char inpbuf[256];
119     char *args;
120     again:
121 greg 1.10 (*dev->comin)(inpbuf, prompt); /* get command + arguments */
122 greg 1.1 for (args = inpbuf; *args && *args != ' '; args++)
123     ;
124     if (*args) *args++ = '\0';
125     else *++args = '\0';
126 greg 2.30
127     if (waitrays() < 0) /* clear ray queue */
128     quit(1);
129 greg 1.1
130     switch (inpbuf[0]) {
131 greg 2.27 case 'f': /* new frame (|focus|free) */
132 greg 2.10 if (badcom("frame")) {
133 greg 2.27 if (badcom("focus")) {
134     if (badcom("free"))
135     goto commerr;
136     free_objmem();
137     break;
138     }
139     getfocus(args);
140 greg 2.10 break;
141     }
142 greg 1.1 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 greg 2.11 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 greg 1.1 break;
164     case 'e': /* exposure */
165     if (badcom("exposure"))
166     goto commerr;
167     getexposure(args);
168     break;
169     case 's': /* set a parameter */
170 greg 2.13 if (badcom("set")) {
171     #ifdef SIGTSTP
172     if (!badcom("stop"))
173     goto dostop;
174     #endif
175 greg 1.1 goto commerr;
176 greg 2.13 }
177 greg 1.1 setparam(args);
178     break;
179     case 'n': /* new picture */
180     if (badcom("new"))
181     goto commerr;
182 greg 2.29 newimage(args);
183 greg 1.1 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 greg 2.10 case 'm': /* move camera (or memstats) */
195 greg 1.1 if (badcom("move"))
196 greg 2.8 #ifdef MSTATS
197 greg 2.2 {
198     if (badcom("memory"))
199     goto commerr;
200     printmemstats(stderr);
201     break;
202     }
203     #else
204 greg 1.1 goto commerr;
205 greg 2.2 #endif
206 greg 1.1 getmove(args);
207     break;
208 greg 1.8 case 'r': /* rotate/repaint */
209     if (badcom("rotate")) {
210 greg 2.13 if (badcom("repaint")) {
211     if (badcom("redraw"))
212     goto commerr;
213     redraw();
214     break;
215     }
216 greg 1.8 getrepaint(args);
217     break;
218     }
219 greg 1.1 getrotate(args);
220     break;
221     case 'p': /* pivot view */
222 greg 2.13 if (badcom("pivot")) {
223     if (badcom("pause"))
224     goto commerr;
225     goto again;
226     }
227 greg 1.1 getpivot(args);
228     break;
229 greg 2.4 case CTRL('R'): /* redraw */
230 greg 1.1 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 greg 2.4 case CTRL('C'): /* interrupt */
242 greg 1.1 goto again;
243 greg 2.8 #ifdef SIGTSTP
244 greg 2.13 case CTRL('Z'):; /* stop */
245     dostop:
246 greg 1.1 devclose();
247     kill(0, SIGTSTP);
248     /* pc stops here */
249 greg 2.18 devopen(dvcname);
250 greg 1.1 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 greg 2.8 #undef badcom
266 greg 1.1 }
267    
268    
269 greg 2.18 void
270 greg 2.29 rsample(void) /* sample the image */
271 greg 1.1 {
272     int xsiz, ysiz, y;
273     PNODE *p;
274 greg 2.29 PNODE **pl;
275     int x;
276 greg 1.1 /*
277     * We initialize the bottom row in the image at our current
278 greg 2.8 * resolution. During sampling, we check super-pixels to the
279 greg 1.1 * 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 greg 2.12 xsiz = (((long)(pframe.r-pframe.l)<<pdepth)+hresolu-1) / hresolu;
284     ysiz = (((long)(pframe.u-pframe.d)<<pdepth)+vresolu-1) / vresolu;
285 greg 1.1 pl = (PNODE **)malloc(xsiz*sizeof(PNODE *));
286 greg 2.29 if (pl == NULL)
287 greg 1.14 return;
288 greg 1.1 /*
289     * Initialize the bottom row.
290     */
291 greg 2.29 pl[0] = findrect(pframe.l, pframe.d, &ptrunk, pdepth);
292 greg 1.1 for (x = 1; x < xsiz; x++) {
293 greg 1.9 pl[x] = findrect(pframe.l+((x*hresolu)>>pdepth),
294 greg 2.29 pframe.d, &ptrunk, pdepth);
295 greg 1.1 }
296     /* sample the image */
297     for (y = 0; /* y < ysiz */ ; y++) {
298     for (x = 0; x < xsiz-1; x++) {
299 greg 1.20 if (dev->inpready || errno == ENOMEM)
300 greg 1.1 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 greg 2.29 refine(pl[x], 1);
307     refine(pl[x+1], 1);
308 greg 1.1 }
309     }
310     if (y >= ysiz-1)
311     break;
312     for (x = 0; x < xsiz; x++) {
313 greg 1.20 if (dev->inpready || errno == ENOMEM)
314 greg 1.1 goto escape;
315     /*
316     * Find super-pixel at this position in next row.
317     */
318 greg 1.9 p = findrect(pframe.l+((x*hresolu)>>pdepth),
319     pframe.d+(((y+1)*vresolu)>>pdepth),
320 greg 2.29 &ptrunk, pdepth);
321 greg 1.1 /*
322     * Test super-pixel in next row.
323     */
324     if (pl[x] != p && bigdiff(pl[x]->v, p->v, maxdiff)) {
325 greg 2.29 refine(pl[x], 1);
326     refine(p, 1);
327 greg 1.1 }
328     /*
329     * Copy into super-pixel array.
330     */
331     pl[x] = p;
332     }
333     }
334     escape:
335 greg 2.18 free((void *)pl);
336 greg 1.1 }
337    
338    
339     int
340 greg 2.29 refine( /* refine a node */
341     PNODE *p,
342     int pd
343     )
344 greg 1.1 {
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 greg 2.29 mx = (p->xmin + p->xmax) >> 1;
356     my = (p->ymin + p->ymax) >> 1;
357 greg 1.1 growth = 0;
358    
359     if (p->kid == NULL) { /* subdivide */
360    
361     if ((p->kid = newptree()) == NULL)
362 greg 1.20 return(0);
363 greg 2.29
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 greg 1.1 /*
381     * The following paint order can leave a black pixel
382 greg 2.7 * if redraw() is called in (*dev->paintr)().
383 greg 1.1 */
384     if (p->x >= mx && p->y >= my)
385     pcopy(p, p->kid+UR);
386 greg 2.29 else if (paint(p->kid+UR) < 0)
387     quit(1);
388 greg 1.1 if (p->x < mx && p->y >= my)
389     pcopy(p, p->kid+UL);
390 greg 2.29 else if (paint(p->kid+UL) < 0)
391     quit(1);
392 greg 1.1 if (p->x >= mx && p->y < my)
393     pcopy(p, p->kid+DR);
394 greg 2.29 else if (paint(p->kid+DR) < 0)
395     quit(1);
396 greg 1.1 if (p->x < mx && p->y < my)
397     pcopy(p, p->kid+DL);
398 greg 2.29 else if (paint(p->kid+DL) < 0)
399     quit(1);
400 greg 1.1
401     growth++;
402     }
403     /* do children */
404     if (mx > pframe.l) {
405     if (my > pframe.d)
406 greg 2.29 growth += refine(p->kid+DL, pd-1);
407 greg 1.1 if (my < pframe.u)
408 greg 2.29 growth += refine(p->kid+UL, pd-1);
409 greg 1.1 }
410     if (mx < pframe.r) {
411     if (my > pframe.d)
412 greg 2.29 growth += refine(p->kid+DR, pd-1);
413 greg 1.1 if (my < pframe.u)
414 greg 2.29 growth += refine(p->kid+UR, pd-1);
415 greg 1.1 }
416     return(growth);
417     }