Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
twopiinit.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11
12/*
13 * Written by Emden R. Gansner
14 * Derived from Graham Wills' algorithm described in GD'97.
15 */
16
17#include <cgraph/cgraph.h>
18#include <twopigen/circle.h>
19#include <neatogen/adjust.h>
20#include <pack/pack.h>
21#include <neatogen/neatoprocs.h>
22#include <stdbool.h>
23#include <stddef.h>
24#include <util/alloc.h>
25
26static void twopi_init_edge(edge_t * e)
27{
28 agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), true); //edge custom data
30 ED_factor(e) = late_double(e, E_weight, 1.0, 0.0);
31}
32
34{
35 node_t *n;
36 edge_t *e;
37 int i = 0;
38 int n_nodes = agnnodes(g);
39
40 rdata* alg = gv_calloc(n_nodes, sizeof(rdata));
41 GD_neato_nlist(g) = gv_calloc(n_nodes + 1, sizeof(node_t*));
42 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
44 ND_alg(n) = alg + i;
45 GD_neato_nlist(g)[i++] = n;
46 }
47 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
48 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
50 }
51 }
52}
53
55{
57 /* GD_ndim(g) = late_int(g,agfindgraphattr(g,"dim"),2,2); */
58 Ndim = GD_ndim(agroot(g)) = 2; /* The algorithm only makes sense in 2D */
60}
61
62static Agnode_t* findRootNode (Agraph_t* sg, Agsym_t* rootattr)
63{
64 Agnode_t* n;
65
66 for (n = agfstnode(sg); n; n = agnxtnode(sg,n)) {
67 if (mapbool(agxget(n,rootattr))) return n;
68 }
69 return NULL;
70
71}
72
73/* twopi_layout:
74 */
76{
77 Agnode_t *ctr = 0;
78 char *s;
79 int setRoot = 0;
80 int setLocalRoot = 0;
81 pointf sc;
82 int r;
83 Agsym_t* rootattr;
84
85 if (agnnodes(g) == 0) return;
86
88 if ((s = agget(g, "root"))) {
89 if (*s) {
90 ctr = agfindnode(g, s);
91 if (!ctr) {
92 agwarningf("specified root node \"%s\" was not found.", s);
93 agerr(AGPREV, "Using default calculation for root node\n");
94 setRoot = 1;
95 }
96 }
97 else {
98 setRoot = 1;
99 }
100 }
101 if ((rootattr = agattr(g, AGNODE, "root", 0))) {
102 setLocalRoot = 1;
103 }
104
105 if ((s = agget(g, "scale")) && *s) {
106 if ((r = sscanf (s, "%lf,%lf",&sc.x,&sc.y))) {
107 if (r == 1) sc.y = sc.x;
108 }
109 }
110
111 if (agnnodes(g)) {
112 Agraph_t **ccs;
113 Agraph_t *sg;
114 Agnode_t *c = NULL;
115 Agnode_t *n;
116 Agnode_t* lctr;
117
118 size_t ncc;
119 ccs = ccomps(g, &ncc, 0);
120 if (ncc == 1) {
121 if (ctr)
122 lctr = ctr;
123 else if (!rootattr || !(lctr = findRootNode(g, rootattr)))
124 lctr = 0;
125 c = circleLayout(g, lctr);
126 if (setRoot && !ctr)
127 ctr = c;
128 if (setLocalRoot && !lctr)
129 agxset (c, rootattr, "1");
130 n = agfstnode(g);
131 free(ND_alg(n));
132 ND_alg(n) = NULL;
133 adjustNodes(g);
134 spline_edges(g);
135 } else {
136 pack_info pinfo;
137 getPackInfo (g, l_node, CL_OFFSET, &pinfo);
138 pinfo.doSplines = false;
139
140 for (size_t i = 0; i < ncc; i++) {
141 sg = ccs[i];
142 if (ctr && agcontains(sg, ctr))
143 lctr = ctr;
144 else if (!rootattr || !(lctr = findRootNode(sg, rootattr)))
145 lctr = 0;
146 (void)graphviz_node_induce(sg, NULL);
147 c = circleLayout(sg, lctr);
148 if (setRoot && !ctr)
149 ctr = c;
150 if (setLocalRoot && (!lctr || (lctr == ctr)))
151 agxset (c, rootattr, "1");
152 adjustNodes(sg);
153 }
154 n = agfstnode(g);
155 free(ND_alg(n));
156 ND_alg(n) = NULL;
157 packSubgraphs(ncc, ccs, g, &pinfo);
158 spline_edges(g);
159 }
160 for (size_t i = 0; i < ncc; i++) {
161 agdelete(g, ccs[i]);
162 }
163 free(ccs);
164 }
165 if (setRoot)
166 agset (g, "root", agnameof (ctr));
168
169}
170
172{
174}
175
176/* twopi_cleanup:
177 * The ND_alg data used by twopi is freed in twopi_layout
178 * before edge routing as edge routing may use this field.
179 */
181{
182 node_t *n;
183 edge_t *e;
184
185 n = agfstnode (g);
186 if (!n) return; /* empty graph */
187 /* free (ND_alg(n)); */
188 for (; n; n = agnxtnode(g, n)) {
189 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
191 }
193 }
195}
196
int adjustNodes(graph_t *G)
Definition adjust.c:1022
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
abstract graph C library, Cgraph API
Agnode_t * circleLayout(Agraph_t *sg, Agnode_t *center)
Definition circle.c:312
bool mapbool(const char *p)
Definition utils.c:335
void setEdgeType(graph_t *g, int defaultValue)
Definition utils.c:1434
double late_double(void *obj, attrsym_t *attr, double defaultValue, double minimum)
Definition utils.c:48
void common_init_edge(edge_t *e)
Definition utils.c:504
#define CL_OFFSET
Definition const.h:151
#define EDGETYPE_LINE
Definition const.h:249
Agsym_t * E_weight
Definition globals.h:81
unsigned short Ndim
Definition globals.h:61
void free(void *)
node NULL
Definition grammar.y:163
int agnnodes(Agraph_t *g)
Definition graph.c:169
size_t graphviz_node_induce(Agraph_t *g, Agraph_t *edgeset)
Definition node_induce.c:9
Agsym_t * agattr(Agraph_t *g, int kind, char *name, const char *value)
creates or looks up attributes of a graph
Definition attr.c:338
int agset(void *obj, char *name, const char *value)
Definition attr.c:466
int agxset(void *obj, Agsym_t *sym, const char *value)
Definition attr.c:478
char * agget(void *obj, char *name)
Definition attr.c:439
char * agxget(void *obj, Agsym_t *sym)
Definition attr.c:455
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition edge.c:24
#define ED_factor(e)
Definition types.h:585
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition edge.c:39
void agwarningf(const char *fmt,...)
Definition agerror.c:173
int agerr(agerrlevel_t level, const char *fmt,...)
Definition agerror.c:155
@ AGPREV
Definition cgraph.h:849
#define GD_ndim(g)
Definition types.h:390
#define GD_neato_nlist(g)
Definition types.h:392
Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
Definition node.c:47
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:40
#define ND_alg(n)
Definition types.h:484
#define agfindnode(g, n)
Definition types.h:611
char * agnameof(void *)
returns a string descriptor for the object.
Definition id.c:158
int agdelete(Agraph_t *g, void *obj)
deletes object. Equivalent to agclose, agdelnode, and agdeledge for obj being a graph,...
Definition obj.c:20
int agcontains(Agraph_t *, void *obj)
returns non-zero if obj is a member of (sub)graph
Definition obj.c:233
Agraph_t * agroot(void *obj)
Definition obj.c:168
@ AGNODE
Definition cgraph.h:207
void * agbindrec(void *obj, const char *name, unsigned int recsize, int move_to_front)
attaches a new record of the given size to the object
Definition rec.c:89
Agraph_t ** ccomps(Agraph_t *g, size_t *ncc, char *pfx)
Definition ccomps.c:187
void neato_init_node(node_t *n)
Definition neatoinit.c:59
NEATOPROCS_API void spline_edges(Agraph_t *)
int packSubgraphs(size_t ng, Agraph_t **gs, Agraph_t *root, pack_info *info)
Definition pack.c:1104
pack_mode getPackInfo(Agraph_t *g, pack_mode dflt, int dfltMargin, pack_info *pinfo)
Definition pack.c:1281
support for connected components
@ l_node
Definition pack.h:55
void dotneato_postprocess(Agraph_t *g)
Definition postproc.c:689
void gv_cleanup_edge(Agedge_t *e)
Definition utils.c:1524
void gv_cleanup_node(Agnode_t *n)
Definition utils.c:1536
graph or subgraph
Definition cgraph.h:425
string attribute descriptor symbol in Agattr_s.dict
Definition cgraph.h:637
bool doSplines
use splines in constructing graph shape
Definition pack.h:71
double x
Definition geom.h:29
double y
Definition geom.h:29
static void twopi_init_edge(edge_t *e)
Definition twopiinit.c:26
static Agnode_t * findRootNode(Agraph_t *sg, Agsym_t *rootattr)
Definition twopiinit.c:62
static void twopi_init_node_edge(graph_t *g)
Definition twopiinit.c:33
void twopi_layout(Agraph_t *g)
Definition twopiinit.c:75
static void twopi_cleanup_graph(graph_t *g)
Definition twopiinit.c:171
void twopi_cleanup(graph_t *g)
Definition twopiinit.c:180
void twopi_init_graph(graph_t *g)
Definition twopiinit.c:54
Definition grammar.c:93