[Bf-blender-cvs] [af998b40a0d] blender2.8: Implement correct drawing of advanced Weight display features.

Alexander Gavrilov noreply at git.blender.org
Tue Sep 25 17:56:32 CEST 2018


Commit: af998b40a0d1cd1615ab836c6214523169d4dd42
Author: Alexander Gavrilov
Date:   Sun Sep 23 20:41:10 2018 +0300
Branches: blender2.8
https://developer.blender.org/rBaf998b40a0d1cd1615ab836c6214523169d4dd42

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

===================================================================

M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache.h
M	source/blender/draw/intern/draw_cache_impl.h
M	source/blender/draw/intern/draw_cache_impl_mesh.c
M	source/blender/draw/modes/edit_mesh_mode.c
M	source/blender/draw/modes/paint_weight_mode.c
M	source/blender/makesrna/intern/rna_mesh.c

===================================================================

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 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list