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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Vazquez <blendergit@gmail.com>2021-12-13 19:09:22 +0300
committerAntonio Vazquez <blendergit@gmail.com>2021-12-13 19:09:22 +0300
commit459af75d1ed586f08cd43e2aec7a3b270e809132 (patch)
treec7dbbe0be774f5a6fc2fb89630b2a00dd2adf0e5 /source/blender
parent49802af7cd920d83f2c1805f4047d91842c76311 (diff)
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
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_gpencil_geom.h6
-rw-r--r--source/blender/blenkernel/BKE_gpencil_modifier.h12
-rw-r--r--source/blender/blenkernel/BKE_shrinkwrap.h8
-rw-r--r--source/blender/blenkernel/intern/gpencil_geom.cc9
-rw-r--r--source/blender/blenkernel/intern/gpencil_modifier.c95
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c50
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_fill.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_interpolate.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c4
-rw-r--r--source/blender/editors/gpencil/gpencil_sculpt_paint.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c3
-rw-r--r--source/blender/gpencil_modifiers/CMakeLists.txt1
-rw-r--r--source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h1
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c1
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c350
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c2
-rw-r--r--source/blender/makesdna/DNA_gpencil_modifier_defaults.h21
-rw-r--r--source/blender/makesdna/DNA_gpencil_modifier_types.h58
-rw-r--r--source/blender/makesdna/intern/dna_defaults.c2
-rw-r--r--source/blender/makesrna/RNA_enum_items.h2
-rw-r--r--source/blender/makesrna/intern/rna_gpencil_modifier.c222
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c80
23 files changed, 851 insertions, 84 deletions
diff --git a/source/blender/blenkernel/BKE_gpencil_geom.h b/source/blender/blenkernel/BKE_gpencil_geom.h
index df6dd6eab92..4b9671c7881 100644
--- a/source/blender/blenkernel/BKE_gpencil_geom.h
+++ b/source/blender/blenkernel/BKE_gpencil_geom.h
@@ -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
diff --git a/source/blender/blenkernel/BKE_gpencil_modifier.h b/source/blender/blenkernel/BKE_gpencil_modifier.h
index e7917ffa578..d850dea0c30 100644
--- a/source/blender/blenkernel/BKE_gpencil_modifier.h
+++ b/source/blender/blenkernel/BKE_gpencil_modifier.h
@@ -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.
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h
index 6ab14628c29..088b270bfed 100644
--- a/source/blender/blenkernel/BKE_shrinkwrap.h
+++ b/source/blender/blenkernel/BKE_shrinkwrap.h
@@ -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.
diff --git a/source/blender/blenkernel/intern/gpencil_geom.cc b/source/blender/blenkernel/intern/gpencil_geom.cc
index aca85984989..84a9735ac5c 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.cc
+++ b/source/blender/blenkernel/intern/gpencil_geom.cc
@@ -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. */
diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index fb6dbc5402d..f3bd17d5ef7 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -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;
+ }
+ if (mmd->cache_data) {
+ BKE_lattice_deform_data_destroy(mmd->cache_data);
+ }
- latob = mmd->object;
- if ((!latob) || (latob->type != OB_LATTICE)) {
- return;
+ /* 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;
+ }
}
}
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index 00a80d6e74f..7618323f488 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -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)
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 7dad83e305f..836d6bf90fe 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -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);
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 90cf64b58d8..c3af28d4382 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -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 */
}
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index 22127d7ac3b..2023ae5fe27 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -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 */
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 018334a851e..dabe2050b28 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -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);
}
}
diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
index 32ad8c98950..186c45c9f39 100644
--- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c
+++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
@@ -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);
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index c339f07fd58..a586f268128 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -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:
diff --git a/source/blender/gpencil_modifiers/CMakeLists.txt b/source/blender/gpencil_modifiers/CMakeLists.txt
index afcd551d0af..5ee75619259 100644
--- a/source/blender/gpencil_modifiers/CMakeLists.txt
+++ b/source/blender/gpencil_modifiers/CMakeLists.txt
@@ -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
diff --git a/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h b/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h
index d9285f44a37..56cee115760 100644
--- a/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h
+++ b/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h
@@ -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[]);
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c
index d3088c68af5..f6a85919de4 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c
@@ -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
}
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c
new file mode 100644
index 00000000000..6990b41e6ce
--- /dev/null
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c
@@ -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,
+};
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c
index b00db1ba2d2..a63cbb53645 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c
@@ -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);
diff --git a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
index 1ad884bee8f..e0947085694 100644
--- a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
+++ b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
@@ -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 */
diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h
index 339714da255..f7964e1f2fa 100644
--- a/source/blender/makesdna/DNA_gpencil_modifier_types.h
+++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h
@@ -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
diff --git a/source/blender/makesdna/intern/dna_defaults.c b/source/blender/makesdna/intern/dna_defaults.c
index 59f30f7b2e3..6c8b4d0acb1 100644
--- a/source/blender/makesdna/intern/dna_defaults.c
+++ b/source/blender/makesdna/intern/dna_defaults.c
@@ -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
diff --git a/source/blender/makesrna/RNA_enum_items.h b/source/blender/makesrna/RNA_enum_items.h
index e9b7532584b..531af92c544 100644
--- a/source/blender/makesrna/RNA_enum_items.h
+++ b/source/blender/makesrna/RNA_enum_items.h
@@ -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)
diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c
index 82f3279146a..72401b460be 100644
--- a/source/blender/makesrna/intern/rna_gpencil_modifier.c
+++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c
@@ -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
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 9ad6771cda3..d46ae13b482 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -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(