Modeling: Add Auto Normalize when Assigning vertex weights
Part of #135062. This PR adds an Auto Normalize option in the Vertex Group panel that when checked will normalize the other deform-bone vertex groups' weights when assigning the weight of a deform-bone vertex group. For example if a selected vertex has the following weights: | Name | Weight | |---------|--------| | Group 1 | 0.2 | | Group 2 | 0.2 | | Group 3 | 0.6 | And the user selects Group 3, checks the Auto Normalize checkbox, sets the weight to 0.8, and clicks Assign, the new weights will be: | Name | Weight | |---------|--------| | Group 1 | 0.1 | | Group 2 | 0.1 | | Group 3 | 0.8 | Co-authored-by: Andy Beers <acbeers1@gmail.com> Pull Request: https://projects.blender.org/blender/blender/pulls/138133
This commit is contained in:
committed by
Nathan Vegdahl
parent
41a69b76a6
commit
4e7dfcbe3f
@@ -272,7 +272,11 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel):
|
||||
sub.operator("object.vertex_group_select", text="Select")
|
||||
sub.operator("object.vertex_group_deselect", text="Deselect")
|
||||
|
||||
layout.prop(context.tool_settings, "vertex_group_weight", text="Weight")
|
||||
col = layout.column(align=True)
|
||||
col.use_property_split = True
|
||||
col.separator()
|
||||
col.prop(context.tool_settings, "vertex_group_weight", text="Weight")
|
||||
col.prop(context.tool_settings, "use_auto_normalize", text="Auto Normalize")
|
||||
|
||||
draw_attribute_warnings(context, layout, None)
|
||||
|
||||
|
||||
@@ -1341,21 +1341,14 @@ static void vgroup_levels_subset(Object *ob,
|
||||
static bool vgroup_normalize_all(Object *ob,
|
||||
const bool *vgroup_validmap,
|
||||
const int vgroup_tot,
|
||||
const int subset_count,
|
||||
const bool lock_active,
|
||||
ReportList *reports)
|
||||
{
|
||||
MDeformVert *dv, **dvert_array = nullptr;
|
||||
int i, dvert_tot = 0;
|
||||
const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1;
|
||||
|
||||
const bool use_vert_sel = vertex_group_use_vert_sel(ob);
|
||||
|
||||
if (subset_count == 0) {
|
||||
BKE_report(reports, RPT_ERROR, "No vertex groups to operate on");
|
||||
return false;
|
||||
}
|
||||
|
||||
vgroup_parray_alloc(static_cast<ID *>(ob->data), &dvert_array, &dvert_tot, use_vert_sel);
|
||||
|
||||
if (dvert_array) {
|
||||
@@ -1411,6 +1404,35 @@ static bool vgroup_normalize_all(Object *ob,
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the currently active vertex group is for a deform bone, normalize all
|
||||
* vertex groups that are for deform bones.
|
||||
*
|
||||
* \param lock_active: If true, the active vertex group will be left untouched,
|
||||
* and the remaining deform groups will be normalized to occupy the remaining
|
||||
* weight not used by it.
|
||||
*/
|
||||
static void vgroup_normalize_all_deform_if_active_is_deform(Object *ob,
|
||||
const bool lock_active,
|
||||
ReportList *reports)
|
||||
{
|
||||
int r_defgroup_tot = BKE_object_defgroup_count(ob);
|
||||
bool *defgroup_validmap = BKE_object_defgroup_validmap_get(ob, r_defgroup_tot);
|
||||
const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1;
|
||||
|
||||
/* Only auto-normalize if the active group is bone-deforming. */
|
||||
if (defgroup_validmap[def_nr] == true) {
|
||||
int subset_count, vgroup_tot;
|
||||
const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(
|
||||
ob, WT_VGROUP_BONE_DEFORM, &vgroup_tot, &subset_count);
|
||||
|
||||
vgroup_normalize_all(ob, vgroup_validmap, vgroup_tot, lock_active, reports);
|
||||
MEM_SAFE_FREE(vgroup_validmap);
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(defgroup_validmap);
|
||||
}
|
||||
|
||||
enum {
|
||||
VGROUP_TOGGLE,
|
||||
VGROUP_LOCK,
|
||||
@@ -2714,13 +2736,18 @@ void OBJECT_OT_vertex_group_remove(wmOperatorType *ot)
|
||||
/** \name Vertex Group Assign Operator
|
||||
* \{ */
|
||||
|
||||
static wmOperatorStatus vertex_group_assign_exec(bContext *C, wmOperator * /*op*/)
|
||||
static wmOperatorStatus vertex_group_assign_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
ToolSettings *ts = CTX_data_tool_settings(C);
|
||||
Object *ob = context_object(C);
|
||||
Scene &scene = *CTX_data_scene(C);
|
||||
|
||||
vgroup_assign_verts(ob, scene, ts->vgroup_weight);
|
||||
|
||||
if (ts->auto_normalize) {
|
||||
vgroup_normalize_all_deform_if_active_is_deform(ob, true, op->reports);
|
||||
}
|
||||
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
|
||||
|
||||
@@ -2818,6 +2845,11 @@ static wmOperatorStatus vertex_group_remove_from_exec(bContext *C, wmOperator *o
|
||||
}
|
||||
}
|
||||
|
||||
ToolSettings *ts = CTX_data_tool_settings(C);
|
||||
if (ts->auto_normalize) {
|
||||
vgroup_normalize_all_deform_if_active_is_deform(ob, false, op->reports);
|
||||
}
|
||||
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
|
||||
|
||||
@@ -3096,8 +3128,14 @@ static wmOperatorStatus vertex_group_normalize_all_exec(bContext *C, wmOperator
|
||||
const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type(
|
||||
ob, subset_type, &vgroup_tot, &subset_count);
|
||||
|
||||
changed = vgroup_normalize_all(
|
||||
ob, vgroup_validmap, vgroup_tot, subset_count, lock_active, op->reports);
|
||||
if (subset_count == 0) {
|
||||
BKE_report(op->reports, RPT_ERROR, "No vertex groups to operate on");
|
||||
changed = false;
|
||||
}
|
||||
else {
|
||||
changed = vgroup_normalize_all(ob, vgroup_validmap, vgroup_tot, lock_active, op->reports);
|
||||
}
|
||||
|
||||
MEM_freeN(vgroup_validmap);
|
||||
|
||||
if (changed) {
|
||||
|
||||
@@ -3272,7 +3272,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Weight Paint Auto-Normalize",
|
||||
"Ensure all bone-deforming vertex groups add up "
|
||||
"to 1.0 while weight painting");
|
||||
"to 1.0 while weight painting or assigning to vertices");
|
||||
RNA_def_property_update(prop, 0, "rna_Scene_update_active_object_data");
|
||||
|
||||
prop = RNA_def_property(srna, "use_lock_relative", PROP_BOOLEAN, PROP_NONE);
|
||||
|
||||
Reference in New Issue
Block a user