WIP: Surface Deform Grease Pencil Modifier - Blender 3.6 #113396

Draft
Elisabetta Abbattista wants to merge 27 commits from bettiabba/blender:Surface-Deform-GP-Modifier-Blender-v3.6 into blender-v3.6-release

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
19 changed files with 4109 additions and 2 deletions

View File

@ -910,6 +910,95 @@ void BKE_gpencil_modifier_blend_write(BlendWriter *writer, ListBase *modbase)
TimeGpencilModifierData *gpmd = (TimeGpencilModifierData *)md;
BLO_write_struct_array(
writer, TimeGpencilModifierSegment, gpmd->segments_len, gpmd->segments);
}
else if (md->type == eGpencilModifierType_SurDeform) {
SurDeformGpencilModifierData *smd = (SurDeformGpencilModifierData *)md;
//const bool is_undo = BLO_write_is_undo(writer);
// if (BKE_gpencil_modifier_is_nonlocal_in_liboverride(md->, md) &&
// !is_undo) {
/* Modifier coming from linked data cannot be bound from an override, so we can remove
* all binding data, can save a significant amount of memory. */
// smd->strokes_num = 0;
// smd->strokes = NULL;
// }
// BLO_write_struct_at_address(writer, SurDeformGpencilModifierData, md, &smd);
if (smd->layers != NULL)
{
BLO_write_struct_array( writer, SDefGPLayer,
smd->num_of_layers,
smd->layers);
for (int l = 0; l < smd->num_of_layers; l++)
{
smd->layers[l].blender_layer = NULL;
if (smd->layers[l].frames != NULL)
{
BLO_write_struct_array( writer, SDefGPFrame,
smd->layers[l].num_of_frames,
smd->layers[l].frames);
for (int f = 0; f < smd->layers[l].num_of_frames; f++)
{
smd->layers[l].frames[f].blender_frame = NULL;
if (smd->layers[l].frames[f].strokes != NULL)
{
//SDefGPStroke *strokes = smd->layers[l].frames[f].strokes;
while (smd->layers[l].frames[f].strokes->stroke_idx > 0)
{
(smd->layers[l].frames[f].strokes)--;
} /*Rewind stroke array */
BLO_write_struct_array( writer, SDefGPStroke,
smd->layers[l].frames[f].strokes_num,
smd->layers[l].frames[f].strokes);
for (int k = 0; k < smd->layers[l].frames[f].strokes_num; k++)
{
if (smd->layers[l].frames[f].strokes[k].verts != NULL)
{
SDefGPVert *bind_verts = smd->layers[l].frames[f].strokes[k].verts;
BLO_write_struct_array(
writer, SDefGPVert, smd->layers[l].frames[f].strokes[k].stroke_verts_num,
smd->layers[l].frames[f].strokes[k].verts);
for (int i = 0; i < smd->layers[l].frames[f].strokes[k].stroke_verts_num; i++)
{
if (bind_verts[i].binds)
{
BLO_write_struct_array(
writer, SDefGPBind, bind_verts[i].binds_num, bind_verts[i].binds);
for (int j = 0; j < bind_verts[i].binds_num; j++)
{
BLO_write_uint32_array(
writer, bind_verts[i].binds[j].verts_num, bind_verts[i].binds[j].vert_inds);
if (ELEM(bind_verts[i].binds[j].mode,
MOD_SDEF_MODE_CENTROID,
MOD_SDEF_MODE_LOOPTRI))
{
BLO_write_float3_array(writer, 1, bind_verts[i].binds[j].vert_weights);
}
else
{
BLO_write_float_array(writer,
bind_verts[i].binds[j].verts_num,
bind_verts[i].binds[j].vert_weights);
}
}
}
}
}
}
}
}
}
}
}
}
}
}
@ -1004,10 +1093,82 @@ void BKE_gpencil_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb)
gpmd->segments[i].gpmd = gpmd;
}
}
if (md->type == eGpencilModifierType_Shrinkwrap) {
else if (md->type == eGpencilModifierType_SurDeform)
{
SurDeformGpencilModifierData *smd = (SurDeformGpencilModifierData *)md;
SDefGPLayer *first_layer;
SDefGPFrame *first_frame;
SDefGPStroke *first_stroke;
BLO_read_data_address(reader, &smd->layers);
if (smd->layers != NULL)
{
first_layer = smd->layers;
for (int l = 0; l < smd->num_of_layers; l++)
{
smd->layers[l].first = first_layer;
BLO_read_data_address(reader, &(smd->layers[l].frames));
if (smd->layers[l].frames != NULL)
{
first_frame = smd->layers[l].frames;
for (int f = 0; f < smd->layers[l].num_of_frames; f++)
{
smd->layers[l].frames[f].first = first_frame;
BLO_read_data_address(reader, &(smd->layers[l].frames[f].strokes));
if (smd->layers[l].frames[f].strokes != NULL)
{
first_stroke = smd->layers[l].frames[f].strokes;
for (int k = 0; k < smd->layers[l].frames[f].strokes_num; k++)
{
smd->layers[l].frames[f].strokes[k].first = first_stroke;
BLO_read_data_address(reader, &smd->layers[l].frames[f].strokes[k].verts);
SDefGPVert *bind_verts = smd->layers[l].frames[f].strokes[k].verts;
if (smd->layers[l].frames[f].strokes[k].verts != NULL)
{
for (int i = 0; i < smd->layers[l].frames[f].strokes[k].stroke_verts_num; i++)
{
BLO_read_data_address(reader, &bind_verts[i].binds);
SDefGPBind *binds = bind_verts[i].binds;
if (bind_verts[i].binds)
{
for (int j = 0; j < bind_verts[i].binds_num; j++)
{
BLO_read_uint32_array(
reader, bind_verts[i].binds[j].verts_num, &bind_verts[i].binds[j].vert_inds);
if (ELEM(bind_verts[i].binds[j].mode,
MOD_SDEF_MODE_CENTROID,
MOD_SDEF_MODE_LOOPTRI))
{
BLO_read_float3_array(reader, 1, &bind_verts[i].binds[j].vert_weights);
}
else
{
BLO_read_float_array(reader,
bind_verts[i].binds[j].verts_num,
&bind_verts[i].binds[j].vert_weights);
}
}
}
}
}
}
}
}
}
}
}
}
if (md->type == eGpencilModifierType_Shrinkwrap)
{
ShrinkwrapGpencilModifierData *gpmd = (ShrinkwrapGpencilModifierData *)md;
gpmd->cache_data = NULL;
}
}
}

View File

@ -58,6 +58,9 @@ void draw_keyframe_shape(float x,
case BEZT_KEYTYPE_KEYFRAME: /* must be full size */
break;
case BEZT_KEYTYPE_SURDEFBOUND: /* surface defrom GP bound - full size */
break;
case BEZT_KEYTYPE_BREAKDOWN: /* slightly smaller than normal keyframe */
size *= 0.85f;
break;
@ -95,6 +98,9 @@ void draw_keyframe_shape(float x,
case BEZT_KEYTYPE_MOVEHOLD: /* similar to traditional keyframes, but different... */
UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_MOVEHOLD_SELECT : TH_KEYTYPE_MOVEHOLD, fill_col);
break;
case BEZT_KEYTYPE_SURDEFBOUND: /* surface defrom GP bound */
UI_GetThemeColor4ubv(TH_TIME_SCRUB_BACKGROUND, fill_col);
break;
case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames (default theme) */
default:
UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_KEYFRAME_SELECT : TH_KEYTYPE_KEYFRAME, fill_col);

View File

@ -241,6 +241,8 @@ bool ED_gpencil_layer_frames_delete(bGPDlayer *gpl)
/* check for frames to delete */
LISTBASE_FOREACH_MUTABLE (bGPDframe *, gpf, &gpl->frames) {
if (gpf->flag & GP_FRAME_SELECT) {
if (gpf->key_type == BEZT_KEYTYPE_SURDEFBOUND)
continue;
BKE_gpencil_layer_frame_delete(gpl, gpf);
changed = true;
}

View File

@ -221,6 +221,10 @@ void OBJECT_OT_gpencil_modifier_move_to_index(struct wmOperatorType *ot);
void OBJECT_OT_gpencil_modifier_apply(struct wmOperatorType *ot);
void OBJECT_OT_gpencil_modifier_copy(struct wmOperatorType *ot);
void OBJECT_OT_gpencil_modifier_copy_to_selected(struct wmOperatorType *ot);
void GPENCIL_OT_gpencilsurdeform_bind(struct wmOperatorType *ot);
void GPENCIL_OT_gpencilsurdeform_unbind(struct wmOperatorType *ot);
void GPENCIL_OT_gpencilsurdeform_bake(struct wmOperatorType *ot);
void GPENCIL_OT_gpencilsurdeform_fillrange(struct wmOperatorType *ot);
void GPENCIL_OT_segment_add(struct wmOperatorType *ot);
void GPENCIL_OT_segment_remove(struct wmOperatorType *ot);

View File

@ -22,6 +22,7 @@
#include "object_intern.h"
#include "MOD_gpencil_legacy_lineart.h"
#include "MOD_gpencil_surdeform_header.h"
/* ************************** registration **********************************/
@ -157,6 +158,7 @@ void ED_operatortypes_object(void)
/* grease pencil line art */
WM_operatortypes_lineart();
WM_operatortypes_gpencilsurdeform();
/* Shader FX. */
WM_operatortype_append(OBJECT_OT_shaderfx_add);

View File

@ -89,6 +89,8 @@ static int count_gplayer_frames(bGPDlayer *gpl, char side, float cfra, bool is_p
/* only include points that occur on the right side of cfra */
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
if (gpf->key_type == BEZT_KEYTYPE_SURDEFBOUND)
continue;
if (FrameOnMouseSide(side, (float)gpf->framenum, cfra)) {
if (gpf->flag & GP_FRAME_SELECT) {
count++;
@ -233,6 +235,8 @@ static int GPLayerToTransData(TransData *td,
/* check for select frames on right side of current frame */
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
if (gpf->key_type == BEZT_KEYTYPE_SURDEFBOUND)
continue;
const bool is_selected = (gpf->flag & GP_FRAME_SELECT) != 0;
if (is_prop_edit || is_selected) {
if (FrameOnMouseSide(side, (float)gpf->framenum, cfra)) {
@ -467,6 +471,8 @@ static void createTransActionData(bContext *C, TransInfo *t)
bGPDframe *gpf;
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
if (gpf->key_type == BEZT_KEYTYPE_SURDEFBOUND)
continue;
if (gpf->flag & GP_FRAME_SELECT) {
td->dist = td->rdist = 0.0f;
}
@ -733,6 +739,13 @@ static void posttrans_gpd_clean(bGPdata *gpd)
}
#endif
}
/*Great place for GP SurDef callback!
Actually I need to make this a callback to some other file
officially, but for now that it's a side project let's leve it
here, it works after all*/
/* set cache flag to dirty */
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);

View File

@ -59,6 +59,8 @@ set(SRC
intern/MOD_gpencil_legacy_util.c
intern/MOD_gpencil_legacy_weight_angle.c
intern/MOD_gpencil_legacy_weight_proximity.c
intern/MOD_gpencilsurdeform.c
intern/MOD_gpencilsurdeform_ops.cc
MOD_gpencil_legacy_lineart.h
MOD_gpencil_legacy_modifiertypes.h

View File

@ -37,6 +37,7 @@ extern GpencilModifierTypeInfo modifierType_Gpencil_Lineart;
extern GpencilModifierTypeInfo modifierType_Gpencil_Dash;
extern GpencilModifierTypeInfo modifierType_Gpencil_Shrinkwrap;
extern GpencilModifierTypeInfo modifierType_Gpencil_Envelope;
extern GpencilModifierTypeInfo modifierType_Gpencil_SurDeform;
/* MOD_gpencil_legacy_util.c */

View File

@ -0,0 +1,34 @@
/*This is a copy of the lineart header file.
I couldent get my operators to be recognized by object_ops.c
anymore, for some reason. I had no idea how it previously worked, has
probably something to do with cmake and can't figure it out.
Well, it's not that bad, it's just one more file.
I will gladly accept any suggestion on how to get rid of this file.
Thanks.*/
/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup modifiers
*/
#pragma once
#include "DNA_windowmanager_types.h"
/* Operator types should be in exposed header. */
#ifdef __cplusplus
extern "C" {
#endif
void GPENCIL_OT_gpencilsurdeform_bind(struct wmOperatorType *ot);
void GPENCIL_OT_gpencilsurdeform_unbind(struct wmOperatorType *ot);
void GPENCIL_OT_gpencilsurdeform_bake(struct wmOperatorType *ot);
void GPENCIL_OT_gpencilsurdeform_fillrange(struct wmOperatorType *ot);
void WM_operatortypes_gpencilsurdeform(void);
#ifdef __cplusplus
}
#endif

View File

@ -58,6 +58,7 @@ void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[])
INIT_GP_TYPE(Dash);
INIT_GP_TYPE(Shrinkwrap);
INIT_GP_TYPE(Envelope);
INIT_GP_TYPE(SurDeform);
#undef INIT_GP_TYPE
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -504,6 +504,7 @@ typedef enum eBezTriple_KeyframeType {
BEZT_KEYTYPE_BREAKDOWN = 2, /* 'breakdown' keyframe */
BEZT_KEYTYPE_JITTER = 3, /* 'jitter' keyframe (for adding 'filler' secondary motion) */
BEZT_KEYTYPE_MOVEHOLD = 4, /* one end of a 'moving hold' */
BEZT_KEYTYPE_SURDEFBOUND = 5, /* Bound frame in GP Surface Deform */
} eBezTriple_KeyframeType;
/* checks if the given BezTriple is selected */

View File

@ -412,5 +412,22 @@
.skip = 0, \
}
#define _DNA_DEFAULT_SurDeformGpencilModifierData \
{ \
.depsgraph = NULL, \
.target = NULL, \
.layers = NULL, \
.falloff = 4.0f, \
.num_of_layers = 0, \
.target_verts_num = 0, \
.target_polys_num = 0, \
.flags = 0, \
.bound_flags = 0, \
.bind_modes = 5, \
.mat = _DNA_DEFAULT_UNIT_M4, \
.strength = 1.0f, \
.defgrp_name = "", \
}
/* clang-format off */

View File

@ -8,6 +8,7 @@
#include "DNA_defs.h"
#include "DNA_listBase.h"
//#include "DNA_gpencil_types.h"
#ifdef __cplusplus
extern "C" {
@ -48,6 +49,7 @@ typedef enum GpencilModifierType {
eGpencilModifierType_Shrinkwrap = 24,
eGpencilModifierType_Envelope = 25,
eGpencilModifierType_Outline = 26,
eGpencilModifierType_SurDeform = 27,
/* Keep last. */
NUM_GREASEPENCIL_MODIFIER_TYPES,
} GpencilModifierType;
@ -1312,6 +1314,161 @@ typedef enum eEnvelopeGpencil_Mode {
GP_ENVELOPE_FILLS = 2,
} eEnvelopeGpencil_Mode;
/* SURFACE DEFORM MODIFIER START */
typedef struct bGPDstroke bGPDstroke;
typedef struct bGPDframe bGPDframe;
typedef struct bGPDlayer bGPDlayer;
typedef struct SDefGPBind {
unsigned int *vert_inds;
unsigned int verts_num;
int mode;
float *vert_weights;
float normal_dist;
float influence;
} SDefGPBind;
typedef struct SDefGPVert {
SDefGPBind *binds;
unsigned int binds_num;
unsigned int vertex_idx;
} SDefGPVert;
typedef struct SDefGPStroke {
struct SDefGPStroke *first;
SDefGPVert *verts;
unsigned int stroke_idx;
/* Number of of vertices on the deformed stroke upon the bind process. former bind_verts_num */
int stroke_verts_num;
/*Keep a pointer to the bGPDstroke UNUSED*/
bGPDstroke *blender_stroke;
} SDefGPStroke;
typedef struct SDefGPFrame{
struct SDefGPFrame *first;
/*SDefGPStroke in this SDefGPFrame*/
SDefGPStroke *strokes;
/*Number on the timeline this frame sits on.*/
unsigned int frame_number;
/*Index of inside the modifier*/
unsigned int frame_idx;
/* Number of strokes */
unsigned int strokes_num;
unsigned int _paddypad;
/*Keep a pointer to the bGPDframe UNUSED */
bGPDframe *blender_frame;
} SDefGPFrame;
typedef struct SDefGPLayer{
struct SDefGPLayer *first;
SDefGPFrame *frames;
/*Index of inside the modifier*/
unsigned int layer_idx;
/*It is actually the name but for some reason it's called info :(*/
char layer_info[128]; //unused for now
/* Number of frames */
unsigned int num_of_frames;
/*Keep a pointer to the bGPDlayer UNUSED */
bGPDlayer *blender_layer;
} SDefGPLayer;
/*Bound frames to be displayed in the UI list.
typedef struct SDefGPBoundFrame {
struct SDefGPBoundFrame *first;
/*name for list ui
char name[128];
/*index for list ui
unsigned int index;
/* layers involved in the frame
bGPDlayer *layers[64];
/* Frame number. This is how we match it with its SDefGPFrame.
We could use the UI to move the frame, and change the data in SDefGPFrame with no risk.
int framenum;
}
SDefGPBoundFrame;
*/
typedef struct SurDeformGpencilModifierData {
GpencilModifierData modifier;
struct Depsgraph *depsgraph;
/** Bind target object. */
struct Object *target;
/** Vertex bind data. */
SDefGPLayer *layers;
void *_pad1;
/*frame list ui*/
//unsigned int uilist_frame_active_index;
//unsigned int uilist_totframes;
//SDefGPBoundFrame *uilist_frame_active;
int bake_range_start;
int bake_range_end;
float falloff;
/* Number of layers in the `frames` array of this modifier. */
unsigned int num_of_layers;
/* Number of vertices and polygons on the target mesh upon bind process. */
unsigned int target_verts_num, target_polys_num;
int flags;
int bound_flags;
int bind_modes;
float strength;
char curr_frame_or_all_frames;
char curr_layer_or_all_layers;
char _pad3[6];
float mat[4][4];
char defgrp_name[64];
} SurDeformGpencilModifierData;
/** Surface Deform Data mode (bind_modes)*/
enum {
GP_MOD_SDEF_BIND_CURRENT_FRAME = (1 << 0),
GP_MOD_SDEF_BIND_ALL_FRAMES = (1 << 1),
GP_MOD_SDEF_BIND_CURRENT_LAYER = (1 << 2),
GP_MOD_SDEF_BIND_ALL_LAYERS = (1 << 3),
GP_MOD_SDEF_UNBIND_MODE = (1 << 4),
};
/*Frame-layer bound combination flags (bound_flags)*/
enum {
GP_MOD_SDEF_ALL_LAYERS_AND_FRAMES_BOUND = (1 << 0),
GP_MOD_SDEF_ALL_LAYERS_CURRENT_FRAMES_BOUND = (1 << 1),
GP_MOD_SDEF_CURRENT_LAYER_ALL_FRAMES_BOUND = (1 << 2),
GP_MOD_SDEF_CURRENT_LAYER_CURRENT_FRAME_BOUND = (1 << 3),
/*So that bound_flags is not 0 and the data doesn't get freed if a frame is added*/
GP_MOD_SDEF_SOMETHING_BOUND = (1 << 4),
};
/** Surface Deform modifier flags. (flags) */
enum {
/* This indicates "do bind on next modifier evaluation" as well as "is bound". */
GP_MOD_SDEF_DO_BIND = (1 << 0),
GP_MOD_SDEF_INVERT_VGROUP = (1 << 1),
/* Only store bind data for nonzero vgroup weights at the time of bind. */
GP_MOD_SDEF_SPARSE_BIND = (1 << 2),
GP_MOD_SDEF_WITHHOLD_EVALUATION = (1 << 3)
};
/** Surface Deform vertex bind modes. */
enum {
GP_MOD_SDEF_MODE_LOOPTRI = 0,
GP_MOD_SDEF_MODE_NGON = 1,
GP_MOD_SDEF_MODE_CENTROID = 2,
};
#ifdef __cplusplus
}
#endif

View File

@ -323,6 +323,7 @@ SDNA_DEFAULT_DECL_STRUCT(DashGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(DashGpencilModifierSegment);
SDNA_DEFAULT_DECL_STRUCT(ShrinkwrapGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(EnvelopeGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(SurDeformGpencilModifierData);
#undef SDNA_DEFAULT_DECL_STRUCT
@ -567,6 +568,7 @@ const void *DNA_default_table[SDNA_TYPE_MAX] = {
SDNA_DEFAULT_DECL(DashGpencilModifierSegment),
SDNA_DEFAULT_DECL(ShrinkwrapGpencilModifierData),
SDNA_DEFAULT_DECL(EnvelopeGpencilModifierData),
SDNA_DEFAULT_DECL(SurDeformGpencilModifierData)
};
#undef SDNA_DEFAULT_DECL
#undef SDNA_DEFAULT_DECL_EX

View File

@ -104,6 +104,12 @@ const EnumPropertyItem rna_enum_beztriple_keyframe_type_items[] = {
ICON_KEYTYPE_JITTER_VEC,
"Jitter",
"A filler or baked keyframe for keying on ones, or some other purpose as needed"},
/*
{BEZT_KEYTYPE_SURDEFBOUND,
"SURDEFBOUND",
ICON_KEYTYPE_JITTER_VEC,
"Surface def bound",
"A filler or baked keyframe for keying on ones, or some other purpose as needed"},*/
{0, NULL, 0, NULL, NULL},
};

View File

@ -89,6 +89,11 @@ static const EnumPropertyItem rna_enum_keyframe_type_items[] = {
ICON_KEYTYPE_JITTER_VEC,
"Jitter",
"A filler or baked keyframe for keying on ones, or some other purpose as needed"},
{BEZT_KEYTYPE_SURDEFBOUND,
"SURDEFBOUND",
ICON_KEYTYPE_JITTER_VEC,
"Surface def bound",
"A filler or baked keyframe for keying on ones, or some other purpose as needed"},
{0, NULL, 0, NULL, NULL},
};
@ -119,6 +124,11 @@ static const EnumPropertyItem rna_enum_onion_keyframe_type_items[] = {
ICON_KEYTYPE_JITTER_VEC,
"Jitter",
"A filler or baked keyframe for keying on ones, or some other purpose as needed"},
{BEZT_KEYTYPE_SURDEFBOUND,
"SURDEFBOUND",
ICON_KEYTYPE_JITTER_VEC,
"Surface def bound",
"A filler or baked keyframe for keying on ones, or some other purpose as needed"},
{0, NULL, 0, NULL, NULL},
};

View File

@ -143,6 +143,12 @@ const EnumPropertyItem rna_enum_object_greasepencil_modifier_type_items[] = {
ICON_MOD_THICKNESS,
"Thickness",
"Change stroke thickness"},
{eGpencilModifierType_SurDeform,
"GP_SURFACEDEFORM",
ICON_MOD_MESHDEFORM,
"Surface Deform",
"Opacity of the strokes"},
RNA_ENUM_ITEM_HEADING(N_("Color"), NULL),
{eGpencilModifierType_Color,
"GP_COLOR",
@ -265,6 +271,16 @@ static const EnumPropertyItem modifier_noise_random_mode_items[] = {
{GP_NOISE_RANDOM_KEYFRAME, "KEYFRAME", 0, "Keyframes", "Randomize on keyframes only"},
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem gpsurdef_curr_frame_or_all_frames_items[] = {
{GP_MOD_SDEF_BIND_CURRENT_FRAME, "CURR_FRAME", 0, "Current Frame", "Bind the current frame"},
{GP_MOD_SDEF_BIND_ALL_FRAMES, "ALL_FRAMES", 0, "All Frames", "Bind all the frames in the layer(s)"},
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem gpsurdef_curr_layer_or_all_layers_items[] = {
{GP_MOD_SDEF_BIND_CURRENT_LAYER, "CURR_LAYER", 0, "Current Layer", "Bind the current frame"},
{GP_MOD_SDEF_BIND_ALL_LAYERS, "ALL_LAYERS", 0, "All Layers", "Bind all the frames in the layer(s)"},
{0, NULL, 0, NULL, NULL},
};
#endif
#ifdef RNA_RUNTIME
@ -340,6 +356,8 @@ static StructRNA *rna_GpencilModifier_refine(struct PointerRNA *ptr)
return &RNA_DashGpencilModifierData;
case eGpencilModifierType_Envelope:
return &RNA_EnvelopeGpencilModifier;
case eGpencilModifierType_SurDeform:
return &RNA_SurDeformGpencilModifier;
/* Default */
case eGpencilModifierType_None:
case NUM_GREASEPENCIL_MODIFIER_TYPES:
@ -417,6 +435,7 @@ RNA_GP_MOD_VGROUP_NAME_SET(WeightAngle, vgname);
RNA_GP_MOD_VGROUP_NAME_SET(Lineart, vgname);
RNA_GP_MOD_VGROUP_NAME_SET(Shrinkwrap, vgname);
RNA_GP_MOD_VGROUP_NAME_SET(Envelope, vgname);
RNA_GP_MOD_VGROUP_NAME_SET(SurDeform, defgrp_name);
RNA_GP_MOD_VGROUP_NAME_SET(Build, target_vgname);
# undef RNA_GP_MOD_VGROUP_NAME_SET
@ -452,6 +471,7 @@ RNA_GP_MOD_OBJECT_SET(Mirror, object, OB_EMPTY);
RNA_GP_MOD_OBJECT_SET(WeightProx, object, OB_EMPTY);
RNA_GP_MOD_OBJECT_SET(Shrinkwrap, target, OB_MESH);
RNA_GP_MOD_OBJECT_SET(Shrinkwrap, aux_target, OB_MESH);
RNA_GP_MOD_OBJECT_SET(SurDeform, target, OB_MESH);
RNA_GP_MOD_OBJECT_SET(Build, object, OB_EMPTY);
# undef RNA_GP_MOD_OBJECT_SET
@ -811,7 +831,14 @@ static void rna_GpencilDash_segments_begin(CollectionPropertyIterator *iter, Poi
rna_iterator_array_begin(
iter, dmd->segments, sizeof(DashGpencilModifierSegment), dmd->segments_len, false, NULL);
}
/*
static void rna_GpencilSurDef_frames_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
SurDeformGpencilModifierData *smd = (SurDeformGpencilModifierData *)ptr->data;
rna_iterator_array_begin(
iter, smd->uilist_frame_active, sizeof(SurDeformGpencilModifierData), smd->uilist_totframes, false, NULL);
}
*/
static void rna_GpencilTime_segments_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
TimeGpencilModifierData *gpmd = (TimeGpencilModifierData *)ptr->data;
@ -971,6 +998,10 @@ const EnumPropertyItem *gpencil_build_time_mode_filter(bContext *UNUSED(C),
return item_list;
}
static bool rna_SurDeformGpencilModifier_is_bound_get(PointerRNA *ptr) /* 83771 - RNA properties which are not in the DNA data. */
{
return ((((SurDeformGpencilModifierData *)ptr->data)->flags) & (1 << 0));
}
#else
@ -4625,7 +4656,130 @@ static void rna_def_modifier_gpencilenvelope(BlenderRNA *brna)
RNA_define_lib_overridable(false);
}
static void rna_def_modifier_gpencilsurdeform(BlenderRNA *brna)
{
StructRNA *srna;
StructRNA *srna_framelist;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "SurDeformGpencilModifier", "GpencilModifier");
RNA_def_struct_ui_text(srna, "Surface Deform Modifier", "Envelope stroke effect modifier");
RNA_def_struct_sdna(srna, "SurDeformGpencilModifierData");
RNA_def_struct_ui_icon(srna, ICON_MOD_MESHDEFORM);
prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Target", "Mesh object to deform with");
RNA_def_property_pointer_funcs(
prop, NULL, "rna_SurDeformGpencilModifier_target_set", NULL, "rna_Mesh_object_poll");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
RNA_def_property_update(prop, 0, "rna_GpencilModifier_dependency_update");
prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 2.0f, 16.0f);
RNA_def_property_ui_text(
prop, "Interpolation Falloff", "Controls how much nearby polygons influence deformation");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "bake_range_start", PROP_INT, PROP_NONE);
RNA_def_property_ui_text(
prop, "Range Start", "The first timeline frame to start baking");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "bake_range_end", PROP_INT, PROP_NONE);
RNA_def_property_ui_text(prop, "Range End", "The last timeline frame to bake");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "is_bound", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_SurDeformGpencilModifier_is_bound_get", NULL);
RNA_def_property_ui_text(prop, "Bound", "Whether geometry has been bound to target mesh");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
RNA_def_property_ui_text(
prop, "Vertex Group", "Vertex group name for selecting/weighting the affected areas");
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SurDeformGpencilModifier_defgrp_name_set");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "invert_vertex_group", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", GP_MOD_SDEF_INVERT_VGROUP);
RNA_def_property_ui_text(prop, "Invert", "Invert vertex group influence");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "use_sparse_bind", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", GP_MOD_SDEF_SPARSE_BIND);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(
prop,
"Sparse Bind",
"Only record binding data for vertices matching the vertex group at the time of bind");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, -100, 100);
RNA_def_property_ui_range(prop, -100, 100, 10, 2);
RNA_def_property_ui_text(prop, "Strength", "Strength of modifier deformations");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "curr_frame_or_all_frames", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "curr_frame_or_all_frames");
RNA_def_property_enum_items(prop, gpsurdef_curr_frame_or_all_frames_items);
RNA_def_property_enum_default(prop, GP_MOD_SDEF_BIND_CURRENT_FRAME);
RNA_def_property_ui_text(prop, " ", "Current frame or all frames");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "unbind_mode", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bound_flags", GP_MOD_SDEF_UNBIND_MODE);
RNA_def_property_ui_text(prop, "Unbind", "Unbind");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
/*Frame-layer bound combination flags (bound_flags)*/
prop = RNA_def_property(srna, "all_layers_and_frames_bound", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bound_flags", GP_MOD_SDEF_ALL_LAYERS_AND_FRAMES_BOUND);
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "all_layers_current_frames_bound", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bound_flags", GP_MOD_SDEF_ALL_LAYERS_CURRENT_FRAMES_BOUND);
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "current_layer_all_frames_bound", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bound_flags", GP_MOD_SDEF_CURRENT_LAYER_ALL_FRAMES_BOUND);
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "current_layer_current_frame_bound", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bound_flags", GP_MOD_SDEF_CURRENT_LAYER_CURRENT_FRAME_BOUND);
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
/*UI list frames*/
/*
prop = RNA_def_property(srna, "uilist_frames", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "SDefGPBoundFrame");
RNA_def_property_collection_sdna(prop, NULL, "uilist_frame_active", NULL);
RNA_def_property_collection_funcs(prop,
"rna_GpencilSurDef_frames_begin",
"rna_iterator_array_next",
"rna_iterator_array_end",
"rna_iterator_array_get",
NULL,
NULL,
NULL,
NULL);
RNA_def_property_ui_text(prop, "Frames", "");
prop = RNA_def_property(srna, "frame_active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Active Surface Deform Frame Index", "Active index in the segment list");
RNA_define_lib_overridable(false);
srna_framelist = RNA_def_struct(brna, "SDefGPBoundFrame", NULL);
RNA_def_struct_ui_text(
srna, "Surface Deform GP Modifier Frame", "Bound frames to be displayed in the UI list.");
RNA_def_struct_sdna(srna, "SDefGPBoundFrame");
// RNA_def_struct_path_func(srna, "rna_DashGpencilModifierSegment_path");*/
RNA_define_lib_overridable(false);
}
void RNA_def_greasepencil_modifier(BlenderRNA *brna)
{
StructRNA *srna;
@ -4718,6 +4872,7 @@ void RNA_def_greasepencil_modifier(BlenderRNA *brna)
rna_def_modifier_gpencildash(brna);
rna_def_modifier_gpencilshrinkwrap(brna);
rna_def_modifier_gpencilenvelope(brna);
rna_def_modifier_gpencilsurdeform(brna);
}
#endif