Modifiers: Add normalize weights option to vertex weight modifiers
Original patch by Cody Winchester (@CodyWinch), several fixes and cleanup by Bastien Montagne (@mont29). Differential revision: https://developer.blender.org/D7656
This commit is contained in:
parent
00674c12cc
commit
de257b6366
|
@ -1437,6 +1437,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
|||
if md.falloff_type == 'CURVE':
|
||||
layout.template_curve_mapping(md, "map_curve")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(md, "normalize")
|
||||
|
||||
# Common mask options
|
||||
layout.separator()
|
||||
self.vertex_weight_mask(layout, ob, md)
|
||||
|
@ -1462,6 +1465,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
|||
col.label(text="Mix Set:")
|
||||
col.prop(md, "mix_set", text="")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(md, "normalize")
|
||||
|
||||
# Common mask options
|
||||
layout.separator()
|
||||
self.vertex_weight_mask(layout, ob, md)
|
||||
|
@ -1495,6 +1501,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
|||
row.prop(md, "falloff_type")
|
||||
row.prop(md, "invert_falloff", text="", icon='ARROW_LEFTRIGHT')
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(md, "normalize")
|
||||
|
||||
# Common mask options
|
||||
layout.separator()
|
||||
self.vertex_weight_mask(layout, ob, md)
|
||||
|
|
|
@ -31,7 +31,7 @@ extern "C" {
|
|||
* \note Use #STRINGIFY() rather than defining with quotes.
|
||||
*/
|
||||
#define BLENDER_VERSION 290
|
||||
#define BLENDER_SUBVERSION 3
|
||||
#define BLENDER_SUBVERSION 4
|
||||
/** Several breakages with 280, e.g. collections vs layers. */
|
||||
#define BLENDER_MINVERSION 280
|
||||
#define BLENDER_MINSUBVERSION 0
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "DNA_brush_types.h"
|
||||
#include "DNA_genfile.h"
|
||||
#include "DNA_gpencil_modifier_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "BKE_collection.h"
|
||||
|
@ -241,6 +243,18 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 290, 4)) {
|
||||
/* Clear old deprecated bitflag from edit weights modifiers, we now use it for something else.
|
||||
*/
|
||||
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
||||
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
|
||||
if (md->type == eModifierType_WeightVGEdit) {
|
||||
md->flag &= ~MOD_WVG_EDIT_WEIGHTS_NORMALIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
|
|
|
@ -1416,7 +1416,7 @@ typedef struct WeightVGEditModifierData {
|
|||
|
||||
/* WeightVGEdit flags. */
|
||||
enum {
|
||||
/* (1 << 0) is free for future use! */
|
||||
MOD_WVG_EDIT_WEIGHTS_NORMALIZE = (1 << 0),
|
||||
MOD_WVG_INVERT_FALLOFF = (1 << 1),
|
||||
MOD_WVG_EDIT_INVERT_VGROUP_MASK = (1 << 2),
|
||||
/** Add vertices with higher weight than threshold to vgroup. */
|
||||
|
@ -1504,6 +1504,7 @@ enum {
|
|||
/* WeightVGMix->flag */
|
||||
enum {
|
||||
MOD_WVG_MIX_INVERT_VGROUP_MASK = (1 << 0),
|
||||
MOD_WVG_MIX_WEIGHTS_NORMALIZE = (1 << 1),
|
||||
};
|
||||
|
||||
typedef struct WeightVGProximityModifierData {
|
||||
|
@ -1566,6 +1567,7 @@ enum {
|
|||
MOD_WVG_PROXIMITY_GEOM_FACES = (1 << 2),
|
||||
MOD_WVG_PROXIMITY_INVERT_VGROUP_MASK = (1 << 3),
|
||||
MOD_WVG_PROXIMITY_INVERT_FALLOFF = (1 << 4),
|
||||
MOD_WVG_PROXIMITY_WEIGHTS_NORMALIZE = (1 << 3),
|
||||
};
|
||||
|
||||
/* Defines common to all WeightVG modifiers. */
|
||||
|
|
|
@ -4888,6 +4888,14 @@ static void rna_def_modifier_weightvgedit(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Invert Falloff", "Invert the resulting falloff weight");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "normalize", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "edit_flags", MOD_WVG_EDIT_WEIGHTS_NORMALIZE);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Normalize Weights",
|
||||
"Normalize the resulting weights (otherwise they are only clamped within [0.0, 1.0] range)");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "map_curve", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "cmap_curve");
|
||||
RNA_def_property_ui_text(prop, "Mapping Curve", "Custom mapping curve");
|
||||
|
@ -5045,6 +5053,14 @@ static void rna_def_modifier_weightvgmix(BlenderRNA *brna)
|
|||
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_WVG_MIX_INVERT_VGROUP_MASK);
|
||||
RNA_def_property_ui_text(prop, "Invert", "Invert vertex group mask influence");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "normalize", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_WVG_MIX_WEIGHTS_NORMALIZE);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Normalize Weights",
|
||||
"Normalize the resulting weights (otherwise they are only clamped within [0.0, 1.0] range)");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
}
|
||||
|
||||
static void rna_def_modifier_weightvgproximity(BlenderRNA *brna)
|
||||
|
@ -5151,6 +5167,15 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Invert Falloff", "Invert the resulting falloff weight");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "normalize", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(
|
||||
prop, NULL, "proximity_flags", MOD_WVG_PROXIMITY_WEIGHTS_NORMALIZE);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Normalize Weights",
|
||||
"Normalize the resulting weights (otherwise they are only clamped within [0.0, 1.0] range)");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
/* Common masking properties. */
|
||||
rna_def_modifier_weightvg_mask(brna,
|
||||
srna,
|
||||
|
|
|
@ -272,16 +272,45 @@ void weightvg_update_vg(MDeformVert *dvert,
|
|||
const bool do_add,
|
||||
const float add_thresh,
|
||||
const bool do_rem,
|
||||
const float rem_thresh)
|
||||
const float rem_thresh,
|
||||
const bool do_normalize)
|
||||
{
|
||||
int i;
|
||||
|
||||
float min_w = weights[0];
|
||||
float norm_fac = 1.0f;
|
||||
if (do_normalize) {
|
||||
float max_w = weights[0];
|
||||
for (i = 1; i < num; i++) {
|
||||
const float w = weights[i];
|
||||
|
||||
/* No need to clamp here, normalization will ensure we stay within [0.0, 1.0] range. */
|
||||
if (w < min_w) {
|
||||
min_w = w;
|
||||
}
|
||||
else if (w > max_w) {
|
||||
max_w = w;
|
||||
}
|
||||
}
|
||||
|
||||
const float range = max_w - min_w;
|
||||
if (fabsf(range) > FLT_EPSILON) {
|
||||
norm_fac = 1.0f / range;
|
||||
}
|
||||
else {
|
||||
min_w = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
float w = weights[i];
|
||||
MDeformVert *dv = &dvert[indices ? indices[i] : i];
|
||||
MDeformWeight *dw = dws ? dws[i] :
|
||||
((defgrp_idx >= 0) ? BKE_defvert_find_index(dv, defgrp_idx) : NULL);
|
||||
|
||||
if (do_normalize) {
|
||||
w = (w - min_w) * norm_fac;
|
||||
}
|
||||
/* Never allow weights out of [0.0, 1.0] range. */
|
||||
CLAMP(w, 0.0f, 1.0f);
|
||||
|
||||
|
|
|
@ -86,6 +86,7 @@ void weightvg_update_vg(struct MDeformVert *dvert,
|
|||
const bool do_add,
|
||||
const float add_thresh,
|
||||
const bool do_rem,
|
||||
const float rem_thresh);
|
||||
const float rem_thresh,
|
||||
const bool do_normalize);
|
||||
|
||||
#endif /* __MOD_WEIGHTVG_UTIL_H__ */
|
||||
|
|
|
@ -239,6 +239,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
|
||||
/* Do mapping. */
|
||||
const bool do_invert_mapping = (wmd->edit_flags & MOD_WVG_INVERT_FALLOFF) != 0;
|
||||
const bool do_normalize = (wmd->edit_flags & MOD_WVG_EDIT_WEIGHTS_NORMALIZE) != 0;
|
||||
if (do_invert_mapping || wmd->falloff_type != MOD_WVG_MAPPING_NONE) {
|
||||
RNG *rng = NULL;
|
||||
|
||||
|
@ -283,7 +284,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
do_add,
|
||||
wmd->add_threshold,
|
||||
do_rem,
|
||||
wmd->rem_threshold);
|
||||
wmd->rem_threshold,
|
||||
do_normalize);
|
||||
|
||||
/* If weight preview enabled... */
|
||||
#if 0 /* XXX Currently done in mod stack :/ */
|
||||
|
|
|
@ -224,6 +224,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
int numIdx = 0;
|
||||
int i;
|
||||
const bool invert_vgroup_mask = (wmd->flag & MOD_WVG_MIX_INVERT_VGROUP_MASK) != 0;
|
||||
const bool do_normalize = (wmd->flag & MOD_WVG_MIX_WEIGHTS_NORMALIZE) != 0;
|
||||
/* Flags. */
|
||||
#if 0
|
||||
const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview) != 0;
|
||||
|
@ -408,7 +409,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
* XXX Depending on the MOD_WVG_SET_xxx option chosen, we might have to add vertices to vgroup.
|
||||
*/
|
||||
weightvg_update_vg(
|
||||
dvert, defgrp_index, dw1, numIdx, indices, org_w, true, -FLT_MAX, false, 0.0f);
|
||||
dvert, defgrp_index, dw1, numIdx, indices, org_w, true, -FLT_MAX, false, 0.0f, do_normalize);
|
||||
|
||||
/* If weight preview enabled... */
|
||||
#if 0 /* XXX Currently done in mod stack :/ */
|
||||
|
|
|
@ -429,6 +429,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
int i;
|
||||
const bool invert_vgroup_mask = (wmd->proximity_flags & MOD_WVG_PROXIMITY_INVERT_VGROUP_MASK) !=
|
||||
0;
|
||||
const bool do_normalize = (wmd->proximity_flags & MOD_WVG_PROXIMITY_WEIGHTS_NORMALIZE) != 0;
|
||||
/* Flags. */
|
||||
#if 0
|
||||
const bool do_prev = (wmd->modifier.mode & eModifierMode_DoWeightPreview) != 0;
|
||||
|
@ -604,7 +605,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
|
|||
invert_vgroup_mask);
|
||||
|
||||
/* Update vgroup. Note we never add nor remove vertices from vgroup here. */
|
||||
weightvg_update_vg(dvert, defgrp_index, dw, numIdx, indices, org_w, false, 0.0f, false, 0.0f);
|
||||
weightvg_update_vg(
|
||||
dvert, defgrp_index, dw, numIdx, indices, org_w, false, 0.0f, false, 0.0f, do_normalize);
|
||||
|
||||
/* If weight preview enabled... */
|
||||
#if 0 /* XXX Currently done in mod stack :/ */
|
||||
|
|
Loading…
Reference in New Issue