00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #define FDP_PRIVATE 1
00026
00027 #include "tlayout.h"
00028 #include "neatoprocs.h"
00029 #include "agxbuf.h"
00030
00031 static void initialPositions(graph_t * g)
00032 {
00033 int i;
00034 node_t *np;
00035 attrsym_t *possym;
00036 attrsym_t *pinsym;
00037 double *pvec;
00038 char *p;
00039 char c;
00040
00041 possym = agfindattr(g->proto->n, "pos");
00042 if (!possym)
00043 return;
00044 pinsym = agfindattr(g->proto->n, "pin");
00045 for (i = 0; (np = GD_neato_nlist(g)[i]); i++) {
00046 p = agxget(np, possym->index);
00047 if (p[0]) {
00048 pvec = ND_pos(np);
00049 c = '\0';
00050 if (sscanf(p, "%lf,%lf%c", pvec, pvec + 1, &c) >= 2) {
00051 if (PSinputscale > 0.0) {
00052 int i;
00053 for (i = 0; i < NDIM; i++)
00054 pvec[i] = pvec[i] / PSinputscale;
00055 }
00056 ND_pinned(np) = P_SET;
00057 if ((c == '!')
00058 || (pinsym && mapbool(agxget(np, pinsym->index))))
00059 ND_pinned(np) = P_PIN;
00060 } else
00061 fprintf(stderr,
00062 "Warning: node %s, position %s, expected two floats\n",
00063 np->name, p);
00064 }
00065 }
00066 }
00067
00068 static void fdp_initNode(node_t * n)
00069 {
00070 neato_init_node(n);
00071 }
00072
00073
00074
00075 static void init_edge(edge_t * e, attrsym_t * E_len)
00076 {
00077 ED_factor(e) = late_double(e, E_weight, 1.0, 0.0);
00078 ED_dist(e) = late_double(e, E_len, fdp_parms.K, 0.0);
00079
00080 common_init_edge(e);
00081 }
00082
00083 void fdp_init_node_edge(graph_t * g)
00084 {
00085 attrsym_t *E_len;
00086 node_t *n;
00087 edge_t *e;
00088 int nn = agnnodes(g);
00089 int i;
00090 ndata* alg = N_NEW(nn, ndata);
00091
00092 processClusterEdges(g);
00093
00094 GD_neato_nlist(g) = N_NEW(nn + 1, node_t *);
00095
00096 for (i = 0, n = agfstnode(g); n; n = agnxtnode(g, n)) {
00097 fdp_initNode (n);
00098 ND_alg(n) = alg + i;
00099 GD_neato_nlist(g)[i] = n;
00100 ND_id(n) = i++;
00101 }
00102
00103 E_len = agfindattr(g->proto->e, "len");
00104 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00105 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00106 init_edge(e, E_len);
00107 }
00108 }
00109 initialPositions(g);
00110
00111 }
00112
00113 static void fdp_cleanup_node(node_t * n)
00114 {
00115 free(ND_pos(n));
00116 if (ND_shape(n))
00117 ND_shape(n)->fns->freefn(n);
00118 free_label(ND_label(n));
00119 memset(&(n->u), 0, sizeof(Agnodeinfo_t));
00120 }
00121
00122 static void fdp_free_splines(edge_t * e)
00123 {
00124 int i;
00125 if (ED_spl(e)) {
00126 for (i = 0; i < ED_spl(e)->size; i++)
00127 free(ED_spl(e)->list[i].list);
00128 free(ED_spl(e)->list);
00129 free(ED_spl(e));
00130 }
00131 ED_spl(e) = NULL;
00132 }
00133
00134 static void fdp_cleanup_edge(edge_t * e)
00135 {
00136 fdp_free_splines(e);
00137 free_label(ED_label(e));
00138 memset(&(e->u), 0, sizeof(Agedgeinfo_t));
00139 }
00140
00141 static void cleanup_subgs(graph_t * g)
00142 {
00143 graph_t *mg;
00144 edge_t *me;
00145 node_t *mn;
00146 graph_t *subg;
00147
00148 mg = g->meta_node->graph;
00149 for (me = agfstout(mg, g->meta_node); me; me = agnxtout(mg, me)) {
00150 mn = me->head;
00151 subg = agusergraph(mn);
00152 free_label(GD_label(subg));
00153 if (GD_alg(subg)) {
00154 free(PORTS(subg));
00155 free(GD_alg(subg));
00156 }
00157 cleanup_subgs(subg);
00158 }
00159 }
00160
00161 static void fdp_cleanup_graph(graph_t * g)
00162 {
00163 cleanup_subgs(g);
00164 free(GD_neato_nlist(g));
00165 free(GD_alg(g));
00166 if (g != g->root) memset(&(g->u), 0, sizeof(Agraphinfo_t));
00167 }
00168
00169 void fdp_cleanup(graph_t * g)
00170 {
00171 node_t *n;
00172 edge_t *e;
00173
00174 n = agfstnode(g);
00175 free(ND_alg(n));
00176 for (; n; n = agnxtnode(g, n)) {
00177 for (e = agfstedge(g, n); e; e = agnxtedge(g, e, n)) {
00178 fdp_cleanup_edge(e);
00179 }
00180 fdp_cleanup_node(n);
00181 }
00182 fdp_cleanup_graph(g);
00183 }