[Bf-blender-cvs] [084bf7daee3] master: Weight Paint: Implement a new Lock-Relative mode.

Alexander Gavrilov noreply at git.blender.org
Wed Mar 18 09:55:57 CET 2020


Commit: 084bf7daee3ebcd57696f5b2a0c83db1b1f3d472
Author: Alexander Gavrilov
Date:   Sun Oct 7 18:25:51 2018 +0300
Branches: master
https://developer.blender.org/rB084bf7daee3ebcd57696f5b2a0c83db1b1f3d472

Weight Paint: Implement a new Lock-Relative mode.

This check box alters how weights are displayed and painted,
similar to Multi Paint, but in a different way. Specifically,
weights are presented as if all locked vertex groups were
deleted, and the remaining deform groups normalized.

The new feature is intended for use when balancing weights within
a group of bones while all others are locked. Enabling the option
presents weight as if the locked bones didn't exist, and their
weight was proportionally redistributed to the editable bones.

Conversely, the Multi-Paint feature allows balancing a group of
bones as a whole against all unselected bones, while ignoring
weight distribution within the selected group.

This mode also allows temporarily viewing non-normalized weights
as if they were normalized, without actually changing the values.

Differential Revision: https://developer.blender.org/D3837

===================================================================

M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/blenkernel/BKE_deform.h
M	source/blender/blenkernel/BKE_object_deform.h
M	source/blender/blenkernel/intern/deform.c
M	source/blender/blenkernel/intern/object_deform.c
M	source/blender/draw/intern/draw_cache_extract.h
M	source/blender/draw/intern/draw_cache_extract_mesh.c
M	source/blender/draw/intern/draw_cache_impl_mesh.c
M	source/blender/editors/sculpt_paint/paint_vertex.c
M	source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
M	source/blender/makesdna/DNA_scene_types.h
M	source/blender/makesrna/intern/rna_scene.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 9ad339b418c..758f0686bb4 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -1058,6 +1058,7 @@ class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel):
         col = layout.column()
 
         col.prop(tool_settings, "use_auto_normalize", text="Auto Normalize")
+        col.prop(tool_settings, "use_lock_relative", text="Lock-Relative")
         col.prop(tool_settings, "use_multipaint", text="Multi-Paint")
 
         col.prop(wpaint, "use_group_restrict")
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index cdfbd45bb5f..c86b877b575 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -67,11 +67,24 @@ float BKE_defvert_array_find_weight_safe(const struct MDeformVert *dvert,
                                          const int index,
                                          const int defgroup);
 
+float BKE_defvert_total_selected_weight(const struct MDeformVert *dv,
+                                        int defbase_tot,
+                                        const bool *defbase_sel);
+
 float BKE_defvert_multipaint_collective_weight(const struct MDeformVert *dv,
                                                int defbase_tot,
                                                const bool *defbase_sel,
                                                int defbase_tot_sel,
-                                               bool do_autonormalize);
+                                               bool is_normalized);
+
+float BKE_defvert_calc_lock_relative_weight(float weight,
+                                            float locked_weight,
+                                            float unlocked_weight);
+float BKE_defvert_lock_relative_weight(float weight,
+                                       const struct MDeformVert *dv,
+                                       int defbase_tot,
+                                       const bool *defbase_locked,
+                                       const bool *defbase_unlocked);
 
 void BKE_defvert_copy(struct MDeformVert *dvert_dst, const struct MDeformVert *dvert_src);
 void BKE_defvert_copy_subset(struct MDeformVert *dvert_dst,
diff --git a/source/blender/blenkernel/BKE_object_deform.h b/source/blender/blenkernel/BKE_object_deform.h
index f5283ef8405..410cb862aa7 100644
--- a/source/blender/blenkernel/BKE_object_deform.h
+++ b/source/blender/blenkernel/BKE_object_deform.h
@@ -76,6 +76,16 @@ bool *BKE_object_defgroup_selected_get(struct Object *ob,
                                        int defbase_tot,
                                        int *r_dg_flags_sel_tot);
 
+bool BKE_object_defgroup_check_lock_relative(const bool *lock_flags,
+                                             const bool *validmap,
+                                             int index);
+bool BKE_object_defgroup_check_lock_relative_multi(int defbase_tot,
+                                                   const bool *lock_flags,
+                                                   const bool *selected,
+                                                   int sel_tot);
+void BKE_object_defgroup_split_locked_validmap(
+    int defbase_tot, const bool *locked, const bool *deform, bool *r_locked, bool *r_unlocked);
+
 void BKE_object_defgroup_mirror_selection(struct Object *ob,
                                           int defbase_tot,
                                           const bool *selection,
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 18064fd95d4..3b7162b122e 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -835,26 +835,21 @@ bool BKE_defvert_is_weight_zero(const struct MDeformVert *dvert, const int defgr
 }
 
 /**
- * \return The representative weight of a multipaint group, used for
- * viewport colors and actual painting.
- *
- * Result equal to sum of weights with auto normalize, and average otherwise.
- * Value is not clamped, since painting relies on multiplication being always
- * commutative with the collective weight function.
+ * \return The total weight in all groups marked in the selection mask.
  */
-float BKE_defvert_multipaint_collective_weight(const struct MDeformVert *dv,
-                                               int defbase_tot,
-                                               const bool *defbase_sel,
-                                               int defbase_tot_sel,
-                                               bool do_autonormalize)
+float BKE_defvert_total_selected_weight(const struct MDeformVert *dv,
+                                        int defbase_tot,
+                                        const bool *defbase_sel)
 {
   int i;
   float total = 0.0f;
   const MDeformWeight *dw = dv->dw;
 
+  if (defbase_sel == NULL) {
+    return total;
+  }
+
   for (i = dv->totweight; i != 0; i--, dw++) {
-    /* in multipaint, get the average if auto normalize is inactive
-     * get the sum if it is active */
     if (dw->def_nr < defbase_tot) {
       if (defbase_sel[dw->def_nr]) {
         total += dw->weight;
@@ -862,13 +857,90 @@ float BKE_defvert_multipaint_collective_weight(const struct MDeformVert *dv,
     }
   }
 
-  if (do_autonormalize == false) {
+  return total;
+}
+
+/**
+ * \return The representative weight of a multipaint group, used for
+ * viewport colors and actual painting.
+ *
+ * Result equal to sum of weights with auto normalize, and average otherwise.
+ * Value is not clamped, since painting relies on multiplication being always
+ * commutative with the collective weight function.
+ */
+float BKE_defvert_multipaint_collective_weight(const struct MDeformVert *dv,
+                                               int defbase_tot,
+                                               const bool *defbase_sel,
+                                               int defbase_tot_sel,
+                                               bool is_normalized)
+{
+  float total = BKE_defvert_total_selected_weight(dv, defbase_tot, defbase_sel);
+
+  /* in multipaint, get the average if auto normalize is inactive
+   * get the sum if it is active */
+  if (!is_normalized) {
     total /= defbase_tot_sel;
   }
 
   return total;
 }
 
+/**
+ * Computes the display weight for the lock relative weight paint mode.
+ *
+ * @return weight divided by 1-locked_weight with division by zero check
+ */
+float BKE_defvert_calc_lock_relative_weight(float weight,
+                                            float locked_weight,
+                                            float unlocked_weight)
+{
+  /* First try normalizing unlocked weights. */
+  if (unlocked_weight > 0.0f) {
+    return weight / unlocked_weight;
+  }
+
+  /* If no unlocked weight exists, take locked into account. */
+  if (locked_weight <= 0.0f) {
+    return weight;
+  }
+
+  /* handle division by zero */
+  if (locked_weight >= 1.0f) {
+    if (weight != 0.0f) {
+      return 1.0f;
+    }
+    else {
+      /* resolve 0/0 to 0 */
+      return 0.0f;
+    }
+  }
+
+  /* non-degenerate division */
+  return weight / (1.0f - locked_weight);
+}
+
+/**
+ * Computes the display weight for the lock relative weight paint mode, using weight data.
+ *
+ * @return weight divided by unlocked, or 1-locked_weight with division by zero check
+ */
+float BKE_defvert_lock_relative_weight(float weight,
+                                       const struct MDeformVert *dv,
+                                       int defbase_tot,
+                                       const bool *defbase_locked,
+                                       const bool *defbase_unlocked)
+{
+  float unlocked = BKE_defvert_total_selected_weight(dv, defbase_tot, defbase_unlocked);
+
+  if (unlocked > 0.0f) {
+    return weight / unlocked;
+  }
+
+  float locked = BKE_defvert_total_selected_weight(dv, defbase_tot, defbase_locked);
+
+  return BKE_defvert_calc_lock_relative_weight(weight, locked, unlocked);
+}
+
 /* -------------------------------------------------------------------- */
 /** \name Defvert Array functions
  * \{ */
diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c
index 00be25d5210..573573f20ed 100644
--- a/source/blender/blenkernel/intern/object_deform.c
+++ b/source/blender/blenkernel/intern/object_deform.c
@@ -693,6 +693,72 @@ bool *BKE_object_defgroup_selected_get(Object *ob, int defbase_tot, int *r_dg_fl
   return dg_selection;
 }
 
+/**
+ * Checks if the lock relative mode is applicable.
+ *
+ * \return true if an unlocked deform group is active.
+ */
+bool BKE_object_defgroup_check_lock_relative(const bool *lock_flags,
+                                             const bool *validmap,
+                                             int index)
+{
+  return validmap && validmap[index] && !(lock_flags && lock_flags[index]);
+}
+
+/**
+ * Additional check for whether the lock relative mode is applicable in multipaint mode.
+ *
+ * @return true if none of the selected groups are locked.
+ */
+bool BKE_object_defgroup_check_lock_relative_multi(int defbase_tot,
+                                                   const bool *lock_flags,
+                                                   const bool *selected,
+                                                   int sel_tot)
+{
+  if (lock_flags == NULL) {
+    return true;
+  }
+
+  if (selected == NULL || sel_tot <= 1) {
+    return true;
+  }
+
+  for (int i = 0; i < defbase_tot; i++) {
+    if (selected[i] && lock_flags[i]) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+/**
+ * Takes a pair of boolean masks of all locked and all deform groups, and computes
+ * a pair of masks for locked deform and unlocked deform groups. Output buffers may
+ * reuse the input ones.
+ */
+void BKE_object_defgroup_split_locked_validmap(
+    int defbase_tot, const bool *locked, const bool *deform, bool *r_locked, bool *r_unlocked)
+{
+  if (!locked) {
+    if 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list