GPencil: New Shrinkwrap modifier

his new modifier is equals to the existing mesh modifier but adapted to grease pencil.

The underlying functions used to calculate the shrink are the same used in meshes.

{F11794101}

Reviewed By: pepeland, HooglyBoogly

Differential Revision: https://developer.blender.org/D13192
This commit is contained in:
Antonio Vazquez 2021-12-13 17:09:22 +01:00
parent 49802af7cd
commit 459af75d1e
23 changed files with 851 additions and 84 deletions

View File

@ -234,8 +234,12 @@ bool BKE_gpencil_stroke_sample(struct bGPdata *gpd,
* \param gps: Stroke to smooth
* \param i: Point index
* \param inf: Amount of smoothing to apply
* \param smooth_caps: Apply smooth to stroke extremes
*/
bool BKE_gpencil_stroke_smooth_point(struct bGPDstroke *gps, int i, float inf);
bool BKE_gpencil_stroke_smooth_point(struct bGPDstroke *gps,
int i,
float inf,
const bool smooth_caps);
/**
* Apply smooth strength to stroke point.
* \param gps: Stroke to smooth

View File

@ -407,16 +407,8 @@ void BKE_gpencil_set_lineart_modifier_limits(struct GpencilModifierData *md,
bool BKE_gpencil_is_first_lineart_in_stack(const struct Object *ob,
const struct GpencilModifierData *md);
/**
* Init grease pencil lattice deform data.
* \param ob: Grease pencil object.
*/
void BKE_gpencil_lattice_init(struct Object *ob);
/**
* Clear grease pencil lattice deform data.
* \param ob: Grease pencil object.
*/
void BKE_gpencil_lattice_clear(struct Object *ob);
void BKE_gpencil_cache_data_init(struct Depsgraph *depsgraph, struct Object *ob);
void BKE_gpencil_cache_data_clear(struct Object *ob);
/**
* Calculate grease-pencil modifiers.

View File

@ -48,6 +48,7 @@ struct Mesh;
struct ModifierEvalContext;
struct Object;
struct ShrinkwrapModifierData;
struct ShrinkwrapGpencilModifierData;
struct SpaceTransform;
/* Information about boundary edges in the mesh. */
@ -123,6 +124,13 @@ void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd,
const int defgrp_index,
float (*vertexCos)[3],
int numVerts);
/* Implementation of the Shrinkwrap Grease Pencil modifier. */
void shrinkwrapGpencilModifier_deform(struct ShrinkwrapGpencilModifierData *mmd,
struct Object *ob,
struct MDeformVert *dvert,
const int defgrp_index,
float (*vertexCos)[3],
int numVerts);
/**
* Used in `editmesh_mask_extract.c` to shrink-wrap the extracted mesh to the sculpt.

View File

@ -912,7 +912,10 @@ bool BKE_gpencil_stroke_shrink(bGPDstroke *gps, const float dist, const short mo
return true;
}
bool BKE_gpencil_stroke_smooth_point(bGPDstroke *gps, int i, float inf)
/**
* Apply smooth position to stroke point.
*/
bool BKE_gpencil_stroke_smooth_point(bGPDstroke *gps, int i, float inf, const bool smooth_caps)
{
bGPDspoint *pt = &gps->points[i];
float sco[3] = {0.0f};
@ -926,7 +929,7 @@ bool BKE_gpencil_stroke_smooth_point(bGPDstroke *gps, int i, float inf)
/* Only affect endpoints by a fraction of the normal strength,
* to prevent the stroke from shrinking too much
*/
if (!is_cyclic && ELEM(i, 0, gps->totpoints - 1)) {
if ((!smooth_caps) && (!is_cyclic && ELEM(i, 0, gps->totpoints - 1))) {
inf *= 0.1f;
}
@ -3333,7 +3336,7 @@ void BKE_gpencil_stroke_join(bGPDstroke *gps_a,
for (i = start; i < end; i++) {
pt = &gps_a->points[i];
pt->pressure += (avg_pressure - pt->pressure) * ratio;
BKE_gpencil_stroke_smooth_point(gps_a, i, ratio * 0.6f);
BKE_gpencil_stroke_smooth_point(gps_a, i, ratio * 0.6f, false);
ratio += step;
/* In the center, reverse the ratio. */

View File

@ -36,6 +36,7 @@
#include "DNA_armature_types.h"
#include "DNA_gpencil_modifier_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
@ -50,7 +51,9 @@
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
#include "BKE_material.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_shrinkwrap.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
@ -76,36 +79,84 @@ static GpencilVirtualModifierData virtualModifierCommonData;
* each loop over all the geometry being evaluated.
*/
void BKE_gpencil_lattice_init(Object *ob)
/**
* Init grease pencil cache deform data.
* \param ob: Grease pencil object
*/
void BKE_gpencil_cache_data_init(Depsgraph *depsgraph, Object *ob)
{
LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) {
if (md->type == eGpencilModifierType_Lattice) {
LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md;
Object *latob = NULL;
switch (md->type) {
case eGpencilModifierType_Lattice: {
LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md;
Object *latob = NULL;
latob = mmd->object;
if ((!latob) || (latob->type != OB_LATTICE)) {
return;
latob = mmd->object;
if ((!latob) || (latob->type != OB_LATTICE)) {
return;
}
if (mmd->cache_data) {
BKE_lattice_deform_data_destroy(mmd->cache_data);
}
/* init deform data */
mmd->cache_data = BKE_lattice_deform_data_create(latob, ob);
break;
}
if (mmd->cache_data) {
BKE_lattice_deform_data_destroy(mmd->cache_data);
case eGpencilModifierType_Shrinkwrap: {
ShrinkwrapGpencilModifierData *mmd = (ShrinkwrapGpencilModifierData *)md;
ob = mmd->target;
if (!ob) {
return;
}
if (mmd->cache_data) {
BKE_shrinkwrap_free_tree(mmd->cache_data);
MEM_SAFE_FREE(mmd->cache_data);
}
Object *ob_target = DEG_get_evaluated_object(depsgraph, ob);
Mesh *target = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob_target, false);
mmd->cache_data = MEM_callocN(sizeof(ShrinkwrapTreeData), __func__);
if (BKE_shrinkwrap_init_tree(
mmd->cache_data, target, mmd->shrink_type, mmd->shrink_mode, false)) {
}
else {
MEM_SAFE_FREE(mmd->cache_data);
}
break;
}
/* init deform data */
mmd->cache_data = BKE_lattice_deform_data_create(latob, ob);
default:
break;
}
}
}
void BKE_gpencil_lattice_clear(Object *ob)
/**
* Clear grease pencil cache deform data.
* \param ob: Grease pencil object
*/
void BKE_gpencil_cache_data_clear(Object *ob)
{
LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) {
if (md->type == eGpencilModifierType_Lattice) {
LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md;
if ((mmd) && (mmd->cache_data)) {
BKE_lattice_deform_data_destroy(mmd->cache_data);
mmd->cache_data = NULL;
switch (md->type) {
case eGpencilModifierType_Lattice: {
LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md;
if ((mmd) && (mmd->cache_data)) {
BKE_lattice_deform_data_destroy(mmd->cache_data);
mmd->cache_data = NULL;
}
break;
}
case eGpencilModifierType_Shrinkwrap: {
ShrinkwrapGpencilModifierData *mmd = (ShrinkwrapGpencilModifierData *)md;
if ((mmd) && (mmd->cache_data)) {
BKE_shrinkwrap_free_tree(mmd->cache_data);
MEM_SAFE_FREE(mmd->cache_data);
}
break;
}
default:
break;
}
}
}
@ -699,7 +750,7 @@ void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
}
/* Init general modifiers data. */
BKE_gpencil_lattice_init(ob);
BKE_gpencil_cache_data_init(depsgraph, ob);
const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
bool is_first_lineart = true;
@ -742,8 +793,8 @@ void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
}
}
/* Clear any lattice data. */
BKE_gpencil_lattice_clear(ob);
/* Clear any cache data. */
BKE_gpencil_cache_data_clear(ob);
MOD_lineart_clear_cache(&gpd->runtime.lineart_cache);
}
@ -901,6 +952,10 @@ void BKE_gpencil_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb)
gpmd->segments[i].dmd = gpmd;
}
}
if (md->type == eGpencilModifierType_Shrinkwrap) {
ShrinkwrapGpencilModifierData *gpmd = (ShrinkwrapGpencilModifierData *)md;
gpmd->cache_data = NULL;
}
}
}

View File

@ -28,6 +28,7 @@
#include <string.h>
#include <time.h>
#include "DNA_gpencil_modifier_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@ -1483,6 +1484,55 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd,
}
}
void shrinkwrapGpencilModifier_deform(ShrinkwrapGpencilModifierData *mmd,
Object *ob,
MDeformVert *dvert,
const int defgrp_index,
float (*vertexCos)[3],
int numVerts)
{
ShrinkwrapCalcData calc = NULL_ShrinkwrapCalcData;
/* Convert gpencil struct to use the same struct and function used with meshes. */
ShrinkwrapModifierData smd;
smd.target = mmd->target;
smd.auxTarget = mmd->aux_target;
smd.keepDist = mmd->keep_dist;
smd.shrinkType = mmd->shrink_type;
smd.shrinkOpts = mmd->shrink_opts;
smd.shrinkMode = mmd->shrink_mode;
smd.projLimit = mmd->proj_limit;
smd.projAxis = mmd->proj_axis;
/* Configure Shrinkwrap calc data. */
calc.smd = &smd;
calc.ob = ob;
calc.numVerts = numVerts;
calc.vertexCos = vertexCos;
calc.dvert = dvert;
calc.vgroup = defgrp_index;
calc.invert_vgroup = (mmd->flag & GP_SHRINKWRAP_INVERT_VGROUP) != 0;
BLI_SPACE_TRANSFORM_SETUP(&calc.local2target, ob, mmd->target);
calc.keepDist = mmd->keep_dist;
calc.tree = mmd->cache_data;
switch (mmd->shrink_type) {
case MOD_SHRINKWRAP_NEAREST_SURFACE:
case MOD_SHRINKWRAP_TARGET_PROJECT:
TIMEIT_BENCH(shrinkwrap_calc_nearest_surface_point(&calc), gpdeform_surface);
break;
case MOD_SHRINKWRAP_PROJECT:
TIMEIT_BENCH(shrinkwrap_calc_normal_projection(&calc), gpdeform_project);
break;
case MOD_SHRINKWRAP_NEAREST_VERTEX:
TIMEIT_BENCH(shrinkwrap_calc_nearest_vertex(&calc), gpdeform_vertex);
break;
}
}
void BKE_shrinkwrap_mesh_nearest_surface_deform(struct bContext *C,
Object *ob_source,
Object *ob_target)

View File

@ -3949,7 +3949,7 @@ static void gpencil_smooth_stroke(bContext *C, wmOperator *op)
/* perform smoothing */
if (smooth_position) {
BKE_gpencil_stroke_smooth_point(gps, i, factor);
BKE_gpencil_stroke_smooth_point(gps, i, factor, false);
}
if (smooth_strength) {
BKE_gpencil_stroke_smooth_strength(gps, i, factor);

View File

@ -1570,7 +1570,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
float smoothfac = 1.0f;
for (int r = 0; r < 1; r++) {
for (int i = 0; i < gps->totpoints; i++) {
BKE_gpencil_stroke_smooth_point(gps, i, smoothfac - reduce);
BKE_gpencil_stroke_smooth_point(gps, i, smoothfac - reduce, false);
}
reduce += 0.25f; /* reduce the factor */
}

View File

@ -336,7 +336,7 @@ static void gpencil_interpolate_smooth_stroke(bGPDstroke *gps,
float reduce = 0.0f;
for (int r = 0; r < smooth_steps; r++) {
for (int i = 0; i < gps->totpoints - 1; i++) {
BKE_gpencil_stroke_smooth_point(gps, i, smooth_factor - reduce);
BKE_gpencil_stroke_smooth_point(gps, i, smooth_factor - reduce, false);
BKE_gpencil_stroke_smooth_strength(gps, i, smooth_factor);
}
reduce += 0.25f; /* reduce the factor */

View File

@ -1205,7 +1205,7 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p)
for (int r = 0; r < brush->gpencil_settings->draw_smoothlvl; r++) {
for (i = 0; i < gps->totpoints - 1; i++) {
BKE_gpencil_stroke_smooth_point(
gps, i, brush->gpencil_settings->draw_smoothfac - reduce);
gps, i, brush->gpencil_settings->draw_smoothfac - reduce, false);
BKE_gpencil_stroke_smooth_strength(gps, i, brush->gpencil_settings->draw_smoothfac);
}
reduce += 0.25f; /* reduce the factor */
@ -1217,7 +1217,7 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p)
float ifac = (float)brush->gpencil_settings->input_samples / 10.0f;
float sfac = interpf(1.0f, 0.2f, ifac);
for (i = 0; i < gps->totpoints - 1; i++) {
BKE_gpencil_stroke_smooth_point(gps, i, sfac);
BKE_gpencil_stroke_smooth_point(gps, i, sfac, false);
BKE_gpencil_stroke_smooth_strength(gps, i, sfac);
}
}

View File

@ -337,7 +337,7 @@ static bool gpencil_brush_smooth_apply(tGP_BrushEditData *gso,
/* perform smoothing */
if (gso->brush->gpencil_settings->sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_POSITION) {
BKE_gpencil_stroke_smooth_point(gps, pt_index, inf);
BKE_gpencil_stroke_smooth_point(gps, pt_index, inf, false);
}
if (gso->brush->gpencil_settings->sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_STRENGTH) {
BKE_gpencil_stroke_smooth_strength(gps, pt_index, inf);

View File

@ -2368,6 +2368,9 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
case eGpencilModifierType_WeightAngle:
data.icon = ICON_MOD_VERTEX_WEIGHT;
break;
case eGpencilModifierType_Shrinkwrap:
data.icon = ICON_MOD_SHRINKWRAP;
break;
/* Default */
default:

View File

@ -62,6 +62,7 @@ set(SRC
intern/MOD_gpencilnoise.c
intern/MOD_gpenciloffset.c
intern/MOD_gpencilopacity.c
intern/MOD_gpencilshrinkwrap.c
intern/MOD_gpencilsimplify.c
intern/MOD_gpencilsmooth.c
intern/MOD_gpencilsubdiv.c

View File

@ -48,6 +48,7 @@ extern GpencilModifierTypeInfo modifierType_Gpencil_WeightProximity;
extern GpencilModifierTypeInfo modifierType_Gpencil_WeightAngle;
extern GpencilModifierTypeInfo modifierType_Gpencil_Lineart;
extern GpencilModifierTypeInfo modifierType_Gpencil_Dash;
extern GpencilModifierTypeInfo modifierType_Gpencil_Shrinkwrap;
/* MOD_gpencil_util.c */
void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[]);

View File

@ -67,6 +67,7 @@ void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[])
INIT_GP_TYPE(WeightProximity);
INIT_GP_TYPE(Lineart);
INIT_GP_TYPE(Dash);
INIT_GP_TYPE(Shrinkwrap);
#undef INIT_GP_TYPE
}

View File

@ -0,0 +1,350 @@
/*
* 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
*/
/** \file
* \ingroup modifiers
*/
#include <stdio.h>
#include <string.h> /* For #MEMCPY_STRUCT_AFTER. */
#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_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "BKE_context.h"
#include "BKE_deform.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_scene.h"
#include "BKE_screen.h"
#include "BKE_shrinkwrap.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"
#include "DEG_depsgraph_build.h"
#include "DEG_depsgraph_query.h"
static void initData(GpencilModifierData *md)
{
ShrinkwrapGpencilModifierData *gpmd = (ShrinkwrapGpencilModifierData *)md;
BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(gpmd, modifier));
MEMCPY_STRUCT_AFTER(gpmd, DNA_struct_default_get(ShrinkwrapGpencilModifierData), modifier);
}
static void copyData(const GpencilModifierData *md, GpencilModifierData *target)
{
BKE_gpencil_modifier_copydata_generic(md, target);
}
static void deformStroke(GpencilModifierData *md,
Depsgraph *UNUSED(depsgraph),
Object *ob,
bGPDlayer *gpl,
bGPDframe *UNUSED(gpf),
bGPDstroke *gps)
{
bGPdata *gpd = ob->data;
ShrinkwrapGpencilModifierData *mmd = (ShrinkwrapGpencilModifierData *)md;
const int def_nr = BKE_object_defgroup_name_index(ob, mmd->vgname);
if (!is_stroke_affected_by_modifier(ob,
mmd->layername,
mmd->material,
mmd->pass_index,
mmd->layer_pass,
1,
gpl,
gps,
mmd->flag & GP_SHRINKWRAP_INVERT_LAYER,
mmd->flag & GP_SHRINKWRAP_INVERT_PASS,
mmd->flag & GP_SHRINKWRAP_INVERT_LAYERPASS,
mmd->flag & GP_SHRINKWRAP_INVERT_MATERIAL)) {
return;
}
if ((mmd->cache_data == NULL) || (mmd->target == ob) || (mmd->aux_target == ob)) {
return;
}
bGPDspoint *pt = gps->points;
float(*vert_coords)[3] = MEM_mallocN(sizeof(float[3]) * gps->totpoints, __func__);
int i;
/* Prepare array of points. */
for (i = 0; i < gps->totpoints; i++, pt++) {
copy_v3_v3(vert_coords[i], &pt->x);
}
shrinkwrapGpencilModifier_deform(mmd, ob, gps->dvert, def_nr, vert_coords, gps->totpoints);
/* Apply deformed coordinates. */
pt = gps->points;
for (i = 0; i < gps->totpoints; i++, pt++) {
copy_v3_v3(&pt->x, vert_coords[i]);
/* Smooth stroke. */
if (mmd->smooth_factor > 0.0f) {
for (int r = 0; r < mmd->smooth_step; r++) {
BKE_gpencil_stroke_smooth_point(gps, i, mmd->smooth_factor, true);
}
}
}
MEM_freeN(vert_coords);
/* Calc geometry data. */
BKE_gpencil_stroke_geometry_update(gpd, gps);
}
static void bakeModifier(Main *UNUSED(bmain),
Depsgraph *depsgraph,
GpencilModifierData *md,
Object *ob)
{
ShrinkwrapGpencilModifierData *mmd = (ShrinkwrapGpencilModifierData *)md;
Scene *scene = DEG_get_evaluated_scene(depsgraph);
bGPdata *gpd = ob->data;
int oldframe = (int)DEG_get_ctime(depsgraph);
if ((mmd->target == ob) || (mmd->aux_target == ob)) {
return;
}
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
/* Apply shrinkwrap effects on this frame. */
CFRA = gpf->framenum;
BKE_scene_graph_update_for_newframe(depsgraph);
/* Recalculate shrinkwrap data. */
if (mmd->cache_data) {
BKE_shrinkwrap_free_tree(mmd->cache_data);
MEM_SAFE_FREE(mmd->cache_data);
}
Object *ob_target = DEG_get_evaluated_object(depsgraph, mmd->target);
Mesh *target = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob_target, false);
mmd->cache_data = MEM_callocN(sizeof(ShrinkwrapTreeData), __func__);
if (BKE_shrinkwrap_init_tree(
mmd->cache_data, target, mmd->shrink_type, mmd->shrink_mode, false)) {
/* Compute shrinkwrap effects on this frame. */
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
deformStroke(md, depsgraph, ob, gpl, gpf, gps);
}
}
/* Free data. */
if (mmd->cache_data) {
BKE_shrinkwrap_free_tree(mmd->cache_data);
MEM_SAFE_FREE(mmd->cache_data);
}
}
}
/* Return frame state and DB to original state. */
CFRA = oldframe;
BKE_scene_graph_update_for_newframe(depsgraph);
}
static void freeData(GpencilModifierData *md)
{
ShrinkwrapGpencilModifierData *mmd = (ShrinkwrapGpencilModifierData *)md;
if (mmd->cache_data) {
BKE_shrinkwrap_free_tree(mmd->cache_data);
MEM_SAFE_FREE(mmd->cache_data);
}
}
static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams))
{
ShrinkwrapGpencilModifierData *mmd = (ShrinkwrapGpencilModifierData *)md;
/* The object type check is only needed here in case we have a placeholder
* object assigned (because the library containing the mesh is missing).
*
* In other cases it should be impossible to have a type mismatch.
*/
if (!mmd->target || mmd->target->type != OB_MESH) {
return true;
}
if (mmd->aux_target && mmd->aux_target->type != OB_MESH) {
return true;
}
return false;
}
static void updateDepsgraph(GpencilModifierData *md,
const ModifierUpdateDepsgraphContext *ctx,
const int UNUSED(mode))
{
ShrinkwrapGpencilModifierData *mmd = (ShrinkwrapGpencilModifierData *)md;
CustomData_MeshMasks mask = {0};
if (BKE_shrinkwrap_needs_normals(mmd->shrink_type, mmd->shrink_mode)) {
mask.vmask |= CD_MASK_NORMAL;
mask.lmask |= CD_MASK_NORMAL | CD_MASK_CUSTOMLOOPNORMAL;
}
if (mmd->target != NULL) {
DEG_add_object_relation(ctx->node, mmd->target, DEG_OB_COMP_TRANSFORM, "Shrinkwrap Modifier");
DEG_add_object_relation(ctx->node, mmd->target, DEG_OB_COMP_GEOMETRY, "Shrinkwrap Modifier");
DEG_add_customdata_mask(ctx->node, mmd->target, &mask);
if (mmd->shrink_type == MOD_SHRINKWRAP_TARGET_PROJECT) {
DEG_add_special_eval_flag(ctx->node, &mmd->target->id, DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY);
}
}
if (mmd->aux_target != NULL) {
DEG_add_object_relation(
ctx->node, mmd->aux_target, DEG_OB_COMP_TRANSFORM, "Shrinkwrap Modifier");
DEG_add_object_relation(
ctx->node, mmd->aux_target, DEG_OB_COMP_GEOMETRY, "Shrinkwrap Modifier");
DEG_add_customdata_mask(ctx->node, mmd->aux_target, &mask);
if (mmd->shrink_type == MOD_SHRINKWRAP_TARGET_PROJECT) {
DEG_add_special_eval_flag(
ctx->node, &mmd->aux_target->id, DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY);
}
}
DEG_add_modifier_to_transform_relation(ctx->node, "Shrinkwrap Modifier");
}
static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
{
ShrinkwrapGpencilModifierData *mmd = (ShrinkwrapGpencilModifierData *)md;
walk(userData, ob, (ID **)&mmd->target, IDWALK_CB_NOP);
walk(userData, ob, (ID **)&mmd->aux_target, IDWALK_CB_NOP);
walk(userData, ob, (ID **)&mmd->material, IDWALK_CB_USER);
}
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
{
uiLayout *row, *col;
uiLayout *layout = panel->layout;
int toggles_flag = UI_ITEM_R_TOGGLE | UI_ITEM_R_FORCE_BLANK_DECORATE;
PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL);
uiLayoutSetPropSep(layout, true);
int wrap_method = RNA_enum_get(ptr, "wrap_method");
uiItemR(layout, ptr, "wrap_method", 0, NULL, ICON_NONE);
if (ELEM(wrap_method,
MOD_SHRINKWRAP_PROJECT,
MOD_SHRINKWRAP_NEAREST_SURFACE,
MOD_SHRINKWRAP_TARGET_PROJECT)) {
uiItemR(layout, ptr, "wrap_mode", 0, NULL, ICON_NONE);
}
if (wrap_method == MOD_SHRINKWRAP_PROJECT) {
uiItemR(layout, ptr, "project_limit", 0, IFACE_("Limit"), ICON_NONE);
uiItemR(layout, ptr, "subsurf_levels", 0, NULL, ICON_NONE);
col = uiLayoutColumn(layout, false);
row = uiLayoutRowWithHeading(col, true, IFACE_("Axis"));
uiItemR(row, ptr, "use_project_x", toggles_flag, NULL, ICON_NONE);
uiItemR(row, ptr, "use_project_y", toggles_flag, NULL, ICON_NONE);
uiItemR(row, ptr, "use_project_z", toggles_flag, NULL, ICON_NONE);
uiItemR(col, ptr, "use_negative_direction", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "use_positive_direction", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "cull_face", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
col = uiLayoutColumn(layout, false);
uiLayoutSetActive(col,
RNA_boolean_get(ptr, "use_negative_direction") &&
RNA_enum_get(ptr, "cull_face") != 0);
uiItemR(col, ptr, "use_invert_cull", 0, NULL, ICON_NONE);
}
uiItemR(layout, ptr, "target", 0, NULL, ICON_NONE);
if (wrap_method == MOD_SHRINKWRAP_PROJECT) {
uiItemR(layout, ptr, "auxiliary_target", 0, NULL, ICON_NONE);
}
uiItemR(layout, ptr, "offset", 0, NULL, ICON_NONE);
uiLayoutSetPropSep(layout, true);
uiItemR(layout, ptr, "smooth_factor", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "smooth_step", 0, IFACE_("Repeat"), 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, true);
}
static void panelRegister(ARegionType *region_type)
{
PanelType *panel_type = gpencil_modifier_panel_register(
region_type, eGpencilModifierType_Shrinkwrap, panel_draw);
gpencil_modifier_subpanel_register(
region_type, "mask", "Influence", NULL, mask_panel_draw, panel_type);
}
GpencilModifierTypeInfo modifierType_Gpencil_Shrinkwrap = {
/* name */ "Shrinkwrap",
/* structName */ "ShrinkwrapGpencilModifierData",
/* structSize */ sizeof(ShrinkwrapGpencilModifierData),
/* type */ eGpencilModifierTypeType_Gpencil,
/* flags */ eGpencilModifierTypeFlag_SupportsEditmode,
/* copyData */ copyData,
/* deformStroke */ deformStroke,
/* generateStrokes */ NULL,
/* bakeModifier */ bakeModifier,
/* remapTime */ NULL,
/* initData */ initData,
/* freeData */ freeData,
/* isDisabled */ isDisabled,
/* updateDepsgraph */ updateDepsgraph,
/* dependsOnTime */ NULL,
/* foreachIDLink */ foreachIDLink,
/* foreachTexLink */ NULL,
/* panelRegister */ panelRegister,
};

View File

@ -132,7 +132,7 @@ static void deformStroke(GpencilModifierData *md,
const float val = mmd->factor * weight;
/* perform smoothing */
if (mmd->flag & GP_SMOOTH_MOD_LOCATION) {
BKE_gpencil_stroke_smooth_point(gps, i, val);
BKE_gpencil_stroke_smooth_point(gps, i, val, false);
}
if (mmd->flag & GP_SMOOTH_MOD_STRENGTH) {
BKE_gpencil_stroke_smooth_strength(gps, i, val);

View File

@ -353,5 +353,26 @@
.mat_nr = -1, \
}
#define _DNA_DEFAULT_ShrinkwrapGpencilModifierData \
{ \
.target = NULL, \
.aux_target = NULL, \
.keep_dist = 0.05f, \
.shrink_type = MOD_SHRINKWRAP_NEAREST_SURFACE, \
.shrink_opts = MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR, \
.shrink_mode = 0, \
.proj_limit = 0.0f, \
.proj_axis = 0, \
.subsurf_levels = 0, \
.material = NULL, \
.layername = "", \
.vgname = "", \
.pass_index = 0, \
.flag = 0, \
.layer_pass = 0, \
.smooth_factor = 0.05f, \
.smooth_step = 1, \
}
/* clang-format off */

View File

@ -28,6 +28,7 @@ extern "C" {
#endif
struct LatticeDeformData;
struct ShrinkwrapTreeData;
/* WARNING ALERT! TYPEDEF VALUES ARE WRITTEN IN FILES! SO DO NOT CHANGE!
* (ONLY ADD NEW ITEMS AT THE END)
@ -58,6 +59,7 @@ typedef enum GpencilModifierType {
eGpencilModifierType_WeightProximity = 21,
eGpencilModifierType_Dash = 22,
eGpencilModifierType_WeightAngle = 23,
eGpencilModifierType_Shrinkwrap = 24,
/* Keep last. */
NUM_GREASEPENCIL_MODIFIER_TYPES,
} GpencilModifierType;
@ -728,7 +730,7 @@ typedef struct SmoothGpencilModifierData {
int pass_index;
/** Several flags. */
int flag;
/** Factor of noise. */
/** Factor of smooth. */
float factor;
/** How many times apply smooth. */
int step;
@ -1073,6 +1075,60 @@ typedef struct LineartGpencilModifierData {
} LineartGpencilModifierData;
typedef struct ShrinkwrapGpencilModifierData {
GpencilModifierData modifier;
/** Shrink target. */
struct Object *target;
/** Additional shrink target. */
struct Object *aux_target;
/** Material for filtering. */
struct Material *material;
/** Layer name. */
char layername[64];
/** Optional vertexgroup filter name, MAX_VGROUP_NAME. */
char vgname[64];
/** Custom index for passes. */
int pass_index;
/** Flags. */
int flag;
/** Custom index for passes. */
int layer_pass;
/** Distance offset to keep from mesh/projection point. */
float keep_dist;
/** Shrink type projection. */
short shrink_type;
/** Shrink options. */
char shrink_opts;
/** Shrink to surface mode. */
char shrink_mode;
/** Limit the projection ray cast. */
float proj_limit;
/** Axis to project over. */
char proj_axis;
/** If using projection over vertex normal this controls the level of subsurface that must be
* done before getting the vertex coordinates and normal
*/
char subsurf_levels;
char _pad[6];
/** Factor of smooth. */
float smooth_factor;
/** How many times apply smooth. */
int smooth_step;
/** Runtime only. */
struct ShrinkwrapTreeData *cache_data;
} ShrinkwrapGpencilModifierData;
typedef enum eShrinkwrapGpencil_Flag {
GP_SHRINKWRAP_INVERT_LAYER = (1 << 0),
GP_SHRINKWRAP_INVERT_PASS = (1 << 1),
GP_SHRINKWRAP_INVERT_LAYERPASS = (1 << 3),
GP_SHRINKWRAP_INVERT_MATERIAL = (1 << 4),
/* Keep next bit as is to be equals to mesh modifier flag to reuse functions. */
GP_SHRINKWRAP_INVERT_VGROUP = (1 << 6),
} eShrinkwrapGpencil_Flag;
#ifdef __cplusplus
}
#endif

View File

@ -324,6 +324,7 @@ SDNA_DEFAULT_DECL_STRUCT(LineartGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(LengthGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(DashGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(DashGpencilModifierSegment);
SDNA_DEFAULT_DECL_STRUCT(ShrinkwrapGpencilModifierData);
#undef SDNA_DEFAULT_DECL_STRUCT
@ -555,6 +556,7 @@ const void *DNA_default_table[SDNA_TYPE_MAX] = {
SDNA_DEFAULT_DECL(LengthGpencilModifierData),
SDNA_DEFAULT_DECL(DashGpencilModifierData),
SDNA_DEFAULT_DECL(DashGpencilModifierSegment),
SDNA_DEFAULT_DECL(ShrinkwrapGpencilModifierData)
};
#undef SDNA_DEFAULT_DECL
#undef SDNA_DEFAULT_DECL_EX

View File

@ -61,6 +61,8 @@ DEF_ENUM(rna_enum_object_shaderfx_type_items)
DEF_ENUM(rna_enum_modifier_triangulate_quad_method_items)
DEF_ENUM(rna_enum_modifier_triangulate_ngon_method_items)
DEF_ENUM(rna_enum_modifier_shrinkwrap_mode_items)
DEF_ENUM(rna_enum_shrinkwrap_type_items)
DEF_ENUM(rna_enum_shrinkwrap_face_cull_items)
DEF_ENUM(rna_enum_image_type_items)
DEF_ENUM(rna_enum_image_color_mode_items)

View File

@ -28,6 +28,7 @@
#include "DNA_gpencil_modifier_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_force_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@ -144,6 +145,11 @@ const EnumPropertyItem rna_enum_object_greasepencil_modifier_type_items[] = {
ICON_MOD_OFFSET,
"Offset",
"Change stroke location, rotation or scale"},
{eGpencilModifierType_Shrinkwrap,
"SHRINKWRAP",
ICON_MOD_SHRINKWRAP,
"Shrinkwrap",
"Project the shape onto another object"},
{eGpencilModifierType_Smooth, "GP_SMOOTH", ICON_MOD_SMOOTH, "Smooth", "Smooth stroke"},
{eGpencilModifierType_Thick,
"GP_THICK",
@ -269,6 +275,8 @@ static StructRNA *rna_GpencilModifier_refine(struct PointerRNA *ptr)
return &RNA_LengthGpencilModifier;
case eGpencilModifierType_Mirror:
return &RNA_MirrorGpencilModifier;
case eGpencilModifierType_Shrinkwrap:
return &RNA_ShrinkwrapGpencilModifier;
case eGpencilModifierType_Smooth:
return &RNA_SmoothGpencilModifier;
case eGpencilModifierType_Hook:
@ -360,6 +368,7 @@ RNA_GP_MOD_VGROUP_NAME_SET(WeightProx, vgname);
RNA_GP_MOD_VGROUP_NAME_SET(WeightAngle, target_vgname);
RNA_GP_MOD_VGROUP_NAME_SET(WeightAngle, vgname);
RNA_GP_MOD_VGROUP_NAME_SET(Lineart, vgname);
RNA_GP_MOD_VGROUP_NAME_SET(Shrinkwrap, vgname);
# undef RNA_GP_MOD_VGROUP_NAME_SET
@ -392,6 +401,8 @@ RNA_GP_MOD_OBJECT_SET(Armature, object, OB_ARMATURE);
RNA_GP_MOD_OBJECT_SET(Lattice, object, OB_LATTICE);
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);
# undef RNA_GP_MOD_OBJECT_SET
@ -685,6 +696,16 @@ static void rna_TextureGpencilModifier_material_set(PointerRNA *ptr,
rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
}
static void rna_ShrinkwrapGpencilModifier_material_set(PointerRNA *ptr,
PointerRNA value,
struct ReportList *reports)
{
ShrinkwrapGpencilModifierData *tmd = (ShrinkwrapGpencilModifierData *)ptr->data;
Material **ma_target = &tmd->material;
rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
}
static void rna_Lineart_start_level_set(PointerRNA *ptr, int value)
{
LineartGpencilModifierData *lmd = (LineartGpencilModifierData *)ptr->data;
@ -756,6 +777,18 @@ static void rna_DashGpencilModifierSegment_name_set(PointerRNA *ptr, const char
BKE_animdata_fix_paths_rename_all(NULL, prefix, oldname, ds->name);
}
static int rna_ShrinkwrapGpencilModifier_face_cull_get(PointerRNA *ptr)
{
ShrinkwrapGpencilModifierData *swm = (ShrinkwrapGpencilModifierData *)ptr->data;
return swm->shrink_opts & MOD_SHRINKWRAP_CULL_TARGET_MASK;
}
static void rna_ShrinkwrapGpencilModifier_face_cull_set(struct PointerRNA *ptr, int value)
{
ShrinkwrapGpencilModifierData *swm = (ShrinkwrapGpencilModifierData *)ptr->data;
swm->shrink_opts = (swm->shrink_opts & ~MOD_SHRINKWRAP_CULL_TARGET_MASK) | value;
}
#else
static void rna_def_modifier_gpencilnoise(BlenderRNA *brna)
@ -3683,6 +3716,194 @@ static void rna_def_modifier_gpencildash(BlenderRNA *brna)
RNA_define_lib_overridable(false);
}
static void rna_def_modifier_gpencilshrinkwrap(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "ShrinkwrapGpencilModifier", "GpencilModifier");
RNA_def_struct_ui_text(srna,
"Shrinkwrap Modifier",
"Shrink wrapping modifier to shrink wrap and object to a target");
RNA_def_struct_sdna(srna, "ShrinkwrapGpencilModifierData");
RNA_def_struct_ui_icon(srna, ICON_MOD_SHRINKWRAP);
RNA_define_lib_overridable(true);
prop = RNA_def_property(srna, "wrap_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "shrink_type");
RNA_def_property_enum_items(prop, rna_enum_shrinkwrap_type_items);
RNA_def_property_ui_text(prop, "Wrap Method", "");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_dependency_update");
prop = RNA_def_property(srna, "wrap_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "shrink_mode");
RNA_def_property_enum_items(prop, rna_enum_modifier_shrinkwrap_mode_items);
RNA_def_property_ui_text(
prop, "Snap Mode", "Select how vertices are constrained to the target surface");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_dependency_update");
prop = RNA_def_property(srna, "cull_face", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "shrink_opts");
RNA_def_property_enum_items(prop, rna_enum_shrinkwrap_face_cull_items);
RNA_def_property_enum_funcs(prop,
"rna_ShrinkwrapGpencilModifier_face_cull_get",
"rna_ShrinkwrapGpencilModifier_face_cull_set",
NULL);
RNA_def_property_ui_text(
prop,
"Face Cull",
"Stop vertices from projecting to a face on the target when facing towards/away");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Target", "Mesh target to shrink to");
RNA_def_property_pointer_funcs(
prop, NULL, "rna_ShrinkwrapGpencilModifier_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, "auxiliary_target", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "aux_target");
RNA_def_property_ui_text(prop, "Auxiliary Target", "Additional mesh target to shrink to");
RNA_def_property_pointer_funcs(
prop, NULL, "rna_ShrinkwrapGpencilModifier_aux_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, "offset", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "keep_dist");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_range(prop, -100, 100, 1, 2);
RNA_def_property_ui_text(prop, "Offset", "Distance to keep from the target");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "project_limit", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "proj_limit");
RNA_def_property_range(prop, 0.0, FLT_MAX);
RNA_def_property_ui_range(prop, 0, 100, 1, 2);
RNA_def_property_ui_text(
prop, "Project Limit", "Limit the distance used for projection (zero disables)");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "use_project_x", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "proj_axis", MOD_SHRINKWRAP_PROJECT_OVER_X_AXIS);
RNA_def_property_ui_text(prop, "X", "");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "use_project_y", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "proj_axis", MOD_SHRINKWRAP_PROJECT_OVER_Y_AXIS);
RNA_def_property_ui_text(prop, "Y", "");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "use_project_z", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "proj_axis", MOD_SHRINKWRAP_PROJECT_OVER_Z_AXIS);
RNA_def_property_ui_text(prop, "Z", "");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "subsurf_levels", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "subsurf_levels");
RNA_def_property_range(prop, 0, 6);
RNA_def_property_ui_range(prop, 0, 6, 1, -1);
RNA_def_property_ui_text(
prop,
"Subdivision Levels",
"Number of subdivisions that must be performed before extracting vertices' "
"positions and normals");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "use_negative_direction", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "shrink_opts", MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR);
RNA_def_property_ui_text(
prop, "Negative", "Allow vertices to move in the negative direction of axis");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "use_positive_direction", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "shrink_opts", MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR);
RNA_def_property_ui_text(
prop, "Positive", "Allow vertices to move in the positive direction of axis");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "use_invert_cull", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "shrink_opts", MOD_SHRINKWRAP_INVERT_CULL_TARGET);
RNA_def_property_ui_text(
prop, "Invert Cull", "When projecting in the negative direction invert the face cull mode");
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);
RNA_def_property_pointer_funcs(prop,
NULL,
"rna_ShrinkwrapGpencilModifier_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, "vertex_group", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "vgname");
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for modulating the deform");
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_ShrinkwrapGpencilModifier_vgname_set");
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_SHRINKWRAP_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_SHRINKWRAP_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_SHRINKWRAP_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, "invert_vertex", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_SHRINKWRAP_INVERT_VGROUP);
RNA_def_property_ui_text(prop, "Inverse VertexGroup", "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_SHRINKWRAP_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, "smooth_factor", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "smooth_factor");
RNA_def_property_range(prop, 0, 1);
RNA_def_property_ui_text(prop, "Smooth Factor", "Amount of smoothing to apply");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "smooth_step", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "smooth_step");
RNA_def_property_range(prop, 1, 10);
RNA_def_property_ui_text(
prop, "Step", "Number of times to apply smooth (high numbers can reduce FPS)");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
RNA_define_lib_overridable(false);
}
void RNA_def_greasepencil_modifier(BlenderRNA *brna)
{
StructRNA *srna;
@ -3772,6 +3993,7 @@ void RNA_def_greasepencil_modifier(BlenderRNA *brna)
rna_def_modifier_gpencillineart(brna);
rna_def_modifier_gpencillength(brna);
rna_def_modifier_gpencildash(brna);
rna_def_modifier_gpencilshrinkwrap(brna);
}
#endif

View File

@ -381,6 +381,42 @@ const EnumPropertyItem rna_enum_modifier_shrinkwrap_mode_items[] = {
{0, NULL, 0, NULL, NULL},
};
const EnumPropertyItem rna_enum_shrinkwrap_type_items[] = {
{MOD_SHRINKWRAP_NEAREST_SURFACE,
"NEAREST_SURFACEPOINT",
0,
"Nearest Surface Point",
"Shrink the mesh to the nearest target surface"},
{MOD_SHRINKWRAP_PROJECT,
"PROJECT",
0,
"Project",
"Shrink the mesh to the nearest target surface along a given axis"},
{MOD_SHRINKWRAP_NEAREST_VERTEX,
"NEAREST_VERTEX",
0,
"Nearest Vertex",
"Shrink the mesh to the nearest target vertex"},
{MOD_SHRINKWRAP_TARGET_PROJECT,
"TARGET_PROJECT",
0,
"Target Normal Project",
"Shrink the mesh to the nearest target surface "
"along the interpolated vertex normals of the target"},
{0, NULL, 0, NULL, NULL},
};
const EnumPropertyItem rna_enum_shrinkwrap_face_cull_items[] = {
{0, "OFF", 0, "Off", "No culling"},
{MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE,
"FRONT",
0,
"Front",
"No projection when in front of the face"},
{MOD_SHRINKWRAP_CULL_TARGET_BACKFACE, "BACK", 0, "Back", "No projection when behind the face"},
{0, NULL, 0, NULL, NULL},
};
#ifndef RNA_RUNTIME
/* use eWarp_Falloff_*** & eHook_Falloff_***, they're in sync */
static const EnumPropertyItem modifier_warp_falloff_items[] = {
@ -4184,46 +4220,6 @@ static void rna_def_modifier_shrinkwrap(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
static const EnumPropertyItem shrink_type_items[] = {
{MOD_SHRINKWRAP_NEAREST_SURFACE,
"NEAREST_SURFACEPOINT",
0,
"Nearest Surface Point",
"Shrink the mesh to the nearest target surface"},
{MOD_SHRINKWRAP_PROJECT,
"PROJECT",
0,
"Project",
"Shrink the mesh to the nearest target surface along a given axis"},
{MOD_SHRINKWRAP_NEAREST_VERTEX,
"NEAREST_VERTEX",
0,
"Nearest Vertex",
"Shrink the mesh to the nearest target vertex"},
{MOD_SHRINKWRAP_TARGET_PROJECT,
"TARGET_PROJECT",
0,
"Target Normal Project",
"Shrink the mesh to the nearest target surface "
"along the interpolated vertex normals of the target"},
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem shrink_face_cull_items[] = {
{0, "OFF", 0, "Off", "No culling"},
{MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE,
"FRONT",
0,
"Front",
"No projection when in front of the face"},
{MOD_SHRINKWRAP_CULL_TARGET_BACKFACE,
"BACK",
0,
"Back",
"No projection when behind the face"},
{0, NULL, 0, NULL, NULL},
};
srna = RNA_def_struct(brna, "ShrinkwrapModifier", "Modifier");
RNA_def_struct_ui_text(srna,
"Shrinkwrap Modifier",
@ -4235,7 +4231,7 @@ static void rna_def_modifier_shrinkwrap(BlenderRNA *brna)
prop = RNA_def_property(srna, "wrap_method", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "shrinkType");
RNA_def_property_enum_items(prop, shrink_type_items);
RNA_def_property_enum_items(prop, rna_enum_shrinkwrap_type_items);
RNA_def_property_ui_text(prop, "Wrap Method", "");
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
@ -4248,7 +4244,7 @@ static void rna_def_modifier_shrinkwrap(BlenderRNA *brna)
prop = RNA_def_property(srna, "cull_face", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "shrinkOpts");
RNA_def_property_enum_items(prop, shrink_face_cull_items);
RNA_def_property_enum_items(prop, rna_enum_shrinkwrap_face_cull_items);
RNA_def_property_enum_funcs(
prop, "rna_ShrinkwrapModifier_face_cull_get", "rna_ShrinkwrapModifier_face_cull_set", NULL);
RNA_def_property_ui_text(