00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "circle.h"
00024 #include "adjust.h"
00025 #include "pack.h"
00026 #include "neatoprocs.h"
00027
00028 static void twopi_init_node(node_t * n)
00029 {
00030 common_init_node(n);
00031
00032 neato_nodesize(n, GD_flip(n->graph));
00033 ND_pos(n) = ALLOC(GD_ndim(n->graph), 0, double);
00034 }
00035
00036 static void twopi_init_edge(edge_t * e)
00037 {
00038 common_init_edge(e);
00039
00040 ED_factor(e) = late_double(e, E_weight, 1.0, 0.0);
00041 }
00042
00043 static void twopi_init_node_edge(graph_t * g)
00044 {
00045 node_t *n;
00046 edge_t *e;
00047 int i = 0;
00048 rdata* alg = N_NEW(agnnodes(g), rdata);
00049
00050 GD_neato_nlist(g) = N_NEW(agnnodes(g) + 1, node_t *);
00051 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00052 ND_alg(n) = alg + i;
00053 GD_neato_nlist(g)[i++] = n;
00054 twopi_init_node(n);
00055 }
00056 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00057 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00058 twopi_init_edge(e);
00059 }
00060 }
00061 }
00062
00063 void twopi_init_graph(graph_t * g)
00064 {
00065 setEdgeType (g, ET_LINE);
00066
00067 Ndim = GD_ndim(g) = 2;
00068 twopi_init_node_edge(g);
00069 }
00070
00071
00072
00073 void twopi_layout(Agraph_t * g)
00074 {
00075 Agnode_t *ctr = 0;
00076 char *s;
00077
00078 twopi_init_graph(g);
00079 s = agget(g, "root");
00080 if (s && (*s != '\0')) {
00081 ctr = agfindnode(g, s);
00082 if (!ctr) {
00083 agerr(AGWARN, "specified root node \"%s\" was not found.", s);
00084 agerr(AGPREV, "Using default calculation for root node\n");
00085 }
00086 }
00087 if (agnnodes(g)) {
00088 Agraph_t **ccs;
00089 Agraph_t *sg;
00090 Agnode_t *c = NULL;
00091 int ncc;
00092 int i;
00093
00094 ccs = ccomps(g, &ncc, 0);
00095 if (ncc == 1) {
00096 circleLayout(g, ctr);
00097 free(ND_alg(agfstnode(g)));
00098 adjustNodes(g);
00099 spline_edges(g);
00100 } else {
00101 pack_info pinfo;
00102 pack_mode pmode = getPackMode(g, l_node);
00103
00104 for (i = 0; i < ncc; i++) {
00105 sg = ccs[i];
00106 if (ctr && agcontains(sg, ctr))
00107 c = ctr;
00108 else
00109 c = 0;
00110 nodeInduce(sg);
00111 circleLayout(sg, c);
00112 adjustNodes(sg);
00113 }
00114 free(ND_alg(agfstnode(g)));
00115 spline_edges(g);
00116 pinfo.margin = getPack(g, CL_OFFSET, CL_OFFSET);
00117 pinfo.doSplines = 1;
00118 pinfo.mode = pmode;
00119 pinfo.fixed = 0;
00120 packSubgraphs(ncc, ccs, g, &pinfo);
00121 }
00122 for (i = 0; i < ncc; i++) {
00123 agdelete(g, ccs[i]);
00124 }
00125 free(ccs);
00126 }
00127 dotneato_postprocess(g);
00128
00129 }
00130
00131 static void twopi_cleanup_node(node_t * n)
00132 {
00133 if (ND_shape(n))
00134 ND_shape(n)->fns->freefn(n);
00135 free_label(ND_label(n));
00136 memset(&(n->u), 0, sizeof(Agnodeinfo_t));
00137 }
00138
00139 static void twopi_free_splines(edge_t * e)
00140 {
00141 int i;
00142 if (ED_spl(e)) {
00143 for (i = 0; i < ED_spl(e)->size; i++)
00144 free(ED_spl(e)->list[i].list);
00145 free(ED_spl(e)->list);
00146 free(ED_spl(e));
00147 }
00148 ED_spl(e) = NULL;
00149 }
00150
00151 static void twopi_cleanup_edge(edge_t * e)
00152 {
00153 twopi_free_splines(e);
00154 free_label(ED_label(e));
00155 memset(&(e->u), 0, sizeof(Agedgeinfo_t));
00156 }
00157
00158 static void twopi_cleanup_graph(graph_t * g)
00159 {
00160 free(GD_neato_nlist(g));
00161 if (g != g->root) memset(&(g->u), 0, sizeof(Agraphinfo_t));
00162 }
00163
00164 void twopi_cleanup(graph_t * g)
00165 {
00166 node_t *n;
00167 edge_t *e;
00168
00169 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00170 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00171 twopi_cleanup_edge(e);
00172 }
00173 twopi_cleanup_node(n);
00174 }
00175 twopi_cleanup_graph(g);
00176 }