Fix T37914: Mask modifier behaves differently until painted

This commit is contained in:
Campbell Barton 2013-12-24 14:26:31 +11:00
parent 4ba80fd461
commit d064968c27
Notes: blender-bot 2023-02-14 11:27:27 +01:00
Referenced by issue #37914, New vertex group behaves as if assigned until modified
1 changed files with 21 additions and 41 deletions

View File

@ -96,14 +96,15 @@ static void updateDepgraph(ModifierData *md, DagForest *forest,
}
static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
DerivedMesh *derivedData,
DerivedMesh *dm,
ModifierApplyFlag UNUSED(flag))
{
MaskModifierData *mmd = (MaskModifierData *)md;
DerivedMesh *dm = derivedData, *result = NULL;
const bool found_test = (mmd->flag & MOD_MASK_INV) == 0;
DerivedMesh *result = NULL;
GHash *vertHash = NULL, *edgeHash, *polyHash;
GHashIterator *hashIter;
MDeformVert *dvert = NULL, *dv;
MDeformVert *dvert, *dv;
int numPolys = 0, numLoops = 0, numEdges = 0, numVerts = 0;
int maxVerts, maxEdges, maxPolys;
int i;
@ -119,6 +120,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
int *loop_mapping;
dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
if (dvert == NULL) {
return found_test ? CDDM_from_template(dm, 0, 0, 0, 0, 0) : dm;
}
/* Overview of Method:
* 1. Get the vertices that are in the vertexgroup of interest
* 2. Filter out unwanted geometry (i.e. not in vertexgroup), by populating mappings with new vs old indices
@ -136,7 +142,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
if (!(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) ||
(maxVerts == 0) || (ob->defbase.first == NULL) )
{
return derivedData;
return dm;
}
/* if mode is to use selected armature bones, aggregate the bone groups */
@ -150,7 +156,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* check that there is armature object with bones to use, otherwise return original mesh */
if (ELEM3(NULL, oba, oba->pose, ob->defbase.first))
return derivedData;
return dm;
/* determine whether each vertexgroup is associated with a selected bone or not
* - each cell is a boolean saying whether bone corresponding to the ith group is selected
@ -168,16 +174,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
bone_select_array[i] = FALSE;
}
}
/* if no dverts (i.e. no data for vertex groups exists), we've got an
* inconsistent situation, so free hashes and return original mesh
*/
dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
if (dvert == NULL) {
MEM_freeN(bone_select_array);
return derivedData;
}
/* verthash gives mapping from original vertex indices to the new indices (including selected matches only)
* key = oldindex, value = newindex
*/
@ -189,7 +186,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
*/
for (i = 0, dv = dvert; i < maxVerts; i++, dv++) {
MDeformWeight *dw = dv->dw;
short found = 0;
bool found = false;
int j;
/* check the groups that vertex is assigned to, and see if it was any use */
@ -204,14 +201,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
}
}
/* check if include vert in vertHash */
if (mmd->flag & MOD_MASK_INV) {
/* if this vert is in the vgroup, don't include it in vertHash */
if (found) continue;
}
else {
/* if this vert isn't in the vgroup, don't include it in vertHash */
if (!found) continue;
if (found_test != found) {
continue;
}
/* add to ghash for verts (numVerts acts as counter for mapping) */
@ -224,13 +215,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
}
else { /* --- Using Nominated VertexGroup only --- */
int defgrp_index = defgroup_name_index(ob, mmd->vgroup);
/* get dverts */
if (defgrp_index != -1)
dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
/* if no vgroup (i.e. dverts) found, return the initial mesh */
if ((defgrp_index == -1) || (dvert == NULL))
if (defgrp_index == -1)
return dm;
/* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
@ -238,18 +225,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* add vertices which exist in vertexgroup into ghash for filtering */
for (i = 0, dv = dvert; i < maxVerts; i++, dv++) {
const int weight_set = defvert_find_weight(dv, defgrp_index) != 0.0f;
/* check if include vert in vertHash */
if (mmd->flag & MOD_MASK_INV) {
/* if this vert is in the vgroup, don't include it in vertHash */
if (weight_set) continue;
const bool found = defvert_find_weight(dv, defgrp_index) != 0.0f;
if (found_test != found) {
continue;
}
else {
/* if this vert isn't in the vgroup, don't include it in vertHash */
if (!weight_set) continue;
}
/* add to ghash for verts (numVerts acts as counter for mapping) */
BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts));
numVerts++;