ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rpict.c
Revision: 1.25
Committed: Tue May 21 17:41:35 1991 UTC (32 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.24: +9 -2 lines
Log Message:
added stratified random sampling with urand

File Contents

# Content
1 /* Copyright (c) 1991 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 #else
19 #include <signal.h>
20 #endif
21 #include <fcntl.h>
22
23 #include "view.h"
24
25 #include "random.h"
26
27 int dimlist[MAXDIM]; /* sampling dimensions */
28 int ndims = 0; /* number of sampling dimensions */
29 int samplendx; /* sample index number */
30
31 VIEW ourview = STDVIEW; /* view parameters */
32 int hresolu = 512; /* horizontal resolution */
33 int vresolu = 512; /* vertical resolution */
34 double pixaspect = 1.0; /* pixel aspect ratio */
35
36 int psample = 4; /* pixel sample size */
37 double maxdiff = .05; /* max. difference for interpolation */
38 double dstrpix = 0.67; /* square pixel distribution */
39 int psuper = 2; /* pixel super-sampling rate */
40
41 double dstrsrc = 0.0; /* square source distribution */
42 double shadthresh = .05; /* shadow threshold */
43 double shadcert = .5; /* shadow certainty */
44
45 int maxdepth = 6; /* maximum recursion depth */
46 double minweight = 5e-3; /* minimum ray weight */
47
48 COLOR ambval = BLKCOLOR; /* ambient value */
49 double ambacc = 0.2; /* ambient accuracy */
50 int ambres = 32; /* ambient resolution */
51 int ambdiv = 128; /* ambient divisions */
52 int ambssamp = 0; /* ambient super-samples */
53 int ambounce = 0; /* ambient bounces */
54 char *amblist[128]; /* ambient include/exclude list */
55 int ambincl = -1; /* include == 1, exclude == 0 */
56
57 int ralrm = 0; /* seconds between reports */
58
59 double pctdone = 0.0; /* percentage done */
60
61 long tlastrept = 0L; /* time at last report */
62
63 extern long time();
64 extern long tstart; /* starting time */
65
66 extern long nrays; /* number of rays traced */
67
68 #define MAXDIV 32 /* maximum sample size */
69
70 #define pixjitter() (.5+dstrpix*(.5-frandom()))
71
72 double pixvalue();
73
74
75 quit(code) /* quit program */
76 int code;
77 {
78 if (code || ralrm > 0) /* report status */
79 report();
80
81 exit(code);
82 }
83
84
85 #ifdef BSD
86 report() /* report progress */
87 {
88 struct rusage rubuf;
89 double t;
90
91 getrusage(RUSAGE_SELF, &rubuf);
92 t = (rubuf.ru_utime.tv_usec + rubuf.ru_stime.tv_usec) / 1e6;
93 t += rubuf.ru_utime.tv_sec + rubuf.ru_stime.tv_sec;
94 getrusage(RUSAGE_CHILDREN, &rubuf);
95 t += (rubuf.ru_utime.tv_usec + rubuf.ru_stime.tv_usec) / 1e6;
96 t += rubuf.ru_utime.tv_sec + rubuf.ru_stime.tv_sec;
97
98 sprintf(errmsg, "%ld rays, %4.2f%% done after %5.4f CPU hours\n",
99 nrays, pctdone, t/3600.0);
100 eputs(errmsg);
101 tlastrept = time((long *)0);
102 }
103 #else
104 report() /* report progress */
105 {
106 signal(SIGALRM, report);
107 tlastrept = time((long *)0);
108 sprintf(errmsg, "%ld rays, %4.2f%% done after %5.4f hours\n",
109 nrays, pctdone, (tlastrept-tstart)/3600.0);
110 eputs(errmsg);
111 }
112 #endif
113
114
115 render(zfile, oldfile) /* render the scene */
116 char *zfile, *oldfile;
117 {
118 extern long lseek();
119 COLOR *scanbar[MAXDIV+1]; /* scanline arrays of pixel values */
120 float *zbar[MAXDIV+1]; /* z values */
121 int ypos; /* current scanline */
122 int ystep; /* current y step size */
123 int zfd;
124 COLOR *colptr;
125 float *zptr;
126 register int i;
127 /* check sampling */
128 if (psample < 1)
129 psample = 1;
130 else if (psample > MAXDIV)
131 psample = MAXDIV;
132 /* allocate scanlines */
133 for (i = 0; i <= psample; i++) {
134 scanbar[i] = (COLOR *)malloc(hresolu*sizeof(COLOR));
135 if (scanbar[i] == NULL)
136 goto memerr;
137 }
138 /* open z file */
139 if (zfile != NULL) {
140 if ((zfd = open(zfile, O_WRONLY|O_CREAT, 0666)) == -1) {
141 sprintf(errmsg, "cannot open z file \"%s\"", zfile);
142 error(SYSTEM, errmsg);
143 }
144 for (i = 0; i <= psample; i++) {
145 zbar[i] = (float *)malloc(hresolu*sizeof(float));
146 if (zbar[i] == NULL)
147 goto memerr;
148 }
149 } else {
150 zfd = -1;
151 for (i = 0; i <= psample; i++)
152 zbar[i] = NULL;
153 }
154 /* write out boundaries */
155 fputresolu(YMAJOR|YDECR, hresolu, vresolu, stdout);
156 /* recover file and compute first */
157 i = salvage(oldfile);
158 if (zfd != -1 && i > 0 &&
159 lseek(zfd, (long)i*hresolu*sizeof(float), 0) == -1)
160 error(SYSTEM, "z file seek error in render");
161 pctdone = 100.0*i/vresolu;
162 if (ralrm > 0) /* report init stats */
163 report();
164 ypos = vresolu-1 - i;
165 fillscanline(scanbar[0], zbar[0], hresolu, ypos, psample);
166 ystep = psample;
167 /* compute scanlines */
168 for (ypos -= ystep; ypos > -ystep; ypos -= ystep) {
169 /* bottom adjust? */
170 if (ypos < 0) {
171 ystep += ypos;
172 ypos = 0;
173 }
174 colptr = scanbar[ystep]; /* move base to top */
175 scanbar[ystep] = scanbar[0];
176 scanbar[0] = colptr;
177 zptr = zbar[ystep];
178 zbar[ystep] = zbar[0];
179 zbar[0] = zptr;
180 /* fill base line */
181 fillscanline(scanbar[0], zbar[0], hresolu, ypos, psample);
182 /* fill bar */
183 fillscanbar(scanbar, zbar, hresolu, ypos, ystep);
184 /* write it out */
185 for (i = ystep; i > 0; i--) {
186 if (zfd != -1 && write(zfd, (char *)zbar[i],
187 hresolu*sizeof(float))
188 < hresolu*sizeof(float))
189 goto writerr;
190 if (fwritescan(scanbar[i], hresolu, stdout) < 0)
191 goto writerr;
192 }
193 if (fflush(stdout) == EOF)
194 goto writerr;
195 /* record progress */
196 pctdone = 100.0*(vresolu-1-ypos)/vresolu;
197 if (ralrm > 0 && time((long *)0) >= tlastrept+ralrm)
198 report();
199 }
200 /* clean up */
201 if (zfd != -1) {
202 if (write(zfd, (char *)zbar[0], hresolu*sizeof(float))
203 < hresolu*sizeof(float))
204 goto writerr;
205 if (close(zfd) == -1)
206 goto writerr;
207 for (i = 0; i <= psample; i++)
208 free((char *)zbar[i]);
209 }
210 fwritescan(scanbar[0], hresolu, stdout);
211 if (fflush(stdout) == EOF)
212 goto writerr;
213 for (i = 0; i <= psample; i++)
214 free((char *)scanbar[i]);
215 pctdone = 100.0;
216 return;
217 writerr:
218 error(SYSTEM, "write error in render");
219 memerr:
220 error(SYSTEM, "out of memory in render");
221 }
222
223
224 fillscanline(scanline, zline, xres, y, xstep) /* fill scan line at y */
225 register COLOR *scanline;
226 register float *zline;
227 int xres, y, xstep;
228 {
229 int b = xstep;
230 double z;
231 register int i;
232
233 z = pixvalue(scanline[0], 0, y);
234 if (zline) zline[0] = z;
235
236 for (i = xstep; i < xres-1+xstep; i += xstep) {
237 if (i >= xres) {
238 xstep += xres-1-i;
239 i = xres-1;
240 }
241 z = pixvalue(scanline[i], i, y);
242 if (zline) zline[i] = z;
243
244 b = fillsample(scanline+i-xstep, zline ? zline+i-xstep : NULL,
245 i-xstep, y, xstep, 0, b/2);
246 }
247 }
248
249
250 fillscanbar(scanbar, zbar, xres, y, ysize) /* fill interior */
251 register COLOR *scanbar[];
252 register float *zbar[];
253 int xres, y, ysize;
254 {
255 COLOR vline[MAXDIV+1];
256 float zline[MAXDIV+1];
257 int b = ysize;
258 register int i, j;
259
260 for (i = 0; i < xres; i++) {
261
262 copycolor(vline[0], scanbar[0][i]);
263 copycolor(vline[ysize], scanbar[ysize][i]);
264 if (zbar[0]) {
265 zline[0] = zbar[0][i];
266 zline[ysize] = zbar[ysize][i];
267 }
268
269 b = fillsample(vline, zbar[0] ? zline : NULL,
270 i, y, 0, ysize, b/2);
271
272 for (j = 1; j < ysize; j++)
273 copycolor(scanbar[j][i], vline[j]);
274 if (zbar[0])
275 for (j = 1; j < ysize; j++)
276 zbar[j][i] = zline[j];
277 }
278 }
279
280
281 int
282 fillsample(colline, zline, x, y, xlen, ylen, b) /* fill interior points */
283 register COLOR *colline;
284 register float *zline;
285 int x, y;
286 int xlen, ylen;
287 int b;
288 {
289 extern double fabs();
290 double ratio;
291 double z;
292 COLOR ctmp;
293 int ncut;
294 register int len;
295
296 if (xlen > 0) /* x or y length is zero */
297 len = xlen;
298 else
299 len = ylen;
300
301 if (len <= 1) /* limit recursion */
302 return(0);
303
304 if (b > 0
305 || (zline && 2.*fabs(zline[0]-zline[len]) > maxdiff*(zline[0]+zline[len]))
306 || bigdiff(colline[0], colline[len], maxdiff)) {
307
308 z = pixvalue(colline[len>>1], x + (xlen>>1), y + (ylen>>1));
309 if (zline) zline[len>>1] = z;
310 ncut = 1;
311
312 } else { /* interpolate */
313
314 copycolor(colline[len>>1], colline[len]);
315 ratio = (double)(len>>1) / len;
316 scalecolor(colline[len>>1], ratio);
317 if (zline) zline[len>>1] = zline[len] * ratio;
318 ratio = 1.0 - ratio;
319 copycolor(ctmp, colline[0]);
320 scalecolor(ctmp, ratio);
321 addcolor(colline[len>>1], ctmp);
322 if (zline) zline[len>>1] += zline[0] * ratio;
323 ncut = 0;
324 }
325 /* recurse */
326 ncut += fillsample(colline, zline, x, y, xlen>>1, ylen>>1, (b-1)/2);
327
328 ncut += fillsample(colline+(len>>1), zline ? zline+(len>>1) : NULL,
329 x+(xlen>>1), y+(ylen>>1),
330 xlen-(xlen>>1), ylen-(ylen>>1), b/2);
331
332 return(ncut);
333 }
334
335
336 double
337 pixvalue(col, x, y) /* compute pixel value */
338 COLOR col; /* returned color */
339 int x, y; /* pixel position */
340 {
341 static RAY thisray;
342
343 if (viewray(thisray.rorg, thisray.rdir, &ourview,
344 (x+pixjitter())/hresolu, (y+pixjitter())/vresolu) < 0) {
345 setcolor(col, 0.0, 0.0, 0.0);
346 return(0.0);
347 }
348
349 rayorigin(&thisray, NULL, PRIMARY, 1.0);
350
351 samplendx = 3*y + x; /* set pixel index */
352
353 rayvalue(&thisray); /* trace ray */
354
355 copycolor(col, thisray.rcol); /* return color */
356
357 return(thisray.rt); /* return distance */
358 }
359
360
361 int
362 salvage(oldfile) /* salvage scanlines from killed program */
363 char *oldfile;
364 {
365 COLR *scanline;
366 FILE *fp;
367 int x, y;
368
369 if (oldfile == NULL)
370 return(0);
371
372 if ((fp = fopen(oldfile, "r")) == NULL) {
373 sprintf(errmsg, "cannot open recover file \"%s\"", oldfile);
374 error(WARNING, errmsg);
375 return(0);
376 }
377 /* discard header */
378 getheader(fp, NULL);
379 /* get picture size */
380 if (fgetresolu(&x, &y, fp) != (YMAJOR|YDECR)) {
381 sprintf(errmsg, "bad recover file \"%s\"", oldfile);
382 error(WARNING, errmsg);
383 fclose(fp);
384 return(0);
385 }
386
387 if (x != hresolu || y != vresolu) {
388 sprintf(errmsg, "resolution mismatch in recover file \"%s\"",
389 oldfile);
390 error(USER, errmsg);
391 }
392
393 scanline = (COLR *)malloc(hresolu*sizeof(COLR));
394 if (scanline == NULL)
395 error(SYSTEM, "out of memory in salvage");
396 for (y = 0; y < vresolu; y++) {
397 if (freadcolrs(scanline, hresolu, fp) < 0)
398 break;
399 if (fwritecolrs(scanline, hresolu, stdout) < 0)
400 goto writerr;
401 }
402 if (fflush(stdout) == EOF)
403 goto writerr;
404 free((char *)scanline);
405 fclose(fp);
406 unlink(oldfile);
407 return(y);
408 writerr:
409 error(SYSTEM, "write error in salvage");
410 }