Fix T93525: Crash with curve/text armature bone gizmo

The problem is that drw_batch_cache_generate_requested_delayed
is called on the object, which uses the original object data type to
choose which data type to get info for. So for curves and text it uses
the incorrect type (not the evaluated mesh like we hardcoded in the
armature overlay code).

To fix this I hardcoded the "delayed" generation to only use the
evaluated mesh. Luckily it wasn't use elsewhere besides this
armature overlay system. That seems like the simplest fix for
3.0. A proper solution should rewrite this whole area anyway.

Differential Revision: https://developer.blender.org/D13439
This commit is contained in:
Hans Goudey 2021-12-01 21:16:18 -05:00
parent 9cec9b4d6e
commit 594656e7a3
Notes: blender-bot 2023-02-14 06:42:54 +01:00
Referenced by issue #94886, Custom bone shape disappears if going to editmode on the custom shape object
Referenced by issue #93525, 3.0.0 crash at startup loading armature custom bone curve
4 changed files with 33 additions and 4 deletions

View File

@ -591,12 +591,16 @@ static void drw_shgroup_bone_custom_wire(ArmatureDrawContext *ctx,
const float color[4],
Object *custom)
{
/* See comments in #drw_shgroup_bone_custom_solid. */
Mesh *mesh = BKE_object_get_evaluated_mesh(custom);
if (mesh == NULL) {
return;
}
/* TODO(fclem): arg... less than ideal but we never iter on this object
* to assure batch cache is valid. */
drw_batch_cache_validate(custom);
struct GPUBatch *geom = DRW_cache_object_all_edges_get(custom);
DRW_mesh_batch_cache_validate(mesh);
struct GPUBatch *geom = DRW_mesh_batch_cache_get_all_edges(mesh);
if (geom) {
DRWCallBuffer *buf = custom_bone_instance_shgroup(ctx, ctx->custom_wire, geom);
BoneInstanceData inst_data;

View File

@ -3450,6 +3450,25 @@ void drw_batch_cache_generate_requested(Object *ob)
}
}
/* Note: Logic here is duplicated from #drw_batch_cache_generate_requested. */
void drw_batch_cache_generate_requested_evaluated_mesh(Object *ob)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene = draw_ctx->scene;
const enum eContextObjectMode mode = CTX_data_mode_enum_ex(
draw_ctx->object_edit, draw_ctx->obact, draw_ctx->object_mode);
const bool is_paint_mode = ELEM(
mode, CTX_MODE_SCULPT, CTX_MODE_PAINT_TEXTURE, CTX_MODE_PAINT_VERTEX, CTX_MODE_PAINT_WEIGHT);
const bool use_hide = ((ob->type == OB_MESH) &&
((is_paint_mode && (ob == draw_ctx->obact) &&
DRW_object_use_hide_faces(ob)) ||
((mode == CTX_MODE_EDIT_MESH) && DRW_object_is_in_edit_mode(ob))));
Mesh *mesh = BKE_object_get_evaluated_mesh(ob);
DRW_mesh_batch_cache_create_requested(DST.task_graph, ob, mesh, scene, is_paint_mode, use_hide);
}
void drw_batch_cache_generate_requested_delayed(Object *ob)
{
BLI_gset_add(DST.delayed_extraction, ob);

View File

@ -173,7 +173,8 @@ static void drw_task_graph_deinit(void)
{
BLI_task_graph_work_and_wait(DST.task_graph);
BLI_gset_free(DST.delayed_extraction, (void (*)(void *key))drw_batch_cache_generate_requested);
BLI_gset_free(DST.delayed_extraction,
(void (*)(void *key))drw_batch_cache_generate_requested_evaluated_mesh);
DST.delayed_extraction = NULL;
BLI_task_graph_work_and_wait(DST.task_graph);

View File

@ -663,7 +663,12 @@ eDRWCommandType command_type_get(const uint64_t *command_type_bits, int index);
void drw_batch_cache_validate(Object *ob);
void drw_batch_cache_generate_requested(struct Object *ob);
/**
* \warning Only evaluated mesh data is handled by this delayed generation.
*/
void drw_batch_cache_generate_requested_delayed(Object *ob);
void drw_batch_cache_generate_requested_evaluated_mesh(Object *ob);
void drw_resource_buffer_finish(DRWData *vmempool);