/* initGraphAttrs: * Set attributes based on original root graph. * This is obtained by taking a node of g, finding its node * in the original graph, and finding that node's graph. */ static void initGraphAttrs(Agraph_t * g, circ_state * state) { static Agraph_t *rootg; static attrsym_t *N_artpos; static attrsym_t *N_root; static attrsym_t *G_mindist; static char *rootname; Agraph_t *rg; node_t *n = agfstnode(g); rg = agraphof(ORIGN(n)); if (rg != rootg) { /* new root graph */ state->blockCount = 0; rootg = rg; G_mindist = agattr(rootg,AGRAPH, "mindist", NULL); N_artpos = agattr(rootg,AGNODE, "articulation_pos", NULL); N_root = agattr(rootg,AGNODE, "root", NULL); } rootname = agget(rootg, "root"); initBlocklist(&state->bl); state->orderCount = 1; state->min_dist = late_double(rootg, G_mindist, MINDIST, 0.0); state->N_artpos = N_artpos; state->N_root = N_root; state->rootname = rootname; }
/* makeDerivedNode: * Make a node in the derived graph, with the given name. * orig points to what it represents, either a real node or * a cluster. Copy size info from original node; needed for * adjustNodes and packSubgraphs. */ static node_t *makeDerivedNode(graph_t * dg, char *name, int isNode, void *orig) { node_t *n = agnode(dg, name,1); agbindrec(n, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE); //node custom data ND_alg(n) = (void *) NEW(cdata); if (isNode) { ND_pos(n) = N_NEW(Ndim, double); ND_lw(n) = ND_lw((node_t *) orig); ND_rw(n) = ND_rw((node_t *) orig); ND_ht(n) = ND_ht((node_t *) orig); ORIGN(n) = (node_t *) orig; } else
/* largest_nodesize: * Return max dimension of nodes on list */ static double largest_nodesize(nodelist_t * list) { Agnode_t *n; nodelistitem_t *item; double size = 0; for (item = list->first; item; item = item->next) { n = ORIGN(item->curr); if (ND_width(n) > size) size = ND_width(n); if (ND_height(n) > size) size = ND_height(n); } return size; }
/* find_blocks: */ static void find_blocks(Agraph_t * g, circ_state * state) { Agnode_t *n; Agnode_t *root = NULL; block_t *rootBlock = NULL; blocklist_t ublks; #ifdef USER_BLOCKS graph_t *clust_subg; graph_t *mg; edge_t *me; node_t *mm; int isRoot; #endif initBlocklist(&ublks); /* check to see if there is a node which is set to be the root */ if (state->rootname) { root = agfindnode(g, state->rootname); } if (!root && state->N_root) { for (n = agfstnode(g); n; n = agnxtnode(g, n)) { if (late_bool(ORIGN(n), state->N_root, 0)) { root = n; break; } } } #ifdef USER_BLOCKS /* process clusters first */ /* by construction, all subgraphs are blocks and are non-empty */ mm = g->meta_node; mg = mm->graph; for (me = agfstout(mg, mm); me; me = agnxtout(mg, me)) { block_t *block; clust_subg = agusergraph(me->head); isRoot = 0; block = mkBlock(clust_subg); /* block = makeBlock(g, state); */ for (n = agfstnode(clust_subg); n; n = agnxtnode(clust_subg, n)) { if (!BCDONE(n)) { /* test not necessary if blocks disjoint */ SET_BCDONE(n); BLOCK(n) = block; if (n == root) isRoot = 1; } } if (isRoot) { /* Assume blocks are disjoint, so don't check if rootBlock is * already assigned. */ rootBlock = block; insertBlock(&state->bl, block); } else { appendBlock(&state->bl, block); } } ublks.first = state->bl.first; ublks.last = state->bl.last; #endif if (!root) root = agfstnode(g); dfs(g, root, state, !rootBlock); #ifdef USER_BLOCKS /* If g has user-supplied blocks, it may be disconnected. * We then fall into the following ugly loop. * We are guaranteed !VISITED(n) and PARENT(n) has been * set to a visited node. */ if (ublks.first) { while (n = findUnvisited(&ublks)) { dfs(g, n, state, 0); } } #endif }