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:
authorMaxime Casas <maxime_casas@orange.fr>2021-09-09 07:01:15 +0300
committerCampbell Barton <ideasman42@gmail.com>2021-09-09 07:05:35 +0300
commitc8f80453d5c8e7004b46b866ca9923ce59766c7b (patch)
tree2206a0bd57e056a2f9f88cfedff9549d2c47d197
parentf9ebd17b4b124d93e4ad94c2c1a2ce020d8d334b (diff)
Modifier: add support for vertex groups
Allow blending the imported cache with the modifiers stack above the MeshCache modifier. This is particularly useful for instance when dealing with cloth simulations performed in another software, where some parts of the cloth are completely pinned (non-simulated, following the armature). Indeed, this would allow modifying the animation in some areas without having to rebake the other parts or the cloth, resulting in a much more flexible workflow. Reviewed By: #modeling, campbellbarton, mont29 Ref D9898
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h6
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c15
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache.c73
3 files changed, 86 insertions, 8 deletions
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 13213f70fed..8520786a030 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1942,6 +1942,7 @@ typedef struct MeshCacheModifierData {
float factor;
char deform_mode;
+ char defgrp_name[64];
char _pad[7];
/* play_mode == MOD_MESHCACHE_PLAY_CFEA */
@@ -1958,6 +1959,11 @@ typedef struct MeshCacheModifierData {
char filepath[1024];
} MeshCacheModifierData;
+/* MeshCache modifier flags. */
+enum {
+ MOD_MESHCACHE_INVERT_VERTEX_GROUP = 1 << 0,
+};
+
enum {
MOD_MESHCACHE_TYPE_MDD = 1,
MOD_MESHCACHE_TYPE_PC2 = 2,
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index f11d845c582..fb4fd4528d6 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -755,6 +755,7 @@ RNA_MOD_VGROUP_NAME_SET(LaplacianDeform, anchor_grp_name);
RNA_MOD_VGROUP_NAME_SET(LaplacianSmooth, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Lattice, name);
RNA_MOD_VGROUP_NAME_SET(Mask, vgroup);
+RNA_MOD_VGROUP_NAME_SET(MeshCache, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(MeshDeform, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(NormalEdit, defgrp_name);
RNA_MOD_VGROUP_NAME_SET(Shrinkwrap, vgroup_name);
@@ -6045,6 +6046,20 @@ static void rna_def_modifier_meshcache(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Influence", "Influence of the deformation");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
+ RNA_def_property_ui_text(
+ prop,
+ "Vertex Group",
+ "Name of the Vertex Group which determines the influence of the modifier per point");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshCacheModifier_defgrp_name_set");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "invert_vertex_group", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_MESHCACHE_INVERT_VERTEX_GROUP);
+ RNA_def_property_ui_text(prop, "Invert", "Invert vertex group influence");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
/* -------------------------------------------------------------------- */
/* Axis Conversion */
prop = RNA_def_property(srna, "forward_axis", PROP_ENUM, PROP_NONE);
diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c
index 6ef64ad8bc9..74f9887a973 100644
--- a/source/blender/modifiers/intern/MOD_meshcache.c
+++ b/source/blender/modifiers/intern/MOD_meshcache.c
@@ -36,8 +36,11 @@
#include "DNA_screen_types.h"
#include "BKE_context.h"
+#include "BKE_deform.h"
+#include "BKE_lib_id.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_wrapper.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
@@ -53,6 +56,7 @@
#include "MOD_meshcache_util.h" /* utility functions */
#include "MOD_modifiertypes.h"
#include "MOD_ui_common.h"
+#include "MOD_util.h"
static void initData(ModifierData *md)
{
@@ -84,11 +88,16 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
static void meshcache_do(MeshCacheModifierData *mcmd,
Scene *scene,
Object *ob,
+ Mesh *mesh,
float (*vertexCos_Real)[3],
int numVerts)
{
const bool use_factor = mcmd->factor < 1.0f;
- float(*vertexCos_Store)[3] = (use_factor ||
+ int influence_group_index;
+ MDeformVert *dvert;
+ MOD_get_vgroup(ob, mesh, mcmd->defgrp_name, &dvert, &influence_group_index);
+
+ float(*vertexCos_Store)[3] = (use_factor || influence_group_index != -1 ||
(mcmd->deform_mode == MOD_MESHCACHE_DEFORM_INTEGRATE)) ?
MEM_malloc_arrayN(
numVerts, sizeof(*vertexCos_Store), __func__) :
@@ -256,7 +265,29 @@ static void meshcache_do(MeshCacheModifierData *mcmd,
if (vertexCos_Store) {
if (ok) {
- if (use_factor) {
+ if (influence_group_index != -1) {
+ const float global_factor = (mcmd->flag & MOD_MESHCACHE_INVERT_VERTEX_GROUP) ?
+ -mcmd->factor :
+ mcmd->factor;
+ const float global_offset = (mcmd->flag & MOD_MESHCACHE_INVERT_VERTEX_GROUP) ?
+ mcmd->factor :
+ 0.0f;
+ if (mesh->dvert != NULL) {
+ for (int i = 0; i < numVerts; i++) {
+ /* For each vertex, compute its blending factor between the mesh cache (for `fac = 0`)
+ * and the former position of the vertex (for `fac = 1`). */
+ const MDeformVert *currentIndexDVert = dvert + i;
+ const float local_vertex_fac = global_offset +
+ BKE_defvert_find_weight(currentIndexDVert,
+ influence_group_index) *
+ global_factor;
+ interp_v3_v3v3(
+ vertexCos_Real[i], vertexCos_Real[i], vertexCos_Store[i], local_vertex_fac);
+ }
+ }
+ }
+ else if (use_factor) {
+ /* Influence_group_index is -1. */
interp_vn_vn(*vertexCos_Real, *vertexCos_Store, mcmd->factor, numVerts * 3);
}
else {
@@ -270,34 +301,59 @@ static void meshcache_do(MeshCacheModifierData *mcmd,
static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
- Mesh *UNUSED(mesh),
+ Mesh *mesh,
float (*vertexCos)[3],
int numVerts)
{
MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- meshcache_do(mcmd, scene, ctx->object, vertexCos, numVerts);
+ Mesh *mesh_src = NULL;
+
+ if (ctx->object->type == OB_MESH && mcmd->defgrp_name[0] != '\0') {
+ /* `mesh_src` is only needed for vertex groups. */
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ }
+ meshcache_do(mcmd, scene, ctx->object, mesh_src, vertexCos, numVerts);
+
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
static void deformVertsEM(ModifierData *md,
const ModifierEvalContext *ctx,
- struct BMEditMesh *UNUSED(editData),
- Mesh *UNUSED(mesh),
+ struct BMEditMesh *editData,
+ Mesh *mesh,
float (*vertexCos)[3],
int numVerts)
{
MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
- meshcache_do(mcmd, scene, ctx->object, vertexCos, numVerts);
+ Mesh *mesh_src = NULL;
+
+ if (ctx->object->type == OB_MESH && mcmd->defgrp_name[0] != '\0') {
+ /* `mesh_src` is only needed for vertex groups. */
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ }
+ if (mesh_src != NULL) {
+ BKE_mesh_wrapper_ensure_mdata(mesh_src);
+ }
+
+ meshcache_do(mcmd, scene, ctx->object, mesh_src, vertexCos, numVerts);
+
+ if (!ELEM(mesh_src, NULL, mesh)) {
+ BKE_id_free(NULL, mesh_src);
+ }
}
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
{
uiLayout *layout = panel->layout;
- PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL);
+ PointerRNA ob_ptr;
+ PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr);
uiLayoutSetPropSep(layout, true);
@@ -307,6 +363,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(layout, ptr, "factor", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(layout, ptr, "deform_mode", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "interpolation", 0, NULL, ICON_NONE);
+ modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
modifier_panel_end(layout, ptr);
}