WIP: Automatic X-Ray #105783

Closed
Lukas Sneyd wants to merge 4 commits from lcas:auto-xray into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
5 changed files with 202 additions and 14 deletions

View File

@ -889,7 +889,7 @@ class VIEW3D_HT_header(Header):
sub.active = overlay.show_overlays
sub.popover(panel="VIEW3D_PT_overlay", text="")
row = layout.row()
row = layout.row(align=True)
row.active = (object_mode == 'EDIT') or (shading.type in {'WIREFRAME', 'SOLID'})
# While exposing `shading.show_xray(_wireframe)` is correct.
@ -906,6 +906,7 @@ class VIEW3D_HT_header(Header):
icon='XRAY',
depress=draw_depressed,
)
row.popover(panel="VIEW3D_PT_xray", text="")
row = layout.row(align=True)
row.prop(shading, "type", text="", expand=True)
@ -6068,17 +6069,7 @@ class VIEW3D_PT_shading_options(Panel):
row = col.row(align=True)
if shading.type == 'WIREFRAME':
row.prop(shading, "show_xray_wireframe", text="")
sub = row.row()
sub.active = shading.show_xray_wireframe
sub.prop(shading, "xray_alpha_wireframe", text="X-Ray")
elif shading.type == 'SOLID':
row.prop(shading, "show_xray", text="")
sub = row.row()
sub.active = shading.show_xray
sub.prop(shading, "xray_alpha", text="X-Ray")
# X-ray mode is off when alpha is 1.0
if shading.type == 'SOLID':
xray_active = shading.show_xray and shading.xray_alpha != 1
row = col.row(align=True)
@ -6263,6 +6254,56 @@ class VIEW3D_PT_gizmo_display(Panel):
col.prop(view, "show_gizmo_camera_dof_distance", text="Focus Distance")
class VIEW3D_PT_xray(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
bl_label = "X-Ray"
bl_ui_units_x = 13
def draw(self, context):
layout = self.layout
layout.label(text="X-Ray Settings")
shading = VIEW3D_PT_shading.get_shading(context)
col = layout.column()
row = col.row(align=True)
if shading.type == 'WIREFRAME':
row.prop(shading, "show_xray_wireframe", text="")
sub = row.row()
sub.active = shading.show_xray_wireframe
sub.prop(shading, "xray_alpha_wireframe", text="X-Ray Wireframe")
elif shading.type == 'SOLID':
row.prop(shading, "show_xray", text="")
sub = row.row()
sub.active = shading.show_xray
sub.prop(shading, "xray_alpha", text="X-Ray Solid")
class VIEW3D_PT_auto_xray(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
bl_parent_id = 'VIEW3D_PT_xray'
bl_label = "Automatic X-Ray"
bl_ui_units_x = 13
def draw(self, context):
layout = self.layout
tool_settings = context.tool_settings
row = layout.row()
row.prop(tool_settings, "auto_xray", text="Auto X-Ray")
sub = row.row()
sub.active = tool_settings.auto_xray
sub.prop(tool_settings, "auto_xray_object", text="Object")
sub.prop(tool_settings, "auto_xray_edit", text="Edit")
row = layout.row()
sub = row.row(align=True)
sub.active = tool_settings.auto_xray
sub.prop(tool_settings, "auto_xray_box", text="Box", toggle=True)
sub.prop(tool_settings, "auto_xray_lasso", text="Lasso", toggle=True)
sub.prop(tool_settings, "auto_xray_circle", text="Circle", toggle=True)
class VIEW3D_PT_overlay(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
@ -8209,6 +8250,8 @@ classes = (
VIEW3D_PT_shading_render_pass,
VIEW3D_PT_shading_compositor,
VIEW3D_PT_gizmo_display,
VIEW3D_PT_xray,
VIEW3D_PT_auto_xray,
VIEW3D_PT_overlay,
VIEW3D_PT_overlay_guides,
VIEW3D_PT_overlay_object,

View File

@ -373,6 +373,13 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
if (idprop) {
IDP_ClearProperty(idprop);
}
/* Auto X-Ray. */
ts->auto_xray_object = true;
ts->auto_xray_edit = true;
ts->auto_xray_box = true;
ts->auto_xray_lasso = true;
ts->auto_xray_circle = true;
}
void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)

View File

@ -1557,7 +1557,16 @@ typedef struct ToolSettings {
char gpencil_v3d_align;
/** General 2D Editor. */
char gpencil_v2d_align;
char _pad0[2];
/* X-Ray Options */
char auto_xray;
char auto_xray_reset;
char auto_xray_object;
char auto_xray_edit;
char auto_xray_box;
char auto_xray_lasso;
char auto_xray_circle;
char _pad0[3];
/* Annotations. */
/** Stroke placement settings - 3D View. */

View File

@ -3725,6 +3725,42 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Normal Vector", "Normal Vector used to copy, add or multiply");
RNA_def_property_ui_range(prop, -10000.0, 10000.0, 1, 3);
/* Auto X-Ray */
prop = RNA_def_property(srna, "auto_xray", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "auto_xray", 0);
RNA_def_property_ui_text(prop, "Auto X-Ray", "Transparent scene display during drag select");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "auto_xray_reset", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "auto_xray_reset", 0);
RNA_def_property_ui_text(prop, "Auto X-Ray Reset", "Helper that turns xray off for autoxray");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "auto_xray_object", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "auto_xray_object", 0);
RNA_def_property_ui_text(prop, "Auto X-Ray Object", "Automatic X-Ray in object mode");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "auto_xray_edit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "auto_xray_edit", 0);
RNA_def_property_ui_text(prop, "Auto X-Ray Edit", "Automatic X-Ray in edit mode");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "auto_xray_box", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "auto_xray_box", 0);
RNA_def_property_ui_text(prop, "Auto X-Ray Box", "Transparent scene display during box select");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "auto_xray_lasso", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "auto_xray_lasso", 0);
RNA_def_property_ui_text(prop, "Auto X-Ray Lasso", "Transparent scene display during lasso select");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "auto_xray_circle", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "auto_xray_circle", 0);
RNA_def_property_ui_text(prop, "Auto X-Ray Circle", "Transparent scene display during circle select");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
/* Unified Paint Settings */
prop = RNA_def_property(srna, "unified_paint_settings", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);

View File

@ -29,6 +29,7 @@
#include "ED_screen.h"
#include "ED_select_utils.h"
#include "ED_view3d.h"
#include "UI_interface.h"
@ -85,6 +86,18 @@ static void gesture_modal_state_to_operator(wmOperator *op, int modal_state)
}
}
static void gesture_toggle_xray(bContext *C)
{
ToolSettings *ts = CTX_data_tool_settings(C);
wmOperatorType *ot = WM_operatortype_find("VIEW3D_OT_toggle_xray", true);
BLI_assert(ot);
PointerRNA ptr;
WM_operator_properties_create_ptr(&ptr, ot);
WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr, NULL);
WM_operator_properties_free(&ptr);
ts->auto_xray_reset ^= true;
}
static int UNUSED_FUNCTION(gesture_modal_state_from_operator)(wmOperator *op)
{
PropertyRNA *prop;
@ -163,9 +176,24 @@ static bool gesture_box_apply(bContext *C, wmOperator *op)
int WM_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C);
const ARegion *region = CTX_wm_region(C);
const bool wait_for_input = !WM_event_is_mouse_drag_or_press(event) &&
RNA_boolean_get(op->ptr, "wait_for_input");
Object *obedit = CTX_data_edit_object(C);
ToolSettings *ts = win->scene->toolsettings;
const bool auto_xray = ts->auto_xray && ts->auto_xray_box ?
obedit ? ts->auto_xray_edit : ts->auto_xray_object :
false;
if (ts->auto_xray_reset) {
ts->auto_xray_reset ^= true;
}
if (v3d && auto_xray) {
if (!XRAY_FLAG_ENABLED(v3d)) {
gesture_toggle_xray(C);
}
}
if (wait_for_input) {
op->customdata = WM_gesture_new(win, region, event, WM_GESTURE_CROSS_RECT);
@ -190,8 +218,11 @@ int WM_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_box_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C);
wmGesture *gesture = op->customdata;
rcti *rect = gesture->customdata;
Object *obedit = CTX_data_edit_object(C);
ToolSettings *ts = win->scene->toolsettings;
if (event->type == EVT_MODAL_MAP) {
switch (event->val) {
@ -214,13 +245,22 @@ int WM_gesture_box_modal(bContext *C, wmOperator *op, const wmEvent *event)
gesture->modal_state = event->val;
}
if (gesture_box_apply(C, op)) {
if (ts->auto_xray_reset) {
gesture_toggle_xray(C);
}
gesture_modal_end(C, op);
return OPERATOR_FINISHED;
}
if (ts->auto_xray_reset) {
gesture_toggle_xray(C);
}
gesture_modal_end(C, op);
return OPERATOR_CANCELLED;
}
case GESTURE_MODAL_CANCEL: {
if (ts->auto_xray_reset) {
gesture_toggle_xray(C);
}
gesture_modal_end(C, op);
return OPERATOR_CANCELLED;
}
@ -286,8 +326,24 @@ static void gesture_circle_apply(bContext *C, wmOperator *op);
int WM_gesture_circle_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C);
const bool wait_for_input = !WM_event_is_mouse_drag_or_press(event) &&
RNA_boolean_get(op->ptr, "wait_for_input");
Object *obedit = CTX_data_edit_object(C);
ToolSettings *ts = win->scene->toolsettings;
const bool auto_xray = ts->auto_xray && ts->auto_xray_circle ?
obedit ? ts->auto_xray_edit : ts->auto_xray_object :
false;
if (ts->auto_xray_reset) {
ts->auto_xray_reset ^= true;
}
if (v3d && auto_xray) {
if (!XRAY_FLAG_ENABLED(v3d)) {
gesture_toggle_xray(C);
}
}
op->customdata = WM_gesture_new(win, CTX_wm_region(C), event, WM_GESTURE_CIRCLE);
wmGesture *gesture = op->customdata;
@ -345,11 +401,14 @@ static void gesture_circle_apply(bContext *C, wmOperator *op)
int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C);
wmGesture *gesture = op->customdata;
rcti *rect = gesture->customdata;
if (event->type == MOUSEMOVE) {
Object *obedit = CTX_data_edit_object(C);
ToolSettings *ts = win->scene->toolsettings;
if (event->type == MOUSEMOVE) {
rect->xmin = event->xy[0] - gesture->winrct.xmin;
rect->ymin = event->xy[1] - gesture->winrct.ymin;
@ -415,6 +474,9 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
if (is_finished) {
if (ts->auto_xray_reset) {
gesture_toggle_xray(C);
}
gesture_modal_end(C, op);
return OPERATOR_FINISHED; /* use finish or we don't get an undo */
}
@ -477,7 +539,23 @@ void WM_OT_circle_gesture(wmOperatorType *ot)
int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
View3D *v3d = CTX_wm_view3d(C);
PropertyRNA *prop;
Object *obedit = CTX_data_edit_object(C);
ToolSettings *ts = win->scene->toolsettings;
const bool auto_xray = ts->auto_xray && ts->auto_xray_lasso ?
obedit ? ts->auto_xray_edit : ts->auto_xray_object :
false;
if (ts->auto_xray_reset) {
ts->auto_xray_reset ^= true;
}
if (v3d && auto_xray) {
if (!XRAY_FLAG_ENABLED(v3d)) {
gesture_toggle_xray(C);
}
}
op->customdata = WM_gesture_new(win, CTX_wm_region(C), event, WM_GESTURE_LASSO);
@ -517,6 +595,10 @@ static int gesture_lasso_apply(bContext *C, wmOperator *op)
int retval = OPERATOR_FINISHED;
wmGesture *gesture = op->customdata;
PointerRNA itemptr;
View3D *v3d = CTX_wm_view3d(C);
Object *obedit = CTX_data_edit_object(C);
wmWindow *win = CTX_wm_window(C);
ToolSettings *ts = win->scene->toolsettings;
float loc[2];
int i;
const short *lasso = gesture->customdata;
@ -538,12 +620,20 @@ static int gesture_lasso_apply(bContext *C, wmOperator *op)
OPERATOR_RETVAL_CHECK(retval);
}
if (ts->auto_xray_reset) {
gesture_toggle_xray(C);
}
return retval;
}
int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmGesture *gesture = op->customdata;
View3D *v3d = CTX_wm_view3d(C);
Object *obedit = CTX_data_edit_object(C);
wmWindow *win = CTX_wm_window(C);
ToolSettings *ts = win->scene->toolsettings;
if (event->type == EVT_MODAL_MAP) {
switch (event->val) {
@ -597,6 +687,9 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
break;
}
case EVT_ESCKEY: {
if (ts->auto_xray_reset) {
gesture_toggle_xray(C);
}
gesture_modal_end(C, op);
return OPERATOR_CANCELLED;
}