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)
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 = (
DATA_PT_context_grease_pencil,
DATA_PT_grease_pencil_layers,
DATA_PT_grease_pencil_display,
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->active_layer = nullptr;
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*/,
@ -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()));
}
copy_v4_v4(grease_pencil_dst->line_color, grease_pencil_src->line_color);
/* Make sure the runtime pointer exists. */
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);
}
float empty_color[4];
zero_v4(empty_color);
DRW_PASS_CREATE(psl->edit_curves_lines_ps[i], (state | pd->clipping_state));
sh = OVERLAY_shader_edit_particle_strand();
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_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_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();
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);
@ -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)
{
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;
if (points_grp) {
GPUBatch *geom = DRW_cache_grease_pencil_edit_points_get(ob, pd->cfra);
DRW_shgroup_call_no_cull(points_grp, geom, ob);
GPUBatch *geom_points = DRW_cache_grease_pencil_edit_points_get(ob, pd->cfra);
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;
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();
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_bool_copy(grp, "useWeight", pd->edit_particle.use_weight);
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();
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_gpencil_points_grp;
DRWShadingGroup *edit_gpencil_wires_grp;
DRWShadingGroup *edit_grease_pencil_wires_grp;
DRWShadingGroup *edit_grease_pencil_points_grp;
DRWShadingGroup *edit_gpencil_curve_handle_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")
.sampler(0, ImageType::FLOAT_1D, "weightTex")
.push_constant(Type::BOOL, "useWeight")
.push_constant(Type::VEC4, "replaceColor")
.vertex_out(overlay_edit_smooth_color_iface)
.fragment_out(0, Type::VEC4, "fragColor")
.vertex_source("overlay_edit_particle_strand_vert.glsl")

View File

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

View File

@ -37,11 +37,14 @@ struct GreasePencilBatchCache {
/** Batches */
GPUBatch *geom_batch;
GPUBatch *edit_points;
GPUBatch *edit_lines;
/* Crazy-space point positions for original points. */
GPUVertBuf *edit_points_pos;
/* Selection of original points. */
GPUVertBuf *edit_points_selection;
/* Indices for lines segments. */
GPUIndexBuf *edit_line_indices;
/** Cache 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_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_selection);
GPU_INDEXBUF_DISCARD_SAFE(cache->edit_line_indices);
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_verts_num = 0;
int total_triangles_num = 0;
int total_line_ids_num = 0;
int v_offset = 0;
Vector<Array<int>> verts_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;
}
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;
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);
GPUIndexBufBuilder ibo;
GPUIndexBufBuilder elb;
MutableSpan<GreasePencilStrokeVert> verts = {
static_cast<GreasePencilStrokeVert *>(GPU_vertbuf_get_data(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)};
/* Create IBO. */
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. */
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,
curves.points_num());
selection_float.materialize(selection_slice);
drawing_start_offset += curves.points_num();
auto populate_point = [&](IndexRange verts_range,
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. */
for (const int i : IndexRange(points.size())) {
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;
}
});
drawing_start_offset += curves.points_num();
}
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);
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;
}
@ -551,6 +593,16 @@ GPUBatch *DRW_cache_grease_pencil_edit_points_get(Object *ob, int cfra)
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)
{
using namespace blender::draw;

View File

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

View File

@ -292,6 +292,8 @@ static void rna_def_grease_pencil_data(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
static float default_line_color[4] = {0.6f, 0.6f, 0.6f, 0.5f};
srna = RNA_def_struct(brna, "GreasePencilv3", "ID");
RNA_def_struct_sdna(srna, "GreasePencil");
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);
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)