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));
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;
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) {
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]);
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]);
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;
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()) {
831 const int domain_size = attributes.
domain_size(domain);
835 const CPPType &type = output_info.field.cpp_type();
848 attributes_to_store.
append(store);
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);
888 attribute.varray.set_all(store.data.data());
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) {
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();
966 btree.ensure_interface_cache();
969 for (
const int i : btree.interface_inputs().index_range()) {
975 param_inputs[function.
inputs.
main[0]] = &input_geometry;
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()) {
996 for (
const int i : attributes_to_propagate.
index_range()) {
1001 for (
const int i :
IndexRange(num_outputs)) {
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_OBJECT_INFO
#define GEO_NODE_SELF_OBJECT
#define GEO_NODE_DEFORM_CURVES_ON_SURFACE
#define GEO_NODE_INPUT_ACTIVE_CAMERA
#define GEO_NODE_COLLECTION_INFO
#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
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
MutableSpan< T > as_mutable_span()
IndexRange index_range() const
int64_t alignment() const
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)
AttributeValidator lookup_validator(const StringRef attribute_id) const
std::optional< AttributeMetaData > lookup_meta_data(const StringRef attribute_id) const
bool domain_supported(const AttrDomain domain) const
int domain_size(const AttrDomain domain) const
virtual std::optional< AttributeAccessor > attributes() const
virtual std::optional< MutableAttributeAccessor > attributes_for_write()
GAttributeWriter lookup_or_add_for_write(StringRef attribute_id, AttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
bool remove(const StringRef attribute_id)
bool add(const StringRef attribute_id, const AttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer)
int add_with_destination(GField field, GVMutableArray dst)
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
input_tx image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "preview_img") .compute_source("compositor_compute_preview.glsl") .do_static_compilation(true)
local_group_size(16, 16) .push_constant(Type texture
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
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
VecBase< float, 3 > float3
VecBase< double, 4 > double4
bool is_layer_selection_field(const bNodeTreeInterfaceSocket &socket)
IDPropertyUIDataEnumItem * enum_items
IDPropertyUIData * ui_data
struct Collection * value
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
Vector< int > geometry_outputs
struct blender::nodes::GeometryNodesGroupFunction::@000115334025155014211241101024303251321212251042::@165376366322230201261276177143336154337260306235 attributes_to_propagate
struct blender::nodes::GeometryNodesGroupFunction::@000115334025155014211241101024303251321212251042 inputs
const LazyFunction * function
struct blender::nodes::GeometryNodesGroupFunction::@375130375132166273253121104163076122003103003070 outputs
GeometryNodesGroupFunction function
bke::GeometryComponent::Type component_type