Blender  V3.3
NOD_derived_node_tree.hh
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #pragma once
4 
14 #include "BLI_function_ref.hh"
15 #include "BLI_vector_set.hh"
16 
17 #include "NOD_node_tree_ref.hh"
18 
19 namespace blender::nodes {
20 
21 class DTreeContext;
22 class DerivedNodeTree;
23 
24 class DNode;
25 class DSocket;
26 class DInputSocket;
27 class DOutputSocket;
28 
36 class DTreeContext {
37  private:
38  /* Null when this context is for the root node group. Otherwise it points to the context one
39  * level up. */
40  DTreeContext *parent_context_;
41  /* Null when this context is for the root node group. Otherwise it points to the group node in
42  * the parent node group that contains this context. */
43  const NodeRef *parent_node_;
44  /* The current node tree. */
45  const NodeTreeRef *tree_;
46  /* All the children contexts of this context. */
48  DerivedNodeTree *derived_tree_;
49 
50  friend DerivedNodeTree;
51 
52  public:
53  const NodeTreeRef &tree() const;
54  const DTreeContext *parent_context() const;
55  const NodeRef *parent_node() const;
56  const DTreeContext *child_context(const NodeRef &node) const;
57  const DerivedNodeTree &derived_tree() const;
58  bool is_root() const;
59 };
60 
65 class DNode {
66  private:
67  const DTreeContext *context_ = nullptr;
68  const NodeRef *node_ref_ = nullptr;
69 
70  public:
71  DNode() = default;
72  DNode(const DTreeContext *context, const NodeRef *node);
73 
74  const DTreeContext *context() const;
75  const NodeRef *node_ref() const;
76  const NodeRef *operator->() const;
77 
78  friend bool operator==(const DNode &a, const DNode &b);
79  friend bool operator!=(const DNode &a, const DNode &b);
80  operator bool() const;
81 
82  uint64_t hash() const;
83 
84  DInputSocket input(int index) const;
85  DOutputSocket output(int index) const;
86 
87  DInputSocket input_by_identifier(StringRef identifier) const;
89 };
90 
98 class DSocket {
99  protected:
100  const DTreeContext *context_ = nullptr;
101  const SocketRef *socket_ref_ = nullptr;
102 
103  public:
104  DSocket() = default;
105  DSocket(const DTreeContext *context, const SocketRef *socket);
106  DSocket(const DInputSocket &input_socket);
107  DSocket(const DOutputSocket &output_socket);
108 
109  const DTreeContext *context() const;
110  const SocketRef *socket_ref() const;
111  const SocketRef *operator->() const;
112 
113  friend bool operator==(const DSocket &a, const DSocket &b);
114  friend bool operator!=(const DSocket &a, const DSocket &b);
115  operator bool() const;
116 
117  uint64_t hash() const;
118 
119  DNode node() const;
120 };
121 
123 class DInputSocket : public DSocket {
124  public:
125  DInputSocket() = default;
126  DInputSocket(const DTreeContext *context, const InputSocketRef *socket);
127  explicit DInputSocket(const DSocket &base_socket);
128 
129  const InputSocketRef *socket_ref() const;
130  const InputSocketRef *operator->() const;
131 
134 
140  void foreach_origin_socket(FunctionRef<void(DSocket)> origin_fn) const;
141 };
142 
144 class DOutputSocket : public DSocket {
145  public:
146  DOutputSocket() = default;
147  DOutputSocket(const DTreeContext *context, const OutputSocketRef *socket);
148  explicit DOutputSocket(const DSocket &base_socket);
149 
150  const OutputSocketRef *socket_ref() const;
151  const OutputSocketRef *operator->() const;
152 
155 
159  };
160 
163 
169  void foreach_target_socket(ForeachTargetSocketFn target_fn) const;
170 
171  private:
173  TargetSocketPathInfo &path_info) const;
174 };
175 
177  private:
178  LinearAllocator<> allocator_;
179  DTreeContext *root_context_;
180  VectorSet<const NodeTreeRef *> used_node_tree_refs_;
181 
182  public:
189  DerivedNodeTree(bNodeTree &btree, NodeTreeRefMap &node_tree_refs);
191 
192  const DTreeContext &root_context() const;
194 
198  bool has_link_cycles() const;
199  bool has_undefined_nodes_or_sockets() const;
201  void foreach_node(FunctionRef<void(DNode)> callback) const;
202 
204  std::string to_dot() const;
205 
206  private:
207  DTreeContext &construct_context_recursively(DTreeContext *parent_context,
208  const NodeRef *parent_node,
209  bNodeTree &btree,
210  NodeTreeRefMap &node_tree_refs);
211  void destruct_context_recursively(DTreeContext *context);
212 
213  void foreach_node_in_context_recursive(const DTreeContext &context,
214  FunctionRef<void(DNode)> callback) const;
215 };
216 
217 namespace derived_node_tree_types {
218 using namespace node_tree_ref_types;
220 using nodes::DInputSocket;
221 using nodes::DNode;
223 using nodes::DSocket;
224 using nodes::DTreeContext;
225 } // namespace derived_node_tree_types
226 
227 /* -------------------------------------------------------------------- */
231 inline const NodeTreeRef &DTreeContext::tree() const
232 {
233  return *tree_;
234 }
235 
237 {
238  return parent_context_;
239 }
240 
241 inline const NodeRef *DTreeContext::parent_node() const
242 {
243  return parent_node_;
244 }
245 
247 {
248  return children_.lookup_default(&node, nullptr);
249 }
250 
252 {
253  return *derived_tree_;
254 }
255 
256 inline bool DTreeContext::is_root() const
257 {
258  return parent_context_ == nullptr;
259 }
260 
263 /* -------------------------------------------------------------------- */
267 inline DNode::DNode(const DTreeContext *context, const NodeRef *node_ref)
268  : context_(context), node_ref_(node_ref)
269 {
270  BLI_assert(node_ref == nullptr || &node_ref->tree() == &context->tree());
271 }
272 
273 inline const DTreeContext *DNode::context() const
274 {
275  return context_;
276 }
277 
278 inline const NodeRef *DNode::node_ref() const
279 {
280  return node_ref_;
281 }
282 
283 inline bool operator==(const DNode &a, const DNode &b)
284 {
285  return a.context_ == b.context_ && a.node_ref_ == b.node_ref_;
286 }
287 
288 inline bool operator!=(const DNode &a, const DNode &b)
289 {
290  return !(a == b);
291 }
292 
293 inline DNode::operator bool() const
294 {
295  return node_ref_ != nullptr;
296 }
297 
298 inline const NodeRef *DNode::operator->() const
299 {
300  return node_ref_;
301 }
302 
303 inline uint64_t DNode::hash() const
304 {
305  return get_default_hash_2(context_, node_ref_);
306 }
307 
308 inline DInputSocket DNode::input(int index) const
309 {
310  return {context_, &node_ref_->input(index)};
311 }
312 
313 inline DOutputSocket DNode::output(int index) const
314 {
315  return {context_, &node_ref_->output(index)};
316 }
317 
319 {
320  return {context_, &node_ref_->input_by_identifier(identifier)};
321 }
322 
324 {
325  return {context_, &node_ref_->output_by_identifier(identifier)};
326 }
327 
330 /* -------------------------------------------------------------------- */
334 inline DSocket::DSocket(const DTreeContext *context, const SocketRef *socket_ref)
335  : context_(context), socket_ref_(socket_ref)
336 {
337  BLI_assert(socket_ref == nullptr || &socket_ref->tree() == &context->tree());
338 }
339 
340 inline DSocket::DSocket(const DInputSocket &input_socket)
341  : DSocket(input_socket.context_, input_socket.socket_ref_)
342 {
343 }
344 
345 inline DSocket::DSocket(const DOutputSocket &output_socket)
346  : DSocket(output_socket.context_, output_socket.socket_ref_)
347 {
348 }
349 
350 inline const DTreeContext *DSocket::context() const
351 {
352  return context_;
353 }
354 
355 inline const SocketRef *DSocket::socket_ref() const
356 {
357  return socket_ref_;
358 }
359 
360 inline bool operator==(const DSocket &a, const DSocket &b)
361 {
362  return a.context_ == b.context_ && a.socket_ref_ == b.socket_ref_;
363 }
364 
365 inline bool operator!=(const DSocket &a, const DSocket &b)
366 {
367  return !(a == b);
368 }
369 
370 inline DSocket::operator bool() const
371 {
372  return socket_ref_ != nullptr;
373 }
374 
375 inline const SocketRef *DSocket::operator->() const
376 {
377  return socket_ref_;
378 }
379 
380 inline uint64_t DSocket::hash() const
381 {
383 }
384 
385 inline DNode DSocket::node() const
386 {
387  BLI_assert(socket_ref_ != nullptr);
388  return {context_, &socket_ref_->node()};
389 }
390 
393 /* -------------------------------------------------------------------- */
398  : DSocket(context, socket_ref)
399 {
400 }
401 
402 inline DInputSocket::DInputSocket(const DSocket &base_socket) : DSocket(base_socket)
403 {
404  BLI_assert(base_socket->is_input());
405 }
406 
408 {
409  return (const InputSocketRef *)socket_ref_;
410 }
411 
413 {
414  return (const InputSocketRef *)socket_ref_;
415 }
416 
419 /* -------------------------------------------------------------------- */
424  : DSocket(context, socket_ref)
425 {
426 }
427 
428 inline DOutputSocket::DOutputSocket(const DSocket &base_socket) : DSocket(base_socket)
429 {
430  BLI_assert(base_socket->is_output());
431 }
432 
434 {
435  return (const OutputSocketRef *)socket_ref_;
436 }
437 
439 {
440  return (const OutputSocketRef *)socket_ref_;
441 }
442 
445 /* -------------------------------------------------------------------- */
450 {
451  return *root_context_;
452 }
453 
455 {
456  return used_node_tree_refs_;
457 }
458 
461 } // namespace blender::nodes
#define BLI_assert(a)
Definition: BLI_assert.h:46
void foreach_origin_socket(FunctionRef< void(DSocket)> origin_fn) const
const InputSocketRef * operator->() const
const InputSocketRef * socket_ref() 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 NodeRef * operator->() const
DOutputSocket output(int index) const
friend bool operator==(const DNode &a, const DNode &b)
const NodeRef * node_ref() const
friend bool operator!=(const DNode &a, const DNode &b)
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
const OutputSocketRef * operator->() const
const OutputSocketRef * socket_ref() const
void foreach_target_socket(ForeachTargetSocketFn target_fn) const
const SocketRef * socket_ref() const
const DTreeContext * context() const
const SocketRef * operator->() const
const DTreeContext * context_
friend bool operator==(const DSocket &a, const DSocket &b)
friend bool operator!=(const DSocket &a, const DSocket &b)
const DTreeContext * parent_context() const
const DTreeContext * child_context(const NodeRef &node) const
const NodeRef * parent_node() const
const DerivedNodeTree & derived_tree() const
const NodeTreeRef & tree() const
Span< const NodeTreeRef * > used_node_tree_refs() const
DerivedNodeTree(bNodeTree &btree, NodeTreeRefMap &node_tree_refs)
const DTreeContext & root_context() const
void foreach_node(FunctionRef< void(DNode)> callback) const
const OutputSocketRef & output_by_identifier(StringRef identifier) const
const OutputSocketRef & output(int index) const
const InputSocketRef & input(int index) const
const InputSocketRef & input_by_identifier(StringRef identifier) const
const NodeTreeRef & tree() const
const NodeRef & node() const
const NodeTreeRef & tree() const
OperationNode * node
DEGForeachIDComponentCallback callback
SyclQueue void void size_t num_bytes void
static unsigned a[3]
Definition: RandGen.cpp:78
bool operator!=(const DNode &a, const DNode &b)
bool operator==(const DNode &a, const DNode &b)
uint64_t get_default_hash_2(const T1 &v1, const T2 &v2)
Definition: BLI_hash.hh:223
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
unsigned __int64 uint64_t
Definition: stdint.h:90