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 */ }
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(); }
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; }
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; }
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]); }
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; }