diff options
-rw-r--r-- | source/blender/makesdna/DNA_modifier_types.h | 6 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_modifier.c | 15 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_meshcache.c | 73 |
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); } |