Graphviz  2.29.20120523.0446
lib/fdpgen/fdpinit.c
Go to the documentation of this file.
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 /* fdpinit.c:
00016  * Written by Emden R. Gansner
00017  *
00018  * Mostly boilerplate initialization and cleanup code.
00019  */
00020 
00021 /* uses PRIVATE interface */
00022 #define FDP_PRIVATE 1
00023 
00024 #include    "tlayout.h"
00025 #include    "neatoprocs.h"
00026 #include    "agxbuf.h"
00027 
00028 static void initialPositions(graph_t * g)
00029 {
00030     int i;
00031     node_t *np;
00032     attrsym_t *possym;
00033     attrsym_t *pinsym;
00034     double *pvec;
00035     char *p;
00036     char c;
00037 
00038 #ifndef WITH_CGRAPH
00039     possym = agfindattr(g->proto->n, "pos");
00040 #else /* WITH_CGRAPH */
00041     possym = agattr(g,AGNODE, "pos", NULL);
00042 #endif /* WITH_CGRAPH */
00043     if (!possym)
00044         return;
00045 #ifndef WITH_CGRAPH
00046     pinsym = agfindattr(g->proto->n, "pin");
00047 #else /* WITH_CGRAPH */
00048     pinsym = agattr(g,AGNODE, "pin", NULL);
00049 #endif /* WITH_CGRAPH */
00050     for (i = 0; (np = GD_neato_nlist(g)[i]); i++) {
00051 #ifndef WITH_CGRAPH
00052         p = agxget(np, possym->index);
00053 #else /* WITH_CGRAPH */
00054         p = agxget(np, possym);
00055 #endif /* WITH_CGRAPH */
00056         if (p[0]) {
00057             pvec = ND_pos(np);
00058             c = '\0';
00059             if (sscanf(p, "%lf,%lf%c", pvec, pvec + 1, &c) >= 2) {
00060                 if (PSinputscale > 0.0) {
00061                     int i;
00062                     for (i = 0; i < NDIM; i++)
00063                         pvec[i] = pvec[i] / PSinputscale;
00064                 }
00065                 ND_pinned(np) = P_SET;
00066                 if ((c == '!')
00067 #ifndef WITH_CGRAPH
00068                     || (pinsym && mapbool(agxget(np, pinsym->index))))
00069 #else /* WITH_CGRAPH */
00070                     || (pinsym && mapbool(agxget(np, pinsym))))
00071 #endif /* WITH_CGRAPH */
00072                     ND_pinned(np) = P_PIN;
00073             } else
00074                 fprintf(stderr,
00075                         "Warning: node %s, position %s, expected two floats\n",
00076                         agnameof(np), p);
00077         }
00078     }
00079 }
00080 
00081 /* init_edge:
00082  */
00083 static void init_edge(edge_t * e, attrsym_t * E_len)
00084 {
00085 #ifdef WITH_CGRAPH
00086     agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE);   //node custom data
00087 #endif /* WITH_CGRAPH */
00088     ED_factor(e) = late_double(e, E_weight, 1.0, 0.0);
00089     ED_dist(e) = late_double(e, E_len, fdp_parms.K, 0.0);
00090 
00091     common_init_edge(e);
00092 }
00093 
00094 #ifdef WITH_CGRAPH
00095 static void init_node(node_t * n)
00096 {
00097     common_init_node(n);
00098     ND_pos(n) = N_NEW(GD_ndim(agraphof(n)), double);
00099     gv_nodesize(n, GD_flip(agraphof(n)));
00100 }
00101 #endif
00102 
00103 void fdp_init_node_edge(graph_t * g)
00104 {
00105     attrsym_t *E_len;
00106     node_t *n;
00107     edge_t *e;
00108     int nn;
00109     int i;
00110     /* ndata* alg; */
00111 
00112 #ifdef WITH_CGRAPH
00113     aginit(g, AGNODE, "Agnodeinfo_t", sizeof(Agnodeinfo_t), TRUE);
00114 #endif
00115     processClusterEdges(g);
00116 
00117     /* Get node count after processClusterEdges(), as this function may
00118      * add new nodes.
00119      */
00120     nn = agnnodes(g);
00121     /* alg = N_NEW(nn, ndata); */
00122     GD_neato_nlist(g) = N_NEW(nn + 1, node_t *);
00123 
00124     for (i = 0, n = agfstnode(g); n; n = agnxtnode(g, n)) {
00125 #ifdef WITH_CGRAPH
00126         init_node (n);
00127 #else
00128         neato_init_node (n);
00129 #endif
00130         /* ND_alg(n) = alg + i; */
00131         GD_neato_nlist(g)[i] = n;
00132         ND_id(n) = i++;
00133     }
00134 
00135 #ifndef WITH_CGRAPH
00136     E_len = agfindattr(g->proto->e, "len");
00137 #else /* WITH_CGRAPH */
00138     E_len = agattr(g,AGEDGE, "len", NULL);
00139 #endif /* WITH_CGRAPH */
00140     for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00141         for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00142             init_edge(e, E_len);
00143         }
00144     }
00145     initialPositions(g);
00146 
00147 }
00148 
00149 static void cleanup_subgs(graph_t * g)
00150 {
00151     graph_t *subg;
00152     int i;
00153 
00154     for (i = 1; i <= GD_n_cluster(g); i++) {
00155         subg = GD_clust(g)[i];
00156         free_label(GD_label(subg));
00157         if (GD_alg(subg)) {
00158             free(PORTS(subg));
00159             free(GD_alg(subg));
00160         }
00161         cleanup_subgs(subg);
00162     }
00163     free (GD_clust(g));
00164     if (g != agroot(g))
00165 #ifndef WITH_CGRAPH
00166         memset(&(g->u), 0, sizeof(Agraphinfo_t));
00167 #else /* WITH_CGRAPH */
00168         agdelrec(g, "Agraphinfo_t");                            
00169 #endif /* WITH_CGRAPH */
00170 }
00171 
00172 static void fdp_cleanup_graph(graph_t * g)
00173 {
00174     cleanup_subgs(g);
00175     free(GD_neato_nlist(g));
00176     free(GD_alg(g));
00177 }
00178 
00179 void fdp_cleanup(graph_t * g)
00180 {
00181     node_t *n;
00182     edge_t *e;
00183 
00184     for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00185         for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00186             gv_cleanup_edge(e);
00187         }
00188         gv_cleanup_node(n);
00189     }
00190     fdp_cleanup_graph(g);
00191 }