예제 #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
int
r_sph(			/* put out a sphere */
	int	ac,
	char	**av
)
{
	static int	nsphs;
	char	*mat;
	double	rad;
	C_VERTEX	*cv;
	FVECT	cent;
	int	inv;
					/* check argument count and type */
	if (ac != 3)
		return(MG_EARGC);
	if (!isflt(av[2]))
		return(MG_ETYPE);
	if ((cv = c_getvert(av[1])) == NULL)	/* get center vertex */
		return(MG_EUNDEF);
	xf_xfmpoint(cent, cv->p);		/* transform center */
	rad = xf_scale(atof(av[2]));		/* scale radius */
	if ((inv = rad < 0.))			/* check for inversion */
		rad = -rad;
	if ((mat = material()) == NULL)		/* get material */
		return(MG_EBADMAT);
						/* spit out primitive */
	printf("\n%s %s %ss%d\n", mat, inv ? "bubble" : "sphere",
			object(), ++nsphs);
	printf("0\n0\n4 %18.12g %18.12g %18.12g %18.12g\n",
			cent[0], cent[1], cent[2], rad);
	return(MG_OK);
}
예제 #3
0
int
i_sph(			/* translate sphere description */
	int	ac,
	char	**av
)
{
	register C_VERTEX	*cent;

	if (ac != 3)
		return(MG_EARGC);
	flush_cache();		/* flush vertex cache */
	printf("%sSeparator {\n", tabs);
	indent(1);
				/* put out current material */
	if (put_material() < 0)
		return(MG_EBADMAT);
				/* get center */
	if ((cent = c_getvert(av[1])) == NULL)
		return(MG_EUNDEF);
				/* get radius */
	if (!isflt(av[2]))
		return(MG_ETYPE);
	printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs,
			cent->p[0], cent->p[1], cent->p[2]);
	printf("%sSphere { radius %s }\n", tabs, av[2]);
	indent(0);
	printf("%s}\n", tabs);
	return(MG_OK);
}
예제 #4
0
int
r_cone(			/* put out a cone */
	int	ac,
	char	**av
)
{
	static int	ncones;
	char	*mat;
	double	r1, r2;
	C_VERTEX	*cv1, *cv2;
	FVECT	p1, p2;
	int	inv;
					/* check argument count and type */
	if (ac != 5)
		return(MG_EARGC);
	if (!isflt(av[2]) || !isflt(av[4]))
		return(MG_ETYPE);
					/* get the endpoint vertices */
	if ((cv1 = c_getvert(av[1])) == NULL ||
			(cv2 = c_getvert(av[3])) == NULL)
		return(MG_EUNDEF);
	xf_xfmpoint(p1, cv1->p);	/* transform endpoints */
	xf_xfmpoint(p2, cv2->p);
	r1 = xf_scale(atof(av[2]));	/* scale radii */
	r2 = xf_scale(atof(av[4]));
	inv = r1 < 0.;			/* check for inverted cone */
	if (r1 == 0.) {			/* check for illegal radii */
		if (r2 == 0.)
			return(MG_EILL);
		inv = r2 < 0.;
	} else if (r2 != 0. && inv ^ (r2 < 0.))
		return(MG_EILL);
	if (inv) {
		r1 = -r1;
		r2 = -r2;
	}
	if ((mat = material()) == NULL)	/* get material */
		return(MG_EBADMAT);
					/* spit the sucker out */
	printf("\n%s %s %sc%d\n", mat, inv ? "cup" : "cone",
			object(), ++ncones);
	printf("0\n0\n8\n");
	putv(p1);
	putv(p2);
	printf("%18.12g %18.12g\n", r1, r2);
	return(MG_OK);
}
예제 #5
0
int
i_cyl(			/* translate a cylinder description */
	int	ac,
	char	**av
)
{
	register C_VERTEX	*v1, *v2;
	FVECT	va;
	double	length, angle;

	if (ac != 4)
		return(MG_EARGC);
	flush_cache();		/* flush vertex cache */
	printf("%sSeparator {\n", tabs);
	indent(1);
				/* put out current material */
	if (put_material() < 0)
		return(MG_EBADMAT);
				/* get endpoints */
	if (((v1 = c_getvert(av[1])) == NULL) | ((v2 = c_getvert(av[3])) == NULL))
		return(MG_EUNDEF);
				/* get radius */
	if (!isflt(av[2]))
		return(MG_ETYPE);
				/* compute transform */
	va[0] = v2->p[0] - v1->p[0];
	va[1] = v2->p[1] - v1->p[1];
	va[2] = v2->p[2] - v1->p[2];
	length = VLEN(va);
	angle = Acos(va[1]/length);
	printf("%sTranslation { translation %13.9g %13.9g %13.9g }\n", tabs,
			.5*(v1->p[0]+v2->p[0]), .5*(v1->p[1]+v2->p[1]),
			.5*(v1->p[2]+v2->p[2]));
	printf("%sRotation { rotation %.9g %.9g %.9g %.9g }\n", tabs,
			va[2], 0., -va[0], angle);
				/* open-ended */
	printf("%sCylinder { parts SIDES height %13.9g radius %s }\n", tabs,
			length, av[2]);
	indent(0);
	printf("%s}\n", tabs);
	return(MG_OK);
}
예제 #6
0
int
r_cyl(			/* put out a cylinder */
	int	ac,
	char	**av
)
{
	static int	ncyls;
	char	*mat;
	double	rad;
	C_VERTEX	*cv1, *cv2;
	FVECT	p1, p2;
	int	inv;
					/* check argument count and type */
	if (ac != 4)
		return(MG_EARGC);
	if (!isflt(av[2]))
		return(MG_ETYPE);
					/* get the endpoint vertices */
	if ((cv1 = c_getvert(av[1])) == NULL ||
			(cv2 = c_getvert(av[3])) == NULL)
		return(MG_EUNDEF);
	xf_xfmpoint(p1, cv1->p);	/* transform endpoints */
	xf_xfmpoint(p2, cv2->p);
	rad = xf_scale(atof(av[2]));	/* scale radius */
	if ((inv = rad < 0.))		/* check for inverted cylinder */
		rad = -rad;
	if ((mat = material()) == NULL)	/* get material */
		return(MG_EBADMAT);
					/* spit out the primitive */
	printf("\n%s %s %scy%d\n", mat, inv ? "tube" : "cylinder",
			object(), ++ncyls);
	printf("0\n0\n7\n");
	putv(p1);
	putv(p2);
	printf("%18.12g\n", rad);
	return(MG_OK);
}
예제 #7
0
int
i_face(			/* translate an N-sided face */
	int	ac,
	char	**av
)
{
	static char	lastmat[MAXID];
	struct face	*newf;
	register C_VERTEX	*vp;
	register LUENT	*lp;
	register int	i;

	if (ac < 4)
		return(MG_EARGC);
	if ( strcmp(lastmat, curmatname) || c_cmaterial->clock ||
			nverts == 0 || nverts+ac-1 >= MAXVERT) {
		flush_cache();			/* new cache */
		lu_init(&vert_tab, MAXVERT);
		printf("%sSeparator {\n", tabs);
		indent(1);
		if (put_material() < 0)		/* put out material */
			return(MG_EBADMAT);
		(void)strcpy(lastmat, curmatname);
	}
				/* allocate new face */
	if ((newf = newface(ac-1)) == NULL)
		return(MG_EMEM);
	newf->nv = ac-1;
				/* get vertex references */
	for (i = 0; i < newf->nv; i++) {
		if ((vp = c_getvert(av[i+1])) == NULL)
			return(MG_EUNDEF);
		setvkey(vlist[nverts], vp);
		lp = lu_find(&vert_tab, vlist[nverts]);
		if (lp == NULL)
			return(MG_EMEM);
		if (lp->key == NULL)
			lp->key = (char *)vlist[nverts++];
		newf->vl[i] = ((char (*)[VFLEN])lp->key - vlist);
	}
				/* add to face list */
	newf->next = NULL;
	if (flist == NULL)
		flist = newf;
	else
		flast->next = newf;
	flast = newf;
	return(MG_OK);		/* we'll actually put it out later */
}
예제 #8
0
int
r_ring(			/* put out a ring */
	int	ac,
	char	**av
)
{
	static int	nrings;
	char	*mat;
	double	r1, r2;
	C_VERTEX	*cv;
	FVECT	cent, norm;
					/* check argument count and type */
	if (ac != 4)
		return(MG_EARGC);
	if (!isflt(av[2]) || !isflt(av[3]))
		return(MG_ETYPE);
	if ((cv = c_getvert(av[1])) == NULL)	/* get center vertex */
		return(MG_EUNDEF);
	if (is0vect(cv->n))			/* make sure we have normal */
		return(MG_EILL);
	xf_xfmpoint(cent, cv->p);		/* transform center */
	xf_rotvect(norm, cv->n);		/* rotate normal */
	r1 = xf_scale(atof(av[2]));		/* scale radii */
	r2 = xf_scale(atof(av[3]));
	if ((r1 < 0.) | (r2 <= r1))
		return(MG_EILL);
	if ((mat = material()) == NULL)		/* get material */
		return(MG_EBADMAT);
						/* spit out primitive */
	printf("\n%s ring %sr%d\n", mat, object(), ++nrings);
	printf("0\n0\n8\n");
	putv(cent);
	putv(norm);
	printf("%18.12g %18.12g\n", r1, r2);
	return(MG_OK);
}