GPencil: Adding length modifier.
Reviewed By: Antonio Vazquez (antoniov) Differential Revision: https://developer.blender.org/D8264
This commit is contained in:
parent
933999db75
commit
cd16123761
Notes:
blender-bot
2023-02-14 09:48:25 +01:00
Referenced by issue #79879, GPencil: New Length modifier
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
};
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue