From: Emden R. Gansner Date: Wed, 7 May 2014 14:43:39 +0000 (-0400) Subject: Partial fix for trouble in init_rank bug. When clusters occur, mincross X-Git-Tag: TRAVIS_CI_BUILD_EXPERIMENTAL~216^2~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bec1ac56a7bb01845e3183cf650c5121cc4a580d;p=graphviz Partial fix for trouble in init_rank bug. When clusters occur, mincross does not save and restore the best layout since is relied on GD_nlist, which is not being set up for clusters. We use the rank arrays instead to get the relevant nodes. --- diff --git a/lib/dotgen/mincross.c b/lib/dotgen/mincross.c index 5142feec5..a7d041c7b 100644 --- a/lib/dotgen/mincross.c +++ b/lib/dotgen/mincross.c @@ -26,11 +26,6 @@ #define saveorder(v) (ND_coord(v)).x #define flatindex(v) ND_low(v) -static int gd_minrank(Agraph_t *g) {return GD_minrank(g);} -static int gd_maxrank(Agraph_t *g) {return GD_maxrank(g);} -static rank_t *gd_rank(Agraph_t *g, int r) {return &GD_rank(g)[r];} -static int nd_order(Agnode_t *v) { return ND_order(v); } - /* forward declarations */ static boolean medians(graph_t * g, int r0, int r1); static int nodeposcmpf(node_t ** n0, node_t ** n1); @@ -51,6 +46,11 @@ static void restore_best(graph_t * g); static adjmatrix_t *new_matrix(int i, int j); static void free_matrix(adjmatrix_t * p); #ifdef DEBUG +static int gd_minrank(Agraph_t *g) {return GD_minrank(g);} +static int gd_maxrank(Agraph_t *g) {return GD_maxrank(g);} +static rank_t *gd_rank(Agraph_t *g, int r) {return &GD_rank(g)[r];} +static int nd_order(Agnode_t *v) { return ND_order(v); } + void check_rs(graph_t * g, int null_ok); void check_order(void); void check_vlists(graph_t * g); @@ -68,6 +68,84 @@ static edge_t **TE_list; static int *TI_list; static boolean ReMincross; +#ifdef DEBUG +static void indent(graph_t* g) +{ + if (g->parent) { + fprintf (stderr, " "); + indent(g->parent); + } +} + +static char* nname(node_t* v) +{ + static char buf[1000]; + if (ND_node_type(v)) { + if (ND_ranktype(v) == CLUSTER) + sprintf (buf, "v%s_%p", agnameof(ND_clust(v)), v); + else + sprintf (buf, "v_%p", v); + } else + sprintf (buf, "%s", agnameof(v)); + return buf; +} +static void dumpg (graph_t* g) +{ + int j, i, r; + node_t* v; + edge_t* e; + + fprintf (stderr, "digraph A {\n"); + for (r = GD_minrank(g); r <= GD_maxrank(g); r++) { + fprintf (stderr, " subgraph {rank=same "); + for (i = 0; i < GD_rank(g)[r].n; i++) { + v = GD_rank(g)[r].v[i]; + if (i > 0) + fprintf (stderr, " -> %s", nname(v)); + else + fprintf (stderr, "%s", nname(v)); + } + if (i > 1) fprintf (stderr, " [style=invis]}\n"); + else fprintf (stderr, " }\n"); + } + for (r = GD_minrank(g); r < GD_maxrank(g); r++) { + for (i = 0; i < GD_rank(g)[r].n; i++) { + v = GD_rank(g)[r].v[i]; + for (j = 0; (e = ND_out(v).list[j]); j++) { + fprintf (stderr, "%s -> ", nname(v)); + fprintf (stderr, "%s\n", nname(aghead(e))); + } + } + } + fprintf (stderr, "}\n"); +} +static void dumpr (graph_t* g, int edges) +{ + int j, i, r; + node_t* v; + edge_t* e; + + for (r = GD_minrank(g); r <= GD_maxrank(g); r++) { + fprintf (stderr, "[%d] ", r); + for (i = 0; i < GD_rank(g)[r].n; i++) { + v = GD_rank(g)[r].v[i]; + fprintf (stderr, "%s(%.02f,%d) ", nname(v), saveorder(v),ND_order(v)); + } + fprintf (stderr, "\n"); + } + if (edges == 0) return; + for (r = GD_minrank(g); r < GD_maxrank(g); r++) { + for (i = 0; i < GD_rank(g)[r].n; i++) { + v = GD_rank(g)[r].v[i]; + for (j = 0; (e = ND_out(v).list[j]); j++) { + fprintf (stderr, "%s -> ", nname(v)); + fprintf (stderr, "%s\n", nname(aghead(e))); + } + } + } +} +#endif + /* dot_mincross: * Minimize edge crossings * Note that nodes are not placed into GD_rank(g) until mincross() @@ -635,10 +713,16 @@ static int mincross(graph_t * g, int startpass, int endpass, int doBalance) static void restore_best(graph_t * g) { node_t *n; - int r; + int i, r; - for (n = GD_nlist(g); n; n = ND_next(n)) - ND_order(n) = saveorder(n); + /* for (n = GD_nlist(g); n; n = ND_next(n)) */ + /* ND_order(n) = saveorder(n); */ + for (r = GD_minrank(g); r <= GD_maxrank(g); r++) { + for (i = 0; i < GD_rank(g)[r].n; i++) { + n = GD_rank(g)[r].v[i]; + ND_order(n) = saveorder(n); + } + } for (r = GD_minrank(g); r <= GD_maxrank(g); r++) { GD_rank(Root)[r].valid = FALSE; qsort(GD_rank(g)[r].v, GD_rank(g)[r].n, sizeof(GD_rank(g)[0].v[0]), @@ -649,8 +733,15 @@ static void restore_best(graph_t * g) static void save_best(graph_t * g) { node_t *n; - for (n = GD_nlist(g); n; n = ND_next(n)) - saveorder(n) = ND_order(n); + /* for (n = GD_nlist(g); n; n = ND_next(n)) */ + /* saveorder(n) = ND_order(n); */ + int i, r; + for (r = GD_minrank(g); r <= GD_maxrank(g); r++) { + for (i = 0; i < GD_rank(g)[r].n; i++) { + n = GD_rank(g)[r].v[i]; + saveorder(n) = ND_order(n); + } + } } /* merges the connected components of g */