GPv3: Rename Cutter tool to Trim

This rename the `Cutter` tool's name, code and icon to `Trim`.
The legacy Grease Pencil code is unchanged.

This was discussed in the 2024-07-30 Grease Pencil Module Meeting.

Reasons for the change:
 - Match the `Trim Stroke Ends` setting on brushes.
 - Match the `stroke_trim` operator.
 - Name is more clear and more commonly used.
 - Frees the name for a future boolean cutting tool.

Pull Request: https://projects.blender.org/blender/blender/pulls/126452
This commit is contained in:
casey bianco-davis
2024-09-13 16:56:51 +02:00
committed by Falk David
parent 613e535fb8
commit 3c67ae7785
10 changed files with 116 additions and 116 deletions

View File

@@ -8638,12 +8638,12 @@ def km_3d_view_tool_paint_gpencil_cutter(params):
)
def km_3d_view_tool_paint_grease_pencil_cutter(params):
def km_3d_view_tool_paint_grease_pencil_trim(params):
return (
"3D View Tool: Paint Grease Pencil, Cutter",
"3D View Tool: Paint Grease Pencil, Trim",
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
{"items": [
("grease_pencil.stroke_cutter", {"type": params.tool_mouse, "value": 'PRESS'}, None),
("grease_pencil.stroke_trim", {"type": params.tool_mouse, "value": 'PRESS'}, None),
]},
)
@@ -9377,7 +9377,7 @@ def generate_keymaps(params=None):
for fallback in (False, True)),
*(km_sequencer_editor_tool_generic_select_box_preview(params, fallback=fallback)
for fallback in (False, True)),
km_3d_view_tool_paint_grease_pencil_cutter(params),
km_3d_view_tool_paint_grease_pencil_trim(params),
km_sequencer_editor_tool_generic_cursor(params),
km_sequencer_editor_tool_blade(params),
km_sequencer_editor_tool_sample(params),

View File

@@ -2052,7 +2052,7 @@ class _defs_grease_pencil_paint:
]
@ToolDef.from_fn
def cutter():
def trim():
def draw_settings(context, layout, _tool):
brush = context.tool_settings.gpencil_paint.brush
gp_settings = brush.gpencil_settings
@@ -2062,9 +2062,9 @@ class _defs_grease_pencil_paint:
row.prop(gp_settings, "use_active_layer_only")
return dict(
idname="builtin.cutter",
label="Cutter",
icon="ops.gpencil.stroke_cutter",
idname="builtin.trim",
label="Trim",
icon="ops.gpencil.stroke_trim",
cursor='KNIFE',
keymap=(),
draw_settings=draw_settings,
@@ -3846,7 +3846,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
_defs_view3d_generic.cursor,
None,
_defs_grease_pencil_paint.generate_from_brushes,
_defs_grease_pencil_paint.cutter,
_defs_grease_pencil_paint.trim,
None,
_defs_grease_pencil_paint.eyedropper,
None,

View File

@@ -69,7 +69,7 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES
ops.gpencil.primitive_line
ops.gpencil.primitive_polyline
ops.gpencil.radius
ops.gpencil.stroke_cutter
ops.gpencil.stroke_trim
ops.gpencil.transform_fill
ops.mesh.bevel
ops.mesh.bisect

View File

@@ -24,7 +24,6 @@ set(INC_SYS
set(SRC
intern/grease_pencil_add.cc
intern/grease_pencil_cutter.cc
intern/grease_pencil_edit.cc
intern/grease_pencil_frames.cc
intern/grease_pencil_geom.cc
@@ -35,6 +34,7 @@ set(SRC
intern/grease_pencil_ops.cc
intern/grease_pencil_primitive.cc
intern/grease_pencil_select.cc
intern/grease_pencil_trim.cc
intern/grease_pencil_undo.cc
intern/grease_pencil_utils.cc
intern/grease_pencil_vertex_paint.cc

View File

@@ -3186,7 +3186,7 @@ void ED_operatortypes_grease_pencil_edit()
WM_operatortype_append(GREASE_PENCIL_OT_copy);
WM_operatortype_append(GREASE_PENCIL_OT_paste);
WM_operatortype_append(GREASE_PENCIL_OT_stroke_merge_by_distance);
WM_operatortype_append(GREASE_PENCIL_OT_stroke_cutter);
WM_operatortype_append(GREASE_PENCIL_OT_stroke_trim);
WM_operatortype_append(GREASE_PENCIL_OT_extrude);
WM_operatortype_append(GREASE_PENCIL_OT_snap_to_grid);
WM_operatortype_append(GREASE_PENCIL_OT_snap_to_cursor);

View File

@@ -825,7 +825,7 @@ bke::CurvesGeometry create_curves_outline(const bke::greasepencil::Drawing &draw
return dst_curves;
}
namespace cutter {
namespace trim {
enum Side : uint8_t { Start = 0, End = 1 };
enum Distance : uint8_t { Min = 0, Max = 1 };
@@ -850,8 +850,8 @@ struct Segment {
* in a CurvesGeometry. */
int point_range[2];
/* The normalized distance where the cutter segment is intersected by another curve.
* For the outer ends of the cutter segment the intersection distance is given between:
/* The normalized distance where the trim segment is intersected by another curve.
* For the outer ends of the trim segment the intersection distance is given between:
* - [start point - 1] and [start point]
* - [end point] and [end point + 1]
*/
@@ -864,14 +864,14 @@ struct Segment {
/**
* Structure describing:
* - A collection of cutter segments.
* - A collection of trim segments.
*/
struct Segments {
/* Collection of cutter segments: parts of curves between other curves, to be removed from the
/* Collection of trim segments: parts of curves between other curves, to be removed from the
* geometry. */
Vector<Segment> segments;
/* Create an initial cutter segment with a point range of one point. */
/* Create an initial trim segment with a point range of one point. */
Segment *create_segment(const int curve, const int point)
{
Segment segment{};
@@ -884,7 +884,7 @@ struct Segments {
return &this->segments.last();
}
/* Merge cutter segments that are next to each other. */
/* Merge trim segments that are next to each other. */
void merge_adjacent_segments()
{
Vector<Segment> merged_segments;
@@ -1072,15 +1072,15 @@ static void get_intersections_of_curve_with_curves(const int src_curve,
}
/**
* Expand a cutter segment by walking along the curve in forward or backward direction.
* A cutter segments ends at an intersection with another curve, or at the outer end of the curve.
* Expand a trim segment by walking along the curve in forward or backward direction.
* A trim segments ends at an intersection with another curve, or at the outer end of the curve.
*/
static void expand_cutter_segment_direction(Segment &segment,
const int direction,
const bke::CurvesGeometry &src,
const Span<bool> is_intersected_after_point,
const Span<float2> intersection_distance,
MutableSpan<bool> point_is_in_segment)
static void expand_trim_segment_direction(Segment &segment,
const int direction,
const bke::CurvesGeometry &src,
const Span<bool> is_intersected_after_point,
const Span<float2> intersection_distance,
MutableSpan<bool> point_is_in_segment)
{
const OffsetIndices<int> points_by_curve = src.points_by_curve();
const int point_first = points_by_curve[segment.curve].first();
@@ -1149,22 +1149,22 @@ static void expand_cutter_segment_direction(Segment &segment,
}
/**
* Expand a cutter segment of one point by walking along the curve in both directions.
* Expand a trim segment of one point by walking along the curve in both directions.
*/
static void expand_cutter_segment(Segment &segment,
const bke::CurvesGeometry &src,
const Span<bool> is_intersected_after_point,
const Span<float2> intersection_distance,
MutableSpan<bool> point_is_in_segment)
static void expand_trim_segment(Segment &segment,
const bke::CurvesGeometry &src,
const Span<bool> is_intersected_after_point,
const Span<float2> intersection_distance,
MutableSpan<bool> point_is_in_segment)
{
const int8_t directions[2] = {-1, 1};
for (const int8_t direction : directions) {
expand_cutter_segment_direction(segment,
direction,
src,
is_intersected_after_point,
intersection_distance,
point_is_in_segment);
expand_trim_segment_direction(segment,
direction,
src,
is_intersected_after_point,
intersection_distance,
point_is_in_segment);
}
}
@@ -1190,28 +1190,28 @@ bke::CurvesGeometry trim_curve_segments(const bke::CurvesGeometry &src,
intersection_distance);
});
/* Expand the selected curve points to cutter segments (the part of the curve between two
/* Expand the selected curve points to trim segments (the part of the curve between two
* intersections). */
const VArray<bool> is_cyclic = src.cyclic();
Array<bool> point_is_in_segment(src_points_num, false);
threading::EnumerableThreadSpecific<Segments> cutter_segments_by_thread;
threading::EnumerableThreadSpecific<Segments> trim_segments_by_thread;
curve_selection.foreach_index(GrainSize(32), [&](const int curve_i, const int pos) {
Segments &thread_segments = cutter_segments_by_thread.local();
Segments &thread_segments = trim_segments_by_thread.local();
for (const int selected_point : selected_points_in_curves[pos]) {
/* Skip point when it is already part of a cutter segment. */
/* Skip point when it is already part of a trim segment. */
if (point_is_in_segment[selected_point]) {
continue;
}
/* Create new cutter segment. */
/* Create new trim segment. */
Segment *segment = thread_segments.create_segment(curve_i, selected_point);
/* Expand the cutter segment in both directions until an intersection is found or the
/* Expand the trim segment in both directions until an intersection is found or the
* end of the curve is reached. */
expand_cutter_segment(
expand_trim_segment(
*segment, src, is_intersected_after_point, intersection_distance, point_is_in_segment);
/* When the end of a curve is reached and the curve is cyclic, we add an extra cutter
/* When the end of a curve is reached and the curve is cyclic, we add an extra trim
* segment for the cyclic second part. */
if (is_cyclic[curve_i] &&
(!segment->is_intersected[Side::Start] || !segment->is_intersected[Side::End]) &&
@@ -1223,28 +1223,28 @@ bke::CurvesGeometry trim_curve_segments(const bke::CurvesGeometry &src,
segment = thread_segments.create_segment(curve_i, cyclic_outer_point);
/* Expand this second segment. */
expand_cutter_segment(
expand_trim_segment(
*segment, src, is_intersected_after_point, intersection_distance, point_is_in_segment);
}
}
});
Segments cutter_segments;
for (Segments &thread_segments : cutter_segments_by_thread) {
cutter_segments.segments.extend(thread_segments.segments);
Segments trim_segments;
for (Segments &thread_segments : trim_segments_by_thread) {
trim_segments.segments.extend(thread_segments.segments);
}
/* Abort when no cutter segments are found in the lasso area. */
/* Abort when no trim segments are found in the lasso area. */
bke::CurvesGeometry dst;
if (cutter_segments.segments.is_empty()) {
if (trim_segments.segments.is_empty()) {
return dst;
}
/* Merge adjacent cutter segments. E.g. two point ranges of 0-10 and 11-20 will be merged
/* Merge adjacent trim segments. E.g. two point ranges of 0-10 and 11-20 will be merged
* to one range of 0-20. */
cutter_segments.merge_adjacent_segments();
trim_segments.merge_adjacent_segments();
/* Create the point transfer data, for converting the source geometry into the new geometry.
* First, add all curve points not affected by the cutter tool. */
* First, add all curve points not affected by the trim tool. */
Array<Vector<PointTransferData>> src_to_dst_points(src_points_num);
for (const int src_curve : src.curves_range()) {
const IndexRange src_points = src_points_by_curve[src_curve];
@@ -1253,19 +1253,19 @@ bke::CurvesGeometry trim_curve_segments(const bke::CurvesGeometry &src,
const int src_next_point = (src_point == src_points.last()) ? src_points.first() :
(src_point + 1);
/* Add the source point only if it does not lie inside a cutter segment. */
/* Add the source point only if it does not lie inside a trim segment. */
if (!point_is_in_segment[src_point]) {
dst_points.append({src_point, src_next_point, 0.0f, true, false});
}
}
}
/* Add new curve points at the intersection points of the cutter segments.
/* Add new curve points at the intersection points of the trim segments.
*
* a b
* source curve o--------o---*---o--------o----*---o--------o
* ^ ^
* cutter segment |-----------------|
* trim segment |-----------------|
*
* o = existing curve point
* * = newly created curve point
@@ -1278,33 +1278,33 @@ bke::CurvesGeometry trim_curve_segments(const bke::CurvesGeometry &src,
* We avoid inserting a new point very close to the adjacent one, because that's just adding
* clutter to the geometry.
*/
for (const Segment &cutter_segment : cutter_segments.segments) {
/* Intersection at cutter segment start. */
if (cutter_segment.is_intersected[Side::Start] &&
cutter_segment.intersection_distance[Side::Start] > DISTANCE_FACTOR_THRESHOLD)
for (const Segment &trim_segment : trim_segments.segments) {
/* Intersection at trim segment start. */
if (trim_segment.is_intersected[Side::Start] &&
trim_segment.intersection_distance[Side::Start] > DISTANCE_FACTOR_THRESHOLD)
{
const int src_point = cutter_segment.point_range[Side::Start] - 1;
const int src_point = trim_segment.point_range[Side::Start] - 1;
Vector<PointTransferData> &dst_points = src_to_dst_points[src_point];
dst_points.append({src_point,
src_point + 1,
cutter_segment.intersection_distance[Side::Start],
trim_segment.intersection_distance[Side::Start],
false,
false});
}
/* Intersection at cutter segment end. */
if (cutter_segment.is_intersected[Side::End]) {
const int src_point = cutter_segment.point_range[Side::End];
if (cutter_segment.intersection_distance[Side::End] < (1.0f - DISTANCE_FACTOR_THRESHOLD)) {
/* Intersection at trim segment end. */
if (trim_segment.is_intersected[Side::End]) {
const int src_point = trim_segment.point_range[Side::End];
if (trim_segment.intersection_distance[Side::End] < (1.0f - DISTANCE_FACTOR_THRESHOLD)) {
Vector<PointTransferData> &dst_points = src_to_dst_points[src_point];
dst_points.append({src_point,
src_point + 1,
cutter_segment.intersection_distance[Side::End],
trim_segment.intersection_distance[Side::End],
false,
true});
}
else {
/* Mark the 'is_cut' flag on the next point, because a new curve is starting here after
* the removed cutter segment. */
* the removed trim segment. */
Vector<PointTransferData> &dst_points = src_to_dst_points[src_point + 1];
for (PointTransferData &dst_point : dst_points) {
if (dst_point.is_src_point) {
@@ -1321,7 +1321,7 @@ bke::CurvesGeometry trim_curve_segments(const bke::CurvesGeometry &src,
return dst;
}
} // namespace cutter
} // namespace trim
Curves2DBVHTree build_curves_2d_bvh_from_visible(const ViewContext &vc,
const Object &object,

View File

@@ -35,17 +35,17 @@ namespace blender::ed::greasepencil {
static constexpr int BBOX_PADDING = 2;
/**
* Apply the stroke cutter to a drawing.
* Apply the stroke trim to a drawing.
*/
static bool execute_cutter_on_drawing(const int layer_index,
const int frame_number,
const Object &ob_eval,
const Object &obact,
const ARegion &region,
const float4x4 &projection,
const Span<int2> mcoords,
const bool keep_caps,
bke::greasepencil::Drawing &drawing)
static bool execute_trim_on_drawing(const int layer_index,
const int frame_number,
const Object &ob_eval,
const Object &obact,
const ARegion &region,
const float4x4 &projection,
const Span<int2> mcoords,
const bool keep_caps,
bke::greasepencil::Drawing &drawing)
{
const bke::CurvesGeometry &src = drawing.strokes();
const OffsetIndices<int> src_points_by_curve = src.points_by_curve();
@@ -122,8 +122,8 @@ static bool execute_cutter_on_drawing(const int layer_index,
return false;
}
/* Apply cutter. */
bke::CurvesGeometry cut_strokes = ed::greasepencil::cutter::trim_curve_segments(
/* Apply trim. */
bke::CurvesGeometry cut_strokes = ed::greasepencil::trim::trim_curve_segments(
src,
screen_space_positions,
screen_space_bbox,
@@ -139,9 +139,9 @@ static bool execute_cutter_on_drawing(const int layer_index,
}
/**
* Apply the stroke cutter to all layers.
* Apply the stroke trim to all layers.
*/
static int stroke_cutter_execute(const bContext *C, const Span<int2> mcoords)
static int stroke_trim_execute(const bContext *C, const Span<int2> mcoords)
{
const Scene *scene = CTX_data_scene(C);
const ARegion *region = CTX_wm_region(C);
@@ -162,7 +162,7 @@ static int stroke_cutter_execute(const bContext *C, const Span<int2> mcoords)
std::atomic<bool> changed = false;
if (active_layer_only) {
/* Apply cutter on drawings of active layer. */
/* Apply trim on drawings of active layer. */
if (!grease_pencil.has_active_layer()) {
return OPERATOR_CANCELLED;
}
@@ -172,37 +172,37 @@ static int stroke_cutter_execute(const bContext *C, const Span<int2> mcoords)
const Vector<ed::greasepencil::MutableDrawingInfo> drawings =
ed::greasepencil::retrieve_editable_drawings_from_layer(*scene, grease_pencil, layer);
threading::parallel_for_each(drawings, [&](const ed::greasepencil::MutableDrawingInfo &info) {
if (execute_cutter_on_drawing(info.layer_index,
info.frame_number,
*ob_eval,
*obact,
*region,
projection,
mcoords,
keep_caps,
info.drawing))
if (execute_trim_on_drawing(info.layer_index,
info.frame_number,
*ob_eval,
*obact,
*region,
projection,
mcoords,
keep_caps,
info.drawing))
{
changed = true;
}
});
}
else {
/* Apply cutter on every editable drawing. */
/* Apply trim on every editable drawing. */
const Vector<ed::greasepencil::MutableDrawingInfo> drawings =
ed::greasepencil::retrieve_editable_drawings(*scene, grease_pencil);
threading::parallel_for_each(drawings, [&](const ed::greasepencil::MutableDrawingInfo &info) {
const bke::greasepencil::Layer &layer = *grease_pencil.layer(info.layer_index);
const float4x4 layer_to_world = layer.to_world_space(*ob_eval);
const float4x4 projection = ED_view3d_ob_project_mat_get_from_obmat(rv3d, layer_to_world);
if (execute_cutter_on_drawing(info.layer_index,
info.frame_number,
*ob_eval,
*obact,
*region,
projection,
mcoords,
keep_caps,
info.drawing))
if (execute_trim_on_drawing(info.layer_index,
info.frame_number,
*ob_eval,
*obact,
*region,
projection,
mcoords,
keep_caps,
info.drawing))
{
changed = true;
}
@@ -217,7 +217,7 @@ static int stroke_cutter_execute(const bContext *C, const Span<int2> mcoords)
return OPERATOR_FINISHED;
}
static int grease_pencil_stroke_cutter(bContext *C, wmOperator *op)
static int grease_pencil_stroke_trim(bContext *C, wmOperator *op)
{
const Array<int2> mcoords = WM_gesture_lasso_path_to_array(C, op);
@@ -225,22 +225,22 @@ static int grease_pencil_stroke_cutter(bContext *C, wmOperator *op)
return OPERATOR_PASS_THROUGH;
}
return stroke_cutter_execute(C, mcoords);
return stroke_trim_execute(C, mcoords);
}
} // namespace blender::ed::greasepencil
void GREASE_PENCIL_OT_stroke_cutter(wmOperatorType *ot)
void GREASE_PENCIL_OT_stroke_trim(wmOperatorType *ot)
{
using namespace blender::ed::greasepencil;
ot->name = "Grease Pencil Cutter";
ot->idname = "GREASE_PENCIL_OT_stroke_cutter";
ot->name = "Grease Pencil Trim";
ot->idname = "GREASE_PENCIL_OT_stroke_trim";
ot->description = "Delete stroke points in between intersecting strokes";
ot->invoke = WM_gesture_lasso_invoke;
ot->modal = WM_gesture_lasso_modal;
ot->exec = grease_pencil_stroke_cutter;
ot->exec = grease_pencil_stroke_trim;
ot->poll = grease_pencil_painting_poll;
ot->cancel = WM_gesture_lasso_cancel;

View File

@@ -73,7 +73,7 @@ void ED_primitivetool_modal_keymap(wmKeyConfig *keyconf);
void ED_filltool_modal_keymap(wmKeyConfig *keyconf);
void ED_interpolatetool_modal_keymap(wmKeyConfig *keyconf);
void GREASE_PENCIL_OT_stroke_cutter(wmOperatorType *ot);
void GREASE_PENCIL_OT_stroke_trim(wmOperatorType *ot);
void ED_undosys_type_grease_pencil(UndoType *undo_type);
@@ -821,14 +821,14 @@ bool apply_mask_as_segment_selection(bke::CurvesGeometry &curves,
GrainSize grain_size,
eSelectOp sel_op);
namespace cutter {
namespace trim {
bke::CurvesGeometry trim_curve_segments(const bke::CurvesGeometry &src,
Span<float2> screen_space_positions,
Span<rcti> screen_space_curve_bounds,
const IndexMask &curve_selection,
const Vector<Vector<int>> &selected_points_in_curves,
bool keep_caps);
}; // namespace cutter
}; // namespace trim
/* Lineart */

View File

@@ -1183,7 +1183,7 @@ static void trim_stroke_ends(bke::greasepencil::Drawing &drawing,
/* Use the first and last point. */
const Vector<Vector<int>> point_selection = {{0, int(points.index_range().last())}};
/* Trim the stroke ends by finding self intersections using the screen space positions. */
bke::CurvesGeometry stroke_trimmed = ed::greasepencil::cutter::trim_curve_segments(
bke::CurvesGeometry stroke_trimmed = ed::greasepencil::trim::trim_curve_segments(
stroke,
screen_space_positions,
{screen_space_bounds},