Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Gavrilov <angavrilov@gmail.com>2018-10-07 18:25:51 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2020-03-18 11:55:44 +0300
commit084bf7daee3ebcd57696f5b2a0c83db1b1f3d472 (patch)
treee5f37d2e47d11a23730d90afb60f7cac633e0f8c /source/blender/blenkernel/intern/deform.c
parent82c51d0edbab45f014b4d0b4c0a96c000c46e232 (diff)
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
Diffstat (limited to 'source/blender/blenkernel/intern/deform.c')
-rw-r--r--source/blender/blenkernel/intern/deform.c100
1 files changed, 86 insertions, 14 deletions
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
* \{ */