Blender  V3.3
graph/node.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #pragma once
5 
6 #include <type_traits>
7 
8 #include "graph/node_type.h"
9 
10 #include "util/array.h"
11 #include "util/map.h"
12 #include "util/param.h"
13 
15 
16 class MD5Hash;
17 struct Node;
18 struct NodeType;
19 struct Transform;
20 
21 /* NOTE: in the following macros we use "type const &" instead of "const type &"
22  * to avoid issues when pasting a pointer type. */
23 #define NODE_SOCKET_API_BASE_METHODS(type_, name, string_name) \
24  const SocketType *get_##name##_socket() const \
25  { \
26  /* Explicitly cast to base class to use `Node::type` even if the derived class defines \
27  * `type`. */ \
28  const Node *self_node = this; \
29  static const SocketType *socket = self_node->type->find_input(ustring(string_name)); \
30  return socket; \
31  } \
32  bool name##_is_modified() const \
33  { \
34  const SocketType *socket = get_##name##_socket(); \
35  return socket_is_modified(*socket); \
36  } \
37  void tag_##name##_modified() \
38  { \
39  const SocketType *socket = get_##name##_socket(); \
40  socket_modified |= socket->modified_flag_bit; \
41  } \
42  type_ const &get_##name() const \
43  { \
44  const SocketType *socket = get_##name##_socket(); \
45  return get_socket_value<type_>(this, *socket); \
46  }
47 
48 #define NODE_SOCKET_API_BASE(type_, name, string_name) \
49  protected: \
50  type_ name; \
51 \
52  public: \
53  NODE_SOCKET_API_BASE_METHODS(type_, name, string_name)
54 
55 #define NODE_SOCKET_API(type_, name) \
56  NODE_SOCKET_API_BASE(type_, name, #name) \
57  void set_##name(type_ value) \
58  { \
59  const SocketType *socket = get_##name##_socket(); \
60  this->set(*socket, value); \
61  }
62 
63 #define NODE_SOCKET_API_ARRAY(type_, name) \
64  NODE_SOCKET_API_BASE(type_, name, #name) \
65  void set_##name(type_ &value) \
66  { \
67  const SocketType *socket = get_##name##_socket(); \
68  this->set(*socket, value); \
69  } \
70  type_ &get_##name() \
71  { \
72  const SocketType *socket = get_##name##_socket(); \
73  return get_socket_value<type_>(this, *socket); \
74  }
75 
76 #define NODE_SOCKET_API_STRUCT_MEMBER(type_, name, member) \
77  NODE_SOCKET_API_BASE_METHODS(type_, name##_##member, #name "." #member) \
78  void set_##name##_##member(type_ value) \
79  { \
80  const SocketType *socket = get_##name##_##member##_socket(); \
81  this->set(*socket, value); \
82  }
83 
84 /* Node */
85 
86 struct NodeOwner {
87  virtual ~NodeOwner();
88 };
89 
90 struct Node {
91  explicit Node(const NodeType *type, ustring name = ustring());
92  virtual ~Node() = 0;
93 
94  /* set values */
95  void set(const SocketType &input, bool value);
96  void set(const SocketType &input, int value);
97  void set(const SocketType &input, uint value);
98  void set(const SocketType &input, float value);
99  void set(const SocketType &input, float2 value);
100  void set(const SocketType &input, float3 value);
101  void set(const SocketType &input, const char *value);
102  void set(const SocketType &input, ustring value);
103  void set(const SocketType &input, const Transform &value);
104  void set(const SocketType &input, Node *value);
105 
106  /* Implicitly cast enums and enum classes to integer, which matches an internal way of how
107  * enumerator values are stored and accessed in a generic API. */
108  template<class ValueType, typename std::enable_if_t<std::is_enum_v<ValueType>> * = nullptr>
109  void set(const SocketType &input, const ValueType &value)
110  {
111  static_assert(sizeof(ValueType) <= sizeof(int), "Enumerator type should fit int");
112  set(input, static_cast<int>(value));
113  }
114 
115  /* set array values. the memory from the input array will taken over
116  * by the node and the input array will be empty after return */
117  void set(const SocketType &input, array<bool> &value);
118  void set(const SocketType &input, array<int> &value);
119  void set(const SocketType &input, array<float> &value);
120  void set(const SocketType &input, array<float2> &value);
121  void set(const SocketType &input, array<float3> &value);
122  void set(const SocketType &input, array<ustring> &value);
123  void set(const SocketType &input, array<Transform> &value);
124  void set(const SocketType &input, array<Node *> &value);
125 
126  /* get values */
127  bool get_bool(const SocketType &input) const;
128  int get_int(const SocketType &input) const;
129  uint get_uint(const SocketType &input) const;
130  float get_float(const SocketType &input) const;
131  float2 get_float2(const SocketType &input) const;
132  float3 get_float3(const SocketType &input) const;
133  ustring get_string(const SocketType &input) const;
134  Transform get_transform(const SocketType &input) const;
135  Node *get_node(const SocketType &input) const;
136 
137  /* get array values */
138  const array<bool> &get_bool_array(const SocketType &input) const;
139  const array<int> &get_int_array(const SocketType &input) const;
140  const array<float> &get_float_array(const SocketType &input) const;
141  const array<float2> &get_float2_array(const SocketType &input) const;
142  const array<float3> &get_float3_array(const SocketType &input) const;
143  const array<ustring> &get_string_array(const SocketType &input) const;
145  const array<Node *> &get_node_array(const SocketType &input) const;
146 
147  /* generic values operations */
148  bool has_default_value(const SocketType &input) const;
149  void set_default_value(const SocketType &input);
150  bool equals_value(const Node &other, const SocketType &input) const;
151  void copy_value(const SocketType &input, const Node &other, const SocketType &other_input);
152  void set_value(const SocketType &input, const Node &other, const SocketType &other_input);
153 
154  /* equals */
155  bool equals(const Node &other) const;
156 
157  /* compute hash of node and its socket values */
158  void hash(MD5Hash &md5);
159 
160  /* Get total size of this node. */
161  size_t get_total_size_in_bytes() const;
162 
163  /* Type testing, taking into account base classes. */
164  bool is_a(const NodeType *type);
165 
166  bool socket_is_modified(const SocketType &input) const;
167 
168  bool is_modified() const;
169 
170  void tag_modified();
171  void clear_modified();
172 
173  void print_modified_sockets() const;
174 
175  ustring name;
176  const NodeType *type;
177 
178  const NodeOwner *get_owner() const;
179  void set_owner(const NodeOwner *owner_);
180 
181  int reference_count() const
182  {
183  return ref_count;
184  }
185 
186  void reference()
187  {
188  ref_count += 1;
189  }
190 
191  void dereference()
192  {
193  ref_count -= 1;
194  }
195 
196  /* Set the reference count to zero. This should only be called when we know for sure that the
197  * Node is not used by anyone else. For now, this is only the case when "deleting" shaders, as
198  * they are never actually deleted. */
199  void clear_reference_count()
200  {
201  ref_count = 0;
202  }
203 
204  protected:
205  const NodeOwner *owner;
206  int ref_count{0};
207 
208  template<typename T> static T &get_socket_value(const Node *node, const SocketType &socket)
209  {
210  return (T &)*(((char *)node) + socket.struct_offset);
211  }
212 
214 
215  template<typename T> void set_if_different(const SocketType &input, T value);
216 
217  /* Explicit overload for Node sockets so we can handle reference counting. The old Node is
218  * dereferenced, and the new one is referenced. */
219  void set_if_different(const SocketType &input, Node *value);
220 
221  template<typename T> void set_if_different(const SocketType &input, array<T> &value);
222 
223  /* Explicit overload for Node sockets so we can handle reference counting. The old Nodes are
224  * dereferenced, and the new ones are referenced. */
225  void set_if_different(const SocketType &input, array<Node *> &value);
226 
227  /* Call this function in derived classes' destructors to ensure that used Nodes are dereferenced
228  * properly. */
230 };
231 
unsigned int uint
Definition: BLI_sys_types.h:67
Definition: md5.h:20
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
OperationNode * node
ccl_global KernelShaderEvalInput * input
#define T
uint64_t SocketModifiedFlags
Definition: node_type.h:16
virtual ~NodeOwner()
Definition: graph/node.cpp:16
bool has_default_value(const SocketType &input) const
Definition: graph/node.cpp:294
const array< float3 > & get_float3_array(const SocketType &input) const
Definition: graph/node.cpp:268
static T & get_socket_value(const Node *node, const SocketType &socket)
Definition: graph/node.h:207
bool equals(const Node &other) const
Definition: graph/node.cpp:549
const array< float > & get_float_array(const SocketType &input) const
Definition: graph/node.cpp:256
const array< int > & get_int_array(const SocketType &input) const
Definition: graph/node.cpp:250
void dereference()
Definition: graph/node.h:190
const NodeOwner * owner
Definition: graph/node.h:204
float get_float(const SocketType &input) const
Definition: graph/node.cpp:197
Transform get_transform(const SocketType &input) const
Definition: graph/node.cpp:231
void set(const SocketType &input, bool value)
Definition: graph/node.cpp:57
const NodeType * type
Definition: graph/node.h:175
void set_value(const SocketType &input, const Node &other, const SocketType &other_input)
Definition: graph/node.cpp:388
void dereference_all_used_nodes()
Definition: graph/node.cpp:779
float3 get_float3(const SocketType &input) const
Definition: graph/node.cpp:209
int ref_count
Definition: graph/node.h:205
void set_default_value(const SocketType &input)
Definition: graph/node.cpp:301
const array< bool > & get_bool_array(const SocketType &input) const
Definition: graph/node.cpp:244
void copy_value(const SocketType &input, const Node &other, const SocketType &other_input)
Definition: graph/node.cpp:321
const array< Node * > & get_node_array(const SocketType &input) const
Definition: graph/node.cpp:286
ustring name
Definition: graph/node.h:174
size_t get_total_size_in_bytes() const
Definition: graph/node.cpp:695
SocketModifiedFlags socket_modified
Definition: graph/node.h:212
bool get_bool(const SocketType &input) const
Definition: graph/node.cpp:179
int reference_count() const
Definition: graph/node.h:180
float2 get_float2(const SocketType &input) const
Definition: graph/node.cpp:203
void clear_modified()
Definition: graph/node.cpp:814
void reference()
Definition: graph/node.h:185
const array< ustring > & get_string_array(const SocketType &input) const
Definition: graph/node.cpp:274
const array< float2 > & get_float2_array(const SocketType &input) const
Definition: graph/node.cpp:262
void hash(MD5Hash &md5)
Definition: graph/node.cpp:595
bool socket_is_modified(const SocketType &input) const
Definition: graph/node.cpp:799
ustring get_string(const SocketType &input) const
Definition: graph/node.cpp:215
bool is_a(const NodeType *type)
Definition: graph/node.cpp:758
void set_if_different(const SocketType &input, T value)
Definition: graph/node.cpp:819
Node * get_node(const SocketType &input) const
Definition: graph/node.cpp:237
virtual ~Node()=0
Definition: graph/node.cpp:38
const NodeOwner * get_owner() const
Definition: graph/node.cpp:768
void tag_modified()
Definition: graph/node.cpp:809
bool is_modified() const
Definition: graph/node.cpp:804
uint get_uint(const SocketType &input) const
Definition: graph/node.cpp:191
Node(const NodeType *type, ustring name=ustring())
Definition: graph/node.cpp:20
int get_int(const SocketType &input) const
Definition: graph/node.cpp:185
const array< Transform > & get_transform_array(const SocketType &input) const
Definition: graph/node.cpp:280
void clear_reference_count()
Definition: graph/node.h:198
bool equals_value(const Node &other, const SocketType &input) const
Definition: graph/node.cpp:485
void print_modified_sockets() const
Definition: graph/node.cpp:881
void set_owner(const NodeOwner *owner_)
Definition: graph/node.cpp:773
int struct_offset
Definition: node_type.h:74