Blender V4.3
BKE_node_tree_interface.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
8#include "DNA_node_types.h"
9
10#include "BKE_node.hh"
11
12#include <queue>
13#include <type_traits>
14
15#include "BLI_cache_mutex.hh"
17#include "BLI_vector.hh"
18
19namespace blender::bke {
20
21class NodeTreeMainUpdater;
22
24 friend bNodeTreeInterface;
25 friend bNodeTree;
26
27 private:
33 uint32_t changed_flag_ = 0;
34
39 CacheMutex items_cache_mutex_;
40
41 /* Runtime topology cache for linear access to items. */
43 /* Socket-only lists for input/output access by index. */
46};
47
48namespace node_interface {
49
50namespace detail {
51
52template<typename T> static bool item_is_type(const bNodeTreeInterfaceItem &item)
53{
54 bool match = false;
55 switch (item.item_type) {
57 match |= std::is_same<T, bNodeTreeInterfaceSocket>::value;
58 break;
59 }
61 match |= std::is_same<T, bNodeTreeInterfacePanel>::value;
62 break;
63 }
64 }
65 return match;
66}
67
68} // namespace detail
69
70template<typename T> T &get_item_as(bNodeTreeInterfaceItem &item)
71{
73 return reinterpret_cast<T &>(item);
74}
75
76template<typename T> const T &get_item_as(const bNodeTreeInterfaceItem &item)
77{
79 return reinterpret_cast<const T &>(item);
80}
81
82template<typename T> T *get_item_as(bNodeTreeInterfaceItem *item)
83{
84 if (item && detail::item_is_type<T>(*item)) {
85 return reinterpret_cast<T *>(item);
86 }
87 return nullptr;
88}
89
90template<typename T> const T *get_item_as(const bNodeTreeInterfaceItem *item)
91{
92 if (item && detail::item_is_type<T>(*item)) {
93 return reinterpret_cast<const T *>(item);
94 }
95 return nullptr;
96}
97
98namespace socket_types {
99
100/* Info for generating static subtypes. */
108
109/* NOTE: Socket and interface subtypes could be defined from a single central list,
110 * but makesrna cannot have a dependency on BKE, so this list would have to live in RNA itself,
111 * with BKE etc. accessing the RNA API to get the subtypes info. */
113 {"NodeSocketFloat", "NodeTreeInterfaceSocketFloat", SOCK_FLOAT, PROP_NONE},
114 {"NodeSocketFloatUnsigned", "NodeTreeInterfaceSocketFloatUnsigned", SOCK_FLOAT, PROP_UNSIGNED},
115 {"NodeSocketFloatPercentage",
116 "NodeTreeInterfaceSocketFloatPercentage",
119 {"NodeSocketFloatFactor", "NodeTreeInterfaceSocketFloatFactor", SOCK_FLOAT, PROP_FACTOR},
120 {"NodeSocketFloatAngle", "NodeTreeInterfaceSocketFloatAngle", SOCK_FLOAT, PROP_ANGLE},
121 {"NodeSocketFloatTime", "NodeTreeInterfaceSocketFloatTime", SOCK_FLOAT, PROP_TIME},
122 {"NodeSocketFloatTimeAbsolute",
123 "NodeTreeInterfaceSocketFloatTimeAbsolute",
126 {"NodeSocketFloatDistance", "NodeTreeInterfaceSocketFloatDistance", SOCK_FLOAT, PROP_DISTANCE},
127 {"NodeSocketFloatWavelength",
128 "NodeTreeInterfaceSocketFloatWavelength",
131 {"NodeSocketFloatColorTemperature",
132 "NodeTreeInterfaceSocketFloatColorTemperature",
135 {"NodeSocketFloatFrequency",
136 "NodeTreeInterfaceSocketFloatFrequency",
139 {"NodeSocketInt", "NodeTreeInterfaceSocketInt", SOCK_INT, PROP_NONE},
140 {"NodeSocketIntUnsigned", "NodeTreeInterfaceSocketIntUnsigned", SOCK_INT, PROP_UNSIGNED},
141 {"NodeSocketIntPercentage", "NodeTreeInterfaceSocketIntPercentage", SOCK_INT, PROP_PERCENTAGE},
142 {"NodeSocketIntFactor", "NodeTreeInterfaceSocketIntFactor", SOCK_INT, PROP_FACTOR},
143 {"NodeSocketBool", "NodeTreeInterfaceSocketBool", SOCK_BOOLEAN, PROP_NONE},
144 {"NodeSocketRotation", "NodeTreeInterfaceSocketRotation", SOCK_ROTATION, PROP_NONE},
145 {"NodeSocketMatrix", "NodeTreeInterfaceSocketMatrix", SOCK_MATRIX, PROP_NONE},
146 {"NodeSocketVector", "NodeTreeInterfaceSocketVector", SOCK_VECTOR, PROP_NONE},
147 {"NodeSocketVectorTranslation",
148 "NodeTreeInterfaceSocketVectorTranslation",
151 {"NodeSocketVectorDirection",
152 "NodeTreeInterfaceSocketVectorDirection",
155 {"NodeSocketVectorVelocity",
156 "NodeTreeInterfaceSocketVectorVelocity",
159 {"NodeSocketVectorAcceleration",
160 "NodeTreeInterfaceSocketVectorAcceleration",
163 {"NodeSocketVectorEuler", "NodeTreeInterfaceSocketVectorEuler", SOCK_VECTOR, PROP_EULER},
164 {"NodeSocketVectorXYZ", "NodeTreeInterfaceSocketVectorXYZ", SOCK_VECTOR, PROP_XYZ},
165 {"NodeSocketColor", "NodeTreeInterfaceSocketColor", SOCK_RGBA, PROP_NONE},
166 {"NodeSocketString", "NodeTreeInterfaceSocketString", SOCK_STRING, PROP_NONE},
167 {"NodeSocketStringFilePath",
168 "NodeTreeInterfaceSocketStringFilePath",
171 {"NodeSocketShader", "NodeTreeInterfaceSocketShader", SOCK_SHADER, PROP_NONE},
172 {"NodeSocketObject", "NodeTreeInterfaceSocketObject", SOCK_OBJECT, PROP_NONE},
173 {"NodeSocketImage", "NodeTreeInterfaceSocketImage", SOCK_IMAGE, PROP_NONE},
174 {"NodeSocketGeometry", "NodeTreeInterfaceSocketGeometry", SOCK_GEOMETRY, PROP_NONE},
175 {"NodeSocketCollection", "NodeTreeInterfaceSocketCollection", SOCK_COLLECTION, PROP_NONE},
176 {"NodeSocketTexture", "NodeTreeInterfaceSocketTexture", SOCK_TEXTURE, PROP_NONE},
177 {"NodeSocketMaterial", "NodeTreeInterfaceSocketMaterial", SOCK_MATERIAL, PROP_NONE},
178 {"NodeSocketMenu", "NodeTreeInterfaceSocketMenu", SOCK_MENU, PROP_NONE},
179};
180
181template<typename Fn> bool socket_data_to_static_type(const eNodeSocketDatatype type, const Fn &fn)
182{
183 switch (type) {
184 case SOCK_FLOAT:
185 fn.template operator()<bNodeSocketValueFloat>();
186 return true;
187 case SOCK_INT:
188 fn.template operator()<bNodeSocketValueInt>();
189 return true;
190 case SOCK_BOOLEAN:
191 fn.template operator()<bNodeSocketValueBoolean>();
192 return true;
193 case SOCK_ROTATION:
194 fn.template operator()<bNodeSocketValueRotation>();
195 return true;
196 case SOCK_VECTOR:
197 fn.template operator()<bNodeSocketValueVector>();
198 return true;
199 case SOCK_RGBA:
200 fn.template operator()<bNodeSocketValueRGBA>();
201 return true;
202 case SOCK_STRING:
203 fn.template operator()<bNodeSocketValueString>();
204 return true;
205 case SOCK_OBJECT:
206 fn.template operator()<bNodeSocketValueObject>();
207 return true;
208 case SOCK_IMAGE:
209 fn.template operator()<bNodeSocketValueImage>();
210 return true;
211 case SOCK_COLLECTION:
212 fn.template operator()<bNodeSocketValueCollection>();
213 return true;
214 case SOCK_TEXTURE:
215 fn.template operator()<bNodeSocketValueTexture>();
216 return true;
217 case SOCK_MATERIAL:
218 fn.template operator()<bNodeSocketValueMaterial>();
219 return true;
220 case SOCK_MENU:
221 fn.template operator()<bNodeSocketValueMenu>();
222 return true;
223
224 case SOCK_CUSTOM:
225 case SOCK_SHADER:
226 case SOCK_MATRIX:
227 case SOCK_GEOMETRY:
228 return true;
229 }
230 return false;
231}
232
233template<typename Fn> bool socket_data_to_static_type(const StringRef socket_type, const Fn &fn)
234{
236 if (socket_type == info.socket_identifier) {
237 return socket_data_to_static_type(info.type, fn);
238 }
239 }
240 return false;
241}
242
243namespace detail {
244
245template<typename Fn> struct TypeTagExecutor {
246 const Fn &fn;
247
248 TypeTagExecutor(const Fn &fn_) : fn(fn_) {}
249
250 template<typename T> void operator()() const
251 {
252 fn(TypeTag<T>{});
253 }
254};
255
256} // namespace detail
257
258template<typename Fn>
259void socket_data_to_static_type_tag(const StringRef socket_type, const Fn &fn)
260{
261 detail::TypeTagExecutor executor{fn};
262 socket_data_to_static_type(socket_type, executor);
263}
264
265} // namespace socket_types
266
267template<typename T> bool socket_data_is_type(const char *socket_type)
268{
269 bool match = false;
270 socket_types::socket_data_to_static_type_tag(socket_type, [&match](auto type_tag) {
271 using SocketDataType = typename decltype(type_tag)::type;
272 match |= std::is_same_v<T, SocketDataType>;
273 });
274 return match;
275}
276
277template<typename T> T &get_socket_data_as(bNodeTreeInterfaceSocket &item)
278{
280 return *static_cast<T *>(item.socket_data);
281}
282
283template<typename T> const T &get_socket_data_as(const bNodeTreeInterfaceSocket &item)
284{
286 return *static_cast<const T *>(item.socket_data);
287}
288
290 const bNode &from_node,
291 const bNodeSocket &from_sock,
292 const StringRef socket_type,
293 const StringRef name);
294
296 const bNode &from_node,
297 const bNodeSocket &from_sock,
298 const StringRef socket_type)
299{
300 return add_interface_socket_from_node(ntree, from_node, from_sock, socket_type, from_sock.name);
301}
302
304 const bNode &from_node,
305 const bNodeSocket &from_sock)
306{
308 ntree, from_node, from_sock, from_sock.typeinfo->idname, from_sock.name);
309}
310
311} // namespace node_interface
312
313} // namespace blender::bke
#define BLI_assert(a)
Definition BLI_assert.h:50
eNodeSocketDatatype
@ SOCK_INT
@ SOCK_TEXTURE
@ SOCK_VECTOR
@ SOCK_BOOLEAN
@ SOCK_MATERIAL
@ SOCK_SHADER
@ SOCK_MATRIX
@ SOCK_FLOAT
@ SOCK_IMAGE
@ SOCK_COLLECTION
@ SOCK_CUSTOM
@ SOCK_GEOMETRY
@ SOCK_ROTATION
@ SOCK_OBJECT
@ SOCK_STRING
@ SOCK_RGBA
@ SOCK_MENU
PropertySubType
Definition RNA_types.hh:135
@ PROP_TIME
Definition RNA_types.hh:156
@ PROP_DIRECTION
Definition RNA_types.hh:165
@ PROP_XYZ
Definition RNA_types.hh:172
@ PROP_DISTANCE
Definition RNA_types.hh:159
@ PROP_ACCELERATION
Definition RNA_types.hh:167
@ PROP_ANGLE
Definition RNA_types.hh:155
@ PROP_TIME_ABSOLUTE
Definition RNA_types.hh:157
@ PROP_EULER
Definition RNA_types.hh:169
@ PROP_COLOR_TEMPERATURE
Definition RNA_types.hh:193
@ PROP_NONE
Definition RNA_types.hh:136
@ PROP_PERCENTAGE
Definition RNA_types.hh:153
@ PROP_FREQUENCY
Definition RNA_types.hh:195
@ PROP_FACTOR
Definition RNA_types.hh:154
@ PROP_TRANSLATION
Definition RNA_types.hh:164
@ PROP_UNSIGNED
Definition RNA_types.hh:152
@ PROP_FILEPATH
Definition RNA_types.hh:139
@ PROP_VELOCITY
Definition RNA_types.hh:166
@ PROP_WAVELENGTH
Definition RNA_types.hh:190
static bool item_is_type(const bNodeTreeInterfaceItem &item)
void socket_data_to_static_type_tag(const StringRef socket_type, const Fn &fn)
bool socket_data_to_static_type(const eNodeSocketDatatype type, const Fn &fn)
static const bNodeSocketStaticTypeInfo node_socket_subtypes[]
T & get_item_as(bNodeTreeInterfaceItem &item)
bool socket_data_is_type(const char *socket_type)
T & get_socket_data_as(bNodeTreeInterfaceSocket &item)
bNodeTreeInterfaceSocket * add_interface_socket_from_node(bNodeTree &ntree, const bNode &from_node, const bNodeSocket &from_sock, const StringRef socket_type, const StringRef name)
unsigned int uint32_t
Definition stdint.h:80
bNodeSocketTypeHandle * typeinfo