|
Graphviz
2.31.20130618.0446
|
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
1.7.5