예제 #1
0
/***************************************************************************
 *
 *N  point_in_face_table
 *
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Purpose:
 *P
 *    Test whether a point is inside a face or not.  Must have a valid path-
 *   name to a valid VPF Face file, or else be in graphics mode for the error
 *   message that will result.  Filename must have all directory seperators
 *   escapes; eg. c:\\vpf    NOT c:\vpf
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *   Parameters:
 *A
 *    x        <input> == (float) given point x coordinate.
 *    y        <input> == (float) given point y coordinate.
 *    face_id  <input> == (rspf_int32) face.
 *    fname    <input> == (char *) pathname to VPF face file.
 *    point_in_face_table <output> == VPF_BOOLEAN:
 *                                            1 --> point is inside
 *                                            0 --> point is not inside
 *E
 **************************************************************************/
int point_in_face_table( float x, float y,
			 rspf_int32 face_id,
			 char *fname )
{
   vpf_table_type facetable, ringtable, edgetable;
   char *name;
   int result;

   name = (char *)vpfmalloc( 255*sizeof(char) );

   facetable = vpf_open_table(fname,disk, "rb", NULL );

   strupr(fname);

   strcpy( name, fname );
   dirpath( name );
   strcat( name, "RNG" );
   ringtable = vpf_open_table( name, disk , "rb", NULL );

   strcpy( name, fname );
   dirpath( name );
   strcat( name, "EDG" );
   edgetable = vpf_open_table( name, disk , "rb", NULL );

   free( name );

   result = point_in_face( x, y, face_id, facetable, ringtable, edgetable );

   vpf_close_table(&facetable);
   vpf_close_table(&ringtable);
   vpf_close_table(&edgetable);

   return result;
}
예제 #2
0
void slice_sphere (struct msscene *ms, struct surface *current_surface, double fine_pixel, struct face *fac)
{
	int k, j;
	double yinc, y, rad, fsgn;
	double cir_center[3], cir_axis[3];
	char message[MAXLINE];
	struct leaf *lf;
	struct circle *cir;
	struct variety *vty;
    struct cept *ex;

	vty = fac -> vty;
	if (vty -> type != SPHERE) {
		ex = new_cept (ENUM_ERROR,  INVALID_VALUE,  FATAL_SEVERITY);
		add_function (ex, "slice_sphere");
		add_source (ex, "msrender.c");
        add_long (ex, "variety type", (long) vty -> type);
		return;
	}


	/* check versus window */
	for (k = 0; k < 3; k++) {
		if (vty -> center[k] + vty -> radii[0] < ms -> window[0][k]) return;
		if (vty -> center[k] - vty -> radii[0] > ms -> window[1][k]) return;
	}

	/* plus one for convex; minus one for concave */
	fsgn = ((fac -> shape == CONVEX) ? 1.0 : -1.0);


	/* set up circle for leaf */
	for (k = 0; k < 3; k++) {
		cir_center[k] = vty -> center[k];
		cir_axis[k] = ((k == 1) ? fsgn : 0.0);
	}
	cir = new_circle (cir_center, (double) 0.0, cir_axis);
	if (cir == NULL) {
		add_object (tail_cept, CIRCLE, "leaf circle");
		add_function (tail_cept, "slice_sphere");
		return;
	}
	lf = allocate_leaf ();
	if (lf == NULL) {
		add_object (tail_cept, LEAF, "leaf");
		add_function (tail_cept, "slice_sphere");
		return;
	}

	/* copy atom number from variety to leaf */
	for (j = 0; j < MAXPA; j++)
		lf -> atmnum[j] = fac -> vty -> atmnum[j];
	for (k = 0; k < 3; k++)
		lf -> focus[k] = vty -> center[k];

	/* set up leaf fields */
	lf -> cir = cir;
	lf -> shape = fac -> shape;
	lf -> type = fac -> vty -> type;
	lf -> fac = fac;
	lf -> side = OUTSIDE;
	lf -> comp = fac -> comp;
	lf -> input_hue = fac -> input_hue;

	/* y increment for lines of latitude on sphere */
	yinc = fine_pixel;

	/* one leaf per line of latitude */

	for (y = vty -> center[1] - vty -> radii[0] - yinc / 2;
		y < vty -> center[1] + vty -> radii[0]; y += yinc) {
		/* change circle center */
		cir -> center[1] = y;
		/* radius of circle of latitude */
		rad = (vty -> radii[0] * vty -> radii[0]) - (y - vty -> center[1])
			 * (y - vty -> center[1]);
		if (rad <= 0.0) continue;
		rad = sqrt (rad);
		if (rad <= 0.0) continue;
		cir -> radius = rad;
		/* leaf endpoints: west and east */
		for (j = 0; j < 2; j++)
			for (k = 0; k < 3; k++)
				lf -> ends[j][k] = cir -> center[k];
		lf -> ends[0][0] -= rad;
		lf -> ends[1][0] += rad;
		/* determine accessibility of endpoints of leaf */
		for (j = 0; j < 2; j++) {
			lf -> where[j] = point_in_face (lf -> ends[j], fac, 1);
			if (lf -> where[j] < 0) {
				ms -> n_bad_projection++;
				lf -> where[j] = 0;
			}
		}

		/* cut, clip and render (outer) leaf */
		lf -> cep = 0;
		lf -> clip_ep = 0;
		cut_leaf (ms, current_surface, fine_pixel, lf);
		if (error()) return;

		if (current_surface -> clipping) {
			/* cut, clip and render (inner) leaf */
			for (k = 0; k < 3; k++)
				cir -> axis[k] = ((k == 1) ? -fsgn : 0.0);
			lf -> cep = 0;
			lf -> clip_ep = 0;
			lf -> side = INSIDE;
			cut_leaf (ms, current_surface, fine_pixel, lf);
			if (error()) return;
			/* reset what we changed */
			lf -> side = OUTSIDE;
			for (k = 0; k < 3; k++)
				cir -> axis[k] = ((k == 1) ? fsgn : 0.0);
		}
	}
	free_leaf (lf);
	free_circle (cir);
	return;
}
예제 #3
0
void render_leaf (struct msscene *ms, struct surface *current_surface, double fine_pixel, struct leaf *lf)
{
	int i, k, npoint, x, y, z, shade, hue, atm;
	int inner, point_clipped, point_if;
	int shape, comp, input_hue;
	double input_opacity;
	double opacity;
	double norvect[3], horvect[3], pnt[3];
	static double *points = (double *) NULL;
	struct circle *cir;

	cir = lf -> cir;
	if (cir -> radius <= 0.0) {
		ms -> n_missing_leaves++;
		return;
	}


	/* check leaf circle versus window */
	for (k = 0; k < 3; k++) {
		if (cir -> center[k] + cir -> radius < ms -> window[0][k]) return;
		if (cir -> center[k] - cir -> radius > ms -> window[1][k]) return;
	}

	/* subdivide leaf into points (pixels) */

	npoint = subdivide_leaf (fine_pixel, lf, &points);
	if (npoint < 2) {
		ms -> n_missing_leaves++;
		return;
	}

	/* for each point, compute normal vector, shade, hue */
	for (i = 0; i < npoint; i++) {
		for (k = 0; k < 3; k++)
			pnt[k] = *(points+3*i+k);
		for (k = 0; k < 3; k++) norvect[k] = (*(points+3*i+k)
			- lf -> focus[k]);
		normalize (norvect);
		if (lf -> shape != CONVEX) reverse (norvect);
		/* check every point ? */
		if (lf -> cep) {
			/* check accessibility for problem leaf */
			point_if = point_in_face (points + 3 * i, lf -> fac, 1);
			if (error()) return;
			if (!point_if) continue;
		}
		if (lf -> clip_ep) {
			/* check clipping for problem leaf */
			point_clipped =  current_surface -> clipping && clipped (ms, points + 3 * i);
			if (point_clipped) continue;
		}
		inner = 0;
		/* if no clipping, do not render backward facing pixels */
		if (norvect[2] <= 0.0) {
			if (!(current_surface -> clipping)) continue;
			/* reverse direction of vector */
			inner = 1;
			for (k = 0; k < 3; k++)
				norvect[k] *= (-1.0);
			for (k = 0; k < 3; k++) 
				horvect[k] = norvect[k];
			horvect[2] = 0.0;
			/* move inner side in one & half pixel widths */
			for (k = 0; k < 3; k++)
				*(points+3*i+k) +=
					 current_surface -> surface_thickness * ms -> pixel_width * horvect[k];
		}

		/* convert from surface to screen coordinates */
		x = ftoi (ms, *(points + 3 * i), 0);
		y = ftoi (ms, *(points + 3 * i + 1), 1);
		z = ftoi (ms, *(points + 3 * i + 2), 2);
		
		/* closest atom of (1, 2, 3) atoms to point */
		atm = closest (current_surface, lf, points + 3 * i);
		if (error()) return;
		if (atm <= 0) continue;

		shape = lf -> shape;
		if (lf -> type == CYLINDER) shape = 2;
		if (shape < 1) shape = 1;
		if (shape > 3) shape = 3;
		comp = lf -> comp;
		input_hue = lf -> input_hue;
		input_opacity = 1 - input_hue % 2;
	
		opacity = detopac (atm, inner, comp, shape, current_surface -> scheme, input_opacity);
		if (error()) return;

		/* hue from color scheme */
		hue = determine_hue (ms -> table, current_surface -> scheme, atm, comp, shape, inner, input_hue, 0.0);
		if (error()) return;

		/* get shade (intensity) */
		shade = detsh(ms, norvect, z);
		if (error()) return;

		/* put pixel into depth buffer */
		putpix (ms, current_surface, inner, shade, hue, opacity, x, y, z);
		if (error()) return;
	}
	/* free points of leaf */
	free_doubles (points, 0, VERTS);
}