ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rview.c
Revision: 2.37
Committed: Fri Oct 18 17:04:13 2013 UTC (10 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, rad5R2, rad4R2P2, rad5R0, rad5R1, rad4R2, rad4R2P1, rad5R3, HEAD
Changes since 2.36: +6 -1 lines
Log Message:
Added rvu "origin" command requested by John M.

File Contents

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