Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc
| Show All 10 Lines | |||||
| namespace blender::nodes::node_geo_attribute_capture_cc { | namespace blender::nodes::node_geo_attribute_capture_cc { | ||||
| NODE_STORAGE_FUNCS(NodeGeometryAttributeCapture) | NODE_STORAGE_FUNCS(NodeGeometryAttributeCapture) | ||||
| static void node_declare(NodeDeclarationBuilder &b) | static void node_declare(NodeDeclarationBuilder &b) | ||||
| { | { | ||||
| b.add_input<decl::Geometry>(N_("Geometry")); | b.add_input<decl::Geometry>(N_("Geometry")); | ||||
| b.add_input<decl::Vector>(N_("Value")).supports_field(); | b.add_input<decl::Vector>(N_("Value"), "Value_Vector").supports_field(); | ||||
| b.add_input<decl::Float>(N_("Value"), "Value_001").supports_field(); | b.add_input<decl::Float>(N_("Value"), "Value_Float").supports_field(); | ||||
| b.add_input<decl::Color>(N_("Value"), "Value_002").supports_field(); | b.add_input<decl::Color>(N_("Value"), "Value_Color").supports_field(); | ||||
| b.add_input<decl::Bool>(N_("Value"), "Value_003").supports_field(); | b.add_input<decl::Bool>(N_("Value"), "Value_Bool").supports_field(); | ||||
| b.add_input<decl::Int>(N_("Value"), "Value_004").supports_field(); | b.add_input<decl::Int>(N_("Value"), "Value_Int").supports_field(); | ||||
| b.add_output<decl::Geometry>(N_("Geometry")); | b.add_output<decl::Geometry>(N_("Geometry")); | ||||
| b.add_output<decl::Vector>(N_("Attribute")).field_source(); | b.add_output<decl::Vector>(N_("Attribute"), "Attribute_Vector").field_source(); | ||||
| b.add_output<decl::Float>(N_("Attribute"), "Attribute_001").field_source(); | b.add_output<decl::Float>(N_("Attribute"), "Attribute_Float").field_source(); | ||||
| b.add_output<decl::Color>(N_("Attribute"), "Attribute_002").field_source(); | b.add_output<decl::Color>(N_("Attribute"), "Attribute_Color").field_source(); | ||||
| b.add_output<decl::Bool>(N_("Attribute"), "Attribute_003").field_source(); | b.add_output<decl::Bool>(N_("Attribute"), "Attribute_Bool").field_source(); | ||||
| b.add_output<decl::Int>(N_("Attribute"), "Attribute_004").field_source(); | b.add_output<decl::Int>(N_("Attribute"), "Attribute_Int").field_source(); | ||||
| } | } | ||||
| static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) | static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) | ||||
| { | { | ||||
| uiLayoutSetPropSep(layout, true); | uiLayoutSetPropSep(layout, true); | ||||
| uiLayoutSetPropDecorate(layout, false); | uiLayoutSetPropDecorate(layout, false); | ||||
| uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE); | uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE); | ||||
| uiItemR(layout, ptr, "domain", 0, "", ICON_NONE); | uiItemR(layout, ptr, "domain", 0, "", ICON_NONE); | ||||
| ▲ Show 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | static void try_capture_field_on_geometry(GeometryComponent &component, | ||||
| fn::FieldEvaluator evaluator{field_context, &mask}; | fn::FieldEvaluator evaluator{field_context, &mask}; | ||||
| evaluator.add_with_destination(field, output_attribute.varray); | evaluator.add_with_destination(field, output_attribute.varray); | ||||
| evaluator.evaluate(); | evaluator.evaluate(); | ||||
| output_attribute.finish(); | output_attribute.finish(); | ||||
| } | } | ||||
| static StringRefNull identifier_suffix(eCustomDataType data_type) | |||||
| { | |||||
| switch (data_type) { | |||||
| case CD_PROP_FLOAT: | |||||
| return "_001"; | |||||
| case CD_PROP_INT32: | |||||
| return "_004"; | |||||
| case CD_PROP_COLOR: | |||||
| return "_002"; | |||||
| case CD_PROP_BOOL: | |||||
| return "_003"; | |||||
| case CD_PROP_FLOAT3: | |||||
| return ""; | |||||
| default: | |||||
| BLI_assert_unreachable(); | |||||
| return ""; | |||||
| } | |||||
| } | |||||
| static void node_geo_exec(GeoNodeExecParams params) | static void node_geo_exec(GeoNodeExecParams params) | ||||
| { | { | ||||
| GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry"); | GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry"); | ||||
| if (!params.output_is_required("Geometry")) { | if (!params.output_is_required("Geometry")) { | ||||
| params.error_message_add( | params.error_message_add( | ||||
| NodeWarningType::Info, | NodeWarningType::Info, | ||||
| TIP_("The attribute output can not be used without the geometry output")); | TIP_("The attribute output can not be used without the geometry output")); | ||||
| params.set_default_remaining_outputs(); | params.set_default_remaining_outputs(); | ||||
| return; | return; | ||||
| } | } | ||||
| const NodeGeometryAttributeCapture &storage = node_storage(params.node()); | const NodeGeometryAttributeCapture &storage = node_storage(params.node()); | ||||
| const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); | const eCustomDataType data_type = static_cast<eCustomDataType>(storage.data_type); | ||||
| const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain); | const eAttrDomain domain = static_cast<eAttrDomain>(storage.domain); | ||||
| const std::string output_identifier = "Attribute" + identifier_suffix(data_type); | std::string postfix = "_" + attribute_math::default_name(data_type); | ||||
HooglyBoogly: `postfix` -> `suffix` | |||||
| if (!params.output_is_required(output_identifier)) { | if (!params.output_is_required("Attribute" + postfix)) { | ||||
| params.set_output("Geometry", geometry_set); | params.set_output("Geometry", geometry_set); | ||||
| return; | return; | ||||
| } | } | ||||
| const std::string input_identifier = "Value" + identifier_suffix(data_type); | |||||
| GField field; | GField field; | ||||
| attribute_math::convert_to_static_type(data_type, [&](auto dummy) { | |||||
| switch (data_type) { | using T = decltype(dummy); | ||||
| case CD_PROP_FLOAT: | field = params.get_input<Field<T>>("Value" + postfix); | ||||
| field = params.get_input<Field<float>>(input_identifier); | }); | ||||
| break; | |||||
| case CD_PROP_FLOAT3: | |||||
| field = params.get_input<Field<float3>>(input_identifier); | |||||
| break; | |||||
| case CD_PROP_COLOR: | |||||
| field = params.get_input<Field<ColorGeometry4f>>(input_identifier); | |||||
| break; | |||||
| case CD_PROP_BOOL: | |||||
| field = params.get_input<Field<bool>>(input_identifier); | |||||
| break; | |||||
| case CD_PROP_INT32: | |||||
| field = params.get_input<Field<int>>(input_identifier); | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| WeakAnonymousAttributeID anonymous_id{"Attribute"}; | WeakAnonymousAttributeID anonymous_id{"Attribute"}; | ||||
| const CPPType &type = field.cpp_type(); | |||||
| /* Run on the instances component separately to only affect the top level of instances. */ | /* Run on the instances component separately to only affect the top level of instances. */ | ||||
| if (domain == ATTR_DOMAIN_INSTANCE) { | if (domain == ATTR_DOMAIN_INSTANCE) { | ||||
| if (geometry_set.has_instances()) { | if (geometry_set.has_instances()) { | ||||
| GeometryComponent &component = geometry_set.get_component_for_write( | GeometryComponent &component = geometry_set.get_component_for_write( | ||||
| GEO_COMPONENT_TYPE_INSTANCES); | GEO_COMPONENT_TYPE_INSTANCES); | ||||
| try_capture_field_on_geometry(component, anonymous_id.get(), domain, field); | try_capture_field_on_geometry(component, anonymous_id.get(), domain, field); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| static const Array<GeometryComponentType> types = { | static const Array<GeometryComponentType> types = { | ||||
| GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE}; | GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE}; | ||||
| geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { | geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { | ||||
| for (const GeometryComponentType type : types) { | for (const GeometryComponentType type : types) { | ||||
| if (geometry_set.has(type)) { | if (geometry_set.has(type)) { | ||||
| GeometryComponent &component = geometry_set.get_component_for_write(type); | GeometryComponent &component = geometry_set.get_component_for_write(type); | ||||
| try_capture_field_on_geometry(component, anonymous_id.get(), domain, field); | try_capture_field_on_geometry(component, anonymous_id.get(), domain, field); | ||||
| } | } | ||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| const CPPType &cpp_attribute_type = *bke::custom_data_type_to_cpp_type(data_type); | |||||
| GField output_field{std::make_shared<bke::AnonymousAttributeFieldInput>( | GField output_field{std::make_shared<bke::AnonymousAttributeFieldInput>( | ||||
| std::move(anonymous_id), type, params.attribute_producer_name())}; | std::move(anonymous_id), cpp_attribute_type, params.attribute_producer_name())}; | ||||
| switch (data_type) { | attribute_math::convert_to_static_type(data_type, [&](auto dummy) { | ||||
| case CD_PROP_FLOAT: { | using T = decltype(dummy); | ||||
| params.set_output(output_identifier, Field<float>(output_field)); | params.set_output<Field<T>>("Attribute" + postfix, output_field); | ||||
| break; | }); | ||||
| } | |||||
| case CD_PROP_FLOAT3: { | |||||
| params.set_output(output_identifier, Field<float3>(output_field)); | |||||
| break; | |||||
| } | |||||
| case CD_PROP_COLOR: { | |||||
| params.set_output(output_identifier, Field<ColorGeometry4f>(output_field)); | |||||
| break; | |||||
| } | |||||
| case CD_PROP_BOOL: { | |||||
| params.set_output(output_identifier, Field<bool>(output_field)); | |||||
| break; | |||||
| } | |||||
| case CD_PROP_INT32: { | |||||
| params.set_output(output_identifier, Field<int>(output_field)); | |||||
| break; | |||||
| } | |||||
| default: | |||||
| break; | |||||
| } | |||||
| params.set_output("Geometry", geometry_set); | params.set_output("Geometry", geometry_set); | ||||
| } | } | ||||
| } // namespace blender::nodes::node_geo_attribute_capture_cc | } // namespace blender::nodes::node_geo_attribute_capture_cc | ||||
| void register_node_type_geo_attribute_capture() | void register_node_type_geo_attribute_capture() | ||||
| { | { | ||||
| Show All 18 Lines | |||||
postfix -> suffix