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/draw
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/draw')
-rw-r--r--source/blender/draw/intern/draw_cache_extract.h5
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.c20
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c49
3 files changed, 65 insertions, 9 deletions
diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h
index 6226b5dcf7f..0e02b07e95b 100644
--- a/source/blender/draw/intern/draw_cache_extract.h
+++ b/source/blender/draw/intern/draw_cache_extract.h
@@ -34,12 +34,17 @@ typedef struct DRW_MeshWeightState {
/* Set of all selected bones for Multipaint. */
bool *defgroup_sel; /* [defgroup_len] */
int defgroup_sel_count;
+
+ /* Set of all locked and unlocked deform bones for Lock Relative mode. */
+ bool *defgroup_locked; /* [defgroup_len] */
+ bool *defgroup_unlocked; /* [defgroup_len] */
} DRW_MeshWeightState;
/* DRW_MeshWeightState.flags */
enum {
DRW_MESH_WEIGHT_STATE_MULTIPAINT = (1 << 0),
DRW_MESH_WEIGHT_STATE_AUTO_NORMALIZE = (1 << 1),
+ DRW_MESH_WEIGHT_STATE_LOCK_RELATIVE = (1 << 2),
};
typedef struct DRW_MeshCDMask {
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index b385facd9aa..274a5492533 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -2407,12 +2407,13 @@ static float evaluate_vertex_weight(const MDeformVert *dvert, const DRW_MeshWeig
float input = 0.0f;
if (wstate->flags & DRW_MESH_WEIGHT_STATE_MULTIPAINT) {
/* Multi-Paint feature */
- input = BKE_defvert_multipaint_collective_weight(
- dvert,
- wstate->defgroup_len,
- wstate->defgroup_sel,
- wstate->defgroup_sel_count,
- (wstate->flags & DRW_MESH_WEIGHT_STATE_AUTO_NORMALIZE) != 0);
+ bool is_normalized = (wstate->flags & (DRW_MESH_WEIGHT_STATE_AUTO_NORMALIZE |
+ DRW_MESH_WEIGHT_STATE_LOCK_RELATIVE));
+ input = BKE_defvert_multipaint_collective_weight(dvert,
+ wstate->defgroup_len,
+ wstate->defgroup_sel,
+ wstate->defgroup_sel_count,
+ is_normalized);
/* make it black if the selected groups have no weight on a vertex */
if (input == 0.0f) {
return -1.0f;
@@ -2435,6 +2436,13 @@ static float evaluate_vertex_weight(const MDeformVert *dvert, const DRW_MeshWeig
}
}
}
+
+ /* Lock-Relative: display the fraction of current weight vs total unlocked weight. */
+ if (wstate->flags & DRW_MESH_WEIGHT_STATE_LOCK_RELATIVE) {
+ input = BKE_defvert_lock_relative_weight(
+ input, dvert, wstate->defgroup_len, wstate->defgroup_locked, wstate->defgroup_unlocked);
+ }
+
CLAMP(input, 0.0f, 1.0f);
return input;
}
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 2e423c4dfe2..c89b6baa921 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -239,6 +239,8 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Mesh *me,
static void drw_mesh_weight_state_clear(struct DRW_MeshWeightState *wstate)
{
MEM_SAFE_FREE(wstate->defgroup_sel);
+ MEM_SAFE_FREE(wstate->defgroup_locked);
+ MEM_SAFE_FREE(wstate->defgroup_unlocked);
memset(wstate, 0, sizeof(*wstate));
@@ -250,12 +252,26 @@ static void drw_mesh_weight_state_copy(struct DRW_MeshWeightState *wstate_dst,
const struct DRW_MeshWeightState *wstate_src)
{
MEM_SAFE_FREE(wstate_dst->defgroup_sel);
+ MEM_SAFE_FREE(wstate_dst->defgroup_locked);
+ MEM_SAFE_FREE(wstate_dst->defgroup_unlocked);
memcpy(wstate_dst, wstate_src, sizeof(*wstate_dst));
if (wstate_src->defgroup_sel) {
wstate_dst->defgroup_sel = MEM_dupallocN(wstate_src->defgroup_sel);
}
+ if (wstate_src->defgroup_locked) {
+ wstate_dst->defgroup_locked = MEM_dupallocN(wstate_src->defgroup_locked);
+ }
+ if (wstate_src->defgroup_unlocked) {
+ wstate_dst->defgroup_unlocked = MEM_dupallocN(wstate_src->defgroup_unlocked);
+ }
+}
+
+static bool drw_mesh_flags_equal(const bool *array1, const bool *array2, int size)
+{
+ return ((!array1 && !array2) ||
+ (array1 && array2 && memcmp(array1, array2, size * sizeof(bool)) == 0));
}
/** Compare two selection structures. */
@@ -265,9 +281,9 @@ static bool drw_mesh_weight_state_compare(const struct DRW_MeshWeightState *a,
return a->defgroup_active == b->defgroup_active && a->defgroup_len == b->defgroup_len &&
a->flags == b->flags && a->alert_mode == b->alert_mode &&
a->defgroup_sel_count == b->defgroup_sel_count &&
- ((!a->defgroup_sel && !b->defgroup_sel) ||
- (a->defgroup_sel && b->defgroup_sel &&
- memcmp(a->defgroup_sel, b->defgroup_sel, a->defgroup_len * sizeof(bool)) == 0));
+ drw_mesh_flags_equal(a->defgroup_sel, b->defgroup_sel, a->defgroup_len) &&
+ drw_mesh_flags_equal(a->defgroup_locked, b->defgroup_locked, a->defgroup_len) &&
+ drw_mesh_flags_equal(a->defgroup_unlocked, b->defgroup_unlocked, a->defgroup_len);
}
static void drw_mesh_weight_state_extract(Object *ob,
@@ -308,6 +324,33 @@ static void drw_mesh_weight_state_extract(Object *ob,
MEM_SAFE_FREE(wstate->defgroup_sel);
}
}
+
+ if (paint_mode && ts->wpaint_lock_relative) {
+ /* Set of locked vertex groups for the lock relative mode. */
+ wstate->defgroup_locked = BKE_object_defgroup_lock_flags_get(ob, wstate->defgroup_len);
+ wstate->defgroup_unlocked = BKE_object_defgroup_validmap_get(ob, wstate->defgroup_len);
+
+ /* Check that a deform group is active, and none of selected groups are locked. */
+ if (BKE_object_defgroup_check_lock_relative(
+ wstate->defgroup_locked, wstate->defgroup_unlocked, wstate->defgroup_active) &&
+ BKE_object_defgroup_check_lock_relative_multi(wstate->defgroup_len,
+ wstate->defgroup_locked,
+ wstate->defgroup_sel,
+ wstate->defgroup_sel_count)) {
+ wstate->flags |= DRW_MESH_WEIGHT_STATE_LOCK_RELATIVE;
+
+ /* Compute the set of locked and unlocked deform vertex groups. */
+ BKE_object_defgroup_split_locked_validmap(wstate->defgroup_len,
+ wstate->defgroup_locked,
+ wstate->defgroup_unlocked,
+ wstate->defgroup_locked, /* out */
+ wstate->defgroup_unlocked);
+ }
+ else {
+ MEM_SAFE_FREE(wstate->defgroup_unlocked);
+ MEM_SAFE_FREE(wstate->defgroup_locked);
+ }
+ }
}
/** \} */