Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/gpencil_modifiers/CMakeLists.txt1
-rw-r--r--source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h1
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c1
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpenciloutline.c342
-rw-r--r--source/blender/makesdna/DNA_gpencil_modifier_defaults.h13
-rw-r--r--source/blender/makesdna/DNA_gpencil_modifier_types.h33
-rw-r--r--source/blender/makesdna/intern/dna_defaults.c2
-rw-r--r--source/blender/makesrna/intern/rna_gpencil_modifier.c141
8 files changed, 534 insertions, 0 deletions
diff --git a/source/blender/gpencil_modifiers/CMakeLists.txt b/source/blender/gpencil_modifiers/CMakeLists.txt
index 5ef9ae1bbc6..8dbac602c06 100644
--- a/source/blender/gpencil_modifiers/CMakeLists.txt
+++ b/source/blender/gpencil_modifiers/CMakeLists.txt
@@ -47,6 +47,7 @@ set(SRC
intern/MOD_gpencilnoise.c
intern/MOD_gpenciloffset.c
intern/MOD_gpencilopacity.c
+ intern/MOD_gpenciloutline.c
intern/MOD_gpencilshrinkwrap.c
intern/MOD_gpencilsimplify.c
intern/MOD_gpencilsmooth.c
diff --git a/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h b/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h
index 9025fecacd8..2f3cf4d2312 100644
--- a/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h
+++ b/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h
@@ -20,6 +20,7 @@ extern GpencilModifierTypeInfo modifierType_Gpencil_Color;
extern GpencilModifierTypeInfo modifierType_Gpencil_Array;
extern GpencilModifierTypeInfo modifierType_Gpencil_Build;
extern GpencilModifierTypeInfo modifierType_Gpencil_Opacity;
+extern GpencilModifierTypeInfo modifierType_Gpencil_Outline;
extern GpencilModifierTypeInfo modifierType_Gpencil_Lattice;
extern GpencilModifierTypeInfo modifierType_Gpencil_Length;
extern GpencilModifierTypeInfo modifierType_Gpencil_Mirror;
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c
index bd8fd9f72ad..d4ada842d0b 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c
@@ -41,6 +41,7 @@ void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[])
INIT_GP_TYPE(Array);
INIT_GP_TYPE(Build);
INIT_GP_TYPE(Opacity);
+ INIT_GP_TYPE(Outline);
INIT_GP_TYPE(Lattice);
INIT_GP_TYPE(Length);
INIT_GP_TYPE(Mirror);
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciloutline.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciloutline.c
new file mode 100644
index 00000000000..9a0ee4d9d92
--- /dev/null
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciloutline.c
@@ -0,0 +1,342 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. */
+
+/** \file
+ * \ingroup modifiers
+ */
+
+#include <stdio.h>
+
+#include "BLI_utildefines.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math_vector.h"
+
+#include "BLT_translation.h"
+
+#include "DNA_defaults.h"
+#include "DNA_gpencil_modifier_types.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_material_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+
+#include "BKE_context.h"
+#include "BKE_gpencil.h"
+#include "BKE_gpencil_geom.h"
+#include "BKE_gpencil_modifier.h"
+#include "BKE_lib_query.h"
+#include "BKE_main.h"
+#include "BKE_material.h"
+#include "BKE_scene.h"
+#include "BKE_screen.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "BKE_modifier.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+#include "MOD_gpencil_modifiertypes.h"
+#include "MOD_gpencil_ui_common.h"
+#include "MOD_gpencil_util.h"
+
+static void initData(GpencilModifierData *md)
+{
+ OutlineGpencilModifierData *gpmd = (OutlineGpencilModifierData *)md;
+
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(gpmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(gpmd, DNA_struct_default_get(OutlineGpencilModifierData), modifier);
+}
+
+static void copyData(const GpencilModifierData *md, GpencilModifierData *target)
+{
+ BKE_gpencil_modifier_copydata_generic(md, target);
+}
+
+static void free_old_strokes(Depsgraph *depsgraph, Object *ob, bGPdata *gpd)
+{
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ /* Free old strokes. */
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ bGPDframe *gpf = BKE_gpencil_frame_retime_get(depsgraph, scene, ob, gpl);
+ if (gpf == NULL) {
+ continue;
+ }
+ LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
+ if (gps->flag & GP_STROKE_TAG) {
+ BLI_remlink(&gpf->strokes, gps);
+ BKE_gpencil_free_stroke(gps);
+ }
+ }
+ }
+}
+
+static void convert_stroke(GpencilModifierData *md,
+ Object *ob,
+ bGPDlayer *gpl,
+ bGPDframe *gpf,
+ bGPDstroke *gps,
+ float viewmat[4][4],
+ float diff_mat[4][4])
+{
+ OutlineGpencilModifierData *mmd = (OutlineGpencilModifierData *)md;
+ bGPdata *gpd = (bGPdata *)ob->data;
+ const bool keep = (mmd->flag & GP_OUTLINE_KEEP_SHAPE) != 0;
+
+ if (!is_stroke_affected_by_modifier(ob,
+ mmd->layername,
+ mmd->material,
+ mmd->pass_index,
+ mmd->layer_pass,
+ 1,
+ gpl,
+ gps,
+ mmd->flag & GP_OUTLINE_INVERT_LAYER,
+ mmd->flag & GP_OUTLINE_INVERT_PASS,
+ mmd->flag & GP_OUTLINE_INVERT_LAYERPASS,
+ mmd->flag & GP_OUTLINE_INVERT_MATERIAL)) {
+ return;
+ }
+
+ MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
+ const bool is_stroke = (gp_style->flag & GP_MATERIAL_STROKE_SHOW) != 0;
+ /* Only strokes type, no fill strokes. */
+ if (!is_stroke) {
+ return;
+ }
+
+ /* 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(ob->obmat);
+ CLAMP_MIN(gps_duplicate->thickness, 1.0f);
+
+ /* Stroke. */
+ const float ovr_thickness = keep ? mmd->thickness : 0.0f;
+ bGPDstroke *gps_perimeter = BKE_gpencil_stroke_perimeter_from_view(
+ viewmat, gpd, gpl, gps_duplicate, mmd->subdiv, diff_mat, ovr_thickness);
+ gps_perimeter->flag &= ~GP_STROKE_SELECT;
+ gps_perimeter->runtime.gps_orig = gps->runtime.gps_orig;
+
+ /* Assign material. */
+ if (mmd->outline_material) {
+ Material *ma = mmd->outline_material;
+ int mat_idx = BKE_gpencil_material_find_index_by_name_prefix(ob, ma->id.name + 2);
+ if (mat_idx > -1) {
+ gps_perimeter->mat_nr = mat_idx;
+ }
+ else {
+ gps_perimeter->mat_nr = gps->mat_nr;
+ }
+ }
+ else {
+ gps_perimeter->mat_nr = gps->mat_nr;
+ }
+
+ /* Sample stroke. */
+ if (mmd->sample_length > 0.0f) {
+ BKE_gpencil_stroke_sample(gpd, gps_perimeter, mmd->sample_length, false, 0);
+ }
+ /* Set stroke thickness. */
+ gps_perimeter->thickness = mmd->thickness;
+
+ /* Set pressure constant. */
+ int orig_idx = -1;
+ float min_distance = FLT_MAX;
+ bGPDspoint *pt;
+ for (int i = 0; i < gps_perimeter->totpoints; i++) {
+ pt = &gps_perimeter->points[i];
+ pt->pressure = 1.0f;
+ pt->runtime.pt_orig = NULL;
+ /* If any target object is defined, find the nearest point. */
+ if (mmd->object) {
+ float wpt[3];
+ mul_v3_m4v3(wpt, diff_mat, &pt->x);
+ float dist = len_squared_v3v3(wpt, mmd->object->loc);
+ if (dist < min_distance) {
+ min_distance = dist;
+ orig_idx = i;
+ }
+ }
+ }
+
+ if (orig_idx > 0) {
+ BKE_gpencil_stroke_start_set(gps_perimeter, orig_idx);
+ BKE_gpencil_stroke_geometry_update(gpd, gps_perimeter);
+ }
+
+ /* Add perimeter stroke to frame. */
+ BLI_insertlinkafter(&gpf->strokes, gps, gps_perimeter);
+
+ /* Free Temp stroke. */
+ BKE_gpencil_free_stroke(gps_duplicate);
+
+ /* Tag original stroke to be removed. */
+ gps->flag |= GP_STROKE_TAG;
+}
+
+static void generateStrokes(GpencilModifierData *md, Depsgraph *depsgraph, Object *ob)
+{
+ bGPdata *gpd = (bGPdata *)ob->data;
+
+ /* Calc camera view matrix. */
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ /* Ensure the camera is the right one. */
+ BKE_scene_camera_switch_update(scene);
+
+ if (!scene->camera) {
+ return;
+ }
+ Object *cam_ob = scene->camera;
+ float viewmat[4][4];
+ invert_m4_m4(viewmat, cam_ob->obmat);
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ bGPDframe *gpf = BKE_gpencil_frame_retime_get(depsgraph, scene, ob, gpl);
+ if (gpf == NULL) {
+ continue;
+ }
+ /* Prepare transform matrix. */
+ float diff_mat[4][4];
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
+
+ LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
+ convert_stroke(md, ob, gpl, gpf, gps, viewmat, diff_mat);
+ }
+ }
+
+ /* Delete original strokes. */
+ free_old_strokes(depsgraph, ob, gpd);
+}
+
+static void bakeModifier(Main *UNUSED(bmain),
+ Depsgraph *depsgraph,
+ GpencilModifierData *md,
+ Object *ob)
+{
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ bGPdata *gpd = ob->data;
+ int oldframe = (int)DEG_get_ctime(depsgraph);
+
+ /* Calc camera view matrix. */
+ if (!scene->camera) {
+ return;
+ }
+ Object *cam_ob = scene->camera;
+ float viewmat[4][4];
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ scene->r.cfra = gpf->framenum;
+ BKE_scene_graph_update_for_newframe(depsgraph);
+ /* Ensure the camera is the right one. */
+ BKE_scene_camera_switch_update(scene);
+ invert_m4_m4(viewmat, cam_ob->obmat);
+
+ /* Prepare transform matrix. */
+ float diff_mat[4][4];
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
+
+ /* Compute all strokes of this frame. */
+ LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
+ convert_stroke(md, ob, gpl, gpf, gps, viewmat, diff_mat);
+ }
+ }
+ }
+
+ /* Delete original strokes. */
+ free_old_strokes(depsgraph, ob, gpd);
+
+ /* Return frame state and DB to original state. */
+ scene->r.cfra = oldframe;
+ BKE_scene_graph_update_for_newframe(depsgraph);
+}
+
+static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
+{
+ OutlineGpencilModifierData *mmd = (OutlineGpencilModifierData *)md;
+
+ walk(userData, ob, (ID **)&mmd->material, IDWALK_CB_USER);
+ walk(userData, ob, (ID **)&mmd->outline_material, IDWALK_CB_USER);
+ walk(userData, ob, (ID **)&mmd->object, IDWALK_CB_NOP);
+}
+
+static void updateDepsgraph(GpencilModifierData *md,
+ const ModifierUpdateDepsgraphContext *ctx,
+ const int UNUSED(mode))
+{
+ OutlineGpencilModifierData *lmd = (OutlineGpencilModifierData *)md;
+ if (ctx->scene->camera) {
+ DEG_add_object_relation(
+ ctx->node, ctx->scene->camera, DEG_OB_COMP_TRANSFORM, "Outline Modifier");
+ DEG_add_object_relation(
+ ctx->node, ctx->scene->camera, DEG_OB_COMP_PARAMETERS, "Outline Modifier");
+ }
+ if (lmd->object != NULL) {
+ DEG_add_object_relation(ctx->node, lmd->object, DEG_OB_COMP_TRANSFORM, "Outline Modifier");
+ }
+ DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Outline Modifier");
+}
+
+static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+{
+ uiLayout *layout = panel->layout;
+
+ PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL);
+
+ uiLayoutSetPropSep(layout, true);
+
+ uiItemR(layout, ptr, "thickness", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "use_keep_shape", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "subdivision", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "sample_length", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "outline_material", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE);
+
+ gpencil_modifier_panel_end(layout, ptr);
+}
+
+static void mask_panel_draw(const bContext *UNUSED(C), Panel *panel)
+{
+ gpencil_modifier_masking_panel_draw(panel, true, false);
+}
+
+static void panelRegister(ARegionType *region_type)
+{
+ PanelType *panel_type = gpencil_modifier_panel_register(
+ region_type, eGpencilModifierType_Outline, panel_draw);
+ gpencil_modifier_subpanel_register(
+ region_type, "mask", "Influence", NULL, mask_panel_draw, panel_type);
+}
+
+GpencilModifierTypeInfo modifierType_Gpencil_Outline = {
+ /* name */ N_("Outline"),
+ /* structName */ "OutlineGpencilModifierData",
+ /* structSize */ sizeof(OutlineGpencilModifierData),
+ /* type */ eGpencilModifierTypeType_Gpencil,
+ /* flags */ eGpencilModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ copyData,
+
+ /* deformStroke */ NULL,
+ /* generateStrokes */ generateStrokes,
+ /* bakeModifier */ bakeModifier,
+ /* remapTime */ NULL,
+
+ /* initData */ initData,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ updateDepsgraph,
+ /* dependsOnTime */ NULL,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ NULL,
+ /* panelRegister */ panelRegister,
+};
diff --git a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
index 324252ca369..56e317adca5 100644
--- a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
+++ b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
@@ -172,6 +172,19 @@
.curve_intensity = NULL, \
}
+#define _DNA_DEFAULT_OutlineGpencilModifierData \
+ { \
+ .material = NULL, \
+ .layername = "", \
+ .pass_index = 0, \
+ .flag = GP_OUTLINE_KEEP_SHAPE, \
+ .thickness = 1, \
+ .sample_length = 0.0f, \
+ .subdiv = 3, \
+ .layer_pass = 0, \
+ .outline_material = NULL, \
+ }
+
#define _DNA_DEFAULT_SimplifyGpencilModifierData \
{ \
.material = NULL, \
diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h
index ca1eac0bde8..629be51893a 100644
--- a/source/blender/makesdna/DNA_gpencil_modifier_types.h
+++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h
@@ -47,6 +47,7 @@ typedef enum GpencilModifierType {
eGpencilModifierType_WeightAngle = 23,
eGpencilModifierType_Shrinkwrap = 24,
eGpencilModifierType_Envelope = 25,
+ eGpencilModifierType_Outline = 26,
/* Keep last. */
NUM_GREASEPENCIL_MODIFIER_TYPES,
} GpencilModifierType;
@@ -313,6 +314,38 @@ typedef enum eOpacityGpencil_Flag {
GP_OPACITY_WEIGHT_FACTOR = (1 << 8),
} eOpacityGpencil_Flag;
+typedef struct OutlineGpencilModifierData {
+ GpencilModifierData modifier;
+ /** Target stroke origin. */
+ struct Object *object;
+ /** Material for filtering. */
+ struct Material *material;
+ /** Layer name. */
+ char layername[64];
+ /** Custom index for passes. */
+ int pass_index;
+ /** Flags. */
+ int flag;
+ /** Thickness. */
+ int thickness;
+ /** Sample Length. */
+ float sample_length;
+ /** Subdivisions. */
+ int subdiv;
+ /** Custom index for passes. */
+ int layer_pass;
+ /** Material for outline. */
+ struct Material *outline_material;
+} OutlineGpencilModifierData;
+
+typedef enum eOutlineGpencil_Flag {
+ GP_OUTLINE_INVERT_LAYER = (1 << 0),
+ GP_OUTLINE_INVERT_PASS = (1 << 1),
+ GP_OUTLINE_INVERT_LAYERPASS = (1 << 2),
+ GP_OUTLINE_INVERT_MATERIAL = (1 << 3),
+ GP_OUTLINE_KEEP_SHAPE = (1 << 4),
+} eOutlineGpencil_Flag;
+
typedef struct ArrayGpencilModifierData {
GpencilModifierData modifier;
struct Object *object;
diff --git a/source/blender/makesdna/intern/dna_defaults.c b/source/blender/makesdna/intern/dna_defaults.c
index 197a863db72..3cd0cbcc3d6 100644
--- a/source/blender/makesdna/intern/dna_defaults.c
+++ b/source/blender/makesdna/intern/dna_defaults.c
@@ -302,6 +302,7 @@ SDNA_DEFAULT_DECL_STRUCT(MultiplyGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(NoiseGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(OffsetGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(OpacityGpencilModifierData);
+SDNA_DEFAULT_DECL_STRUCT(OutlineGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(SimplifyGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(SmoothGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(SubdivGpencilModifierData);
@@ -542,6 +543,7 @@ const void *DNA_default_table[SDNA_TYPE_MAX] = {
SDNA_DEFAULT_DECL(NoiseGpencilModifierData),
SDNA_DEFAULT_DECL(OffsetGpencilModifierData),
SDNA_DEFAULT_DECL(OpacityGpencilModifierData),
+ SDNA_DEFAULT_DECL(OutlineGpencilModifierData),
SDNA_DEFAULT_DECL(SimplifyGpencilModifierData),
SDNA_DEFAULT_DECL(SmoothGpencilModifierData),
SDNA_DEFAULT_DECL(SubdivGpencilModifierData),
diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c
index 2dfd9d46665..0a400d3bcef 100644
--- a/source/blender/makesrna/intern/rna_gpencil_modifier.c
+++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c
@@ -105,6 +105,11 @@ const EnumPropertyItem rna_enum_object_greasepencil_modifier_type_items[] = {
ICON_GP_MULTIFRAME_EDITING,
"Multiple Strokes",
"Produce multiple strokes along one stroke"},
+ {eGpencilModifierType_Outline,
+ "GP_OUTLINE",
+ ICON_MOD_SKIN,
+ "Outline",
+ "Convert stroke to perimeter"},
{eGpencilModifierType_Simplify,
"GP_SIMPLIFY",
ICON_MOD_SIMPLIFY,
@@ -286,6 +291,8 @@ static StructRNA *rna_GpencilModifier_refine(struct PointerRNA *ptr)
return &RNA_BuildGpencilModifier;
case eGpencilModifierType_Opacity:
return &RNA_OpacityGpencilModifier;
+ case eGpencilModifierType_Outline:
+ return &RNA_OutlineGpencilModifier;
case eGpencilModifierType_Lattice:
return &RNA_LatticeGpencilModifier;
case eGpencilModifierType_Length:
@@ -668,6 +675,37 @@ static void rna_OpacityGpencilModifier_material_set(PointerRNA *ptr,
rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
}
+static void rna_OutlineGpencilModifier_object_set(PointerRNA *ptr,
+ PointerRNA value,
+ struct ReportList *UNUSED(reports))
+{
+ OutlineGpencilModifierData *omd = ptr->data;
+ Object *ob = (Object *)value.data;
+
+ omd->object = ob;
+ id_lib_extern((ID *)ob);
+}
+
+static void rna_OutlineGpencilModifier_material_set(PointerRNA *ptr,
+ PointerRNA value,
+ struct ReportList *reports)
+{
+ OutlineGpencilModifierData *omd = (OutlineGpencilModifierData *)ptr->data;
+ Material **ma_target = &omd->material;
+
+ rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
+static void rna_OutlineStrokeGpencilModifier_material_set(PointerRNA *ptr,
+ PointerRNA value,
+ struct ReportList *reports)
+{
+ OutlineGpencilModifierData *omd = (OutlineGpencilModifierData *)ptr->data;
+ Material **ma_target = &omd->outline_material;
+
+ rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
static void rna_LatticeGpencilModifier_material_set(PointerRNA *ptr,
PointerRNA value,
struct ReportList *reports)
@@ -1972,6 +2010,108 @@ static void rna_def_modifier_gpencilopacity(BlenderRNA *brna)
RNA_define_lib_overridable(false);
}
+static void rna_def_modifier_gpenciloutline(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "OutlineGpencilModifier", "GpencilModifier");
+ RNA_def_struct_ui_text(srna, "Outline Modifier", "Outline of Strokes modifier from camera view");
+ RNA_def_struct_sdna(srna, "OutlineGpencilModifierData");
+ // TODO: add new icon
+ RNA_def_struct_ui_icon(srna, ICON_MOD_SKIN);
+
+ RNA_define_lib_overridable(true);
+
+ prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "layername");
+ RNA_def_property_ui_text(prop, "Layer", "Layer name");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "material", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_pointer_funcs(prop,
+ NULL,
+ "rna_OutlineGpencilModifier_material_set",
+ NULL,
+ "rna_GpencilModifier_material_poll");
+ RNA_def_property_ui_text(prop, "Material", "Material used for filtering effect");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "pass_index");
+ RNA_def_property_range(prop, 0, 100);
+ RNA_def_property_ui_text(prop, "Pass", "Pass index");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OUTLINE_INVERT_LAYER);
+ RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "invert_materials", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OUTLINE_INVERT_MATERIAL);
+ RNA_def_property_ui_text(prop, "Inverse Materials", "Inverse filter");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "invert_material_pass", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OUTLINE_INVERT_PASS);
+ RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "layer_pass", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "layer_pass");
+ RNA_def_property_range(prop, 0, 100);
+ RNA_def_property_ui_text(prop, "Pass", "Layer pass index");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "invert_layer_pass", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OUTLINE_INVERT_LAYERPASS);
+ RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "thickness", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "thickness");
+ RNA_def_property_range(prop, 1, 1000);
+ RNA_def_property_ui_text(prop, "Thickness", "Thickness of the perimeter stroke");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "sample_length", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "sample_length");
+ RNA_def_property_ui_range(prop, 0.0f, 100.0f, 0.1f, 2);
+ RNA_def_property_ui_text(prop, "Sample Length", "");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "subdivision", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "subdiv");
+ RNA_def_property_range(prop, 0, 10);
+ RNA_def_property_ui_text(prop, "Subdivisions", "Number of subdivisions");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "use_keep_shape", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OUTLINE_KEEP_SHAPE);
+ RNA_def_property_ui_text(prop, "Keep Shape", "Try to keep global shape");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "outline_material", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_pointer_funcs(prop,
+ NULL,
+ "rna_OutlineStrokeGpencilModifier_material_set",
+ NULL,
+ "rna_GpencilModifier_material_poll");
+ RNA_def_property_ui_text(prop, "Outline Material", "Material used for outline strokes");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Target Object", "Target object to define stroke start");
+ RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_OutlineGpencilModifier_object_set", NULL, NULL);
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_dependency_update");
+
+ RNA_define_lib_overridable(false);
+}
+
static void rna_def_modifier_gpencilarray(BlenderRNA *brna)
{
StructRNA *srna;
@@ -4353,6 +4493,7 @@ void RNA_def_greasepencil_modifier(BlenderRNA *brna)
rna_def_modifier_gpencilarray(brna);
rna_def_modifier_gpencilbuild(brna);
rna_def_modifier_gpencilopacity(brna);
+ rna_def_modifier_gpenciloutline(brna);
rna_def_modifier_gpencillattice(brna);
rna_def_modifier_gpencilmirror(brna);
rna_def_modifier_gpencilhook(brna);