ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rview.c
Revision: 2.38
Committed: Sat Jun 7 05:09:46 2025 UTC (18 hours, 32 minutes ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.37: +3 -2 lines
Log Message:
refactor: Put some declarations into "paths.h" and included in "platform.h"

File Contents

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