Graphviz 14.1.3~dev.20260207.0611
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 "config.h"
18
19#include <assert.h>
20#include <cgraph/cgraph.h>
21#include <twopigen/circle.h>
22#include <neatogen/adjust.h>
23#include <pack/pack.h>
24#include <neatogen/neatoprocs.h>
25#include <stdbool.h>
26#include <stddef.h>
27#include <util/alloc.h>
28
29static void twopi_init_edge(edge_t * e)
30{
31 agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), true); //edge custom data
33 ED_factor(e) = late_double(e, E_weight, 1.0, 0.0);
34}
35
37{
38 node_t *n;
39 edge_t *e;
40 int i = 0;
41 int n_nodes = agnnodes(g);
42
43 assert(n_nodes >= 0);
44 rdata* alg = gv_calloc((size_t)n_nodes, sizeof(rdata));
45 GD_neato_nlist(g) = gv_calloc((size_t)n_nodes + 1, sizeof(node_t*));
46 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
48 ND_alg(n) = alg + i;
49 GD_neato_nlist(g)[i++] = n;
50 }
51 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
52 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
54 }
55 }
56}
57
59{
61 Ndim = GD_ndim(agroot(g)) = 2; /* The algorithm only makes sense in 2D */
63}
64
65static Agnode_t* findRootNode (Agraph_t* sg, Agsym_t* rootattr)
66{
67 Agnode_t* n;
68
69 for (n = agfstnode(sg); n; n = agnxtnode(sg,n)) {
70 if (mapbool(agxget(n,rootattr))) return n;
71 }
72 return NULL;
73
74}
75
77{
78 Agnode_t *ctr = 0;
79 char *s;
80 bool setRoot = false;
81 bool setLocalRoot = false;
82 pointf sc;
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 = true;
95 }
96 }
97 else {
98 setRoot = true;
99 }
100 }
101 if ((rootattr = agattr_text(g, AGNODE, "root", 0))) {
102 setLocalRoot = true;
103 }
104
105 if ((s = agget(g, "scale")) && *s) {
106 if (sscanf(s, "%lf,%lf", &sc.x, &sc.y) == 1) {
107 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/* The ND_alg data used by twopi is freed in twopi_layout
177 * before edge routing as edge routing may use this field.
178 */
180{
181 node_t *n;
182 edge_t *e;
183
184 n = agfstnode (g);
185 if (!n) return; /* empty graph */
186 for (; n; n = agnxtnode(g, n)) {
187 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
189 }
191 }
193}
194
int adjustNodes(graph_t *G)
Definition adjust.c:999
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:341
void setEdgeType(graph_t *g, int defaultValue)
Definition utils.c:1422
double late_double(void *obj, attrsym_t *attr, double defaultValue, double minimum)
Definition utils.c:54
void common_init_edge(edge_t *e)
Definition utils.c:509
#define CL_OFFSET
Definition const.h:142
#define EDGETYPE_LINE
Definition const.h:235
Agsym_t * E_weight
Definition globals.h:82
unsigned short Ndim
Definition globals.h:62
void free(void *)
node NULL
Definition grammar.y:181
int agnnodes(Agraph_t *g)
Definition graph.c:157
size_t graphviz_node_induce(Agraph_t *g, Agraph_t *edgeset)
Definition node_induce.c:12
Agsym_t * agattr_text(Agraph_t *g, int kind, char *name, const char *value)
creates or looks up text attributes of a graph
Definition attr.c:336
int agset(void *obj, char *name, const char *value)
Definition attr.c:477
int agxset(void *obj, Agsym_t *sym, const char *value)
Definition attr.c:524
char * agget(void *obj, char *name)
Definition attr.c:450
char * agxget(void *obj, Agsym_t *sym)
Definition attr.c:460
Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
Definition edge.c:28
#define ED_factor(e)
Definition types.h:585
Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)
Definition edge.c:43
void agwarningf(const char *fmt,...)
Definition agerror.c:175
int agerr(agerrlevel_t level, const char *fmt,...)
Definition agerror.c:157
@ AGPREV
Definition cgraph.h:946
#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:50
Agnode_t * agfstnode(Agraph_t *g)
Definition node.c:43
#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:145
int agdelete(Agraph_t *g, void *obj)
deletes object. Equivalent to agclose, agdelnode, and agdeledge for obj being a graph,...
Definition obj.c:22
int agcontains(Agraph_t *, void *obj)
returns non-zero if obj is a member of (sub)graph
Definition obj.c:235
Agraph_t * agroot(void *obj)
Definition obj.c:170
@ 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:91
Agraph_t ** ccomps(Agraph_t *g, size_t *ncc, char *pfx)
Definition ccomps.c:185
void neato_init_node(node_t *n)
Definition neatoinit.c:60
NEATOPROCS_API void spline_edges(Agraph_t *)
int packSubgraphs(size_t ng, Agraph_t **gs, Agraph_t *root, pack_info *info)
Definition pack.c:1107
pack_mode getPackInfo(Agraph_t *g, pack_mode dflt, int dfltMargin, pack_info *pinfo)
Definition pack.c:1284
support for connected components
@ l_node
Definition pack.h:55
void dotneato_postprocess(Agraph_t *g)
Definition postproc.c:691
void gv_cleanup_edge(Agedge_t *e)
Definition utils.c:1512
void gv_cleanup_node(Agnode_t *n)
Definition utils.c:1524
graph or subgraph
Definition cgraph.h:424
string attribute descriptor symbol in Agattr_s.dict
Definition cgraph.h:640
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:29
static Agnode_t * findRootNode(Agraph_t *sg, Agsym_t *rootattr)
Definition twopiinit.c:65
static void twopi_init_node_edge(graph_t *g)
Definition twopiinit.c:36
void twopi_layout(Agraph_t *g)
Definition twopiinit.c:76
static void twopi_cleanup_graph(graph_t *g)
Definition twopiinit.c:171
void twopi_cleanup(graph_t *g)
Definition twopiinit.c:179
void twopi_init_graph(graph_t *g)
Definition twopiinit.c:58
Definition grammar.c:90