Curves: cage overlay for sculpt mode #104467

Merged
Jacques Lucke merged 44 commits from JacquesLucke/blender:sculpt-edit-overlay into main 2023-02-14 18:10:24 +01:00
11 changed files with 148 additions and 16 deletions

View File

@ -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'

View File

@ -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. */
}
}

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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<Curves *>(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<Curves *>(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);
}

View File

@ -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();

View File

@ -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");

View File

@ -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;
}

View File

@ -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 */

View File

@ -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");
JacquesLucke marked this conversation as resolved
Review

Show points -> Show curves (not just showing the points but the segments between them)

Maybe add Show original curves to make the difference clearer too?

`Show points` -> `Show curves` (not just showing the points but the segments between them) Maybe add `Show original curves` to make the difference clearer too?
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", "");