Graphviz 14.1.3~dev.20260126.0926
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 <cgraph/cgraph.h>
20#include <twopigen/circle.h>
21#include <neatogen/adjust.h>
22#include <pack/pack.h>
23#include <neatogen/neatoprocs.h>
24#include <stdbool.h>
25#include <stddef.h>
26#include <util/alloc.h>
27
28static void twopi_init_edge(edge_t * e)
29{
30 agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), true); //edge custom data
32 ED_factor(e) = late_double(e, E_weight, 1.0, 0.0);
33}
34
36{
37 node_t *n;
38 edge_t *e;
39 int i = 0;
40 int n_nodes = agnnodes(g);
41
42 rdata* alg = gv_calloc(n_nodes, sizeof(rdata));
43 GD_neato_nlist(g) = gv_calloc(n_nodes + 1, sizeof(node_t*));
44 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
46 ND_alg(n) = alg + i;
47 GD_neato_nlist(g)[i++] = n;
48 }
49 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
50 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
52 }
53 }
54}
55
57{
59 /* GD_ndim(g) = late_int(g,agfindgraphattr(g,"dim"),2,2); */
60 Ndim = GD_ndim(agroot(g)) = 2; /* The algorithm only makes sense in 2D */
62}
63
64static Agnode_t* findRootNode (Agraph_t* sg, Agsym_t* rootattr)
65{
66 Agnode_t* n;
67
68 for (n = agfstnode(sg); n; n = agnxtnode(sg,n)) {
69 if (mapbool(agxget(n,rootattr))) return n;
70 }
71 return NULL;
72
73}
74
75/* twopi_layout:
76 */
78{
79 Agnode_t *ctr = 0;
80 char *s;
81 int setRoot = 0;
82 int setLocalRoot = 0;
83 pointf sc;
84 int r;
85 Agsym_t* rootattr;
86
87 if (agnnodes(g) == 0) return;
88
90 if ((s = agget(g, "root"))) {
91 if (*s) {
92 ctr = agfindnode(g, s);
93 if (!ctr) {
94 agwarningf("specified root node \"%s\" was not found.", s);
95 agerr(AGPREV, "Using default calculation for root node\n");
96 setRoot = 1;
97 }
98 }
99 else {
100 setRoot = 1;
101 }
102 }
103 if ((rootattr = agattr_text(g, AGNODE, "root", 0))) {
104 setLocalRoot = 1;
105 }
106
107 if ((s = agget(g, "scale")) && *s) {
108 if ((r = sscanf (s, "%lf,%lf",&sc.x,&sc.y))) {
109 if (r == 1) sc.y = sc.x;
110 }
111 }
112
113 if (agnnodes(g)) {
114 Agraph_t **ccs;
115 Agraph_t *sg;
116 Agnode_t *c = NULL;
117 Agnode_t *n;
118 Agnode_t* lctr;
119
120 size_t ncc;
121 ccs = ccomps(g, &ncc, 0);
122 if (ncc == 1) {
123 if (ctr)
124 lctr = ctr;
125 else if (!rootattr || !(lctr = findRootNode(g, rootattr)))
126 lctr = 0;
127 c = circleLayout(g, lctr);
128 if (setRoot && !ctr)
129 ctr = c;
130 if (setLocalRoot && !lctr)
131 agxset (c, rootattr, "1");
132 n = agfstnode(g);
133 free(ND_alg(n));
134 ND_alg(n) = NULL;
135 adjustNodes(g);
136 spline_edges(g);
137 } else {
138 pack_info pinfo;
139 getPackInfo (g, l_node, CL_OFFSET, &pinfo);
140 pinfo.doSplines = false;
141
142 for (size_t i = 0; i < ncc; i++) {
143 sg = ccs[i];
144 if (ctr && agcontains(sg, ctr))
145 lctr = ctr;
146 else if (!rootattr || !(lctr = findRootNode(sg, rootattr)))
147 lctr = 0;
148 (void)graphviz_node_induce(sg, NULL);
149 c = circleLayout(sg, lctr);
150 if (setRoot && !ctr)
151 ctr = c;
152 if (setLocalRoot && (!lctr || (lctr == ctr)))
153 agxset (c, rootattr, "1");
154 adjustNodes(sg);
155 }
156 n = agfstnode(g);
157 free(ND_alg(n));
158 ND_alg(n) = NULL;
159 packSubgraphs(ncc, ccs, g, &pinfo);
160 spline_edges(g);
161 }
162 for (size_t i = 0; i < ncc; i++) {
163 agdelete(g, ccs[i]);
164 }
165 free(ccs);
166 }
167 if (setRoot)
168 agset (g, "root", agnameof (ctr));
170
171}
172
174{
176}
177
178/* twopi_cleanup:
179 * The ND_alg data used by twopi is freed in twopi_layout
180 * before edge routing as edge routing may use this field.
181 */
183{
184 node_t *n;
185 edge_t *e;
186
187 n = agfstnode (g);
188 if (!n) return; /* empty graph */
189 /* free (ND_alg(n)); */
190 for (; n; n = agnxtnode(g, n)) {
191 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
193 }
195 }
197}
198
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:28
static Agnode_t * findRootNode(Agraph_t *sg, Agsym_t *rootattr)
Definition twopiinit.c:64
static void twopi_init_node_edge(graph_t *g)
Definition twopiinit.c:35
void twopi_layout(Agraph_t *g)
Definition twopiinit.c:77
static void twopi_cleanup_graph(graph_t *g)
Definition twopiinit.c:173
void twopi_cleanup(graph_t *g)
Definition twopiinit.c:182
void twopi_init_graph(graph_t *g)
Definition twopiinit.c:56
Definition grammar.c:90