From a07089dcb10d8f0265220bf5abe07dca03097fe1 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 24 Nov 2021 10:39:33 -0500 Subject: Fix T92120 (partially): No bone custom shape with curve object meshes This part of the drawing code assumes that the bone custom object has only one evaluated geometry component, and it also uses the object type to check which data to draw, with the functions like `DRW_cache_object_surface_get` that just take an object input. Those functions usually work on evaluated objects, which use the instancing system to access a temporary object with `object.data` replaced for data types that don't match the original object. That assumption used to work, but now curve, point cloud, or volume objects can have an evaluated mesh which is not accessed with the same object for render engine drawing. The "correct" solution for the way this code is structured would be to loop through all of the geometry components and try to get GPU batches from every one of them. However, that significantly increases complexity in an area that should probably be refactored anyway. This patch treats the mesh as a special case, and only draws the evaluated mesh. The **best** solution in my opinion might be refactoring this area to use the instancing system with some sort of viewport-only flag so the custom shape instances aren't added in the render. The solution is "partial" because the "Wireframe" option only works for meshes from mesh objects, even after this fix, and because other data besides meshes is not displayed at all. Differential Revision: https://developer.blender.org/D13038 --- .../blender/draw/engines/overlay/overlay_armature.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/source/blender/draw/engines/overlay/overlay_armature.c b/source/blender/draw/engines/overlay/overlay_armature.c index 1da682ff01b..50d8fe3065d 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.c +++ b/source/blender/draw/engines/overlay/overlay_armature.c @@ -26,6 +26,7 @@ #include "DNA_armature_types.h" #include "DNA_constraint_types.h" +#include "DNA_mesh_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_view3d_types.h" @@ -39,6 +40,7 @@ #include "BKE_armature.h" #include "BKE_deform.h" #include "BKE_modifier.h" +#include "BKE_object.h" #include "DEG_depsgraph_query.h" @@ -52,6 +54,8 @@ #include "overlay_private.h" +#include "draw_cache_impl.h" + #define BONE_VAR(eBone, pchan, var) ((eBone) ? (eBone->var) : (pchan->var)) #define BONE_FLAG(eBone, pchan) ((eBone) ? (eBone->flag) : (pchan->bone->flag)) @@ -535,13 +539,22 @@ static void drw_shgroup_bone_custom_solid(ArmatureDrawContext *ctx, const float outline_color[4], Object *custom) { + /* The custom object is not an evaluated object, so its object->data field hasn't been replaced + * by #data_eval. This is bad since it gives preference to an object's evaluated mesh over any + * other data type, but supporting all evaluated geometry components would require a much larger + * refactor of this area. */ + 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); + DRW_mesh_batch_cache_validate(mesh); - struct GPUBatch *surf = DRW_cache_object_surface_get(custom); - struct GPUBatch *edges = DRW_cache_object_edge_detection_get(custom, NULL); - struct GPUBatch *ledges = DRW_cache_object_loose_edges_get(custom); + struct GPUBatch *surf = DRW_mesh_batch_cache_get_surface(mesh); + struct GPUBatch *edges = DRW_mesh_batch_cache_get_edge_detection(mesh, NULL); + struct GPUBatch *ledges = DRW_mesh_batch_cache_get_loose_edges(mesh); BoneInstanceData inst_data; DRWCallBuffer *buf; -- cgit v1.2.3