[Bf-blender-cvs] [613b6ad9e55] master: GPencil: New conversion to outline in draw mode

Antonio Vazquez noreply at git.blender.org
Mon Aug 29 09:53:49 CEST 2022


Commit: 613b6ad9e55fe904a90ba9166c8eb2fd654a8d85
Author: Antonio Vazquez
Date:   Mon Aug 29 09:47:08 2022 +0200
Branches: master
https://developer.blender.org/rB613b6ad9e55fe904a90ba9166c8eb2fd654a8d85

GPencil: New conversion to outline in draw mode

This new option converts the stroke to outline perimeter as soon as is drawn.

If no alternative material is set, the actual material is used.

The algorithm is similar to the new operator in D15664

Reviewed By: pepeland

Differential Revision: https://developer.blender.org/D15738

===================================================================

M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/blenkernel/intern/brush.cc
M	source/blender/editors/gpencil/gpencil_paint.c
M	source/blender/makesdna/DNA_brush_enums.h
M	source/blender/makesdna/DNA_brush_types.h
M	source/blender/makesrna/intern/rna_brush.c

===================================================================

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);



More information about the Bf-blender-cvs mailing list