diff options
Diffstat (limited to 'source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc')
-rw-r--r-- | source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc | 376 |
1 files changed, 79 insertions, 297 deletions
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 173ef43bfb6..337a6037c42 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc @@ -14,6 +14,8 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include "BLI_virtual_array.hh" + #include "BKE_context.h" #include "BKE_editmesh.h" #include "BKE_lib_id.h" @@ -51,30 +53,6 @@ using blender::fn::GField; namespace blender::ed::spreadsheet { -static std::optional<eSpreadsheetColumnValueType> cpp_type_to_column_value_type( - const fn::CPPType &type) -{ - if (type.is<bool>()) { - return SPREADSHEET_VALUE_TYPE_BOOL; - } - if (type.is<int>()) { - return SPREADSHEET_VALUE_TYPE_INT32; - } - if (type.is<float>()) { - return SPREADSHEET_VALUE_TYPE_FLOAT; - } - if (type.is<float2>()) { - return SPREADSHEET_VALUE_TYPE_FLOAT2; - } - if (type.is<float3>()) { - return SPREADSHEET_VALUE_TYPE_FLOAT3; - } - if (type.is<ColorGeometry4f>()) { - return SPREADSHEET_VALUE_TYPE_COLOR; - } - return std::nullopt; -} - void ExtraColumns::foreach_default_column_ids( FunctionRef<void(const SpreadsheetColumnID &, bool is_extra)> fn) const { @@ -92,39 +70,7 @@ std::unique_ptr<ColumnValues> ExtraColumns::get_column_values( if (values == nullptr) { return {}; } - eSpreadsheetColumnValueType column_type = *cpp_type_to_column_value_type(values->type()); - return column_values_from_function(column_type, - column_id.name, - values->size(), - [column_type, values](int index, CellValue &r_cell_value) { - const void *value = (*values)[index]; - switch (column_type) { - case SPREADSHEET_VALUE_TYPE_BOOL: - r_cell_value.value_bool = *(const bool *)value; - break; - case SPREADSHEET_VALUE_TYPE_INT32: - r_cell_value.value_int = *(const int *)value; - break; - case SPREADSHEET_VALUE_TYPE_FLOAT: - r_cell_value.value_float = *(const float *)value; - break; - case SPREADSHEET_VALUE_TYPE_FLOAT2: - r_cell_value.value_float2 = *(const float2 *)value; - break; - case SPREADSHEET_VALUE_TYPE_FLOAT3: - r_cell_value.value_float3 = *(const float3 *)value; - break; - case SPREADSHEET_VALUE_TYPE_COLOR: - r_cell_value.value_color = *( - const ColorGeometry4f *)value; - break; - case SPREADSHEET_VALUE_TYPE_STRING: - r_cell_value.value_string = *(const std::string *)value; - break; - case SPREADSHEET_VALUE_TYPE_INSTANCES: - break; - } - }); + return std::make_unique<ColumnValues>(column_id.name, fn::GVArray::ForSpan(*values)); } void GeometryDataSource::foreach_default_column_ids( @@ -179,52 +125,25 @@ std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values( if (STREQ(column_id.name, "Name")) { Span<int> reference_handles = instances.instance_reference_handles(); Span<InstanceReference> references = instances.references(); - std::unique_ptr<ColumnValues> values = column_values_from_function( - SPREADSHEET_VALUE_TYPE_INSTANCES, - "Name", - domain_size, - [reference_handles, references](int index, CellValue &r_cell_value) { - const InstanceReference &reference = references[reference_handles[index]]; - switch (reference.type()) { - case InstanceReference::Type::Object: { - Object &object = reference.object(); - r_cell_value.value_object = ObjectCellValue{&object}; - break; - } - case InstanceReference::Type::Collection: { - Collection &collection = reference.collection(); - r_cell_value.value_collection = CollectionCellValue{&collection}; - break; - } - case InstanceReference::Type::GeometrySet: { - const GeometrySet &geometry_set = reference.geometry_set(); - r_cell_value.value_geometry_set = GeometrySetCellValue{&geometry_set}; - break; - } - case InstanceReference::Type::None: { - break; - } - } - }); - return values; + return std::make_unique<ColumnValues>( + column_id.name, + VArray<InstanceReference>::ForFunc(domain_size, + [reference_handles, references](int64_t index) { + return references[reference_handles[index]]; + })); } Span<float4x4> transforms = instances.instance_transforms(); if (STREQ(column_id.name, "Rotation")) { - return column_values_from_function( - SPREADSHEET_VALUE_TYPE_FLOAT3, - column_id.name, - domain_size, - [transforms](int index, CellValue &r_cell_value) { - r_cell_value.value_float3 = transforms[index].to_euler(); - }); + return std::make_unique<ColumnValues>( + column_id.name, VArray<float3>::ForFunc(domain_size, [transforms](int64_t index) { + return transforms[index].to_euler(); + })); } if (STREQ(column_id.name, "Scale")) { - return column_values_from_function(SPREADSHEET_VALUE_TYPE_FLOAT3, - column_id.name, - domain_size, - [transforms](int index, CellValue &r_cell_value) { - r_cell_value.value_float3 = transforms[index].scale(); - }); + return std::make_unique<ColumnValues>( + column_id.name, VArray<float3>::ForFunc(domain_size, [transforms](int64_t index) { + return transforms[index].scale(); + })); } } @@ -237,71 +156,7 @@ std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values( return {}; } - const CustomDataType type = bke::cpp_type_to_custom_data_type(varray.type()); - switch (type) { - case CD_PROP_FLOAT: - return column_values_from_function(SPREADSHEET_VALUE_TYPE_FLOAT, - column_id.name, - domain_size, - [varray](int index, CellValue &r_cell_value) { - float value; - varray.get(index, &value); - r_cell_value.value_float = value; - }); - case CD_PROP_INT32: - return column_values_from_function( - SPREADSHEET_VALUE_TYPE_INT32, - column_id.name, - domain_size, - [varray](int index, CellValue &r_cell_value) { - int value; - varray.get(index, &value); - r_cell_value.value_int = value; - }, - STREQ(column_id.name, "id") ? 5.5f : 0.0f); - case CD_PROP_BOOL: - return column_values_from_function(SPREADSHEET_VALUE_TYPE_BOOL, - column_id.name, - domain_size, - [varray](int index, CellValue &r_cell_value) { - bool value; - varray.get(index, &value); - r_cell_value.value_bool = value; - }); - case CD_PROP_FLOAT2: { - return column_values_from_function(SPREADSHEET_VALUE_TYPE_FLOAT2, - column_id.name, - domain_size, - [varray](int index, CellValue &r_cell_value) { - float2 value; - varray.get(index, &value); - r_cell_value.value_float2 = value; - }); - } - case CD_PROP_FLOAT3: { - return column_values_from_function(SPREADSHEET_VALUE_TYPE_FLOAT3, - column_id.name, - domain_size, - [varray](int index, CellValue &r_cell_value) { - float3 value; - varray.get(index, &value); - r_cell_value.value_float3 = value; - }); - } - case CD_PROP_COLOR: { - return column_values_from_function(SPREADSHEET_VALUE_TYPE_COLOR, - column_id.name, - domain_size, - [varray](int index, CellValue &r_cell_value) { - ColorGeometry4f value; - varray.get(index, &value); - r_cell_value.value_color = value; - }); - } - default: - break; - } - return {}; + return std::make_unique<ColumnValues>(column_id.name, std::move(varray)); } int GeometryDataSource::tot_rows() const @@ -309,90 +164,9 @@ int GeometryDataSource::tot_rows() const return component_->attribute_domain_size(domain_); } -using IsVertexSelectedFn = FunctionRef<bool(int vertex_index)>; - -static void get_selected_vertex_indices(const Mesh &mesh, - const IsVertexSelectedFn is_vertex_selected_fn, - MutableSpan<bool> selection) -{ - for (const int i : IndexRange(mesh.totvert)) { - if (!selection[i]) { - continue; - } - if (!is_vertex_selected_fn(i)) { - selection[i] = false; - } - } -} - -static void get_selected_corner_indices(const Mesh &mesh, - const IsVertexSelectedFn is_vertex_selected_fn, - MutableSpan<bool> selection) -{ - for (const int i : IndexRange(mesh.totloop)) { - const MLoop &loop = mesh.mloop[i]; - if (!selection[i]) { - continue; - } - if (!is_vertex_selected_fn(loop.v)) { - selection[i] = false; - } - } -} - -static void get_selected_face_indices(const Mesh &mesh, - const IsVertexSelectedFn is_vertex_selected_fn, - MutableSpan<bool> selection) -{ - for (const int poly_index : IndexRange(mesh.totpoly)) { - if (!selection[poly_index]) { - continue; - } - const MPoly &poly = mesh.mpoly[poly_index]; - for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = mesh.mloop[loop_index]; - if (!is_vertex_selected_fn(loop.v)) { - selection[poly_index] = false; - break; - } - } - } -} - -static void get_selected_edge_indices(const Mesh &mesh, - const IsVertexSelectedFn is_vertex_selected_fn, - MutableSpan<bool> selection) -{ - for (const int i : IndexRange(mesh.totedge)) { - if (!selection[i]) { - continue; - } - const MEdge &edge = mesh.medge[i]; - if (!is_vertex_selected_fn(edge.v1) || !is_vertex_selected_fn(edge.v2)) { - selection[i] = false; - } - } -} - -static void get_selected_indices_on_domain(const Mesh &mesh, - const AttributeDomain domain, - const IsVertexSelectedFn is_vertex_selected_fn, - MutableSpan<bool> selection) -{ - switch (domain) { - case ATTR_DOMAIN_POINT: - return get_selected_vertex_indices(mesh, is_vertex_selected_fn, selection); - case ATTR_DOMAIN_FACE: - return get_selected_face_indices(mesh, is_vertex_selected_fn, selection); - case ATTR_DOMAIN_CORNER: - return get_selected_corner_indices(mesh, is_vertex_selected_fn, selection); - case ATTR_DOMAIN_EDGE: - return get_selected_edge_indices(mesh, is_vertex_selected_fn, selection); - default: - return; - } -} - +/** + * 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_); @@ -409,7 +183,18 @@ bool GeometryDataSource::has_selection_filter() const return true; } -void GeometryDataSource::apply_selection_filter(MutableSpan<bool> rows_included) const +static IndexMask index_mask_from_bool_array(const VArray<bool> &selection, + Vector<int64_t> &indices) +{ + for (const int i : selection.index_range()) { + if (selection[i]) { + indices.append(i); + } + } + return IndexMask(indices); +} + +IndexMask GeometryDataSource::apply_selection_filter(Vector<int64_t> &indices) const { std::lock_guard lock{mutex_}; @@ -425,27 +210,38 @@ void GeometryDataSource::apply_selection_filter(MutableSpan<bool> rows_included) int *orig_indices = (int *)CustomData_get_layer(&mesh_eval->vdata, CD_ORIGINDEX); if (orig_indices != nullptr) { /* Use CD_ORIGINDEX layer if it exists. */ - auto is_vertex_selected = [&](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); - }; - get_selected_indices_on_domain(*mesh_eval, domain_, is_vertex_selected, rows_included); - } - else if (mesh_eval->totvert == bm->totvert) { + VArray<bool> selection = mesh_component->attribute_try_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_from_bool_array(selection, indices); + } + + if (mesh_eval->totvert == bm->totvert) { /* Use a simple heuristic to match original vertices to evaluated ones. */ - auto is_vertex_selected = [&](int vertex_index) -> bool { - BMVert *vert = bm->vtable[vertex_index]; - return BM_elem_flag_test(vert, BM_ELEM_SELECT); - }; - get_selected_indices_on_domain(*mesh_eval, domain_, is_vertex_selected, rows_included); - } + VArray<bool> selection = mesh_component->attribute_try_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_from_bool_array(selection, indices); + } + + return IndexMask(mesh_eval->totvert); } void VolumeDataSource::foreach_default_column_ids( @@ -472,50 +268,36 @@ std::unique_ptr<ColumnValues> VolumeDataSource::get_column_values( #ifdef WITH_OPENVDB const int size = this->tot_rows(); if (STREQ(column_id.name, "Grid Name")) { - return column_values_from_function( - SPREADSHEET_VALUE_TYPE_STRING, - IFACE_("Grid Name"), - size, - [volume](int index, CellValue &r_cell_value) { + return std::make_unique<ColumnValues>( + IFACE_("Grid Name"), VArray<std::string>::ForFunc(size, [volume](int64_t index) { const VolumeGrid *volume_grid = BKE_volume_grid_get_for_read(volume, index); - r_cell_value.value_string = BKE_volume_grid_name(volume_grid); - }, - 6.0f); + return BKE_volume_grid_name(volume_grid); + })); } if (STREQ(column_id.name, "Data Type")) { - return column_values_from_function( - SPREADSHEET_VALUE_TYPE_STRING, - IFACE_("Type"), - size, - [volume](int index, CellValue &r_cell_value) { + return std::make_unique<ColumnValues>( + IFACE_("Data Type"), VArray<std::string>::ForFunc(size, [volume](int64_t index) { const VolumeGrid *volume_grid = BKE_volume_grid_get_for_read(volume, index); const VolumeGridType type = BKE_volume_grid_type(volume_grid); const char *name = nullptr; RNA_enum_name_from_value(rna_enum_volume_grid_data_type_items, type, &name); - r_cell_value.value_string = IFACE_(name); - }, - 5.0f); + return IFACE_(name); + })); } if (STREQ(column_id.name, "Class")) { - return column_values_from_function( - SPREADSHEET_VALUE_TYPE_STRING, - IFACE_("Class"), - size, - [volume](int index, CellValue &r_cell_value) { + return std::make_unique<ColumnValues>( + IFACE_("Class"), VArray<std::string>::ForFunc(size, [volume](int64_t index) { const VolumeGrid *volume_grid = BKE_volume_grid_get_for_read(volume, index); openvdb::GridBase::ConstPtr grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid); openvdb::GridClass grid_class = grid->getGridClass(); if (grid_class == openvdb::GridClass::GRID_FOG_VOLUME) { - r_cell_value.value_string = IFACE_("Fog Volume"); - } - else if (grid_class == openvdb::GridClass::GRID_LEVEL_SET) { - r_cell_value.value_string = IFACE_("Level Set"); + return IFACE_("Fog Volume"); } - else { - r_cell_value.value_string = IFACE_("Unknown"); + if (grid_class == openvdb::GridClass::GRID_LEVEL_SET) { + return IFACE_("Level Set"); } - }, - 5.0f); + return IFACE_("Unknown"); + })); } #else UNUSED_VARS(column_id); |