Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||||
| #include "DNA_pointcloud_types.h" | #include "DNA_pointcloud_types.h" | ||||
| #include "BKE_attribute_math.hh" | #include "BKE_attribute_math.hh" | ||||
| #include "BKE_instances.hh" | #include "BKE_instances.hh" | ||||
| #include "BKE_pointcloud.h" | #include "BKE_pointcloud.h" | ||||
| #include "node_geometry_util.hh" | #include "node_geometry_util.hh" | ||||
| namespace blender::nodes::node_geo_instances_to_points_cc { | namespace blender::nodes::node_geo_instances_to_points_cc { | ||||
| static void node_declare(NodeDeclarationBuilder &b) | static void node_declare(NodeDeclarationBuilder &b) | ||||
| { | { | ||||
| b.add_input<decl::Geometry>(N_("Instances")).only_instances(); | b.add_input<decl::Geometry>(N_("Instances")).only_instances(); | ||||
| b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field(); | b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().field_on_auto(); | ||||
| b.add_input<decl::Vector>(N_("Position")).implicit_field(implicit_field_inputs::position); | b.add_input<decl::Vector>(N_("Position")) | ||||
| .implicit_field_on_auto(implicit_field_inputs::position); | |||||
| b.add_input<decl::Float>(N_("Radius")) | b.add_input<decl::Float>(N_("Radius")) | ||||
| .default_value(0.05f) | .default_value(0.05f) | ||||
| .min(0.0f) | .min(0.0f) | ||||
| .subtype(PROP_DISTANCE) | .subtype(PROP_DISTANCE) | ||||
| .supports_field(); | .field_on_auto(); | ||||
| b.add_output<decl::Geometry>(N_("Points")); | b.add_output<decl::Geometry>(N_("Points")).propagate_from_auto(); | ||||
| } | } | ||||
| static void convert_instances_to_points(GeometrySet &geometry_set, | static void convert_instances_to_points(GeometrySet &geometry_set, | ||||
| Field<float3> position_field, | Field<float3> position_field, | ||||
| Field<float> radius_field, | Field<float> radius_field, | ||||
| const Field<bool> selection_field) | const Field<bool> selection_field, | ||||
| const AnonymousAttributePropagationInfo &propagation_info) | |||||
| { | { | ||||
| const bke::Instances &instances = *geometry_set.get_instances_for_read(); | const bke::Instances &instances = *geometry_set.get_instances_for_read(); | ||||
| const bke::InstancesFieldContext context{instances}; | const bke::InstancesFieldContext context{instances}; | ||||
| fn::FieldEvaluator evaluator{context, instances.instances_num()}; | fn::FieldEvaluator evaluator{context, instances.instances_num()}; | ||||
| evaluator.set_selection(std::move(selection_field)); | evaluator.set_selection(std::move(selection_field)); | ||||
| evaluator.add(std::move(position_field)); | evaluator.add(std::move(position_field)); | ||||
| evaluator.add(std::move(radius_field)); | evaluator.add(std::move(radius_field)); | ||||
| Show All 19 Lines | static void convert_instances_to_points(GeometrySet &geometry_set, | ||||
| radii.materialize_compressed_to_uninitialized(selection, point_radii.span); | radii.materialize_compressed_to_uninitialized(selection, point_radii.span); | ||||
| point_positions.finish(); | point_positions.finish(); | ||||
| point_radii.finish(); | point_radii.finish(); | ||||
| Map<AttributeIDRef, AttributeKind> attributes_to_propagate; | Map<AttributeIDRef, AttributeKind> attributes_to_propagate; | ||||
| geometry_set.gather_attributes_for_propagation({GEO_COMPONENT_TYPE_INSTANCES}, | geometry_set.gather_attributes_for_propagation({GEO_COMPONENT_TYPE_INSTANCES}, | ||||
| GEO_COMPONENT_TYPE_POINT_CLOUD, | GEO_COMPONENT_TYPE_POINT_CLOUD, | ||||
| false, | false, | ||||
| propagation_info, | |||||
| attributes_to_propagate); | attributes_to_propagate); | ||||
| /* These two attributes are added by the implicit inputs above. */ | /* These two attributes are added by the implicit inputs above. */ | ||||
| attributes_to_propagate.remove("position"); | attributes_to_propagate.remove("position"); | ||||
| attributes_to_propagate.remove("radius"); | attributes_to_propagate.remove("radius"); | ||||
| for (const auto item : attributes_to_propagate.items()) { | for (const auto item : attributes_to_propagate.items()) { | ||||
| const AttributeIDRef &attribute_id = item.key; | const AttributeIDRef &attribute_id = item.key; | ||||
| const AttributeKind attribute_kind = item.value; | const AttributeKind attribute_kind = item.value; | ||||
| Show All 13 Lines | |||||
| static void node_geo_exec(GeoNodeExecParams params) | static void node_geo_exec(GeoNodeExecParams params) | ||||
| { | { | ||||
| GeometrySet geometry_set = params.extract_input<GeometrySet>("Instances"); | GeometrySet geometry_set = params.extract_input<GeometrySet>("Instances"); | ||||
| if (geometry_set.has_instances()) { | if (geometry_set.has_instances()) { | ||||
| convert_instances_to_points(geometry_set, | convert_instances_to_points(geometry_set, | ||||
| params.extract_input<Field<float3>>("Position"), | params.extract_input<Field<float3>>("Position"), | ||||
| params.extract_input<Field<float>>("Radius"), | params.extract_input<Field<float>>("Radius"), | ||||
| params.extract_input<Field<bool>>("Selection")); | params.extract_input<Field<bool>>("Selection"), | ||||
| params.get_output_propagation_info("Points")); | |||||
| geometry_set.keep_only({GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_EDIT}); | geometry_set.keep_only({GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_EDIT}); | ||||
| params.set_output("Points", std::move(geometry_set)); | params.set_output("Points", std::move(geometry_set)); | ||||
| } | } | ||||
| else { | else { | ||||
| params.set_default_remaining_outputs(); | params.set_default_remaining_outputs(); | ||||
| } | } | ||||
| } | } | ||||
| Show All 14 Lines | |||||