From 65c5ebf5779d07fb92fabd0ff992337f6c980cde Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Nov 2021 00:33:22 +1100 Subject: Fix T91923: Save/Apply as Shape Key ignores shape keys Support virtual modifiers when using applying the modifier as a shape. --- source/blender/blenkernel/BKE_mesh.h | 1 + source/blender/blenkernel/intern/mesh_convert.cc | 51 ++++++++++++++++++++---- source/blender/editors/object/object_modifier.c | 9 +++-- 3 files changed, 51 insertions(+), 10 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index f44d35c62a3..be9b84ccd62 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -209,6 +209,7 @@ struct Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob_eval, struct ModifierData *md_eval, + const bool use_virtual_modifiers, const bool build_shapekey_layers); /* Copies a nomain-Mesh into an existing Mesh. */ diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index adfbe4b8c94..b8fcc10be44 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -1277,10 +1277,16 @@ static void add_shapekey_layers(Mesh *mesh_dest, Mesh *mesh_src) } } +/** + * \param use_virtual_modifiers: When enabled calculate virtual-modifiers before applying `md_eval` + * support this since virtual-modieirs are not modifiers from auser perspective, + * allowing shape keys to be included with the modifier being applied, see: T91923. + */ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph, Scene *scene, Object *ob_eval, ModifierData *md_eval, + const bool use_virtual_modifiers, const bool build_shapekey_layers) { Mesh *me = ob_eval->runtime.data_orig ? (Mesh *)ob_eval->runtime.data_orig : @@ -1303,22 +1309,49 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph, BKE_keyblock_convert_to_mesh(kb, me); } - if (mti->type == eModifierTypeType_OnlyDeform) { - int numVerts; - float(*deformedVerts)[3] = BKE_mesh_vert_coords_alloc(me, &numVerts); + Mesh *mesh_temp = (Mesh *)BKE_id_copy_ex(nullptr, &me->id, nullptr, LIB_ID_COPY_LOCALIZE); + int numVerts = 0; + float(*deformedVerts)[3] = nullptr; + + if (use_virtual_modifiers) { + VirtualModifierData virtualModifierData; + for (ModifierData *md_eval_virt = + BKE_modifiers_get_virtual_modifierlist(ob_eval, &virtualModifierData); + md_eval_virt && (md_eval_virt != ob_eval->modifiers.first); + md_eval_virt = md_eval_virt->next) { + if (!BKE_modifier_is_enabled(scene, md_eval_virt, eModifierMode_Realtime)) { + continue; + } + /* All virtual modifiers are deform modifiers. */ + const ModifierTypeInfo *mti_virt = BKE_modifier_get_info((ModifierType)md_eval_virt->type); + BLI_assert(mti_virt->type == eModifierTypeType_OnlyDeform); + if (mti_virt->type != eModifierTypeType_OnlyDeform) { + continue; + } + + if (deformedVerts == nullptr) { + deformedVerts = BKE_mesh_vert_coords_alloc(me, &numVerts); + } + mti_virt->deformVerts(md_eval_virt, &mectx, mesh_temp, deformedVerts, numVerts); + } + } - result = (Mesh *)BKE_id_copy_ex(nullptr, &me->id, nullptr, LIB_ID_COPY_LOCALIZE); + if (mti->type == eModifierTypeType_OnlyDeform) { + if (deformedVerts == nullptr) { + deformedVerts = BKE_mesh_vert_coords_alloc(me, &numVerts); + } + result = mesh_temp; mti->deformVerts(md_eval, &mectx, result, deformedVerts, numVerts); BKE_mesh_vert_coords_apply(result, deformedVerts); if (build_shapekey_layers) { add_shapekey_layers(result, me); } - - MEM_freeN(deformedVerts); } else { - Mesh *mesh_temp = (Mesh *)BKE_id_copy_ex(nullptr, &me->id, nullptr, LIB_ID_COPY_LOCALIZE); + if (deformedVerts != nullptr) { + BKE_mesh_vert_coords_apply(mesh_temp, deformedVerts); + } if (build_shapekey_layers) { add_shapekey_layers(mesh_temp, me); @@ -1332,6 +1365,10 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph, } } + if (deformedVerts != nullptr) { + MEM_freeN(deformedVerts); + } + return result; } diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index efe19785f31..21b978268d9 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -666,12 +666,13 @@ bool ED_object_modifier_convert(ReportList *UNUSED(reports), static Mesh *modifier_apply_create_mesh_for_modifier(Depsgraph *depsgraph, Object *object, ModifierData *md_eval, + bool use_virtual_modifiers, bool build_shapekey_layers) { Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); Object *object_eval = DEG_get_evaluated_object(depsgraph, object); Mesh *mesh_applied = BKE_mesh_create_derived_for_modifier( - depsgraph, scene_eval, object_eval, md_eval, build_shapekey_layers); + depsgraph, scene_eval, object_eval, md_eval, use_virtual_modifiers, build_shapekey_layers); return mesh_applied; } @@ -708,7 +709,8 @@ static bool modifier_apply_shape(Main *bmain, return false; } - Mesh *mesh_applied = modifier_apply_create_mesh_for_modifier(depsgraph, ob, md_eval, false); + Mesh *mesh_applied = modifier_apply_create_mesh_for_modifier( + depsgraph, ob, md_eval, true, false); if (!mesh_applied) { BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply"); return false; @@ -767,7 +769,8 @@ static bool modifier_apply_obdata( } } else { - Mesh *mesh_applied = modifier_apply_create_mesh_for_modifier(depsgraph, ob, md_eval, true); + Mesh *mesh_applied = modifier_apply_create_mesh_for_modifier( + depsgraph, ob, md_eval, true, true); if (!mesh_applied) { BKE_report(reports, RPT_ERROR, "Modifier returned error, skipping apply"); return false; -- cgit v1.2.3