Grease Pencil: Draw Tool: Add option to create cyclic stroke

Adds a tool option to create cyclic strokes.
This is exposed in the header and the side panel.

Pull Request: https://projects.blender.org/blender/blender/pulls/157190
This commit is contained in:
Falk David 2026-09-18 14:43:36 +02:00 • committed by Falk David
parent 8cd6099ecf
commit 02c927c0ff
7 changed files with 37 additions and 1 deletions

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
height="1600"
viewBox="0 0 1600 1600"
width="1600"
version="1.1"
id="svg4"
xml:space="preserve"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs4" /><path
style="display:inline;opacity:0.6;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:200;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none"
d="m 1200,1260 c 0,0 -60,140 -200,140 -160,0 -246,-152 -200,-300 -258,132 -600,46 -600,-200 0,-246 456,-740 900,-700 233.6088,21.04584 300,200 300,200"
id="path6" /><path
style="opacity:1;fill:none;stroke:#ffffff;stroke-width:200;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:100, 260;stroke-dashoffset:0;stroke-opacity:1"
d="m 1400,400 -200,860"
id="path1" /></svg>

After

Width:  |  Height:  |  Size: 852 B

View file

@ -1955,6 +1955,12 @@ def brush_basic_grease_pencil_paint_settings(layout, context, brush, props, *, c
else:
row.prop(brush.gpencil_settings, "stroke_type")
row = layout.row(align=True)
if compact:
row.prop(gp_settings, "use_cyclic_stroke", text="")
else:
row.prop(gp_settings, "use_cyclic_stroke", text="Cyclic")
row = layout.row(align=True)
if compact:
row.prop(gp_settings, "caps_type", text="", expand=True)

View file

@ -417,6 +417,7 @@ if(WITH_BLENDER)
gizmo
gp_caps_flat
gp_caps_round
gp_cyclic_stroke
gp_draw_stroke
gp_draw_fill
gp_draw_both

View file

@ -300,6 +300,7 @@ DEF_ICON(UGLYPACKAGE)
DEF_ICON(GP_DRAW_STROKE)
DEF_ICON(GP_DRAW_FILL)
DEF_ICON(GP_DRAW_BOTH)
DEF_ICON(GP_CYCLIC_STROKE)
/* Careful, order is narrow to wide. */
/* INPUT */

View file

@ -361,6 +361,7 @@ struct PaintOperationExecutor {
const bool on_back = (scene_->toolsettings->gpencil_flags & GP_TOOL_FLAG_PAINT_ONBACK) != 0;
const bool hide_fill_while_drawing = (settings_->flag & GP_BRUSH_DISSABLE_LASSO) != 0;
const bool cyclic_stroke = (settings_->flag & GP_BRUSH_USE_CYCLIC_STROKE) != 0;
self.screen_space_coords_orig_.append(start_coords);
self.screen_space_curve_fitted_coords_.append(Vector<float2>({start_coords}));
@ -405,7 +406,7 @@ struct PaintOperationExecutor {
"material_index", bke::AttrDomain::Curve);
bke::SpanAttributeWriter<bool> cyclic = attributes.convert_or_add_for_write_span<bool>(
"cyclic", bke::AttrDomain::Curve);
cyclic.span[active_curve] = use_fill && !use_stroke;
cyclic.span[active_curve] = cyclic_stroke;
materials.span[active_curve] = material_index;
curve_attributes_to_skip.add_multiple({"material_index", "cyclic"});
cyclic.finish();

View file

@ -59,6 +59,8 @@ enum eGPDbrush_Flag : int {
GP_BRUSH_FILL_AUTO_REMOVE_FILL_GUIDES = (1 << 21),
/* Fill Tool create internal gaps. */
GP_BRUSH_FILL_INTERNAL_GAPS = (1 << 22),
/* Create a cylic stroke. */
GP_BRUSH_USE_CYCLIC_STROKE = (1 << 23),
};
ENUM_OPERATORS(eGPDbrush_Flag)

View file

@ -1910,6 +1910,14 @@ static void rna_def_gpencil_options(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update");
prop = RNA_def_property(srna, "use_cyclic_stroke", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, nullptr, "flag", GP_BRUSH_USE_CYCLIC_STROKE);
RNA_def_property_boolean_default(prop, false);
RNA_def_property_ui_icon(prop, ICON_GP_CYCLIC_STROKE, 0);
RNA_def_property_ui_text(prop, "Cyclic", "Create a cyclic stroke");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update");
prop = RNA_def_property(srna, "eraser_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, nullptr, "eraser_mode");
RNA_def_property_enum_items(prop, rna_enum_gpencil_brush_eraser_modes_items);