Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/sculpt_paint/curves_sculpt_selection.cc
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||||
| #include "BLI_index_mask_ops.hh" | #include "BLI_index_mask_ops.hh" | ||||
| #include "BKE_curves.hh" | #include "BKE_curves.hh" | ||||
| #include "curves_sculpt_intern.hh" | #include "curves_sculpt_intern.hh" | ||||
| #include "ED_curves_sculpt.h" | #include "ED_curves_sculpt.h" | ||||
| namespace blender::ed::sculpt_paint { | namespace blender::ed::sculpt_paint { | ||||
| static VArray<float> get_curves_selection(const CurvesGeometry &curves, const eAttrDomain domain) | bke::SpanAttributeWriter<float> float_selection_ensure(Curves &curves_id) | ||||
| { | { | ||||
| switch (domain) { | /* TODO: Use a generic attribute conversion utility instead of this function. */ | ||||
| case ATTR_DOMAIN_CURVE: | bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); | ||||
| return curves.selection_curve_float(); | bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); | ||||
| case ATTR_DOMAIN_POINT: | |||||
| return curves.adapt_domain( | if (const auto meta_data = attributes.lookup_meta_data(".selection")) { | ||||
| curves.selection_point_float(), ATTR_DOMAIN_POINT, ATTR_DOMAIN_CURVE); | if (meta_data->data_type == CD_PROP_BOOL) { | ||||
| default: | const VArray<float> selection = attributes.lookup<float>(".selection"); | ||||
| BLI_assert_unreachable(); | float *dst = static_cast<float *>( | ||||
| return {}; | MEM_malloc_arrayN(selection.size(), sizeof(float), __func__)); | ||||
| } | selection.materialize({dst, selection.size()}); | ||||
| attributes.remove(".selection"); | |||||
| attributes.add( | |||||
| ".selection", meta_data->domain, CD_PROP_FLOAT, bke::AttributeInitMoveArray(dst)); | |||||
| } | |||||
| } | |||||
| else { | |||||
| const eAttrDomain domain = eAttrDomain(curves_id.selection_domain); | |||||
| const int64_t size = attributes.domain_size(domain); | |||||
| attributes.add(".selection", | |||||
| domain, | |||||
| CD_PROP_FLOAT, | |||||
| bke::AttributeInitVArray(VArray<float>::ForSingle(size, 1.0f))); | |||||
| } | } | ||||
| VArray<float> get_curves_selection(const Curves &curves_id) | return curves.attributes_for_write().lookup_for_write_span<float>(".selection"); | ||||
| { | |||||
| return get_curves_selection(CurvesGeometry::wrap(curves_id.geometry), | |||||
| eAttrDomain(curves_id.selection_domain)); | |||||
| } | |||||
| static VArray<float> get_point_selection(const CurvesGeometry &curves, const eAttrDomain domain) | |||||
| { | |||||
| switch (domain) { | |||||
| case ATTR_DOMAIN_CURVE: | |||||
| return curves.adapt_domain( | |||||
| curves.selection_curve_float(), ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT); | |||||
| case ATTR_DOMAIN_POINT: | |||||
| return curves.selection_point_float(); | |||||
| default: | |||||
| BLI_assert_unreachable(); | |||||
| return {}; | |||||
| } | |||||
| } | |||||
| VArray<float> get_point_selection(const Curves &curves_id) | |||||
| { | |||||
| return get_point_selection(CurvesGeometry::wrap(curves_id.geometry), | |||||
| eAttrDomain(curves_id.selection_domain)); | |||||
| } | |||||
| static IndexMask retrieve_selected_curves(const CurvesGeometry &curves, | |||||
| const eAttrDomain domain, | |||||
| Vector<int64_t> &r_indices) | |||||
| { | |||||
| switch (domain) { | |||||
| case ATTR_DOMAIN_POINT: { | |||||
| const VArray<float> selection = curves.selection_point_float(); | |||||
| if (selection.is_single()) { | |||||
| return selection.get_internal_single() <= 0.0f ? IndexMask(0) : | |||||
| IndexMask(curves.curves_num()); | |||||
| } | |||||
| const Span<float> point_selection_span = selection.get_internal_span(); | |||||
| return index_mask_ops::find_indices_based_on_predicate( | |||||
| curves.curves_range(), 512, r_indices, [&](const int curve_i) { | |||||
| for (const int i : curves.points_for_curve(curve_i)) { | |||||
| if (point_selection_span[i] > 0.0f) { | |||||
| return true; | |||||
| } | |||||
| } | |||||
| return false; | |||||
| }); | |||||
| } | |||||
| case ATTR_DOMAIN_CURVE: { | |||||
| const VArray<float> selection = curves.selection_curve_float(); | |||||
| if (selection.is_single()) { | |||||
| return selection.get_internal_single() <= 0.0f ? IndexMask(0) : | |||||
| IndexMask(curves.curves_num()); | |||||
| } | |||||
| return index_mask_ops::find_indices_based_on_predicate( | |||||
| curves.curves_range(), 2048, r_indices, [&](const int i) { | |||||
| return selection[i] > 0.0f; | |||||
| }); | |||||
| } | |||||
| default: | |||||
| BLI_assert_unreachable(); | |||||
| return {}; | |||||
| } | |||||
| } | |||||
| IndexMask retrieve_selected_curves(const Curves &curves_id, Vector<int64_t> &r_indices) | |||||
| { | |||||
| return retrieve_selected_curves(CurvesGeometry::wrap(curves_id.geometry), | |||||
| eAttrDomain(curves_id.selection_domain), | |||||
| r_indices); | |||||
| } | |||||
| static IndexMask retrieve_selected_points(const CurvesGeometry &curves, | |||||
| const eAttrDomain domain, | |||||
| Vector<int64_t> &r_indices) | |||||
| { | |||||
| switch (domain) { | |||||
| case ATTR_DOMAIN_POINT: { | |||||
| const VArray<float> selection = curves.selection_point_float(); | |||||
| if (selection.is_single()) { | |||||
| return selection.get_internal_single() <= 0.0f ? IndexMask(0) : | |||||
| IndexMask(curves.points_num()); | |||||
| } | |||||
| return index_mask_ops::find_indices_based_on_predicate( | |||||
| curves.points_range(), 2048, r_indices, [&](const int i) { | |||||
| return selection[i] > 0.0f; | |||||
| }); | |||||
| } | |||||
| case ATTR_DOMAIN_CURVE: { | |||||
| const VArray<float> selection = curves.selection_curve_float(); | |||||
| if (selection.is_single()) { | |||||
| return selection.get_internal_single() <= 0.0f ? IndexMask(0) : | |||||
| IndexMask(curves.points_num()); | |||||
| } | |||||
| const VArray<float> point_selection = curves.adapt_domain( | |||||
| selection, ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT); | |||||
| return index_mask_ops::find_indices_based_on_predicate( | |||||
| curves.points_range(), 2048, r_indices, [&](const int i) { | |||||
| return point_selection[i] > 0.0f; | |||||
| }); | |||||
| } | |||||
| default: | |||||
| BLI_assert_unreachable(); | |||||
| return {}; | |||||
| } | |||||
| } | |||||
| IndexMask retrieve_selected_points(const Curves &curves_id, Vector<int64_t> &r_indices) | |||||
| { | |||||
| return retrieve_selected_points(CurvesGeometry::wrap(curves_id.geometry), | |||||
| eAttrDomain(curves_id.selection_domain), | |||||
| r_indices); | |||||
| } | } | ||||
| } // namespace blender::ed::sculpt_paint | } // namespace blender::ed::sculpt_paint | ||||