diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 97eb45462ed..a1548741187 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -6755,6 +6755,13 @@ class VIEW3D_PT_overlay_sculpt_curves(Panel): row.active = overlay.show_overlays row.prop(overlay, "sculpt_mode_mask_opacity", text="Selection Opacity") + row = layout.row(align=True) + row.active = overlay.show_overlays + row.prop(overlay, "sculpt_curves_cage", text="") + subrow = row.row(align=True) + subrow.active = overlay.sculpt_curves_cage + subrow.prop(overlay, "sculpt_curves_cage_opacity", text="Cage Opacity") + class VIEW3D_PT_overlay_bones(Panel): bl_space_type = 'VIEW_3D' diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index e8e7c6b552a..2340d585d5d 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3926,6 +3926,18 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } } + LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->overlay.flag |= V3D_OVERLAY_SCULPT_CURVES_CAGE; + v3d->overlay.sculpt_curves_cage_opacity = 0.5f; + } + } + } + } + /* Keep this block, even when empty. */ } } diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 063050660c6..3560a982b90 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -702,6 +702,7 @@ set(GLSL_SRC engines/overlay/shaders/overlay_point_varying_color_frag.glsl engines/overlay/shaders/overlay_point_varying_color_varying_outline_aa_frag.glsl engines/overlay/shaders/overlay_pointcloud_only_vert.glsl + engines/overlay/shaders/overlay_sculpt_curves_cage_vert.glsl engines/overlay/shaders/overlay_sculpt_curves_selection_frag.glsl engines/overlay/shaders/overlay_sculpt_curves_selection_vert.glsl engines/overlay/shaders/overlay_sculpt_mask_frag.glsl diff --git a/source/blender/draw/engines/overlay/overlay_engine.cc b/source/blender/draw/engines/overlay/overlay_engine.cc index 6f90645a0da..5b414c8c5f0 100644 --- a/source/blender/draw/engines/overlay/overlay_engine.cc +++ b/source/blender/draw/engines/overlay/overlay_engine.cc @@ -632,6 +632,10 @@ static void OVERLAY_draw_scene(void *vedata) GPU_framebuffer_bind(fbl->overlay_line_fb); } + if (pd->ctx_mode == CTX_MODE_SCULPT_CURVES) { + OVERLAY_sculpt_curves_draw_wires(data); + } + OVERLAY_wireframe_draw(data); OVERLAY_armature_draw(data); OVERLAY_particle_draw(data); diff --git a/source/blender/draw/engines/overlay/overlay_private.hh b/source/blender/draw/engines/overlay/overlay_private.hh index 8eb6ebecb7b..b9aa77106f5 100644 --- a/source/blender/draw/engines/overlay/overlay_private.hh +++ b/source/blender/draw/engines/overlay/overlay_private.hh @@ -120,6 +120,7 @@ typedef struct OVERLAY_PassList { DRWPass *pointcloud_ps; DRWPass *sculpt_mask_ps; DRWPass *sculpt_curves_selection_ps; + DRWPass *sculpt_curves_cage_ps; DRWPass *volume_ps; DRWPass *wireframe_ps; DRWPass *wireframe_xray_ps; @@ -287,6 +288,7 @@ typedef struct OVERLAY_PrivateData { DRWShadingGroup *pointcloud_dots_grp; DRWShadingGroup *sculpt_mask_grp; DRWShadingGroup *sculpt_curves_selection_grp; + DRWShadingGroup *sculpt_curves_cage_lines_grp; DRWShadingGroup *viewer_attribute_curve_grp; DRWShadingGroup *viewer_attribute_curves_grp; DRWShadingGroup *viewer_attribute_mesh_grp; @@ -687,6 +689,7 @@ void OVERLAY_sculpt_draw(OVERLAY_Data *vedata); void OVERLAY_sculpt_curves_cache_init(OVERLAY_Data *vedata); void OVERLAY_sculpt_curves_cache_populate(OVERLAY_Data *vedata, Object *ob); void OVERLAY_sculpt_curves_draw(OVERLAY_Data *vedata); +void OVERLAY_sculpt_curves_draw_wires(OVERLAY_Data *vedata); void OVERLAY_viewer_attribute_cache_init(OVERLAY_Data *vedata); void OVERLAY_viewer_attribute_cache_populate(OVERLAY_Data *vedata, Object *object); @@ -776,6 +779,7 @@ GPUShader *OVERLAY_shader_particle_dot(void); GPUShader *OVERLAY_shader_particle_shape(void); GPUShader *OVERLAY_shader_sculpt_mask(void); GPUShader *OVERLAY_shader_sculpt_curves_selection(void); +GPUShader *OVERLAY_shader_sculpt_curves_cage(void); GPUShader *OVERLAY_shader_viewer_attribute_curve(void); GPUShader *OVERLAY_shader_viewer_attribute_curves(void); GPUShader *OVERLAY_shader_viewer_attribute_mesh(void); diff --git a/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc b/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc index f84b93a487c..c73386f7897 100644 --- a/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc +++ b/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc @@ -11,23 +11,41 @@ #include "overlay_private.hh" #include "BKE_attribute.hh" +#include "BKE_crazyspace.hh" #include "BKE_curves.hh" +#include "DEG_depsgraph_query.h" + void OVERLAY_sculpt_curves_cache_init(OVERLAY_Data *vedata) { OVERLAY_PassList *psl = vedata->psl; OVERLAY_PrivateData *pd = vedata->stl->pd; + const View3DOverlay &overlay = vedata->stl->pd->overlay; - const DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA; - DRW_PASS_CREATE(psl->sculpt_curves_selection_ps, state | pd->clipping_state); + /* Selection overlay. */ + { + const DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA; + DRW_PASS_CREATE(psl->sculpt_curves_selection_ps, state | pd->clipping_state); - GPUShader *sh = OVERLAY_shader_sculpt_curves_selection(); - pd->sculpt_curves_selection_grp = DRW_shgroup_create(sh, psl->sculpt_curves_selection_ps); - DRWShadingGroup *grp = pd->sculpt_curves_selection_grp; + GPUShader *sh = OVERLAY_shader_sculpt_curves_selection(); + pd->sculpt_curves_selection_grp = DRW_shgroup_create(sh, psl->sculpt_curves_selection_ps); + DRWShadingGroup *grp = pd->sculpt_curves_selection_grp; - /* Reuse the same mask opacity from sculpt mode, since it wasn't worth it to add a different - * property yet. */ - DRW_shgroup_uniform_float_copy(grp, "selection_opacity", pd->overlay.sculpt_mode_mask_opacity); + /* Reuse the same mask opacity from sculpt mode, since it wasn't worth it to add a different + * property yet. */ + DRW_shgroup_uniform_float_copy(grp, "selection_opacity", pd->overlay.sculpt_mode_mask_opacity); + } + /* Cage overlay. */ + { + const DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | + DRW_STATE_BLEND_ALPHA; + DRW_PASS_CREATE(psl->sculpt_curves_cage_ps, state | pd->clipping_state); + + GPUShader *sh = OVERLAY_shader_sculpt_curves_cage(); + pd->sculpt_curves_cage_lines_grp = DRW_shgroup_create(sh, psl->sculpt_curves_cage_ps); + DRW_shgroup_uniform_float_copy( + pd->sculpt_curves_cage_lines_grp, "opacity", overlay.sculpt_curves_cage_opacity); + } } static bool everything_selected(const Curves &curves_id) @@ -39,7 +57,7 @@ static bool everything_selected(const Curves &curves_id) return selection.is_single() && selection.get_internal_single(); } -void OVERLAY_sculpt_curves_cache_populate(OVERLAY_Data *vedata, Object *object) +static void populate_selection_overlay(OVERLAY_Data *vedata, Object *object) { OVERLAY_PrivateData *pd = vedata->stl->pd; Curves *curves = static_cast(object->data); @@ -68,16 +86,35 @@ void OVERLAY_sculpt_curves_cache_populate(OVERLAY_Data *vedata, Object *object) DRW_shgroup_buffer_texture(grp, "selection_tx", *texture); } +static void populate_edit_overlay(OVERLAY_Data *vedata, Object *object) +{ + OVERLAY_PrivateData *pd = vedata->stl->pd; + Curves *curves = static_cast(object->data); + + GPUBatch *geom_lines = DRW_curves_batch_cache_get_edit_lines(curves); + DRW_shgroup_call_no_cull(pd->sculpt_curves_cage_lines_grp, geom_lines, object); +} + +void OVERLAY_sculpt_curves_cache_populate(OVERLAY_Data *vedata, Object *object) +{ + populate_selection_overlay(vedata, object); + const View3DOverlay &overlay = vedata->stl->pd->overlay; + if ((overlay.flag & V3D_OVERLAY_SCULPT_CURVES_CAGE) && + overlay.sculpt_curves_cage_opacity > 0.0f) { + populate_edit_overlay(vedata, object); + } +} + void OVERLAY_sculpt_curves_draw(OVERLAY_Data *vedata) { OVERLAY_PassList *psl = vedata->psl; - OVERLAY_PrivateData *pd = vedata->stl->pd; - OVERLAY_FramebufferList *fbl = vedata->fbl; - - if (DRW_state_is_fbo()) { - GPU_framebuffer_bind(pd->painting.in_front ? fbl->overlay_in_front_fb : - fbl->overlay_default_fb); - } DRW_draw_pass(psl->sculpt_curves_selection_ps); } + +void OVERLAY_sculpt_curves_draw_wires(OVERLAY_Data *vedata) +{ + OVERLAY_PassList *psl = vedata->psl; + + DRW_draw_pass(psl->sculpt_curves_cage_ps); +} diff --git a/source/blender/draw/engines/overlay/overlay_shader.cc b/source/blender/draw/engines/overlay/overlay_shader.cc index 5fd009db715..2229316d295 100644 --- a/source/blender/draw/engines/overlay/overlay_shader.cc +++ b/source/blender/draw/engines/overlay/overlay_shader.cc @@ -91,6 +91,7 @@ struct OVERLAY_Shaders { GPUShader *particle_shape; GPUShader *pointcloud_dot; GPUShader *sculpt_mask; + GPUShader *sculpt_curves_cage; GPUShader *sculpt_curves_selection; GPUShader *uniform_color; GPUShader *uniform_color_pointcloud; @@ -856,6 +857,18 @@ GPUShader *OVERLAY_shader_sculpt_curves_selection(void) return sh_data->sculpt_curves_selection; } +GPUShader *OVERLAY_shader_sculpt_curves_cage(void) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; + if (!sh_data->sculpt_curves_cage) { + sh_data->sculpt_curves_cage = GPU_shader_create_from_info_name( + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_sculpt_curves_cage_clipped" : + "overlay_sculpt_curves_cage"); + } + return sh_data->sculpt_curves_cage; +} + GPUShader *OVERLAY_shader_viewer_attribute_mesh(void) { const DRWContextState *draw_ctx = DRW_context_state_get(); diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_sculpt_curves_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_sculpt_curves_info.hh index 46e3943b293..b0b261ed9f1 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/overlay_sculpt_curves_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_sculpt_curves_info.hh @@ -19,3 +19,24 @@ GPU_SHADER_CREATE_INFO(overlay_sculpt_curves_selection) GPU_SHADER_CREATE_INFO(overlay_sculpt_curves_selection_clipped) .do_static_compilation(true) .additional_info("overlay_sculpt_curves_selection", "drw_clipped"); + +GPU_SHADER_INTERFACE_INFO(overlay_sculpt_curves_cage_iface, "") + .no_perspective(Type::VEC2, "edgePos") + .flat(Type::VEC2, "edgeStart") + .smooth(Type::VEC4, "finalColor"); + +GPU_SHADER_CREATE_INFO(overlay_sculpt_curves_cage) + .do_static_compilation(true) + .vertex_in(0, Type::VEC3, "pos") + .vertex_in(1, Type::FLOAT, "selection") + .vertex_out(overlay_sculpt_curves_cage_iface) + .fragment_out(0, Type::VEC4, "fragColor") + .fragment_out(1, Type::VEC4, "lineOutput") + .push_constant(Type::FLOAT, "opacity") + .vertex_source("overlay_sculpt_curves_cage_vert.glsl") + .fragment_source("overlay_extra_frag.glsl") + .additional_info("draw_modelmat", "draw_view", "draw_globals"); + +GPU_SHADER_CREATE_INFO(overlay_sculpt_curves_cage_clipped) + .do_static_compilation(true) + .additional_info("overlay_sculpt_curves_cage", "drw_clipped"); diff --git a/source/blender/draw/engines/overlay/shaders/overlay_sculpt_curves_cage_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_sculpt_curves_cage_vert.glsl new file mode 100644 index 00000000000..162934f64de --- /dev/null +++ b/source/blender/draw/engines/overlay/shaders/overlay_sculpt_curves_cage_vert.glsl @@ -0,0 +1,15 @@ + +#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl) +#pragma BLENDER_REQUIRE(common_view_lib.glsl) + +void main() +{ + vec3 world_pos = point_object_to_world(pos); + gl_Position = point_world_to_ndc(world_pos); + + finalColor = vec4(selection); + finalColor.a *= opacity; + + /* Convert to screen position [0..sizeVp]. */ + edgePos = edgeStart = ((gl_Position.xy / gl_Position.w) * 0.5 + 0.5) * sizeViewport.xy; +} diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index f6ee3d6e2dd..fb70fe982ba 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -232,6 +232,10 @@ typedef struct View3DOverlay { float gpencil_vertex_paint_opacity; /** Handles display type for curves. */ int handle_display; + + /** Curves sculpt mode settings. */ + float sculpt_curves_cage_opacity; + char _pad[4]; } View3DOverlay; /** #View3DOverlay.handle_display */ @@ -547,6 +551,7 @@ enum { V3D_OVERLAY_VIEWER_ATTRIBUTE = (1 << 13), V3D_OVERLAY_SCULPT_SHOW_MASK = (1 << 14), V3D_OVERLAY_SCULPT_SHOW_FACE_SETS = (1 << 15), + V3D_OVERLAY_SCULPT_CURVES_CAGE = (1 << 16), }; /** #View3DOverlay.edit_flag */ diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index ae07f2372b6..68c3aeb5c83 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -4714,6 +4714,19 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna) RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "sculpt_curves_cage", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_SCULPT_CURVES_CAGE); + RNA_def_property_ui_text( + prop, "Sculpt Curves Cage", "Show original curves that are currently being edited"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "sculpt_curves_cage_opacity", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "overlay.sculpt_curves_cage_opacity"); + RNA_def_property_ui_text( + prop, "Curves Sculpt Cage Opacity", "Opacity of the cage overlay in curves sculpt mode"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "sculpt_mode_face_sets_opacity", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "overlay.sculpt_mode_face_sets_opacity"); RNA_def_property_ui_text(prop, "Sculpt Face Sets Opacity", "");