Fix T103074: flipped vertex group meaning in Multi-Modifier Armature.

For some reason the Armature modifier in the Multi-Modifier mode
interpreted the vertex group in a way essentially opposite to the
regular mode. Moreover, this depended not on the Multi-Modifier
checkbox, but on whether the mode was actually active.

This fixes the flip and adds versioning code to patch old files.
One difficulty is that whether the Multi-Modifier flag is valid
can be different between the viewport and render. The versioning
code assumes any modifier enabled in either to be active.

This change is not forward compatible, so min version is also bumped.

Differential Revision: https://developer.blender.org/D16787
This commit is contained in:
Alexander Gavrilov 2022-12-15 23:37:14 +02:00
parent 09a26f26e8
commit ea1c31a244
Notes: blender-bot 2023-02-14 05:52:32 +01:00
Referenced by issue #103074, Armature Modifier: Multi Modifier changes the meaning of the mask vertex group.
3 changed files with 48 additions and 12 deletions

View File

@ -25,13 +25,13 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 7
#define BLENDER_FILE_SUBVERSION 8
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file
* was written with too new a version. */
#define BLENDER_FILE_MIN_VERSION 305
#define BLENDER_FILE_MIN_SUBVERSION 4
#define BLENDER_FILE_MIN_SUBVERSION 8
/** User readable version string. */
const char *BKE_blender_version_string(void);

View File

@ -270,7 +270,7 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data,
float *vec = NULL, (*smat)[3] = NULL;
float contrib = 0.0f;
float armature_weight = 1.0f; /* default to 1 if no overall def group */
float prevco_weight = 1.0f; /* weight for optional cached vertexcos */
float prevco_weight = 0.0f; /* weight for optional cached vertexcos */
if (use_quaternion) {
memset(&sumdq, 0, sizeof(DualQuat));
@ -295,7 +295,9 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data,
/* hackish: the blending factor can be used for blending with vert_coords_prev too */
if (vert_coords_prev) {
prevco_weight = armature_weight;
/* This weight specifies the contribution from the coordinates at the start of this
* modifier evaluation, while armature_weight is normally the opposite of that. */
prevco_weight = 1.0f - armature_weight;
armature_weight = 1.0f;
}
}

View File

@ -3858,6 +3858,48 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 305, 8)) {
const int CV_SCULPT_SELECTION_ENABLED = (1 << 1);
LISTBASE_FOREACH (Curves *, curves_id, &bmain->hair_curves) {
curves_id->flag &= ~CV_SCULPT_SELECTION_ENABLED;
}
LISTBASE_FOREACH (Curves *, curves_id, &bmain->hair_curves) {
BKE_id_attribute_rename(&curves_id->id, ".selection_point_float", ".selection", nullptr);
BKE_id_attribute_rename(&curves_id->id, ".selection_curve_float", ".selection", nullptr);
}
/* Toggle the Invert Vertex Group flag on Armature modifiers in some cases. */
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
bool after_armature = false;
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
if (md->type == eModifierType_Armature) {
ArmatureModifierData *amd = (ArmatureModifierData *)md;
if (amd->multi) {
/* Toggle the invert vertex group flag on operational Multi Modifier entries. */
if (after_armature && amd->defgrp_name[0]) {
amd->deformflag ^= ARM_DEF_INVERT_VGROUP;
}
}
else {
/* Disabled multi modifiers don't reset propagation, but non-multi ones do. */
after_armature = false;
}
/* Multi Modifier is only valid and operational after an active Armature modifier. */
if (md->mode & (eModifierMode_Realtime | eModifierMode_Render)) {
after_armature = true;
}
}
else if (ELEM(md->type, eModifierType_Lattice, eModifierType_MeshDeform)) {
/* These modifiers will also allow a following Multi Modifier to work. */
after_armature = (md->mode & (eModifierMode_Realtime | eModifierMode_Render)) != 0;
}
else {
after_armature = false;
}
}
}
}
/**
* Versioning code until next subversion bump goes here.
*
@ -3869,13 +3911,5 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
*/
{
/* Keep this block, even when empty. */
const int CV_SCULPT_SELECTION_ENABLED = (1 << 1);
LISTBASE_FOREACH (Curves *, curves_id, &bmain->hair_curves) {
curves_id->flag &= ~CV_SCULPT_SELECTION_ENABLED;
}
LISTBASE_FOREACH (Curves *, curves_id, &bmain->hair_curves) {
BKE_id_attribute_rename(&curves_id->id, ".selection_point_float", ".selection", nullptr);
BKE_id_attribute_rename(&curves_id->id, ".selection_curve_float", ".selection", nullptr);
}
}
}