Grease Pencil: Use Curve overlay for Bezier handles
This makes it so that Grease Pencil Bezier handles use the same colors and shaders as `Curves` Objects. This also makes the handles follow `handle_display` and add the option the the edit mode overlay. Pull Request: https://projects.blender.org/blender/blender/pulls/141524
This commit is contained in:
committed by
Falk David
parent
f271a48b6b
commit
dfeeaa98fd
@@ -7950,6 +7950,8 @@ class VIEW3D_PT_overlay_grease_pencil_options(Panel):
|
||||
col.prop(overlay, "use_gpencil_edit_lines", text="Edit Lines")
|
||||
col = split.column()
|
||||
col.prop(overlay, "use_gpencil_multiedit_line_only", text="Only in Multiframe")
|
||||
row = layout.row()
|
||||
row.prop(overlay, "display_handle", text="Handles")
|
||||
|
||||
if ob.mode == 'EDIT':
|
||||
split = layout.split()
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace blender::draw::overlay {
|
||||
class GreasePencil : Overlay {
|
||||
private:
|
||||
PassSimple edit_grease_pencil_ps_ = {"GPencil Edit"};
|
||||
PassSimple::Sub *edit_handles_ = nullptr;
|
||||
PassSimple::Sub *edit_points_ = nullptr;
|
||||
PassSimple::Sub *edit_lines_ = nullptr;
|
||||
|
||||
@@ -107,6 +108,7 @@ class GreasePencil : Overlay {
|
||||
break;
|
||||
}
|
||||
|
||||
edit_handles_ = nullptr;
|
||||
edit_points_ = nullptr;
|
||||
edit_lines_ = nullptr;
|
||||
|
||||
@@ -119,6 +121,15 @@ class GreasePencil : Overlay {
|
||||
DRW_STATE_BLEND_ALPHA,
|
||||
state.clipping_plane_count);
|
||||
|
||||
{
|
||||
auto &sub = pass.sub("Handles");
|
||||
sub.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA, state.clipping_plane_count);
|
||||
sub.shader_set(res.shaders->curve_edit_handles.get());
|
||||
sub.push_constant("show_curve_handles", state.overlay.handle_display != CURVE_HANDLE_NONE);
|
||||
sub.push_constant("curve_handle_display", int(state.overlay.handle_display));
|
||||
edit_handles_ = ⊂
|
||||
}
|
||||
|
||||
if (show_points_) {
|
||||
auto &sub = pass.sub("Points");
|
||||
sub.shader_set(res.shaders->curve_edit_points.get());
|
||||
@@ -126,6 +137,7 @@ class GreasePencil : Overlay {
|
||||
sub.push_constant("use_weight", show_weight_);
|
||||
sub.push_constant("use_grease_pencil", true);
|
||||
sub.push_constant("do_stroke_endpoints", show_direction);
|
||||
sub.push_constant("curve_handle_display", int(state.overlay.handle_display));
|
||||
edit_points_ = ⊂
|
||||
}
|
||||
|
||||
@@ -173,6 +185,12 @@ class GreasePencil : Overlay {
|
||||
|
||||
Object *ob = ob_ref.object;
|
||||
|
||||
{
|
||||
gpu::Batch *geom = DRW_cache_grease_pencil_edit_handles_get(state.scene, ob);
|
||||
if (geom) {
|
||||
edit_handles_->draw_expand(geom, GPU_PRIM_TRIS, 8, 1, manager.unique_handle(ob_ref));
|
||||
}
|
||||
}
|
||||
if (show_points_) {
|
||||
gpu::Batch *geom = show_weight_ ?
|
||||
DRW_cache_grease_pencil_weight_points_get(state.scene, ob) :
|
||||
|
||||
@@ -152,6 +152,7 @@ gpu::Batch *DRW_cache_volume_selection_surface_get(Object *ob);
|
||||
gpu::Batch *DRW_cache_grease_pencil_get(const Scene *scene, Object *ob);
|
||||
gpu::Batch *DRW_cache_grease_pencil_edit_points_get(const Scene *scene, Object *ob);
|
||||
gpu::Batch *DRW_cache_grease_pencil_edit_lines_get(const Scene *scene, Object *ob);
|
||||
gpu::Batch *DRW_cache_grease_pencil_edit_handles_get(const Scene *scene, Object *ob);
|
||||
gpu::VertBuf *DRW_cache_grease_pencil_position_buffer_get(const Scene *scene, Object *ob);
|
||||
gpu::VertBuf *DRW_cache_grease_pencil_color_buffer_get(const Scene *scene, Object *ob);
|
||||
gpu::Batch *DRW_cache_grease_pencil_weight_points_get(const Scene *scene, Object *ob);
|
||||
|
||||
@@ -36,6 +36,14 @@
|
||||
|
||||
namespace blender::draw {
|
||||
|
||||
#define EDIT_CURVES_NURBS_CONTROL_POINT (1u)
|
||||
#define EDIT_CURVES_BEZIER_HANDLE (1u << 1)
|
||||
#define EDIT_CURVES_ACTIVE_HANDLE (1u << 2)
|
||||
/* Bezier curve control point lying on the curve.
|
||||
* The one between left and right handles. */
|
||||
#define EDIT_CURVES_BEZIER_KNOT (1u << 3)
|
||||
#define EDIT_CURVES_HANDLE_TYPES_SHIFT (4u)
|
||||
|
||||
struct GreasePencilBatchCache {
|
||||
/** Instancing Data */
|
||||
gpu::VertBuf *vbo;
|
||||
@@ -47,6 +55,7 @@ struct GreasePencilBatchCache {
|
||||
gpu::Batch *lines_batch;
|
||||
gpu::Batch *edit_points;
|
||||
gpu::Batch *edit_lines;
|
||||
gpu::Batch *edit_handles;
|
||||
|
||||
/* Crazy-space point positions for original points. */
|
||||
gpu::VertBuf *edit_points_pos;
|
||||
@@ -64,6 +73,21 @@ struct GreasePencilBatchCache {
|
||||
/* Indices for lines segments. */
|
||||
gpu::IndexBuf *edit_line_indices;
|
||||
|
||||
/* Additional data needed for shader to choose color for each point in edit_points_pos.
|
||||
* If first bit is set, then point is NURBS control point. EDIT_CURVES_NURBS_CONTROL_POINT is
|
||||
* used to set and test. If second, then point is Bezier handle point. Set and tested with
|
||||
* EDIT_CURVES_BEZIER_HANDLE.
|
||||
* In Bezier case two handle types of HandleType are also encoded.
|
||||
* Byte structure for Bezier knot point (handle middle point):
|
||||
* | left handle type | right handle type | | BEZIER| NURBS|
|
||||
* | 7 6 | 5 4 | 3 2 | 1 | 0 |
|
||||
*
|
||||
* If it is left or right handle point, then same handle type is repeated in both slots.
|
||||
*/
|
||||
gpu::VertBuf *edit_points_info;
|
||||
|
||||
gpu::IndexBuf *edit_handles_ibo;
|
||||
|
||||
/** Cache is dirty. */
|
||||
bool is_dirty;
|
||||
/** Last cached frame. */
|
||||
@@ -164,11 +188,14 @@ static void grease_pencil_batch_cache_clear(GreasePencil &grease_pencil)
|
||||
GPU_BATCH_DISCARD_SAFE(cache->lines_batch);
|
||||
GPU_BATCH_DISCARD_SAFE(cache->edit_points);
|
||||
GPU_BATCH_DISCARD_SAFE(cache->edit_lines);
|
||||
GPU_BATCH_DISCARD_SAFE(cache->edit_handles);
|
||||
|
||||
GPU_VERTBUF_DISCARD_SAFE(cache->edit_points_pos);
|
||||
GPU_VERTBUF_DISCARD_SAFE(cache->edit_points_selection);
|
||||
GPU_VERTBUF_DISCARD_SAFE(cache->edit_points_vflag);
|
||||
GPU_INDEXBUF_DISCARD_SAFE(cache->edit_points_indices);
|
||||
GPU_VERTBUF_DISCARD_SAFE(cache->edit_points_info);
|
||||
GPU_INDEXBUF_DISCARD_SAFE(cache->edit_handles_ibo);
|
||||
|
||||
GPU_VERTBUF_DISCARD_SAFE(cache->edit_line_pos);
|
||||
GPU_VERTBUF_DISCARD_SAFE(cache->edit_line_selection);
|
||||
@@ -598,16 +625,12 @@ static void index_buf_add_nurbs_lines(Object &object,
|
||||
*r_drawing_line_index = line_index;
|
||||
}
|
||||
|
||||
static void index_buf_add_bezier_lines(Object &object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
int layer_index,
|
||||
IndexMaskMemory &memory,
|
||||
MutableSpan<uint> lines_data,
|
||||
int *r_drawing_line_index,
|
||||
int *r_drawing_line_start_offset)
|
||||
static void index_buf_add_bezier_handle_lines(const IndexMask bezier_points,
|
||||
const int all_points,
|
||||
MutableSpan<uint2> handle_lines,
|
||||
int *r_drawing_line_index,
|
||||
int *r_drawing_line_start_offset)
|
||||
{
|
||||
const IndexMask bezier_points = ed::greasepencil::retrieve_visible_bezier_handle_points(
|
||||
object, drawing, layer_index, memory);
|
||||
if (bezier_points.is_empty()) {
|
||||
return;
|
||||
}
|
||||
@@ -615,17 +638,15 @@ static void index_buf_add_bezier_lines(Object &object,
|
||||
const int offset = *r_drawing_line_start_offset;
|
||||
int line_index = *r_drawing_line_index;
|
||||
|
||||
/* Add all bezier points. */
|
||||
for (const int point : bezier_points.index_range()) {
|
||||
lines_data[line_index++] = point + bezier_points.size() * 0 + offset;
|
||||
lines_data[line_index++] = point + bezier_points.size() * 1 + offset;
|
||||
lines_data[line_index++] = point + bezier_points.size() * 2 + offset;
|
||||
|
||||
lines_data[line_index++] = gpu::RESTART_INDEX;
|
||||
}
|
||||
/* Add all bezier handle lines. */
|
||||
bezier_points.foreach_index([&](const int point_i, const int pos) {
|
||||
handle_lines[line_index++] = uint2(offset + all_points + pos + bezier_points.size() * 0,
|
||||
offset + point_i);
|
||||
handle_lines[line_index++] = uint2(offset + all_points + pos + bezier_points.size() * 1,
|
||||
offset + point_i);
|
||||
});
|
||||
|
||||
*r_drawing_line_index = line_index;
|
||||
*r_drawing_line_start_offset += bezier_points.size() * 3;
|
||||
}
|
||||
|
||||
static void index_buf_add_points(Object &object,
|
||||
@@ -658,16 +679,17 @@ static void index_buf_add_points(Object &object,
|
||||
*r_drawing_start_offset += curves.points_num();
|
||||
}
|
||||
|
||||
static void index_buf_add_bezier_line_points(Object &object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
int layer_index,
|
||||
IndexMaskMemory &memory,
|
||||
static uint32_t bezier_data_value(int8_t handle_type, bool is_active)
|
||||
{
|
||||
return (handle_type << EDIT_CURVES_HANDLE_TYPES_SHIFT) | EDIT_CURVES_BEZIER_HANDLE |
|
||||
(is_active ? EDIT_CURVES_ACTIVE_HANDLE : 0);
|
||||
}
|
||||
|
||||
static void index_buf_add_bezier_line_points(const IndexMask bezier_points,
|
||||
MutableSpan<uint> points_data,
|
||||
int *r_drawing_point_index,
|
||||
int *r_drawing_start_offset)
|
||||
{
|
||||
const IndexMask bezier_points = ed::greasepencil::retrieve_visible_bezier_handle_points(
|
||||
object, drawing, layer_index, memory);
|
||||
if (bezier_points.is_empty()) {
|
||||
return;
|
||||
}
|
||||
@@ -729,6 +751,9 @@ static void grease_pencil_edit_batch_ensure(Object &object,
|
||||
static const GPUVertFormat format_edit_line_selection = GPU_vertformat_from_attribute(
|
||||
"selection", gpu::VertAttrType::SFLOAT_32);
|
||||
|
||||
static const GPUVertFormat format_edit_points_info = GPU_vertformat_from_attribute(
|
||||
"data", gpu::VertAttrType::UINT_32);
|
||||
|
||||
GPUUsageType vbo_flag = GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY;
|
||||
cache->edit_points_pos = GPU_vertbuf_create_with_format_ex(format_edit_points_pos, vbo_flag);
|
||||
cache->edit_points_selection = GPU_vertbuf_create_with_format_ex(format_edit_points_selection,
|
||||
@@ -737,6 +762,7 @@ static void grease_pencil_edit_batch_ensure(Object &object,
|
||||
cache->edit_line_pos = GPU_vertbuf_create_with_format_ex(format_edit_line_pos, vbo_flag);
|
||||
cache->edit_line_selection = GPU_vertbuf_create_with_format_ex(format_edit_line_selection,
|
||||
vbo_flag);
|
||||
cache->edit_points_info = GPU_vertbuf_create_with_format_ex(format_edit_points_info, vbo_flag);
|
||||
|
||||
int total_points_num = 0;
|
||||
for (const ed::greasepencil::DrawingInfo &info : drawings) {
|
||||
@@ -760,7 +786,7 @@ static void grease_pencil_edit_batch_ensure(Object &object,
|
||||
for (const ed::greasepencil::DrawingInfo &info : drawings) {
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask bezier_points = ed::greasepencil::retrieve_visible_bezier_handle_points(
|
||||
object, info.drawing, info.layer_index, memory);
|
||||
object, info.drawing, info.layer_index, CURVE_HANDLE_ALL, memory);
|
||||
|
||||
total_bezier_point_num += bezier_points.size();
|
||||
}
|
||||
@@ -776,8 +802,6 @@ static void grease_pencil_edit_batch_ensure(Object &object,
|
||||
|
||||
/* Add two for each bezier point, (one left, one right). */
|
||||
total_points_num += total_bezier_point_num * 2;
|
||||
/* Add three for each bezier point, (one left, one right and one for the center point). */
|
||||
total_line_points_num += total_bezier_point_num * 3;
|
||||
|
||||
if (total_points_num == 0) {
|
||||
return;
|
||||
@@ -788,18 +812,22 @@ static void grease_pencil_edit_batch_ensure(Object &object,
|
||||
GPU_vertbuf_data_alloc(*cache->edit_points_vflag, total_points_num);
|
||||
GPU_vertbuf_data_alloc(*cache->edit_line_pos, total_line_points_num);
|
||||
GPU_vertbuf_data_alloc(*cache->edit_line_selection, total_line_points_num);
|
||||
GPU_vertbuf_data_alloc(*cache->edit_points_info, total_points_num);
|
||||
|
||||
MutableSpan<float3> edit_points = cache->edit_points_pos->data<float3>();
|
||||
MutableSpan<float> edit_points_selection = cache->edit_points_selection->data<float>();
|
||||
MutableSpan<uint32_t> edit_points_vflag = cache->edit_points_vflag->data<uint32_t>();
|
||||
MutableSpan<float3> edit_line_points = cache->edit_line_pos->data<float3>();
|
||||
MutableSpan<float> edit_line_selection = cache->edit_line_selection->data<float>();
|
||||
MutableSpan<uint32_t> edit_points_info = cache->edit_points_info->data<uint32_t>();
|
||||
edit_points_selection.fill(0.0f);
|
||||
edit_points_vflag.fill(0);
|
||||
edit_points_info.fill(0);
|
||||
edit_line_selection.fill(0.0f);
|
||||
|
||||
int visible_points_num = 0;
|
||||
int total_line_ids_num = 0;
|
||||
int total_bezier_num = 0;
|
||||
int drawing_start_offset = 0;
|
||||
int drawing_line_start_offset = 0;
|
||||
for (const ed::greasepencil::DrawingInfo &info : drawings) {
|
||||
@@ -838,9 +866,9 @@ static void grease_pencil_edit_batch_ensure(Object &object,
|
||||
|
||||
/* Flag the start and end points. */
|
||||
for (const int curve_i : curves.curves_range()) {
|
||||
const IndexRange points = points_by_curve[curve_i].shift(drawing_start_offset);
|
||||
edit_points_vflag[points.first()] |= GREASE_PENCIL_EDIT_STROKE_START;
|
||||
edit_points_vflag[points.last()] |= GREASE_PENCIL_EDIT_STROKE_END;
|
||||
const IndexRange sub_points = points_by_curve[curve_i].shift(drawing_start_offset);
|
||||
edit_points_vflag[sub_points.first()] |= GREASE_PENCIL_EDIT_STROKE_START;
|
||||
edit_points_vflag[sub_points.last()] |= GREASE_PENCIL_EDIT_STROKE_END;
|
||||
}
|
||||
|
||||
const IndexMask selected_editable_points =
|
||||
@@ -901,7 +929,7 @@ static void grease_pencil_edit_batch_ensure(Object &object,
|
||||
&total_line_ids_num);
|
||||
|
||||
const IndexMask bezier_points = ed::greasepencil::retrieve_visible_bezier_handle_points(
|
||||
object, info.drawing, info.layer_index, memory);
|
||||
object, info.drawing, info.layer_index, CURVE_HANDLE_ALL, memory);
|
||||
if (bezier_points.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
@@ -938,48 +966,23 @@ static void grease_pencil_edit_batch_ensure(Object &object,
|
||||
array_utils::gather(selected_left, bezier_points, selection_slice_left);
|
||||
array_utils::gather(selected_right, bezier_points, selection_slice_right);
|
||||
|
||||
const IndexRange eval_left_slice = IndexRange(drawing_line_start_offset, bezier_points.size());
|
||||
const IndexRange eval_center_slice = IndexRange(
|
||||
drawing_line_start_offset + bezier_points.size(), bezier_points.size());
|
||||
const IndexRange eval_right_slice = IndexRange(
|
||||
drawing_line_start_offset + bezier_points.size() * 2, bezier_points.size());
|
||||
const VArray<int8_t> types_left = curves.handle_types_left();
|
||||
const VArray<int8_t> types_right = curves.handle_types_right();
|
||||
|
||||
MutableSpan<float3> positions_eval_left_slice = edit_line_points.slice(eval_left_slice);
|
||||
MutableSpan<float3> positions_eval_center_slice = edit_line_points.slice(eval_center_slice);
|
||||
MutableSpan<float3> positions_eval_right_slice = edit_line_points.slice(eval_right_slice);
|
||||
bezier_points.foreach_index([&](const int point_i, const int pos) {
|
||||
const bool selected = selected_point[point_i] || selected_left[point_i] ||
|
||||
selected_right[point_i];
|
||||
edit_points_info.slice(left_slice)[pos] = bezier_data_value(types_left[point_i], selected);
|
||||
edit_points_info.slice(right_slice)[pos] = bezier_data_value(types_right[point_i], selected);
|
||||
|
||||
array_utils::copy(positions_slice_left.as_span(), positions_eval_left_slice);
|
||||
array_utils::copy(positions_slice_right.as_span(), positions_eval_right_slice);
|
||||
|
||||
/* This will copy over the position but without the layer transform. */
|
||||
array_utils::gather(positions, bezier_points, positions_eval_center_slice);
|
||||
|
||||
/* Go through the position and apply the layer transform. */
|
||||
threading::parallel_for(bezier_points.index_range(), 1024, [&](const IndexRange range) {
|
||||
copy_transformed_positions(positions_eval_center_slice,
|
||||
range,
|
||||
layer_space_to_object_space,
|
||||
positions_eval_center_slice);
|
||||
edit_points_info.slice(points)[point_i] = EDIT_CURVES_BEZIER_KNOT;
|
||||
});
|
||||
|
||||
MutableSpan<float> selection_eval_slice_left = edit_line_selection.slice(eval_left_slice);
|
||||
MutableSpan<float> selection_eval_slice_center = edit_line_selection.slice(eval_center_slice);
|
||||
MutableSpan<float> selection_eval_slice_right = edit_line_selection.slice(eval_right_slice);
|
||||
array_utils::copy(selection_slice_left.as_span(), selection_eval_slice_left);
|
||||
array_utils::copy(selection_slice_right.as_span(), selection_eval_slice_right);
|
||||
|
||||
array_utils::gather(selected_point, bezier_points, selection_eval_slice_center);
|
||||
|
||||
/* Add two for each bezier point, (one left, one right). */
|
||||
visible_points_num += bezier_points.size() * 2;
|
||||
drawing_start_offset += bezier_points.size() * 2;
|
||||
|
||||
/* Add three for each bezier point, (one left, one right and one for the center point). */
|
||||
drawing_line_start_offset += bezier_points.size() * 3;
|
||||
total_line_ids_num += bezier_points.size() * 3;
|
||||
|
||||
/* Add one id for the restart after every bezier. */
|
||||
total_line_ids_num += bezier_points.size();
|
||||
total_bezier_num += bezier_points.size();
|
||||
}
|
||||
|
||||
GPUIndexBufBuilder lines_builder;
|
||||
@@ -993,6 +996,11 @@ static void grease_pencil_edit_batch_ensure(Object &object,
|
||||
MutableSpan<uint> points_data = GPU_indexbuf_get_data(&points_builder);
|
||||
int points_ibo_index = 0;
|
||||
|
||||
GPUIndexBufBuilder handles_builder;
|
||||
GPU_indexbuf_init(&handles_builder, GPU_PRIM_LINES, total_bezier_num * 2, total_points_num);
|
||||
MutableSpan<uint2> handle_lines = GPU_indexbuf_get_data(&handles_builder).cast<uint2>();
|
||||
|
||||
int handle_lines_id = 0;
|
||||
/* Fill line index and point index buffers with data. */
|
||||
drawing_start_offset = 0;
|
||||
drawing_line_start_offset = 0;
|
||||
@@ -1009,6 +1017,9 @@ static void grease_pencil_edit_batch_ensure(Object &object,
|
||||
&drawing_line_start_offset);
|
||||
|
||||
if (!layer->is_locked()) {
|
||||
const IndexMask bezier_points = ed::greasepencil::retrieve_visible_bezier_handle_points(
|
||||
object, info.drawing, info.layer_index, CURVE_HANDLE_ALL, memory);
|
||||
|
||||
index_buf_add_nurbs_lines(object,
|
||||
info.drawing,
|
||||
info.layer_index,
|
||||
@@ -1016,13 +1027,11 @@ static void grease_pencil_edit_batch_ensure(Object &object,
|
||||
lines_data,
|
||||
&lines_ibo_index,
|
||||
&drawing_line_start_offset);
|
||||
index_buf_add_bezier_lines(object,
|
||||
info.drawing,
|
||||
info.layer_index,
|
||||
memory,
|
||||
lines_data,
|
||||
&lines_ibo_index,
|
||||
&drawing_line_start_offset);
|
||||
index_buf_add_bezier_handle_lines(bezier_points,
|
||||
info.drawing.strokes().points_num(),
|
||||
handle_lines,
|
||||
&handle_lines_id,
|
||||
&drawing_start_offset);
|
||||
index_buf_add_points(object,
|
||||
info.drawing,
|
||||
info.layer_index,
|
||||
@@ -1030,35 +1039,38 @@ static void grease_pencil_edit_batch_ensure(Object &object,
|
||||
points_data,
|
||||
&points_ibo_index,
|
||||
&drawing_start_offset);
|
||||
index_buf_add_bezier_line_points(object,
|
||||
info.drawing,
|
||||
info.layer_index,
|
||||
memory,
|
||||
points_data,
|
||||
&points_ibo_index,
|
||||
&drawing_start_offset);
|
||||
index_buf_add_bezier_line_points(
|
||||
bezier_points, points_data, &points_ibo_index, &drawing_start_offset);
|
||||
}
|
||||
}
|
||||
|
||||
cache->edit_line_indices = GPU_indexbuf_build_ex(&lines_builder, 0, total_points_num, true);
|
||||
cache->edit_points_indices = GPU_indexbuf_build_ex(&points_builder, 0, total_points_num, false);
|
||||
cache->edit_handles_ibo = GPU_indexbuf_build_ex(&handles_builder, 0, total_points_num, false);
|
||||
|
||||
/* Create the batches */
|
||||
cache->edit_points = GPU_batch_create(
|
||||
GPU_PRIM_POINTS, cache->edit_points_pos, cache->edit_points_indices);
|
||||
GPU_batch_vertbuf_add(cache->edit_points, cache->edit_points_selection, false);
|
||||
GPU_batch_vertbuf_add(cache->edit_points, cache->edit_points_vflag, false);
|
||||
GPU_batch_vertbuf_add(cache->edit_points, cache->edit_points_info, false);
|
||||
|
||||
cache->edit_lines = GPU_batch_create(
|
||||
GPU_PRIM_LINE_STRIP, cache->edit_line_pos, cache->edit_line_indices);
|
||||
GPU_batch_vertbuf_add(cache->edit_lines, cache->edit_line_selection, false);
|
||||
|
||||
cache->edit_handles = GPU_batch_create(
|
||||
GPU_PRIM_LINES, cache->edit_points_pos, cache->edit_handles_ibo);
|
||||
GPU_batch_vertbuf_add(cache->edit_handles, cache->edit_points_info, false);
|
||||
GPU_batch_vertbuf_add(cache->edit_handles, cache->edit_points_selection, false);
|
||||
|
||||
/* Allow creation of buffer texture. */
|
||||
GPU_vertbuf_use(cache->edit_points_pos);
|
||||
GPU_vertbuf_use(cache->edit_line_pos);
|
||||
GPU_vertbuf_use(cache->edit_points_selection);
|
||||
GPU_vertbuf_use(cache->edit_line_selection);
|
||||
GPU_vertbuf_use(cache->edit_points_vflag);
|
||||
GPU_vertbuf_use(cache->edit_points_info);
|
||||
|
||||
cache->is_dirty = false;
|
||||
}
|
||||
@@ -1496,7 +1508,7 @@ gpu::Batch *DRW_cache_grease_pencil_edit_points_get(const Scene *scene, Object *
|
||||
GreasePencilBatchCache *cache = grease_pencil_batch_cache_get(grease_pencil);
|
||||
grease_pencil_edit_batch_ensure(*ob, grease_pencil, *scene);
|
||||
|
||||
/* Can be `nullptr` when there's no grease pencil drawing visible. */
|
||||
/* Can be `nullptr` when there's no Grease Pencil drawing visible. */
|
||||
return cache->edit_points;
|
||||
}
|
||||
|
||||
@@ -1506,10 +1518,20 @@ gpu::Batch *DRW_cache_grease_pencil_edit_lines_get(const Scene *scene, Object *o
|
||||
GreasePencilBatchCache *cache = grease_pencil_batch_cache_get(grease_pencil);
|
||||
grease_pencil_edit_batch_ensure(*ob, grease_pencil, *scene);
|
||||
|
||||
/* Can be `nullptr` when there's no grease pencil drawing visible. */
|
||||
/* Can be `nullptr` when there's no Grease Pencil drawing visible. */
|
||||
return cache->edit_lines;
|
||||
}
|
||||
|
||||
gpu::Batch *DRW_cache_grease_pencil_edit_handles_get(const Scene *scene, Object *ob)
|
||||
{
|
||||
GreasePencil &grease_pencil = DRW_object_get_data_for_drawing<GreasePencil>(*ob);
|
||||
GreasePencilBatchCache *cache = grease_pencil_batch_cache_get(grease_pencil);
|
||||
grease_pencil_edit_batch_ensure(*ob, grease_pencil, *scene);
|
||||
|
||||
/* Can be `nullptr` when there's no Grease Pencil drawing visible. */
|
||||
return cache->edit_handles;
|
||||
}
|
||||
|
||||
gpu::VertBuf *DRW_cache_grease_pencil_position_buffer_get(const Scene *scene, Object *ob)
|
||||
{
|
||||
GreasePencil &grease_pencil = DRW_object_get_data_for_drawing<GreasePencil>(*ob);
|
||||
@@ -1534,7 +1556,7 @@ gpu::Batch *DRW_cache_grease_pencil_weight_points_get(const Scene *scene, Object
|
||||
GreasePencilBatchCache *cache = grease_pencil_batch_cache_get(grease_pencil);
|
||||
grease_pencil_weight_batch_ensure(*ob, grease_pencil, *scene);
|
||||
|
||||
/* Can be `nullptr` when there's no grease pencil drawing visible. */
|
||||
/* Can be `nullptr` when there's no Grease Pencil drawing visible. */
|
||||
return cache->edit_points;
|
||||
}
|
||||
|
||||
@@ -1544,7 +1566,7 @@ gpu::Batch *DRW_cache_grease_pencil_weight_lines_get(const Scene *scene, Object
|
||||
GreasePencilBatchCache *cache = grease_pencil_batch_cache_get(grease_pencil);
|
||||
grease_pencil_weight_batch_ensure(*ob, grease_pencil, *scene);
|
||||
|
||||
/* Can be `nullptr` when there's no grease pencil drawing visible. */
|
||||
/* Can be `nullptr` when there's no Grease Pencil drawing visible. */
|
||||
return cache->edit_lines;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "BKE_brush.hh"
|
||||
#include "BKE_colortools.hh"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_curves_utils.hh"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_material.hh"
|
||||
@@ -1186,10 +1187,9 @@ IndexMask retrieve_visible_points(Object &object,
|
||||
});
|
||||
}
|
||||
|
||||
IndexMask retrieve_visible_bezier_handle_points(Object &object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
const int layer_index,
|
||||
IndexMaskMemory &memory)
|
||||
IndexMask retrieve_visible_bezier_strokes(Object &object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
const bke::CurvesGeometry &curves = drawing.strokes();
|
||||
|
||||
@@ -1197,8 +1197,79 @@ IndexMask retrieve_visible_bezier_handle_points(Object &object,
|
||||
return IndexMask(0);
|
||||
}
|
||||
|
||||
/* Make sure that the handle position attributes exists. */
|
||||
if (curves.handle_positions_left().is_empty() || curves.handle_positions_right().is_empty()) {
|
||||
const IndexRange curves_range = curves.curves_range();
|
||||
const VArray<int8_t> curve_types = curves.curve_types();
|
||||
const std::array<int, CURVE_TYPES_NUM> type_counts = curves.curve_type_counts();
|
||||
|
||||
const IndexMask bezier_strokes = bke::curves::indices_for_type(
|
||||
curve_types, type_counts, CURVE_TYPE_BEZIER, curves_range, memory);
|
||||
|
||||
const IndexMask visible_strokes = ed::greasepencil::retrieve_visible_strokes(
|
||||
object, drawing, memory);
|
||||
|
||||
return IndexMask::from_intersection(visible_strokes, bezier_strokes, memory);
|
||||
}
|
||||
|
||||
IndexMask retrieve_visible_bezier_points(Object &object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
const bke::CurvesGeometry &curves = drawing.strokes();
|
||||
|
||||
if (!curves.has_curve_with_type(CURVE_TYPE_BEZIER)) {
|
||||
return IndexMask(0);
|
||||
}
|
||||
|
||||
const IndexMask visible_bezier_strokes = retrieve_visible_bezier_strokes(
|
||||
object, drawing, memory);
|
||||
|
||||
return IndexMask::from_ranges(curves.points_by_curve(), visible_bezier_strokes, memory);
|
||||
}
|
||||
|
||||
IndexMask retrieve_visible_bezier_handle_strokes(Object &object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
const int handle_display,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
if (handle_display == CURVE_HANDLE_NONE) {
|
||||
return IndexMask(0);
|
||||
}
|
||||
|
||||
const bke::CurvesGeometry &curves = drawing.strokes();
|
||||
|
||||
if (!curves.has_curve_with_type(CURVE_TYPE_BEZIER)) {
|
||||
return IndexMask(0);
|
||||
}
|
||||
|
||||
const IndexMask visible_bezier_strokes = retrieve_visible_bezier_strokes(
|
||||
object, drawing, memory);
|
||||
|
||||
if (handle_display == CURVE_HANDLE_ALL) {
|
||||
return visible_bezier_strokes;
|
||||
}
|
||||
|
||||
/* handle_display == CURVE_HANDLE_SELECTED */
|
||||
const IndexMask selected_strokes = ed::curves::retrieve_selected_curves(curves, memory);
|
||||
return IndexMask::from_intersection(visible_bezier_strokes, selected_strokes, memory);
|
||||
}
|
||||
|
||||
IndexMask retrieve_visible_bezier_handle_points(Object &object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
const int layer_index,
|
||||
const int handle_display,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
if (handle_display == CURVE_HANDLE_NONE) {
|
||||
return IndexMask(0);
|
||||
}
|
||||
else if (handle_display == CURVE_HANDLE_ALL) {
|
||||
return retrieve_visible_bezier_points(object, drawing, memory);
|
||||
}
|
||||
/* else handle_display == CURVE_HANDLE_SELECTED */
|
||||
|
||||
const bke::CurvesGeometry &curves = drawing.strokes();
|
||||
|
||||
if (!curves.has_curve_with_type(CURVE_TYPE_BEZIER)) {
|
||||
return IndexMask(0);
|
||||
}
|
||||
|
||||
@@ -1230,15 +1301,16 @@ IndexMask retrieve_visible_bezier_handle_elements(Object &object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
const int layer_index,
|
||||
const bke::AttrDomain selection_domain,
|
||||
const int handle_display,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
if (selection_domain == bke::AttrDomain::Curve) {
|
||||
return ed::greasepencil::retrieve_editable_and_selected_strokes(
|
||||
object, drawing, layer_index, memory);
|
||||
return ed::greasepencil::retrieve_visible_bezier_handle_strokes(
|
||||
object, drawing, handle_display, memory);
|
||||
}
|
||||
if (selection_domain == bke::AttrDomain::Point) {
|
||||
return ed::greasepencil::retrieve_visible_bezier_handle_points(
|
||||
object, drawing, layer_index, memory);
|
||||
object, drawing, layer_index, handle_display, memory);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -411,14 +411,27 @@ IndexMask retrieve_visible_points(Object &object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
IndexMaskMemory &memory);
|
||||
|
||||
IndexMask retrieve_visible_bezier_strokes(Object &object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
IndexMaskMemory &memory);
|
||||
IndexMask retrieve_visible_bezier_points(Object &object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
IndexMaskMemory &memory);
|
||||
|
||||
IndexMask retrieve_visible_bezier_handle_strokes(Object &object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
int handle_display,
|
||||
IndexMaskMemory &memory);
|
||||
IndexMask retrieve_visible_bezier_handle_points(Object &object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
int layer_index,
|
||||
int handle_display,
|
||||
IndexMaskMemory &memory);
|
||||
IndexMask retrieve_visible_bezier_handle_elements(Object &object,
|
||||
const bke::greasepencil::Drawing &drawing,
|
||||
int layer_index,
|
||||
bke::AttrDomain selection_domain,
|
||||
int handle_display,
|
||||
IndexMaskMemory &memory);
|
||||
|
||||
IndexMask retrieve_editable_and_selected_strokes(Object &grease_pencil_object,
|
||||
|
||||
@@ -1187,7 +1187,12 @@ static bool do_lasso_select_grease_pencil(const ViewContext *vc,
|
||||
ob_eval, *object, info.drawing);
|
||||
const IndexMask visible_handle_elements =
|
||||
ed::greasepencil::retrieve_visible_bezier_handle_elements(
|
||||
*object, info.drawing, info.layer_index, selection_domain, memory);
|
||||
*object,
|
||||
info.drawing,
|
||||
info.layer_index,
|
||||
selection_domain,
|
||||
vc->v3d->overlay.handle_display,
|
||||
memory);
|
||||
const float4x4 layer_to_world = layer.to_world_space(*ob_eval);
|
||||
const float4x4 projection = ED_view3d_ob_project_mat_get_from_obmat(vc->rv3d,
|
||||
layer_to_world);
|
||||
@@ -3365,7 +3370,12 @@ static bool ed_grease_pencil_select_pick(bContext *C,
|
||||
}
|
||||
const IndexMask visible_handle_elements =
|
||||
ed::greasepencil::retrieve_visible_bezier_handle_elements(
|
||||
*object, info.drawing, info.layer_index, selection_domain, memory);
|
||||
*object,
|
||||
info.drawing,
|
||||
info.layer_index,
|
||||
selection_domain,
|
||||
vc.v3d->overlay.handle_display,
|
||||
memory);
|
||||
const bke::CurvesGeometry &curves = info.drawing.strokes();
|
||||
const float4x4 layer_to_world = layer.to_world_space(*ob_eval);
|
||||
const float4x4 projection = ED_view3d_ob_project_mat_get_from_obmat(vc.rv3d,
|
||||
@@ -4416,7 +4426,12 @@ static bool do_grease_pencil_box_select(const ViewContext *vc,
|
||||
ob_eval, *object, info.drawing);
|
||||
const IndexMask visible_handle_elements =
|
||||
ed::greasepencil::retrieve_visible_bezier_handle_elements(
|
||||
*object, info.drawing, info.layer_index, selection_domain, memory);
|
||||
*object,
|
||||
info.drawing,
|
||||
info.layer_index,
|
||||
selection_domain,
|
||||
vc->v3d->overlay.handle_display,
|
||||
memory);
|
||||
const float4x4 layer_to_world = layer.to_world_space(*ob_eval);
|
||||
const float4x4 projection = ED_view3d_ob_project_mat_get_from_obmat(vc->rv3d,
|
||||
layer_to_world);
|
||||
@@ -5299,7 +5314,12 @@ static bool grease_pencil_circle_select(const ViewContext *vc,
|
||||
ob_eval, *object, info.drawing);
|
||||
const IndexMask visible_handle_elements =
|
||||
ed::greasepencil::retrieve_visible_bezier_handle_elements(
|
||||
*object, info.drawing, info.layer_index, selection_domain, memory);
|
||||
*object,
|
||||
info.drawing,
|
||||
info.layer_index,
|
||||
selection_domain,
|
||||
vc->v3d->overlay.handle_display,
|
||||
memory);
|
||||
const float4x4 layer_to_world = layer.to_world_space(*ob_eval);
|
||||
const float4x4 projection = ED_view3d_ob_project_mat_get_from_obmat(vc->rv3d,
|
||||
layer_to_world);
|
||||
|
||||
Reference in New Issue
Block a user