GPencil: Adding length modifier.

Reviewed By: Antonio Vazquez (antoniov)

Differential Revision: https://developer.blender.org/D8264
This commit is contained in:
YimingWu 2021-05-20 23:35:53 +08:00
parent 933999db75
commit cd16123761
Notes: blender-bot 2023-02-14 09:48:25 +01:00
Referenced by issue #79879, GPencil: New Length modifier
11 changed files with 452 additions and 68 deletions

View File

@ -111,7 +111,10 @@ void BKE_gpencil_dissolve_points(struct bGPdata *gpd,
struct bGPDstroke *gps,
const short tag);
bool BKE_gpencil_stroke_stretch(struct bGPDstroke *gps, const float dist, const float tip_length);
bool BKE_gpencil_stroke_stretch(struct bGPDstroke *gps,
const float dist,
const float overshoot_fac,
const short mode);
bool BKE_gpencil_stroke_trim_points(struct bGPDstroke *gps,
const int index_from,
const int index_to);
@ -135,7 +138,7 @@ bool BKE_gpencil_stroke_split(struct bGPdata *gpd,
struct bGPDstroke *gps,
const int before_index,
struct bGPDstroke **remaining_gps);
bool BKE_gpencil_stroke_shrink(struct bGPDstroke *gps, const float dist);
bool BKE_gpencil_stroke_shrink(struct bGPDstroke *gps, const float dist, const short mode);
float BKE_gpencil_stroke_length(const struct bGPDstroke *gps, bool use_3d);
float BKE_gpencil_stroke_segment_length(const struct bGPDstroke *gps,

View File

@ -530,14 +530,23 @@ bool BKE_gpencil_stroke_sample(bGPdata *gpd, bGPDstroke *gps, const float dist,
/**
* Backbone stretch similar to Freestyle.
* \param gps: Stroke to sample
* \param dist: Distance of one segment
* \param tip_length: Ignore tip jittering, set zero to use default value.
* \param gps: Stroke to sample.
* \param dist: Distance of one segment.
* \param overshoot_fac: How exact is the follow curve algorithm.
* \param mode: Affect to Start, End or Both extremes (0->Both, 1->Start, 2->End)
*/
bool BKE_gpencil_stroke_stretch(bGPDstroke *gps, const float dist, const float tip_length)
bool BKE_gpencil_stroke_stretch(bGPDstroke *gps,
const float dist,
const float overshoot_fac,
const short mode)
{
#define BOTH 0
#define START 1
#define END 2
bGPDspoint *pt = gps->points, *last_pt, *second_last, *next_pt;
float threshold = (tip_length == 0 ? 0.001f : tip_length);
int i;
float threshold = (overshoot_fac == 0 ? 0.001f : overshoot_fac);
if (gps->totpoints < 2 || dist < FLT_EPSILON) {
return false;
@ -547,34 +556,37 @@ bool BKE_gpencil_stroke_stretch(bGPDstroke *gps, const float dist, const float t
second_last = &pt[gps->totpoints - 2];
next_pt = &pt[1];
float len1 = 0.0f;
float len2 = 0.0f;
if (mode == BOTH || mode == START) {
float len1 = 0.0f;
i = 1;
while (len1 < threshold && gps->totpoints > i) {
next_pt = &pt[i];
len1 = len_v3v3(&next_pt->x, &pt->x);
i++;
}
float extend1 = (len1 + dist) / len1;
float result1[3];
int i = 1;
while (len1 < threshold && gps->totpoints > i) {
next_pt = &pt[i];
len1 = len_v3v3(&next_pt->x, &pt->x);
i++;
interp_v3_v3v3(result1, &next_pt->x, &pt->x, extend1);
copy_v3_v3(&pt->x, result1);
}
i = 2;
while (len2 < threshold && gps->totpoints >= i) {
second_last = &pt[gps->totpoints - i];
len2 = len_v3v3(&last_pt->x, &second_last->x);
i++;
if (mode == BOTH || mode == END) {
float len2 = 0.0f;
i = 2;
while (len2 < threshold && gps->totpoints >= i) {
second_last = &pt[gps->totpoints - i];
len2 = len_v3v3(&last_pt->x, &second_last->x);
i++;
}
float extend2 = (len2 + dist) / len2;
float result2[3];
interp_v3_v3v3(result2, &second_last->x, &last_pt->x, extend2);
copy_v3_v3(&last_pt->x, result2);
}
float extend1 = (len1 + dist) / len1;
float extend2 = (len2 + dist) / len2;
float result1[3], result2[3];
interp_v3_v3v3(result1, &next_pt->x, &pt->x, extend1);
interp_v3_v3v3(result2, &second_last->x, &last_pt->x, extend2);
copy_v3_v3(&pt->x, result1);
copy_v3_v3(&last_pt->x, result2);
return true;
}
@ -702,48 +714,64 @@ bool BKE_gpencil_stroke_split(bGPdata *gpd,
* Shrink the stroke by length.
* \param gps: Stroke to shrink
* \param dist: delta length
* \param mode: 1->Start, 2->End
*/
bool BKE_gpencil_stroke_shrink(bGPDstroke *gps, const float dist)
bool BKE_gpencil_stroke_shrink(bGPDstroke *gps, const float dist, const short mode)
{
#define START 1
#define END 2
bGPDspoint *pt = gps->points, *second_last;
int i;
if (gps->totpoints < 2 || dist < FLT_EPSILON) {
if (gps->totpoints < 2) {
if (gps->totpoints == 1) {
second_last = &pt[1];
if (len_v3v3(&second_last->x, &pt->x) < dist) {
BKE_gpencil_stroke_trim_points(gps, 0, 0);
return true;
}
}
return false;
}
second_last = &pt[gps->totpoints - 2];
float len1, this_len1, cut_len1;
float len2, this_len2, cut_len2;
int index_start, index_end;
float len1, cut_len1;
float len2, cut_len2;
len1 = len2 = cut_len1 = cut_len2 = 0.0f;
len1 = len2 = this_len1 = this_len2 = cut_len1 = cut_len2 = 0.0f;
i = 1;
while (len1 < dist && gps->totpoints > i - 1) {
this_len1 = len_v3v3(&pt[i].x, &pt[i + 1].x);
len1 += this_len1;
cut_len1 = len1 - dist;
i++;
int index_start = 0;
int index_end = 0;
if (mode == START) {
i = 0;
index_end = gps->totpoints - 1;
while (len1 < dist && gps->totpoints > i + 1) {
len1 += len_v3v3(&pt[i].x, &pt[i + 1].x);
cut_len1 = len1 - dist;
i++;
}
index_start = i - 1;
}
index_start = i - 2;
i = 2;
while (len2 < dist && gps->totpoints >= i) {
second_last = &pt[gps->totpoints - i];
this_len2 = len_v3v3(&second_last[1].x, &second_last->x);
len2 += this_len2;
cut_len2 = len2 - dist;
i++;
if (mode == END) {
index_start = 0;
i = 2;
while (len2 < dist && gps->totpoints >= i) {
second_last = &pt[gps->totpoints - i];
len2 += len_v3v3(&second_last[1].x, &second_last->x);
cut_len2 = len2 - dist;
i++;
}
index_end = gps->totpoints - i + 2;
}
index_end = gps->totpoints - i + 2;
if (len1 < dist || len2 < dist || index_end <= index_start) {
if (index_end <= index_start) {
index_start = index_end = 0; /* empty stroke */
}
if ((index_end == index_start + 1) && (cut_len1 + cut_len2 > 1.0f)) {
if ((index_end == index_start + 1) && (cut_len1 + cut_len2 < dist)) {
index_start = index_end = 0; /* no length left to cut */
}
@ -753,22 +781,8 @@ bool BKE_gpencil_stroke_shrink(bGPDstroke *gps, const float dist)
return false;
}
pt = gps->points;
float cut1 = cut_len1 / this_len1;
float cut2 = cut_len2 / this_len2;
float result1[3], result2[3];
interp_v3_v3v3(result1, &pt[1].x, &pt[0].x, cut1);
interp_v3_v3v3(result2, &pt[gps->totpoints - 2].x, &pt[gps->totpoints - 1].x, cut2);
copy_v3_v3(&pt[0].x, result1);
copy_v3_v3(&pt[gps->totpoints - 1].x, result2);
return true;
}
/**
* Apply smooth position to stroke point.
* \param gps: Stroke to smooth

View File

@ -54,6 +54,7 @@ set(SRC
intern/MOD_gpencilcolor.c
intern/MOD_gpencilhook.c
intern/MOD_gpencillattice.c
intern/MOD_gpencillength.c
intern/MOD_gpencillineart.c
intern/MOD_gpencilmirror.c
intern/MOD_gpencilmultiply.c

View File

@ -35,6 +35,7 @@ extern GpencilModifierTypeInfo modifierType_Gpencil_Array;
extern GpencilModifierTypeInfo modifierType_Gpencil_Build;
extern GpencilModifierTypeInfo modifierType_Gpencil_Opacity;
extern GpencilModifierTypeInfo modifierType_Gpencil_Lattice;
extern GpencilModifierTypeInfo modifierType_Gpencil_Length;
extern GpencilModifierTypeInfo modifierType_Gpencil_Mirror;
extern GpencilModifierTypeInfo modifierType_Gpencil_Smooth;
extern GpencilModifierTypeInfo modifierType_Gpencil_Hook;

View File

@ -54,6 +54,7 @@ void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[])
INIT_GP_TYPE(Build);
INIT_GP_TYPE(Opacity);
INIT_GP_TYPE(Lattice);
INIT_GP_TYPE(Length);
INIT_GP_TYPE(Mirror);
INIT_GP_TYPE(Smooth);
INIT_GP_TYPE(Hook);

View File

@ -0,0 +1,223 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2017, Blender Foundation
* This is a new part of Blender
*
* ***** END GPL LICENSE BLOCK *****
*
*/
/** \file
* \ingroup modifiers
*/
#include <stdio.h>
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
#include "DNA_defaults.h"
#include "DNA_gpencil_modifier_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "BKE_context.h"
#include "BKE_gpencil_geom.h"
#include "BKE_gpencil_modifier.h"
#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
#include "BKE_screen.h"
#include "MEM_guardedalloc.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "RNA_access.h"
#include "MOD_gpencil_modifiertypes.h"
#include "MOD_gpencil_ui_common.h"
#include "MOD_gpencil_util.h"
#include "DEG_depsgraph.h"
static void initData(GpencilModifierData *md)
{
LengthGpencilModifierData *gpmd = (LengthGpencilModifierData *)md;
BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(gpmd, modifier));
MEMCPY_STRUCT_AFTER(gpmd, DNA_struct_default_get(LengthGpencilModifierData), modifier);
}
static void copyData(const GpencilModifierData *md, GpencilModifierData *target)
{
BKE_gpencil_modifier_copydata_generic(md, target);
}
static bool gpencil_modify_stroke(bGPDstroke *gps,
float length,
const float overshoot_fac,
const short len_mode)
{
bool changed = false;
if (length == 0.0f) {
return changed;
}
if (length > 0.0f) {
BKE_gpencil_stroke_stretch(gps, length, overshoot_fac, len_mode);
}
else {
changed |= BKE_gpencil_stroke_shrink(gps, fabs(length), len_mode);
}
return changed;
}
static void applyLength(LengthGpencilModifierData *lmd, bGPdata *gpd, bGPDstroke *gps)
{
bool changed = false;
const float len = (lmd->mode == GP_LENGTH_ABSOLUTE) ? 1.0f :
BKE_gpencil_stroke_length(gps, true);
if (len < FLT_EPSILON) {
return;
}
changed |= gpencil_modify_stroke(gps, len * lmd->start_fac, lmd->overshoot_fac, 1);
changed |= gpencil_modify_stroke(gps, len * lmd->end_fac, lmd->overshoot_fac, 2);
if (changed) {
BKE_gpencil_stroke_geometry_update(gpd, gps);
}
}
static void bakeModifier(Main *UNUSED(bmain),
Depsgraph *UNUSED(depsgraph),
GpencilModifierData *md,
Object *ob)
{
bGPdata *gpd = ob->data;
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
LengthGpencilModifierData *lmd = (LengthGpencilModifierData *)md;
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
applyLength(lmd, gpd, gps);
}
}
}
}
/* -------------------------------- */
/* Generic "generateStrokes" callback */
static void deformStroke(GpencilModifierData *md,
Depsgraph *UNUSED(depsgraph),
Object *ob,
bGPDlayer *gpl,
bGPDframe *UNUSED(gpf),
bGPDstroke *gps)
{
bGPdata *gpd = ob->data;
LengthGpencilModifierData *lmd = (LengthGpencilModifierData *)md;
if (is_stroke_affected_by_modifier(ob,
lmd->layername,
lmd->material,
lmd->pass_index,
lmd->layer_pass,
1,
gpl,
gps,
lmd->flag & GP_LENGTH_INVERT_LAYER,
lmd->flag & GP_LENGTH_INVERT_PASS,
lmd->flag & GP_LENGTH_INVERT_LAYERPASS,
lmd->flag & GP_LENGTH_INVERT_MATERIAL)) {
applyLength(lmd, gpd, gps);
}
}
static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
LengthGpencilModifierData *mmd = (LengthGpencilModifierData *)md;
walk(userData, ob, (ID **)&mmd->material, IDWALK_CB_USER);
}
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, "mode", 0, NULL, ICON_NONE);
uiLayout *col = uiLayoutColumn(layout, true);
uiItemR(col, ptr, "start_factor", 0, IFACE_("Start"), ICON_NONE);
uiItemR(col, ptr, "end_factor", 0, IFACE_("End"), ICON_NONE);
uiItemR(layout, ptr, "overshoot_factor", UI_ITEM_R_SLIDER, IFACE_("Overshoot"), 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_Length, panel_draw);
gpencil_modifier_subpanel_register(
region_type, "mask", "Influence", NULL, mask_panel_draw, panel_type);
}
GpencilModifierTypeInfo modifierType_Gpencil_Length = {
/* name */ "Length",
/* structName */ "LengthGpencilModifierData",
/* structSize */ sizeof(LengthGpencilModifierData),
/* type */ eGpencilModifierTypeType_Gpencil,
/* flags */ eGpencilModifierTypeFlag_SupportsEditmode,
/* copyData */ copyData,
/* deformStroke */ deformStroke,
/* generateStrokes */ NULL,
/* bakeModifier */ bakeModifier,
/* remapTime */ NULL,
/* initData */ initData,
/* freeData */ NULL,
/* isDisabled */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* panelRegister */ panelRegister,
};

View File

@ -299,4 +299,14 @@
.chaining_image_threshold = 0.001f, \
}
#define _DNA_DEFAULT_LengthGpencilModifierData \
{ \
.start_fac = 0.1f,\
.end_fac = 0.1f,\
.overshoot_fac = 0.01f,\
.pass_index = 0,\
.material = NULL,\
}
/* clang-format off */

View File

@ -54,6 +54,7 @@ typedef enum GpencilModifierType {
eGpencilModifierType_Multiply = 17,
eGpencilModifierType_Texture = 18,
eGpencilModifierType_Lineart = 19,
eGpencilModifierType_Length = 20,
/* Keep last. */
NUM_GREASEPENCIL_MODIFIER_TYPES,
} GpencilModifierType;
@ -484,6 +485,39 @@ typedef enum eLatticeGpencil_Flag {
GP_LATTICE_INVERT_MATERIAL = (1 << 4),
} eLatticeGpencil_Flag;
typedef struct LengthGpencilModifierData {
GpencilModifierData modifier;
/** Material for filtering. */
struct Material *material;
/** Layer name. */
char layername[64];
/** Custom index for passes. */
int pass_index;
/** Flags. */
int flag;
/** Custom index for passes. */
int layer_pass;
/** Length. */
float start_fac, end_fac;
/** Overshoot trajectory factor. */
float overshoot_fac;
/** Modifier mode. */
int mode;
char _pad[4];
} LengthGpencilModifierData;
typedef enum eLengthGpencil_Flag {
GP_LENGTH_INVERT_LAYER = (1 << 0),
GP_LENGTH_INVERT_PASS = (1 << 1),
GP_LENGTH_INVERT_LAYERPASS = (1 << 2),
GP_LENGTH_INVERT_MATERIAL = (1 << 3),
} eLengthGpencil_Flag;
typedef enum eLengthGpencil_Type {
GP_LENGTH_RELATIVE = 0,
GP_LENGTH_ABSOLUTE = 1,
} eLengthGpencil_Type;
typedef struct MirrorGpencilModifierData {
GpencilModifierData modifier;
struct Object *object;

View File

@ -316,6 +316,7 @@ SDNA_DEFAULT_DECL_STRUCT(ThickGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(TimeGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(TintGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(LineartGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(LengthGpencilModifierData);
#undef SDNA_DEFAULT_DECL_STRUCT
@ -541,6 +542,7 @@ const void *DNA_default_table[SDNA_TYPE_MAX] = {
SDNA_DEFAULT_DECL(TimeGpencilModifierData),
SDNA_DEFAULT_DECL(TintGpencilModifierData),
SDNA_DEFAULT_DECL(LineartGpencilModifierData),
SDNA_DEFAULT_DECL(LengthGpencilModifierData),
};
#undef SDNA_DEFAULT_DECL
#undef SDNA_DEFAULT_DECL_EX

View File

@ -336,6 +336,7 @@ extern StructRNA RNA_LatticeModifier;
extern StructRNA RNA_LatticePoint;
extern StructRNA RNA_LayerCollection;
extern StructRNA RNA_LayerObjects;
extern StructRNA RNA_LengthGpencilModifier;
extern StructRNA RNA_Library;
extern StructRNA RNA_Light;
extern StructRNA RNA_LightProbe;

View File

@ -109,6 +109,11 @@ const EnumPropertyItem rna_enum_object_greasepencil_modifier_type_items[] = {
ICON_MOD_LATTICE,
"Lattice",
"Deform strokes using lattice"},
{eGpencilModifierType_Length,
"GP_LENGTH",
ICON_MOD_EDGESPLIT,
"Length",
"Extend or shrink strokes"},
{eGpencilModifierType_Noise, "GP_NOISE", ICON_MOD_NOISE, "Noise", "Add noise to strokes"},
{eGpencilModifierType_Offset,
"GP_OFFSET",
@ -188,6 +193,11 @@ static const EnumPropertyItem gpencil_tint_type_items[] = {
{GP_TINT_GRADIENT, "GRADIENT", 0, "Gradient", ""},
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem gpencil_length_mode_items[] = {
{GP_LENGTH_RELATIVE, "RELATIVE", 0, "Relative", "Length in ratio to the stroke's length"},
{GP_LENGTH_ABSOLUTE, "ABSOLUTE", 0, "Absolute", "Length in geometry space"},
{0, NULL, 0, NULL, NULL},
};
#endif
#ifdef RNA_RUNTIME
@ -233,6 +243,8 @@ static StructRNA *rna_GpencilModifier_refine(struct PointerRNA *ptr)
return &RNA_OpacityGpencilModifier;
case eGpencilModifierType_Lattice:
return &RNA_LatticeGpencilModifier;
case eGpencilModifierType_Length:
return &RNA_LengthGpencilModifier;
case eGpencilModifierType_Mirror:
return &RNA_MirrorGpencilModifier;
case eGpencilModifierType_Smooth:
@ -2901,6 +2913,87 @@ static void rna_def_modifier_gpencillineart(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
}
static void rna_def_modifier_gpencillength(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "LengthGpencilModifier", "GpencilModifier");
RNA_def_struct_ui_text(srna, "Length Modifier", "Stretch or shrink strokes");
RNA_def_struct_sdna(srna, "LengthGpencilModifierData");
RNA_def_struct_ui_icon(srna, ICON_MOD_EDGESPLIT);
prop = RNA_def_property(srna, "start_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "start_fac");
RNA_def_property_ui_range(prop, -10.0f, 10.0f, 0.1, 1);
RNA_def_property_ui_text(prop, "Start Factor", "Length difference for each segment");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "end_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "end_fac");
RNA_def_property_ui_range(prop, -10.0f, 10.0f, 0.1, 1);
RNA_def_property_ui_text(prop, "End Factor", "Length difference for each segment");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "overshoot_factor", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "overshoot_fac");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(
prop,
"Overshoot Factor",
"Defines how precise must follow the stroke trajectory for the overshoot extremes");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mode");
RNA_def_property_enum_items(prop, gpencil_length_mode_items);
RNA_def_property_ui_text(prop, "Mode", "Mode to define length");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
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 | PROP_ID_SELF_CHECK);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
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_LENGTH_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_LENGTH_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_LENGTH_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_LENGTH_INVERT_LAYERPASS);
RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
}
void RNA_def_greasepencil_modifier(BlenderRNA *brna)
{
StructRNA *srna;
@ -2976,6 +3069,7 @@ void RNA_def_greasepencil_modifier(BlenderRNA *brna)
rna_def_modifier_gpencilmultiply(brna);
rna_def_modifier_gpenciltexture(brna);
rna_def_modifier_gpencillineart(brna);
rna_def_modifier_gpencillength(brna);
}
#endif