[Bf-blender-cvs] [26fc6c71c4] blender2.8: Edit Mode overlays: separate multiple shaders for loose edges and verts

Clément Foucault noreply at git.blender.org
Thu Mar 2 01:10:42 CET 2017


Commit: 26fc6c71c411e9ba3650a8f5dbb16167a528f984
Author: Clément Foucault
Date:   Wed Mar 1 14:07:04 2017 +0100
Branches: blender2.8
https://developer.blender.org/rB26fc6c71c411e9ba3650a8f5dbb16167a528f984

Edit Mode overlays: separate multiple shaders for loose edges and verts

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

M	source/blender/blenkernel/BKE_mesh_render.h
M	source/blender/blenkernel/intern/mesh_render.c
M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache.h
M	source/blender/draw/intern/draw_mode_pass.c
M	source/blender/draw/intern/draw_mode_pass.h
M	source/blender/draw/modes/edit_mesh_mode.c
M	source/blender/editors/space_view3d/drawobject.c
M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/GPU_shader.h
M	source/blender/gpu/intern/gpu_shader.c
A	source/blender/gpu/shaders/gpu_shader_edit_overlay_geom_edge.glsl
R083	source/blender/gpu/shaders/gpu_shader_edit_overlay_geom.glsl	source/blender/gpu/shaders/gpu_shader_edit_overlay_geom_tri.glsl
A	source/blender/gpu/shaders/gpu_shader_edit_overlay_geom_vert.glsl

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

diff --git a/source/blender/blenkernel/BKE_mesh_render.h b/source/blender/blenkernel/BKE_mesh_render.h
index f4e322fca6..0370426d41 100644
--- a/source/blender/blenkernel/BKE_mesh_render.h
+++ b/source/blender/blenkernel/BKE_mesh_render.h
@@ -40,6 +40,8 @@ struct Batch *BKE_mesh_batch_cache_get_all_triangles(struct Mesh *me);
 struct Batch *BKE_mesh_batch_cache_get_triangles_with_normals(struct Mesh *me);
 struct Batch *BKE_mesh_batch_cache_get_all_verts(struct Mesh *me);
 struct Batch *BKE_mesh_batch_cache_get_fancy_edges(struct Mesh *me);
-struct Batch *BKE_mesh_batch_cache_get_overlay_edges(struct Mesh *me);
+struct Batch *BKE_mesh_batch_cache_get_overlay_triangles(struct Mesh *me);
+struct Batch *BKE_mesh_batch_cache_get_overlay_loose_edges(struct Mesh *me);
+struct Batch *BKE_mesh_batch_cache_get_overlay_loose_verts(struct Mesh *me);
 
 #endif /* __BKE_MESH_RENDER_H__ */
diff --git a/source/blender/blenkernel/intern/mesh_render.c b/source/blender/blenkernel/intern/mesh_render.c
index 2e9ea90792..9488b80f20 100644
--- a/source/blender/blenkernel/intern/mesh_render.c
+++ b/source/blender/blenkernel/intern/mesh_render.c
@@ -123,15 +123,11 @@ typedef struct MeshRenderData {
 
 enum {
 	MR_DATATYPE_VERT       = 1 << 0,
-	MR_DATATYPE_LOOSE_VERT = 1 << 1,
-	MR_DATATYPE_EDGE       = 1 << 2,
-	MR_DATATYPE_LOOSE_EDGE = 1 << 3,
-	MR_DATATYPE_LOOPTRI    = 1 << 4,
-	MR_DATATYPE_LOOP       = 1 << 5,
-	MR_DATATYPE_POLY       = 1 << 6,
-	MR_DATATYPE_ACTIVE     = 1 << 7,
-	MR_DATATYPE_CREASE     = 1 << 8,
-	MR_DATATYPE_BWEIGHT    = 1 << 9,
+	MR_DATATYPE_EDGE       = 1 << 1,
+	MR_DATATYPE_LOOPTRI    = 1 << 2,
+	MR_DATATYPE_LOOP       = 1 << 3,
+	MR_DATATYPE_POLY       = 1 << 4,
+	MR_DATATYPE_OVERLAY    = 1 << 5,
 };
 
 static MeshRenderData *mesh_render_data_create(Mesh *me, const int types)
@@ -146,11 +142,11 @@ static MeshRenderData *mesh_render_data_create(Mesh *me, const int types)
 		mrdata->edit_bmesh = embm;
 
 		int bm_ensure_types = 0;
-		if (types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOSE_VERT)) {
+		if (types & (MR_DATATYPE_VERT)) {
 			mrdata->totvert = bm->totvert;
 			bm_ensure_types |= BM_VERT;
 		}
-		if (types & (MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_EDGE)) {
+		if (types & (MR_DATATYPE_EDGE)) {
 			mrdata->totedge = bm->totedge;
 			bm_ensure_types |= BM_EDGE;
 		}
@@ -166,72 +162,56 @@ static MeshRenderData *mesh_render_data_create(Mesh *me, const int types)
 			mrdata->totpoly = bm->totface;
 			bm_ensure_types |= BM_FACE;
 		}
-		if (types & MR_DATATYPE_ACTIVE) {
+		if (types & MR_DATATYPE_OVERLAY) {
 			mrdata->efa_act = BM_mesh_active_face_get(bm, false, true);
 			mrdata->eed_act = BM_mesh_active_edge_get(bm);
 			mrdata->eve_act = BM_mesh_active_vert_get(bm);
-		}
-		if (types & MR_DATATYPE_CREASE) {
 			mrdata->crease_ofs = CustomData_get_offset(&bm->edata, CD_CREASE);
-		}
-		if (types & MR_DATATYPE_BWEIGHT) {
 			mrdata->bweight_ofs = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
 		}
 		BM_mesh_elem_index_ensure(bm, bm_ensure_types);
 		BM_mesh_elem_table_ensure(bm, bm_ensure_types & ~BM_LOOP);
-		if (types & MR_DATATYPE_LOOSE_VERT) {
-			mrdata->types |= MR_DATATYPE_VERT;
-			mrdata->totlvert = 0;
-			/* XXX slow, looping twice */
+		if (types & MR_DATATYPE_OVERLAY) {
+			mrdata->totlvert = mrdata->totledge = 0;
+
+			int *lverts = mrdata->loose_verts = MEM_mallocN(mrdata->totvert * sizeof(int), "Loose Vert");
+			int *ledges = mrdata->loose_edges = MEM_mallocN(mrdata->totedge * sizeof(int), "Loose Edges");
+
 			for (int i = 0; i < mrdata->totvert; ++i) {
 				BMVert *bv = BM_vert_at_index(bm, i);
-				if (BM_vert_edge_count_ex(bv, 1) == 0) {
+
+				/* Loose vert */
+				if (bv->e == NULL) {
+					lverts[mrdata->totlvert] = BM_elem_index_get(bv);
 					mrdata->totlvert++;
+					continue;
 				}
-			}
 
-			int *lverts = mrdata->loose_verts = MEM_mallocN(mrdata->totlvert * sizeof(int), "Loose Vert");
-
-			int li = 0;
-			if (mrdata->totlvert > 0) {
-				for (int i = 0; i < mrdata->totvert; ++i) {
-					BMVert *bv = BM_vert_at_index(bm, i);
-					if (BM_vert_edge_count_ex(bv, 1) == 0) {
-						lverts[li++] = i;
+				/* Find Loose Edges */
+				BMEdge *e_iter, *e_first;
+				e_first = e_iter = bv->e;
+				do {
+					if (e_iter->l == NULL) {
+						BMVert *other_vert = BM_edge_other_vert(e_iter, bv);
+
+						/* Verify we do not add the same edge twice */
+						if (BM_elem_index_get(other_vert) > i) {
+							ledges[mrdata->totledge] = BM_elem_index_get(e_iter);
+							mrdata->totledge++;
+						}
 					}
-				}
-			}
-		}
-		if (types & MR_DATATYPE_LOOSE_EDGE) {
-			mrdata->types |= MR_DATATYPE_EDGE;
-			mrdata->totledge = 0;
-			/* XXX slow, looping twice */
-			for (int i = 0; i < mrdata->totedge; ++i) {
-				BMEdge *bv = BM_edge_at_index(bm, i);
-				if (BM_edge_is_wire(bv)) {
-					mrdata->totledge++;
-				}
-			}
-
-			int *ledges = mrdata->loose_edges = MEM_mallocN(mrdata->totledge * sizeof(int), "Loose Egde");
-
-			int li = 0;
-			if (mrdata->totledge > 0) {
-				for (int i = 0; i < mrdata->totedge; ++i) {
-					BMEdge *bv = BM_edge_at_index(bm, i);
-					if (BM_edge_is_wire(bv)) {
-						ledges[li++] = i;
-					}
-				}
+				} while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, bv)) != e_first);
 			}
+			mrdata->loose_verts = MEM_reallocN(mrdata->loose_verts, mrdata->totlvert * sizeof(int));
+			mrdata->loose_edges = MEM_reallocN(mrdata->loose_edges, mrdata->totledge * sizeof(int));
 		}
 	}
 	else {
-		if (types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOSE_VERT)) {
+		if (types & (MR_DATATYPE_VERT)) {
 			mrdata->totvert = me->totvert;
 			mrdata->mvert = CustomData_get_layer(&me->vdata, CD_MVERT);
 		}
-		if (types & (MR_DATATYPE_EDGE | MR_DATATYPE_LOOSE_EDGE)) {
+		if (types & (MR_DATATYPE_EDGE)) {
 			mrdata->totedge = me->totedge;
 			mrdata->medge = CustomData_get_layer(&me->edata, CD_MEDGE);
 		}
@@ -248,16 +228,6 @@ static MeshRenderData *mesh_render_data_create(Mesh *me, const int types)
 			mrdata->totpoly = me->totpoly;
 			mrdata->mpoly = CustomData_get_layer(&me->pdata, CD_MPOLY);
 		}
-		if (types & MR_DATATYPE_LOOSE_VERT) {
-			mrdata->types |= MR_DATATYPE_VERT;
-			mrdata->totlvert = 0;
-			/* TODO */
-		}
-		if (types & MR_DATATYPE_LOOSE_EDGE) {
-			mrdata->types |= MR_DATATYPE_EDGE;
-			mrdata->totledge = 0;
-			/* TODO */
-		}
 	}
 
 	return mrdata;
@@ -300,7 +270,7 @@ static int mesh_render_data_verts_num_get(const MeshRenderData *mrdata)
 
 static int mesh_render_data_loose_verts_num_get(const MeshRenderData *mrdata)
 {
-	BLI_assert(mrdata->types & MR_DATATYPE_LOOSE_VERT);
+	BLI_assert(mrdata->types & MR_DATATYPE_OVERLAY);
 	return mrdata->totlvert;
 }
 
@@ -312,7 +282,7 @@ static int mesh_render_data_edges_num_get(const MeshRenderData *mrdata)
 
 static int mesh_render_data_loose_edges_num_get(const MeshRenderData *mrdata)
 {
-	BLI_assert(mrdata->types & MR_DATATYPE_LOOSE_EDGE);
+	BLI_assert(mrdata->types & MR_DATATYPE_OVERLAY);
 	return mrdata->totledge;
 }
 
@@ -547,6 +517,171 @@ static bool mesh_render_data_looptri_cos_nors_smooth_get(
 	}
 }
 
+/* First 2 bytes are bit flags
+ * 3rd is for sharp edges
+ * 4rd is for creased edges */
+enum {
+	VFLAG_VERTEX_ACTIVE   = 1 << 0,
+	VFLAG_VERTEX_SELECTED = 1 << 1,
+	VFLAG_FACE_ACTIVE     = 1 << 2,
+	VFLAG_FACE_SELECTED   = 1 << 3,
+};
+
+enum {
+	VFLAG_EDGE_EXISTS   = 1 << 0,
+	VFLAG_EDGE_ACTIVE   = 1 << 1,
+	VFLAG_EDGE_SELECTED = 1 << 2,
+	VFLAG_EDGE_SEAM     = 1 << 3,
+	VFLAG_EDGE_SHARP    = 1 << 4,
+	/* Beware to not go over 1 << 7
+	 * (see gpu_shader_edit_overlay_geom.glsl) */
+};
+
+static unsigned char mesh_render_data_looptri_flag(MeshRenderData *mrdata, const int f)
+{
+	unsigned char fflag = 0;
+
+	if (mrdata->edit_bmesh) {
+		BMFace *bf = mrdata->edit_bmesh->looptris[f][0]->f;
+
+		if (bf == mrdata->efa_act)
+			fflag |= VFLAG_FACE_ACTIVE;
+
+		if (BM_elem_flag_test(bf, BM_ELEM_SELECT))
+			fflag |= VFLAG_FACE_SELECTED;
+	}
+
+	return fflag;
+}
+
+static unsigned char *mesh_render_data_edge_flag(
+        MeshRenderData *mrdata, const int v1, const int v2, const int e)
+{
+	static unsigned char eflag[4];
+	memset(eflag, 0, sizeof(char) * 4);
+
+	/* if edge exists */
+	if (mrdata->edit_bmesh) {
+		BMesh *bm = mrdata->edit_bmesh->bm;
+		BMEdge *be = NULL;
+
+		if (e != -1) be = BM_edge_at_index(bm, e);
+		else         be = BM_edge_exists(BM_vert_at_index(bm, v1),
+		                                 BM_vert_at_index(bm, v2));
+
+		if (be != NULL) {
+
+			eflag[1] |= VFLAG_EDGE_EXISTS;
+
+			if (be == mrdata->eed_act)
+				eflag[1] |= VFLAG_EDGE_ACTIVE;
+
+			if (BM_elem_flag_test(be, BM_ELEM_SELECT))
+				eflag[1] |= VFLAG_EDGE_SELECTED;
+
+			if (BM_elem_flag_test(be, BM_ELEM_SEAM))
+				eflag[1] |= VFLAG_EDGE_SEAM;
+
+			if (!BM_elem_flag_test(be, BM_ELEM_SMOOTH))
+				eflag[1] |= VFLAG_EDGE_SHARP;
+
+			/* Use a byte for value range */
+			if (mrdata->crease_ofs != -1) {
+				float crease = BM_ELEM_CD_GET_FLOAT(be, mrdata->crease_ofs);
+				if (crease > 0) {
+					eflag[2] = (char)(crease * 255.0f);
+				}
+			}
+
+			/* Use a byte for value range */
+			if (mrdata->bweight_ofs != -1) {
+				float bweight = BM_ELEM_CD_GET_FLOAT(be, mrdata->bweight_ofs);
+				if (bweight > 0) {
+					eflag[3] = (char)(bweight * 255.0f);
+				}
+			}
+		}
+	}
+	else if ((e == -1) && mesh_render_data_edge_exists(mrdata, v1, v2)) {
+		eflag[1] |= VFLAG_EDGE_EXISTS;
+	}
+
+	return eflag;
+}
+
+static unsigned char mesh_render_data_vertex_flag(MeshRenderData *mrdata, const int v)
+{
+
+	unsigned char vflag = 0;
+
+	if (mrdata->edit_bmesh) {
+		BMesh *bm = mrdata->edit_bmesh->bm;
+		BMVert *bv = BM_vert_at_index(bm, v);
+
+		/* Current vertex */
+		if (bv == mrdata->eve_act)
+			vflag |= VFLAG_VERTEX_ACTIVE;
+
+		if (BM_elem_flag_test(bv, BM_ELEM_SELECT))
+			vflag |= VFLAG_VERTEX_SELECTED;
+	}
+
+	return vflag;
+}
+
+static void add_overlay_tri(
+        MeshRenderData *mrdata, VertexBuffer *vbo, const unsigned int pos_id, const unsigned int edgeMod_id,
+        const int v1, const int v2, const int v3, const int f, const int base_vert_idx)
+{
+	const float *pos = mesh_render_data_vert_co(mrdata, v1);
+	unsigned char *eflag = mesh_render_data_edge_flag(mrdata, v2, v3, -1);
+	unsigned char  fflag = mesh_render_data_looptri_flag(mrdata, f);
+	unsigned char  vflag = mesh_render_

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list