Differential D14233 Diff 48875 source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc
Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||||
| #include "BKE_spline.hh" | #include "BKE_curves.hh" | ||||
| #include "UI_interface.h" | #include "UI_interface.h" | ||||
| #include "UI_resources.h" | #include "UI_resources.h" | ||||
| Context not available. | |||||
| N_("The selection from the start and end of the splines based on the input sizes")); | N_("The selection from the start and end of the splines based on the input sizes")); | ||||
| } | } | ||||
| static void select_by_spline(const int start, const int end, MutableSpan<bool> r_selection) | |||||
| { | |||||
| const int size = r_selection.size(); | |||||
| const int start_use = std::min(start, size); | |||||
| const int end_use = std::min(end, size); | |||||
| r_selection.slice(0, start_use).fill(true); | |||||
| r_selection.slice(size - end_use, end_use).fill(true); | |||||
| } | |||||
| class EndpointFieldInput final : public GeometryFieldInput { | class EndpointFieldInput final : public GeometryFieldInput { | ||||
| Field<int> start_size_; | Field<int> start_size_; | ||||
| Field<int> end_size_; | Field<int> end_size_; | ||||
| Context not available. | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| const std::unique_ptr<CurveEval> curve = curves_to_curve_eval(*curve_component.get_for_read()); | const Curves &curves_id = *curve_component.get_for_read(); | ||||
| const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); | |||||
| Array<int> control_point_offsets = curve->control_point_offsets(); | if (curves.points_size() == 0) { | ||||
| if (curve == nullptr || control_point_offsets.last() == 0) { | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| GeometryComponentFieldContext size_context{curve_component, ATTR_DOMAIN_CURVE}; | GeometryComponentFieldContext size_context{curve_component, ATTR_DOMAIN_CURVE}; | ||||
| fn::FieldEvaluator evaluator{size_context, curve->splines().size()}; | fn::FieldEvaluator evaluator{size_context, curves.curves_size()}; | ||||
| evaluator.add(start_size_); | evaluator.add(start_size_); | ||||
| evaluator.add(end_size_); | evaluator.add(end_size_); | ||||
| evaluator.evaluate(); | evaluator.evaluate(); | ||||
| const VArray<int> &start_size = evaluator.get_evaluated<int>(0); | const VArray<int> &start_size = evaluator.get_evaluated<int>(0); | ||||
| const VArray<int> &end_size = evaluator.get_evaluated<int>(1); | const VArray<int> &end_size = evaluator.get_evaluated<int>(1); | ||||
| const int point_size = control_point_offsets.last(); | Array<bool> selection(curves.points_size(), false); | ||||
| Array<bool> selection(point_size, false); | |||||
| int current_point = 0; | |||||
| MutableSpan<bool> selection_span = selection.as_mutable_span(); | MutableSpan<bool> selection_span = selection.as_mutable_span(); | ||||
| for (int i : IndexRange(curve->splines().size())) { | devirtualize_varray2(start_size, end_size, [&](const auto &start_size, const auto &end_size) { | ||||
| const SplinePtr &spline = curve->splines()[i]; | threading::parallel_for(curves.curves_range(), 1024, [&](IndexRange curves_range) { | ||||
| if (start_size[i] <= 0 && end_size[i] <= 0) { | for (const int i : curves_range) { | ||||
| selection_span.slice(current_point, spline->size()).fill(false); | const IndexRange range = curves.range_for_curve(i); | ||||
| } | const int start = std::max(start_size[i], 0); | ||||
| else { | const int end = std::max(end_size[i], 0); | ||||
| int start_use = std::max(start_size[i], 0); | |||||
| int end_use = std::max(end_size[i], 0); | selection_span.slice(range.take_front(start)).fill(true); | ||||
| select_by_spline(start_use, end_use, selection_span.slice(current_point, spline->size())); | selection_span.slice(range.take_back(end)).fill(true); | ||||
| } | } | ||||
| current_point += spline->size(); | }); | ||||
| } | }); | ||||
| return VArray<bool>::ForContainer(std::move(selection)); | return VArray<bool>::ForContainer(std::move(selection)); | ||||
| }; | }; | ||||
| Context not available. | |||||