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:
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);
+ }
+ }
}
/** \} */