42 switch (socket->type) {
45 ids.
add(
reinterpret_cast<ID *
>(
object));
52 ids.
add(
reinterpret_cast<ID *
>(collection));
58 ids.
add(
reinterpret_cast<ID *
>(material));
64 ids.
add(
reinterpret_cast<ID *
>(texture));
70 ids.
add(
reinterpret_cast<ID *
>(image));
86 if (node.type == GEO_NODE_COLLECTION_INFO) {
92 if (node.type == GEO_NODE_OBJECT_INFO) {
97 if (node.type == GEO_NODE_SELF_OBJECT) {
100 if (node.type == GEO_NODE_DEFORM_CURVES_ON_SURFACE) {
109 bool &r_needs_own_transform_relation,
110 bool &r_needs_scene_camera_relation,
113 if (!checked_groups.
add(&
tree)) {
117 tree.ensure_topology_cache();
118 for (
const bNode *node :
tree.all_nodes()) {
125 for (
const bNode *node :
tree.group_nodes()) {
129 r_needs_own_transform_relation,
130 r_needs_scene_camera_relation,
138 bool &r_needs_own_transform_relation,
139 bool &r_needs_scene_camera_relation)
143 tree, r_ids, r_needs_own_transform_relation, r_needs_scene_camera_relation, checked_groups);
148 return "_use_attribute";
153 return "_attribute_name";
165 node_tree.interface_inputs()[socket_index]->socket_typeinfo();
172 *
node_tree.runtime->field_inferencing_interface;
179 int idprop_items_num = 0;
182 if (value->enum_items && !value->enum_items->items.is_empty()) {
184 idprop_items_num = items.
size();
185 idprop_items = MEM_cnew_array<IDPropertyUIDataEnumItem>(items.
size(), __func__);
196 idprop_item.
icon = ICON_NONE;
202 if (idprop_items_num == 0) {
203 idprop_items_num = 1;
204 idprop_items = MEM_cnew_array<IDPropertyUIDataEnumItem>(1, __func__);
205 idprop_items->
value = 0;
209 idprop_items->
icon = ICON_NONE;
221 const std::optional<ID_Type> id_type,
222 const bool use_name_for_ids)
224 if (use_name_for_ids) {
268 identifier,
Span<float>{value->value[0], value->value[1], value->value[2]});
271 ui_data->soft_min =
double(value->min);
272 ui_data->soft_max =
double(value->max);
273 ui_data->default_array = (
double *)
MEM_mallocN(
sizeof(
double[3]),
"mod_prop_default");
274 ui_data->default_array_len = 3;
276 ui_data->default_array[i] =
double(value->value[i]);
285 Span<float>{value->value[0], value->value[1], value->value[2], value->value[3]});
288 ui_data->default_array = (
double *)
MEM_mallocN(
sizeof(
double[4]), __func__);
289 ui_data->default_array_len = 4;
292 ui_data->soft_min = 0.0;
293 ui_data->soft_max = 1.0;
295 ui_data->default_array[i] =
double(value->value[i]);
316 Span<float>{value->value_euler[0], value->value_euler[1], value->value_euler[2]});
343 ID *
id =
reinterpret_cast<ID *
>(value->value);
350 ID *
id =
reinterpret_cast<ID *
>(value->value);
356 ID *
id =
reinterpret_cast<ID *
>(value->value);
362 ID *
id =
reinterpret_cast<ID *
>(value->value);
368 ID *
id =
reinterpret_cast<ID *
>(value->value);
404 new_property->
len ==
len);
406 switch (old_property.
subtype) {
408 double *
const old_value =
static_cast<double *const
>(
IDP_Array(&old_property));
409 float *new_value =
static_cast<float *
>(new_property->
data.
pointer);
410 for (
int i = 0; i <
len; i++) {
411 new_value[i] =
float(old_value[i]);
416 int *
const old_value =
static_cast<int *const
>(
IDP_Array(&old_property));
417 float *new_value =
static_cast<float *
>(new_property->
data.
pointer);
418 for (
int i = 0; i <
len; i++) {
419 new_value[i] =
float(old_value[i]);
424 float *
const old_value =
static_cast<float *const
>(
IDP_Array(&old_property));
425 memcpy(new_property->
data.
pointer, old_value,
sizeof(
float) *
size_t(
len));
458 const bool use_name_for_ids)
469 switch (old_property.
type) {
487 old_property, new_property, 3);
490 old_property, new_property, 4);
503 switch (old_property.
type) {
522 if (use_name_for_ids) {
548 const bool use_name_for_ids)
551 socket, property,
nullptr, use_name_for_ids);
558 switch (socket_value_type) {
571 int value =
IDP_Int(&property);
576 const void *property_array =
IDP_Array(&property);
579 value =
float3(
static_cast<const float *
>(property_array));
582 value =
float3(
int3(
static_cast<const int *
>(property_array)));
586 value =
float3(
double3(
static_cast<const double *
>(property_array)));
592 const void *property_array =
IDP_Array(&property);
595 vec =
float4(
static_cast<const float *
>(property_array));
598 vec =
float4(
int4(
static_cast<const int *
>(property_array)));
602 vec =
float4(
double4(
static_cast<const double *
>(property_array)));
609 const bool value =
IDP_Bool(&property);
614 const void *property_array =
IDP_Array(&property);
617 vec =
float3(
static_cast<const float *
>(property_array));
620 vec =
float3(
int3(
static_cast<const int *
>(property_array)));
624 vec =
float3(
double3(
static_cast<const double *
>(property_array)));
636 int value =
IDP_Int(&property);
643 *(
Object **)r_value =
object;
654 Tex *texture = (
id &&
GS(id->name) ==
ID_TE) ? (
Tex *)id :
nullptr;
655 *(
Tex **)r_value = texture;
661 *(
Image **)r_value = image;
682 if (!use_attribute) {
686 if (
IDP_Int(use_attribute) == 0) {
704 const int input_index,
711 if (properties ==
nullptr) {
716 if (property ==
nullptr) {
741 std::make_shared<bke::NamedLayerSelectionFieldInput>(layer_name), 0);
768 const bNode &output_node = *
tree.group_output_node();
770 for (
const bNodeSocket *socket : output_node.input_sockets().drop_front(1).drop_back(1)) {
777 if (prop ==
nullptr) {
788 const int index = socket->index();
795 output_info.
field = std::move(field);
796 output_info.
name = attribute_name;
797 outputs_by_domain.
add(domain, std::move(output_info));
799 return outputs_by_domain;
809 const bool do_instances)
817 if (!geometry.has(component_type)) {
825 for (
const auto item : outputs_by_domain.
items()) {
828 if (!attributes.domain_supported(domain)) {
831 const int domain_size = attributes.domain_size(domain);
835 const CPPType &type = output_info.field.cpp_type();
847 field_evaluator.add_with_destination(std::move(field), store.data);
848 attributes_to_store.
append(store);
850 field_evaluator.evaluate();
853 return attributes_to_store;
864 const std::optional<bke::AttributeMetaData> meta_data = attributes.lookup_meta_data(
869 if (meta_data.has_value() &&
870 (meta_data->domain != store.domain || meta_data->data_type != data_type))
872 attributes.remove(store.name);
877 if (attributes.add(store.name,
886 store.name, store.domain, data_type);
893 store.data.type().destruct_n(store.data.data(), store.data.size());
907 if (outputs_by_domain.
size() == 0) {
910 const bool only_instance_attributes = outputs_by_domain.
size() == 1 &&
911 *outputs_by_domain.
keys().begin() ==
913 if (only_instance_attributes) {
918 geometry, outputs_by_domain,
true);
925 const bool do_instances = &geometry == &instance_geometry;
927 instance_geometry, outputs_by_domain, do_instances);
942 const int num_inputs = lazy_function.
inputs().size();
943 const int num_outputs = lazy_function.
outputs().size();
952 param_output_usages.
as_mutable_span().slice(function.outputs.main).fill(lf::ValueUsage::Used);
954 .slice(function.outputs.input_usages)
955 .fill(lf::ValueUsage::Unused);
966 btree.ensure_interface_cache();
969 for (
const int i : btree.interface_inputs().index_range()) {
975 param_inputs[function.inputs.main[0]] = &input_geometry;
981 void *value = allocator.
allocate(type->size(), type->alignment());
983 param_inputs[function.inputs.main[i]] = {type, value};
984 inputs_to_destruct.
append({type, value});
988 Array<bool> output_used_inputs(btree.interface_outputs().size(),
true);
989 for (
const int i : btree.interface_outputs().index_range()) {
990 param_inputs[function.inputs.output_usages[i]] = &output_used_inputs[i];
995 function.inputs.attributes_to_propagate.geometry_outputs.size());
996 for (
const int i : attributes_to_propagate.
index_range()) {
997 param_inputs[function.inputs.attributes_to_propagate.range[i]] = &attributes_to_propagate[i];
1001 for (
const int i :
IndexRange(num_outputs)) {
1004 void *buffer = allocator.
allocate(type.size(), type.alignment());
1005 param_outputs[i] = {type, buffer};
1015 param_output_usages,
1019 lazy_function.
execute(lf_params, lf_context);
1027 bke::GeometrySet output_geometry = std::move(*param_outputs[0].get<bke::GeometrySet>());
1030 for (
const int i :
IndexRange(num_outputs)) {
1031 if (param_set_outputs[i]) {
1037 return output_geometry;
1043 const bool use_name_for_ids)
1045 tree.ensure_interface_cache();
1055 if (new_prop ==
nullptr) {
1069 if (old_properties !=
nullptr) {
1071 socket_identifier.
c_str());
1072 if (old_prop !=
nullptr) {
1076 socket, *old_prop, new_prop, use_name_for_ids);
1090 if (old_properties ==
nullptr) {
1093 IDP_Int(use_attribute_prop) = 1;
1098 use_attribute_id.c_str());
1099 if (old_prop_use_attribute !=
nullptr) {
1104 attribute_name_id.c_str());
1105 if (old_attribute_name_prop !=
nullptr) {
1117 tree.ensure_topology_cache();
1137 if (old_properties ==
nullptr) {
1144 if (old_prop !=
nullptr) {
1150 if (new_prop->
ui_data !=
nullptr) {
void IDP_ui_data_free(IDProperty *prop)
bool IDP_EnumItemsValidate(const IDPropertyUIDataEnumItem *items, int items_num, void(*error_fn)(const char *))
void IDP_CopyPropertyContent(IDProperty *dst, const IDProperty *src) ATTR_NONNULL()
void IDP_AssignString(IDProperty *prop, const char *st) ATTR_NONNULL()
IDProperty * IDP_GetPropertyFromGroup(const IDProperty *prop, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void IDP_AssignStringMaxSize(IDProperty *prop, const char *st, size_t st_maxncpy) ATTR_NONNULL()
bool IDP_AddToGroup(IDProperty *group, IDProperty *prop) ATTR_NONNULL()
IDProperty * IDP_NewStringMaxSize(const char *st, size_t st_maxncpy, const char *name, eIDPropertyFlag flags={}) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(3)
IDPropertyUIData * IDP_ui_data_ensure(IDProperty *prop)
#define GEO_NODE_INPUT_ACTIVE_CAMERA
#define BLI_assert_unreachable()
#define LISTBASE_FOREACH(type, var, list)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
char * BLI_strdup_null(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_MALLOC
typedef double(DMatrix)[4][4]
@ IDP_FLAG_OVERRIDABLE_LIBRARY
@ GEO_NODE_TRANSFORM_SPACE_RELATIVE
MutableSpan< T > as_mutable_span()
IndexRange index_range() const
void set_all(const void *src)
void * allocate(const int64_t size, const int64_t alignment)
MapType::KeyIterator keys() const
MapType::ItemIterator items() const
void add(const Key &key, const Value &value)
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
constexpr const char * c_str() const
void append(const T &value)
virtual std::optional< AttributeAccessor > attributes() const
virtual std::optional< MutableAttributeAccessor > attributes_for_write()
virtual void * init_storage(LinearAllocator<> &allocator) const
Span< Input > inputs() const
Span< Output > outputs() const
virtual void destruct_storage(void *storage) const
void execute(Params ¶ms, const Context &context) const
draw_view in_light_buf[] float
void * MEM_mallocN_aligned(size_t len, size_t alignment, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
std::unique_ptr< IDProperty, IDPropertyDeleter > create_bool(StringRefNull prop_name, bool value, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_BOOLEAN, set its name and value.
std::unique_ptr< IDProperty, IDPropertyDeleter > create(StringRefNull prop_name, int32_t value, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_INT, set its name and value.
bool allow_procedural_attribute_access(StringRef attribute_name)
eCustomDataType cpp_type_to_custom_data_type(const CPPType &type)
QuaternionBase< T > to_quaternion(const AxisAngleBase< T, AngleT > &axis_angle)
EulerXYZBase< float > EulerXYZ
StringRef input_attribute_name_suffix()
static void store_computed_output_attributes(bke::GeometrySet &geometry, const Span< OutputAttributeToStore > attributes_to_store)
StringRef input_use_attribute_suffix()
static void process_nodes_for_depsgraph(const bNodeTree &tree, Set< ID * > &ids, bool &r_needs_own_transform_relation, bool &r_needs_scene_camera_relation, Set< const bNodeTree * > &checked_groups)
static bool old_id_property_type_matches_socket_convert_to_new_string(const IDProperty &old_property, IDProperty *new_property)
static void store_output_attributes(bke::GeometrySet &geometry, const bNodeTree &tree, const IDProperty *properties, Span< GMutablePointer > output_values)
void update_input_properties_from_node_tree(const bNodeTree &tree, const IDProperty *old_properties, IDProperty &properties, const bool use_name_for_ids)
bool input_has_attribute_toggle(const bNodeTree &node_tree, const int socket_index)
static bool node_needs_own_transform_relation(const bNode &node)
static void id_property_int_update_enum_items(const bNodeSocketValueMenu *value, IDPropertyUIDataInt *ui_data)
void find_node_tree_dependencies(const bNodeTree &tree, Set< ID * > &r_ids, bool &r_needs_own_transform_relation, bool &r_needs_scene_camera_relation)
bool id_property_type_matches_socket(const bNodeTreeInterfaceSocket &socket, const IDProperty &property, const bool use_name_for_ids)
bke::GeometrySet execute_geometry_nodes_on_geometry(const bNodeTree &btree, const IDProperty *properties, const ComputeContext &base_compute_context, GeoNodesCallData &call_data, bke::GeometrySet input_geometry)
std::unique_ptr< IDProperty, bke::idprop::IDPropertyDeleter > id_property_create_from_socket(const bNodeTreeInterfaceSocket &socket, const bool use_name_for_ids)
const GeometryNodesLazyFunctionGraphInfo * ensure_geometry_nodes_lazy_function_graph(const bNodeTree &btree)
bool socket_type_supports_fields(const eNodeSocketDatatype socket_type)
static Vector< OutputAttributeToStore > compute_attributes_to_store(const bke::GeometrySet &geometry, const MultiValueMap< bke::AttrDomain, OutputAttributeInfo > &outputs_by_domain, const bool do_instances)
void update_output_properties_from_node_tree(const bNodeTree &tree, const IDProperty *old_properties, IDProperty &properties)
static void add_used_ids_from_sockets(const ListBase &sockets, Set< ID * > &ids)
static bool old_id_property_type_matches_socket_convert_to_new_float_vec(const IDProperty &old_property, IDProperty *new_property, const int len)
static void init_socket_cpp_value_from_property(const IDProperty &property, const eNodeSocketDatatype socket_value_type, void *r_value)
static MultiValueMap< bke::AttrDomain, OutputAttributeInfo > find_output_attributes_to_store(const bNodeTree &tree, const IDProperty *properties, Span< GMutablePointer > output_values)
bool socket_type_has_attribute_toggle(const eNodeSocketDatatype type)
static void initialize_group_input(const bNodeTree &tree, const IDProperty *properties, const int input_index, void *r_value)
static std::unique_ptr< IDProperty, bke::idprop::IDPropertyDeleter > id_name_or_value_prop(const StringRefNull identifier, ID *id, const std::optional< ID_Type > id_type, const bool use_name_for_ids)
std::optional< StringRef > input_attribute_name_get(const IDProperty &props, const bNodeTreeInterfaceSocket &io_input)
static bool old_id_property_type_matches_socket_convert_to_new(const bNodeTreeInterfaceSocket &socket, const IDProperty &old_property, IDProperty *new_property, const bool use_name_for_ids)
static bool old_id_property_type_matches_socket_convert_to_new_int(const IDProperty &old_property, IDProperty *new_property)
VecBase< int32_t, 4 > int4
VecBase< float, 4 > float4
VecBase< int32_t, 3 > int3
VecBase< double, 3 > double3
VecBase< float, 3 > float3
VecBase< double, 4 > double4
bool is_layer_selection_field(const bNodeTreeInterfaceSocket &socket)
IDPropertyUIDataEnumItem * enum_items
IDPropertyUIData * ui_data
char * default_attribute_name
fn::GField validate_field_if_necessary(const fn::GField &field) const
const blender::CPPType * geometry_nodes_cpp_type
SocketGetGeometryNodesCPPValueFunction get_geometry_nodes_cpp_value
const blender::CPPType * base_cpp_type
Vector< InputSocketFieldType > inputs
const bNodeTree * root_ntree
const ComputeContext * compute_context
const GeoNodesCallData * call_data
GeometryNodesGroupFunction function
bke::GeometryComponent::Type component_type