Fix: Avoid accessing face set with invalid index
When the PBVH is rebuilt, the `active_face_index` and `active_grid_index` fields are initialized to -1. This results in a possible segmentation fault if the `active_face_set_get` method is called without these fields being populated. This commit switches the raw `int` usage for `std::optional` to better communicate the intent of these fields. Pull Request: https://projects.blender.org/blender/blender/pulls/127959
This commit is contained in:
@@ -407,8 +407,8 @@ struct SculptSession : blender::NonCopyable, blender::NonMovable {
|
||||
blender::ed::sculpt_paint::expand::Cache *expand_cache = nullptr;
|
||||
|
||||
/* Cursor data and active vertex for tools */
|
||||
int active_face_index = -1;
|
||||
int active_grid_index = -1;
|
||||
std::optional<int> active_face_index;
|
||||
std::optional<int> active_grid_index;
|
||||
|
||||
/* When active, the cursor draws with faded colors, indicating that there is an action
|
||||
* enabled.
|
||||
|
||||
@@ -203,20 +203,20 @@ int active_face_set_get(const Object &object)
|
||||
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
|
||||
const bke::AttributeAccessor attributes = mesh.attributes();
|
||||
const VArray face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
|
||||
if (!face_sets) {
|
||||
if (!face_sets || !ss.active_face_index) {
|
||||
return SCULPT_FACE_SET_NONE;
|
||||
}
|
||||
return face_sets[ss.active_face_index];
|
||||
return face_sets[*ss.active_face_index];
|
||||
}
|
||||
case bke::pbvh::Type::Grids: {
|
||||
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
|
||||
const bke::AttributeAccessor attributes = mesh.attributes();
|
||||
const VArray face_sets = *attributes.lookup<int>(".sculpt_face_set", bke::AttrDomain::Face);
|
||||
if (!face_sets) {
|
||||
if (!face_sets || !ss.active_grid_index) {
|
||||
return SCULPT_FACE_SET_NONE;
|
||||
}
|
||||
const int face_index = BKE_subdiv_ccg_grid_to_face_index(*ss.subdiv_ccg,
|
||||
ss.active_grid_index);
|
||||
*ss.active_grid_index);
|
||||
return face_sets[face_index];
|
||||
}
|
||||
case bke::pbvh::Type::BMesh:
|
||||
@@ -4645,15 +4645,15 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
|
||||
switch (pbvh->type()) {
|
||||
case bke::pbvh::Type::Mesh:
|
||||
ss.active_face_index = srd.active_face_grid_index;
|
||||
ss.active_grid_index = 0;
|
||||
ss.active_grid_index = std::nullopt;
|
||||
break;
|
||||
case bke::pbvh::Type::Grids:
|
||||
ss.active_face_index = 0;
|
||||
ss.active_face_index = std::nullopt;
|
||||
ss.active_grid_index = srd.active_face_grid_index;
|
||||
break;
|
||||
case bke::pbvh::Type::BMesh:
|
||||
ss.active_face_index = 0;
|
||||
ss.active_grid_index = 0;
|
||||
ss.active_face_index = std::nullopt;
|
||||
ss.active_grid_index = std::nullopt;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -2273,10 +2273,16 @@ static int active_face_set_id_get(Object &object, Cache &expand_cache)
|
||||
SculptSession &ss = *object.sculpt;
|
||||
switch (bke::object::pbvh_get(object)->type()) {
|
||||
case bke::pbvh::Type::Mesh:
|
||||
return expand_cache.original_face_sets[ss.active_face_index];
|
||||
if (!ss.active_face_index) {
|
||||
return SCULPT_FACE_SET_NONE;
|
||||
}
|
||||
return expand_cache.original_face_sets[*ss.active_face_index];
|
||||
case bke::pbvh::Type::Grids: {
|
||||
if (!ss.active_grid_index) {
|
||||
return SCULPT_FACE_SET_NONE;
|
||||
}
|
||||
const int face_index = BKE_subdiv_ccg_grid_to_face_index(*ss.subdiv_ccg,
|
||||
ss.active_grid_index);
|
||||
*ss.active_grid_index);
|
||||
return expand_cache.original_face_sets[face_index];
|
||||
}
|
||||
case bke::pbvh::Type::BMesh: {
|
||||
|
||||
Reference in New Issue
Block a user