Xray: Add possibility to select wires in priority before surfaces
If no wires were found, try to select surfaces in a second loop.
This commit is contained in:
parent
950dcaea10
commit
30ae0ce0e1
Notes:
blender-bot
2023-02-14 05:22:11 +01:00
Referenced by issue #56695, Selecting an occluded object in xray causes crash Referenced by issue #56649, Proposal: Blender 2.8: Wireframe, Select Through & X-Ray
|
@ -119,7 +119,7 @@ void DRW_draw_render_loop_offscreen(
|
|||
void DRW_draw_select_loop(
|
||||
struct Depsgraph *depsgraph,
|
||||
struct ARegion *ar, struct View3D *v3d,
|
||||
bool use_obedit_skip, bool use_nearest, const struct rcti *rect,
|
||||
bool use_obedit_skip, bool draw_surface, bool use_nearest, const struct rcti *rect,
|
||||
DRW_SelectPassFn select_pass_fn, void *select_pass_user_data,
|
||||
DRW_ObjectFilterFn object_filter_fn, void *object_filter_user_data);
|
||||
void DRW_draw_depth_loop(
|
||||
|
|
|
@ -1987,7 +1987,7 @@ void DRW_render_instance_buffer_finish(void)
|
|||
void DRW_draw_select_loop(
|
||||
struct Depsgraph *depsgraph,
|
||||
ARegion *ar, View3D *v3d,
|
||||
bool UNUSED(use_obedit_skip), bool UNUSED(use_nearest), const rcti *rect,
|
||||
bool UNUSED(use_obedit_skip), bool draw_surface, bool UNUSED(use_nearest), const rcti *rect,
|
||||
DRW_SelectPassFn select_pass_fn, void *select_pass_user_data,
|
||||
DRW_ObjectFilterFn object_filter_fn, void *object_filter_user_data)
|
||||
{
|
||||
|
@ -2037,6 +2037,10 @@ void DRW_draw_select_loop(
|
|||
drw_engines_enable_from_paint_mode(obedit_mode);
|
||||
drw_engines_enable_from_mode(obedit_mode);
|
||||
}
|
||||
else if (!draw_surface) {
|
||||
drw_engines_enable_from_overlays(v3d->overlay.flag);
|
||||
drw_engines_enable_from_object_mode();
|
||||
}
|
||||
else {
|
||||
drw_engines_enable_basic();
|
||||
drw_engines_enable_from_object_mode();
|
||||
|
|
|
@ -67,6 +67,7 @@ static struct {
|
|||
/* Face orientation shader */
|
||||
struct GPUShader *face_orientation_sh;
|
||||
/* Wireframe shader */
|
||||
struct GPUShader *select_wireframe_sh;
|
||||
struct GPUShader *face_wireframe_sh;
|
||||
struct GPUShader *face_wireframe_pretty_sh;
|
||||
struct GPUShader *face_wireframe_sculpt_sh;
|
||||
|
@ -105,6 +106,14 @@ static void overlay_engine_init(void *vedata)
|
|||
if (!e_data.face_wireframe_sh) {
|
||||
bool use_geom = GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY);
|
||||
|
||||
e_data.select_wireframe_sh = DRW_shader_create(
|
||||
datatoc_overlay_face_wireframe_vert_glsl,
|
||||
datatoc_overlay_face_wireframe_geom_glsl,
|
||||
datatoc_overlay_face_wireframe_frag_glsl,
|
||||
"#define SELECT_EDGES\n"
|
||||
"#define LIGHT_EDGES\n"
|
||||
"#define USE_GEOM_SHADER\n");
|
||||
|
||||
e_data.face_wireframe_sh = DRW_shader_create(
|
||||
datatoc_overlay_face_wireframe_vert_glsl,
|
||||
use_geom ? datatoc_overlay_face_wireframe_geom_glsl : NULL,
|
||||
|
@ -207,6 +216,7 @@ static void overlay_cache_populate(void *vedata, Object *ob)
|
|||
OVERLAY_PrivateData *pd = stl->g_data;
|
||||
OVERLAY_PassList *psl = data->psl;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
View3D *v3d = draw_ctx->v3d;
|
||||
|
||||
if (!stl->g_data->show_overlays)
|
||||
return;
|
||||
|
@ -250,13 +260,31 @@ static void overlay_cache_populate(void *vedata, Object *ob)
|
|||
DRWPass *pass = (all_wires) ? psl->face_wireframe_full_pass : psl->face_wireframe_pass;
|
||||
GPUShader *sh = (all_wires) ? e_data.face_wireframe_sh : e_data.face_wireframe_pretty_sh;
|
||||
|
||||
DRWShadingGroup *shgrp = DRW_shgroup_create(sh, pass);
|
||||
DRW_shgroup_stencil_mask(shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF);
|
||||
DRW_shgroup_uniform_texture(shgrp, "vertData", verts);
|
||||
DRW_shgroup_uniform_texture(shgrp, "faceIds", faceids);
|
||||
DRW_shgroup_uniform_vec3(shgrp, "wireColor", ts.colorWire, 1);
|
||||
DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1);
|
||||
DRW_shgroup_call_object_procedural_triangles_culled_add(shgrp, tri_count, ob);
|
||||
if ((DRW_state_is_select() || DRW_state_is_depth()) &&
|
||||
(v3d->shading.flag & V3D_SHADING_XRAY) != 0)
|
||||
{
|
||||
static float params[2] = {1.2f, 1.0f}; /* Parameters for all wires */
|
||||
|
||||
sh = e_data.select_wireframe_sh;
|
||||
DRWShadingGroup *shgrp = DRW_shgroup_create(sh, pass);
|
||||
DRW_shgroup_uniform_vec2(shgrp, "viewportSize", DRW_viewport_size_get(), 1);
|
||||
DRW_shgroup_uniform_vec2(shgrp, "wireStepParam", (all_wires)
|
||||
? params
|
||||
: stl->g_data->wire_step_param, 1);
|
||||
DRW_shgroup_uniform_texture(shgrp, "vertData", verts);
|
||||
DRW_shgroup_uniform_texture(shgrp, "faceIds", faceids);
|
||||
DRW_shgroup_call_object_procedural_triangles_culled_add(shgrp, tri_count, ob);
|
||||
}
|
||||
else {
|
||||
DRWShadingGroup *shgrp = DRW_shgroup_create(sh, pass);
|
||||
DRW_shgroup_stencil_mask(shgrp, (ob->dtx & OB_DRAWXRAY) ? 0x00 : 0xFF);
|
||||
DRW_shgroup_uniform_texture(shgrp, "vertData", verts);
|
||||
DRW_shgroup_uniform_texture(shgrp, "faceIds", faceids);
|
||||
DRW_shgroup_uniform_vec3(shgrp, "wireColor", ts.colorWire, 1);
|
||||
DRW_shgroup_uniform_vec3(shgrp, "rimColor", rim_col, 1);
|
||||
DRW_shgroup_call_object_procedural_triangles_culled_add(shgrp, tri_count, ob);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -291,7 +319,9 @@ static void overlay_draw_scene(void *vedata)
|
|||
OVERLAY_PassList *psl = data->psl;
|
||||
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
|
||||
|
||||
GPU_framebuffer_bind(dfbl->default_fb);
|
||||
if (DRW_state_is_fbo()) {
|
||||
GPU_framebuffer_bind(dfbl->default_fb);
|
||||
}
|
||||
DRW_draw_pass(psl->face_orientation_pass);
|
||||
DRW_draw_pass(psl->face_wireframe_pass);
|
||||
DRW_draw_pass(psl->face_wireframe_full_pass);
|
||||
|
@ -300,6 +330,7 @@ static void overlay_draw_scene(void *vedata)
|
|||
static void overlay_engine_free(void)
|
||||
{
|
||||
DRW_SHADER_FREE_SAFE(e_data.face_orientation_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.select_wireframe_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.face_wireframe_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.face_wireframe_pretty_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.face_wireframe_sculpt_sh);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#ifndef SELECT_EDGES
|
||||
uniform vec3 wireColor;
|
||||
uniform vec3 rimColor;
|
||||
|
||||
|
@ -6,11 +7,12 @@ flat in vec3 ssVec1;
|
|||
flat in vec3 ssVec2;
|
||||
in float facing;
|
||||
|
||||
#ifdef LIGHT_EDGES
|
||||
# ifdef LIGHT_EDGES
|
||||
flat in vec3 edgeSharpness;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
out vec4 fragColor;
|
||||
#endif
|
||||
|
||||
float min_v3(vec3 v) { return min(v.x, min(v.y, v.z)); }
|
||||
float max_v3(vec3 v) { return max(v.x, max(v.y, v.z)); }
|
||||
|
@ -25,6 +27,7 @@ const float rim_alpha = 0.75;
|
|||
|
||||
void main()
|
||||
{
|
||||
#ifndef SELECT_EDGES
|
||||
vec3 ss_pos = vec3(gl_FragCoord.xy, 1.0);
|
||||
vec3 dist_to_edge = vec3(
|
||||
dot(ss_pos, ssVec0),
|
||||
|
@ -32,11 +35,11 @@ void main()
|
|||
dot(ss_pos, ssVec2)
|
||||
);
|
||||
|
||||
#ifdef LIGHT_EDGES
|
||||
# ifdef LIGHT_EDGES
|
||||
vec3 fac = abs(dist_to_edge);
|
||||
#else
|
||||
# else
|
||||
float fac = min_v3(abs(dist_to_edge));
|
||||
#endif
|
||||
# endif
|
||||
|
||||
fac = smoothstep(wire_size + wire_smooth, wire_size, fac);
|
||||
|
||||
|
@ -45,9 +48,10 @@ void main()
|
|||
vec3 final_front_col = mix(rimColor, wireColor, 0.05);
|
||||
fragColor = mix(vec4(rimColor, rim_alpha), vec4(final_front_col, front_alpha), facing_clamped);
|
||||
|
||||
#ifdef LIGHT_EDGES
|
||||
# ifdef LIGHT_EDGES
|
||||
fragColor.a *= max_v3(fac * edgeSharpness);
|
||||
#else
|
||||
# else
|
||||
fragColor.a *= fac;
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -3,24 +3,32 @@
|
|||
* than doing everything thrice in the vertex shader. */
|
||||
|
||||
layout(triangles) in;
|
||||
#ifdef SELECT_EDGES
|
||||
layout(line_strip, max_vertices = 6) out;
|
||||
#else
|
||||
layout(triangle_strip, max_vertices = 3) out;
|
||||
#endif
|
||||
|
||||
uniform vec2 wireStepParam;
|
||||
|
||||
in vec2 ssPos[];
|
||||
in float facingOut[];
|
||||
|
||||
#ifndef SELECT_EDGES
|
||||
flat out vec3 ssVec0;
|
||||
flat out vec3 ssVec1;
|
||||
flat out vec3 ssVec2;
|
||||
out float facing;
|
||||
#endif
|
||||
|
||||
#ifdef LIGHT_EDGES
|
||||
in vec3 obPos[];
|
||||
in vec3 vNor[];
|
||||
in float forceEdge[];
|
||||
|
||||
# ifndef SELECT_EDGES
|
||||
flat out vec3 edgeSharpness;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define NO_EDGE vec3(10000.0);
|
||||
|
@ -53,9 +61,13 @@ void main(void)
|
|||
bvec3 do_edge = greaterThan(abs(facings), vec3(1.0));
|
||||
facings = fract(facings) - clamp(-sign(facings), 0.0, 1.0);
|
||||
|
||||
#ifndef SELECT_EDGES
|
||||
ssVec0 = do_edge.x ? compute_vec(ssPos[0], ssPos[1]) : NO_EDGE;
|
||||
ssVec1 = do_edge.y ? compute_vec(ssPos[1], ssPos[2]) : NO_EDGE;
|
||||
ssVec2 = do_edge.z ? compute_vec(ssPos[2], ssPos[0]) : NO_EDGE;
|
||||
#else
|
||||
vec3 edgeSharpness;
|
||||
#endif
|
||||
|
||||
#ifdef LIGHT_EDGES
|
||||
vec3 edges[3];
|
||||
|
@ -71,6 +83,34 @@ void main(void)
|
|||
edgeSharpness.y = (forceEdge[1] == 1.0) ? 1.0 : edgeSharpness.y;
|
||||
edgeSharpness.z = (forceEdge[2] == 1.0) ? 1.0 : edgeSharpness.z;
|
||||
#endif
|
||||
|
||||
#ifdef SELECT_EDGES
|
||||
const float edge_select_threshold = 0.3;
|
||||
if (edgeSharpness.x > edge_select_threshold) {
|
||||
gl_Position = gl_in[0].gl_Position;
|
||||
EmitVertex();
|
||||
gl_Position = gl_in[1].gl_Position;
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
if (edgeSharpness.y > edge_select_threshold) {
|
||||
gl_Position = gl_in[1].gl_Position;
|
||||
EmitVertex();
|
||||
gl_Position = gl_in[2].gl_Position;
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
if (edgeSharpness.z > edge_select_threshold) {
|
||||
gl_Position = gl_in[2].gl_Position;
|
||||
EmitVertex();
|
||||
gl_Position = gl_in[0].gl_Position;
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
}
|
||||
#else
|
||||
|
||||
gl_Position = gl_in[0].gl_Position;
|
||||
facing = facings.x;
|
||||
EmitVertex();
|
||||
|
@ -83,4 +123,5 @@ void main(void)
|
|||
facing = facings.z;
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -27,13 +27,13 @@ out float facing;
|
|||
#endif
|
||||
|
||||
#ifdef LIGHT_EDGES
|
||||
#ifdef USE_GEOM_SHADER
|
||||
# ifdef USE_GEOM_SHADER
|
||||
out vec3 obPos;
|
||||
out vec3 vNor;
|
||||
out float forceEdge;
|
||||
#else
|
||||
# else
|
||||
flat out vec3 edgeSharpness;
|
||||
#endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* project to screen space */
|
||||
|
|
|
@ -857,7 +857,6 @@ void view3d_opengl_select_cache_end(void)
|
|||
GPU_select_cache_end();
|
||||
}
|
||||
|
||||
#ifndef WITH_OPENGL_LEGACY
|
||||
struct DrawSelectLoopUserData {
|
||||
uint pass;
|
||||
uint hits;
|
||||
|
@ -894,7 +893,6 @@ static bool drw_select_loop_pass(eDRWSelectStage stage, void *user_data)
|
|||
return continue_pass;
|
||||
|
||||
}
|
||||
#endif /* WITH_OPENGL_LEGACY */
|
||||
|
||||
/** Implement #VIEW3D_SELECT_FILTER_OBJECT_MODE_LOCK. */
|
||||
static bool drw_select_filter_object_mode_lock(Object *ob, void *user_data)
|
||||
|
@ -920,7 +918,7 @@ int view3d_opengl_select(
|
|||
View3D *v3d = vc->v3d;
|
||||
ARegion *ar = vc->ar;
|
||||
rcti rect;
|
||||
int hits;
|
||||
int hits = 0;
|
||||
const bool use_obedit_skip = (OBEDIT_FROM_VIEW_LAYER(vc->view_layer) != NULL) && (vc->obedit == NULL);
|
||||
const bool is_pick_select = (U.gpu_select_pick_deph != 0);
|
||||
const bool do_passes = (
|
||||
|
@ -928,6 +926,7 @@ int view3d_opengl_select(
|
|||
(select_mode == VIEW3D_SELECT_PICK_NEAREST) &&
|
||||
GPU_select_query_check_active());
|
||||
const bool use_nearest = (is_pick_select && select_mode == VIEW3D_SELECT_PICK_NEAREST);
|
||||
bool draw_surface = true;
|
||||
|
||||
char gpu_select_mode;
|
||||
|
||||
|
@ -992,10 +991,8 @@ int view3d_opengl_select(
|
|||
goto finally;
|
||||
}
|
||||
|
||||
#ifndef WITH_OPENGL_LEGACY
|
||||
/* All of the queries need to be perform on the drawing context. */
|
||||
DRW_opengl_context_enable();
|
||||
#endif
|
||||
|
||||
G.f |= G_PICKSEL;
|
||||
|
||||
|
@ -1007,25 +1004,12 @@ int view3d_opengl_select(
|
|||
GPU_depth_test(true);
|
||||
}
|
||||
|
||||
if (vc->rv3d->rflag & RV3D_CLIPPING)
|
||||
if (vc->rv3d->rflag & RV3D_CLIPPING) {
|
||||
ED_view3d_clipping_set(vc->rv3d);
|
||||
|
||||
|
||||
#ifdef WITH_OPENGL_LEGACY
|
||||
if (IS_VIEWPORT_LEGACY(vc->v3d)) {
|
||||
GPU_select_begin(buffer, bufsize, &rect, gpu_select_mode, 0);
|
||||
ED_view3d_draw_select_loop(vc, scene, sl, v3d, ar, use_obedit_skip, use_nearest);
|
||||
hits = GPU_select_end();
|
||||
|
||||
if (do_passes && (hits > 0)) {
|
||||
GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
|
||||
ED_view3d_draw_select_loop(vc, scene, sl, v3d, ar, use_obedit_skip, use_nearest);
|
||||
GPU_select_end();
|
||||
}
|
||||
}
|
||||
else
|
||||
#else
|
||||
{
|
||||
|
||||
/* If in xray mode, we select the wires in priority. */
|
||||
if (v3d->shading.flag & V3D_SHADING_XRAY) {
|
||||
/* We need to call "GPU_select_*" API's inside DRW_draw_select_loop
|
||||
* because the OpenGL context created & destroyed inside this function. */
|
||||
struct DrawSelectLoopUserData drw_select_loop_user_data = {
|
||||
|
@ -1036,14 +1020,34 @@ int view3d_opengl_select(
|
|||
.rect = &rect,
|
||||
.gpu_select_mode = gpu_select_mode,
|
||||
};
|
||||
draw_surface = false;
|
||||
DRW_draw_select_loop(
|
||||
depsgraph, ar, v3d,
|
||||
use_obedit_skip, use_nearest, &rect,
|
||||
use_obedit_skip, draw_surface, use_nearest, &rect,
|
||||
drw_select_loop_pass, &drw_select_loop_user_data,
|
||||
object_filter.fn, object_filter.user_data);
|
||||
hits = drw_select_loop_user_data.hits;
|
||||
}
|
||||
|
||||
if (hits == 0) {
|
||||
/* We need to call "GPU_select_*" API's inside DRW_draw_select_loop
|
||||
* because the OpenGL context created & destroyed inside this function. */
|
||||
struct DrawSelectLoopUserData drw_select_loop_user_data = {
|
||||
.pass = 0,
|
||||
.hits = 0,
|
||||
.buffer = buffer,
|
||||
.buffer_len = bufsize,
|
||||
.rect = &rect,
|
||||
.gpu_select_mode = gpu_select_mode,
|
||||
};
|
||||
draw_surface = true;
|
||||
DRW_draw_select_loop(
|
||||
depsgraph, ar, v3d,
|
||||
use_obedit_skip, draw_surface, use_nearest, &rect,
|
||||
drw_select_loop_pass, &drw_select_loop_user_data,
|
||||
object_filter.fn, object_filter.user_data);
|
||||
hits = drw_select_loop_user_data.hits;
|
||||
}
|
||||
#endif /* WITH_OPENGL_LEGACY */
|
||||
|
||||
G.f &= ~G_PICKSEL;
|
||||
ED_view3d_draw_setup_view(vc->win, depsgraph, scene, ar, v3d, vc->rv3d->viewmat, NULL, NULL);
|
||||
|
@ -1055,9 +1059,7 @@ int view3d_opengl_select(
|
|||
if (vc->rv3d->rflag & RV3D_CLIPPING)
|
||||
ED_view3d_clipping_disable();
|
||||
|
||||
#ifndef WITH_OPENGL_LEGACY
|
||||
DRW_opengl_context_disable();
|
||||
#endif
|
||||
|
||||
finally:
|
||||
|
||||
|
|
Loading…
Reference in New Issue