Esempio n. 1
0
static AMBHEMI *
samp_hemi(				/* sample indirect hemisphere */
	COLOR	rcol,
	RAY	*r,
	double	wt
)
{
	AMBHEMI	*hp;
	double	d;
	int	n, i, j;
					/* insignificance check */
	if (bright(rcol) <= FTINY)
		return(NULL);
					/* set number of divisions */
	if (ambacc <= FTINY &&
			wt > (d = 0.8*intens(rcol)*r->rweight/(ambdiv*minweight)))
		wt = d;			/* avoid ray termination */
	n = sqrt(ambdiv * wt) + 0.5;
	i = 1 + 5*(ambacc > FTINY);	/* minimum number of samples */
	if (n < i)
		n = i;
					/* allocate sampling array */
	hp = (AMBHEMI *)malloc(sizeof(AMBHEMI) + sizeof(AMBSAMP)*(n*n - 1));
	if (hp == NULL)
		error(SYSTEM, "out of memory in samp_hemi");
	hp->rp = r;
	hp->ns = n;
	hp->acol[RED] = hp->acol[GRN] = hp->acol[BLU] = 0.0;
	memset(hp->sa, 0, sizeof(AMBSAMP)*n*n);
	hp->sampOK = 0;
					/* assign coefficient */
	copycolor(hp->acoef, rcol);
	d = 1.0/(n*n);
	scalecolor(hp->acoef, d);
					/* make tangent plane axes */
	if (!getperpendicular(hp->ux, r->ron, 1))
		error(CONSISTENCY, "bad ray direction in samp_hemi");
	VCROSS(hp->uy, r->ron, hp->ux);
					/* sample divisions */
	for (i = hp->ns; i--; )
	    for (j = hp->ns; j--; )
		hp->sampOK += ambsample(hp, i, j, 0);
	copycolor(rcol, hp->acol);
	if (!hp->sampOK) {		/* utter failure? */
		free(hp);
		return(NULL);
	}
	if (hp->sampOK < hp->ns*hp->ns) {
		hp->sampOK *= -1;	/* soft failure */
		return(hp);
	}
	if (hp->sampOK < 64)
		return(hp);		/* insufficient for super-sampling */
	n = ambssamp*wt + 0.5;
	if (n > 8) {			/* perform super-sampling? */
		ambsupersamp(hp, n);
		copycolor(rcol, hp->acol);
	}
	return(hp);			/* all is well */
}
Esempio n. 2
0
/* Get ray contribution from previous file */
static int
get_contrib(DCOLOR cnt, FILE *finp)
{
	COLOR	fv;
	COLR	cv;

	switch (outfmt) {
	case 'a':
		return(fscanf(finp,"%lf %lf %lf",&cnt[0],&cnt[1],&cnt[2]) == 3);
	case 'f':
		if (fread(fv, sizeof(fv[0]), 3, finp) != 3)
			return(0);
		copycolor(cnt, fv);
		return(1);
	case 'd':
		return(fread(cnt, sizeof(cnt[0]), 3, finp) == 3);
	case 'c':
		if (fread(cv, sizeof(cv), 1, finp) != 1)
			return(0);
		colr_color(fv, cv);
		copycolor(cnt, fv);
		return(1);
	default:
		error(INTERNAL, "botched output format");
	}
	return(0);	/* pro forma return */
}
Esempio n. 3
0
/* write out matrix to file (precede by resolution string if picture) */
int
cm_write(const CMATRIX *cm, int dtype, FILE *fp)
{
	static const char	tabEOL[2] = {'\t','\n'};
	const COLORV		*mp = cm->cmem;
	int			r, c;

	switch (dtype) {
	case DTascii:
		for (r = 0; r < cm->nrows; r++)
			for (c = 0; c < cm->ncols; c++, mp += 3)
				fprintf(fp, "%.6e %.6e %.6e%c",
						mp[0], mp[1], mp[2],
						tabEOL[c >= cm->ncols-1]);
		break;
	case DTfloat:
	case DTdouble:
		if (sizeof(COLOR) == cm_elem_size[dtype]) {
			r = cm->ncols*cm->nrows;
			while (r > 0) {
				c = putbinary(mp, sizeof(COLOR), r, fp);
				if (c <= 0)
					return(0);
				mp += 3*c;
				r -= c;
			}
		} else if (dtype == DTdouble) {
			double	dc[3];
			r = cm->ncols*cm->nrows;
			while (r--) {
				copycolor(dc, mp);
				if (putbinary(dc, sizeof(double), 3, fp) != 3)
					return(0);
				mp += 3;
			}
		} else /* dtype == DTfloat */ {
			float	fc[3];
			r = cm->ncols*cm->nrows;
			while (r--) {
				copycolor(fc, mp);
				if (putbinary(fc, sizeof(float), 3, fp) != 3)
					return(0);
				mp += 3;
			}
		}
		break;
	case DTrgbe:
	case DTxyze:
		fprtresolu(cm->ncols, cm->nrows, fp);
		for (r = 0; r < cm->nrows; r++, mp += 3*cm->ncols)
			if (fwritescan((COLOR *)mp, cm->ncols, fp) < 0)
				return(0);
		break;
	default:
		fputs("Unsupported data type in cm_write()!\n", stderr);
		return(0);
	}
	return(fflush(fp) == 0);
}
Esempio n. 4
0
extern int
raymixture(		/* mix modifiers */
	RAY  *r,
	OBJECT  fore,
	OBJECT  back,
	double  coef
)
{
	RAY  fr, br;
	int  foremat, backmat;
	int  i;
					/* bound coefficient */
	if (coef > 1.0)
		coef = 1.0;
	else if (coef < 0.0)
		coef = 0.0;
					/* compute foreground and background */
	foremat = backmat = 0;
					/* foreground */
	fr = *r;
	if (coef > FTINY) {
		fr.rweight *= coef;
		scalecolor(fr.rcoef, coef);
		foremat = rayshade(&fr, fore);
	}
					/* background */
	br = *r;
	if (coef < 1.0-FTINY) {
		br.rweight *= 1.0-coef;
		scalecolor(br.rcoef, 1.0-coef);
		backmat = rayshade(&br, back);
	}
					/* check for transparency */
	if (backmat ^ foremat) {
		if (backmat && coef > FTINY)
			raytrans(&fr);
		else if (foremat && coef < 1.0-FTINY)
			raytrans(&br);
	}
					/* mix perturbations */
	for (i = 0; i < 3; i++)
		r->pert[i] = coef*fr.pert[i] + (1.0-coef)*br.pert[i];
					/* mix pattern colors */
	scalecolor(fr.pcol, coef);
	scalecolor(br.pcol, 1.0-coef);
	copycolor(r->pcol, fr.pcol);
	addcolor(r->pcol, br.pcol);
					/* return value tells if material */
	if (!foremat & !backmat)
		return(0);
					/* mix returned ray values */
	scalecolor(fr.rcol, coef);
	scalecolor(br.rcol, 1.0-coef);
	copycolor(r->rcol, fr.rcol);
	addcolor(r->rcol, br.rcol);
	r->rt = bright(fr.rcol) > bright(br.rcol) ? fr.rt : br.rt;
	return(1);
}
Esempio n. 5
0
static void
dirashik(		/* compute source contribution */
	COLOR  cval,		/* returned coefficient */
	void  *nnp,		/* material data */
	FVECT  ldir,		/* light source direction */
	double  omega		/* light source size */
)
{
	ASHIKDAT *np = nnp;
	double  ldot;
	double  dtmp, dtmp1, dtmp2;
	FVECT  h;
	COLOR  ctmp;

	setcolor(cval, 0.0, 0.0, 0.0);

	ldot = DOT(np->pnorm, ldir);

	if (ldot < 0.0)
		return;		/* wrong side */

	/*
	 *  Compute and add diffuse reflected component to returned
	 *  color.
	 */
	copycolor(ctmp, np->mcolor);
	dtmp = ldot * omega * (1.0/PI) * (1. - schlick_fres(ldot));
	scalecolor(ctmp, dtmp);		
	addcolor(cval, ctmp);

	if ((np->specfl & (SPA_REFL|SPA_BADU)) != SPA_REFL)
		return;
	/*
	 *  Compute specular reflection coefficient
	 */
					/* half vector */
	VSUB(h, ldir, np->rp->rdir);
	normalize(h);
					/* ellipse */
	dtmp1 = DOT(np->u, h);
	dtmp1 *= dtmp1 * np->u_power;
	dtmp2 = DOT(np->v, h);
	dtmp2 *= dtmp2 * np->v_power;
					/* Ashikhmin-Shirley model*/
	dtmp = DOT(np->pnorm, h);
	dtmp = pow(dtmp, (dtmp1+dtmp2)/(1.-dtmp*dtmp));
	dtmp *= sqrt((np->u_power+1.)*(np->v_power+1.));
	dtmp /= 8.*PI * DOT(ldir,h) * MAX(ldot,np->pdot);
					/* worth using? */
	if (dtmp > FTINY) {
		copycolor(ctmp, np->scolor);
		dtmp *= ldot * omega;
		scalecolor(ctmp, dtmp);
		addcolor(cval, ctmp);
	}
}
static void
picdebug(void)			/* put out debugging picture */
{
	static COLOR	blkcol = BLKCOLOR;
	COLOR	*scan;
	int	y, i;
	register int	x, rg;

	if (fseek(stdin, 0L, 0) == EOF) {
		fprintf(stderr, "%s: cannot seek on input picture\n", progname);
		exit(1);
	}
	getheader(stdin, NULL, NULL);		/* skip input header */
	fgetresolu(&xmax, &ymax, stdin);
						/* allocate scanline */
	scan = (COLOR *)malloc(xmax*sizeof(COLOR));
	if (scan == NULL) {
		perror(progname);
		exit(1);
	}
						/* finish debug header */
	fputformat(COLRFMT, debugfp);
	putc('\n', debugfp);
	fprtresolu(xmax, ymax, debugfp);
						/* write debug picture */
	for (y = ymax-1; y >= 0; y--) {
		if (freadscan(scan, xmax, stdin) < 0) {
			fprintf(stderr, "%s: error rereading input picture\n",
					progname);
			exit(1);
		}
		for (x = 0; x < xmax; x++) {
			rg = chartndx(x, y, &i);
			if (rg == RG_CENT) {
				if (!(1L<<i & gmtflags) || (x+y)&07) {
					copycolor(scan[x], mbRGB[i]);
					clipgamut(scan[x], bright(scan[x]),
						CGAMUT, colmin, colmax);
				} else
					copycolor(scan[x], blkcol);
			} else if (rg == RG_CORR)
				cvtcolor(scan[x], scan[x]);
			else if (rg != RG_ORIG)
				copycolor(scan[x], blkcol);
		}
		if (fwritescan(scan, xmax, debugfp) < 0) {
			fprintf(stderr, "%s: error writing debugging picture\n",
					progname);
			exit(1);
		}
	}
						/* clean up */
	fclose(debugfp);
	free((void *)scan);
}
Esempio n. 7
0
int
freadscan(			/* read in a scanline */
	COLOR  *scanline,
	int  len,
	FILE  *fp
)
{
	COLR  *clrscan;

	if ((clrscan = (COLR *)tempbuffer(len*sizeof(COLR))) == NULL)
		return(-1);
	if (freadcolrs(clrscan, len, fp) < 0)
		return(-1);
					/* convert scanline */
	colr_color(scanline[0], clrscan[0]);
	while (--len > 0) {
		scanline++; clrscan++;
		if (clrscan[0][GRN] == clrscan[-1][GRN] &&
			    (clrscan[0][RED] == clrscan[-1][RED]) &
			    (clrscan[0][BLU] == clrscan[-1][BLU]) &
			    (clrscan[0][EXP] == clrscan[-1][EXP]))
			copycolor(scanline[0], scanline[-1]);
		else
			colr_color(scanline[0], clrscan[0]);
	}
	return(0);
}
Esempio n. 8
0
int
m_aniso(			/* anisotropic material */
	register OBJREC	*o
)
{
	register MATREC	*m;
					/* check arguments */
	if (o->oargs.nfargs < (o->otype == MAT_TRANS2 ? 8 : 6))
		objerror(o, USER, "bad # of real arguments");
					/* allocate/insert material */
	m = newmaterial(o->oname);
					/* assign parameters */
	setcolor(m->u.m.ambdiff, o->oargs.farg[0],
			o->oargs.farg[1], o->oargs.farg[2]);
	if ((m->type = o->otype) == MAT_METAL2)
		copycolor(m->u.m.specular, m->u.m.ambdiff);
	else
		setcolor(m->u.m.specular, 1., 1., 1.);
	scalecolor(m->u.m.specular, o->oargs.farg[3]);
	scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[3]);
	if (m->type == MAT_TRANS2) {
		scalecolor(m->u.m.specular, 1.-o->oargs.farg[6]);
		scalecolor(m->u.m.ambdiff, 1.-o->oargs.farg[6]);
	}
	if (o->oargs.farg[4]*o->oargs.farg[5] <= FTINY*FTINY)
		m->u.m.specexp = MAXSPECEXP;
	else
		m->u.m.specexp = 2./(o->oargs.farg[4]*o->oargs.farg[5]);
	if (m->u.m.specexp > MAXSPECEXP)
		m->u.m.specexp = MAXSPECEXP;
	return(0);
}
Esempio n. 9
0
extern void
extambient(		/* extrapolate value at pv, nv */
	COLOR  cr,
	AMBVAL	 *ap,
	FVECT  pv,
	FVECT  nv
)
{
	FVECT  v1;
	int  i;
	double	d;

	d = 1.0;			/* zeroeth order */
					/* gradient due to translation */
	for (i = 0; i < 3; i++)
		d += ap->gpos[i]*(pv[i]-ap->pos[i]);
					/* gradient due to rotation */
	VCROSS(v1, ap->dir, nv);
	d += DOT(ap->gdir, v1);
	if (d <= 0.0) {
		setcolor(cr, 0.0, 0.0, 0.0);
		return;
	}
	copycolor(cr, ap->val);
	scalecolor(cr, d);
}
Esempio n. 10
0
/* Put out ray contribution to file */
static void
put_contrib(const DCOLOR cnt, FILE *fout)
{
	double	sf = 1;
	COLOR	fv;
	COLR	cv;

	if (accumulate > 1)
		sf = 1./(double)accumulate;
	switch (outfmt) {
	case 'a':
		if (accumulate > 1)
			fprintf(fout, "%.6e\t%.6e\t%.6e\t",
					sf*cnt[0], sf*cnt[1], sf*cnt[2]);
		else
			fprintf(fout, "%.6e\t%.6e\t%.6e\t",
					cnt[0], cnt[1], cnt[2]);
		break;
	case 'f':
		if (accumulate > 1) {
			copycolor(fv, cnt);
			scalecolor(fv, sf);
		} else
			copycolor(fv, cnt);
		fwrite(fv, sizeof(float), 3, fout);
		break;
	case 'd':
		if (accumulate > 1) {
			DCOLOR	dv;
			copycolor(dv, cnt);
			scalecolor(dv, sf);
			fwrite(dv, sizeof(double), 3, fout);
		} else
			fwrite(cnt, sizeof(double), 3, fout);
		break;
	case 'c':
		if (accumulate > 1)
			setcolr(cv, sf*cnt[0], sf*cnt[1], sf*cnt[2]);
		else
			setcolr(cv, cnt[0], cnt[1], cnt[2]);
		fwrite(cv, sizeof(cv), 1, fout);
		break;
	default:
		error(INTERNAL, "botched output format");
	}
}
Esempio n. 11
0
void
pcopy(					/* copy paint node p1 into p2 */
	PNODE  *p1,
	PNODE  *p2
)
{
	copycolor(p2->v, p1->v);
	p2->x = p1->x;
	p2->y = p1->y;
}
Esempio n. 12
0
/* Multiply two matrices (or a matrix and a vector) and allocate the result */
CMATRIX *
cm_multiply(const CMATRIX *cm1, const CMATRIX *cm2)
{
	char	*rowcheck=NULL, *colcheck=NULL;
	CMATRIX	*cmr;
	int	dr, dc, i;

	if ((cm1->ncols <= 0) | (cm1->ncols != cm2->nrows))
		error(INTERNAL, "matrix dimension mismatch in cm_multiply()");
	cmr = cm_alloc(cm1->nrows, cm2->ncols);
	if (cmr == NULL)
		return(NULL);
				/* optimization: check for zero rows & cols */
	if (((cm1->nrows > 5) | (cm2->ncols > 5)) & (cm1->ncols > 5)) {
		static const COLOR	czero;
		rowcheck = (char *)calloc(cmr->nrows, 1);
		for (dr = cm1->nrows*(rowcheck != NULL); dr--; )
		    for (dc = cm1->ncols; dc--; )
			if (memcmp(cm_lval(cm1,dr,dc), czero, sizeof(COLOR))) {
				rowcheck[dr] = 1;
				break;
			}
		colcheck = (char *)calloc(cmr->ncols, 1);
		for (dc = cm2->ncols*(colcheck != NULL); dc--; )
		    for (dr = cm2->nrows; dr--; )
			if (memcmp(cm_lval(cm2,dr,dc), czero, sizeof(COLOR))) {
				colcheck[dc] = 1;
				break;
			}
	}
	for (dr = 0; dr < cmr->nrows; dr++)
	    for (dc = 0; dc < cmr->ncols; dc++) {
		COLORV	*dp = cm_lval(cmr,dr,dc);
		double	res[3];
		dp[0] = dp[1] = dp[2] = 0;
		if (rowcheck != NULL && !rowcheck[dr])
			continue;
		if (colcheck != NULL && !colcheck[dc])
			continue;
		res[0] = res[1] = res[2] = 0;
		for (i = 0; i < cm1->ncols; i++) {
		    const COLORV	*cp1 = cm_lval(cm1,dr,i);
		    const COLORV	*cp2 = cm_lval(cm2,i,dc);
		    res[0] += (double)cp1[0] * cp2[0];
		    res[1] += (double)cp1[1] * cp2[1];
		    res[2] += (double)cp1[2] * cp2[2];
		}
		copycolor(dp, res);
	    }
	if (rowcheck != NULL) free(rowcheck);
	if (colcheck != NULL) free(colcheck);
	return(cmr);
}
Esempio n. 13
0
extern void
raytrans(			/* transmit ray as is */
	RAY  *r
)
{
	RAY  tr;

	if (rayorigin(&tr, TRANS, r, NULL) == 0) {
		VCOPY(tr.rdir, r->rdir);
		rayvalue(&tr);
		copycolor(r->rcol, tr.rcol);
		r->rt = r->rot + tr.rt;
	}
}
Esempio n. 14
0
static double
greypoint(			/* compute gamut mapping grey target */
	COLOR col
)
{
	COLOR	gryc;
	int	i;
				/* improves saturated color rendering */
	copycolor(gryc, col);
	for (i = 3; i--; )
		if (gryc[i] > 1)
			gryc[i] = 1;
		else if (gryc[i] < 0)
			gryc[i] = 0;
	return(bright(gryc));
}
Esempio n. 15
0
static void
vips_rad2float_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width )
{
	COLR *inp = (COLR *) in[0];
	COLOR *outbuf = (COLOR *) out;

	colr_color(outbuf[0], inp[0]);
	while (--width > 0) {
		outbuf++; inp++;
		if (inp[0][RED] == inp[-1][RED] &&
			    inp[0][GRN] == inp[-1][GRN] &&
			    inp[0][BLU] == inp[-1][BLU] &&
			    inp[0][EXP] == inp[-1][EXP])
			copycolor(outbuf[0], outbuf[-1]);
		else
			colr_color(outbuf[0], inp[0]);
	}
}
Esempio n. 16
0
int
waitrays(void)					/* finish up pending rays */
{
	int	nwaited = 0;
	int	rval;
	RAY	raydone;

	if (!ray_pnprocs)			/* immediate mode? */
		return(0);
	while ((rval = ray_presult(&raydone, 0)) > 0) {
		PNODE  *p = (PNODE *)raydone.rno;
		copycolor(p->v, raydone.rcol);
		scalecolor(p->v, exposure);
		recolor(p);
		nwaited++;
	}
	if (rval < 0)
		return(-1);
	return(nwaited);
}
Esempio n. 17
0
extern double
makeambient(		/* make a new ambient value for storage */
	COLOR  acol,
	RAY  *r,
	FVECT  rn,
	int  al
)
{
	AMBVAL	amb;
	FVECT	gp, gd;
	int	i;

	amb.weight = 1.0;			/* compute weight */
	for (i = al; i-- > 0; )
		amb.weight *= AVGREFL;
	if (r->rweight < 0.1*amb.weight)	/* heuristic override */
		amb.weight = 1.25*r->rweight;
	setcolor(acol, AVGREFL, AVGREFL, AVGREFL);
						/* compute ambient */
	amb.rad = doambient(acol, r, amb.weight, gp, gd);
	if (amb.rad <= FTINY) {
		setcolor(acol, 0.0, 0.0, 0.0);
		return(0.0);
	}
	scalecolor(acol, 1./AVGREFL);		/* undo assumed reflectance */
						/* store value */
	VCOPY(amb.pos, r->rop);
	VCOPY(amb.dir, r->ron);
	amb.lvl = al;
	copycolor(amb.val, acol);
	VCOPY(amb.gpos, gp);
	VCOPY(amb.gdir, gd);
						/* insert into tree */
	avsave(&amb);				/* and save to file */
	if (rn != r->ron)
		extambient(acol, &amb, r->rop, rn);	/* texture */
	return(amb.rad);
}
Esempio n. 18
0
static void
starpoint(		/* pixel is on the star's point */
	COLOR  fcol,
	int  x,
	int  y,
	register HOTPIX	 *hp
)
{
	COLOR  ctmp;
	double	d2;
	
	d2 = (double)(x - hp->x)*(x - hp->x) + (double)(y - hp->y)*(y - hp->y);
	if (d2 > sprdfact) {
		d2 = sprdfact / d2;
		if (d2 < FTINY)
			return;
		copycolor(ctmp, hp->val);
		scalecolor(ctmp, d2);
		addcolor(fcol, ctmp);
	} else if (d2 > FTINY) {
		addcolor(fcol, hp->val);
	}
}
Esempio n. 19
0
static inline void
split_patch(pdf_tensorpatch *s0, pdf_tensorpatch *s1, const pdf_tensorpatch *p)
{
    split_curve_s(&p->pole[0][0], &s0->pole[0][0], &s1->pole[0][0], 4);
    split_curve_s(&p->pole[0][1], &s0->pole[0][1], &s1->pole[0][1], 4);
    split_curve_s(&p->pole[0][2], &s0->pole[0][2], &s1->pole[0][2], 4);
    split_curve_s(&p->pole[0][3], &s0->pole[0][3], &s1->pole[0][3], 4);

	copycolor(s0->color[0], p->color[0]);
	midcolor(s0->color[1], p->color[0], p->color[1]);
	midcolor(s0->color[2], p->color[2], p->color[3]);
	copycolor(s0->color[3], p->color[3]);

	copycolor(s1->color[0], s0->color[1]);
	copycolor(s1->color[1], p->color[1]);
	copycolor(s1->color[2], p->color[2]);	
	copycolor(s1->color[3], s0->color[2]);
}
Esempio n. 20
0
extern void
dogauss(		/* gaussian filter */
	COLOR  csum,
	int  xcent,
	int  ycent,
	int  c,
	int  r
)
{
	double  dy, dx, weight, wsum;
	COLOR  ctmp;
	int  y;
	register int  x, offs;
	register COLOR	*scan;

	wsum = FTINY;
	setcolor(csum, 0.0, 0.0, 0.0);
	for (y = ycent-yrad; y <= ycent+yrad; y++) {
		if (y < 0) continue;
		if (y >= yres) break;
		dy = (y_r*(y+.5) - (r+.5))/rad;
		scan = scanin[y%barsize];
		for (x = xcent-xrad; x <= xcent+xrad; x++) {
			offs = x < 0 ? xres : x >= xres ? -xres : 0;
			if (offs && !wrapfilt)
				continue;
			dx = (x_c*(x+.5) - (c+.5))/rad;
			weight = lookgauss(dx*dx + dy*dy);
			wsum += weight;
			copycolor(ctmp, scan[x+offs]);
			scalecolor(ctmp, weight);
			addcolor(csum, ctmp);
		}
	}
	weight = 1.0/wsum;
	scalecolor(csum, weight);
}
Esempio n. 21
0
extern void
pass1scan(		/* process first pass scanline */
	register COLOR	*scan,
	int  y
)
{
	double	cbrt;
	register int  x;
	register HOTPIX	 *hp;

	for (x = 0; x < xres; x++) {
	
		cbrt = (*ourbright)(scan[x]);

		if (cbrt <= 0)
			continue;

		if (avghot || cbrt < hotlvl) {
			avgbrt += cbrt;
			npix++;
		}
		if (npts && cbrt >= hotlvl) {
			hp = (HOTPIX *)malloc(sizeof(HOTPIX));
			if (hp == NULL) {
				fprintf(stderr, "%s: out of memory\n",
						progname);
				quit(1);
			}
			copycolor(hp->val, scan[x]);
			hp->x = x;
			hp->y = y;
			hp->slope = tan(PI*(0.5-(random()%npts+0.5)/npts));
			hp->next = head;
			head = hp;
		}
	}
}
Esempio n. 22
0
static inline void
split_stripe(pdf_tensorpatch *s0, pdf_tensorpatch *s1, const pdf_tensorpatch *p)

{
    split_curve_s(p->pole[0], s0->pole[0], s1->pole[0], 1);
    split_curve_s(p->pole[1], s0->pole[1], s1->pole[1], 1);
    split_curve_s(p->pole[2], s0->pole[2], s1->pole[2], 1);
    split_curve_s(p->pole[3], s0->pole[3], s1->pole[3], 1);

	copycolor(s0->color[0], p->color[0]);
	copycolor(s0->color[1], p->color[1]);
	midcolor(s0->color[2], p->color[1], p->color[2]);
	midcolor(s0->color[3], p->color[0], p->color[3]);

	copycolor(s1->color[0], s0->color[3]);
	copycolor(s1->color[1], s0->color[2]);
	copycolor(s1->color[2], p->color[2]);
	copycolor(s1->color[3], p->color[3]);
}
Esempio n. 23
0
static void
sumans(		/* sum input pixel to output */
	int  px,
	int  py,
	int  rcent,
	int  ccent,
	double  m
)
{
	double  dy2, dx;
	COLOR  pval, ctmp;
	int  ksiz, r, offs;
	double  pc, pr, norm;
	register int  i, c;
	register COLOR	*scan;
	/*
	 * This normalization method fails at the picture borders because
	 * a different number of input pixels contribute there.
	 */
	scan = scanin[py%barsize] + (px < 0 ? xres : px >= xres ? -xres : 0);
	copycolor(pval, scan[px]);
	pc = x_c*(px+.5);
	pr = y_r*(py+.5);
	ksiz = CHECKRAD*m*rad + 1;
	if (ksiz > orad) ksiz = orad;
						/* compute normalization */
	norm = 0.0;
	i = 0;
	for (r = rcent-ksiz; r <= rcent+ksiz; r++) {
		if (r < 0) continue;
		if (r >= nrows) break;
		dy2 = (pr - (r+.5))/(m*rad);
		dy2 *= dy2;
		for (c = ccent-ksiz; c <= ccent+ksiz; c++) {
			if (!wrapfilt) {
				if (c < 0) continue;
				if (c >= ncols) break;
			}
			dx = (pc - (c+.5))/(m*rad);
			norm += warr[i++] = lookgauss(dx*dx + dy2);
		}
	}
	norm = 1.0/norm;
	if (x_c < 1.0) norm *= x_c;
	if (y_r < 1.0) norm *= y_r;
						/* sum pixels */
	i = 0;
	for (r = rcent-ksiz; r <= rcent+ksiz; r++) {
		if (r < 0) continue;
		if (r >= nrows) break;
		scan = scoutbar[r%obarsize];
		for (c = ccent-ksiz; c <= ccent+ksiz; c++) {
			offs = c < 0 ? ncols : c >= ncols ? -ncols : 0;
			if (offs && !wrapfilt)
				continue;
			copycolor(ctmp, pval);
			dx = norm*warr[i++];
			scalecolor(ctmp, dx);
			addcolor(scan[c+offs], ctmp);
		}
	}
}
Esempio n. 24
0
static int
ambsample(				/* initial ambient division sample */
	AMBHEMI	*hp,
	int	i,
	int	j,
	int	n
)
{
	AMBSAMP	*ap = &ambsam(hp,i,j);
	RAY	ar;
	int	hlist[3], ii;
	double	spt[2], zd;
					/* generate hemispherical sample */
					/* ambient coefficient for weight */
	if (ambacc > FTINY)
		setcolor(ar.rcoef, AVGREFL, AVGREFL, AVGREFL);
	else
		copycolor(ar.rcoef, hp->acoef);
	if (rayorigin(&ar, AMBIENT, hp->rp, ar.rcoef) < 0)
		return(0);
	if (ambacc > FTINY) {
		multcolor(ar.rcoef, hp->acoef);
		scalecolor(ar.rcoef, 1./AVGREFL);
	}
	hlist[0] = hp->rp->rno;
	hlist[1] = j;
	hlist[2] = i;
	multisamp(spt, 2, urand(ilhash(hlist,3)+n));
resample:
	SDsquare2disk(spt, (j+spt[1])/hp->ns, (i+spt[0])/hp->ns);
	zd = sqrt(1. - spt[0]*spt[0] - spt[1]*spt[1]);
	for (ii = 3; ii--; )
		ar.rdir[ii] =	spt[0]*hp->ux[ii] +
				spt[1]*hp->uy[ii] +
				zd*hp->rp->ron[ii];
	checknorm(ar.rdir);
					/* avoid coincident samples */
	if (!n && ambcollision(hp, i, j, ar.rdir)) {
		spt[0] = frandom(); spt[1] = frandom();
		goto resample;		/* reject this sample */
	}
	dimlist[ndims++] = AI(hp,i,j) + 90171;
	rayvalue(&ar);			/* evaluate ray */
	ndims--;
	zd = raydistance(&ar);
	if (zd <= FTINY)
		return(0);		/* should never happen */
	multcolor(ar.rcol, ar.rcoef);	/* apply coefficient */
	if (zd*ap->d < 1.0)		/* new/closer distance? */
		ap->d = 1.0/zd;
	if (!n) {			/* record first vertex & value */
		if (zd > 10.0*thescene.cusize + 1000.)
			zd = 10.0*thescene.cusize + 1000.;
		VSUM(ap->p, ar.rorg, ar.rdir, zd);
		copycolor(ap->v, ar.rcol);
	} else {			/* else update recorded value */
		hp->acol[RED] -= colval(ap->v,RED);
		hp->acol[GRN] -= colval(ap->v,GRN);
		hp->acol[BLU] -= colval(ap->v,BLU);
		zd = 1.0/(double)(n+1);
		scalecolor(ar.rcol, zd);
		zd *= (double)n;
		scalecolor(ap->v, zd);
		addcolor(ap->v, ar.rcol);
	}
	addcolor(hp->acol, ap->v);	/* add to our sum */
	return(1);
}
Esempio n. 25
0
extern void
direct(					/* add direct component */
	RAY  *r,			/* ray that hit surface */
	srcdirf_t *f,			/* direct component coefficient function */
	void  *p			/* data for f */
)
{
	register int  sn;
	register CONTRIB  *scp;
	SRCINDEX  si;
	int  nshadcheck, ncnts;
	int  nhits;
	double  prob, ourthresh, hwt;
	RAY  sr;
			/* NOTE: srccnt and cntord global so no recursion */
	if (nsources <= 0)
		return;		/* no sources?! */
						/* potential contributions */
	initsrcindex(&si);
	for (sn = 0; srcray(&sr, r, &si); sn++) {
		if (sn >= maxcntr) {
			maxcntr = sn + MAXSPART;
			srccnt = (CONTRIB *)realloc((void *)srccnt,
					maxcntr*sizeof(CONTRIB));
			cntord = (CNTPTR *)realloc((void *)cntord,
					maxcntr*sizeof(CNTPTR));
			if ((srccnt == NULL) | (cntord == NULL))
				error(SYSTEM, "out of memory in direct");
		}
		cntord[sn].sndx = sn;
		scp = srccnt + sn;
		scp->sno = sr.rsrc;
						/* compute coefficient */
		(*f)(scp->coef, p, sr.rdir, si.dom);
		cntord[sn].brt = intens(scp->coef);
		if (cntord[sn].brt <= 0.0)
			continue;
#if SHADCACHE
						/* check shadow cache */
		if (si.np == 1 && srcblocked(&sr)) {
			cntord[sn].brt = 0.0;
			continue;
		}
#endif
		VCOPY(scp->dir, sr.rdir);
		copycolor(sr.rcoef, scp->coef);
						/* compute potential */
		sr.revf = srcvalue;
		rayvalue(&sr);
		multcolor(sr.rcol, sr.rcoef);
		copycolor(scp->val, sr.rcol);
		cntord[sn].brt = bright(sr.rcol);
	}
						/* sort contributions */
	qsort(cntord, sn, sizeof(CNTPTR), cntcmp);
	{					/* find last */
		register int  l, m;

		ncnts = l = sn;
		sn = 0;
		while ((m = (sn + ncnts) >> 1) != l) {
			if (cntord[m].brt > 0.0)
				sn = m;
			else
				ncnts = m;
			l = m;
		}
	}
	if (ncnts == 0)
		return;		/* no contributions! */
                                                /* accumulate tail */
        for (sn = ncnts-1; sn > 0; sn--)
                cntord[sn-1].brt += cntord[sn].brt;
						/* compute number to check */
	nshadcheck = pow((double)ncnts, shadcert) + .5;
						/* modify threshold */
	ourthresh = shadthresh / r->rweight;
						/* test for shadows */
	for (nhits = 0, hwt = 0.0, sn = 0; sn < ncnts;
			hwt += (double)source[scp->sno].nhits /
				(double)source[scp->sno].ntests,
			sn++) {
						/* check threshold */
		if ((sn+nshadcheck>=ncnts ? cntord[sn].brt :
				cntord[sn].brt-cntord[sn+nshadcheck].brt)
				< ourthresh*bright(r->rcol))
			break;
		scp = srccnt + cntord[sn].sndx;
						/* test for hit */
		rayorigin(&sr, SHADOW, r, NULL);
		copycolor(sr.rcoef, scp->coef);
		VCOPY(sr.rdir, scp->dir);
		sr.rsrc = scp->sno;
						/* keep statistics */
		if (source[scp->sno].ntests++ > 0xfffffff0) {
			source[scp->sno].ntests >>= 1;
			source[scp->sno].nhits >>= 1;
		}
		if (localhit(&sr, &thescene) &&
				( sr.ro != source[scp->sno].so ||
				source[scp->sno].sflags & SFOLLOW )) {
						/* follow entire path */
			raycont(&sr);
			if (trace != NULL)
				(*trace)(&sr);	/* trace execution */
			if (bright(sr.rcol) <= FTINY) {
#if SHADCACHE
				if ((scp <= srccnt || scp[-1].sno != scp->sno)
						&& (scp >= srccnt+ncnts-1 ||
						    scp[1].sno != scp->sno))
					srcblocker(&sr);
#endif
				continue;	/* missed! */
			}
			rayparticipate(&sr);
			multcolor(sr.rcol, sr.rcoef);
			copycolor(scp->val, sr.rcol);
		} else if (trace != NULL &&
			(source[scp->sno].sflags & (SDISTANT|SVIRTUAL|SFOLLOW))
						== (SDISTANT|SFOLLOW) &&
				sourcehit(&sr) && rayshade(&sr, sr.ro->omod)) {
			(*trace)(&sr);		/* trace execution */
			/* skip call to rayparticipate() & scp->val update */
		}
						/* add contribution if hit */
		addcolor(r->rcol, scp->val);
		nhits++;
		source[scp->sno].nhits++;
	}
Esempio n. 26
0
int
m_dielectric(	/* color a ray which hit a dielectric interface */
	OBJREC  *m,
	RAY  *r
)
{
	double  cos1, cos2, nratio;
	COLOR  ctrans;
	COLOR  talb;
	int  hastexture;
	int	flatsurface;
	double  refl, trans;
	FVECT  dnorm;
	double  d1, d2;
	RAY  p;
	int  i;

	/* PMAP: skip refracted shadow or ambient ray if accounted for in
	   photon map */
	if (shadowRayInPmap(r) || ambRayInPmap(r))
		return(1);
	
	if (m->oargs.nfargs != (m->otype==MAT_DIELECTRIC ? 5 : 8))
		objerror(m, USER, "bad arguments");

	raytexture(r, m->omod);			/* get modifiers */

	if ( (hastexture = DOT(r->pert,r->pert) > FTINY*FTINY) )
		cos1 = raynormal(dnorm, r);	/* perturb normal */
	else {
		VCOPY(dnorm, r->ron);
		cos1 = r->rod;
	}
	flatsurface = r->ro != NULL && isflat(r->ro->otype) &&
			!hastexture | (r->crtype & AMBIENT);

						/* index of refraction */
	if (m->otype == MAT_DIELECTRIC)
		nratio = m->oargs.farg[3] + m->oargs.farg[4]/MLAMBDA;
	else
		nratio = m->oargs.farg[3] / m->oargs.farg[7];
	
	if (cos1 < 0.0) {			/* inside */
		hastexture = -hastexture;
		cos1 = -cos1;
		dnorm[0] = -dnorm[0];
		dnorm[1] = -dnorm[1];
		dnorm[2] = -dnorm[2];
		setcolor(r->cext, -mylog(m->oargs.farg[0]*colval(r->pcol,RED)),
				 -mylog(m->oargs.farg[1]*colval(r->pcol,GRN)),
				 -mylog(m->oargs.farg[2]*colval(r->pcol,BLU)));
		setcolor(r->albedo, 0., 0., 0.);
		r->gecc = 0.;
		if (m->otype == MAT_INTERFACE) {
			setcolor(ctrans,
				-mylog(m->oargs.farg[4]*colval(r->pcol,RED)),
				-mylog(m->oargs.farg[5]*colval(r->pcol,GRN)),
				-mylog(m->oargs.farg[6]*colval(r->pcol,BLU)));
			setcolor(talb, 0., 0., 0.);
		} else {
			copycolor(ctrans, cextinction);
			copycolor(talb, salbedo);
		}
	} else {				/* outside */
		nratio = 1.0 / nratio;

		setcolor(ctrans, -mylog(m->oargs.farg[0]*colval(r->pcol,RED)),
				 -mylog(m->oargs.farg[1]*colval(r->pcol,GRN)),
				 -mylog(m->oargs.farg[2]*colval(r->pcol,BLU)));
		setcolor(talb, 0., 0., 0.);
		if (m->otype == MAT_INTERFACE) {
			setcolor(r->cext,
				-mylog(m->oargs.farg[4]*colval(r->pcol,RED)),
				-mylog(m->oargs.farg[5]*colval(r->pcol,GRN)),
				-mylog(m->oargs.farg[6]*colval(r->pcol,BLU)));
			setcolor(r->albedo, 0., 0., 0.);
			r->gecc = 0.;
		}
	}

	d2 = 1.0 - nratio*nratio*(1.0 - cos1*cos1);	/* compute cos theta2 */

	if (d2 < FTINY)			/* total reflection */

		refl = 1.0;

	else {				/* refraction occurs */
					/* compute Fresnel's equations */
		cos2 = sqrt(d2);
		d1 = cos1;
		d2 = nratio*cos2;
		d1 = (d1 - d2) / (d1 + d2);
		refl = d1 * d1;

		d1 = 1.0 / cos1;
		d2 = nratio / cos2;
		d1 = (d1 - d2) / (d1 + d2);
		refl += d1 * d1;

		refl *= 0.5;
		trans = 1.0 - refl;

		trans *= nratio*nratio;		/* solid angle ratio */

		setcolor(p.rcoef, trans, trans, trans);

		if (rayorigin(&p, REFRACTED, r, p.rcoef) == 0) {

						/* compute refracted ray */
			d1 = nratio*cos1 - cos2;
			for (i = 0; i < 3; i++)
				p.rdir[i] = nratio*r->rdir[i] + d1*dnorm[i];
						/* accidental reflection? */
			if (hastexture &&
				DOT(p.rdir,r->ron)*hastexture >= -FTINY) {
				d1 *= (double)hastexture;
				for (i = 0; i < 3; i++)	/* ignore texture */
					p.rdir[i] = nratio*r->rdir[i] +
							d1*r->ron[i];
				normalize(p.rdir);	/* not exact */
			} else
				checknorm(p.rdir);
#ifdef  DISPERSE
			if (m->otype != MAT_DIELECTRIC
					|| r->rod > 0.0
					|| r->crtype & SHADOW
					|| !directvis
					|| m->oargs.farg[4] == 0.0
					|| !disperse(m, r, p.rdir,
							trans, ctrans, talb))
#endif
			{
				copycolor(p.cext, ctrans);
				copycolor(p.albedo, talb);
				rayvalue(&p);
				multcolor(p.rcol, p.rcoef);
				addcolor(r->rcol, p.rcol);
						/* virtual distance */
				if (flatsurface ||
					(1.-FTINY <= nratio) &
						(nratio <= 1.+FTINY))
					r->rxt = r->rot + raydistance(&p);
			}
		}
	}
	setcolor(p.rcoef, refl, refl, refl);

	if (!(r->crtype & SHADOW) &&
			rayorigin(&p, REFLECTED, r, p.rcoef) == 0) {

					/* compute reflected ray */
		VSUM(p.rdir, r->rdir, dnorm, 2.*cos1);
					/* accidental penetration? */
		if (hastexture && DOT(p.rdir,r->ron)*hastexture <= FTINY)
			VSUM(p.rdir, r->rdir, r->ron, 2.*r->rod);
		checknorm(p.rdir);
		rayvalue(&p);			/* reflected ray value */

		multcolor(p.rcol, p.rcoef);	/* color contribution */
		copycolor(r->mcol, p.rcol);
		addcolor(r->rcol, p.rcol);
						/* virtual distance */
		r->rmt = r->rot;
		if (flatsurface)
			r->rmt += raydistance(&p);
	}
				/* rayvalue() computes absorption */
	return(1);
}
Esempio n. 27
0
static int
disperse(  /* check light sources for dispersion */
	OBJREC  *m,
	RAY  *r,
	FVECT  vt,
	double  tr,
	COLOR  cet,
	COLOR  abt
)
{
	RAY  sray;
	const RAY  *entray;
	FVECT  v1, v2, n1, n2;
	FVECT  dv, v2Xdv;
	double  v2Xdvv2Xdv;
	int  success = 0;
	SRCINDEX  si;
	FVECT  vtmp1, vtmp2;
	double  dtmp1, dtmp2;
	int  l1, l2;
	COLOR  ctmp;
	int  i;
	
	/*
	 *     This routine computes dispersion to the first order using
	 *  the following assumptions:
	 *
	 *	1) The dependency of the index of refraction on wavelength
	 *		is approximated by Hartmann's equation with lambda0
	 *		equal to zero.
	 *	2) The entry and exit locations are constant with respect
	 *		to dispersion.
	 *
	 *     The second assumption permits us to model dispersion without
	 *  having to sample refracted directions.  We assume that the
	 *  geometry inside the material is constant, and concern ourselves
	 *  only with the relationship between the entering and exiting ray.
	 *  We compute the first derivatives of the entering and exiting
	 *  refraction with respect to the index of refraction.  This 
	 *  is then used in a first order Taylor series to determine the
	 *  index of refraction necessary to send the exiting ray to each
	 *  light source.
	 *     If an exiting ray hits a light source within the refraction
	 *  boundaries, we sum all the frequencies over the disc of the
	 *  light source to determine the resulting color.  A smaller light
	 *  source will therefore exhibit a sharper spectrum.
	 */

	if (!(r->crtype & REFRACTED)) {		/* ray started in material */
		VCOPY(v1, r->rdir);
		n1[0] = -r->rdir[0]; n1[1] = -r->rdir[1]; n1[2] = -r->rdir[2];
	} else {
						/* find entry point */
		for (entray = r; entray->rtype != REFRACTED;
				entray = entray->parent)
			;
		entray = entray->parent;
		if (entray->crtype & REFRACTED)		/* too difficult */
			return(0);
		VCOPY(v1, entray->rdir);
		VCOPY(n1, entray->ron);
	}
	VCOPY(v2, vt);			/* exiting ray */
	VCOPY(n2, r->ron);

					/* first order dispersion approx. */
	dtmp1 = 1./DOT(n1, v1);
	dtmp2 = 1./DOT(n2, v2);
	for (i = 0; i < 3; i++)
		dv[i] = v1[i] + v2[i] - n1[i]*dtmp1 - n2[i]*dtmp2;
		
	if (DOT(dv, dv) <= FTINY)	/* null effect */
		return(0);
					/* compute plane normal */
	fcross(v2Xdv, v2, dv);
	v2Xdvv2Xdv = DOT(v2Xdv, v2Xdv);

					/* check sources */
	initsrcindex(&si);
	while (srcray(&sray, r, &si)) {

		if (DOT(sray.rdir, v2) < MINCOS)
			continue;			/* bad source */
						/* adjust source ray */

		dtmp1 = DOT(v2Xdv, sray.rdir) / v2Xdvv2Xdv;
		sray.rdir[0] -= dtmp1 * v2Xdv[0];
		sray.rdir[1] -= dtmp1 * v2Xdv[1];
		sray.rdir[2] -= dtmp1 * v2Xdv[2];

		l1 = lambda(m, v2, dv, sray.rdir);	/* mean lambda */

		if (l1 > MAXLAMBDA || l1 < MINLAMBDA)	/* not visible */
			continue;
						/* trace source ray */
		copycolor(sray.cext, cet);
		copycolor(sray.albedo, abt);
		normalize(sray.rdir);
		rayvalue(&sray);
		if (bright(sray.rcol) <= FTINY)	/* missed it */
			continue;
		
		/*
		 *	Compute spectral sum over diameter of source.
		 *  First find directions for rays going to opposite
		 *  sides of source, then compute wavelengths for each.
		 */
		 
		fcross(vtmp1, v2Xdv, sray.rdir);
		dtmp1 = sqrt(si.dom  / v2Xdvv2Xdv / PI);

							/* compute first ray */
		VSUM(vtmp2, sray.rdir, vtmp1, dtmp1);

		l1 = lambda(m, v2, dv, vtmp2);		/* first lambda */
		if (l1 < 0)
			continue;
							/* compute second ray */
		VSUM(vtmp2, sray.rdir, vtmp1, -dtmp1);

		l2 = lambda(m, v2, dv, vtmp2);		/* second lambda */
		if (l2 < 0)
			continue;
					/* compute color from spectrum */
		if (l1 < l2)
			spec_rgb(ctmp, l1, l2);
		else
			spec_rgb(ctmp, l2, l1);
		multcolor(ctmp, sray.rcol);
		scalecolor(ctmp, tr);
		addcolor(r->rcol, ctmp);
		success++;
	}
	return(success);
}
Esempio n. 28
0
/* Load previously accumulated values */
void
reload_output()
{
	int		i, j;
	MODCONT		*mp;
	int		ofl;
	char		oname[1024];
	char		*fmode = "rb";
	char		*outvfmt;
	LUENT		*oent;
	int		xr, yr;
	STREAMOUT	sout;
	DCOLOR		rgbv;

	if (outfmt == 'a')
		fmode = "r";
	outvfmt = formstr(outfmt);
						/* reload modifier values */
	for (i = 0; i < nmods; i++) {
		mp = (MODCONT *)lu_find(&modconttab,modname[i])->data;
		if (mp->outspec == NULL)
			error(USER, "cannot reload from stdout");
		if (mp->outspec[0] == '!')
			error(USER, "cannot reload from command");
		for (j = 0; ; j++) {		/* load each modifier bin */
			ofl = ofname(oname, mp->outspec, mp->modname, j);
			if (ofl < 0)
				error(USER, "bad output file specification");
			oent = lu_find(&ofiletab, oname);
			if (oent->data != NULL) {
				sout = *(STREAMOUT *)oent->data;
			} else {
				sout.reclen = 0;
				sout.outpipe = 0;
				sout.xr = xres; sout.yr = yres;
				sout.ofp = NULL;
			}
			if (sout.ofp == NULL) {	/* open output as input */
				sout.ofp = fopen(oname, fmode);
				if (sout.ofp == NULL) {
					if (j == mp->nbins)
						break;	/* assume end of modifier */
					sprintf(errmsg, "missing reload file '%s'",
							oname);
					error(WARNING, errmsg);
					break;
				}
#ifdef getc_unlocked
				flockfile(sout.ofp);
#endif
				if (header && checkheader(sout.ofp, outvfmt, NULL) != 1) {
					sprintf(errmsg, "format mismatch for '%s'",
							oname);
					error(USER, errmsg);
				}
				if ((sout.xr > 0) & (sout.yr > 0) &&
						(!fscnresolu(&xr, &yr, sout.ofp) ||
							(xr != sout.xr) |
							(yr != sout.yr))) {
					sprintf(errmsg, "resolution mismatch for '%s'",
							oname);
					error(USER, errmsg);
				}
			}
							/* read in RGB value */
			if (!get_contrib(rgbv, sout.ofp)) {
				if (!j) {
					fclose(sout.ofp);
					break;		/* ignore empty file */
				}
				if (j < mp->nbins) {
					sprintf(errmsg, "missing data in '%s'",
							oname);
					error(USER, errmsg);
				}
				break;
			}
			if (j >= mp->nbins) {		/* check modifier size */
				sprintf(errmsg,
				"mismatched -bn setting for reloading '%s'",
						modname[i]);
				error(USER, errmsg);
			}
				
			copycolor(mp->cbin[j], rgbv);
			if (oent->key == NULL)		/* new file entry */
				oent->key = strcpy((char *)
						malloc(strlen(oname)+1), oname);
			if (oent->data == NULL)
				oent->data = (char *)malloc(sizeof(STREAMOUT));
			*(STREAMOUT *)oent->data = sout;
		}
	}
	lu_doall(&ofiletab, &myclose, NULL);	/* close all files */
}
Esempio n. 29
0
static void
dirbrdf(		/* compute source contribution */
	COLOR  cval,			/* returned coefficient */
	void  *nnp,		/* material data */
	FVECT  ldir,			/* light source direction */
	double  omega			/* light source size */
)
{
	BRDFDAT *np = nnp;
	double  ldot;
	double  dtmp;
	COLOR  ctmp;
	FVECT  ldx;
	static double  vldx[5], pt[MAXDIM];
	char	**sa;
	int	i;
#define lddx (vldx+1)

	setcolor(cval, 0.0, 0.0, 0.0);
	
	ldot = DOT(np->pnorm, ldir);

	if (ldot <= FTINY && ldot >= -FTINY)
		return;		/* too close to grazing */

	if (ldot < 0.0 ? np->trans <= FTINY : np->trans >= 1.0-FTINY)
		return;		/* wrong side */

	if (ldot > 0.0) {
		/*
		 *  Compute and add diffuse reflected component to returned
		 *  color.  The diffuse reflected component will always be
		 *  modified by the color of the material.
		 */
		copycolor(ctmp, np->rdiff);
		dtmp = ldot * omega / PI;
		scalecolor(ctmp, dtmp);
		addcolor(cval, ctmp);
	} else {
		/*
		 *  Diffuse transmitted component.
		 */
		copycolor(ctmp, np->tdiff);
		dtmp = -ldot * omega / PI;
		scalecolor(ctmp, dtmp);
		addcolor(cval, ctmp);
	}
	if (ldot > 0.0 ? np->rspec <= FTINY : np->tspec <= FTINY)
		return;		/* diffuse only */
					/* set up function */
	setbrdfunc(np);
	sa = np->mp->oargs.sarg;
	errno = 0;
					/* transform light vector */
	multv3(ldx, ldir, funcxf.xfm);
	for (i = 0; i < 3; i++)
		lddx[i] = ldx[i]/funcxf.sca;
	lddx[3] = omega;
					/* compute BRTDF */
	if (np->mp->otype == MAT_BRTDF) {
		if (sa[6][0] == '0')		/* special case */
			colval(ctmp,RED) = 0.0;
		else
			colval(ctmp,RED) = funvalue(sa[6], 4, lddx);
		if (sa[7][0] == '0')
			colval(ctmp,GRN) = 0.0;
		else if (!strcmp(sa[7],sa[6]))
			colval(ctmp,GRN) = colval(ctmp,RED);
		else
			colval(ctmp,GRN) = funvalue(sa[7], 4, lddx);
		if (!strcmp(sa[8],sa[6]))
			colval(ctmp,BLU) = colval(ctmp,RED);
		else if (!strcmp(sa[8],sa[7]))
			colval(ctmp,BLU) = colval(ctmp,GRN);
		else
			colval(ctmp,BLU) = funvalue(sa[8], 4, lddx);
		dtmp = bright(ctmp);
	} else if (np->dp == NULL) {
		dtmp = funvalue(sa[0], 4, lddx);
		setcolor(ctmp, dtmp, dtmp, dtmp);
	} else {
		for (i = 0; i < np->dp->nd; i++)
			pt[i] = funvalue(sa[3+i], 4, lddx);
		vldx[0] = datavalue(np->dp, pt);
		dtmp = funvalue(sa[0], 5, vldx);
		setcolor(ctmp, dtmp, dtmp, dtmp);
	}
	if ((errno == EDOM) | (errno == ERANGE)) {
		objerror(np->mp, WARNING, "compute error");
		return;
	}
	if (dtmp <= FTINY)
		return;
	if (ldot > 0.0) {
		/*
		 *  Compute reflected non-diffuse component.
		 */
		if ((np->mp->otype == MAT_MFUNC) | (np->mp->otype == MAT_MDATA))
			multcolor(ctmp, np->mcolor);
		dtmp = ldot * omega * np->rspec;
		scalecolor(ctmp, dtmp);
		addcolor(cval, ctmp);
	} else {
		/*
		 *  Compute transmitted non-diffuse component.
		 */
		if ((np->mp->otype == MAT_TFUNC) | (np->mp->otype == MAT_TDATA))
			multcolor(ctmp, np->mcolor);
		dtmp = -ldot * omega * np->tspec;
		scalecolor(ctmp, dtmp);
		addcolor(cval, ctmp);
	}
#undef lddx
}
Esempio n. 30
0
static void
pixtoval(void)				/* convert picture to values */
{
	register COLOR	*scanln;
	int  dogamma;
	COLOR  lastc;
	RREAL  hv[2];
	int  startprim, endprim;
	long  startpos;
	int  y;
	register int  x;

	scanln = (COLOR *)malloc(scanlen(&picres)*sizeof(COLOR));
	if (scanln == NULL) {
		fprintf(stderr, "%s: out of memory\n", progname);
		quit(1);
	}
	dogamma = gamcor < .95 || gamcor > 1.05;
	if (putprim == ALL && !interleave) {
		startprim = RED; endprim = BLU;
		startpos = ftell(fin);
	} else {
		startprim = putprim; endprim = putprim;
	}
	for (putprim = startprim; putprim <= endprim; putprim++) {
		if (putprim != startprim && fseek(fin, startpos, 0)) {
			fprintf(stderr, "%s: seek error on input file\n",
					progname);
			quit(1);
		}
		set_io();
		setcolor(lastc, 0.0, 0.0, 0.0);
		for (y = 0; y < numscans(&picres); y++) {
			if (freadscan(scanln, scanlen(&picres), fin) < 0) {
				fprintf(stderr, "%s: read error\n", progname);
				quit(1);
			}
			for (x = 0; x < scanlen(&picres); x++) {
				if (uniq) {
					if (	colval(scanln[x],RED) ==
							colval(lastc,RED) &&
						colval(scanln[x],GRN) ==
							colval(lastc,GRN) &&
						colval(scanln[x],BLU) ==
							colval(lastc,BLU)	)
						continue;
					else
						copycolor(lastc, scanln[x]);
				}
				if (doexposure)
					multcolor(scanln[x], exposure);
				if (dogamma)
					setcolor(scanln[x],
					pow(colval(scanln[x],RED), 1.0/gamcor),
					pow(colval(scanln[x],GRN), 1.0/gamcor),
					pow(colval(scanln[x],BLU), 1.0/gamcor));
				if (!dataonly) {
					pix2loc(hv, &picres, x, y);
					printf("%7d %7d ",
							(int)(hv[0]*picres.xr),
							(int)(hv[1]*picres.yr));
				}
				if ((*putval)(scanln[x]) < 0) {
					fprintf(stderr, "%s: write error\n",
							progname);
					quit(1);
				}
			}
		}
	}
	free((void *)scanln);
}