GPv3: Add edit mode lines to overlay #9

Closed
casey-bianco-davis wants to merge 1 commits from GPv3-edit-mode-lines into main

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

View File

@ -71,9 +71,25 @@ class DATA_PT_grease_pencil_layers(DataButtonsPanel, Panel):
col.prop(layer, "opacity", text="Opacity", slider=True) col.prop(layer, "opacity", text="Opacity", slider=True)
class DATA_PT_grease_pencil_display(DataButtonsPanel, Panel):
bl_label = "Viewport Display"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False
ob = context.object
grease_pencil = context.grease_pencil
layout.prop(grease_pencil, "edit_line_color", text="Edit Line Color")
classes = ( classes = (
DATA_PT_context_grease_pencil, DATA_PT_context_grease_pencil,
DATA_PT_grease_pencil_layers, DATA_PT_grease_pencil_layers,
DATA_PT_grease_pencil_display,
GREASE_PENCIL_MT_grease_pencil_add_layer_extra, GREASE_PENCIL_MT_grease_pencil_add_layer_extra,
) )

View File

@ -73,6 +73,8 @@ static void grease_pencil_init_data(ID *id)
grease_pencil->root_group_ptr = MEM_new<greasepencil::LayerGroup>(__func__); grease_pencil->root_group_ptr = MEM_new<greasepencil::LayerGroup>(__func__);
grease_pencil->active_layer = nullptr; grease_pencil->active_layer = nullptr;
grease_pencil->flag |= GREASE_PENCIL_ANIM_CHANNEL_EXPANDED; grease_pencil->flag |= GREASE_PENCIL_ANIM_CHANNEL_EXPANDED;
ARRAY_SET_ITEMS(grease_pencil->line_color, 0.6f, 0.6f, 0.6f, 0.5f);
} }
static void grease_pencil_copy_data(Main * /*bmain*/, static void grease_pencil_copy_data(Main * /*bmain*/,
@ -123,6 +125,8 @@ static void grease_pencil_copy_data(Main * /*bmain*/,
grease_pencil_dst->find_layer_by_name(grease_pencil_src->active_layer->wrap().name())); grease_pencil_dst->find_layer_by_name(grease_pencil_src->active_layer->wrap().name()));
} }
copy_v4_v4(grease_pencil_dst->line_color, grease_pencil_src->line_color);
/* Make sure the runtime pointer exists. */ /* Make sure the runtime pointer exists. */
grease_pencil_dst->runtime = MEM_new<bke::GreasePencilRuntime>(__func__); grease_pencil_dst->runtime = MEM_new<bke::GreasePencilRuntime>(__func__);
} }

View File

@ -54,11 +54,16 @@ void OVERLAY_edit_curves_cache_init(OVERLAY_Data *vedata)
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
} }
float empty_color[4];
zero_v4(empty_color);
DRW_PASS_CREATE(psl->edit_curves_lines_ps[i], (state | pd->clipping_state)); DRW_PASS_CREATE(psl->edit_curves_lines_ps[i], (state | pd->clipping_state));
sh = OVERLAY_shader_edit_particle_strand(); sh = OVERLAY_shader_edit_particle_strand();
grp = pd->edit_curves_lines_grp[i] = DRW_shgroup_create(sh, psl->edit_curves_lines_ps[i]); grp = pd->edit_curves_lines_grp[i] = DRW_shgroup_create(sh, psl->edit_curves_lines_ps[i]);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_bool_copy(grp, "useWeight", false); DRW_shgroup_uniform_bool_copy(grp, "useWeight", false);
/* Set to zero so that `globalsBlock.color_wire` will be used. */
DRW_shgroup_uniform_vec4_copy(grp, "replaceColor", empty_color);
} }
} }

View File

@ -24,6 +24,10 @@ void OVERLAY_edit_grease_pencil_cache_init(OVERLAY_Data *vedata)
DRW_STATE_BLEND_ALPHA; DRW_STATE_BLEND_ALPHA;
DRW_PASS_CREATE(psl->edit_grease_pencil_ps, (state | pd->clipping_state)); DRW_PASS_CREATE(psl->edit_grease_pencil_ps, (state | pd->clipping_state));
sh = OVERLAY_shader_edit_particle_strand();
grp = pd->edit_grease_pencil_wires_grp = DRW_shgroup_create(sh, psl->edit_grease_pencil_ps);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
sh = OVERLAY_shader_edit_particle_point(); sh = OVERLAY_shader_edit_particle_point();
grp = pd->edit_grease_pencil_points_grp = DRW_shgroup_create(sh, psl->edit_grease_pencil_ps); grp = pd->edit_grease_pencil_points_grp = DRW_shgroup_create(sh, psl->edit_grease_pencil_ps);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
@ -32,11 +36,22 @@ void OVERLAY_edit_grease_pencil_cache_init(OVERLAY_Data *vedata)
void OVERLAY_edit_grease_pencil_cache_populate(OVERLAY_Data *vedata, Object *ob) void OVERLAY_edit_grease_pencil_cache_populate(OVERLAY_Data *vedata, Object *ob)
{ {
OVERLAY_PrivateData *pd = vedata->stl->pd; OVERLAY_PrivateData *pd = vedata->stl->pd;
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
DRWShadingGroup *lines_grp = pd->edit_grease_pencil_wires_grp;
if (lines_grp) {
DRWShadingGroup *grp = DRW_shgroup_create_sub(lines_grp);
DRW_shgroup_uniform_vec4_copy(grp, "replaceColor", grease_pencil.line_color);
GPUBatch *geom_lines = DRW_cache_grease_pencil_edit_lines_get(ob, pd->cfra);
DRW_shgroup_call_no_cull(grp, geom_lines, ob);
}
DRWShadingGroup *points_grp = pd->edit_grease_pencil_points_grp; DRWShadingGroup *points_grp = pd->edit_grease_pencil_points_grp;
if (points_grp) { if (points_grp) {
GPUBatch *geom = DRW_cache_grease_pencil_edit_points_get(ob, pd->cfra); GPUBatch *geom_points = DRW_cache_grease_pencil_edit_points_get(ob, pd->cfra);
DRW_shgroup_call_no_cull(points_grp, geom, ob); DRW_shgroup_call_no_cull(points_grp, geom_points, ob);
} }
} }

View File

@ -37,11 +37,16 @@ void OVERLAY_edit_particle_cache_init(OVERLAY_Data *vedata)
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL; DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
DRW_PASS_CREATE(psl->edit_particle_ps, state | pd->clipping_state); DRW_PASS_CREATE(psl->edit_particle_ps, state | pd->clipping_state);
float empty_color[4];
zero_v4(empty_color);
sh = OVERLAY_shader_edit_particle_strand(); sh = OVERLAY_shader_edit_particle_strand();
pd->edit_particle_strand_grp = grp = DRW_shgroup_create(sh, psl->edit_particle_ps); pd->edit_particle_strand_grp = grp = DRW_shgroup_create(sh, psl->edit_particle_ps);
DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
DRW_shgroup_uniform_bool_copy(grp, "useWeight", pd->edit_particle.use_weight); DRW_shgroup_uniform_bool_copy(grp, "useWeight", pd->edit_particle.use_weight);
DRW_shgroup_uniform_texture(grp, "weightTex", G_draw.weight_ramp); DRW_shgroup_uniform_texture(grp, "weightTex", G_draw.weight_ramp);
/* Set to zero so that `globalsBlock.color_wire` will be used. */
DRW_shgroup_uniform_vec4_copy(grp, "replaceColor", empty_color);
sh = OVERLAY_shader_edit_particle_point(); sh = OVERLAY_shader_edit_particle_point();
pd->edit_particle_point_grp = grp = DRW_shgroup_create(sh, psl->edit_particle_ps); pd->edit_particle_point_grp = grp = DRW_shgroup_create(sh, psl->edit_particle_ps);

View File

@ -251,6 +251,7 @@ struct OVERLAY_PrivateData {
DRWShadingGroup *edit_lattice_wires_grp; DRWShadingGroup *edit_lattice_wires_grp;
DRWShadingGroup *edit_gpencil_points_grp; DRWShadingGroup *edit_gpencil_points_grp;
DRWShadingGroup *edit_gpencil_wires_grp; DRWShadingGroup *edit_gpencil_wires_grp;
DRWShadingGroup *edit_grease_pencil_wires_grp;
DRWShadingGroup *edit_grease_pencil_points_grp; DRWShadingGroup *edit_grease_pencil_points_grp;
DRWShadingGroup *edit_gpencil_curve_handle_grp; DRWShadingGroup *edit_gpencil_curve_handle_grp;
DRWShadingGroup *edit_gpencil_curve_points_grp; DRWShadingGroup *edit_gpencil_curve_points_grp;

View File

@ -531,6 +531,7 @@ GPU_SHADER_CREATE_INFO(overlay_edit_particle_strand)
.vertex_in(1, Type::FLOAT, "selection") .vertex_in(1, Type::FLOAT, "selection")
.sampler(0, ImageType::FLOAT_1D, "weightTex") .sampler(0, ImageType::FLOAT_1D, "weightTex")
.push_constant(Type::BOOL, "useWeight") .push_constant(Type::BOOL, "useWeight")
.push_constant(Type::VEC4, "replaceColor")
.vertex_out(overlay_edit_smooth_color_iface) .vertex_out(overlay_edit_smooth_color_iface)
.fragment_out(0, Type::VEC4, "fragColor") .fragment_out(0, Type::VEC4, "fragColor")
.vertex_source("overlay_edit_particle_strand_vert.glsl") .vertex_source("overlay_edit_particle_strand_vert.glsl")

View File

@ -7,11 +7,13 @@
#define no_active_weight 666.0 #define no_active_weight 666.0
#define base_color (replaceColor == 0.0 ? colorWire : replaceColor)
vec3 weight_to_rgb(float t) vec3 weight_to_rgb(float t)
{ {
if (t == no_active_weight) { if (t == no_active_weight) {
/* No weight. */ /* No weight. */
return colorWire.rgb; return base_color.rgb;
} }
if (t > 1.0 || t < 0.0) { if (t > 1.0 || t < 0.0) {
/* Error color */ /* Error color */
@ -31,7 +33,7 @@ void main()
finalColor = vec4(weight_to_rgb(selection), 1.0); finalColor = vec4(weight_to_rgb(selection), 1.0);
} }
else { else {
finalColor = mix(colorWire, colorVertexSelect, selection); finalColor = mix(base_color, colorVertexSelect, selection);
} }
view_clipping_distances(world_pos); view_clipping_distances(world_pos);

View File

@ -281,6 +281,7 @@ void DRW_cache_gpencil_sbuffer_clear(struct Object *ob);
struct GPUBatch *DRW_cache_grease_pencil_get(struct Object *ob, int cfra); struct GPUBatch *DRW_cache_grease_pencil_get(struct Object *ob, int cfra);
struct GPUBatch *DRW_cache_grease_pencil_edit_points_get(struct Object *ob, int cfra); struct GPUBatch *DRW_cache_grease_pencil_edit_points_get(struct Object *ob, int cfra);
struct GPUBatch *DRW_cache_grease_pencil_edit_lines_get(struct Object *ob, int cfra);
struct GPUVertBuf *DRW_cache_grease_pencil_position_buffer_get(struct Object *ob, int cfra); struct GPUVertBuf *DRW_cache_grease_pencil_position_buffer_get(struct Object *ob, int cfra);
struct GPUVertBuf *DRW_cache_grease_pencil_color_buffer_get(struct Object *ob, int cfra); struct GPUVertBuf *DRW_cache_grease_pencil_color_buffer_get(struct Object *ob, int cfra);

View File

@ -37,11 +37,14 @@ struct GreasePencilBatchCache {
/** Batches */ /** Batches */
GPUBatch *geom_batch; GPUBatch *geom_batch;
GPUBatch *edit_points; GPUBatch *edit_points;
GPUBatch *edit_lines;
/* Crazy-space point positions for original points. */ /* Crazy-space point positions for original points. */
GPUVertBuf *edit_points_pos; GPUVertBuf *edit_points_pos;
/* Selection of original points. */ /* Selection of original points. */
GPUVertBuf *edit_points_selection; GPUVertBuf *edit_points_selection;
/* Indices for lines segments. */
GPUIndexBuf *edit_line_indices;
/** Cache is dirty. */ /** Cache is dirty. */
bool is_dirty; bool is_dirty;
@ -139,8 +142,10 @@ static void grease_pencil_batch_cache_clear(GreasePencil &grease_pencil)
GPU_INDEXBUF_DISCARD_SAFE(cache->ibo); GPU_INDEXBUF_DISCARD_SAFE(cache->ibo);
GPU_BATCH_DISCARD_SAFE(cache->edit_points); GPU_BATCH_DISCARD_SAFE(cache->edit_points);
GPU_BATCH_DISCARD_SAFE(cache->edit_lines);
GPU_VERTBUF_DISCARD_SAFE(cache->edit_points_pos); GPU_VERTBUF_DISCARD_SAFE(cache->edit_points_pos);
GPU_VERTBUF_DISCARD_SAFE(cache->edit_points_selection); GPU_VERTBUF_DISCARD_SAFE(cache->edit_points_selection);
GPU_INDEXBUF_DISCARD_SAFE(cache->edit_line_indices);
cache->is_dirty = true; cache->is_dirty = true;
} }
@ -212,6 +217,7 @@ static void grease_pencil_geom_batch_ensure(GreasePencil &grease_pencil, int cfr
int total_points_num = 0; int total_points_num = 0;
int total_verts_num = 0; int total_verts_num = 0;
int total_triangles_num = 0; int total_triangles_num = 0;
int total_line_ids_num = 0;
int v_offset = 0; int v_offset = 0;
Vector<Array<int>> verts_start_offsets_per_visible_drawing; Vector<Array<int>> verts_start_offsets_per_visible_drawing;
Vector<Array<int>> tris_start_offsets_per_visible_drawing; Vector<Array<int>> tris_start_offsets_per_visible_drawing;
@ -241,6 +247,19 @@ static void grease_pencil_geom_batch_ensure(GreasePencil &grease_pencil, int cfr
t_offset += points.size() - 2; t_offset += points.size() - 2;
} }
if (points.size() > 1) {
/* Add one id for the first point in the curve. */
total_line_ids_num++;
/* Add ids for the segments. */
total_line_ids_num += points.size() - 1;
/* Add one segment for the cycle line. */
if (points.size() > 2 && is_cyclic) {
total_line_ids_num++;
}
/* Add one id for the jump to the next curve. */
total_line_ids_num++;
}
verts_start_offsets[curve_i] = v_offset; verts_start_offsets[curve_i] = v_offset;
v_offset += 1 + points.size() + (is_cyclic ? 1 : 0) + 1; v_offset += 1 + points.size() + (is_cyclic ? 1 : 0) + 1;
} }
@ -291,6 +310,7 @@ static void grease_pencil_geom_batch_ensure(GreasePencil &grease_pencil, int cfr
GPU_vertbuf_data_alloc(cache->vbo_col, total_verts_num + 2); GPU_vertbuf_data_alloc(cache->vbo_col, total_verts_num + 2);
GPUIndexBufBuilder ibo; GPUIndexBufBuilder ibo;
GPUIndexBufBuilder elb;
MutableSpan<GreasePencilStrokeVert> verts = { MutableSpan<GreasePencilStrokeVert> verts = {
static_cast<GreasePencilStrokeVert *>(GPU_vertbuf_get_data(cache->vbo)), static_cast<GreasePencilStrokeVert *>(GPU_vertbuf_get_data(cache->vbo)),
GPU_vertbuf_get_vertex_len(cache->vbo)}; GPU_vertbuf_get_vertex_len(cache->vbo)};
@ -305,6 +325,10 @@ static void grease_pencil_geom_batch_ensure(GreasePencil &grease_pencil, int cfr
GPU_vertbuf_get_vertex_len(cache->edit_points_selection)}; GPU_vertbuf_get_vertex_len(cache->edit_points_selection)};
/* Create IBO. */ /* Create IBO. */
GPU_indexbuf_init(&ibo, GPU_PRIM_TRIS, total_triangles_num, 0xFFFFFFFFu); GPU_indexbuf_init(&ibo, GPU_PRIM_TRIS, total_triangles_num, 0xFFFFFFFFu);
GPU_indexbuf_init_ex(&elb,
GPU_PRIM_LINE_STRIP,
total_line_ids_num,
GPU_vertbuf_get_vertex_len(cache->edit_points_pos));
/* Fill buffers with data. */ /* Fill buffers with data. */
int drawing_start_offset = 0; int drawing_start_offset = 0;
@ -334,7 +358,6 @@ static void grease_pencil_geom_batch_ensure(GreasePencil &grease_pencil, int cfr
MutableSpan<float> selection_slice = edit_points_selection.slice(drawing_start_offset, MutableSpan<float> selection_slice = edit_points_selection.slice(drawing_start_offset,
curves.points_num()); curves.points_num());
selection_float.materialize(selection_slice); selection_float.materialize(selection_slice);
drawing_start_offset += curves.points_num();
auto populate_point = [&](IndexRange verts_range, auto populate_point = [&](IndexRange verts_range,
int curve_i, int curve_i,
@ -394,6 +417,18 @@ static void grease_pencil_geom_batch_ensure(GreasePencil &grease_pencil, int cfr
} }
} }
if (points.size() > 1) {
for (const int point : points) {
GPU_indexbuf_add_generic_vert(&elb, point + drawing_start_offset);
}
if (points.size() > 2 && is_cyclic) {
GPU_indexbuf_add_generic_vert(&elb, points.first() + drawing_start_offset);
}
GPU_indexbuf_add_primitive_restart(&elb);
}
/* Write all the point attributes to the vertex buffers. Create a quad for each point. */ /* Write all the point attributes to the vertex buffers. Create a quad for each point. */
for (const int i : IndexRange(points.size())) { for (const int i : IndexRange(points.size())) {
const int idx = i + 1; const int idx = i + 1;
@ -423,6 +458,7 @@ static void grease_pencil_geom_batch_ensure(GreasePencil &grease_pencil, int cfr
verts_slice.last().mat = -1; verts_slice.last().mat = -1;
} }
}); });
drawing_start_offset += curves.points_num();
} }
if (grease_pencil.runtime->has_stroke_buffer()) { if (grease_pencil.runtime->has_stroke_buffer()) {
@ -488,6 +524,12 @@ static void grease_pencil_geom_batch_ensure(GreasePencil &grease_pencil, int cfr
cache->edit_points = GPU_batch_create(GPU_PRIM_POINTS, cache->edit_points_pos, nullptr); cache->edit_points = GPU_batch_create(GPU_PRIM_POINTS, cache->edit_points_pos, nullptr);
GPU_batch_vertbuf_add(cache->edit_points, cache->edit_points_selection, false); GPU_batch_vertbuf_add(cache->edit_points, cache->edit_points_selection, false);
cache->edit_line_indices = GPU_indexbuf_build(&elb);
cache->edit_lines = GPU_batch_create(
GPU_PRIM_LINE_STRIP, cache->edit_points_pos, cache->edit_line_indices);
GPU_batch_vertbuf_add(cache->edit_lines, cache->edit_points_selection, false);
cache->is_dirty = false; cache->is_dirty = false;
} }
@ -551,6 +593,16 @@ GPUBatch *DRW_cache_grease_pencil_edit_points_get(Object *ob, int cfra)
return cache->edit_points; return cache->edit_points;
} }
GPUBatch *DRW_cache_grease_pencil_edit_lines_get(Object *ob, int cfra)
{
using namespace blender::draw;
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
GreasePencilBatchCache *cache = grease_pencil_batch_cache_get(grease_pencil);
grease_pencil_geom_batch_ensure(grease_pencil, cfra);
return cache->edit_lines;
}
GPUVertBuf *DRW_cache_grease_pencil_position_buffer_get(Object *ob, int cfra) GPUVertBuf *DRW_cache_grease_pencil_position_buffer_get(Object *ob, int cfra)
{ {
using namespace blender::draw; using namespace blender::draw;

View File

@ -401,6 +401,9 @@ typedef struct GreasePencil {
int drawing_array_num; int drawing_array_num;
char _pad[4]; char _pad[4];
/* Color for line (edit mode). */
float line_color[4];
/* Root group of the layer tree. */ /* Root group of the layer tree. */
GreasePencilLayerTreeGroup *root_group_ptr; GreasePencilLayerTreeGroup *root_group_ptr;

View File

@ -292,6 +292,8 @@ static void rna_def_grease_pencil_data(BlenderRNA *brna)
StructRNA *srna; StructRNA *srna;
PropertyRNA *prop; PropertyRNA *prop;
static float default_line_color[4] = {0.6f, 0.6f, 0.6f, 0.5f};
srna = RNA_def_struct(brna, "GreasePencilv3", "ID"); srna = RNA_def_struct(brna, "GreasePencilv3", "ID");
RNA_def_struct_sdna(srna, "GreasePencil"); RNA_def_struct_sdna(srna, "GreasePencil");
RNA_def_struct_ui_text(srna, "Grease Pencil", "Grease Pencil data-block"); RNA_def_struct_ui_text(srna, "Grease Pencil", "Grease Pencil data-block");
@ -328,6 +330,15 @@ static void rna_def_grease_pencil_data(BlenderRNA *brna)
nullptr, /* TODO */ nullptr, /* TODO */
nullptr); nullptr);
RNA_def_property_ui_text(prop, "Layer Groups", "Grease Pencil layer groups"); RNA_def_property_ui_text(prop, "Layer Groups", "Grease Pencil layer groups");
/* Line Color (Edit Mode) */
prop = RNA_def_property(srna, "edit_line_color", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, nullptr, "line_color");
RNA_def_property_array(prop, 4);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_float_array_default(prop, default_line_color);
RNA_def_property_ui_text(prop, "Edit Line Color", "Color for editing line");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_grease_pencil_update");
} }
void RNA_def_grease_pencil(BlenderRNA *brna) void RNA_def_grease_pencil(BlenderRNA *brna)