Graphviz  2.31.20130618.0446
lib/dotgen/class1.c
Go to the documentation of this file.
00001 /* $Id$ $Revision$ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /*************************************************************************
00005  * Copyright (c) 2011 AT&T Intellectual Property 
00006  * All rights reserved. This program and the accompanying materials
00007  * are made available under the terms of the Eclipse Public License v1.0
00008  * which accompanies this distribution, and is available at
00009  * http://www.eclipse.org/legal/epl-v10.html
00010  *
00011  * Contributors: See CVS logs. Details at http://www.graphviz.org/
00012  *************************************************************************/
00013 
00014 
00015 /*
00016  * Classify edges for rank assignment phase to
00017  * create temporary edges.
00018  */
00019 
00020 #include "dot.h"
00021 
00022 
00023 int nonconstraint_edge(edge_t * e)
00024 {
00025     char *constr;
00026 
00027 #ifndef WITH_CGRAPH
00028     if (E_constr && (constr = agxget(e, E_constr->index))) {
00029 #else /* WITH_CGRAPH */
00030     if (E_constr && (constr = agxget(e, E_constr))) {
00031 #endif /* WITH_CGRAPH */
00032         if (constr[0] && mapbool(constr) == FALSE)
00033             return TRUE;
00034     }
00035     return FALSE;
00036 }
00037 
00038 static void 
00039 interclust1(graph_t * g, node_t * t, node_t * h, edge_t * e)
00040 {
00041     node_t *v, *t0, *h0;
00042     int offset, t_len, h_len, t_rank, h_rank;
00043     edge_t *rt, *rh;
00044 
00045     if (ND_clust(agtail(e)))
00046         t_rank = ND_rank(agtail(e)) - ND_rank(GD_leader(ND_clust(agtail(e))));
00047     else
00048         t_rank = 0;
00049     if (ND_clust(aghead(e)))
00050         h_rank = ND_rank(aghead(e)) - ND_rank(GD_leader(ND_clust(aghead(e))));
00051     else
00052         h_rank = 0;
00053     offset = ED_minlen(e) + t_rank - h_rank;
00054     if (offset > 0) {
00055         t_len = 0;
00056         h_len = offset;
00057     } else {
00058         t_len = -offset;
00059         h_len = 0;
00060     }
00061 
00062     v = virtual_node(g);
00063     ND_node_type(v) = SLACKNODE;
00064     t0 = UF_find(t);
00065     h0 = UF_find(h);
00066     rt = make_aux_edge(v, t0, t_len, CL_BACK * ED_weight(e));
00067     rh = make_aux_edge(v, h0, h_len, ED_weight(e));
00068     ED_to_orig(rt) = ED_to_orig(rh) = e;
00069 }
00070 void class1(graph_t * g)
00071 {
00072     node_t *n, *t, *h;
00073     edge_t *e, *rep;
00074 
00075     mark_clusters(g);
00076     for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00077         for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00078 
00079             /* skip edges already processed */
00080             if (ED_to_virt(e))
00081                 continue;
00082 
00083             /* skip edges that we want to ignore in this phase */
00084             if (nonconstraint_edge(e))
00085                 continue;
00086 
00087             t = UF_find(agtail(e));
00088             h = UF_find(aghead(e));
00089 
00090             /* skip self, flat, and intra-cluster edges */
00091             if (t == h)
00092                 continue;
00093 
00094 
00095             /* inter-cluster edges require special treatment */
00096             if (ND_clust(t) || ND_clust(h)) {
00097                 interclust1(g, agtail(e), aghead(e), e);
00098                 continue;
00099             }
00100 
00101             if ((rep = find_fast_edge(t, h)))
00102                 merge_oneway(e, rep);
00103             else
00104                 virtual_edge(t, h, e);
00105 
00106 #ifdef NOTDEF
00107             if ((t == agtail(e)) && (h == aghead(e))) {
00108                 if (rep = find_fast_edge(t, h))
00109                     merge_oneway(e, rep);
00110                 else
00111                     virtual_edge(t, h, e);
00112             } else {
00113                 f = agfindedge(g, t, h);
00114                 if (f && (ED_to_virt(f) == NULL))
00115                     rep = virtual_edge(t, h, f);
00116                 else
00117                     rep = find_fast_edge(t, h);
00118                 if (rep)
00119                     merge_oneway(e, rep);
00120                 else
00121                     virtual_edge(t, h, e);
00122             }
00123 #endif
00124         }
00125     }
00126 }
00127