Пример #1
0
int
r_face(			/* convert a face */
	int	ac,
	char	**av
)
{
	static int	nfaces;
	int		myi = invert;
	char	*mat;
	register int	i;
	register C_VERTEX	*cv;
	FVECT	v;

					/* check argument count and type */
	if (ac < 4)
		return(MG_EARGC);
	if ((mat = material()) == NULL)	/* get material */
		return(MG_EBADMAT);
	if (ac <= 5) {				/* check for smoothing */
		C_VERTEX	*cva[5];
		for (i = 1; i < ac; i++) {
			if ((cva[i-1] = c_getvert(av[i])) == NULL)
				return(MG_EUNDEF);
			if (is0vect(cva[i-1]->n))
				break;
		}
		if (i < ac)
			i = ISFLAT;
		else
			i = flat_tri(cva[0]->p, cva[1]->p, cva[2]->p,
					cva[0]->n, cva[1]->n, cva[2]->n);
		if (i == DEGEN)
			return(MG_OK);		/* degenerate (error?) */
		if (i == RVBENT) {
			myi = !myi;
			i = ISBENT;
		} else if (i == RVFLAT) {
			myi = !myi;
			i = ISFLAT;
		}
		if (i == ISBENT) {		/* smoothed triangles */
			do_tri(mat, cva[0], cva[1], cva[2], myi);
			if (ac == 5)
				do_tri(mat, cva[2], cva[3], cva[0], myi);
			return(MG_OK);
		}
	}
					/* spit out unsmoothed primitive */
	printf("\n%s polygon %sf%d\n", mat, object(), ++nfaces);
	printf("0\n0\n%d\n", 3*(ac-1));
	for (i = 1; i < ac; i++) {	/* get, transform, print each vertex */
		if ((cv = c_getvert(av[myi ? ac-i : i])) == NULL)
			return(MG_EUNDEF);
		xf_xfmpoint(v, cv->p);
		putv(v);
	}
	return(MG_OK);
}
Пример #2
0
void
triangle(	/* put out a triangle */
	char	*pn,
	char	*mod,
	char	*obj,
	VERTEX	*v1,
	VERTEX	*v2,
	VERTEX	*v3
)
{
	static char	vfmt[] = "%18.12g %18.12g %18.12g\n";
	static int	ntri = 0;
	int		flatness = ISFLAT;
	BARYCCM	bvecs;
	RREAL	bvm[3][3];
	int	i;
					/* compute barycentric coordinates */
	if (v1->flags & v2->flags & v3->flags & (V_HASINDX|V_HASNORM))
		if (comp_baryc(&bvecs, v1->pos, v2->pos, v3->pos) < 0)
			return;
					/* check flatness */
	if (v1->flags & v2->flags & v3->flags & V_HASNORM) {
		flatness = flat_tri(v1->pos, v2->pos, v3->pos,
					v1->nor, v2->nor, v3->nor);
		if (flatness == DEGEN)
			return;
	}
					/* put out texture (if any) */
	if (flatness == ISBENT || flatness == RVBENT) {
		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++) {
			bvm[i][0] = v1->nor[i];
			bvm[i][1] = v2->nor[i];
			bvm[i][2] = v3->nor[i];
		}
		put_baryc(&bvecs, bvm, 3);
	}
					/* put out pattern (if any) */
	if (*pn && (v1->flags & v2->flags & v3->flags & V_HASINDX)) {
		printf("\n%s colorpict %s\n", mod, PATNAME);
		mod = PATNAME;
		printf("7 noneg noneg noneg %s %s u v\n", pn, TCALNAME);
		printf("0\n");
		for (i = 0; i < 2; i++) {
			bvm[i][0] = v1->ndx[i];
			bvm[i][1] = v2->ndx[i];
			bvm[i][2] = v3->ndx[i];
		}
		put_baryc(&bvecs, bvm, 2);
	}
					/* put out (reversed) triangle */
	printf("\n%s polygon %s.%d\n", mod, obj, ++ntri);
	printf("0\n0\n9\n");
	if (flatness == RVFLAT || flatness == RVBENT) {
		printf(vfmt, v3->pos[0],v3->pos[1],v3->pos[2]);
		printf(vfmt, v2->pos[0],v2->pos[1],v2->pos[2]);
		printf(vfmt, v1->pos[0],v1->pos[1],v1->pos[2]);
	} else {
		printf(vfmt, v1->pos[0],v1->pos[1],v1->pos[2]);
		printf(vfmt, v2->pos[0],v2->pos[1],v2->pos[2]);
		printf(vfmt, v3->pos[0],v3->pos[1],v3->pos[2]);
	}
}
Пример #3
0
int				/* create an extended triangle */
cvtri(
	OBJECT	mo,
	FVECT	vp1,
	FVECT	vp2,
	FVECT	vp3,
	FVECT	vn1,
	FVECT	vn2,
	FVECT	vn3,
	RREAL	vc1[2],
	RREAL	vc2[2],
	RREAL	vc3[2]
)
{
	static OBJECT	fobj = OVOID;
	char		buf[32];
	int		flags;
	TRIDATA		*ts;
	FACE		*f;
	OBJREC		*fop;
	int		j;
	
	flags = MT_V;		/* check what we have */
	if (vn1 != NULL && vn2 != NULL && vn3 != NULL) {
		RREAL	*rp;
		switch (flat_tri(vp1, vp2, vp3, vn1, vn2, vn3)) {
		case ISBENT:
			flags |= MT_N;
			/* fall through */
		case ISFLAT:
			break;
		case RVBENT:
			flags |= MT_N;
			rp = vn1; vn1 = vn3; vn3 = rp;
			/* fall through */
		case RVFLAT:
			rp = vp1; vp1 = vp3; vp3 = rp;
			rp = vc1; vc1 = vc3; vc3 = rp;
			break;
		case DEGEN:
			error(WARNING, "degenerate triangle");
			return(0);
		default:
			error(INTERNAL, "bad return from flat_tri()");
		}
	}
	if (vc1 != NULL && vc2 != NULL && vc3 != NULL)
		flags |= MT_UV;
	if (fobj == OVOID) {	/* create new triangle object */
		fobj = newobject();
		if (fobj == OVOID)
			goto nomem;
		fop = objptr(fobj);
		fop->omod = mo;
		fop->otype = OBJ_FACE;
		sprintf(buf, "t%ld", (long)fobj);
		fop->oname = savqstr(buf);
		fop->oargs.nfargs = 9;
		fop->oargs.farg = (RREAL *)malloc(9*sizeof(RREAL));
		if (fop->oargs.farg == NULL)
			goto nomem;
	} else {		/* else reuse failed one */
		fop = objptr(fobj);
		if (fop->otype != OBJ_FACE || fop->oargs.nfargs != 9)
			error(CONSISTENCY, "code error 1 in cvtri");
	}
	for (j = 3; j--; ) {
		fop->oargs.farg[j] = vp1[j];
		fop->oargs.farg[3+j] = vp2[j];
		fop->oargs.farg[6+j] = vp3[j];
	}
				/* create face record */
	f = getface(fop);
	if (f->area == 0.) {
		free_os(fop);
		return(0);
	}
	if (fop->os != (char *)f)
		error(CONSISTENCY, "code error 2 in cvtri");
				/* follow with auxliary data */
	f = (FACE *)realloc((void *)f, sizeof(FACE)+tdsize(flags));
	if (f == NULL)
		goto nomem;
	fop->os = (char *)f;
	ts = (TRIDATA *)(f+1);
	ts->fl = flags;
	ts->obj = OVOID;
	if (flags & MT_N)
		for (j = 3; j--; ) {
			ts->vn[0][j] = vn1[j];
			ts->vn[1][j] = vn2[j];
			ts->vn[2][j] = vn3[j];
		}
	if (flags & MT_UV)
		for (j = 2; j--; ) {
			ts->vc[0][j] = vc1[j];
			ts->vc[1][j] = vc2[j];
			ts->vc[2][j] = vc3[j];
		}
	else
		vc1 = vc2 = vc3 = NULL;
				/* update bounds */
	add2bounds(vp1, vc1);
	add2bounds(vp2, vc2);
	add2bounds(vp3, vc3);
	fobj = OVOID;		/* we used this one */
	return(1);
nomem:
	error(SYSTEM, "out of memory in cvtri");
	return(0);
}
Пример #4
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);
}