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 (17 hours, 21 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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: rview.c,v 2.37 2013/10/18 17:04:13 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 "paths.h"
17 #include "rpaint.h"
18
19 #define CTRL(c) ((c)-'@')
20
21
22 void
23 quit(code) /* quit program */
24 int code;
25 {
26 if (ray_pnprocs > 0) /* close children if any */
27 ray_pclose(0);
28 if (!ray_pnprocs) /* in parent */
29 devclose();
30 exit(code);
31 }
32
33
34 void
35 devopen( /* open device driver */
36 char *dname
37 )
38 {
39 extern char *octname;
40 char *id;
41 int i;
42
43 id = octname!=NULL ? octname : progname;
44 /* check device table */
45 for (i = 0; devtable[i].name; i++)
46 if (!strcmp(dname, devtable[i].name)) {
47 if ((dev = (*devtable[i].init)(dname, id)) == NULL) {
48 sprintf(errmsg, "cannot initialize %s", dname);
49 error(USER, errmsg);
50 } else
51 return;
52 }
53 /* not there, try exec */
54 if ((dev = comm_init(dname, id)) == NULL) {
55 sprintf(errmsg, "cannot start device \"%s\"", dname);
56 error(USER, errmsg);
57 }
58 }
59
60
61 void
62 devclose(void) /* close our device */
63 {
64 if (dev != NULL)
65 (*dev->close)();
66 dev = NULL;
67 }
68
69
70 void
71 printdevices(void) /* print list of output devices */
72 {
73 int i;
74
75 for (i = 0; devtable[i].name; i++)
76 printf("%-16s # %s\n", devtable[i].name, devtable[i].descrip);
77 }
78
79
80 void
81 rview(void) /* do a view */
82 {
83 char buf[32];
84
85 devopen(dvcname); /* open device */
86 newimage(NULL); /* start image */
87
88 for ( ; ; ) { /* quit in command() */
89 while (hresolu <= 1<<pdepth && vresolu <= 1<<pdepth)
90 command("done: ");
91 errno = 0;
92 if (hresolu <= psample<<pdepth && vresolu <= psample<<pdepth) {
93 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 refine(&ptrunk, pdepth+1);
100 }
101 if (dev->inpready) /* noticed some input */
102 command(": ");
103 else /* finished this depth */
104 pdepth++;
105 }
106 }
107
108
109 void
110 command( /* get/execute command */
111 char *prompt
112 )
113 {
114 #define badcom(s) strncmp(s, inpbuf, args-inpbuf-1)
115 char inpbuf[256];
116 char *args;
117 again:
118 (*dev->comin)(inpbuf, prompt); /* get command + arguments */
119 for (args = inpbuf; *args && *args != ' '; args++)
120 ;
121 if (*args) *args++ = '\0';
122 else *++args = '\0';
123
124 if (waitrays() < 0) /* clear ray queue */
125 quit(1);
126
127 switch (inpbuf[0]) {
128 case 'f': /* new frame (|focus|free) */
129 if (badcom("frame")) {
130 if (badcom("focus")) {
131 if (badcom("free"))
132 goto commerr;
133 free_objmem();
134 break;
135 }
136 getfocus(args);
137 break;
138 }
139 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 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 break;
161 case 'e': /* exposure */
162 if (badcom("exposure"))
163 goto commerr;
164 getexposure(args);
165 break;
166 case 's': /* set a parameter */
167 if (badcom("set")) {
168 #ifdef SIGTSTP
169 if (!badcom("stop"))
170 goto dostop;
171 #endif
172 goto commerr;
173 }
174 setparam(args);
175 break;
176 case 'n': /* new picture */
177 if (badcom("new"))
178 goto commerr;
179 newimage(args);
180 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 case 'm': /* move camera (or memstats) */
192 if (badcom("move"))
193 goto commerr;
194 getmove(args);
195 break;
196 case 'r': /* rotate/repaint */
197 if (badcom("rotate")) {
198 if (badcom("repaint")) {
199 if (badcom("redraw"))
200 goto commerr;
201 redraw();
202 break;
203 }
204 getrepaint(args);
205 break;
206 }
207 getrotate(args);
208 break;
209 case 'p': /* pivot view */
210 if (badcom("pivot")) {
211 if (badcom("pause"))
212 goto commerr;
213 goto again;
214 }
215 getpivot(args);
216 break;
217 case 'o': /* origin view */
218 if (badcom("origin"))
219 goto commerr;
220 getorigin(args);
221 break;
222 case CTRL('R'): /* redraw */
223 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 case CTRL('C'): /* interrupt */
235 goto again;
236 #ifdef SIGTSTP
237 case CTRL('Z'):; /* stop */
238 dostop:
239 devclose();
240 kill(0, SIGTSTP);
241 /* pc stops here */
242 devopen(dvcname);
243 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 if (newparam && ray_pnprocs) /* drop into immediate mode */
259 ray_pclose(0);
260 #undef badcom
261 }
262
263
264 void
265 rsample(void) /* sample the image */
266 {
267 int xsiz, ysiz, y;
268 PNODE *p;
269 PNODE **pl;
270 int x;
271 /*
272 * We initialize the bottom row in the image at our current
273 * resolution. During sampling, we check super-pixels to the
274 * 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 xsiz = (((long)(pframe.r-pframe.l)<<pdepth)+hresolu-1) / hresolu;
279 ysiz = (((long)(pframe.u-pframe.d)<<pdepth)+vresolu-1) / vresolu;
280 pl = (PNODE **)malloc(xsiz*sizeof(PNODE *));
281 if (pl == NULL)
282 return;
283 /*
284 * Initialize the bottom row.
285 */
286 pl[0] = findrect(pframe.l, pframe.d, &ptrunk, pdepth);
287 for (x = 1; x < xsiz; x++) {
288 pl[x] = findrect(pframe.l+((x*hresolu)>>pdepth),
289 pframe.d, &ptrunk, pdepth);
290 }
291 /* sample the image */
292 for (y = 0; /* y < ysiz */ ; y++) {
293 for (x = 0; x < xsiz-1; x++) {
294 if (dev->inpready)
295 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 refine(pl[x], 1);
302 refine(pl[x+1], 1);
303 }
304 }
305 if (y >= ysiz-1)
306 break;
307 for (x = 0; x < xsiz; x++) {
308 if (dev->inpready)
309 goto escape;
310 /*
311 * Find super-pixel at this position in next row.
312 */
313 p = findrect(pframe.l+((x*hresolu)>>pdepth),
314 pframe.d+(((y+1)*vresolu)>>pdepth),
315 &ptrunk, pdepth);
316 /*
317 * Test super-pixel in next row.
318 */
319 if (pl[x] != p && bigdiff(pl[x]->v, p->v, maxdiff)) {
320 refine(pl[x], 1);
321 refine(p, 1);
322 }
323 /*
324 * Copy into super-pixel array.
325 */
326 pl[x] = p;
327 }
328 }
329 escape:
330 free((void *)pl);
331 }
332
333
334 int
335 refine( /* refine a node */
336 PNODE *p,
337 int pd
338 )
339 {
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 mx = (p->xmin + p->xmax) >> 1;
350 my = (p->ymin + p->ymax) >> 1;
351 growth = 0;
352
353 if (p->kid == NULL) { /* subdivide */
354
355 if ((p->kid = newptree()) == NULL)
356 return(0);
357
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 /*
375 * The following paint order can leave a black pixel
376 * if redraw() is called in (*dev->paintr)().
377 */
378 if (p->x >= mx && p->y >= my)
379 pcopy(p, p->kid+UR);
380 else if (paint(p->kid+UR) < 0)
381 quit(1);
382 if (p->x < mx && p->y >= my)
383 pcopy(p, p->kid+UL);
384 else if (paint(p->kid+UL) < 0)
385 quit(1);
386 if (p->x >= mx && p->y < my)
387 pcopy(p, p->kid+DR);
388 else if (paint(p->kid+DR) < 0)
389 quit(1);
390 if (p->x < mx && p->y < my)
391 pcopy(p, p->kid+DL);
392 else if (paint(p->kid+DL) < 0)
393 quit(1);
394
395 growth++;
396 }
397 /* do children */
398 if (mx > pframe.l) {
399 if (my > pframe.d)
400 growth += refine(p->kid+DL, pd-1);
401 if (my < pframe.u)
402 growth += refine(p->kid+UL, pd-1);
403 }
404 if (mx < pframe.r) {
405 if (my > pframe.d)
406 growth += refine(p->kid+DR, pd-1);
407 if (my < pframe.u)
408 growth += refine(p->kid+UR, pd-1);
409 }
410 return(growth);
411 }