diff options
-rw-r--r-- | release/scripts/startup/bl_ui/space_view3d_toolbar.py | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/brush.cc | 4 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_paint.c | 86 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_brush_enums.h | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_brush_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_brush.c | 15 |
6 files changed, 104 insertions, 11 deletions
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 892dc9a1e42..aa0e834cfa7 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -1742,6 +1742,12 @@ class VIEW3D_PT_tools_grease_pencil_brush_post_processing(View3DPanel, Panel): col1 = col.column(align=True) col1.prop(gp_settings, "use_trim") + row = col.row(heading="Outline", align=True) + row.prop(gp_settings, "use_settings_outline", text="") + row2 = row.row(align=True) + row2.enabled = gp_settings.use_settings_outline + row2.prop(gp_settings, "material_alt", text="") + class VIEW3D_PT_tools_grease_pencil_brush_random(View3DPanel, Panel): bl_context = ".greasepencil_paint" diff --git a/source/blender/blenkernel/intern/brush.cc b/source/blender/blenkernel/intern/brush.cc index fc45ce0bbe7..34b87dda338 100644 --- a/source/blender/blenkernel/intern/brush.cc +++ b/source/blender/blenkernel/intern/brush.cc @@ -186,6 +186,7 @@ static void brush_foreach_id(ID *id, LibraryForeachIDData *data) BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, brush->paint_curve, IDWALK_CB_USER); if (brush->gpencil_settings) { BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, brush->gpencil_settings->material, IDWALK_CB_USER); + BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, brush->gpencil_settings->material_alt, IDWALK_CB_USER); } BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, BKE_texture_mtex_foreach_id(data, &brush->mtex)); BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data, @@ -346,6 +347,7 @@ static void brush_blend_read_lib(BlendLibReader *reader, ID *id) else { brush->gpencil_settings->material = nullptr; } + BLO_read_id_address(reader, brush->id.lib, &brush->gpencil_settings->material_alt); } } @@ -358,6 +360,7 @@ static void brush_blend_read_expand(BlendExpander *expander, ID *id) BLO_expand(expander, brush->paint_curve); if (brush->gpencil_settings != nullptr) { BLO_expand(expander, brush->gpencil_settings->material); + BLO_expand(expander, brush->gpencil_settings->material_alt); } } @@ -704,6 +707,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type) /* Set vertex mix factor. */ brush->gpencil_settings->vertex_mode = GPPAINT_MODE_BOTH; brush->gpencil_settings->vertex_factor = 1.0f; + brush->gpencil_settings->material_alt = nullptr; switch (type) { case GP_BRUSH_PRESET_AIRBRUSH: { diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 50651e1919a..7f11ff7ebd5 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -918,6 +918,64 @@ static void gpencil_stroke_unselect(bGPdata *gpd, bGPDstroke *gps) } } +static bGPDstroke *gpencil_stroke_to_outline(tGPsdata *p, bGPDstroke *gps) +{ + bGPDlayer *gpl = p->gpl; + RegionView3D *rv3d = p->region->regiondata; + Brush *brush = p->brush; + BrushGpencilSettings *gpencil_settings = brush->gpencil_settings; + MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(p->ob, gps->mat_nr + 1); + const bool is_stroke = ((gp_style->flag & GP_MATERIAL_STROKE_SHOW) != 0); + + if (!is_stroke) { + return gps; + } + + /* Duplicate the stroke to apply any layer thickness change. */ + bGPDstroke *gps_duplicate = BKE_gpencil_stroke_duplicate(gps, true, false); + + /* Apply layer thickness change. */ + gps_duplicate->thickness += gpl->line_change; + /* Apply object scale to thickness. */ + gps_duplicate->thickness *= mat4_to_scale(p->ob->obmat); + CLAMP_MIN(gps_duplicate->thickness, 1.0f); + + /* Stroke. */ + float diff_mat[4][4]; + unit_m4(diff_mat); + bGPDstroke *gps_perimeter = BKE_gpencil_stroke_perimeter_from_view( + rv3d, p->gpd, gpl, gps_duplicate, 3, diff_mat); + /* Assign material. */ + if (gpencil_settings->material_alt == NULL) { + gps_perimeter->mat_nr = gps->mat_nr; + } + else { + Material *ma = gpencil_settings->material_alt; + int mat_idx = BKE_gpencil_material_find_index_by_name_prefix(p->ob, ma->id.name + 2); + if (mat_idx > -1) { + gps_perimeter->mat_nr = mat_idx; + } + else { + gps_perimeter->mat_nr = gps->mat_nr; + } + } + + /* Set pressure constant. */ + bGPDspoint *pt; + for (int i = 0; i < gps_perimeter->totpoints; i++) { + pt = &gps_perimeter->points[i]; + pt->pressure = 1.0f; + } + + /* Remove original stroke. */ + BKE_gpencil_free_stroke(gps); + + /* Free Temp stroke. */ + BKE_gpencil_free_stroke(gps_duplicate); + + return gps_perimeter; +} + /* make a new stroke from the buffer data */ static void gpencil_stroke_newfrombuffer(tGPsdata *p) { @@ -1221,6 +1279,23 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p) BKE_gpencil_stroke_simplify_adaptive(gpd, gps, brush->gpencil_settings->simplify_f); } + /* Set material index. */ + gps->mat_nr = BKE_gpencil_object_material_get_index_from_brush(p->ob, p->brush); + if (gps->mat_nr < 0) { + if (p->ob->actcol - 1 < 0) { + gps->mat_nr = 0; + } + else { + gps->mat_nr = p->ob->actcol - 1; + } + } + + /* Convert to Outline. */ + if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_SETTINGS) && + (brush->gpencil_settings->flag & GP_BRUSH_OUTLINE_STROKE)) { + gps = gpencil_stroke_to_outline(p, gps); + } + /* reproject to plane (only in 3d space) */ gpencil_reproject_toplane(p, gps); /* change position relative to parent object */ @@ -1235,17 +1310,6 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p) } } - /* Save material index */ - gps->mat_nr = BKE_gpencil_object_material_get_index_from_brush(p->ob, p->brush); - if (gps->mat_nr < 0) { - if (p->ob->actcol - 1 < 0) { - gps->mat_nr = 0; - } - else { - gps->mat_nr = p->ob->actcol - 1; - } - } - /* add stroke to frame, usually on tail of the listbase, but if on back is enabled the stroke * is added on listbase head because the drawing order is inverse and the head stroke is the * first to draw. This is very useful for artist when drawing the background. diff --git a/source/blender/makesdna/DNA_brush_enums.h b/source/blender/makesdna/DNA_brush_enums.h index adda23c26f2..988853e6694 100644 --- a/source/blender/makesdna/DNA_brush_enums.h +++ b/source/blender/makesdna/DNA_brush_enums.h @@ -87,6 +87,8 @@ typedef enum eGPDbrush_Flag { GP_BRUSH_OCCLUDE_ERASER = (1 << 15), /* Post process trim stroke */ GP_BRUSH_TRIM_STROKE = (1 << 16), + /* Post process convert to outline stroke */ + GP_BRUSH_OUTLINE_STROKE = (1 << 17), } eGPDbrush_Flag; typedef enum eGPDbrush_Flag2 { diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index b24bb786593..174ec614238 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -135,6 +135,8 @@ typedef struct BrushGpencilSettings { /* optional link of material to replace default in context */ /** Material. */ struct Material *material; + /** Material Alternative for secondary operations. */ + struct Material *material_alt; } BrushGpencilSettings; typedef struct BrushCurvesSculptSettings { diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 82eb390df52..40038921573 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -1820,6 +1820,12 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Trim Stroke Ends", "Trim intersecting stroke ends"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + prop = RNA_def_property(srna, "use_settings_outline", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_OUTLINE_STROKE); + RNA_def_property_boolean_default(prop, false); + RNA_def_property_ui_text(prop, "Outline", "Convert stroke to perimeter"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + prop = RNA_def_property(srna, "direction", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "sculpt_flag"); RNA_def_property_enum_items(prop, prop_direction_items); @@ -1883,6 +1889,15 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_Brush_material_update"); + /* Secondary Material */ + prop = RNA_def_property(srna, "material_alt", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "Material"); + RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_BrushGpencilSettings_material_poll"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK | PROP_CONTEXT_UPDATE); + RNA_def_property_ui_text(prop, "Material", "Material used for secondary uses for this brush"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_Brush_material_update"); + prop = RNA_def_property(srna, "show_fill_boundary", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_FILL_SHOW_HELPLINES); RNA_def_property_boolean_default(prop, true); |