예제 #1
0
int subdivide_leaf (double fine_pixel, struct leaf *lf, double **pntptr)
{
	int j, k, n;
	double alpha;
	struct arc *lfarc;
	struct vertex *lfvtx[2];
    struct cept *ex;

	if (lf -> cir -> radius <= 0.0) {
		return (0);
	}

	lfarc = allocate_arc ();
	if (lfarc == NULL) {
		add_object (tail_cept, ARC, "leaf arc");
		add_function (tail_cept, "subdivide_leaf");
		add_source (tail_cept, "msrender.c");
		return (0);
	}
	for (j = 0; j < 2; j++) {
		lfvtx[j] = allocate_vertex ();
		if (error()) {
			add_object (tail_cept, VERTEX, "leaf vertex");
			add_function (tail_cept, "subdivide_leaf");
			add_source (tail_cept, "msrender.c");
			return (0);
		}
	}
	/* convert to arc for subdivision */
	lfarc -> cir = lf -> cir;
	for (k = 0; k < 3; k++) {
		lfvtx[0] -> center[k] = lf -> ends[0][k];
		lfvtx[1] -> center[k] = lf -> ends[1][k];
	}

	for (j = 0; j < 2; j++)
		lfarc -> vtx[j] = lfvtx[j];

	/* angular parameter for subdivision */
	alpha = fine_pixel / (lf -> cir -> radius);

	/* call geometric subdivision function */
	n = render_sub_arc (lfarc, pntptr, alpha);
	if (error()) return(0);

	free_arc (lfarc);
	for (j = 0; j < 2; j++)
		free_vertex (lfvtx[j]);
	
	return (n); 	/* return number of subdivision points */

}
예제 #2
0
파일: u_drag.c 프로젝트: hhoeflin/xfig
static void
cancel_drag_arc(void)
{
    canvas_ref_proc = canvas_locmove_proc = null_proc;
    elastic_movearc(new_a);
    /* erase last lengths if appres.showlengths is true */
    erase_lengths();
    if (return_proc == copy_selected) {
	free_arc(&new_a);
    } else {
	list_add_arc(&objects.arcs, new_a);
	redisplay_arc(new_a);
    }
    /* turn back on all relevant markers */
    update_markers(new_objmask);
    (*return_proc) ();
    draw_mousefun_canvas();
}
예제 #3
0
파일: u_free.c 프로젝트: harbaum/xfig-gcode
void free_compound(F_compound **list)
{
    F_compound	   *c, *compound;

    for (c = *list; c != NULL;) {
	compound = c;
	c = c->next;
	free_arc(&compound->arcs);
	free_compound(&compound->compounds);
	free_ellipse(&compound->ellipses);
	free_line(&compound->lines);
	free_spline(&compound->splines);
	free_text(&compound->texts);
	if (compound->comments) {
	    free(compound->comments);
	    compound->comments = NULL;
	}
	free((char *) compound);
	compound = NULL;
    }
    *list = NULL;
}
예제 #4
0
void clean_up(void)
{
    if (last_action == F_EDIT) {
	switch (last_object) {
	  case O_ARC:
	    saved_objects.arcs->next = NULL;
	    free_arc(&saved_objects.arcs);
	    break;
	  case O_COMPOUND:
	    saved_objects.compounds->next = NULL;
	    free_compound(&saved_objects.compounds);
	    break;
	  case O_ELLIPSE:
	    saved_objects.ellipses->next = NULL;
	    free_ellipse(&saved_objects.ellipses);
	    break;
	  case O_POLYLINE:
	    saved_objects.lines->next = NULL;
	    free_line(&saved_objects.lines);
	    break;
	  case O_SPLINE:
	    saved_objects.splines->next = NULL;
	    free_spline(&saved_objects.splines);
	    break;
	  case O_TXT:
	    saved_objects.texts->next = NULL;
	    free_text(&saved_objects.texts);
	    break;
	  case O_FIGURE:
	    free((char *) saved_objects.comments);
	    break;
	}
    } else if (last_action==F_DELETE || last_action==F_JOIN || last_action==F_SPLIT) {
	switch (last_object) {
	  case O_ARC:
	    free_arc(&saved_objects.arcs);
	    break;
	  case O_COMPOUND:
	    free_compound(&saved_objects.compounds);
	    break;
	  case O_ELLIPSE:
	    free_ellipse(&saved_objects.ellipses);
	    break;
	  case O_POLYLINE:
	    free_line(&saved_objects.lines);
	    break;
	  case O_SPLINE:
	    free_spline(&saved_objects.splines);
	    break;
	  case O_TXT:
	    free_text(&saved_objects.texts);
	    break;
	  case O_ALL_OBJECT:
	    free_arc(&saved_objects.arcs);
	    free_compound(&saved_objects.compounds);
	    free_ellipse(&saved_objects.ellipses);
	    free_line(&saved_objects.lines);
	    free_spline(&saved_objects.splines);
	    free_text(&saved_objects.texts);
	    break;
	}
    } else if (last_action == F_DELETE_POINT || last_action == F_ADD_POINT) {
	if (last_action == F_DELETE_POINT) {
/**************************************************
	    free((char *) last_selected_point);
	    free((char *) last_selected_sfactor);
**************************************************/
	    last_next_point = NULL;
	}
	last_prev_point = NULL;
	last_selected_point = NULL;
	saved_objects.arcs = NULL;
	saved_objects.compounds = NULL;
	saved_objects.ellipses = NULL;
	saved_objects.lines = NULL;
	saved_objects.splines = NULL;
	saved_objects.texts = NULL;
    } else if (last_action == F_LOAD) {
	free_arc(&saved_objects.arcs);
	free_compound(&saved_objects.compounds);
	free_ellipse(&saved_objects.ellipses);
	free_line(&saved_objects.lines);
	free_spline(&saved_objects.splines);
	free_text(&saved_objects.texts);
    } else if (last_action == F_GLUE) {
	saved_objects.compounds = NULL;
    } else if (last_action == F_BREAK) {
	free((char *) saved_objects.compounds);
	saved_objects.compounds = NULL;
    } else if (last_action == F_ADD || last_action == F_MOVE) {
	saved_objects.arcs = NULL;
	saved_objects.compounds = NULL;
	saved_objects.ellipses = NULL;
	saved_objects.lines = NULL;
	saved_objects.splines = NULL;
	saved_objects.texts = NULL;
	free_linkinfo(&last_links);
    } else if (last_action == F_CONVERT) {
	if (last_object == O_POLYLINE)
	    saved_objects.splines = NULL;
	else
	    saved_objects.lines = NULL;
    } else if (last_action == F_OPEN_CLOSE) {
        saved_objects.splines = NULL;
        saved_objects.lines = NULL;
	free((char *) last_for_arrow);
	free((char *) last_back_arrow);
    } else if (last_action == F_ADD_ARROW_HEAD ||
	       last_action == F_DELETE_ARROW_HEAD) {
	saved_objects.splines = NULL;
	saved_objects.lines = NULL;
	saved_objects.arcs = NULL;
	last_prev_point = NULL;
	last_selected_point = NULL;
    }
    last_action = F_NULL;
}
예제 #5
0
void slice_elbow (struct msscene *ms, struct surface *current_surface, double fine_pixel, struct face *fac)
{
	char message[MAXLINE];
	struct leaf *lf;
	struct circle *lfcir, *torcir;
	struct arc *torarc;
	struct vertex *torvtx[2];
	int i, j, k, nfocus, atmnum;
	double anginc, bigrad;
	double atmcen[3], ccens[2][3], cradii[2];
	double focus[3], vect[3], z_axis[3], base[3];
	struct variety *vty;
	double *foci;
    struct cept *ex;
	
	vty = fac -> vty;
	atmnum = vty -> atmnum[0];
	if (debug >= 2) {
		sprintf (message,"render elbow face for atom %5d", atmnum);
		inform(message);
	}
	for (k = 0; k < 3; k++)
		atmcen[k] = *(current_surface -> atom_centers + 3 * (atmnum - 1) + k);
	for (j = 0; j < 2; j++)
		cradii[j] = vty -> radii[1];
	for (j = 0; j < 2; j++)
		for (k = 0; k < 3; k++) {
			ccens[j][k] = vty -> ccens[j][k];
		}
	bigrad = distance (atmcen, ccens[0]) + cradii[0];
	for (k = 0; k < 3; k++) {
		if (atmcen[k] + bigrad < ms -> window[0][k]) return;
		if (atmcen[k] - bigrad > ms -> window[1][k]) return;
	}
	/* leaf circle */
	lfcir = allocate_circle ();
	if (lfcir == NULL) {
		ex = new_cept (MEMORY_ERROR,  ALLOCATION,  FATAL_SEVERITY);
		add_object (ex, CIRCLE, "leaf circle");
		add_function (ex, "slice_elbow");
		add_source (ex, "msrender.c");
		return;
	}
	/* leaf */
	lf = allocate_leaf ();
	if (lf == NULL) {
		add_object (tail_cept, LEAF, "leaf");
		add_function (tail_cept, "slice_sphere");
		return;
	}
	/* torus circle radius, center, axis */
	torcir = new_circle (vty -> center, vty -> radii[0], vty -> axis);
	if (torcir == NULL) {
		add_object (tail_cept, CIRCLE, "torus circle");
		add_function (tail_cept, "slice_elbow");
		return;
	}
	/* torus arc */
	torarc = allocate_arc ();
	if (torarc == NULL) {
		add_object (tail_cept, ARC, "torus arc");
		add_function (tail_cept, "slice_elbow");
		add_source (tail_cept, "msrender.c");
		return;
	}
	for (j = 0; j < 2; j++) {
		torvtx[j] = allocate_vertex ();
		if (error()) {
			add_object (tail_cept, VERTEX, "torus vertex");
			add_function (tail_cept, "slice_elbow");
			add_source (tail_cept, "msrender.c");
			return;
		}
	}
	/* set up leaf fields */
	for (k = 0; k < MAXPA; k++)
		lf -> atmnum[k] = vty -> atmnum[k];
	lf -> cir = lfcir;
	lf -> shape = CONVEX;		/* to avoid reversing normal vector */
	lf -> type = vty -> type;
	lf -> fac = fac;
	lf -> cep = 0;
	lf -> clip_ep = 0;
	lf -> side = OUTSIDE;
	lf -> comp = fac -> comp;
	lf -> input_hue = fac -> input_hue;
	for (j = 0; j < 2; j++)
		lf -> where[j] = ACCESSIBLE;

	/* setup torus central circle for subdivision */
	anginc = fine_pixel / ((vty -> radii[0] + cradii[0]));
	torcir -> radius = vty -> radii[0];
	for (k = 0; k < 3; k++) {
		torcir -> center[k] = vty -> center[k];
		torcir -> axis[k] = vty -> axis[k];
	}
	torarc -> cir = torcir;
	for (j = 0; j < 2; j++) {
		torarc -> vtx[j] = torvtx[j];
		for (k = 0; k < 3; k++)
			torvtx[j] -> center[k] = ccens[j][k];
	}
	foci = (double *) NULL;
	nfocus = render_sub_arc (torarc, &foci, anginc);
	if (nfocus < 2) {
		ex = new_cept (LOGIC_ERROR, MSUNDERFLOW, FATAL_SEVERITY);
        add_function (ex, "slice_elbow");
        add_source (ex, "msrender.c");
        add_long (ex, "number of foci", (long) nfocus);
		return;
	}

	/* create leaves */
	for (i = 0; i < nfocus; i++) {
		for (k = 0; k < 3; k++) {
			focus[k] = (*(foci + 3 * i + k));
			lfcir -> center[k] = focus[k];
			lf -> focus[k] = focus[k];
		}
		lfcir -> radius = cradii[0];
		/* compute tangent to torus central circle */
		for (k = 0; k < 3; k++)
			vect[k] = focus[k] - vty -> center[k];
		cross (vty -> axis, vect, lfcir -> axis);
		normalize (lfcir -> axis);
		for (k = 0; k < 3; k++)
			z_axis[k] = ((k == 2) ? 1.0 : 0.0);
		cross (lfcir -> axis, z_axis, base);
		if (norm (base) <= 0.0) {
			continue;
		}
		normalize (base);
		for (k = 0; k < 3; k++) {
			lf -> ends[0][k] = lfcir -> center[k] - lfcir -> radius * base[k];
			lf -> ends[1][k] = lfcir -> center[k] + lfcir -> radius * base[k];
		}
		/* clip and render leaf */
		clip_leaf (ms, current_surface, fine_pixel, lf);
		if (error()) return;
	}
	free_doubles (foci, 0, VERTS);
	free_leaf (lf);
	free_arc (torarc);
	free_circle (torcir);
	free_circle (lfcir);
	for (j = 0; j < 2; j++)
		free_vertex (torvtx[j]);
}
예제 #6
0
void slice_torus (struct msscene *ms, struct surface *current_surface, double fine_pixel, double probe_radius, struct face *fac)
{
	int k, j, i, nfocus, near1, naif;
	double anginc, bigrad;
	double focus[3], vect1[3], vect2[3], vect[3], qvect[3];
	double dtq, tcv[3];
	double *foci = (double *) NULL;
	char message[MAXLINE];
	struct leaf *lf;
	struct circle *cir1, *cir2, *cir3;
	struct circle *lfcir, *torcir;
	struct variety *vty, *atm1, *atm2;
	struct arc *a, *nxta;
	struct arc *torarc;
	struct vertex *torvtx[2];
	struct vertex *qvtx;
	struct vertex *conevtx;
	struct cycle *cyc;
	struct edge *edg;
    struct cept *ex;

	vty = fac -> vty;
	if (vty -> type != TORUS) {
		ex = new_cept (GEOMETRY_ERROR,  INCONSISTENCY,  FATAL_SEVERITY);
		add_function (ex, "slice_torus");
		add_source (ex, "msrender.c");
        add_long (ex, "variety type", (long) vty -> type);
		return;
	}
	if (vty -> tube) {
		slice_elbow (ms, current_surface, fine_pixel, fac);
		return;
	}

	if (debug >= 2) {
		sprintf (message,"render saddle face for atoms %5d %5d",
			vty -> atmnum[0], vty -> atmnum[1]);
		inform(message);
	}

	/* get pointers to atom varieties */
	atm1 = *(current_surface -> variety_handles + fac -> vty -> atmnum[0] - 1);
	atm2 = *(current_surface -> variety_handles + fac -> vty -> atmnum[1] - 1);

	/* check versus window */
	bigrad = distance (atm1 -> center, atm2 -> center) +
		atm1 -> radii[0] + atm2 -> radii[0];

	for (k = 0; k < 3; k++) {
		if (vty -> center[k] + bigrad < ms -> window[0][k]) return;
		if (vty -> center[k] - bigrad > ms -> window[1][k]) return;
	}
	/* leaf circle */
	lfcir = allocate_circle ();
	if (error()) {
		add_object (tail_cept, CIRCLE, "leaf circle");
		add_function (tail_cept, "slice_torus");
		return;
	}
	/* leaf */
	lf = allocate_leaf ();
	if (error()) {
		add_object (tail_cept, LEAF, "leaf");
		add_function (tail_cept, "slice_sphere");
		return;
	}
	/* torus circle radius, center, axis */
	torcir = new_circle (vty -> center, vty -> radii[0], vty -> axis);
	if (torcir == NULL) {
		add_object (tail_cept, CIRCLE, "torus circle");
		add_function (tail_cept, "slice_circle");
		return;
	}
	/* torus arc */
	torarc = allocate_arc ();
	if (error()) {
		add_object (tail_cept, ARC, "torus arc");
		add_function (tail_cept, "slice_torus");
		add_source (tail_cept, "msrender.c");
		return;
	}
	for (j = 0; j < 2; j++) {
		torvtx[j] = allocate_vertex ();
		if (error()) {
			add_object (tail_cept, VERTEX, "torus vertex");
			add_function (tail_cept, "slice_torus");
			add_source (tail_cept, "msrender.c");
			return;
		}
	}
	torarc -> cir = torcir;
	/* copy atom numbers from variety to leaf */
	for (k = 0; k < MAXPA; k++)
		lf -> atmnum[k] = fac -> vty -> atmnum[k];

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

	/* both endpoints of saddle face leaf are always accessible */
	for (j = 0; j < 2; j++)
		lf -> where[j] = ACCESSIBLE;

	/* angular increment for rotation of leaf about torus axis */
	anginc = fine_pixel / (vty -> radii[0]);

	/* next we need endpoints for torus arc */
	/* get them from concave arcs bounding saddle face */

	/* intialization */
	cir1 = NULL;
	cir2 = NULL;
	cir3 = NULL;
	qvtx = NULL;
	conevtx = NULL;
	near1 = 0;

	/* look for concave arcs */
	naif = 0;
	for (cyc = fac -> first_cycle; cyc != NULL; cyc = cyc -> next)
		for (edg = cyc -> first_edge; edg != NULL; edg = edg -> next) {
			naif++;
			a = edg -> arcptr;
			if (a -> shape == CONVEX) {
				cir3 = a -> cir;
				continue;
			}
			if (edg -> next == NULL)
				nxta = cyc -> first_edge -> arcptr;
			else
				nxta = edg -> next -> arcptr;
			if (along (edg, vty -> axis))
				cir2 = a -> cir;
			else
				cir1 = a -> cir;
			/* check for cusp vertex */
			if (a -> shape == CONCAVE && nxta -> shape == CONCAVE) {
				/* cusp point joints two concave arcs */
				qvtx = a -> vtx[1-edg->orn];
			}
		}

	dtq = probe_radius * probe_radius - vty -> radii[0] * vty -> radii[0];

	/* later: note: check PI in bubbles */

	if (naif == 1) {
		if (dtq <= 0.0) {
			ex = new_cept (GEOMETRY_ERROR,  INCONSISTENCY,  FATAL_SEVERITY);
			add_function (ex, "slice_torus");
			add_source (ex, "msrender.c");
			add_message(ex, "toroidal face with only one arc, but not cone");
			return;
		}
		if (cir3 == NULL) {
			ex = new_cept (GEOMETRY_ERROR,  INCONSISTENCY,  FATAL_SEVERITY);
			add_function (ex, "slice_torus");
			add_source (ex, "msrender.c");
			add_message(ex, "toroidal face with only one arc, but no contact circle");
			return;
		}
		/* cone */
		qvtx = allocate_vertex ();
		if (error()) {
			add_object (tail_cept, VERTEX, "CUSP VERTEX");
			add_function (tail_cept, "slice_torus");
			add_source (tail_cept, "msrender.c");
			return;
		}
		conevtx = qvtx;
		dtq = sqrt (dtq);
		for (k = 0; k < 3; k++)
			tcv[k] = cir3 -> center[k] - torcir -> center[k];
		normalize (tcv);
		for (k = 0; k < 3; k++)
			qvtx -> center[k] = torcir -> center[k] + dtq * tcv[k];
		/* hope this is enough */
	}
	if (cir1 == NULL) informd2 ("cir1 null");
	if (cir2 == NULL) informd2 ("cir2 null");
	if (qvtx != NULL) informd2 ("cusp present");

	/* check for cusp vertex */
	if (qvtx != NULL) {
		for (k = 0; k < 3; k++)
			qvect[k] = qvtx -> center[k] - vty -> center[k];
		near1 = (dot_product (qvect, vty -> axis) < 0.0);
	}

	/* check for hoop saddle face */
	if (cir1 == NULL || cir2 == NULL) {
		for (j = 0; j < 2; j++)
			torarc -> vtx[j] = NULL;
		informd2 ("complete toroidal hoop");
	}
	else {
		/* concave arc circle centers are endpoints of sphere rolling */
		for (k = 0; k < 3; k++) {
			torvtx[0] -> center[k] = cir1 -> center[k];
			torvtx[1] -> center[k] = cir2 -> center[k];
		}
		for (j = 0; j < 2; j++)
			torarc -> vtx[j] = torvtx[j];
		sprintf (message, "saddle rendering (from): %8.3f %8.3f %8.3f",
			cir1 -> center[0], cir1 -> center[1], cir1 -> center[2]);
		informd2 (message);
		sprintf (message, "saddle rendering (to)  : %8.3f %8.3f %8.3f",
			cir2 -> center[0], cir2 -> center[1], cir2 -> center[2]);
		informd2 (message);
	}

	/* the probe sphere centers are the foci of the leaves */
	nfocus = render_sub_arc (torarc, &foci, anginc);
	if (nfocus < 2) {
		ex = new_cept (LOGIC_ERROR, MSUNDERFLOW, FATAL_SEVERITY);
        add_function (ex, "slice_torus");
        add_source (ex, "msrender.c");
        add_long (ex, "number of foci", (long) nfocus);
		return;
	}
	sprintf (message, "nfocus = %d", nfocus);
	informd2 (message);

	/* create leaves */
	for (i = 0; i < nfocus; i++) {
		for (k = 0; k < 3; k++) {
			focus[k] = (*(foci + 3 * i + k));
			lfcir -> center[k] = focus[k];
			lf -> focus[k] = focus[k];
		}

		/* unit vectors from focus toward atoms */
		for (k = 0; k < 3; k++) {
			vect1[k] = atm1 -> center[k] - focus[k];
			vect2[k] = atm2 -> center[k] - focus[k];
		}
		/* correct for cusp vertex */
		if (qvtx != NULL) {
			if (near1)
				for (k = 0; k < 3; k++)
					vect2[k] = qvtx -> center[k] - focus[k];
			else
				for (k = 0; k < 3; k++)
					vect1[k] = qvtx -> center[k] - focus[k];
		}
		/* normalize vectors to unit length */
		normalize (vect1);
		normalize (vect2);

		/* leaf circle radius is probe radius */
		lfcir -> radius = probe_radius;
		/* set up endpoints of leaf */
		for (k = 0; k < 3; k++) {
			lf -> ends[0][k] = focus[k] + lfcir -> radius * vect1[k];
			lf -> ends[1][k] = focus[k] + lfcir -> radius * vect2[k];
		}
		/* compute leaf circle axis */
		for (k = 0; k < 3; k++)
			vect[k] = focus[k] - vty -> center[k];
		cross (vty -> axis, vect, lfcir -> axis);
		normalize (lfcir -> axis);

		/* clip and render leaf */
		clip_leaf (ms, current_surface, fine_pixel, lf);
		if (error()) return;
	}

	/* return temporary memory */
	if (!free_doubles (foci, 0, VERTS)) {
		ex = new_cept (MEMORY_ERROR,  FREEING,  FATAL_SEVERITY);
		add_variable (ex, VERTS, "foci");
		add_function (ex, "slice_torus");
		add_source (ex, "msrender.c");
		return;
	}

	free_leaf (lf);
	free_arc (torarc);
	free_circle (torcir);
	free_circle (lfcir);
	for (j = 0; j < 2; j++)
		free_vertex (torvtx[j]);
	if (conevtx != NULL) free_vertex (conevtx);
	return;
}