]> granicus.if.org Git - graphviz/commitdiff
Partial fix for trouble in init_rank bug. When clusters occur, mincross
authorEmden R. Gansner <erg@alum.mit.edu>
Wed, 7 May 2014 14:43:39 +0000 (10:43 -0400)
committerEmden R. Gansner <erg@alum.mit.edu>
Wed, 7 May 2014 14:43:39 +0000 (10:43 -0400)
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.

lib/dotgen/mincross.c

index 5142feec5abad3c9f1c488a3dea15a0c0aff0a95..a7d041c7bba89799793f8ee7c66a92b2cb512b5c 100644 (file)
 #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 */