diff options
6 files changed, 170 insertions, 71 deletions
diff --git a/release/scripts/startup/bl_ui/space_spreadsheet.py b/release/scripts/startup/bl_ui/space_spreadsheet.py index d6ee747f263..741ad544d67 100644 --- a/release/scripts/startup/bl_ui/space_spreadsheet.py +++ b/release/scripts/startup/bl_ui/space_spreadsheet.py @@ -95,8 +95,10 @@ class SPREADSHEET_HT_header(bpy.types.Header): obj = root_context.object if obj is None: return False - if obj.type != 'MESH' or obj.mode != 'EDIT': - return False + if obj.type == 'MESH': + return obj.mode == 'EDIT' + if obj.type == 'CURVES': + return obj.mode == 'SCULPT_CURVES' return True diff --git a/source/blender/editors/include/ED_curves_sculpt.h b/source/blender/editors/include/ED_curves_sculpt.h index 8aab1533e25..625af914280 100644 --- a/source/blender/editors/include/ED_curves_sculpt.h +++ b/source/blender/editors/include/ED_curves_sculpt.h @@ -10,8 +10,33 @@ extern "C" { #endif +struct Curves; + void ED_operatortypes_sculpt_curves(void); #ifdef __cplusplus + +# include "BLI_index_mask.hh" +# include "BLI_vector.hh" + +namespace blender::ed::sculpt_paint { + +/** + * Find curves that have any point selected (a selection factor greater than zero), + * or curves that have their own selection factor greater than zero. + */ +IndexMask retrieve_selected_curves(const Curves &curves_id, Vector<int64_t> &r_indices); + +/** + * Find points that are selected (a selection factor greater than zero), + * or points in curves with a selection factor greater than zero). + */ +IndexMask retrieve_selected_points(const Curves &curves_id, Vector<int64_t> &r_indices); + +} // namespace blender::ed::sculpt_paint + +#endif + +#ifdef __cplusplus } #endif diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh b/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh index c31bba2fe1e..61aa7d201b1 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh @@ -14,6 +14,8 @@ #include "BKE_attribute.h" #include "BKE_curves.hh" +#include "ED_curves_sculpt.h" + struct ARegion; struct RegionView3D; struct Depsgraph; @@ -98,12 +100,6 @@ VArray<float> get_curves_selection(const Curves &curves_id); */ VArray<float> get_point_selection(const Curves &curves_id); -/** - * Find curves that have any point selected (a selection factor greater than zero), - * or curves that have their own selection factor greater than zero. - */ -IndexMask retrieve_selected_curves(const Curves &curves_id, Vector<int64_t> &r_indices); - void move_last_point_and_resample(MutableSpan<float3> positions, const float3 &new_last_position); class CurvesSculptCommonContext { diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc b/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc index f620fed5761..5bfc8ccc667 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc @@ -6,6 +6,8 @@ #include "curves_sculpt_intern.hh" +#include "ED_curves_sculpt.h" + namespace blender::ed::sculpt_paint { static VArray<float> get_curves_selection(const CurvesGeometry &curves, const eAttrDomain domain) @@ -62,7 +64,7 @@ static IndexMask retrieve_selected_curves(const CurvesGeometry &curves, 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) : + return selection.get_internal_single() <= 0.0f ? IndexMask(0) : IndexMask(curves.curves_num()); } return index_mask_ops::find_indices_based_on_predicate( @@ -78,7 +80,7 @@ static IndexMask retrieve_selected_curves(const CurvesGeometry &curves, 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) : + return selection.get_internal_single() <= 0.0f ? IndexMask(0) : IndexMask(curves.curves_num()); } return index_mask_ops::find_indices_based_on_predicate( @@ -102,4 +104,49 @@ IndexMask retrieve_selected_curves(const Curves &curves_id, Vector<int64_t> &r_i 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) +{ + if (!(curves_id.flag & CV_SCULPT_SELECTION_ENABLED)) { + return CurvesGeometry::wrap(curves_id.geometry).points_range(); + } + return retrieve_selected_points(CurvesGeometry::wrap(curves_id.geometry), + eAttrDomain(curves_id.selection_domain), + r_indices); +} + } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc index c7653e94b4d..629a0b5802b 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc @@ -5,6 +5,7 @@ #include "BKE_attribute.hh" #include "BKE_context.h" +#include "BKE_curves.hh" #include "BKE_editmesh.h" #include "BKE_geometry_fields.hh" #include "BKE_global.h" @@ -22,6 +23,7 @@ #include "DEG_depsgraph_query.h" +#include "ED_curves_sculpt.h" #include "ED_spreadsheet.h" #include "NOD_geometry_nodes_eval_log.hh" @@ -232,23 +234,31 @@ int GeometryDataSource::tot_rows() const return attributes.domain_size(domain_); } -/** - * Only data sets corresponding to mesh objects in edit mode currently support selection filtering. - */ bool GeometryDataSource::has_selection_filter() const { Object *object_orig = DEG_get_original_object(object_eval_); - if (object_orig->type != OB_MESH) { - return false; - } - if (object_orig->mode != OB_MODE_EDIT) { - return false; - } - if (component_->type() != GEO_COMPONENT_TYPE_MESH) { - return false; + switch (component_->type()) { + case GEO_COMPONENT_TYPE_MESH: { + if (object_orig->type != OB_MESH) { + return false; + } + if (object_orig->mode != OB_MODE_EDIT) { + return false; + } + return true; + } + case GEO_COMPONENT_TYPE_CURVE: { + if (object_orig->type != OB_CURVES) { + return false; + } + if (object_orig->mode != OB_MODE_SCULPT_CURVES) { + return false; + } + return true; + } + default: + return false; } - - return true; } IndexMask GeometryDataSource::apply_selection_filter(Vector<int64_t> &indices) const @@ -256,50 +266,73 @@ IndexMask GeometryDataSource::apply_selection_filter(Vector<int64_t> &indices) c std::lock_guard lock{mutex_}; const IndexMask full_range(this->tot_rows()); - BLI_assert(object_eval_->mode == OB_MODE_EDIT); - BLI_assert(component_->type() == GEO_COMPONENT_TYPE_MESH); - Object *object_orig = DEG_get_original_object(object_eval_); - const MeshComponent *mesh_component = static_cast<const MeshComponent *>(component_); - const Mesh *mesh_eval = mesh_component->get_for_read(); - Mesh *mesh_orig = (Mesh *)object_orig->data; - BMesh *bm = mesh_orig->edit_mesh->bm; - BM_mesh_elem_table_ensure(bm, BM_VERT); - - const int *orig_indices = (int *)CustomData_get_layer(&mesh_eval->vdata, CD_ORIGINDEX); - if (orig_indices != nullptr) { - /* Use CD_ORIGINDEX layer if it exists. */ - VArray<bool> selection = mesh_component->attributes()->adapt_domain<bool>( - VArray<bool>::ForFunc(mesh_eval->totvert, - [bm, orig_indices](int vertex_index) -> bool { - const int i_orig = orig_indices[vertex_index]; - if (i_orig < 0) { - return false; - } - if (i_orig >= bm->totvert) { - return false; - } - BMVert *vert = bm->vtable[i_orig]; - return BM_elem_flag_test(vert, BM_ELEM_SELECT); - }), - ATTR_DOMAIN_POINT, - domain_); - return index_mask_ops::find_indices_from_virtual_array(full_range, selection, 1024, indices); - } - - if (mesh_eval->totvert == bm->totvert) { - /* Use a simple heuristic to match original vertices to evaluated ones. */ - VArray<bool> selection = mesh_component->attributes()->adapt_domain<bool>( - VArray<bool>::ForFunc(mesh_eval->totvert, - [bm](int vertex_index) -> bool { - BMVert *vert = bm->vtable[vertex_index]; - return BM_elem_flag_test(vert, BM_ELEM_SELECT); - }), - ATTR_DOMAIN_POINT, - domain_); - return index_mask_ops::find_indices_from_virtual_array(full_range, selection, 2048, indices); - } - - return full_range; + switch (component_->type()) { + case GEO_COMPONENT_TYPE_MESH: { + BLI_assert(object_eval_->type == OB_MESH); + BLI_assert(object_eval_->mode == OB_MODE_EDIT); + Object *object_orig = DEG_get_original_object(object_eval_); + const Mesh *mesh_eval = geometry_set_.get_mesh_for_read(); + const bke::AttributeAccessor attributes_eval = bke::mesh_attributes(*mesh_eval); + Mesh *mesh_orig = (Mesh *)object_orig->data; + BMesh *bm = mesh_orig->edit_mesh->bm; + BM_mesh_elem_table_ensure(bm, BM_VERT); + + const int *orig_indices = (int *)CustomData_get_layer(&mesh_eval->vdata, CD_ORIGINDEX); + if (orig_indices != nullptr) { + /* Use CD_ORIGINDEX layer if it exists. */ + VArray<bool> selection = attributes_eval.adapt_domain<bool>( + VArray<bool>::ForFunc(mesh_eval->totvert, + [bm, orig_indices](int vertex_index) -> bool { + const int i_orig = orig_indices[vertex_index]; + if (i_orig < 0) { + return false; + } + if (i_orig >= bm->totvert) { + return false; + } + const BMVert *vert = BM_vert_at_index(bm, i_orig); + return BM_elem_flag_test(vert, BM_ELEM_SELECT); + }), + ATTR_DOMAIN_POINT, + domain_); + return index_mask_ops::find_indices_from_virtual_array( + full_range, selection, 1024, indices); + } + + if (mesh_eval->totvert == bm->totvert) { + /* Use a simple heuristic to match original vertices to evaluated ones. */ + VArray<bool> selection = attributes_eval.adapt_domain<bool>( + VArray<bool>::ForFunc(mesh_eval->totvert, + [bm](int vertex_index) -> bool { + const BMVert *vert = BM_vert_at_index(bm, vertex_index); + return BM_elem_flag_test(vert, BM_ELEM_SELECT); + }), + ATTR_DOMAIN_POINT, + domain_); + return index_mask_ops::find_indices_from_virtual_array( + full_range, selection, 2048, indices); + } + + return full_range; + } + case GEO_COMPONENT_TYPE_CURVE: { + BLI_assert(object_eval_->type == OB_CURVES); + BLI_assert(object_eval_->mode == OB_MODE_SCULPT_CURVES); + const CurveComponent &component = static_cast<const CurveComponent &>(*component_); + const Curves &curves_id = *component.get_for_read(); + switch (domain_) { + case ATTR_DOMAIN_POINT: + return sculpt_paint::retrieve_selected_points(curves_id, indices); + case ATTR_DOMAIN_CURVE: + return sculpt_paint::retrieve_selected_curves(curves_id, indices); + default: + BLI_assert_unreachable(); + } + return full_range; + } + default: + return full_range; + } } void VolumeDataSource::foreach_default_column_ids( diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh index 04b4f6d8d06..71bc4768949 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.hh @@ -68,10 +68,6 @@ class GeometryDataSource : public DataSource { return object_eval_; } - /** - * Only data sets corresponding to mesh objects in edit mode currently support selection - * filtering. - */ bool has_selection_filter() const override; IndexMask apply_selection_filter(Vector<int64_t> &indices) const; |