Fix #119586: Vertex paint mode crash after converting color attribute

Converting a color attribute to a non-color domain or type causes vertex
paint mode to try to change the attribute even though it's unsupported.
That leads to a crash here and unpredictable behavior elsewhere.

This PR modifies some poll functions to check for the proper domain and
data type before continuing. Even if converting an attribute properly
updates the active color attribute, we can still run into situations where
the active name references an attribute with incorrect metadata.

Pull Request: https://projects.blender.org/blender/blender/pulls/119657
This commit is contained in:
Hans Goudey 2024-03-19 19:49:00 +01:00 committed by Hans Goudey
parent ab9f9930b5
commit 3641b4b884
2 changed files with 29 additions and 5 deletions

View File

@ -437,8 +437,15 @@ bool ED_mesh_color_ensure(Mesh *mesh, const char *name)
{
using namespace blender;
BLI_assert(mesh->edit_mesh == nullptr);
if (mesh->attributes().contains(mesh->active_color_attribute)) {
return true;
const bke::AttributeAccessor attributes = mesh->attributes();
if (const std::optional<bke::AttributeMetaData> meta_data = attributes.lookup_meta_data(
mesh->active_color_attribute))
{
if ((ATTR_DOMAIN_AS_MASK(meta_data->domain) & ATTR_DOMAIN_MASK_COLOR) &&
(CD_TYPE_AS_MASK(meta_data->data_type) & CD_MASK_COLOR_ALL))
{
return true;
}
}
const std::string unique_name = BKE_id_attribute_calc_unique_name(mesh->id, name);

View File

@ -597,6 +597,24 @@ void smooth_brush_toggle_on(const bContext *C, Paint *paint, StrokeCache *cache)
/** \} */
} // namespace blender::ed::sculpt_paint::vwpaint
static bool color_attribute_supported(const std::optional<bke::AttributeMetaData> meta_data)
{
if (!meta_data) {
return false;
}
if (!(ATTR_DOMAIN_AS_MASK(meta_data->domain) & ATTR_DOMAIN_MASK_COLOR) ||
!(CD_TYPE_AS_MASK(meta_data->data_type) & CD_MASK_COLOR_ALL))
{
return false;
}
return true;
}
static bool color_attribute_supported(const Mesh &mesh, const StringRef name)
{
return color_attribute_supported(mesh.attributes().lookup_meta_data(name));
}
bool vertex_paint_mode_poll(bContext *C)
{
const Object *ob = CTX_data_active_object(C);
@ -609,7 +627,7 @@ bool vertex_paint_mode_poll(bContext *C)
return false;
}
if (!mesh->attributes().contains(mesh->active_color_attribute)) {
if (!color_attribute_supported(*mesh, mesh->active_color_attribute)) {
return false;
}
@ -991,8 +1009,7 @@ static bool vpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo
const std::optional<bke::AttributeMetaData> meta_data = *mesh->attributes().lookup_meta_data(
mesh->active_color_attribute);
if (!meta_data) {
if (!color_attribute_supported(meta_data)) {
return false;
}