Blender V4.3
BLI_dot_export.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
14#include "BLI_map.hh"
15#include "BLI_set.hh"
16#include "BLI_utility_mixins.hh"
17#include "BLI_vector.hh"
18
20
21#include <iosfwd>
22#include <optional>
23
24namespace blender::dot {
25
26class Graph;
27class DirectedGraph;
28class UndirectedGraph;
29class Node;
30class NodePort;
31class DirectedEdge;
32class UndirectedEdge;
33class Cluster;
34
36 private:
38
39 public:
40 void export__as_bracket_list(std::stringstream &ss) const;
41
42 void set(StringRef key, StringRef value)
43 {
44 attributes_.add_overwrite(key, value);
45 }
46
47 void set(StringRef key, float value)
48 {
49 attributes_.add_overwrite(key, std::to_string(value));
50 }
51};
52
53class Graph {
54 private:
57
58 Set<Node *> top_level_nodes_;
59 Set<Cluster *> top_level_clusters_;
60
61 friend Cluster;
62 friend Node;
63
64 public:
66
67 public:
70
71 void export__declare_nodes_and_clusters(std::stringstream &ss) const;
72
73 void set_rankdir(Attr_rankdir rankdir)
74 {
75 attributes.set("rankdir", rankdir_to_string(rankdir));
76 }
77
79};
80
81class Cluster {
82 private:
83 Graph &graph_;
84 Cluster *parent_ = nullptr;
85 Set<Cluster *> children_;
86 Set<Node *> nodes_;
87
88 friend Graph;
89 friend Node;
90
91 public:
93
94 Cluster(Graph &graph) : graph_(graph) {}
95
96 public:
97 void export__declare_nodes_and_clusters(std::stringstream &ss) const;
98
99 std::string name() const
100 {
101 return "cluster_" + std::to_string(uintptr_t(this));
102 }
103
104 void set_parent_cluster(Cluster *new_parent);
106 {
107 this->set_parent_cluster(&cluster);
108 }
109
111 {
112 return parent_;
113 }
114
116
117 bool contains(Node &node) const;
118};
119
120class Node {
121 private:
122 Graph &graph_;
123 Cluster *cluster_ = nullptr;
124
125 friend Graph;
126
127 public:
129
130 Node(Graph &graph) : graph_(graph) {}
131
132 public:
133 void set_parent_cluster(Cluster *cluster);
135 {
136 this->set_parent_cluster(&cluster);
137 }
138
140 {
141 return cluster_;
142 }
143
144 void set_shape(Attr_shape shape)
145 {
146 attributes.set("shape", shape_to_string(shape));
147 }
148
149 /* See https://www.graphviz.org/doc/info/attrs.html#k:color. */
151 {
152 attributes.set("fillcolor", name);
153 attributes.set("style", "filled");
154 }
155
156 void export__as_id(std::stringstream &ss) const;
157
158 void export__as_declaration(std::stringstream &ss) const;
159};
160
161class UndirectedGraph final : public Graph {
162 private:
164
165 public:
166 std::string to_dot_string() const;
167
169};
170
171class DirectedGraph final : public Graph {
172 private:
174
175 public:
176 std::string to_dot_string() const;
177
179};
180
181class NodePort {
182 private:
183 Node *node_;
184 std::optional<std::string> port_name_;
185 std::optional<std::string> port_position_;
186
187 public:
189 std::optional<std::string> port_name = {},
190 std::optional<std::string> port_position = {})
191 : node_(&node), port_name_(std::move(port_name)), port_position_(std::move(port_position))
192 {
193 }
194
195 void to_dot_string(std::stringstream &ss) const;
196};
197
199 protected:
202
203 public:
205
206 public:
207 Edge(NodePort a, NodePort b) : a_(std::move(a)), b_(std::move(b)) {}
208
209 void set_arrowhead(Attr_arrowType type)
210 {
211 attributes.set("arrowhead", arrowType_to_string(type));
212 }
213
214 void set_arrowtail(Attr_arrowType type)
215 {
216 attributes.set("arrowtail", arrowType_to_string(type));
217 }
218
219 void set_dir(Attr_dirType type)
220 {
221 attributes.set("dir", dirType_to_string(type));
222 }
223
225 {
226 attributes.set("label", label);
227 }
228};
229
230class DirectedEdge : public Edge {
231 public:
232 DirectedEdge(NodePort from, NodePort to) : Edge(std::move(from), std::move(to)) {}
233
234 void export__as_edge_statement(std::stringstream &ss) const;
235};
236
237class UndirectedEdge : public Edge {
238 public:
239 UndirectedEdge(NodePort a, NodePort b) : Edge(std::move(a), std::move(b)) {}
240
241 void export__as_edge_statement(std::stringstream &ss) const;
242};
243
244std::string color_attr_from_hsv(float h, float s, float v);
245
247 struct Socket {
248 std::string name;
249 std::optional<std::string> fontcolor;
250 };
251 struct Input : public Socket {};
252 struct Output : public Socket {};
253
254 std::string node_name;
257
258 Input &add_input(std::string name)
259 {
260 this->inputs.append({});
261 Input &input = this->inputs.last();
262 input.name = std::move(name);
263 return input;
264 }
265
266 Output &add_output(std::string name)
267 {
268 this->outputs.append({});
269 Output &output = this->outputs.last();
270 output.name = std::move(name);
271 return output;
272 }
273};
274
276 private:
277 Node *node_;
278
279 public:
280 NodeWithSocketsRef(Node &node, const NodeWithSockets &data);
281
283 {
284 return *node_;
285 }
286
287 NodePort input(int index) const
288 {
289 std::string port = "\"in" + std::to_string(index) + "\"";
290 return NodePort(*node_, port, "w");
291 }
292
293 NodePort output(int index) const
294 {
295 std::string port = "\"out" + std::to_string(index) + "\"";
296 return NodePort(*node_, port, "e");
297 }
298};
299
300} // namespace blender::dot
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define output
bool add_overwrite(const Key &key, const Value &value)
Definition BLI_map.hh:301
void append(const T &value)
const T & last(const int64_t n=0) const
void export__as_bracket_list(std::stringstream &ss) const
void set(StringRef key, StringRef value)
void set(StringRef key, float value)
void set_parent_cluster(Cluster *new_parent)
Definition dot_export.cc:48
bool contains(Node &node) const
std::string name() const
void export__declare_nodes_and_clusters(std::stringstream &ss) const
void set_parent_cluster(Cluster &cluster)
void set_random_cluster_bgcolors()
Definition dot_export.cc:98
DirectedEdge(NodePort from, NodePort to)
void export__as_edge_statement(std::stringstream &ss) const
DirectedEdge & new_edge(NodePort from, NodePort to)
Definition dot_export.cc:41
std::string to_dot_string() const
void set_arrowtail(Attr_arrowType type)
Edge(NodePort a, NodePort b)
void set_arrowhead(Attr_arrowType type)
void set_dir(Attr_dirType type)
void set_label(StringRef label)
Cluster & new_cluster(StringRef label="")
Definition dot_export.cc:25
void set_random_cluster_bgcolors()
Definition dot_export.cc:91
Node & new_node(StringRef label)
Definition dot_export.cc:16
void export__declare_nodes_and_clusters(std::stringstream &ss) const
void set_rankdir(Attr_rankdir rankdir)
NodePort(Node &node, std::optional< std::string > port_name={}, std::optional< std::string > port_position={})
void to_dot_string(std::stringstream &ss) const
NodePort output(int index) const
NodeWithSocketsRef(Node &node, const NodeWithSockets &data)
NodePort input(int index) const
void set_shape(Attr_shape shape)
void export__as_declaration(std::stringstream &ss) const
void set_background_color(StringRef name)
Cluster * parent_cluster()
void export__as_id(std::stringstream &ss) const
void set_parent_cluster(Cluster *cluster)
Definition dot_export.cc:68
void set_parent_cluster(Cluster &cluster)
UndirectedEdge(NodePort a, NodePort b)
void export__as_edge_statement(std::stringstream &ss) const
UndirectedEdge & new_edge(NodePort a, NodePort b)
Definition dot_export.cc:34
std::string to_dot_string() const
local_group_size(16, 16) .push_constant(Type b
const char * label
std::string color_attr_from_hsv(float h, float s, float v)
_W64 unsigned int uintptr_t
Definition stdint.h:119
std::optional< std::string > fontcolor
Input & add_input(std::string name)
Output & add_output(std::string name)