45 const std::string idname(socket_type);
47 if (typeinfo ==
nullptr) {
139 static float default_value[] = {0.0f, 0.0f, 0.0f};
147 static float default_value[] = {0.0f, 0.0f, 0.0f, 1.0f};
153 data.value[0] =
'\0';
157 data.value =
nullptr;
161 data.value =
nullptr;
165 data.value =
nullptr;
169 data.value =
nullptr;
173 data.value =
nullptr;
178 data.enum_items =
nullptr;
179 data.runtime_flag = 0;
184 void *socket_data =
nullptr;
186 using SocketDataType =
typename decltype(type_tag)::type;
187 SocketDataType *new_socket_data = MEM_cnew<SocketDataType>(__func__);
189 socket_data = new_socket_data;
205 dst.
enum_items->remove_user_and_delete_if_last();
212 using SocketDataType = typename decltype(type_tag)::type;
214 socket_data_id_user_decrement(get_socket_data_as<SocketDataType>(socket));
241 using SocketDataType = typename decltype(type_tag)::type;
242 dst.socket_data = MEM_dupallocN(src.socket_data);
243 socket_data_copy_impl(get_socket_data_as<SocketDataType>(dst),
244 get_socket_data_as<SocketDataType>(src));
245 if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
246 socket_data_id_user_increment(get_socket_data_as<SocketDataType>(dst));
253 const void *src_socket_data,
257 using SocketDataType = typename decltype(type_tag)::type;
259 if (dst.socket_data != nullptr) {
260 socket_data_free(dst, true);
261 MEM_SAFE_FREE(dst.socket_data);
266 *
static_cast<const SocketDataType *
>(src_socket_data));
337 using SocketDataType = typename decltype(type_tag)::type;
338 socket_data_write_impl(writer, get_socket_data_as<SocketDataType>(socket));
360 (*data)->enum_items =
nullptr;
361 (*data)->runtime_flag = 0;
366 bool data_read =
false;
368 using SocketDataType = typename decltype(type_tag)::type;
369 socket_data_read_data_impl(reader, reinterpret_cast<SocketDataType **>(&socket.socket_data));
415 using SocketDataType = typename decltype(type_tag)::type;
416 socket_data_foreach_id_impl(data, get_socket_data_as<SocketDataType>(socket));
525 panel.clear(do_id_user);
622 BKE_lib_query_idpropertiesForeachIDLink_callback(prop, data);
647 return panel.items();
677bool bNodeTreeInterfaceSocket::set_socket_type(
const char *new_socket_type)
680 if (idname ==
nullptr) {
696void bNodeTreeInterfaceSocket::init_from_socket_instance(
const bNodeSocket *socket)
732 return items().contains(&
item);
742 if (&titem == &
item) {
754 return items().first_index_try(&
item);
764 if (&titem == &
item) {
771 return found ?
index : -1;
792 std::queue<bNodeTreeInterfacePanel *>
queue;
794 if (this->contains(
item)) {
799 while (!
queue.empty()) {
809 if (tpanel->contains(
item)) {
819int bNodeTreeInterfacePanel::find_valid_insert_position_for_item(
822 const bool sockets_above_panels = !(this->
flag &
824 const blender::Span<const bNodeTreeInterfaceItem *> items = this->items();
831 if (sockets_above_panels) {
842 if (is_output_a != is_output_b) {
856 int test_pos =
clamp_i(initial_pos, 0, items.
size());
858 while (test_pos > 0 && item_compare(
item, *items[test_pos - 1])) {
863 while (test_pos < items.
size() && item_compare(*items[test_pos],
item)) {
882 position = find_valid_insert_position_for_item(
item, position);
885 blender::MutableSpan<bNodeTreeInterfaceItem *> old_items = this->items();
892 if (old_items.
data()) {
900 if (!this->items().index_range().contains(position)) {
904 blender::MutableSpan<bNodeTreeInterfaceItem *> old_items = this->items();
920void bNodeTreeInterfacePanel::clear(
bool do_id_user)
932 const int old_position = this->item_position(
item);
933 if (!this->items().index_range().contains(old_position)) {
936 if (old_position == new_position) {
941 new_position = find_valid_insert_position_for_item(
item, new_position);
942 new_position = std::min(std::max(new_position, 0),
items_num);
944 if (old_position < new_position) {
946 const blender::Span<bNodeTreeInterfaceItem *> moved_items = this->items().
slice(
947 old_position + 1, new_position - old_position - 1);
950 moved_items.
begin(), moved_items.
end(), this->items().drop_front(old_position).data());
951 this->items()[new_position - 1] = tmp;
954 const blender::Span<bNodeTreeInterfaceItem *> moved_items = this->items().
slice(
955 new_position, old_position - new_position);
958 moved_items.
begin(), moved_items.
end(), this->items().drop_front(old_position + 1).data());
959 this->items()[new_position] = tmp;
965void bNodeTreeInterfacePanel::foreach_item(
968 using ItemSpan = blender::Span<bNodeTreeInterfaceItem *>;
969 blender::Stack<ItemSpan> stack;
971 if (include_self && fn(this->
item) ==
false) {
974 stack.
push(this->items());
977 const ItemSpan current_items = stack.
pop();
979 for (
const int index : current_items.index_range()) {
981 if (fn(*
item) ==
false) {
988 if (index < current_items.size() - 1) {
989 const ItemSpan remaining_items = current_items.drop_front(index + 1);
990 stack.
push(remaining_items);
993 stack.
push(panel->items());
1000void bNodeTreeInterfacePanel::foreach_item(
1003 using ItemSpan = blender::Span<const bNodeTreeInterfaceItem *>;
1004 blender::Stack<ItemSpan> stack;
1006 if (include_self && fn(this->
item) ==
false) {
1009 stack.
push(this->items());
1012 const ItemSpan current_items = stack.
pop();
1014 for (
const int index : current_items.index_range()) {
1016 if (fn(*
item) ==
false) {
1024 if (index < current_items.size() - 1) {
1025 const ItemSpan remaining_items = current_items.drop_front(index + 1);
1026 stack.
push(remaining_items);
1029 stack.
push(panel->items());
1047 if (idname ==
nullptr) {
1070 const bNode &from_node,
1081 if (iosock ==
nullptr) {
1112void bNodeTreeInterface::init_data()
1114 this->
runtime = MEM_new<blender::bke::bNodeTreeInterfaceRuntime>(__func__);
1115 this->tag_missing_runtime_data();
1126 this->
runtime = MEM_new<blender::bke::bNodeTreeInterfaceRuntime>(__func__);
1127 this->tag_missing_runtime_data();
1130void bNodeTreeInterface::free_data()
1138void bNodeTreeInterface::write(
BlendWriter *writer)
1148 this->
runtime = MEM_new<blender::bke::bNodeTreeInterfaceRuntime>(__func__);
1149 this->tag_missing_runtime_data();
1187 if (&titem == item) {
1206 if (parent ==
nullptr) {
1214 parent->add_item(new_socket->
item);
1217 this->tag_items_changed();
1228 if (parent ==
nullptr) {
1236 parent->insert_item(new_socket->
item, position);
1239 this->tag_items_changed();
1248 if (parent ==
nullptr) {
1260 parent->add_item(new_panel->
item);
1263 this->tag_items_changed();
1273 if (parent ==
nullptr) {
1285 parent->insert_item(new_panel->
item, position);
1288 this->tag_items_changed();
1295 if (parent ==
nullptr) {
1310 parent->add_item(*citem);
1312 this->tag_items_changed();
1320 if (parent ==
nullptr) {
1335 parent->insert_item(*citem, position);
1337 this->tag_items_changed();
1344 if (parent ==
nullptr) {
1347 if (move_content_to_parent) {
1348 int position = parent->item_position(item);
1352 this->move_item_to_parent(*child, parent, position++);
1355 if (parent->remove_item(item,
true)) {
1356 this->tag_items_changed();
1363void bNodeTreeInterface::clear_items()
1366 this->tag_items_changed();
1372 if (parent ==
nullptr) {
1376 if (parent->move_item(item, new_position)) {
1377 this->tag_items_changed();
1387 if (new_parent ==
nullptr) {
1391 if (parent ==
nullptr) {
1400 if (parent == new_parent) {
1401 if (parent->move_item(item, new_position)) {
1402 this->tag_items_changed();
1409 if (parent->remove_item(item,
false)) {
1410 new_parent->insert_item(item, new_position);
1411 this->tag_items_changed();
1423bool bNodeTreeInterface::items_cache_is_available()
const
1425 return !this->
runtime->items_cache_mutex_.is_dirty();
1428void bNodeTreeInterface::ensure_items_cache()
const
1430 blender::bke::bNodeTreeInterfaceRuntime &
runtime = *this->
runtime;
1432 runtime.items_cache_mutex_.ensure([&]() {
1447 runtime.inputs_.append(socket);
1450 runtime.outputs_.append(socket);
1458void bNodeTreeInterface::tag_missing_runtime_data()
1461 this->
runtime->items_cache_mutex_.tag_dirty();
1464bool bNodeTreeInterface::is_changed()
const
1469void bNodeTreeInterface::tag_items_changed()
1472 this->
runtime->items_cache_mutex_.tag_dirty();
1475void bNodeTreeInterface::reset_changed_flags()
void IDP_foreach_property(IDProperty *id_property_root, int type_filter, blender::FunctionRef< void(IDProperty *id_property)> callback)
#define IDP_BlendDataRead(reader, prop)
void IDP_FreePropertyContent_ex(IDProperty *prop, bool do_id_user)
IDProperty * IDP_CopyProperty_ex(const IDProperty *prop, int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void IDP_BlendWrite(BlendWriter *writer, const IDProperty *prop)
@ LIB_ID_CREATE_NO_USER_REFCOUNT
#define BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data_, func_call_)
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(data_, id_super_, cb_flag_)
void BLI_kdtree_nd_ free(KDTree *tree)
MINLINE int clamp_i(int value, int min, int max)
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v3_v3(float r[3], const float a[3])
char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
char * BLI_strdupn(const char *str, size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
char * BLI_strdup_null(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_MALLOC
#define SET_FLAG_FROM_TEST(value, test, flag)
#define BLO_read_data_address(reader, ptr_p)
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_read_string(BlendDataReader *reader, char **ptr_p)
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
void BLO_read_pointer_array(BlendDataReader *reader, int array_size, void **ptr_p)
#define BLO_read_struct(reader, struct_name, ptr_p)
void BLO_write_pointer_array(BlendWriter *writer, uint num, const void *data_ptr)
Object groups, one object can be in many groups at once.
NodeTreeInterfacePanelFlag
@ NODE_INTERFACE_PANEL_ALLOW_CHILD_PANELS
@ NODE_INTERFACE_PANEL_ALLOW_SOCKETS_AFTER_PANELS
NodeTreeInterfaceSocketFlag
@ NODE_INTERFACE_SOCKET_OUTPUT
@ NODE_INTERFACE_SOCKET_INPUT
@ NODE_INTERFACE_SOCKET_HIDE_VALUE
struct bNodeTreeInterface bNodeTreeInterface
struct bNodeTreeInterfaceSocket bNodeTreeInterfaceSocket
struct bNodeTreeInterfacePanel bNodeTreeInterfacePanel
struct bNodeTreeInterfaceItem bNodeTreeInterfaceItem
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a color
constexpr T * data() const
constexpr MutableSpan drop_front(const int64_t n) const
constexpr MutableSpan take_front(const int64_t n) const
constexpr Span drop_front(int64_t n) const
constexpr Span slice(int64_t start, int64_t size) const
constexpr int64_t size() const
constexpr const T * end() const
constexpr IndexRange index_range() const
constexpr const T * begin() const
constexpr Span take_front(int64_t n) const
constexpr bool is_empty() const
void push(const T &value)
constexpr bool is_empty() const
constexpr int64_t size() const
constexpr const char * data() const
local_group_size(16, 16) .push_constant(Type b
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void MEM_freeN(void *vmemh)
void *(* MEM_dupallocN)(const void *vmemh)
void item_write_struct(BlendWriter *writer, bNodeTreeInterfaceItem &item)
static void item_copy(bNodeTreeInterfaceItem &dst, const bNodeTreeInterfaceItem &src, int flag, UidGeneratorFn generate_uid)
static void item_free(bNodeTreeInterfaceItem &item, const bool do_id_user)
blender::FunctionRef< int()> UidGeneratorFn
static void item_write_data(BlendWriter *writer, bNodeTreeInterfaceItem &item)
static Span< bNodeTreeInterfaceItem * > item_children(bNodeTreeInterfaceItem &item)
static void item_read_data(BlendDataReader *reader, bNodeTreeInterfaceItem &item)
static void item_foreach_id(LibraryForeachIDData *data, bNodeTreeInterfaceItem &item)
static void panel_init(bNodeTreeInterfacePanel &panel, const Span< const bNodeTreeInterfaceItem * > items_src, const int flag, UidGeneratorFn generate_uid)
static void socket_data_read_data(BlendDataReader *reader, bNodeTreeInterfaceSocket &socket)
void socket_data_foreach_id_impl(LibraryForeachIDData *, T &)
static void * make_socket_data(const StringRef socket_type)
void socket_data_id_user_decrement(T &)
void socket_data_copy_impl(T &, const T &)
static const char * try_get_supported_socket_type(const StringRef socket_type)
void socket_data_free_impl(T &, const bool)
static void socket_data_free(bNodeTreeInterfaceSocket &socket, const bool do_id_user)
void socket_data_to_static_type_tag(const StringRef socket_type, const Fn &fn)
static void socket_data_write(BlendWriter *writer, bNodeTreeInterfaceSocket &socket)
static void socket_data_foreach_id(LibraryForeachIDData *data, bNodeTreeInterfaceSocket &socket)
void socket_data_id_user_increment(T &)
void socket_data_init_impl(T &)
static void socket_data_copy(bNodeTreeInterfaceSocket &dst, const bNodeTreeInterfaceSocket &src, int flag)
static void socket_data_copy_ptr(bNodeTreeInterfaceSocket &dst, const void *src_socket_data, int flag)
void socket_data_write_impl(BlendWriter *writer, bNodeSocketValueFloat &data)
void socket_data_read_data_impl(BlendDataReader *reader, T **data)
T & get_item_as(bNodeTreeInterfaceItem &item)
static bNodeTreeInterfaceSocket * make_socket(const int uid, const StringRef name, const StringRef description, const StringRef socket_type, const NodeTreeInterfaceSocketFlag flag)
static bNodeTreeInterfacePanel * make_panel(const int uid, const blender::StringRef name, const blender::StringRef description, const NodeTreeInterfacePanelFlag flag)
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)
bool node_is_static_socket_type(const bNodeSocketType *stype)
bNodeSocketType * node_socket_type_find(const char *idname)
const char * node_static_socket_type(int type, int subtype)
ThreadQueue * queue
all scheduled work for the cpu
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
NodeTreeInterfaceChangedFlag
@ NODE_INTERFACE_CHANGED_ALL
@ NODE_INTERFACE_CHANGED_ITEMS
@ NODE_INTERFACE_CHANGED_NOTHING
static bool is_child(const Object *ob, const Object *parent)
bNodeTreeInterfaceItem ** items_array
bNodeTreeInterfaceItem item
bNodeTreeInterfaceItem item
char * default_attribute_name
bNodeTreeInterfacePanel root_panel
bNodeTreeInterfaceRuntimeHandle * runtime
bNodeTreeInterface tree_interface
void(* draw_color_simple)(const bNodeSocketType *socket_type, float *r_color)
void(* interface_from_socket)(ID *id, bNodeTreeInterfaceSocket *interface_socket, const bNode *node, const bNodeSocket *socket)