diff options
author | Joseph Eagar <joeedh@gmail.com> | 2022-06-01 02:35:22 +0300 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2022-06-01 02:35:22 +0300 |
commit | b38a59881be863bff079b4600a08d6b3a8b4b59a (patch) | |
tree | 713fb7596630d92631b459fe5072b64e3eec1644 /source/blender/editors | |
parent | 79cee340a8af413822e752057b71bf0c91e6e40c (diff) | |
parent | 6cee4049143abf692af6ffb78c109fb0760fe67d (diff) |
Merge branch 'blender-v3.2-release'
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/geometry/geometry_attributes.cc | 36 | ||||
-rw-r--r-- | source/blender/editors/include/ED_geometry.h | 12 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_undo.c | 19 |
3 files changed, 66 insertions, 1 deletions
diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index ed16b8a903a..814c2639169 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" @@ -572,3 +573,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; +} diff --git a/source/blender/editors/include/ED_geometry.h b/source/blender/editors/include/ED_geometry.h index 74ff968828c..46e6904523a 100644 --- a/source/blender/editors/include/ED_geometry.h +++ b/source/blender/editors/include/ED_geometry.h @@ -7,12 +7,22 @@ #pragma once +#include "BKE_attribute.h" +#include "DNA_customdata_types.h" + #ifdef __cplusplus extern "C" { #endif -void ED_operatortypes_geometry(void); +struct Mesh; +void ED_operatortypes_geometry(void); +bool ED_geometry_attribute_convert(struct Mesh *mesh, + const char *layer_name, + CustomDataType old_type, + AttributeDomain old_domain, + CustomDataType new_type, + AttributeDomain new_domain); #ifdef __cplusplus } #endif diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index 1fee20444e7..4588930bdee 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -50,6 +50,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "ED_geometry.h" #include "ED_object.h" #include "ED_sculpt.h" #include "ED_undo.h" @@ -1565,6 +1566,24 @@ static void sculpt_undo_set_active_layer(struct bContext *C, SculptAttrRef *attr CustomDataLayer *layer; layer = BKE_id_attribute_find(&me->id, attr->name, attr->type, attr->domain); + /* Temporary fix for T97408. This is a fundamental + * bug in the undo stack; the operator code needs to push + * an extra undo step before running an operator if a + * non-memfile undo system is active. + * + * For now, detect if the layer does exist but with a different + * domain and just unconvert it. + */ + if (!layer) { + layer = BKE_id_attribute_search(&me->id, attr->name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL); + AttributeDomain domain = layer ? BKE_id_attribute_domain(&me->id, layer) : ATTR_DOMAIN_NUM; + + if (layer && ED_geometry_attribute_convert( + me, attr->name, layer->type, domain, attr->type, attr->domain)) { + layer = BKE_id_attribute_find(&me->id, attr->name, attr->type, attr->domain); + } + } + if (!layer) { /* Memfile undo killed the layer; re-create it. */ CustomData *cdata = attr->domain == ATTR_DOMAIN_POINT ? &me->vdata : &me->ldata; |