diff options
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r-- | source/blender/draw/intern/draw_cache_extract.h | 5 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_extract_mesh.c | 20 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_mesh.c | 49 |
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); + } + } } /** \} */ |