Пример #1
0
static int
puttri(			/* convert a triangle */
	char	*v1,
	char	*v2,
	char	*v3
)
{
	VNDX	v1i, v2i, v3i;
	RREAL	*v1c, *v2c, *v3c;
	RREAL	*v1n, *v2n, *v3n;
	
	if (!cvtndx(v1i, v1) || !cvtndx(v2i, v2) || !cvtndx(v3i, v3)) {
		error(WARNING, "bad vertex reference");
		return(0);
	}
	if (v1i[1]>=0 && v2i[1]>=0 && v3i[1]>=0) {
		v1c = vtlist[v1i[1]];
		v2c = vtlist[v2i[1]];
		v3c = vtlist[v3i[1]];
	} else
		v1c = v2c = v3c = NULL;

	if (v1i[2]>=0 && v2i[2]>=0 && v3i[2]>=0) {
		v1n = vnlist[v1i[2]];
		v2n = vnlist[v2i[2]];
		v3n = vnlist[v3i[2]];
	} else
		v1n = v2n = v3n = NULL;
	
	return(cvtri(getmod(), vlist[v1i[0]], vlist[v2i[0]], vlist[v3i[0]],
			v1n, v2n, v3n, v1c, v2c, v3c) >= 0);
}
Пример #2
0
int
nonplanar(			/* are vertices non-planar? */
	int	ac,
	char	**av
)
{
	VNDX	vi;
	RREAL	*p0, *p1;
	FVECT	v1, v2, nsum, newn;
	double	d;
	int	i;

	if (!cvtndx(vi, av[0]))
		return(0);
	if (!flatten && vi[2] >= 0)
		return(1);		/* has interpolated normals */
	if (ac < 4)
		return(0);		/* it's a triangle! */
					/* set up */
	p0 = vlist[vi[0]];
	if (!cvtndx(vi, av[1]))
		return(0);		/* error gets caught later */
	nsum[0] = nsum[1] = nsum[2] = 0.;
	p1 = vlist[vi[0]];
	fvsum(v2, p1, p0, -1.0);
	for (i = 2; i < ac; i++) {
		VCOPY(v1, v2);
		if (!cvtndx(vi, av[i]))
			return(0);
		p1 = vlist[vi[0]];
		fvsum(v2, p1, p0, -1.0);
		fcross(newn, v1, v2);
		if (normalize(newn) == 0.0) {
			if (i < 3)
				return(1);	/* can't deal with this */
			fvsum(nsum, nsum, nsum, 1./(i-2));
			continue;
		}
		d = fdot(newn,nsum);
		if (d >= 0) {
			if (d < (1.0-FTINY)*(i-2))
				return(1);
			fvsum(nsum, nsum, newn, 1.0);
		} else {
			if (d > -(1.0-FTINY)*(i-2))
				return(1);
			fvsum(nsum, nsum, newn, -1.0);
		}
	}
	return(0);
}
Пример #3
0
int
putface(				/* put out an N-sided polygon */
	int	ac,
	char	**av
)
{
	VNDX	vi;
	char	*cp;
	int	i;

	if (nonplanar(ac, av)) {	/* break into triangles */
		while (ac > 2) {
			if (!puttri(av[0], av[1], av[2]))
				return(0);
			ac--;		/* remove vertex & rotate */
			cp = av[0];
			for (i = 0; i < ac-1; i++)
				av[i] = av[i+2];
			av[i] = cp;
		}
		return(1);
	}
	if ((cp = getmtl()) == NULL)
		return(-1);
	printf("\n%s polygon %s.%d\n", cp, getonm(), faceno);
	printf("0\n0\n%d\n", 3*ac);
	for (i = 0; i < ac; i++) {
		if (!cvtndx(vi, av[i]))
			return(0);
		pvect(vlist[vi[0]]);
	}
	return(1);
}
Пример #4
0
/* determine dominant axis for triangle */
static int
dominant_axis(char *v1, char *v2, char *v3)
{
	VNDX	v1i, v2i, v3i;
	FVECT	e1, e2, vn;
	int	i, imax;

	if (!cvtndx(v1i, v1) || !cvtndx(v2i, v2) || !cvtndx(v3i, v3))
		return(-1);
	VSUB(e1, vlist[v2i[0]], vlist[v1i[0]]);
	VSUB(e2, vlist[v3i[0]], vlist[v2i[0]]);
	VCROSS(vn, e1, e2);
	for (i = imax = 2; i--; )
		if (vn[i]*vn[i] > vn[imax]*vn[imax])
			imax = i;
	return(vn[imax]*vn[imax] > FTINY*FTINY ? imax : -1);
}
Пример #5
0
static int
putface(				/* put out an N-sided polygon */
	int	ac,
	char	**av
)
{
	Vert2_list	*poly = polyAlloc(ac);
	int		i, ax, ay;

	if (poly == NULL)
		return(0);
	poly->p = (void *)av;
	for (i = ac-3; i >= 0; i--)	/* identify dominant axis */
		if ((ax = dominant_axis(av[i], av[i+1], av[i+2])) >= 0)
			break;
	if (ax < 0)
		return(1);		/* ignore degenerate face */
	if (++ax >= 3) ax = 0;
	ay = ax;
	if (++ay >= 3) ay = 0;
	for (i = 0; i < ac; i++) {	/* convert to 2-D polygon */
		VNDX	vi;
		if (!cvtndx(vi, av[i])) {
			error(WARNING, "bad vertex reference");
			polyFree(poly);
			return(0);
		}
		poly->v[i].mX = vlist[vi[0]][ax];
		poly->v[i].mY = vlist[vi[0]][ay];
	}
					/* break into triangles & output */
	if (!polyTriangulate(poly, &tri_out)) {
		sprintf(errmsg, "self-intersecting face with %d vertices", ac);
		error(WARNING, errmsg);
	}
	polyFree(poly);
	return(1);
}
Пример #6
0
int
puttri(			/* put out a triangle */
	char *v1,
	char *v2,
	char *v3
)
{
	char	*mod;
	VNDX	v1i, v2i, v3i;
	BARYCCM	bvecs;
	RREAL	bcoor[3][3];
	int	texOK = 0, patOK;
	int	flatness;
	int	i;

	if ((mod = getmtl()) == NULL)
		return(-1);

	if (!cvtndx(v1i, v1) || !cvtndx(v2i, v2) || !cvtndx(v3i, v3))
		return(0);
					/* compute barycentric coordinates */
	if (v1i[2]>=0 && v2i[2]>=0 && v3i[2]>=0)
		flatness = flat_tri(vlist[v1i[0]], vlist[v2i[0]], vlist[v3i[0]],
				vnlist[v1i[2]], vnlist[v2i[2]], vnlist[v3i[2]]);
	else
		flatness = ISFLAT;

	switch (flatness) {
	case DEGEN:			/* zero area */
		ndegen++;
		return(-1);
	case RVFLAT:			/* reversed normals, but flat */
	case ISFLAT:			/* smoothing unnecessary */
		texOK = 0;
		break;
	case RVBENT:			/* reversed normals with smoothing */
	case ISBENT:			/* proper smoothing */
		texOK = 1;
		break;
	}
	if (flatten)
		texOK = 0;
#ifdef TEXMAPS
	patOK = mapname[0] && (v1i[1]>=0 && v2i[1]>=0 && v3i[1]>=0);
#else
	patOK = 0;
#endif
	if (texOK | patOK)
		if (comp_baryc(&bvecs, vlist[v1i[0]], vlist[v2i[0]],
				vlist[v3i[0]]) < 0)
			texOK = patOK = 0;
					/* put out texture (if any) */
	if (texOK) {
		printf("\n%s texfunc %s\n", mod, TEXNAME);
		mod = TEXNAME;
		printf("4 dx dy dz %s\n", TCALNAME);
		printf("0\n");
		for (i = 0; i < 3; i++) {
			bcoor[i][0] = vnlist[v1i[2]][i];
			bcoor[i][1] = vnlist[v2i[2]][i];
			bcoor[i][2] = vnlist[v3i[2]][i];
		}
		put_baryc(&bvecs, bcoor, 3);
	}
#ifdef TEXMAPS
					/* put out pattern (if any) */
	if (patOK) {
		printf("\n%s colorpict %s\n", mod, PATNAME);
		mod = PATNAME;
		printf("7 noneg noneg noneg %s %s u v\n", mapname, TCALNAME);
		printf("0\n");
		for (i = 0; i < 2; i++) {
			bcoor[i][0] = vtlist[v1i[1]][i];
			bcoor[i][1] = vtlist[v2i[1]][i];
			bcoor[i][2] = vtlist[v3i[1]][i];
		}
		put_baryc(&bvecs, bcoor, 2);
	}
#endif
					/* put out (reversed) triangle */
	printf("\n%s polygon %s.%d\n", mod, getonm(), faceno);
	printf("0\n0\n9\n");
	if (flatness == RVFLAT || flatness == RVBENT) {
		pvect(vlist[v3i[0]]);
		pvect(vlist[v2i[0]]);
		pvect(vlist[v1i[0]]);
	} else {
		pvect(vlist[v1i[0]]);
		pvect(vlist[v2i[0]]);
		pvect(vlist[v3i[0]]);
	}
	return(1);
}