Blender V4.3
NOD_derived_node_tree.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
16#include "BLI_function_ref.hh"
18#include "BLI_vector_set.hh"
19
20#include "BKE_node_runtime.hh"
21
22namespace blender::nodes {
23
24class DTreeContext;
25class DerivedNodeTree;
26
27class DNode;
28class DSocket;
29class DInputSocket;
30class DOutputSocket;
31
40 private:
41 /* Null when this context is for the root node group. Otherwise it points to the context one
42 * level up. */
43 DTreeContext *parent_context_;
44 /* Null when this context is for the root node group. Otherwise it points to the group node in
45 * the parent node group that contains this context. */
46 const bNode *parent_node_;
47 /* The current node tree. */
48 const bNodeTree *btree_;
49 /* The instance key of the parent node. bke::NODE_INSTANCE_KEY_BASE for root contexts. */
50 bNodeInstanceKey instance_key_;
51 /* All the children contexts of this context. */
53 DerivedNodeTree *derived_tree_;
54
55 friend DerivedNodeTree;
56
57 public:
58 const bNodeTree &btree() const;
59 const DTreeContext *parent_context() const;
60 const bNode *parent_node() const;
61 const bNodeInstanceKey instance_key() const;
62 const DTreeContext *child_context(const bNode &node) const;
63 const DerivedNodeTree &derived_tree() const;
64 bool is_root() const;
65};
66
71class DNode {
72 private:
73 const DTreeContext *context_ = nullptr;
74 const bNode *bnode_ = nullptr;
75
76 public:
77 DNode() = default;
78 DNode(const DTreeContext *context, const bNode *node);
79
80 const DTreeContext *context() const;
81 const bNode *bnode() const;
82 const bNodeInstanceKey instance_key() const;
83 const bNode *operator->() const;
84 const bNode &operator*() const;
85
86 BLI_STRUCT_EQUALITY_OPERATORS_2(DNode, context_, bnode_)
87
88 operator bool() const;
89
90 uint64_t hash() const;
91
92 DInputSocket input(int index) const;
93 DOutputSocket output(int index) const;
94
97};
98
106class DSocket {
107 protected:
108 const DTreeContext *context_ = nullptr;
109 const bNodeSocket *bsocket_ = nullptr;
110
111 public:
112 DSocket() = default;
113 DSocket(const DTreeContext *context, const bNodeSocket *socket);
114 DSocket(const DInputSocket &input_socket);
115 DSocket(const DOutputSocket &output_socket);
116
117 const DTreeContext *context() const;
118 const bNodeSocket *bsocket() const;
119 const bNodeSocket *operator->() const;
120 const bNodeSocket &operator*() const;
121
123
124 operator bool() const;
125
126 uint64_t hash() const;
127
128 DNode node() const;
129};
130
132class DInputSocket : public DSocket {
133 public:
134 DInputSocket() = default;
135 DInputSocket(const DTreeContext *context, const bNodeSocket *socket);
136 explicit DInputSocket(const DSocket &base_socket);
137
140
146 void foreach_origin_socket(FunctionRef<void(DSocket)> origin_fn) const;
147};
148
150class DOutputSocket : public DSocket {
151 public:
152 DOutputSocket() = default;
153 DOutputSocket(const DTreeContext *context, const bNodeSocket *socket);
154 explicit DOutputSocket(const DSocket &base_socket);
155
158
163
165 FunctionRef<void(DInputSocket, const TargetSocketPathInfo &path_info)>;
166
172 void foreach_target_socket(ForeachTargetSocketFn target_fn) const;
173
174 private:
176 TargetSocketPathInfo &path_info) const;
177};
178
180 private:
181 LinearAllocator<> allocator_;
182 DTreeContext *root_context_;
183 VectorSet<const bNodeTree *> used_btrees_;
184
185 public:
192 DerivedNodeTree(const bNodeTree &btree);
194
195 const DTreeContext &root_context() const;
197
204 const DTreeContext &active_context() const;
205
209 bool has_link_cycles() const;
212 void foreach_node(FunctionRef<void(DNode)> callback) const;
213
215 std::string to_dot() const;
216
217 private:
218 DTreeContext &construct_context_recursively(DTreeContext *parent_context,
219 const bNode *parent_node,
220 const bNodeTree &btree,
221 const bNodeInstanceKey instance_key);
222 void destruct_context_recursively(DTreeContext *context);
223
224 void foreach_node_in_context_recursive(const DTreeContext &context,
225 FunctionRef<void(DNode)> callback) const;
226};
227
228namespace derived_node_tree_types {
231using nodes::DNode;
233using nodes::DSocket;
235} // namespace derived_node_tree_types
236
237/* -------------------------------------------------------------------- */
241inline const bNodeTree &DTreeContext::btree() const
242{
243 return *btree_;
244}
245
247{
248 return parent_context_;
249}
250
251inline const bNode *DTreeContext::parent_node() const
252{
253 return parent_node_;
254}
255
257{
258 return instance_key_;
259}
260
261inline const DTreeContext *DTreeContext::child_context(const bNode &node) const
262{
263 return children_.lookup_default(&node, nullptr);
264}
265
267{
268 return *derived_tree_;
269}
270
271inline bool DTreeContext::is_root() const
272{
273 return parent_context_ == nullptr;
274}
275
278/* -------------------------------------------------------------------- */
282inline DNode::DNode(const DTreeContext *context, const bNode *bnode)
283 : context_(context), bnode_(bnode)
284{
285 BLI_assert(bnode == nullptr || bnode->runtime->owner_tree == &context->btree());
286}
287
288inline const DTreeContext *DNode::context() const
289{
290 return context_;
291}
292
293inline const bNode *DNode::bnode() const
294{
295 return bnode_;
296}
297
298inline DNode::operator bool() const
299{
300 return bnode_ != nullptr;
301}
302
303inline const bNode *DNode::operator->() const
304{
305 return bnode_;
306}
307
308inline const bNode &DNode::operator*() const
309{
310 BLI_assert(bnode_ != nullptr);
311 return *bnode_;
312}
313
314inline uint64_t DNode::hash() const
315{
316 return get_default_hash(context_, bnode_);
317}
318
319inline DInputSocket DNode::input(int index) const
320{
321 return {context_, &bnode_->input_socket(index)};
322}
323
324inline DOutputSocket DNode::output(int index) const
325{
326 return {context_, &bnode_->output_socket(index)};
327}
328
330{
331 return {context_, &bnode_->input_by_identifier(identifier)};
332}
333
335{
336 return {context_, &bnode_->output_by_identifier(identifier)};
337}
338
341/* -------------------------------------------------------------------- */
345inline DSocket::DSocket(const DTreeContext *context, const bNodeSocket *bsocket)
346 : context_(context), bsocket_(bsocket)
347{
348 BLI_assert(bsocket == nullptr ||
349 bsocket->runtime->owner_node->runtime->owner_tree == &context->btree());
350}
351
352inline DSocket::DSocket(const DInputSocket &input_socket)
353 : DSocket(input_socket.context_, input_socket.bsocket_)
354{
355}
356
357inline DSocket::DSocket(const DOutputSocket &output_socket)
358 : DSocket(output_socket.context_, output_socket.bsocket_)
359{
360}
361
362inline const DTreeContext *DSocket::context() const
363{
364 return context_;
365}
366
367inline const bNodeSocket *DSocket::bsocket() const
368{
369 return bsocket_;
370}
371
372inline DSocket::operator bool() const
373{
374 return bsocket_ != nullptr;
375}
376
377inline const bNodeSocket *DSocket::operator->() const
378{
379 return bsocket_;
380}
381
382inline const bNodeSocket &DSocket::operator*() const
383{
384 BLI_assert(bsocket_ != nullptr);
385 return *bsocket_;
386}
387
389{
391}
392
393inline DNode DSocket::node() const
394{
395 BLI_assert(bsocket_ != nullptr);
396 return {context_, bsocket_->runtime->owner_node};
397}
398
401/* -------------------------------------------------------------------- */
405inline DInputSocket::DInputSocket(const DTreeContext *context, const bNodeSocket *bsocket)
406 : DSocket(context, bsocket)
407{
408}
409
410inline DInputSocket::DInputSocket(const DSocket &base_socket) : DSocket(base_socket)
411{
412 BLI_assert(base_socket->is_input());
413}
414
417/* -------------------------------------------------------------------- */
421inline DOutputSocket::DOutputSocket(const DTreeContext *context, const bNodeSocket *bsocket)
422 : DSocket(context, bsocket)
423{
424}
425
426inline DOutputSocket::DOutputSocket(const DSocket &base_socket) : DSocket(base_socket)
427{
428 BLI_assert(base_socket->is_output());
429}
430
433/* -------------------------------------------------------------------- */
438{
439 return *root_context_;
440}
441
443{
444 return used_btrees_;
445}
446
449} // namespace blender::nodes
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_STRUCT_EQUALITY_OPERATORS_2(Type, m1, m2)
#define output
void foreach_origin_socket(FunctionRef< void(DSocket)> origin_fn) const
DOutputSocket get_corresponding_group_node_output() const
Vector< DOutputSocket, 4 > get_corresponding_group_input_sockets() const
DInputSocket input_by_identifier(StringRef identifier) const
const DTreeContext * context() const
const bNodeInstanceKey instance_key() const
DOutputSocket output(int index) const
const bNode * bnode() const
const bNode * operator->() const
const bNode & operator*() const
DOutputSocket output_by_identifier(StringRef identifier) const
DInputSocket input(int index) const
DInputSocket get_corresponding_group_node_input() const
DInputSocket get_active_corresponding_group_output_socket() const
void foreach_target_socket(ForeachTargetSocketFn target_fn) const
const bNodeSocket * operator->() const
const DTreeContext * context() const
const bNodeSocket & operator*() const
const bNodeSocket * bsocket() const
const DTreeContext * child_context(const bNode &node) const
const DTreeContext * parent_context() const
const bNodeInstanceKey instance_key() const
const DerivedNodeTree & derived_tree() const
const bNodeTree & btree() const
const DTreeContext & active_context() const
DerivedNodeTree(const bNodeTree &btree)
Span< const bNodeTree * > used_btrees() const
const DTreeContext & root_context() const
void foreach_node(FunctionRef< void(DNode)> callback) const
DEGForeachIDComponentCallback callback
uint64_t get_default_hash(const T &v)
Definition BLI_hash.hh:219
unsigned __int64 uint64_t
Definition stdint.h:90
bNodeSocketRuntimeHandle * runtime
bNodeRuntimeHandle * runtime