From 75162ab8c23937fce64e7b2674cc706a008ded96 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Tue, 31 May 2022 15:46:09 -0700 Subject: Fix T97408: Temporary fix for attribute convert undo Sculpt undo now detects if an attribute layer has changed type/domain and unconverts it back. This is a temporary workaround to a more fundamental bug in the undo system. Memfile undo assumes it can always rebuild the application state from the prior undo step, which isn't true with incremental undo systems. The correct fix is to push an extra undo step prior to running an operator if an incremental undo system is active and the operator is using memfile undo. --- .../editors/geometry/geometry_attributes.cc | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'source/blender/editors/geometry') diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index 05f9e19da71..17784a50bca 100644 --- a/source/blender/editors/geometry/geometry_attributes.cc +++ b/source/blender/editors/geometry/geometry_attributes.cc @@ -33,6 +33,7 @@ #include "UI_interface.h" #include "UI_resources.h" +#include "ED_geometry.h" #include "ED_object.h" #include "geometry_intern.hh" @@ -580,3 +581,38 @@ void GEOMETRY_OT_attribute_convert(wmOperatorType *ot) } } // namespace blender::ed::geometry + +using blender::CPPType; +using blender::GVArray; + +bool ED_geometry_attribute_convert(Mesh *mesh, + const char *layer_name, + CustomDataType old_type, + AttributeDomain old_domain, + CustomDataType new_type, + AttributeDomain new_domain) +{ + CustomDataLayer *layer = BKE_id_attribute_find(&mesh->id, layer_name, old_type, old_domain); + const std::string name = layer->name; + + if (!layer) { + return false; + } + + MeshComponent mesh_component; + mesh_component.replace(mesh, GeometryOwnershipType::Editable); + GVArray src_varray = mesh_component.attribute_get_for_read(name, new_domain, new_type); + + const CPPType &cpp_type = src_varray.type(); + void *new_data = MEM_malloc_arrayN(src_varray.size(), cpp_type.size(), __func__); + src_varray.materialize_to_uninitialized(new_data); + mesh_component.attribute_try_delete(name); + mesh_component.attribute_try_create(name, new_domain, new_type, AttributeInitMove(new_data)); + + int *active_index = BKE_id_attributes_active_index_p(&mesh->id); + if (*active_index > 0) { + *active_index -= 1; + } + + return true; +} -- cgit v1.2.3