Blender V4.5
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
8
9#pragma once
10
12#include "DNA_node_types.h"
13
14#include "BKE_node.hh"
15
16#include <type_traits>
17
18#include "BLI_cache_mutex.hh"
20#include "BLI_vector_set.hh"
21
22namespace blender::bke {
23
25
27 friend bNodeTreeInterface;
28 friend bNodeTree;
29
30 private:
34 std::atomic<bool> interface_changed_ = true;
35
40 CacheMutex items_cache_mutex_;
41
42 /* Runtime topology cache for linear access to items. */
44 /* Socket-only lists for input/output access by index. */
47};
48
49namespace node_interface {
50
51namespace detail {
52
53template<typename T> static bool item_is_type(const bNodeTreeInterfaceItem &item)
54{
55 bool match = false;
58 match |= std::is_same_v<T, bNodeTreeInterfaceSocket>;
59 break;
60 }
62 match |= std::is_same_v<T, bNodeTreeInterfacePanel>;
63 break;
64 }
65 }
66 return match;
67}
68
69} // namespace detail
70
71template<typename T> T &get_item_as(bNodeTreeInterfaceItem &item)
72{
74 return reinterpret_cast<T &>(item);
75}
76
77template<typename T> const T &get_item_as(const bNodeTreeInterfaceItem &item)
78{
80 return reinterpret_cast<const T &>(item);
81}
82
83template<typename T> T *get_item_as(bNodeTreeInterfaceItem *item)
84{
85 if (item && detail::item_is_type<T>(*item)) {
86 return reinterpret_cast<T *>(item);
87 }
88 return nullptr;
89}
90
91template<typename T> const T *get_item_as(const bNodeTreeInterfaceItem *item)
92{
93 if (item && detail::item_is_type<T>(*item)) {
94 return reinterpret_cast<const T *>(item);
95 }
96 return nullptr;
97}
98
99namespace socket_types {
100
101/* Info for generating static subtypes. */
109
110/* NOTE: Socket and interface subtypes could be defined from a single central list,
111 * but makesrna cannot have a dependency on BKE, so this list would have to live in RNA itself,
112 * with BKE etc. accessing the RNA API to get the subtypes info. */
114 {"NodeSocketFloat", "NodeTreeInterfaceSocketFloat", SOCK_FLOAT, PROP_NONE},
115 {"NodeSocketFloatUnsigned", "NodeTreeInterfaceSocketFloatUnsigned", SOCK_FLOAT, PROP_UNSIGNED},
116 {"NodeSocketFloatPercentage",
117 "NodeTreeInterfaceSocketFloatPercentage",
120 {"NodeSocketFloatFactor", "NodeTreeInterfaceSocketFloatFactor", SOCK_FLOAT, PROP_FACTOR},
121 {"NodeSocketFloatAngle", "NodeTreeInterfaceSocketFloatAngle", SOCK_FLOAT, PROP_ANGLE},
122 {"NodeSocketFloatTime", "NodeTreeInterfaceSocketFloatTime", SOCK_FLOAT, PROP_TIME},
123 {"NodeSocketFloatTimeAbsolute",
124 "NodeTreeInterfaceSocketFloatTimeAbsolute",
127 {"NodeSocketFloatDistance", "NodeTreeInterfaceSocketFloatDistance", SOCK_FLOAT, PROP_DISTANCE},
128 {"NodeSocketFloatWavelength",
129 "NodeTreeInterfaceSocketFloatWavelength",
132 {"NodeSocketFloatColorTemperature",
133 "NodeTreeInterfaceSocketFloatColorTemperature",
136 {"NodeSocketFloatFrequency",
137 "NodeTreeInterfaceSocketFloatFrequency",
140 {"NodeSocketInt", "NodeTreeInterfaceSocketInt", SOCK_INT, PROP_NONE},
141 {"NodeSocketIntUnsigned", "NodeTreeInterfaceSocketIntUnsigned", SOCK_INT, PROP_UNSIGNED},
142 {"NodeSocketIntPercentage", "NodeTreeInterfaceSocketIntPercentage", SOCK_INT, PROP_PERCENTAGE},
143 {"NodeSocketIntFactor", "NodeTreeInterfaceSocketIntFactor", SOCK_INT, PROP_FACTOR},
144 {"NodeSocketBool", "NodeTreeInterfaceSocketBool", SOCK_BOOLEAN, PROP_NONE},
145 {"NodeSocketRotation", "NodeTreeInterfaceSocketRotation", SOCK_ROTATION, PROP_NONE},
146 {"NodeSocketMatrix", "NodeTreeInterfaceSocketMatrix", SOCK_MATRIX, PROP_NONE},
147
148 {"NodeSocketVector", "NodeTreeInterfaceSocketVector", SOCK_VECTOR, PROP_NONE},
149 {"NodeSocketVectorFactor", "NodeTreeInterfaceSocketVectorFactor", SOCK_VECTOR, PROP_FACTOR},
150 {"NodeSocketVectorPercentage",
151 "NodeTreeInterfaceSocketVectorPercentage",
154 {"NodeSocketVectorTranslation",
155 "NodeTreeInterfaceSocketVectorTranslation",
158 {"NodeSocketVectorDirection",
159 "NodeTreeInterfaceSocketVectorDirection",
162 {"NodeSocketVectorVelocity",
163 "NodeTreeInterfaceSocketVectorVelocity",
166 {"NodeSocketVectorAcceleration",
167 "NodeTreeInterfaceSocketVectorAcceleration",
170 {"NodeSocketVectorEuler", "NodeTreeInterfaceSocketVectorEuler", SOCK_VECTOR, PROP_EULER},
171 {"NodeSocketVectorXYZ", "NodeTreeInterfaceSocketVectorXYZ", SOCK_VECTOR, PROP_XYZ},
172
173 {"NodeSocketVector2D", "NodeTreeInterfaceSocketVector2D", SOCK_VECTOR, PROP_NONE},
174 {"NodeSocketVectorFactor2D",
175 "NodeTreeInterfaceSocketVectorFactor2D",
178 {"NodeSocketVectorPercentage2D",
179 "NodeTreeInterfaceSocketVectorPercentage2D",
182 {"NodeSocketVectorTranslation2D",
183 "NodeTreeInterfaceSocketVectorTranslation2D",
186 {"NodeSocketVectorDirection2D",
187 "NodeTreeInterfaceSocketVectorDirection2D",
190 {"NodeSocketVectorVelocity2D",
191 "NodeTreeInterfaceSocketVectorVelocity2D",
194 {"NodeSocketVectorAcceleration2D",
195 "NodeTreeInterfaceSocketVectorAcceleration2D",
198 {"NodeSocketVectorEuler2D", "NodeTreeInterfaceSocketVectorEuler2D", SOCK_VECTOR, PROP_EULER},
199 {"NodeSocketVectorXYZ2D", "NodeTreeInterfaceSocketVectorXYZ2D", SOCK_VECTOR, PROP_XYZ},
200
201 {"NodeSocketVector4D", "NodeTreeInterfaceSocketVector4D", SOCK_VECTOR, PROP_NONE},
202 {"NodeSocketVectorFactor4D",
203 "NodeTreeInterfaceSocketVectorFactor4D",
206 {"NodeSocketVectorPercentage4D",
207 "NodeTreeInterfaceSocketVectorPercentage4D",
210 {"NodeSocketVectorTranslation4D",
211 "NodeTreeInterfaceSocketVectorTranslation4D",
214 {"NodeSocketVectorDirection4D",
215 "NodeTreeInterfaceSocketVectorDirection4D",
218 {"NodeSocketVectorVelocity4D",
219 "NodeTreeInterfaceSocketVectorVelocity4D",
222 {"NodeSocketVectorAcceleration4D",
223 "NodeTreeInterfaceSocketVectorAcceleration4D",
226 {"NodeSocketVectorEuler4D", "NodeTreeInterfaceSocketVectorEuler4D", SOCK_VECTOR, PROP_EULER},
227 {"NodeSocketVectorXYZ4D", "NodeTreeInterfaceSocketVectorXYZ4D", SOCK_VECTOR, PROP_XYZ},
228
229 {"NodeSocketColor", "NodeTreeInterfaceSocketColor", SOCK_RGBA, PROP_NONE},
230 {"NodeSocketString", "NodeTreeInterfaceSocketString", SOCK_STRING, PROP_NONE},
231 {"NodeSocketStringFilePath",
232 "NodeTreeInterfaceSocketStringFilePath",
235 {"NodeSocketShader", "NodeTreeInterfaceSocketShader", SOCK_SHADER, PROP_NONE},
236 {"NodeSocketObject", "NodeTreeInterfaceSocketObject", SOCK_OBJECT, PROP_NONE},
237 {"NodeSocketImage", "NodeTreeInterfaceSocketImage", SOCK_IMAGE, PROP_NONE},
238 {"NodeSocketGeometry", "NodeTreeInterfaceSocketGeometry", SOCK_GEOMETRY, PROP_NONE},
239 {"NodeSocketCollection", "NodeTreeInterfaceSocketCollection", SOCK_COLLECTION, PROP_NONE},
240 {"NodeSocketTexture", "NodeTreeInterfaceSocketTexture", SOCK_TEXTURE, PROP_NONE},
241 {"NodeSocketMaterial", "NodeTreeInterfaceSocketMaterial", SOCK_MATERIAL, PROP_NONE},
242 {"NodeSocketMenu", "NodeTreeInterfaceSocketMenu", SOCK_MENU, PROP_NONE},
243 {"NodeSocketBundle", "NodeTreeInterfaceSocketBundle", SOCK_BUNDLE, PROP_NONE},
244 {"NodeSocketClosure", "NodeTreeInterfaceSocketClosure", SOCK_CLOSURE, PROP_NONE},
245};
246
247template<typename Fn> bool socket_data_to_static_type(const eNodeSocketDatatype type, const Fn &fn)
248{
249 switch (type) {
250 case SOCK_FLOAT:
251 fn.template operator()<bNodeSocketValueFloat>();
252 return true;
253 case SOCK_INT:
254 fn.template operator()<bNodeSocketValueInt>();
255 return true;
256 case SOCK_BOOLEAN:
257 fn.template operator()<bNodeSocketValueBoolean>();
258 return true;
259 case SOCK_ROTATION:
260 fn.template operator()<bNodeSocketValueRotation>();
261 return true;
262 case SOCK_VECTOR:
263 fn.template operator()<bNodeSocketValueVector>();
264 return true;
265 case SOCK_RGBA:
266 fn.template operator()<bNodeSocketValueRGBA>();
267 return true;
268 case SOCK_STRING:
269 fn.template operator()<bNodeSocketValueString>();
270 return true;
271 case SOCK_OBJECT:
272 fn.template operator()<bNodeSocketValueObject>();
273 return true;
274 case SOCK_IMAGE:
275 fn.template operator()<bNodeSocketValueImage>();
276 return true;
277 case SOCK_COLLECTION:
278 fn.template operator()<bNodeSocketValueCollection>();
279 return true;
280 case SOCK_TEXTURE:
281 fn.template operator()<bNodeSocketValueTexture>();
282 return true;
283 case SOCK_MATERIAL:
284 fn.template operator()<bNodeSocketValueMaterial>();
285 return true;
286 case SOCK_MENU:
287 fn.template operator()<bNodeSocketValueMenu>();
288 return true;
289
290 case SOCK_CUSTOM:
291 case SOCK_SHADER:
292 case SOCK_MATRIX:
293 case SOCK_GEOMETRY:
294 case SOCK_BUNDLE:
295 case SOCK_CLOSURE:
296 return true;
297 }
298 return false;
299}
300
301template<typename Fn> bool socket_data_to_static_type(const StringRef socket_type, const Fn &fn)
302{
304 if (socket_type == info.socket_identifier) {
305 return socket_data_to_static_type(info.type, fn);
306 }
307 }
308 return false;
309}
310
311namespace detail {
312
313template<typename Fn> struct TypeTagExecutor {
314 const Fn &fn;
315
316 TypeTagExecutor(const Fn &fn_) : fn(fn_) {}
317
318 template<typename T> void operator()() const
319 {
320 fn(TypeTag<T>{});
321 }
322};
323
324} // namespace detail
325
326template<typename Fn>
327void socket_data_to_static_type_tag(const StringRef socket_type, const Fn &fn)
328{
329 detail::TypeTagExecutor executor{fn};
330 socket_data_to_static_type(socket_type, executor);
331}
332
333} // namespace socket_types
334
335template<typename T> bool socket_data_is_type(const char *socket_type)
336{
337 bool match = false;
338 socket_types::socket_data_to_static_type_tag(socket_type, [&match](auto type_tag) {
339 using SocketDataType = typename decltype(type_tag)::type;
340 match |= std::is_same_v<T, SocketDataType>;
341 });
342 return match;
343}
344
346{
348 return *static_cast<T *>(item.socket_data);
349}
350
351template<typename T> const T &get_socket_data_as(const bNodeTreeInterfaceSocket &item)
352{
354 return *static_cast<const T *>(item.socket_data);
355}
356
358 const bNode &from_node,
359 const bNodeSocket &from_sock,
360 StringRef socket_type,
361 StringRef name);
362
364 const bNode &from_node,
365 const bNodeSocket &from_sock,
366 const StringRef socket_type)
367{
368 return add_interface_socket_from_node(ntree, from_node, from_sock, socket_type, from_sock.name);
369}
370
372 const bNode &from_node,
373 const bNodeSocket &from_sock)
374{
376 ntree, from_node, from_sock, from_sock.typeinfo->idname, from_sock.name);
377}
378
390
391} // namespace node_interface
392
393} // namespace blender::bke
#define BLI_assert(a)
Definition BLI_assert.h:46
eNodeSocketDatatype
@ SOCK_INT
@ SOCK_TEXTURE
@ SOCK_VECTOR
@ SOCK_CLOSURE
@ SOCK_BOOLEAN
@ SOCK_MATERIAL
@ SOCK_SHADER
@ SOCK_MATRIX
@ SOCK_FLOAT
@ SOCK_IMAGE
@ SOCK_COLLECTION
@ SOCK_CUSTOM
@ SOCK_BUNDLE
@ SOCK_GEOMETRY
@ SOCK_ROTATION
@ SOCK_OBJECT
@ SOCK_STRING
@ SOCK_RGBA
@ SOCK_MENU
PropertySubType
Definition RNA_types.hh:220
@ PROP_TIME
Definition RNA_types.hh:241
@ PROP_DIRECTION
Definition RNA_types.hh:250
@ PROP_XYZ
Definition RNA_types.hh:257
@ PROP_DISTANCE
Definition RNA_types.hh:244
@ PROP_ACCELERATION
Definition RNA_types.hh:252
@ PROP_ANGLE
Definition RNA_types.hh:240
@ PROP_TIME_ABSOLUTE
Definition RNA_types.hh:242
@ PROP_EULER
Definition RNA_types.hh:254
@ PROP_COLOR_TEMPERATURE
Definition RNA_types.hh:278
@ PROP_NONE
Definition RNA_types.hh:221
@ PROP_PERCENTAGE
Definition RNA_types.hh:238
@ PROP_FREQUENCY
Definition RNA_types.hh:280
@ PROP_FACTOR
Definition RNA_types.hh:239
@ PROP_TRANSLATION
Definition RNA_types.hh:249
@ PROP_UNSIGNED
Definition RNA_types.hh:237
@ PROP_FILEPATH
Definition RNA_types.hh:224
@ PROP_VELOCITY
Definition RNA_types.hh:251
@ PROP_WAVELENGTH
Definition RNA_types.hh:275
#define T
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)
bNodeTreeInterfaceSocket * add_interface_socket_from_node(bNodeTree &ntree, const bNode &from_node, const bNodeSocket &from_sock, StringRef socket_type, StringRef name)
bool socket_data_is_type(const char *socket_type)
T & get_socket_data_as(bNodeTreeInterfaceSocket &item)
bNodeSocketTypeHandle * typeinfo