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
path: root/source
diff options
context:
space:
mode:
authorAlexander Gavrilov <angavrilov@gmail.com>2018-09-23 20:41:10 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2018-09-25 18:44:57 +0300
commitaf998b40a0d1cd1615ab836c6214523169d4dd42 (patch)
tree1c2a05cf7fa7ccf7b35e8501eba5a99ab5e51071 /source
parentbd51cada8db64e45cabca66cd61438c1ae2bdf25 (diff)
Implement correct drawing of advanced Weight display features.
This adds existing behavior from calc_weightpaint_vert_array that was missing from the new rendering code: - No selected Vertex Group displays as a solid pink color. - Zero weight displays as alert color depending on Options. - Multipaint mode correctly displays collective weight. In order to properly implement this variety, a data structure holding all relevant parameters is introduced. Reviewers: fclem, campbellbarton Subscribers: jbakker Differential Revision: https://developer.blender.org/D3722
Diffstat (limited to 'source')
-rw-r--r--source/blender/draw/intern/draw_cache.c43
-rw-r--r--source/blender/draw/intern/draw_cache.h2
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h25
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c161
-rw-r--r--source/blender/draw/modes/edit_mesh_mode.c2
-rw-r--r--source/blender/draw/modes/paint_weight_mode.c2
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c1
7 files changed, 198 insertions, 38 deletions
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index c4214b436f1..abc62c7e175 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -37,11 +37,16 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "BLI_listbase.h"
+
+#include "BKE_object_deform.h"
#include "GPU_batch.h"
#include "GPU_batch_presets.h"
#include "GPU_batch_utils.h"
+#include "MEM_guardedalloc.h"
+
#include "draw_cache.h"
#include "draw_cache_impl.h"
@@ -2950,12 +2955,46 @@ GPUBatch *DRW_cache_mesh_loose_edges_get(Object *ob)
return DRW_mesh_batch_cache_get_loose_edges_with_normals(me);
}
-GPUBatch *DRW_cache_mesh_surface_weights_get(Object *ob)
+GPUBatch *DRW_cache_mesh_surface_weights_get(Object *ob, ToolSettings *ts, bool paint_mode)
{
BLI_assert(ob->type == OB_MESH);
Mesh *me = ob->data;
- return DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(me, ob->actdef - 1);
+
+ /* Extract complete vertex weight group selection state and mode flags. */
+ VertexWeightSelection vwsel;
+ memset(&vwsel, 0, sizeof(vwsel));
+
+ vwsel.defgroup_active = ob->actdef - 1;
+ vwsel.defgroup_tot = BLI_listbase_count(&ob->defbase);
+
+ vwsel.alert_mode = ts->weightuser;
+
+ if (paint_mode && ts->multipaint) {
+ /* Multipaint needs to know all selected bones, not just the active group.
+ * This is actually a relatively expensive operation, but caching would be difficult. */
+ vwsel.defgroup_sel = BKE_object_defgroup_selected_get(ob, vwsel.defgroup_tot, &vwsel.defgroup_sel_tot);
+
+ if (vwsel.defgroup_sel_tot > 1) {
+ vwsel.flags |= VWEIGHT_MULTIPAINT | (ts->auto_normalize ? VWEIGHT_AUTO_NORMALIZE : 0);
+
+ if (me->editflag & ME_EDIT_MIRROR_X) {
+ BKE_object_defgroup_mirror_selection(ob, vwsel.defgroup_tot, vwsel.defgroup_sel, vwsel.defgroup_sel, &vwsel.defgroup_sel_tot);
+ }
+ }
+ /* With only one selected bone Multipaint reverts to regular mode. */
+ else {
+ vwsel.defgroup_sel_tot = 0;
+ MEM_SAFE_FREE(vwsel.defgroup_sel);
+ }
+ }
+
+ /* Generate the weight data using the selection. */
+ GPUBatch *batch = DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(me, &vwsel);
+
+ DRW_vweight_selection_clear(&vwsel);
+
+ return batch;
}
GPUBatch *DRW_cache_mesh_surface_vert_colors_get(Object *ob)
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index 08c93010700..edd1362bf9b 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -135,7 +135,7 @@ struct GPUBatch *DRW_cache_mesh_wire_outline_get(struct Object *ob);
struct GPUBatch *DRW_cache_mesh_edge_detection_get(struct Object *ob, bool *r_is_manifold);
struct GPUBatch *DRW_cache_mesh_surface_get(struct Object *ob);
struct GPUBatch *DRW_cache_mesh_loose_edges_get(struct Object *ob);
-struct GPUBatch *DRW_cache_mesh_surface_weights_get(struct Object *ob);
+struct GPUBatch *DRW_cache_mesh_surface_weights_get(struct Object *ob, struct ToolSettings *ts, bool paint_mode);
struct GPUBatch *DRW_cache_mesh_surface_vert_colors_get(struct Object *ob);
struct GPUBatch *DRW_cache_mesh_surface_verts_get(struct Object *ob);
struct GPUBatch *DRW_cache_mesh_edges_get(struct Object *ob);
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index d601bfc3a3e..444d5aeb12d 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -96,8 +96,29 @@ struct GPUBatch *DRW_lattice_batch_cache_get_all_edges(struct Lattice *lt, bool
struct GPUBatch *DRW_lattice_batch_cache_get_all_verts(struct Lattice *lt);
struct GPUBatch *DRW_lattice_batch_cache_get_overlay_verts(struct Lattice *lt);
-/* Mesh */
+/* Vertex Group Selection and display options */
+typedef struct VertexWeightSelection {
+ int defgroup_active;
+ int defgroup_tot;
+
+ short flags;
+ char alert_mode;
+
+ /* Set of all selected bones for Multipaint. */
+ int defgroup_sel_tot;
+ bool *defgroup_sel;
+} VertexWeightSelection;
+
+enum {
+ VWEIGHT_MULTIPAINT = (1 << 0),
+ VWEIGHT_AUTO_NORMALIZE = (1 << 1),
+};
+void DRW_vweight_selection_clear(struct VertexWeightSelection *sel);
+void DRW_vweight_selection_copy(struct VertexWeightSelection *sel, const struct VertexWeightSelection *src);
+bool DRW_vweight_selection_compare(const struct VertexWeightSelection *a, const struct VertexWeightSelection *b);
+
+/* Mesh */
struct GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(
struct Mesh *me, struct GPUMaterial **gpumat_array, uint gpumat_array_len,
char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count);
@@ -109,7 +130,7 @@ struct GPUBatch *DRW_mesh_batch_cache_get_weight_overlay_verts(struct Mesh *me);
struct GPUBatch *DRW_mesh_batch_cache_get_all_edges(struct Mesh *me);
struct GPUBatch *DRW_mesh_batch_cache_get_all_triangles(struct Mesh *me);
struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals(struct Mesh *me);
-struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(struct Mesh *me, int defgroup);
+struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(struct Mesh *me, const struct VertexWeightSelection *vwsel);
struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(struct Mesh *me);
struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me, bool use_hide, uint select_id_offset);
struct GPUBatch *DRW_mesh_batch_cache_get_triangles_with_select_mask(struct Mesh *me, bool use_hide);
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 75aaac23f75..8fef7675587 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -34,6 +34,7 @@
#include "BLI_utildefines.h"
#include "BLI_math_vector.h"
#include "BLI_math_bits.h"
+#include "BLI_math_color.h"
#include "BLI_string.h"
#include "BLI_alloca.h"
#include "BLI_edgehash.h"
@@ -1101,13 +1102,67 @@ static void rgb_from_weight(float r_rgb[3], const float weight)
}
}
+static void vertex_weight_color(float vweight[3], float weight, bool show_alert_color)
+{
+ CLAMP(weight, 0.0f, 1.0f);
+
+ if (show_alert_color) {
+ bTheme *theme = U.themes.first;
+
+ rgb_uchar_to_float(vweight, (unsigned char*)theme->tv3d.vertex_unreferenced);
+ }
+ else if (U.flag & USER_CUSTOM_RANGE) {
+ BKE_colorband_evaluate(&U.coba_weight, weight, vweight);
+ }
+ else {
+ rgb_from_weight(vweight, weight);
+ }
+}
+
+static void evaluate_vertex_weight(float vweight[3], const MDeformVert *dvert, const VertexWeightSelection *vwsel)
+{
+ float input = 0.0f;
+ bool show_alert_color = false;
+
+ if (vwsel->flags & VWEIGHT_MULTIPAINT) {
+ /* Multi-Paint feature */
+ input = BKE_defvert_multipaint_collective_weight(
+ dvert, vwsel->defgroup_tot, vwsel->defgroup_sel, vwsel->defgroup_sel_tot, (vwsel->flags & VWEIGHT_AUTO_NORMALIZE) != 0);
+
+ /* make it black if the selected groups have no weight on a vertex */
+ if (input == 0.0f) {
+ show_alert_color = true;
+ }
+ }
+ else {
+ /* default, non tricky behavior */
+ input = defvert_find_weight(dvert, vwsel->defgroup_active);
+
+ if (input == 0.0f) {
+ switch (vwsel->alert_mode) {
+ case OB_DRAW_GROUPUSER_ACTIVE:
+ show_alert_color = true;
+ break;
+
+ case OB_DRAW_GROUPUSER_ALL:
+ show_alert_color = defvert_is_weight_zero(dvert, vwsel->defgroup_tot);
+ break;
+ }
+ }
+ }
+
+ vertex_weight_color(vweight, input, show_alert_color);
+}
+
+/* color-code for missing data (full brightness isn't easy on the eye). */
+static const unsigned char missing_weight_color[3] = { 0xa0, 0x00, 0xa0 };
/** Ensure #MeshRenderData.vert_weight_color */
-static void mesh_render_data_ensure_vert_weight_color(MeshRenderData *rdata, const int defgroup)
+static void mesh_render_data_ensure_vert_weight_color(MeshRenderData *rdata, const VertexWeightSelection *vwsel)
{
float (*vweight)[3] = rdata->vert_weight_color;
if (vweight == NULL) {
- if (defgroup == -1) {
+ if (vwsel->defgroup_active == -1) {
goto fallback;
}
@@ -1125,13 +1180,7 @@ static void mesh_render_data_ensure_vert_weight_color(MeshRenderData *rdata, con
vweight = rdata->vert_weight_color = MEM_mallocN(sizeof(*vweight) * rdata->vert_len, __func__);
BM_ITER_MESH_INDEX(eve, &viter, bm, BM_VERT, i) {
const MDeformVert *dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
- float weight = defvert_find_weight(dvert, defgroup);
- if (U.flag & USER_CUSTOM_RANGE) {
- BKE_colorband_evaluate(&U.coba_weight, weight, vweight[i]);
- }
- else {
- rgb_from_weight(vweight[i], weight);
- }
+ evaluate_vertex_weight(vweight[i], dvert, vwsel);
}
}
else {
@@ -1141,23 +1190,26 @@ static void mesh_render_data_ensure_vert_weight_color(MeshRenderData *rdata, con
vweight = rdata->vert_weight_color = MEM_mallocN(sizeof(*vweight) * rdata->vert_len, __func__);
for (int i = 0; i < rdata->vert_len; i++) {
- float weight = defvert_find_weight(&rdata->dvert[i], defgroup);
- if (U.flag & USER_CUSTOM_RANGE) {
- BKE_colorband_evaluate(&U.coba_weight, weight, vweight[i]);
- }
- else {
- rgb_from_weight(vweight[i], weight);
- }
+ evaluate_vertex_weight(vweight[i], &rdata->dvert[i], vwsel);
}
}
}
return;
fallback:
- vweight = rdata->vert_weight_color = MEM_callocN(sizeof(*vweight) * rdata->vert_len, __func__);
+ vweight = rdata->vert_weight_color = MEM_mallocN(sizeof(*vweight) * rdata->vert_len, __func__);
+
+ float error_color[3];
+
+ if ((vwsel->defgroup_active < 0) && (vwsel->defgroup_tot > 0)) {
+ rgb_uchar_to_float(error_color, missing_weight_color);
+ }
+ else {
+ vertex_weight_color(error_color, 0.0f, vwsel->alert_mode != OB_DRAW_GROUPUSER_NONE);
+ }
for (int i = 0; i < rdata->vert_len; i++) {
- vweight[i][2] = 0.5f;
+ copy_v3_v3(vweight[i], error_color);
}
}
@@ -1537,6 +1589,47 @@ static void add_overlay_loose_vert(
/** \} */
+/* ---------------------------------------------------------------------- */
+
+/** \name Vertex Group Selection
+ * \{ */
+
+/** Reset the selection structure, deallocating heap memory as appropriate. */
+void DRW_vweight_selection_clear(struct VertexWeightSelection *sel)
+{
+ MEM_SAFE_FREE(sel->defgroup_sel);
+
+ memset(sel, 0, sizeof(VertexWeightSelection));
+
+ sel->defgroup_active = -1;
+}
+
+/** Copy selection data from one structure to another, including heap memory. */
+void DRW_vweight_selection_copy(struct VertexWeightSelection *sel, const struct VertexWeightSelection *src)
+{
+ MEM_SAFE_FREE(sel->defgroup_sel);
+
+ memcpy(sel, src, sizeof(VertexWeightSelection));
+
+ if (src->defgroup_sel) {
+ sel->defgroup_sel = MEM_dupallocN(src->defgroup_sel);
+ }
+}
+
+/** Compare two selection structures. */
+bool DRW_vweight_selection_compare(const struct VertexWeightSelection *a, const struct VertexWeightSelection *b)
+{
+ return a->defgroup_active == b->defgroup_active &&
+ a->defgroup_tot == b->defgroup_tot &&
+ a->flags == b->flags &&
+ a->alert_mode == b->alert_mode &&
+ a->defgroup_sel_tot == b->defgroup_sel_tot &&
+ ((!a->defgroup_sel && !b->defgroup_sel) ||
+ (a->defgroup_sel && b->defgroup_sel &&
+ memcmp(a->defgroup_sel, b->defgroup_sel, a->defgroup_tot * sizeof(bool)) == 0));
+}
+
+/** \} */
/* ---------------------------------------------------------------------- */
@@ -1646,7 +1739,8 @@ typedef struct MeshBatchCache {
int vert_len;
int mat_len;
bool is_editmode;
- int vertex_group_index;
+
+ VertexWeightSelection vertex_weight_selection;
/* XXX, only keep for as long as sculpt mode uses shaded drawing. */
bool is_sculpt_points_tag;
@@ -1722,7 +1816,8 @@ static void mesh_batch_cache_init(Mesh *me)
cache->is_maybe_dirty = false;
cache->is_dirty = false;
- cache->vertex_group_index = -1;
+
+ DRW_vweight_selection_clear(&cache->vertex_weight_selection);
}
static MeshBatchCache *mesh_batch_cache_get(Mesh *me)
@@ -1734,13 +1829,13 @@ static MeshBatchCache *mesh_batch_cache_get(Mesh *me)
return me->runtime.batch_cache;
}
-static MeshBatchCache *mesh_batch_cache_get__check_vertex_group(Mesh *me, int defgroup)
+static void mesh_batch_cache_check_vertex_group(MeshBatchCache *cache, const VertexWeightSelection *vwsel)
{
- MeshBatchCache *cache = mesh_batch_cache_get(me);
- if (cache->vertex_group_index != defgroup) {
- cache->is_dirty = true;
+ if (!DRW_vweight_selection_compare(&cache->vertex_weight_selection, vwsel)) {
+ GPU_BATCH_DISCARD_SAFE(cache->triangles_with_weights);
+
+ DRW_vweight_selection_clear(&cache->vertex_weight_selection);
}
- return mesh_batch_cache_get(me);
}
static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache)
@@ -1918,6 +2013,7 @@ static void mesh_batch_cache_clear(Mesh *me)
GPU_BATCH_DISCARD_SAFE(cache->texpaint_triangles_single);
+ DRW_vweight_selection_clear(&cache->vertex_weight_selection);
}
void DRW_mesh_batch_cache_free(Mesh *me)
@@ -2674,7 +2770,7 @@ static GPUVertBuf *mesh_create_verts_select_id(
}
static GPUVertBuf *mesh_create_tri_weights(
- MeshRenderData *rdata, bool use_hide, int defgroup)
+ MeshRenderData *rdata, bool use_hide, const VertexWeightSelection *vwsel)
{
BLI_assert(
rdata->types &
@@ -2697,7 +2793,7 @@ static GPUVertBuf *mesh_create_tri_weights(
int vbo_len_used = 0;
GPU_vertbuf_data_alloc(vbo, vbo_len_capacity);
- mesh_render_data_ensure_vert_weight_color(rdata, defgroup);
+ mesh_render_data_ensure_vert_weight_color(rdata, vwsel);
const float (*vert_weight_color)[3] = rdata->vert_weight_color;
if (rdata->edit_bmesh) {
@@ -3866,9 +3962,11 @@ GPUBatch *DRW_mesh_batch_cache_get_loose_edges_with_normals(Mesh *me)
return cache->ledges_with_normals;
}
-GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(Mesh *me, int defgroup)
+GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(Mesh *me, const VertexWeightSelection *vwsel)
{
- MeshBatchCache *cache = mesh_batch_cache_get__check_vertex_group(me, defgroup);
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ mesh_batch_cache_check_vertex_group(cache, vwsel);
if (cache->triangles_with_weights == NULL) {
const bool use_hide = (me->editflag & (ME_EDIT_PAINT_VERT_SEL | ME_EDIT_PAINT_FACE_SEL)) != 0;
@@ -3877,8 +3975,9 @@ GPUBatch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(Mesh *me,
MeshRenderData *rdata = mesh_render_data_create(me, datatype);
cache->triangles_with_weights = GPU_batch_create_ex(
- GPU_PRIM_TRIS, mesh_create_tri_weights(rdata, use_hide, defgroup), NULL, GPU_BATCH_OWNS_VBO);
- cache->vertex_group_index = defgroup;
+ GPU_PRIM_TRIS, mesh_create_tri_weights(rdata, use_hide, vwsel), NULL, GPU_BATCH_OWNS_VBO);
+
+ DRW_vweight_selection_copy(&cache->vertex_weight_selection, vwsel);
GPUVertBuf *vbo_tris = use_hide ?
mesh_create_tri_pos_and_normals_visible_only(rdata) :
diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c
index 4cf99ef3c1e..3a2ad27bfa9 100644
--- a/source/blender/draw/modes/edit_mesh_mode.c
+++ b/source/blender/draw/modes/edit_mesh_mode.c
@@ -594,7 +594,7 @@ static void EDIT_MESH_cache_populate(void *vedata, Object *ob)
}
if (do_show_weight) {
- geom = DRW_cache_mesh_surface_weights_get(ob);
+ geom = DRW_cache_mesh_surface_weights_get(ob, tsettings, false);
DRW_shgroup_call_add(stl->g_data->fvcolor_shgrp, geom, ob->obmat);
}
diff --git a/source/blender/draw/modes/paint_weight_mode.c b/source/blender/draw/modes/paint_weight_mode.c
index c4608dfd397..3826e8af8fa 100644
--- a/source/blender/draw/modes/paint_weight_mode.c
+++ b/source/blender/draw/modes/paint_weight_mode.c
@@ -183,7 +183,7 @@ static void PAINT_WEIGHT_cache_populate(void *vedata, Object *ob)
struct GPUBatch *geom;
if (use_surface) {
- geom = DRW_cache_mesh_surface_weights_get(ob);
+ geom = DRW_cache_mesh_surface_weights_get(ob, draw_ctx->scene->toolsettings, true);
DRW_shgroup_call_add(stl->g_data->fweights_shgrp, geom, ob->obmat);
}
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 53c5da243fe..eaf212eabfe 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -3598,6 +3598,7 @@ static void rna_def_mesh(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_mirror_x", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_MIRROR_X);
RNA_def_property_ui_text(prop, "X Mirror", "X Axis mirror editing");
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_draw");
#if 0
prop = RNA_def_property(srna, "use_mirror_y", PROP_BOOLEAN, PROP_NONE);