Commit: 47fa00ffef28e2fc2c065d709987b80eb1f5c043 Author: Hans Goudey Date: Fri Sep 3 13:12:50 2021 -0500 Branches: temp-geometry-nodes-fields https://developer.blender.org/rB47fa00ffef28e2fc2c065d709987b80eb1f5c043
Support fields in the point translate node, add selection input Because we don't have a "Extract Named Attribute" node currently, I had to keep the old string input. Otherwise we wouldn't be able to add versioning. =================================================================== M source/blender/nodes/geometry/nodes/node_geo_point_translate.cc =================================================================== diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_translate.cc b/source/blender/nodes/geometry/nodes/node_geo_point_translate.cc index d187bf0fa71..6adebfa0d5e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_point_translate.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_point_translate.cc @@ -17,6 +17,8 @@ #include "UI_interface.h" #include "UI_resources.h" +#include "FN_multi_function_builder.hh" + #include "node_geometry_util.hh" namespace blender::nodes { @@ -26,6 +28,7 @@ static void geo_node_point_translate_declare(NodeDeclarationBuilder &b) b.add_input<decl::Geometry>("Geometry"); b.add_input<decl::String>("Translation"); b.add_input<decl::Vector>("Translation", "Translation_001").subtype(PROP_TRANSLATION); + b.add_input<decl::Bool>("Selection").default_value(true); b.add_output<decl::Geometry>("Geometry"); } @@ -36,7 +39,7 @@ static void geo_node_point_translate_layout(uiLayout *layout, bContext *UNUSED(C uiItemR(layout, ptr, "input_type", 0, IFACE_("Type"), ICON_NONE); } -static void execute_on_component(GeoNodeExecParams params, GeometryComponent &component) +static void execute_on_component_legacy(GeoNodeExecParams params, GeometryComponent &component) { OutputAttribute_Typed<float3> position_attribute = component.attribute_try_get_for_output<float3>("position", ATTR_DOMAIN_POINT, {0, 0, 0}); @@ -53,20 +56,85 @@ static void execute_on_component(GeoNodeExecParams params, GeometryComponent &co position_attribute.save(); } +class SpanFieldInput final : public fn::FieldInput { + GSpan span_; + + public: + SpanFieldInput(GSpan span) : FieldInput(CPPType::get<float3>(), "Span"), span_(span) + { + } + const GVArray *try_get_varray_for_context(const fn::FieldContext &UNUSED(context), + IndexMask UNUSED(mask), + ResourceScope &scope) const final + { + return &scope.construct<fn::GVArray_For_GSpan>(__func__, span_); + } +}; + +static void execute_on_component(GeometryComponent &component, + const Field<bool> &selection_field, + const Field<float3> &translation_field) +{ + GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT}; + const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT); + + fn::FieldEvaluator selection_evaluator{field_context, domain_size}; + selection_evaluator.add(selection_field); + selection_evaluator.evaluate(); + const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0); + + OutputAttribute_Typed<float3> positions = component.attribute_try_get_for_output<float3>( + "position", ATTR_DOMAIN_POINT, {0, 0, 0}); + MutableSpan<float3> position_span = positions.as_span(); + fn::Field<float3> position_field{std::make_shared<SpanFieldInput>(position_span.as_span())}; + + /* Retrieve the translation field and add an add operation field on top of that, which can be + * evaluated directly into the position virtual array so that any optimizations can be done more + * generally for the whole evaluation system. */ + static const fn::CustomMF_SI_SI_SO<float3, float3, float3> add_fn = { + "Add", [](float3 a, float3 b) { return a + b; }}; + std::shared_ptr<fn::FieldOperation> add_operation = std::make_shared<fn::FieldOperation>( + fn::FieldOperation(add_fn, {position_field, translation_field})); + + fn::FieldEvaluator position_evaluator{field_context, &selection}; + position_evaluator.add_with_destination({add_operation}, position_span); + position_evaluator.evaluate(); + + positions.save(); +} + static void geo_node_point_translate_exec(GeoNodeExecParams params) { GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry"); geometry_set = geometry_set_realize_instances(geometry_set); - if (geometry_set.has<MeshComponent>()) { - execute_on_component(params, geometry_set.get_component_for_write<MeshComponent>()); - } - if (geometry_set.has<PointCloudComponent>()) { - execute_on_component(params, geometry_set.get_component_for_write<PointCloudComponent>()); + const NodeGeometryPointTranslate &storage = + *(const NodeGeometryPointTranslate *)params.node().storage; + + const Array<GeometryComponentType> types{ + GEO_COMPONENT_TYPE_MESH, + GEO_COMPONENT_TYPE_POINT_CLOUD, + GEO_COMPONENT_TYPE_CURVE, + }; + + /* TODO: Remove legacy string input and add versioning. */ + if (storage.input_type == GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE) { + for (const GeometryComponentType type : types) { + if (geometry_set.has(type)) { + execute_on_component_legacy(params, geometry_set.get_component_for_write(type)); + } + } + params.error_message_add(NodeWarningType::Info, "Selection not supported in legacy mode"); } - if (geometry_set.has<CurveComponent>()) { - execute_on_component(params, geometry_set.get_component_for_write<CurveComponent>()); + else { + Field<bool> selection = params.extract_input<Field<bool>>("Selection"); + Field<float3> translation = params.extract_input<Field<float3>>("Translation_001"); + for (const GeometryComponentType type : types) { + if (geometry_set.has(type)) { + execute_on_component(geometry_set.get_component_for_write(type), selection, translation); + } + } } params.set_output("Geometry", std::move(geometry_set)); _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs