35namespace socket_types {
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));
424namespace item_types {
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 &
829 if (a.item_type !=
b.item_type) {
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);
883 position = std::min(std::max(position, 0),
items_num);
890 this->items()[position] = &
item;
892 if (old_items.
data()) {
899 const int position = this->item_position(
item);
900 if (!this->items().index_range().contains(position)) {
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) {
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;
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(
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(
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
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
void ensure(FunctionRef< void()> compute_cache)
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)
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)
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)