/misc/src/release/graphviz-2.18-1/src/graphviz-2.18/lib/twopigen/twopiinit.c

Go to the documentation of this file.
00001 /* $Id: twopiinit.c,v 1.8 2007/06/22 19:11:23 erg Exp $ $Revision: 1.8 $ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /**********************************************************
00005 *      This software is part of the graphviz package      *
00006 *                http://www.graphviz.org/                 *
00007 *                                                         *
00008 *            Copyright (c) 1994-2004 AT&T Corp.           *
00009 *                and is licensed under the                *
00010 *            Common Public License, Version 1.0           *
00011 *                      by AT&T Corp.                      *
00012 *                                                         *
00013 *        Information and Software Systems Research        *
00014 *              AT&T Research, Florham Park NJ             *
00015 **********************************************************/
00016 
00017 
00018 /*
00019  * Written by Emden R. Gansner
00020  * Derived from Graham Wills' algorithm described in GD'97.
00021  */
00022 
00023 #include    "circle.h"
00024 #include    "adjust.h"
00025 #include    "pack.h"
00026 #include    "neatoprocs.h"
00027 
00028 static void twopi_init_node(node_t * n)
00029 {
00030     common_init_node(n);
00031 
00032     neato_nodesize(n, GD_flip(n->graph));
00033     ND_pos(n) = ALLOC(GD_ndim(n->graph), 0, double);
00034 }
00035 
00036 static void twopi_init_edge(edge_t * e)
00037 {
00038     common_init_edge(e);
00039 
00040     ED_factor(e) = late_double(e, E_weight, 1.0, 0.0);
00041 }
00042 
00043 static void twopi_init_node_edge(graph_t * g)
00044 {
00045     node_t *n;
00046     edge_t *e;
00047     int i = 0;
00048     rdata* alg = N_NEW(agnnodes(g), rdata);
00049 
00050     GD_neato_nlist(g) = N_NEW(agnnodes(g) + 1, node_t *);
00051     for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00052         ND_alg(n) = alg + i;
00053         GD_neato_nlist(g)[i++] = n;
00054         twopi_init_node(n);
00055     }
00056     for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00057         for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00058             twopi_init_edge(e);
00059         }
00060     }
00061 }
00062 
00063 void twopi_init_graph(graph_t * g)
00064 {
00065     setEdgeType (g, ET_LINE);
00066     /* GD_ndim(g) = late_int(g,agfindattr(g,"dim"),2,2); */
00067     Ndim = GD_ndim(g) = 2;      /* The algorithm only makes sense in 2D */
00068     twopi_init_node_edge(g);
00069 }
00070 
00071 /* twopi_layout:
00072  */
00073 void twopi_layout(Agraph_t * g)
00074 {
00075     Agnode_t *ctr = 0;
00076     char *s;
00077 
00078     twopi_init_graph(g);
00079     s = agget(g, "root");
00080     if (s && (*s != '\0')) {
00081         ctr = agfindnode(g, s);
00082         if (!ctr) {
00083             agerr(AGWARN, "specified root node \"%s\" was not found.", s);
00084             agerr(AGPREV, "Using default calculation for root node\n");
00085         }
00086     }
00087     if (agnnodes(g)) {
00088         Agraph_t **ccs;
00089         Agraph_t *sg;
00090         Agnode_t *c = NULL;
00091         int ncc;
00092         int i;
00093 
00094         ccs = ccomps(g, &ncc, 0);
00095         if (ncc == 1) {
00096             circleLayout(g, ctr);
00097             free(ND_alg(agfstnode(g)));
00098             adjustNodes(g);
00099             spline_edges(g);
00100         } else {
00101             pack_info pinfo;
00102             pack_mode pmode = getPackMode(g, l_node);
00103 
00104             for (i = 0; i < ncc; i++) {
00105                 sg = ccs[i];
00106                 if (ctr && agcontains(sg, ctr))
00107                     c = ctr;
00108                 else
00109                     c = 0;
00110                 nodeInduce(sg);
00111                 circleLayout(sg, c);
00112                 adjustNodes(sg);
00113             }
00114             free(ND_alg(agfstnode(g)));
00115             spline_edges(g);
00116             pinfo.margin = getPack(g, CL_OFFSET, CL_OFFSET);
00117             pinfo.doSplines = 1;
00118             pinfo.mode = pmode;
00119             pinfo.fixed = 0;
00120             packSubgraphs(ncc, ccs, g, &pinfo);
00121         }
00122         for (i = 0; i < ncc; i++) {
00123             agdelete(g, ccs[i]);
00124         }
00125         free(ccs);
00126     }
00127     dotneato_postprocess(g);
00128 
00129 }
00130 
00131 static void twopi_cleanup_node(node_t * n)
00132 {
00133     if (ND_shape(n))
00134         ND_shape(n)->fns->freefn(n);
00135     free_label(ND_label(n));
00136     memset(&(n->u), 0, sizeof(Agnodeinfo_t));
00137 }
00138 
00139 static void twopi_free_splines(edge_t * e)
00140 {
00141     int i;
00142     if (ED_spl(e)) {
00143         for (i = 0; i < ED_spl(e)->size; i++)
00144             free(ED_spl(e)->list[i].list);
00145         free(ED_spl(e)->list);
00146         free(ED_spl(e));
00147     }
00148     ED_spl(e) = NULL;
00149 }
00150 
00151 static void twopi_cleanup_edge(edge_t * e)
00152 {
00153     twopi_free_splines(e);
00154     free_label(ED_label(e));
00155     memset(&(e->u), 0, sizeof(Agedgeinfo_t));
00156 }
00157 
00158 static void twopi_cleanup_graph(graph_t * g)
00159 {
00160     free(GD_neato_nlist(g));
00161     if (g != g->root) memset(&(g->u), 0, sizeof(Agraphinfo_t));
00162 }
00163 
00164 void twopi_cleanup(graph_t * g)
00165 {
00166     node_t *n;
00167     edge_t *e;
00168 
00169     for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00170         for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00171             twopi_cleanup_edge(e);
00172         }
00173         twopi_cleanup_node(n);
00174     }
00175     twopi_cleanup_graph(g);
00176 }

Generated on Mon Mar 31 19:03:28 2008 for Graphviz by  doxygen 1.5.1