/* * attach and install edges between clusters. * essentially, class2() for interclust edges. */ void interclexp(graph_t* subg) { graph_t *g; node_t *n; edge_t *e,*prev; g = subg->root; for (n = agfstnode(subg); n; n = agnxtnode(subg,n)) { /* N.B. n may be in a sub-cluster of subg */ prev = NULL; for (e = agfstedge(subg->root,n); e; e = agnxtedge(subg->root,e,n)) { if (agcontains(subg,e)) continue; /* short/flat multi edges */ if (mergeable(prev,e)) { if (e->tail->u.rank == e->head->u.rank) e->u.to_virt = prev; else e->u.to_virt = NULL; if (prev->u.to_virt == NULL) continue; /* internal edge */ merge_chain(subg,e,prev->u.to_virt,FALSE); safe_other_edge(e); continue; } /* flat edges */ if (e->tail->u.rank == e->head->u.rank) { if (find_flat_edge(e->tail,e->head) == NULL) { flat_edge(g,e); prev = e; } else prev = NULL; continue; } assert (e->u.to_virt != NULL); /* forward edges */ if (e->head->u.rank > e->tail->u.rank) { make_interclust_chain(g,e->tail,e->head,e); prev = e; continue; } /* backward edges */ else { /* I think that make_interclust_chain should create call other_edge(e) anyway if (agcontains(subg,e->tail) && agfindedge(subg->root,e->head,e->tail)) other_edge(e); */ make_interclust_chain(g,e->head,e->tail,e); prev = e; } } } }
/* * attach and install edges between clusters. * essentially, class2() for interclust edges. */ void interclexp(graph_t * subg) { graph_t *g; node_t *n; edge_t *e, *prev, *next; g = agroot(subg); for (n = agfstnode(subg); n; n = agnxtnode(subg, n)) { /* N.B. n may be in a sub-cluster of subg */ prev = NULL; for (e = agfstedge(agroot(subg), n); e; e = next) { next = agnxtedge(agroot(subg), e, n); if (agcontains(subg, e)) continue; #ifdef WITH_CGRAPH /* canonicalize edge */ e = AGMKOUT(e); #endif /* short/flat multi edges */ if (mergeable(prev, e)) { if (ND_rank(agtail(e)) == ND_rank(aghead(e))) ED_to_virt(e) = prev; else ED_to_virt(e) = NULL; if (ED_to_virt(prev) == NULL) continue; /* internal edge */ merge_chain(subg, e, ED_to_virt(prev), FALSE); safe_other_edge(e); continue; } /* flat edges */ if (ND_rank(agtail(e)) == ND_rank(aghead(e))) { edge_t* fe; if ((fe = find_flat_edge(agtail(e), aghead(e))) == NULL) { flat_edge(g, e); prev = e; } else if (e != fe) { safe_other_edge(e); if (!ED_to_virt(e)) merge_oneway(e, fe); } continue; } /* This assertion is still valid if the new ranking is not used */ #ifndef WITH_CGRAPH assert(ED_to_virt(e) != NULL); #endif /* forward edges */ if (ND_rank(aghead(e)) > ND_rank(agtail(e))) { make_interclust_chain(g, agtail(e), aghead(e), e); prev = e; continue; } /* backward edges */ else { /* I think that make_interclust_chain should create call other_edge(e) anyway if (agcontains(subg,agtail(e)) && agfindedge(subg->root,aghead(e),agtail(e))) other_edge(e); */ make_interclust_chain(g, aghead(e), agtail(e), e); prev = e; } } } }