T54983: Bone selection overlay
Bone selection overlay is only available in pose mode. and when active overrules the selection buffer. This is currently `tricked` by switching the draw engines, but this is an exception. Not sure how to solve this in a better way. After this is solved we can look at how to localize the dim effect to only the objects connected to the active armatures. Currently it dims the whole screen (including background). @campbellbarton I added you as reviewer as it you have done a lot in the DRW_draw_select_loop Reviewers: campbellbarton, fclem Reviewed By: fclem Subscribers: campbellbarton Tags: #bf_blender_2.8, #code_quest Maniphest Tasks: T54983 Differential Revision: https://developer.blender.org/D3241
This commit is contained in:
parent
266638d783
commit
6d155dc462
Notes:
blender-bot
2023-02-13 15:19:58 +01:00
Referenced by issue #98456, Eydropper selection of custom bone shape do not work for 3D view with Xray
|
@ -3656,6 +3656,7 @@ class VIEW3D_PT_overlay(Panel):
|
|||
col = layout.column()
|
||||
col.active = display_all
|
||||
col.prop(overlay, "transparent_bones")
|
||||
col.prop(overlay, "show_bone_selection")
|
||||
|
||||
elif context.mode == 'EDIT_ARMATURE':
|
||||
col.separator()
|
||||
|
|
|
@ -423,6 +423,7 @@ bool modifiers_isClothEnabled(struct Object *ob);
|
|||
bool modifiers_isParticleEnabled(struct Object *ob);
|
||||
|
||||
struct Object *modifiers_isDeformedByArmature(struct Object *ob);
|
||||
struct Object *modifiers_isDeformedByMeshDeform(struct Object *ob);
|
||||
struct Object *modifiers_isDeformedByLattice(struct Object *ob);
|
||||
struct Object *modifiers_isDeformedByCurve(struct Object *ob);
|
||||
bool modifiers_usesArmature(struct Object *ob, struct bArmature *arm);
|
||||
|
|
|
@ -627,6 +627,27 @@ Object *modifiers_isDeformedByArmature(Object *ob)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
Object *modifiers_isDeformedByMeshDeform(Object *ob)
|
||||
{
|
||||
VirtualModifierData virtualModifierData;
|
||||
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
|
||||
MeshDeformModifierData *mdmd = NULL;
|
||||
|
||||
/* return the first selected armature, this lets us use multiple armatures */
|
||||
for (; md; md = md->next) {
|
||||
if (md->type == eModifierType_MeshDeform) {
|
||||
mdmd = (MeshDeformModifierData *) md;
|
||||
if (mdmd->object && (mdmd->object->flag & SELECT))
|
||||
return mdmd->object;
|
||||
}
|
||||
}
|
||||
|
||||
if (mdmd) /* if were still here then return the last armature */
|
||||
return mdmd->object;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Takes an object and returns its first selected lattice, else just its lattice
|
||||
* This should work for multiple lattices per object
|
||||
*/
|
||||
|
|
|
@ -1570,6 +1570,15 @@ void DRW_draw_select_loop(
|
|||
obedit_mode = CTX_MODE_EDIT_ARMATURE;
|
||||
}
|
||||
}
|
||||
bool use_bone_selection_overlay = false;
|
||||
if (v3d->overlay.flag &= V3D_OVERLAY_BONE_SELECTION) {
|
||||
if (!(v3d->flag2 &= V3D_RENDER_OVERRIDE)) {
|
||||
Object *obpose = OBPOSE_FROM_OBACT(obact);
|
||||
if (obpose) {
|
||||
use_bone_selection_overlay = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct GPUViewport *viewport = GPU_viewport_create();
|
||||
GPU_viewport_size_set(viewport, (const int[2]){BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)});
|
||||
|
@ -1584,8 +1593,17 @@ void DRW_draw_select_loop(
|
|||
drw_engines_enable_from_mode(obedit_mode);
|
||||
}
|
||||
else {
|
||||
drw_engines_enable_basic();
|
||||
drw_engines_enable_from_object_mode();
|
||||
/* when in pose mode and overlays enable and bone selection overlay
|
||||
active, switch order as the bone selection must have more precedence
|
||||
than the rest of the scene */
|
||||
if (use_bone_selection_overlay) {
|
||||
drw_engines_enable_from_object_mode();
|
||||
drw_engines_enable_basic();
|
||||
}
|
||||
else {
|
||||
drw_engines_enable_basic();
|
||||
drw_engines_enable_from_object_mode();
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup viewport */
|
||||
|
|
|
@ -22,10 +22,13 @@
|
|||
/** \file blender/draw/modes/pose_mode.c
|
||||
* \ingroup draw
|
||||
*/
|
||||
#include "BKE_modifier.h"
|
||||
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
#include "DRW_engine.h"
|
||||
#include "DRW_render.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
|
||||
/* If builtin shaders are needed */
|
||||
#include "GPU_shader.h"
|
||||
|
@ -50,6 +53,7 @@ typedef struct POSE_PassList {
|
|||
struct DRWPass *bone_envelope;
|
||||
struct DRWPass *bone_axes;
|
||||
struct DRWPass *relationship;
|
||||
struct DRWPass *bone_selection;
|
||||
} POSE_PassList;
|
||||
|
||||
typedef struct POSE_StorageList {
|
||||
|
@ -67,10 +71,33 @@ typedef struct POSE_Data {
|
|||
/* *********** STATIC *********** */
|
||||
|
||||
typedef struct POSE_PrivateData {
|
||||
char pad; /* UNUSED */
|
||||
DRWShadingGroup *bone_selection_shgrp;
|
||||
} POSE_PrivateData; /* Transient data */
|
||||
|
||||
static struct {
|
||||
struct GPUShader *bone_selection_sh;
|
||||
} e_data = {NULL};
|
||||
|
||||
static float blend_color[4] = {0.0, 0.0, 0.0, 0.5};
|
||||
|
||||
/* *********** FUNCTIONS *********** */
|
||||
static bool POSE_is_bone_selection_overlay_active(void)
|
||||
{
|
||||
const DRWContextState *dcs = DRW_context_state_get();
|
||||
const View3D *v3d = dcs->v3d;
|
||||
return v3d && (v3d->overlay.flag & V3D_OVERLAY_BONE_SELECTION);
|
||||
}
|
||||
|
||||
static void POSE_engine_init(void *UNUSED(vedata))
|
||||
{
|
||||
if (!e_data.bone_selection_sh) {
|
||||
e_data.bone_selection_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
static void POSE_engine_free(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* Here init all passes and shading groups
|
||||
* Assume that all Passes are NULL */
|
||||
|
@ -120,12 +147,42 @@ static void POSE_cache_init(void *vedata)
|
|||
DRW_STATE_BLEND | DRW_STATE_WIRE;
|
||||
psl->relationship = DRW_pass_create("Bone Relationship Pass", state);
|
||||
}
|
||||
|
||||
{
|
||||
if (POSE_is_bone_selection_overlay_active()) {
|
||||
DRWShadingGroup *grp;
|
||||
psl->bone_selection = DRW_pass_create("Bone Selection", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND);
|
||||
grp = DRW_shgroup_create(e_data.bone_selection_sh, psl->bone_selection);
|
||||
DRW_shgroup_uniform_vec4(grp, "color", blend_color, 1);
|
||||
stl->g_data->bone_selection_shgrp = grp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool POSE_is_driven_by_active_armature(Object *ob)
|
||||
{
|
||||
Object *armature = modifiers_isDeformedByArmature(ob);
|
||||
if (armature) {
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
bool is_active = DRW_pose_mode_armature(armature, draw_ctx->obact);
|
||||
if (!is_active && armature->proxy_from) {
|
||||
is_active = DRW_pose_mode_armature(armature->proxy_from, draw_ctx->obact);
|
||||
}
|
||||
return is_active;
|
||||
} else {
|
||||
Object *meshDeform = modifiers_isDeformedByMeshDeform(ob);
|
||||
if (meshDeform) {
|
||||
return POSE_is_driven_by_active_armature(meshDeform);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Add geometry to shading groups. Execute for each objects */
|
||||
static void POSE_cache_populate(void *vedata, Object *ob)
|
||||
{
|
||||
POSE_PassList *psl = ((POSE_Data *)vedata)->psl;
|
||||
POSE_StorageList *stl = ((POSE_Data *)vedata)->stl;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
|
||||
/* In the future this will allow us to implement face manipulators,
|
||||
|
@ -143,6 +200,11 @@ static void POSE_cache_populate(void *vedata, Object *ob)
|
|||
};
|
||||
DRW_shgroup_armature_pose(ob, passes);
|
||||
}
|
||||
} else if (ob->type == OB_MESH && POSE_is_bone_selection_overlay_active() && POSE_is_driven_by_active_armature(ob)) {
|
||||
struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob);
|
||||
if (geom) {
|
||||
DRW_shgroup_call_object_add(stl->g_data->bone_selection_shgrp, geom, ob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,6 +240,14 @@ static void POSE_draw_scene(void *vedata)
|
|||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
const bool transparent_bones = (draw_ctx->v3d->overlay.arm_flag & V3D_OVERLAY_ARM_TRANSP_BONES) != 0;
|
||||
const bool bone_selection_overlay = POSE_is_bone_selection_overlay_active();
|
||||
|
||||
if(bone_selection_overlay) {
|
||||
GPU_framebuffer_bind(dfbl->default_fb);
|
||||
DRW_draw_pass(psl->bone_selection);
|
||||
GPU_framebuffer_clear_depth(dfbl->depth_only_fb, 1.0);
|
||||
GPU_framebuffer_bind(dfbl->default_fb);
|
||||
}
|
||||
|
||||
DRW_draw_pass(psl->bone_envelope);
|
||||
|
||||
|
@ -228,8 +298,8 @@ DrawEngineType draw_engine_pose_type = {
|
|||
NULL, NULL,
|
||||
N_("PoseMode"),
|
||||
&POSE_data_size,
|
||||
NULL,
|
||||
NULL,
|
||||
&POSE_engine_init,
|
||||
&POSE_engine_free,
|
||||
&POSE_cache_init,
|
||||
&POSE_cache_populate,
|
||||
NULL,
|
||||
|
|
|
@ -137,6 +137,7 @@ void POSE_OT_rotation_mode_set(struct wmOperatorType *ot);
|
|||
void POSE_OT_quaternions_flip(struct wmOperatorType *ot);
|
||||
|
||||
void POSE_OT_bone_layers(struct wmOperatorType *ot);
|
||||
void POSE_OT_toggle_bone_selection_overlay(struct wmOperatorType *ot);
|
||||
|
||||
/* ******************************************************* */
|
||||
/* Pose Tool Utilities (for PoseLib, Pose Sliding, etc.) */
|
||||
|
|
|
@ -131,6 +131,8 @@ void ED_operatortypes_armature(void)
|
|||
WM_operatortype_append(POSE_OT_quaternions_flip);
|
||||
|
||||
WM_operatortype_append(POSE_OT_bone_layers);
|
||||
|
||||
WM_operatortype_append(POSE_OT_toggle_bone_selection_overlay);
|
||||
|
||||
WM_operatortype_append(POSE_OT_propagate);
|
||||
|
||||
|
@ -363,6 +365,7 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
|
|||
WM_keymap_add_item(keymap, "ARMATURE_OT_layers_show_all", ACCENTGRAVEKEY, KM_PRESS, KM_CTRL, 0);
|
||||
WM_keymap_add_item(keymap, "ARMATURE_OT_armature_layers", MKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
WM_keymap_add_item(keymap, "POSE_OT_bone_layers", MKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "POSE_OT_toggle_bone_selection_overlay", ZKEY, KM_PRESS, 0, 0);
|
||||
|
||||
/* special transforms: */
|
||||
/* 1) envelope/b-bone size */
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#include "ED_keyframing.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_object.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
|
||||
|
@ -1240,3 +1241,34 @@ void POSE_OT_quaternions_flip(wmOperatorType *ot)
|
|||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Toggle Bone selection Overlay Operator
|
||||
* \{ */
|
||||
|
||||
static int toggle_bone_selection_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
v3d->overlay.flag ^= V3D_OVERLAY_BONE_SELECTION;
|
||||
ED_view3d_shade_update(CTX_data_main(C), v3d, CTX_wm_area(C));
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int pose_select_linked_poll(bContext *C)
|
||||
{
|
||||
return (ED_operator_view3d_active(C) && ED_operator_posemode(C));
|
||||
}
|
||||
|
||||
void POSE_OT_toggle_bone_selection_overlay(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Toggle Bone Selection Overlay";
|
||||
ot->description = "Toggle bone selection overlay of the viewport";
|
||||
ot->idname = "POSE_OT_toggle_bone_selection_overlay";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = toggle_bone_selection_exec;
|
||||
ot->poll = pose_select_linked_poll;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -1678,6 +1678,8 @@ extern const char *RE_engine_id_CYCLES;
|
|||
(((workspace)->object_mode & OD_MODE_EDIT) ? OBACT(_view_layer) : NULL)
|
||||
#define OBEDIT_FROM_OBACT(ob) \
|
||||
((ob) ? (((ob)->mode & OB_MODE_EDIT) ? ob : NULL) : NULL)
|
||||
#define OBPOSE_FROM_OBACT(ob) \
|
||||
((ob) ? (((ob)->mode & OB_MODE_POSE) ? ob : NULL) : NULL)
|
||||
#define OBEDIT_FROM_VIEW_LAYER(view_layer) \
|
||||
OBEDIT_FROM_OBACT(OBACT(view_layer))
|
||||
|
||||
|
|
|
@ -346,6 +346,7 @@ enum {
|
|||
enum {
|
||||
V3D_OVERLAY_FACE_ORIENTATION = (1 << 0),
|
||||
V3D_OVERLAY_HIDE_CURSOR = (1 << 1),
|
||||
V3D_OVERLAY_BONE_SELECTION = (1 << 2),
|
||||
};
|
||||
|
||||
/* View3DOverlay->edit_flag */
|
||||
|
|
|
@ -2323,6 +2323,12 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Face Orientation", "Show the Face Orientation Overlay");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "show_bone_selection", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_BONE_SELECTION);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Bone Selection", "Show the Bone Selection Overlay");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "show_paint_wire", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "overlay.paint_flag", V3D_OVERLAY_PAINT_WIRE);
|
||||
RNA_def_property_ui_text(prop, "Show Wire", "Use wireframe display in painting modes");
|
||||
|
|
Loading…
Reference in New Issue