XR: Add object extras, object types visibility session options

This allows object extras such as image-empties to be shown in the VR
viewport/headset display. Being able to see reference images in VR can
be useful for architectural walkthroughs and 3D modeling applications.

Since users may not want to see all object extras (lights, cameras,
etc.), per-object-type visibility settings are also added as session
options.

By slightly refactoring the definition of the 3D View object types
visibility panel (note: no functional changes), the VR Scene Inspection
add-on can show a similar panel without duplicating code. When VR
selection is possible in the future, the object type select options can
also be enabled.

Reviewed By: Severin

Differential Revision: https://developer.blender.org/D14220
This commit is contained in:
Peter Kim 2022-04-30 16:23:43 +09:00
parent 2fc6563a59
commit 5c92c04518
11 changed files with 162 additions and 77 deletions

View File

@ -5684,13 +5684,14 @@ class VIEW3D_PT_object_type_visibility(Panel):
bl_label = "View Object Types"
bl_ui_units_x = 7
def draw(self, context):
# Allows derived classes to pass view data other than context.space_data.
# This is used by the official VR add-on, which passes XrSessionSettings
# since VR has a 3D view that only exists for the duration of the VR session.
def draw_ex(self, context, view, show_select):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
view = context.space_data
layout.label(text="Object Types Visibility")
layout.separator()
col = layout.column()
@ -5728,19 +5729,25 @@ class VIEW3D_PT_object_type_visibility(Panel):
continue
attr_v = "show_object_viewport_" + attr
attr_s = "show_object_select_" + attr
icon_v = 'HIDE_OFF' if getattr(view, attr_v) else 'HIDE_ON'
icon_s = 'RESTRICT_SELECT_OFF' if getattr(view, attr_s) else 'RESTRICT_SELECT_ON'
row = col.row(align=True)
row.alignment = 'RIGHT'
row.label(text=attr_name)
row.prop(view, attr_v, text="", icon=icon_v, emboss=False)
rowsub = row.row(align=True)
rowsub.active = getattr(view, attr_v)
rowsub.prop(view, attr_s, text="", icon=icon_s, emboss=False)
if show_select:
attr_s = "show_object_select_" + attr
icon_s = 'RESTRICT_SELECT_OFF' if getattr(view, attr_s) else 'RESTRICT_SELECT_ON'
rowsub = row.row(align=True)
rowsub.active = getattr(view, attr_v)
rowsub.prop(view, attr_s, text="", icon=icon_s, emboss=False)
def draw(self, context):
view = context.space_data
self.draw_ex(context, view, True)
class VIEW3D_PT_shading(Panel):

View File

@ -49,6 +49,8 @@ void ED_view3d_draw_offscreen_simple(struct Depsgraph *depsgraph,
struct Scene *scene,
struct View3DShading *shading_override,
eDrawType drawtype,
int object_type_exclude_viewport_override,
int object_type_exclude_select_override,
int winx,
int winy,
unsigned int draw_flags,

View File

@ -1723,6 +1723,8 @@ void ED_view3d_draw_offscreen_simple(Depsgraph *depsgraph,
Scene *scene,
View3DShading *shading_override,
eDrawType drawtype,
int object_type_exclude_viewport_override,
int object_type_exclude_select_override,
int winx,
int winy,
uint draw_flags,
@ -1785,7 +1787,10 @@ void ED_view3d_draw_offscreen_simple(Depsgraph *depsgraph,
/* Disable other overlays (set all available _HIDE_ flags). */
v3d.overlay.flag |= V3D_OVERLAY_HIDE_CURSOR | V3D_OVERLAY_HIDE_TEXT |
V3D_OVERLAY_HIDE_MOTION_PATHS | V3D_OVERLAY_HIDE_BONES |
V3D_OVERLAY_HIDE_OBJECT_XTRAS | V3D_OVERLAY_HIDE_OBJECT_ORIGINS;
V3D_OVERLAY_HIDE_OBJECT_ORIGINS;
if ((draw_flags & V3D_OFSDRAW_SHOW_OBJECT_EXTRAS) == 0) {
v3d.overlay.flag |= V3D_OVERLAY_HIDE_OBJECT_XTRAS;
}
v3d.flag |= V3D_HIDE_HELPLINES;
}
@ -1793,6 +1798,9 @@ void ED_view3d_draw_offscreen_simple(Depsgraph *depsgraph,
v3d.flag |= V3D_XR_SESSION_SURFACE;
}
v3d.object_type_exclude_viewport = object_type_exclude_viewport_override;
v3d.object_type_exclude_select = object_type_exclude_select_override;
rv3d.persp = RV3D_PERSP;
v3d.clip_start = clip_start;
v3d.clip_end = clip_end;

View File

@ -19,6 +19,7 @@ typedef enum eV3DOffscreenDrawFlag {
V3D_OFSDRAW_SHOW_SELECTION = (1 << 3),
V3D_OFSDRAW_XR_SHOW_CONTROLLERS = (1 << 4),
V3D_OFSDRAW_XR_SHOW_CUSTOM_OVERLAYS = (1 << 5),
V3D_OFSDRAW_SHOW_OBJECT_EXTRAS = (1 << 6),
} eV3DOffscreenDrawFlag;
/** #View3DShading.light */

View File

@ -36,6 +36,10 @@ typedef struct XrSessionSettings {
float clip_start, clip_end;
int flag;
/** Object type settings to apply to VR view (unlike shading, not shared with window 3D-View). */
int object_type_exclude_viewport;
int object_type_exclude_select;
} XrSessionSettings;
typedef enum eXrSessionFlag {

View File

@ -318,6 +318,10 @@ void rna_object_vcollayer_name_set(struct PointerRNA *ptr,
PointerRNA rna_object_shapekey_index_get(struct ID *id, int value);
int rna_object_shapekey_index_set(struct ID *id, PointerRNA value, int current);
void rna_def_object_type_visibility_flags_common(StructRNA *srna, int noteflag);
int rna_object_type_visibility_icon_get_common(int object_type_exclude_viewport,
const int *object_type_exclude_select);
/* ViewLayer related functions defined in rna_scene.c but required in rna_layer.c */
void rna_def_freestyle_settings(struct BlenderRNA *brna);
struct PointerRNA rna_FreestyleLineSet_linestyle_get(struct PointerRNA *ptr);

View File

@ -1515,12 +1515,8 @@ static void rna_SpaceView3D_mirror_xr_session_update(Main *main,
static int rna_SpaceView3D_icon_from_show_object_viewport_get(PointerRNA *ptr)
{
const View3D *v3d = (View3D *)ptr->data;
/* Ignore selection values when view is off,
* intent is to show if visible objects aren't selectable. */
const int view_value = (v3d->object_type_exclude_viewport != 0);
const int select_value = (v3d->object_type_exclude_select &
~v3d->object_type_exclude_viewport) != 0;
return ICON_VIS_SEL_11 + (view_value << 1) + select_value;
return rna_object_type_visibility_icon_get_common(v3d->object_type_exclude_viewport,
&v3d->object_type_exclude_select);
}
static char *rna_View3DShading_path(PointerRNA *UNUSED(ptr))
@ -4997,68 +4993,15 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_update(
prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_SpaceView3D_mirror_xr_session_update");
{
struct {
const char *name;
int type_mask;
const char *identifier[2];
} info[] = {
{"Mesh", (1 << OB_MESH), {"show_object_viewport_mesh", "show_object_select_mesh"}},
{"Curve",
(1 << OB_CURVES_LEGACY),
{"show_object_viewport_curve", "show_object_select_curve"}},
{"Surface", (1 << OB_SURF), {"show_object_viewport_surf", "show_object_select_surf"}},
{"Meta", (1 << OB_MBALL), {"show_object_viewport_meta", "show_object_select_meta"}},
{"Font", (1 << OB_FONT), {"show_object_viewport_font", "show_object_select_font"}},
{"Hair Curves",
(1 << OB_CURVES),
{"show_object_viewport_curves", "show_object_select_curves"}},
{"Point Cloud",
(1 << OB_POINTCLOUD),
{"show_object_viewport_pointcloud", "show_object_select_pointcloud"}},
{"Volume", (1 << OB_VOLUME), {"show_object_viewport_volume", "show_object_select_volume"}},
{"Armature",
(1 << OB_ARMATURE),
{"show_object_viewport_armature", "show_object_select_armature"}},
{"Lattice",
(1 << OB_LATTICE),
{"show_object_viewport_lattice", "show_object_select_lattice"}},
{"Empty", (1 << OB_EMPTY), {"show_object_viewport_empty", "show_object_select_empty"}},
{"Grease Pencil",
(1 << OB_GPENCIL),
{"show_object_viewport_grease_pencil", "show_object_select_grease_pencil"}},
{"Camera", (1 << OB_CAMERA), {"show_object_viewport_camera", "show_object_select_camera"}},
{"Light", (1 << OB_LAMP), {"show_object_viewport_light", "show_object_select_light"}},
{"Speaker",
(1 << OB_SPEAKER),
{"show_object_viewport_speaker", "show_object_select_speaker"}},
{"Light Probe",
(1 << OB_LIGHTPROBE),
{"show_object_viewport_light_probe", "show_object_select_light_probe"}},
};
rna_def_object_type_visibility_flags_common(srna,
NC_SPACE | ND_SPACE_VIEW3D | NS_VIEW3D_SHADING);
const char *view_mask_member[2] = {
"object_type_exclude_viewport",
"object_type_exclude_select",
};
for (int mask_index = 0; mask_index < 2; mask_index++) {
for (int type_index = 0; type_index < ARRAY_SIZE(info); type_index++) {
prop = RNA_def_property(
srna, info[type_index].identifier[mask_index], PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(
prop, NULL, view_mask_member[mask_index], info[type_index].type_mask);
RNA_def_property_ui_text(prop, info[type_index].name, "");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D | NS_VIEW3D_SHADING, NULL);
}
}
/* Helper for drawing the icon. */
prop = RNA_def_property(srna, "icon_from_show_object_viewport", PROP_INT, PROP_NONE);
RNA_def_property_int_funcs(
prop, "rna_SpaceView3D_icon_from_show_object_viewport_get", NULL, NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Visibility Icon", "");
}
/* Helper for drawing the icon. */
prop = RNA_def_property(srna, "icon_from_show_object_viewport", PROP_INT, PROP_NONE);
RNA_def_property_int_funcs(
prop, "rna_SpaceView3D_icon_from_show_object_viewport_get", NULL, NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Visibility Icon", "");
/* Nested Structs */
prop = RNA_def_property(srna, "shading", PROP_POINTER, PROP_NONE);

View File

@ -4,6 +4,8 @@
* \ingroup RNA
*/
#include "DNA_object_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
@ -17,6 +19,21 @@
# include "ED_screen.h"
# include "ED_text.h"
int rna_object_type_visibility_icon_get_common(int object_type_exclude_viewport,
const int *object_type_exclude_select)
{
const int view_value = (object_type_exclude_viewport != 0);
if (object_type_exclude_select) {
/* Ignore selection values when view is off,
* intent is to show if visible objects aren't selectable. */
const int select_value = (*object_type_exclude_select & ~object_type_exclude_viewport) != 0;
return ICON_VIS_SEL_11 + (view_value << 1) + select_value;
}
return view_value ? ICON_HIDE_ON : ICON_HIDE_OFF;
}
static void rna_RegionView3D_update(ID *id, RegionView3D *rv3d, bContext *C)
{
bScreen *screen = (bScreen *)id;
@ -102,6 +119,65 @@ void RNA_api_space_text(StructRNA *srna)
RNA_def_function_output(func, parm);
}
void rna_def_object_type_visibility_flags_common(StructRNA *srna, int noteflag)
{
PropertyRNA *prop;
struct {
const char *name;
int type_mask;
const char *identifier[2];
} info[] = {
{"Mesh", (1 << OB_MESH), {"show_object_viewport_mesh", "show_object_select_mesh"}},
{"Curve",
(1 << OB_CURVES_LEGACY),
{"show_object_viewport_curve", "show_object_select_curve"}},
{"Surface", (1 << OB_SURF), {"show_object_viewport_surf", "show_object_select_surf"}},
{"Meta", (1 << OB_MBALL), {"show_object_viewport_meta", "show_object_select_meta"}},
{"Font", (1 << OB_FONT), {"show_object_viewport_font", "show_object_select_font"}},
{"Hair Curves",
(1 << OB_CURVES),
{"show_object_viewport_curves", "show_object_select_curves"}},
{"Point Cloud",
(1 << OB_POINTCLOUD),
{"show_object_viewport_pointcloud", "show_object_select_pointcloud"}},
{"Volume", (1 << OB_VOLUME), {"show_object_viewport_volume", "show_object_select_volume"}},
{"Armature",
(1 << OB_ARMATURE),
{"show_object_viewport_armature", "show_object_select_armature"}},
{"Lattice",
(1 << OB_LATTICE),
{"show_object_viewport_lattice", "show_object_select_lattice"}},
{"Empty", (1 << OB_EMPTY), {"show_object_viewport_empty", "show_object_select_empty"}},
{"Grease Pencil",
(1 << OB_GPENCIL),
{"show_object_viewport_grease_pencil", "show_object_select_grease_pencil"}},
{"Camera", (1 << OB_CAMERA), {"show_object_viewport_camera", "show_object_select_camera"}},
{"Light", (1 << OB_LAMP), {"show_object_viewport_light", "show_object_select_light"}},
{"Speaker",
(1 << OB_SPEAKER),
{"show_object_viewport_speaker", "show_object_select_speaker"}},
{"Light Probe",
(1 << OB_LIGHTPROBE),
{"show_object_viewport_light_probe", "show_object_select_light_probe"}},
};
const char *view_mask_member[2] = {
"object_type_exclude_viewport",
"object_type_exclude_select",
};
for (int mask_index = 0; mask_index < 2; mask_index++) {
for (int type_index = 0; type_index < ARRAY_SIZE(info); type_index++) {
prop = RNA_def_property(
srna, info[type_index].identifier[mask_index], PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(
prop, NULL, view_mask_member[mask_index], info[type_index].type_mask);
RNA_def_property_ui_text(prop, info[type_index].name, "");
RNA_def_property_update(prop, noteflag, NULL);
}
}
}
void RNA_api_space_filebrowser(StructRNA *srna)
{
FunctionRNA *func;

View File

@ -691,6 +691,24 @@ static void rna_XrSessionSettings_use_absolute_tracking_set(PointerRNA *ptr, boo
# endif
}
static int rna_XrSessionSettings_icon_from_show_object_viewport_get(PointerRNA *ptr)
{
# ifdef WITH_XR_OPENXR
const wmXrData *xr = rna_XrSession_wm_xr_data_get(ptr);
return rna_object_type_visibility_icon_get_common(
xr->session_settings.object_type_exclude_viewport,
# if 0
/* For the future when selection in VR is reliably supported. */
&xr->session_settings.object_type_exclude_select
# else
NULL
# endif
);
# else
return ICON_NONE;
# endif
}
/** \} */
/* -------------------------------------------------------------------- */
@ -1944,6 +1962,12 @@ static void rna_def_xr_session_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show Custom Overlays", "Show custom VR overlays");
RNA_def_property_update(prop, NC_WM | ND_XR_DATA_CHANGED, NULL);
prop = RNA_def_property(srna, "show_object_extras", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "draw_flags", V3D_OFSDRAW_SHOW_OBJECT_EXTRAS);
RNA_def_property_ui_text(
prop, "Show Object Extras", "Show object extras, including empties, lights, and cameras");
RNA_def_property_update(prop, NC_WM | ND_XR_DATA_CHANGED, NULL);
prop = RNA_def_property(srna, "controller_draw_style", PROP_ENUM, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_enum_items(prop, controller_draw_styles);
@ -1982,6 +2006,15 @@ static void rna_def_xr_session_settings(BlenderRNA *brna)
"Absolute Tracking",
"Allow the VR tracking origin to be defined independently of the headset location");
RNA_def_property_update(prop, NC_WM | ND_XR_DATA_CHANGED, NULL);
rna_def_object_type_visibility_flags_common(srna, NC_WM | ND_XR_DATA_CHANGED);
/* Helper for drawing the icon. */
prop = RNA_def_property(srna, "icon_from_show_object_viewport", PROP_INT, PROP_NONE);
RNA_def_property_int_funcs(
prop, "rna_XrSessionSettings_icon_from_show_object_viewport_get", NULL, NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Visibility Icon", "");
}
/** \} */

View File

@ -160,6 +160,8 @@ void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata)
draw_data->scene,
&settings->shading,
(eDrawType)settings->shading.type,
settings->object_type_exclude_viewport,
settings->object_type_exclude_select,
draw_view->width,
draw_view->height,
display_flags,

View File

@ -1212,6 +1212,11 @@ void wm_xr_session_actions_update(wmWindowManager *wm)
xr->runtime->area = ED_area_offscreen_create(win, SPACE_VIEW3D);
}
/* Set XR area object type flags for operators. */
View3D *v3d = xr->runtime->area->spacedata.first;
v3d->object_type_exclude_viewport = settings->object_type_exclude_viewport;
v3d->object_type_exclude_select = settings->object_type_exclude_select;
wm_xr_session_events_dispatch(xr, xr_context, active_action_set, state, win);
}
}