ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rpict.c
Revision: 1.10
Committed: Tue Oct 3 12:17:09 1989 UTC (34 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.9: +38 -27 lines
Log Message:
Fixed routines to render only desired pixels

File Contents

# User Rev Content
1 greg 1.1 /* Copyright (c) 1986 Regents of the University of California */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * rpict.c - routines and variables for picture generation.
9     *
10     * 8/14/85
11     */
12    
13     #include "ray.h"
14    
15     #ifdef BSD
16     #include <sys/time.h>
17     #include <sys/resource.h>
18     #endif
19    
20     #include "view.h"
21    
22     #include "random.h"
23    
24     VIEW ourview = STDVIEW(512); /* view parameters */
25    
26     int psample = 4; /* pixel sample size */
27     double maxdiff = .05; /* max. difference for interpolation */
28 greg 1.3 double dstrpix = 0.67; /* square pixel distribution */
29 greg 1.1
30     double dstrsrc = 0.0; /* square source distribution */
31 greg 1.4 double shadthresh = .05; /* shadow threshold */
32 greg 1.5 double shadcert = .5; /* shadow certainty */
33 greg 1.1
34     int maxdepth = 6; /* maximum recursion depth */
35     double minweight = 5e-3; /* minimum ray weight */
36    
37     COLOR ambval = BLKCOLOR; /* ambient value */
38     double ambacc = 0.2; /* ambient accuracy */
39 greg 1.6 int ambres = 32; /* ambient resolution */
40 greg 1.1 int ambdiv = 128; /* ambient divisions */
41     int ambssamp = 0; /* ambient super-samples */
42     int ambounce = 0; /* ambient bounces */
43     char *amblist[128]; /* ambient include/exclude list */
44     int ambincl = -1; /* include == 1, exclude == 0 */
45    
46     int ralrm = 0; /* seconds between reports */
47    
48     double pctdone = 0.0; /* percentage done */
49    
50     extern long nrays; /* number of rays traced */
51    
52     #define MAXDIV 32 /* maximum sample size */
53    
54     #define pixjitter() (.5+dstrpix*(.5-frandom()))
55    
56    
57     quit(code) /* quit program */
58     int code;
59     {
60     if (code || ralrm > 0) /* report status */
61     report();
62    
63     exit(code);
64     }
65    
66    
67     report() /* report progress */
68     {
69     #ifdef BSD
70     struct rusage rubuf;
71     double t;
72    
73     getrusage(RUSAGE_SELF, &rubuf);
74     t = (rubuf.ru_utime.tv_usec + rubuf.ru_stime.tv_usec) / 1e6;
75     t += rubuf.ru_utime.tv_sec + rubuf.ru_stime.tv_sec;
76     getrusage(RUSAGE_CHILDREN, &rubuf);
77     t += (rubuf.ru_utime.tv_usec + rubuf.ru_stime.tv_usec) / 1e6;
78     t += rubuf.ru_utime.tv_sec + rubuf.ru_stime.tv_sec;
79    
80     sprintf(errmsg, "%ld rays, %4.2f%% done after %5.4f CPU hours\n",
81     nrays, pctdone, t/3600.0);
82     #else
83     sprintf(errmsg, "%ld rays, %4.2f%% done\n", nrays, pctdone);
84     #endif
85     eputs(errmsg);
86    
87     if (ralrm > 0)
88     alarm(ralrm);
89     }
90    
91    
92     render(oldfile) /* render the scene */
93     char *oldfile;
94     {
95     COLOR *scanbar[MAXDIV+1]; /* scanline arrays of pixel values */
96     int ypos; /* current scanline */
97     COLOR *colptr;
98     register int i;
99 greg 1.10 /* check sampling */
100     if (psample < 1)
101 greg 1.1 psample = 1;
102 greg 1.10 else if (psample > MAXDIV)
103     psample = MAXDIV;
104 greg 1.9 /* allocate scanlines */
105 greg 1.1 for (i = 0; i <= psample; i++) {
106 greg 1.10 scanbar[i] = (COLOR *)malloc(ourview.hresolu*sizeof(COLOR));
107 greg 1.1 if (scanbar[i] == NULL)
108     error(SYSTEM, "out of memory in render");
109     }
110     /* write out boundaries */
111 greg 1.9 fputresolu(YMAJOR|YDECR, ourview.hresolu, ourview.vresolu, stdout);
112 greg 1.10 /* recover file and compute first */
113     ypos = ourview.vresolu-1 - salvage(oldfile);
114     fillscanline(scanbar[0], ourview.hresolu, ypos, psample);
115     /* compute scanlines */
116     for (ypos -= psample; ypos >= 0; ypos -= psample) {
117 greg 1.1
118 greg 1.10 pctdone = 100.0*(ourview.vresolu-ypos-psample)/ourview.vresolu;
119 greg 1.9
120     colptr = scanbar[psample]; /* move base to top */
121 greg 1.1 scanbar[psample] = scanbar[0];
122     scanbar[0] = colptr;
123 greg 1.10 /* fill base line */
124     fillscanline(scanbar[0], ourview.hresolu, ypos, psample);
125     /* fill bar */
126     fillscanbar(scanbar, ourview.hresolu, ypos, psample);
127     /* write it out */
128     for (i = psample; i > 0; i--)
129 greg 1.9 if (fwritescan(scanbar[i], ourview.hresolu, stdout) < 0)
130 greg 1.1 goto writerr;
131     if (fflush(stdout) == EOF)
132     goto writerr;
133     }
134 greg 1.10 /* compute residual */
135     colptr = scanbar[psample];
136     scanbar[psample] = scanbar[0];
137     scanbar[0] = colptr;
138     if (ypos > -psample) {
139     fillscanline(scanbar[-ypos], ourview.hresolu,
140     0, psample);
141     fillscanbar(scanbar-ypos, ourview.hresolu,
142     0, psample+ypos);
143     }
144     for (i = psample; i+ypos >= 0; i--)
145     if (fwritescan(scanbar[i], ourview.hresolu, stdout) < 0)
146     goto writerr;
147     if (fflush(stdout) == EOF)
148     goto writerr;
149 greg 1.9 pctdone = 100.0;
150 greg 1.10 /* free scanlines */
151 greg 1.1 for (i = 0; i <= psample; i++)
152     free((char *)scanbar[i]);
153     return;
154     writerr:
155     error(SYSTEM, "write error in render");
156     }
157    
158    
159 greg 1.9 fillscanline(scanline, xres, y, xstep) /* fill scan line at y */
160 greg 1.1 register COLOR *scanline;
161 greg 1.9 int xres, y, xstep;
162 greg 1.1 {
163     int b = xstep;
164     register int i;
165    
166     pixvalue(scanline[0], 0, y);
167    
168 greg 1.9 for (i = xstep; i < xres; i += xstep) {
169 greg 1.1
170     pixvalue(scanline[i], i, y);
171    
172     b = fillsample(scanline+i-xstep, i-xstep, y, xstep, 0, b/2);
173 greg 1.10 }
174     if (i-xstep < xres-1) {
175     pixvalue(scanline[xres-1], xres-1, y);
176     fillsample(scanline+i-xstep, i-xstep, y,
177     xres-1-(i-xstep), 0, b/2);
178 greg 1.1 }
179     }
180    
181    
182 greg 1.9 fillscanbar(scanbar, xres, y, ysize) /* fill interior */
183 greg 1.1 register COLOR *scanbar[];
184 greg 1.9 int xres, y, ysize;
185 greg 1.1 {
186     COLOR vline[MAXDIV+1];
187     int b = ysize;
188     register int i, j;
189    
190 greg 1.8 for (i = 0; i < xres; i++) {
191 greg 1.1
192     copycolor(vline[0], scanbar[0][i]);
193     copycolor(vline[ysize], scanbar[ysize][i]);
194    
195     b = fillsample(vline, i, y, 0, ysize, b/2);
196    
197     for (j = 1; j < ysize; j++)
198     copycolor(scanbar[j][i], vline[j]);
199     }
200     }
201    
202    
203     int
204     fillsample(colline, x, y, xlen, ylen, b) /* fill interior points */
205     register COLOR *colline;
206     int x, y;
207     int xlen, ylen;
208     int b;
209     {
210     double ratio;
211     COLOR ctmp;
212     int ncut;
213     register int len;
214    
215     if (xlen > 0) /* x or y length is zero */
216     len = xlen;
217     else
218     len = ylen;
219    
220     if (len <= 1) /* limit recursion */
221     return(0);
222    
223     if (b > 0 || bigdiff(colline[0], colline[len], maxdiff)) {
224    
225     pixvalue(colline[len>>1], x + (xlen>>1), y + (ylen>>1));
226     ncut = 1;
227    
228     } else { /* interpolate */
229    
230     copycolor(colline[len>>1], colline[len]);
231     ratio = (double)(len>>1) / len;
232     scalecolor(colline[len>>1], ratio);
233     copycolor(ctmp, colline[0]);
234     ratio = 1.0 - ratio;
235     scalecolor(ctmp, ratio);
236     addcolor(colline[len>>1], ctmp);
237     ncut = 0;
238     }
239     /* recurse */
240     ncut += fillsample(colline, x, y, xlen>>1, ylen>>1, (b-1)/2);
241    
242     ncut += fillsample(colline + (len>>1), x + (xlen>>1), y + (ylen>>1),
243     xlen - (xlen>>1), ylen - (ylen>>1), b/2);
244    
245     return(ncut);
246     }
247    
248    
249     pixvalue(col, x, y) /* compute pixel value */
250     COLOR col; /* returned color */
251     int x, y; /* pixel position */
252     {
253     static RAY thisray; /* our ray for this pixel */
254    
255     rayview(thisray.rorg, thisray.rdir, &ourview,
256     x + pixjitter(), y + pixjitter());
257    
258     rayorigin(&thisray, NULL, PRIMARY, 1.0);
259    
260     rayvalue(&thisray); /* trace ray */
261    
262     copycolor(col, thisray.rcol); /* return color */
263     }
264    
265    
266     int
267     salvage(oldfile) /* salvage scanlines from killed program */
268     char *oldfile;
269     {
270     COLR *scanline;
271     FILE *fp;
272     int x, y;
273    
274     if (oldfile == NULL)
275     return(0);
276 greg 1.9
277     if ((fp = fopen(oldfile, "r")) == NULL) {
278 greg 1.1 sprintf(errmsg, "cannot open recover file \"%s\"", oldfile);
279     error(WARNING, errmsg);
280     return(0);
281     }
282     /* discard header */
283     getheader(fp, NULL);
284     /* get picture size */
285 greg 1.7 if (fgetresolu(&x, &y, fp) != (YMAJOR|YDECR)) {
286 greg 1.2 sprintf(errmsg, "bad recover file \"%s\"", oldfile);
287     error(WARNING, errmsg);
288 greg 1.1 fclose(fp);
289     return(0);
290     }
291    
292 greg 1.9 if (x != ourview.hresolu || y != ourview.vresolu) {
293 greg 1.1 sprintf(errmsg, "resolution mismatch in recover file \"%s\"",
294     oldfile);
295     error(USER, errmsg);
296     }
297    
298 greg 1.9 scanline = (COLR *)malloc(ourview.hresolu*sizeof(COLR));
299 greg 1.1 if (scanline == NULL)
300     error(SYSTEM, "out of memory in salvage");
301 greg 1.9 for (y = 0; y < ourview.vresolu; y++) {
302     if (freadcolrs(scanline, ourview.hresolu, fp) < 0)
303 greg 1.1 break;
304 greg 1.9 if (fwritecolrs(scanline, ourview.hresolu, stdout) < 0)
305 greg 1.1 goto writerr;
306     }
307     if (fflush(stdout) == EOF)
308     goto writerr;
309     free((char *)scanline);
310     fclose(fp);
311     unlink(oldfile);
312     return(y);
313     writerr:
314     error(SYSTEM, "write error in salvage");
315     }