//------------------------------------------------------------------------------ static Agraph_t *mostra_grafo(Agraph_t *g) { if ( ! g ) return NULL; direcionado = agisdirected(g); n_vertices = agnnodes(g); n_arestas = agnedges(g); lista_arestas = constroi_lista(); printf("strict %sgraph \"%s\" {\n\n", agisdirected(g) ? "di" : "", agnameof(g) ); mostra_vertices(g); printf("\n"); mostra_arestas(); printf("}\n"); destroi_lista(lista_arestas, NULL); return g; }
static void emit (Agraph_t* g, int root) { int n_edges = agnedges(g); int n_nodes = agnnodes(g); int n_cc = 0; int n_cl = 0; char* file = 0; if (flags & CC) n_cc = cc_decompose (g); if (flags & CL) n_cl = GD_cl_cnt(g); if (root) file = fname; wcp (n_nodes, n_edges, n_cc, n_cl, g->name, file); if (root) { n_graphs++; tot_edges += n_edges; tot_nodes += n_nodes; tot_cc += n_cc; tot_cl += n_cl; } }
int main() { FILE * fp = fopen("test", "r"); assert(fp); Agraph_t * graph = agread(fp, NULL); assert(graph); printf("Number of nodes is %d\n", agnnodes(graph)); printf("Number of edges is %d\n", agnedges(graph)); /* Iterate through nodes */ Agnode_t * node = agfstnode(graph); while (node != NULL) { assert(node); printf("Iterating through yet another node\n"); char * label = agget(node, "label"); printf("Node label is %s\n", label); Agedge_t * edge = agfstout(graph, node); while (edge != NULL) { assert(edge); printf("Iterating through yet another edge \n"); assert(agtail(edge) == node); edge = agnxtout(graph, edge); } /* Move on to the next node */ printf("\n"); node = agnxtnode(graph, node); } /* Free graph structure */ agclose(graph); return 0; }
static v_data *makeGraph(Agraph_t* gg, int *nedges) { int i; int ne = agnedges(gg); int nv = agnnodes(gg); v_data *graph = N_NEW(nv, v_data); int *edges = N_NEW(2 * ne + nv, int); /* reserve space for self loops */ float *ewgts = N_NEW(2 * ne + nv, float); Agnode_t *np; Agedge_t *ep; Agraph_t *g = NULL; int i_nedges; ne = 0; i=0; // for (i = 0; i < nv; i++) { for (np = agfstnode(gg); np; np = agnxtnode(gg, np)) { graph[i].edges = edges++; /* reserve space for the self loop */ graph[i].ewgts = ewgts++; #ifdef STYLES graph[i].styles = NULL; #endif i_nedges = 1; /* one for the self */ if (!g) g = agraphof(np); for (ep = agfstedge(g, np); ep; ep = agnxtedge(g, ep, np)) { Agnode_t *vp; Agnode_t *tp = agtail(ep); Agnode_t *hp = aghead(ep); assert(hp != tp); /* FIX: handle multiedges */ vp = (tp == np ? hp : tp); ne++; i_nedges++; // *edges++ = ((temp_node_record *) AGDATA(vp))->TVref; *edges++ = ND_TVref(vp); *ewgts++ = 1; } graph[i].nedges = i_nedges; graph[i].edges[0] = i; graph[i].ewgts[0] = 1 - i_nedges; i++; } ne /= 2; /* each edge counted twice */ *nedges = ne; return graph; }
static void process(Agraph_t* G) { Agnode_t* n; Agraph_t* map; int nc = 0; float nontree_frac; int Maxdegree; Stack stack; sccstate state; aginit(G,AGRAPH,"scc_graph",sizeof(Agraphinfo_t),TRUE); aginit(G,AGNODE,"scc_node",sizeof(Agnodeinfo_t),TRUE); state.Comp = state.ID = 0; state.N_nodes_in_nontriv_SCC = 0; if (Verbose) nc = countComponents(G,&Maxdegree,&nontree_frac); initStack(&stack, agnnodes(G) + 1); map = agopen("scc_map",Agdirected,(Agdisc_t *)0); for (n = agfstnode(G); n; n = agnxtnode(n)) if (getval(n) == 0) visit(n,map,&stack,&state); freeStack(&stack); if (!Silent) agwrite(map,stdout); agclose(map); if (Verbose) fprintf(stderr,"%d %d %d %d %.4f %d %.4f\n", agnnodes(G), agnedges(G), nc, state.Comp, state.N_nodes_in_nontriv_SCC / (double) agnnodes(G), Maxdegree, nontree_frac); else fprintf(stderr,"%d nodes, %d edges, %d strong components\n", agnnodes(G), agnedges(G), state.Comp); }
/* dumpE: */ void dumpE(graph_t * g, int derived) { Agnode_t *n; Agedge_t *e; Agedge_t **ep; Agedge_t *el; int i; int deg; prIndent(); fprintf(stderr, "Graph %s : %d nodes %d edges\n", g->name, agnnodes(g), agnedges(g)); for (n = agfstnode(g); n; n = agnxtnode(g, n)) { deg = 0; for (e = agfstout(g, n); e; e = agnxtout(g, e)) { deg++; prIndent(); fprintf(stderr, " %s -- %s\n", e->tail->name, e->head->name); if (derived) { for (i = 0, ep = (Agedge_t **) ED_to_virt(e); i < ED_count(e); i++, ep++) { el = *ep; prIndent(); fprintf(stderr, " %s -- %s\n", el->tail->name, el->head->name); } } } if (deg == 0) { /* no out edges */ if (!agfstin(g, n)) /* no in edges */ fprintf(stderr, " %s\n", n->name); } } if (!derived) { bport_t *pp; if ((pp = PORTS(g))) { int sz = NPORTS(g); fprintf(stderr, " %d ports\n", sz); while (pp->e) { fprintf(stderr, " %s : %s -- %s\n", pp->n->name, pp->e->tail->name, pp->e->head->name); pp++; } } } }
/* cloneGraph: * Clone node, edge and subgraph structure from src to tgt. */ static void cloneGraph(Agraph_t * tgt, Agraph_t * src) { Agedge_t *e; Agedge_t *ne; Agnode_t *t; Agraph_t *sg; char* name; Dt_t* emap = dtopen (&edgepair, Dtoset); edgepair_t* data = (edgepair_t*)malloc(sizeof(edgepair_t)*agnedges(src)); edgepair_t* ep = data; for (t = agfstnode(src); t; t = agnxtnode(src, t)) { if (!copy(tgt, OBJ(t))) { exerror("error cloning node %s from graph %s", agnameof(t), agnameof(src)); } } for (t = agfstnode(src); t; t = agnxtnode(src, t)) { for (e = agfstout(src, t); e; e = agnxtout(src, e)) { if (!(ne = (Agedge_t*)copy(tgt, OBJ(e)))) { name = agnameof(AGMKOUT(e)); if (name) exerror("error cloning edge (%s,%s)[%s] from graph %s", agnameof(agtail(e)), agnameof(aghead(e)), name, agnameof(src)); else exerror("error cloning edge (%s,%s) from graph %s", agnameof(agtail(e)), agnameof(aghead(e)), agnameof(src)); return; } ep->key = e; ep->val = ne; dtinsert (emap, ep++); } } for (sg = agfstsubg(src); sg; sg = agnxtsubg(sg)) { if (!cloneSubg(tgt, sg, emap)) { exerror("error cloning subgraph %s from graph %s", agnameof(sg), agnameof(src)); } } dtclose (emap); free (data); }
/* mkMCGraph: * Clone original graph. We only need the nodes, edges and clusters. * Copy */ Agraph_t* mkMCGraph (Agraph_t* g) { Agnode_t* t; Agnode_t* newt; Agnode_t* newh; Agedge_t* e; Agedge_t* newe; Agraph_t* sg; edgepair_t* data; edgepair_t* ep; Agraph_t* newg = agopen (agnameof(g), g->desc, 0); Dt_t* emap = dtopen (&edgepair, Dtoset);; data = N_NEW(agnedges(g), edgepair_t); ep = data; for (t = agfstnode(g); t; t = agnxtnode(g, t)) { newt = mkMCNode (newg, STDNODE, agnameof(t)); assert(newt); MND_orig(newt) = t; MND_rank(newt) = ND_rank(t); } for (t = agfstnode(g); t; t = agnxtnode(g, t)) { newt = agnode (newg, agnameof(t), 0); for (e = agfstout(g, t); e; e = agnxtout(g, e)) { newh = agnode (newg, agnameof(aghead(e)), 0); assert(newh); newe = mkMCEdge (newg, newt, newh, agnameof (e), NORMAL, e); assert(newe); ep->key = e; ep->val = newe; dtinsert (emap, ep++); } } for (sg = agfstsubg(g); sg; sg = agnxtsubg(sg)) { cloneSubg(newg, sg, emap); } dtclose (emap); free (data); return newg; }
/* scan_graph_mode: * Prepare the graph and data structures depending on the layout mode. * If Reduce is true, eliminate singletons and trees. Since G may be a * subgraph, we remove the nodes from the root graph. * Return the number of nodes in the reduced graph. */ int scan_graph_mode(graph_t * G, int mode) { int i, lenx, nV, nE, deg; char *str; node_t *np, *xp, *other; double total_len = 0.0; if (Verbose) fprintf(stderr, "Scanning graph %s, %d nodes\n", G->name, agnnodes(G)); /* Eliminate singletons and trees */ if (Reduce) { for (np = agfstnode(G); np; np = xp) { xp = agnxtnode(G, np); deg = degreeKind(G, np, &other); if (deg == 0) { /* singleton node */ agdelete(G->root, np); } else if (deg == 1) { agdelete(G->root, np); xp = prune(G, other, xp); } } } nV = agnnodes(G); nE = agnedges(G); lenx = agindex(G->root->proto->e, "len"); if (mode == MODE_KK) { Epsilon = .0001 * nV; getdouble(G, "epsilon", &Epsilon); if ((str = agget(G->root, "Damping"))) Damping = atof(str); else Damping = .99; GD_neato_nlist(G) = N_NEW(nV + 1, node_t *); for (i = 0, np = agfstnode(G); np; np = agnxtnode(G, np)) { GD_neato_nlist(G)[i] = np; ND_id(np) = i++; ND_heapindex(np) = -1; total_len += setEdgeLen(G, np, lenx); } } else {
/* orthoEdges: * For edges without position information, construct an orthogonal routing. * If doLbls is true, use edge label info when available to guide routing, * and set label pos for those edges for which this info is not available. */ void orthoEdges (Agraph_t* g, int doLbls) { sgraph* sg; maze* mp; int n_edges; route* route_list; int i, gstart; Agnode_t* n; Agedge_t* e; snode* sn; snode* dn; epair_t* es = N_GNEW(agnedges(g), epair_t); cell* start; cell* dest; PointSet* ps; textlabel_t* lbl; if (Concentrate) ps = newPS(); #ifdef DEBUG { char* s = agget(g, "odb"); char c; odb_flags = 0; if (s && (*s != '\0')) { while ((c = *s++)) { switch (c) { case 'c' : odb_flags |= ODB_CHANG; // emit channel graph break; case 'i' : odb_flags |= (ODB_SGRAPH|ODB_IGRAPH); // emit search graphs break; case 'm' : odb_flags |= ODB_MAZE; // emit maze break; case 'r' : odb_flags |= ODB_ROUTE; // emit routes in maze break; case 's' : odb_flags |= ODB_SGRAPH; // emit search graph break; } } } } #endif if (doLbls) { agerr(AGWARN, "Orthogonal edges do not currently handle edge labels. Try using xlabels.\n"); doLbls = 0; } mp = mkMaze (g, doLbls); sg = mp->sg; #ifdef DEBUG if (odb_flags & ODB_SGRAPH) emitSearchGraph (stderr, sg); #endif /* store edges to be routed in es, along with their lengths */ n_edges = 0; for (n = agfstnode (g); n; n = agnxtnode(g, n)) { for (e = agfstout(g, n); e; e = agnxtout(g,e)) { if ((Nop == 2) && ED_spl(e)) continue; if (Concentrate) { int ti = AGID(agtail(e)); int hi = AGID(aghead(e)); if (ti <= hi) { if (isInPS (ps,ti,hi)) continue; else addPS (ps,ti,hi); } else { if (isInPS (ps,hi,ti)) continue; else addPS (ps,hi,ti); } } es[n_edges].e = e; es[n_edges].d = edgeLen (e); n_edges++; } } route_list = N_NEW (n_edges, route); qsort((char *)es, n_edges, sizeof(epair_t), (qsort_cmpf) edgecmp); gstart = sg->nnodes; PQgen (sg->nnodes+2); sn = &sg->nodes[gstart]; dn = &sg->nodes[gstart+1]; for (i = 0; i < n_edges; i++) { #ifdef DEBUG if ((i > 0) && (odb_flags & ODB_IGRAPH)) emitSearchGraph (stderr, sg); #endif e = es[i].e; start = CELL(agtail(e)); dest = CELL(aghead(e)); if (doLbls && (lbl = ED_label(e)) && lbl->set) { } else { if (start == dest) addLoop (sg, start, dn, sn); else { addNodeEdges (sg, dest, dn); addNodeEdges (sg, start, sn); } if (shortPath (sg, dn, sn)) goto orthofinish; } route_list[i] = convertSPtoRoute(sg, sn, dn); reset (sg); } PQfree (); mp->hchans = extractHChans (mp); mp->vchans = extractVChans (mp); assignSegs (n_edges, route_list, mp); if (setjmp(jbuf)) goto orthofinish; assignTracks (n_edges, route_list, mp); #ifdef DEBUG if (odb_flags & ODB_ROUTE) emitGraph (stderr, mp, n_edges, route_list, es); #endif attachOrthoEdges (g, mp, n_edges, route_list, &sinfo, es, doLbls); orthofinish: if (Concentrate) freePS (ps); for (i=0; i < n_edges; i++) free (route_list[i].segs); free (route_list); freeMaze (mp); }
int ggen_read_graph(igraph_t *g,FILE *input) { Agraph_t *cg; Agnode_t *v; Agedge_t *e; igraph_vector_t edges; igraph_vector_t vertices; int err; unsigned long esize; unsigned long vsize; unsigned long from, to; igraph_integer_t eid; Agsym_t *att; /* read the graph */ cg = agread((void *)input,NULL); if(!cg) return 1; if(!agisdirected(cg)) { error("Input graph is undirected\n"); err = 1; goto error_d; } /* init edge array */ err = igraph_vector_init(&edges,2*agnedges(cg)); if(err) goto error_d; err = igraph_vector_init(&vertices,agnnodes(cg)); if(err) goto error_de; /* init igraph */ igraph_empty(g,agnnodes(cg),1); /* asign id to each vertex */ vsize = 0; for(v = agfstnode(cg); v; v = agnxtnode(cg,v)) VECTOR(vertices)[vsize++] = AGID(v); /* loop through each edge */ esize = 0; for(v = agfstnode(cg); v; v = agnxtnode(cg,v)) { from = find_id(AGID(v),vertices,vsize); for(e = agfstout(cg,v); e; e = agnxtout(cg,e)) { to = find_id(AGID(aghead(e)),vertices,vsize); VECTOR(edges)[esize++] = from; VECTOR(edges)[esize++] = to; } } /* finish the igraph */ err = igraph_add_edges(g,&edges,NULL); if(err) goto error; /* read graph properties */ att = agnxtattr(cg,AGRAPH,NULL); while(att != NULL) { /* copy this attribute to igraph */ SETGAS(g,att->name,agxget(cg,att)); att = agnxtattr(cg,AGRAPH,att); } /* we keep the graph name using a special attribute */ SETGAS(g,GGEN_GRAPH_NAME_ATTR,agnameof(cg)); /* read vertex properties */ att = agnxtattr(cg,AGNODE,NULL); while(att != NULL) { /* iterate over all vertices for this attribute */ for(v = agfstnode(cg); v; v = agnxtnode(cg,v)) { from = find_id(AGID(v),vertices,vsize); SETVAS(g,att->name,from,agxget(v,att)); } att = agnxtattr(cg,AGNODE,att); } /* we keep each vertex name in a special attribute */ for(v = agfstnode(cg); v; v = agnxtnode(cg,v)) { from = find_id(AGID(v),vertices,vsize); SETVAS(g,GGEN_VERTEX_NAME_ATTR,from,agnameof(v)); } /* read edges properties */ att = agnxtattr(cg,AGEDGE,NULL); while(att != NULL) { /* the only way to iterate over all edges is to iterate * over the vertices */ for(v = agfstnode(cg); v; v = agnxtnode(cg,v)) { from = find_id(AGID(v),vertices,vsize); for(e = agfstout(cg,v); e; e = agnxtout(cg,e)) { to = find_id(AGID(aghead(e)),vertices,vsize); igraph_get_eid(g,&eid,from,to,1,0); SETEAS(g,att->name,eid,agxget(e,att)); } } att = agnxtattr(cg,AGEDGE,att); } goto cleanup; error: igraph_destroy(g); cleanup: igraph_vector_destroy(&vertices); error_de: igraph_vector_destroy(&edges); error_d: agclose(cg); return err; }
static int visit(Agnode_t * n, Agraph_t * map, Stack * sp, sccstate * st) { unsigned int m, min; Agnode_t *t; Agraph_t *subg; Agedge_t *e; min = ++(st->ID); setval(n, min); push(sp, n); #ifdef USE_CGRAPH for (e = agfstout(n->root, n); e; e = agnxtout(n->root, e)) { #else for (e = agfstout(n); e; e = agnxtout(e)) { #endif t = aghead(e); if (getval(t) == 0) m = visit(t, map, sp, st); else m = getval(t); if (m < min) min = m; } if (getval(n) == min) { if (!wantDegenerateComp && (top(sp) == n)) { setval(n, INF); pop(sp); } else { char name[32]; Agraph_t *G = agraphof(n);; sprintf(name, "cluster_%d", (st->Comp)++); subg = agsubg(G, name, TRUE); agbindrec(subg, "scc_graph", sizeof(Agraphinfo_t), TRUE); setrep(subg, agnode(map, name, TRUE)); do { t = pop(sp); agsubnode(subg, t, TRUE); setval(t, INF); setscc(t, subg); st->N_nodes_in_nontriv_SCC++; } while (t != n); #ifdef USE_CGRAPH nodeInduce(subg, map); #else nodeInduce(subg); #endif if (!Silent) agwrite(subg, stdout); } } return min; } static int label(Agnode_t * n, int nodecnt, int *edgecnt) { Agedge_t *e; setval(n, 1); nodecnt++; #ifdef USE_CGRAPH for (e = agfstedge(n->root, n); e; e = agnxtedge(n->root, e, n)) { #else for (e = agfstedge(n); e; e = agnxtedge(e, n)) { #endif (*edgecnt) += 1; if (e->node == n) e = agopp(e); if (!getval(e->node)) nodecnt = label(e->node, nodecnt, edgecnt); } return nodecnt; } static int countComponents(Agraph_t * g, int *max_degree, float *nontree_frac) { int nc = 0; int sum_edges = 0; int sum_nontree = 0; int deg; int n_edges; int n_nodes; Agnode_t *n; #ifdef USE_CGRAPH for (n = agfstnode(g); n; n = agnxtnode(g, n)) { #else for (n = agfstnode(g); n; n = agnxtnode(n)) { #endif if (!getval(n)) { nc++; n_edges = 0; n_nodes = label(n, 0, &n_edges); sum_edges += n_edges; sum_nontree += (n_edges - n_nodes + 1); } } if (max_degree) { int maxd = 0; #ifdef USE_CGRAPH for (n = agfstnode(g); n; n = agnxtnode(g, n)) { deg = agdegree(g, n, TRUE, TRUE); #else for (n = agfstnode(g); n; n = agnxtnode(n)) { deg = agdegree(n, TRUE, TRUE); #endif if (maxd < deg) maxd = deg; setval(n, 0); } *max_degree = maxd; } if (nontree_frac) { if (sum_edges > 0) *nontree_frac = (float) sum_nontree / (float) sum_edges; else *nontree_frac = 0.0; } return nc; } static void process(Agraph_t * G) { Agnode_t *n; Agraph_t *map; int nc = 0; float nontree_frac = 0; int Maxdegree = 0; Stack stack; sccstate state; aginit(G, AGRAPH, "scc_graph", sizeof(Agraphinfo_t), TRUE); aginit(G, AGNODE, "scc_node", sizeof(Agnodeinfo_t), TRUE); state.Comp = state.ID = 0; state.N_nodes_in_nontriv_SCC = 0; if (Verbose) nc = countComponents(G, &Maxdegree, &nontree_frac); initStack(&stack, agnnodes(G) + 1); map = agopen("scc_map", Agdirected, (Agdisc_t *) 0); #ifdef USE_CGRAPH for (n = agfstnode(G); n; n = agnxtnode(G, n)) #else for (n = agfstnode(G); n; n = agnxtnode(n)) #endif if (getval(n) == 0) visit(n, map, &stack, &state); freeStack(&stack); if (!Silent) agwrite(map, stdout); agclose(map); if (Verbose) fprintf(stderr, "%d %d %d %d %.4f %d %.4f\n", agnnodes(G), agnedges(G), nc, state.Comp, state.N_nodes_in_nontriv_SCC / (double) agnnodes(G), Maxdegree, nontree_frac); else fprintf(stderr, "%d nodes, %d edges, %d strong components\n", agnnodes(G), agnedges(G), state.Comp); } static char *useString = "Usage: %s [-sdv?] <files>\n\ -s - silent\n\ -d - allow degenerate components\n\ -v - verbose\n\ -? - print usage\n\ If no files are specified, stdin is used\n"; static void usage(int v) { printf(useString, CmdName); exit(v); }
grafo le_grafo(FILE *input) { Agraph_t *ag = agread(input, 0); if(!(ag && agisstrict(ag))) return NULL; // struct grafo *g = malloc(sizeof(struct grafo)); grafo g = malloc(sizeof(struct grafo)); if( !g ) return NULL; g->vertices = constroi_lista(); g->nome = malloc(sizeof(char) * strlen(agnameof(ag)+1)); strcpy(g->nome, agnameof(ag)); g->direcionado = agisdirected(ag); g->n_vertices = (unsigned int)agnnodes(ag); g->n_arestas = (unsigned int)agnedges(ag); g->ponderado = 0; for( Agnode_t *v = agfstnode(ag); v; v = agnxtnode(ag,v) ){ vertice vt = malloc(sizeof(struct vertice)); vt->nome = malloc(sizeof(char) * strlen(agnameof(v))+1); strcpy( vt->nome, agnameof(v) ); vt->visitado = 0; vt->coberto = 0; vt->arestas_saida = constroi_lista(); vt->arestas_entrada = constroi_lista(); insere_lista(vt, g->vertices); } for( Agnode_t *v = agfstnode(ag); v; v = agnxtnode(ag,v) ){ vertice vt = busca_vertice(g->vertices, agnameof(v)); if( g-> direcionado ){ for( Agedge_t *e = agfstout(ag,v); e; e = agnxtout(ag,e) ){ aresta at = cria_aresta(g->vertices, e); if( at->peso != 0 ) g->ponderado = 1; insere_lista(at, vt->arestas_saida); } for( Agedge_t *e = agfstin(ag,v); e; e = agnxtin(ag,e) ){ aresta at = cria_aresta(g->vertices, e); if( at->peso != 0 ) g->ponderado = 1; insere_lista(at, vt->arestas_entrada); } } else { for( Agedge_t *e = agfstedge(ag,v); e; e = agnxtedge(ag,e,v) ){ if( agtail(e) != v ) continue; aresta at = cria_aresta(g->vertices, e); if( at->peso != 0 ) g->ponderado = 1; insere_lista(at, at->origem->arestas_saida); insere_lista(at, at->destino->arestas_saida); } } } if( agclose(ag) ) return NULL; return g; }
SEXP getEdgeLocs(Agraph_t *g) { SEXP outList, curCP, curEP, pntList, pntSet, curXY, curLab; SEXP epClass, cpClass, xyClass, labClass; Agnode_t *node, *head; Agedge_t *edge; char *tmpString; bezier bez; int nodes; int i,k,l,pntLstEl; int curEle = 0; epClass = MAKE_CLASS("AgEdge"); cpClass = MAKE_CLASS("BezierCurve"); xyClass = MAKE_CLASS("xyPoint"); labClass = MAKE_CLASS("AgTextLabel"); /* tmpString is used to convert a char to a char* w/ labels */ tmpString = (char *)R_alloc(2, sizeof(char)); if (tmpString == NULL) error("Allocation error in getEdgeLocs"); PROTECT(outList = allocVector(VECSXP, agnedges(g))); nodes = agnnodes(g); node = agfstnode(g); for (i = 0; i < nodes; i++) { edge = agfstout(g, node); while (edge != NULL && edge->u.spl != NULL) { PROTECT(curEP = NEW_OBJECT(epClass)); bez = edge->u.spl->list[0]; PROTECT(pntList = allocVector(VECSXP, ((bez.size-1)/3))); pntLstEl = 0; /* There are really (bez.size-1)/3 sets of control */ /* points, with the first set containing teh first 4 */ /* points, and then every other set starting with the */ /* last point from the previous set and then the next 3 */ for (k = 1; k < bez.size; k += 3) { PROTECT(curCP = NEW_OBJECT(cpClass)); PROTECT(pntSet = allocVector(VECSXP, 4)); for (l = -1; l < 3; l++) { PROTECT(curXY = NEW_OBJECT(xyClass)); SET_SLOT(curXY, Rf_install("x"), Rf_ScalarInteger(bez.list[k+l].x)); SET_SLOT(curXY, Rf_install("y"), Rf_ScalarInteger(bez.list[k+l].y)); SET_ELEMENT(pntSet, l+1, curXY); UNPROTECT(1); } SET_SLOT(curCP, Rf_install("cPoints"), pntSet); SET_ELEMENT(pntList, pntLstEl++, curCP); UNPROTECT(2); } SET_SLOT(curEP, Rf_install("splines"), pntList); /* get the sp and ep */ PROTECT(curXY = NEW_OBJECT(xyClass)); SET_SLOT(curXY, Rf_install("x"), Rf_ScalarInteger(bez.sp.x)); SET_SLOT(curXY, Rf_install("y"), Rf_ScalarInteger(bez.sp.y)); SET_SLOT(curEP, Rf_install("sp"), curXY); UNPROTECT(1); PROTECT(curXY = NEW_OBJECT(xyClass)); SET_SLOT(curXY, Rf_install("x"), Rf_ScalarInteger(bez.ep.x)); SET_SLOT(curXY, Rf_install("y"), Rf_ScalarInteger(bez.ep.y)); SET_SLOT(curEP, Rf_install("ep"), curXY); UNPROTECT(1); SET_SLOT(curEP, Rf_install("tail"), Rgraphviz_ScalarStringOrNull(node->name)); head = edge->head; SET_SLOT(curEP, Rf_install("head"), Rgraphviz_ScalarStringOrNull(head->name)); /* TODO: clean up the use of attrs: dir, arrowhead, arrowtail. * the following are for interactive plotting in R-env, not needed * for output to files. The existing codes set "dir"-attr, but use * "arrowhead"/"arrowtail" instead. Quite confusing. */ SET_SLOT(curEP, Rf_install("dir"), Rgraphviz_ScalarStringOrNull(agget(edge, "dir"))); SET_SLOT(curEP, Rf_install("arrowhead"), Rgraphviz_ScalarStringOrNull(agget(edge, "arrowhead"))); SET_SLOT(curEP, Rf_install("arrowtail"), Rgraphviz_ScalarStringOrNull(agget(edge, "arrowtail"))); SET_SLOT(curEP, Rf_install("arrowsize"), Rgraphviz_ScalarStringOrNull(agget(edge, "arrowsize"))); SET_SLOT(curEP, Rf_install("color"), Rgraphviz_ScalarStringOrNull(agget(edge, "color"))); /* get lty/lwd info */ if ( agget(edge, "lty") ) SET_SLOT(curEP, Rf_install("lty"), Rgraphviz_ScalarStringOrNull(agget(edge, "lty"))); if ( agget(edge, "lwd") ) SET_SLOT(curEP, Rf_install("lwd"), Rgraphviz_ScalarStringOrNull(agget(edge, "lwd"))); /* Get the label information */ if (edge->u.label != NULL) { PROTECT(curLab = NEW_OBJECT(labClass)); SET_SLOT(curLab, Rf_install("labelText"), Rgraphviz_ScalarStringOrNull(ED_label(edge)->text)); /* Get the X/Y location of the label */ PROTECT(curXY = NEW_OBJECT(xyClass)); #if GRAPHVIZ_MAJOR == 2 && GRAPHVIZ_MINOR > 20 SET_SLOT(curXY, Rf_install("x"), Rf_ScalarInteger(ED_label(edge)->pos.x)); SET_SLOT(curXY, Rf_install("y"), Rf_ScalarInteger(ED_label(edge)->pos.y)); #else SET_SLOT(curXY, Rf_install("x"), Rf_ScalarInteger(edge->u.label->p.x)); SET_SLOT(curXY, Rf_install("y"), Rf_ScalarInteger(edge->u.label->p.y)); #endif SET_SLOT(curLab, Rf_install("labelLoc"), curXY); UNPROTECT(1); snprintf(tmpString, 2, "%c",ED_label(edge)->u.txt.para->just); SET_SLOT(curLab, Rf_install("labelJust"), Rgraphviz_ScalarStringOrNull(tmpString)); SET_SLOT(curLab, Rf_install("labelWidth"), Rf_ScalarInteger(ED_label(edge)->u.txt.para->width)); SET_SLOT(curLab, Rf_install("labelColor"), Rgraphviz_ScalarStringOrNull(edge->u.label->fontcolor)); SET_SLOT(curLab, Rf_install("labelFontsize"), Rf_ScalarReal(edge->u.label->fontsize)); SET_SLOT(curEP, Rf_install("txtLabel"), curLab); UNPROTECT(1); } SET_ELEMENT(outList, curEle++, curEP); UNPROTECT(2); edge = agnxtout(g, edge); } node = agnxtnode(g, node); } UNPROTECT(1); return(outList); }
main(int argc, char *argv[]) { Agraph_t **gs; Agraph_t **ccs; Agraph_t *g; Agraph_t *gp; char *fname; FILE *fp; int cnt; int i; init(argc, argv); if (!Files) { fprintf(stderr, "No input files given\n"); exit(1); } PSinputscale = POINTS_PER_INCH; if (doComps) { if (verbose) fprintf(stderr, "do Comps\n"); while (fname = *Files++) { fp = fopen(fname, "r"); if (!fp) { fprintf(stderr, "Could not open %s\n", fname); continue; } g = agread(fp); fclose(fp); if (!g) { fprintf(stderr, "Could not read graph\n"); continue; } printf("%s %d nodes %d edges %sconnected\n", g->name, agnnodes(g), agnedges(g), (isConnected(g) ? "" : "not ")); gs = ccomps(g, &cnt, "abc"); for (i = 0; i < cnt; i++) { gp = gs[i]; printf(" %s %d nodes %d edges\n", gp->name, agnnodes(gp), agnedges(gp)); } } } else { gs = N_GNEW(nFiles, Agraph_t *); cnt = 0; while (fname = Files[cnt]) { fp = fopen(fname, "r"); if (!fp) { fprintf(stderr, "Could not open %s\n", fname); exit(1); } g = agread(fp); fclose(fp); if (!g) { fprintf(stderr, "Could not read graph\n"); exit(1); } if (!single) { graph_init(g); ptest_initGraph(g); } initPos(g); /* if (Verbose) dumpG (g); */ gs[cnt++] = g; } if (single) { Agraph_t *root; Agnode_t *n; Agnode_t *np; Agnode_t *tp; Agnode_t *hp; Agedge_t *e; Agedge_t *ep; root = agopen("root", 0); agedgeattr(root, "pos", ""); for (i = 0; i < cnt; i++) { g = gs[i]; for (n = agfstnode(g); n; n = agnxtnode(g, n)) { if (agfindnode(root, n->name)) { fprintf(stderr, "Error: node %s in graph %d (%s) previously added\n", n->name, i, Files[i]); exit(1); } np = agnode(root, n->name); ND_pos(np)[0] = ND_pos(n)[0]; ND_pos(np)[1] = ND_pos(n)[1]; ND_coord_i(np).x = ND_coord_i(n).x; ND_coord_i(np).y = ND_coord_i(n).y; } for (n = agfstnode(g); n; n = agnxtnode(g, n)) { tp = agfindnode(root, n->name); for (e = agfstout(g, n); e; e = agnxtout(g, e)) { hp = agfindnode(root, e->head->name); ep = agedge(root, tp, hp); ED_spl(ep) = ED_spl(e); } } } graph_init(root); ptest_initGraph(root); ccs = ccomps(root, &cnt, 0); packGraphs(cnt, ccs, root, margin, doEdges); if (!doEdges) copyPos(root); else State = GVSPLINES; attach_attrs(root); for (i = 0; i < cnt; i++) { agdelete(root, ccs[i]); } agwrite(root, stdout); } else { packGraphs(cnt, gs, 0, margin, doEdges); if (doEdges) State = GVSPLINES; for (i = 0; i < cnt; i++) { if (!doEdges) copyPos(gs[i]); attach_attrs(gs[i]); agwrite(gs[i], stdout); } } } }