[Bf-blender-cvs] [604101d2620] blender2.8: Mesh Batch Cache: Port edge_detection to batch request

Clément Foucault noreply at git.blender.org
Tue Dec 18 20:52:06 CET 2018


Commit: 604101d2620626c1ad95e1271b6616a339dbe9b8
Author: Clément Foucault
Date:   Tue Dec 18 19:56:55 2018 +0100
Branches: blender2.8
https://developer.blender.org/rB604101d2620626c1ad95e1271b6616a339dbe9b8

Mesh Batch Cache: Port edge_detection to batch request

Also add proper support for mapped meshes (deformed by modifiers in edit
mode). So this fixes the shadows of workbench in edit mode.

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

M	source/blender/draw/intern/draw_cache_impl_mesh.c

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

diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 5d3a856a2d2..fd0926fcb4a 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -1164,7 +1164,7 @@ static const char *mesh_render_data_tangent_layer_uuid_get(const MeshRenderData
 	return rdata->cd.uuid.tangent[layer];
 }
 
-static int mesh_render_data_verts_len_get(const MeshRenderData *rdata)
+static int UNUSED_FUNCTION(mesh_render_data_verts_len_get)(const MeshRenderData *rdata)
 {
 	BLI_assert(rdata->types & MR_DATATYPE_VERT);
 	return rdata->vert_len;
@@ -2026,6 +2026,7 @@ typedef struct MeshBatchCache {
 		/* Indices to verts. */
 		GPUIndexBuf *surf_tris;
 		GPUIndexBuf *edges_lines;
+		GPUIndexBuf *edges_adj_lines;
 		/* Indices to vloops. */
 		GPUIndexBuf *loops_tris;
 		GPUIndexBuf *loops_lines;
@@ -2050,6 +2051,7 @@ typedef struct MeshBatchCache {
 		/* Common display / Other */
 		GPUBatch *all_verts;
 		GPUBatch *all_edges;
+		GPUBatch *edge_detection;
 		GPUBatch *wire_loops; /* Loops around faces. */
 		GPUBatch *wire_triangles; /* Triangles for object mode wireframe. */
 	} batch;
@@ -3891,95 +3893,119 @@ static void mesh_create_edit_facedots(
 /* Indices */
 
 #define NO_EDGE INT_MAX
-static GPUIndexBuf *mesh_batch_cache_get_edges_adjacency(MeshRenderData *rdata, MeshBatchCache *cache)
+static void mesh_create_edges_adjacency_lines(
+        MeshRenderData *rdata, GPUIndexBuf *ibo, bool *r_is_manifold, const bool use_hide)
 {
-	BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI));
+	const MLoopTri *mlooptri;
+	const int vert_len = mesh_render_data_verts_len_get_maybe_mapped(rdata);
+	const int tri_len = mesh_render_data_looptri_len_get_maybe_mapped(rdata);
 
-	if (cache->edges_adjacency == NULL) {
-		const int vert_len = mesh_render_data_verts_len_get(rdata);
-		const int tri_len = mesh_render_data_looptri_len_get(rdata);
+	*r_is_manifold = true;
 
-		cache->is_manifold = true;
+	/* Allocate max but only used indices are sent to GPU. */
+	GPUIndexBufBuilder elb;
+	GPU_indexbuf_init(&elb, GPU_PRIM_LINES_ADJ, tri_len * 3, vert_len);
 
-		/* Allocate max but only used indices are sent to GPU. */
-		GPUIndexBufBuilder elb;
-		GPU_indexbuf_init(&elb, GPU_PRIM_LINES_ADJ, tri_len * 3, vert_len);
+	if (rdata->mapped.use) {
+		Mesh *me_cage = rdata->mapped.me_cage;
+		mlooptri = BKE_mesh_runtime_looptri_ensure(me_cage);
+	}
+	else {
+		mlooptri = rdata->mlooptri;
+	}
 
-		EdgeHash *eh = BLI_edgehash_new_ex(__func__, tri_len * 3);
-		/* Create edges for each pair of triangles sharing an edge. */
-		for (int i = 0; i < tri_len; i++) {
-			for (int e = 0; e < 3; e++) {
-				uint v0, v1, v2;
-				if (rdata->edit_bmesh) {
-					const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
-					if (BM_elem_flag_test(bm_looptri[0]->f, BM_ELEM_HIDDEN)) {
+	EdgeHash *eh = BLI_edgehash_new_ex(__func__, tri_len * 3);
+	/* Create edges for each pair of triangles sharing an edge. */
+	for (int i = 0; i < tri_len; i++) {
+		for (int e = 0; e < 3; e++) {
+			uint v0, v1, v2;
+			if (rdata->mapped.use) {
+				const MLoop *mloop = rdata->mloop;
+				const MLoopTri *mlt = mlooptri + i;
+				const int p_orig = rdata->mapped.p_origindex[mlt->poly];
+				if (p_orig != ORIGINDEX_NONE) {
+					BMesh *bm = rdata->edit_bmesh->bm;
+					BMFace *efa = BM_face_at_index(bm, p_orig);
+					/* Assume 'use_hide' */
+					if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
 						break;
 					}
-					v0 = BM_elem_index_get(bm_looptri[e]->v);
-					v1 = BM_elem_index_get(bm_looptri[(e + 1) % 3]->v);
-					v2 = BM_elem_index_get(bm_looptri[(e + 2) % 3]->v);
 				}
-				else {
-					const MLoop *mloop = rdata->mloop;
-					const MLoopTri *mlt = rdata->mlooptri + i;
-					v0 = mloop[mlt->tri[e]].v;
-					v1 = mloop[mlt->tri[(e + 1) % 3]].v;
-					v2 = mloop[mlt->tri[(e + 2) % 3]].v;
+				v0 = mloop[mlt->tri[e]].v;
+				v1 = mloop[mlt->tri[(e + 1) % 3]].v;
+				v2 = mloop[mlt->tri[(e + 2) % 3]].v;
+			}
+			else if (rdata->edit_bmesh) {
+				const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[i];
+				if (BM_elem_flag_test(bm_looptri[0]->f, BM_ELEM_HIDDEN)) {
+					break;
+				}
+				v0 = BM_elem_index_get(bm_looptri[e]->v);
+				v1 = BM_elem_index_get(bm_looptri[(e + 1) % 3]->v);
+				v2 = BM_elem_index_get(bm_looptri[(e + 2) % 3]->v);
+			}
+			else {
+				const MLoop *mloop = rdata->mloop;
+				const MLoopTri *mlt = mlooptri + i;
+				const MPoly *mp = &rdata->mpoly[mlt->poly];
+				if (use_hide && (mp->flag & ME_HIDE)) {
+					break;
 				}
-				bool inv_indices = (v1 > v2);
-				void **pval;
-				bool value_is_init = BLI_edgehash_ensure_p(eh, v1, v2, &pval);
-				int v_data = POINTER_AS_INT(*pval);
-				if (!value_is_init || v_data == NO_EDGE) {
-					/* Save the winding order inside the sign bit. Because the
-					 * edgehash sort the keys and we need to compare winding later. */
-					int value = (int)v0 + 1; /* Int 0 cannot be signed */
-					*pval = POINTER_FROM_INT((inv_indices) ? -value : value);
+				v0 = mloop[mlt->tri[e]].v;
+				v1 = mloop[mlt->tri[(e + 1) % 3]].v;
+				v2 = mloop[mlt->tri[(e + 2) % 3]].v;
+			}
+			bool inv_indices = (v1 > v2);
+			void **pval;
+			bool value_is_init = BLI_edgehash_ensure_p(eh, v1, v2, &pval);
+			int v_data = POINTER_AS_INT(*pval);
+			if (!value_is_init || v_data == NO_EDGE) {
+				/* Save the winding order inside the sign bit. Because the
+				 * edgehash sort the keys and we need to compare winding later. */
+				int value = (int)v0 + 1; /* Int 0 bm_looptricannot be signed */
+				*pval = POINTER_FROM_INT((inv_indices) ? -value : value);
+			}
+			else {
+				/* HACK Tag as not used. Prevent overhead of BLI_edgehash_remove. */
+				*pval = POINTER_FROM_INT(NO_EDGE);
+				bool inv_opposite = (v_data < 0);
+				uint v_opposite = (uint)abs(v_data) - 1;
+
+				if (inv_opposite == inv_indices) {
+					/* Don't share edge if triangles have non matching winding. */
+					GPU_indexbuf_add_line_adj_verts(&elb, v0, v1, v2, v0);
+					GPU_indexbuf_add_line_adj_verts(&elb, v_opposite, v1, v2, v_opposite);
+					*r_is_manifold = false;
 				}
 				else {
-					/* HACK Tag as not used. Prevent overhead of BLI_edgehash_remove. */
-					*pval = POINTER_FROM_INT(NO_EDGE);
-					bool inv_opposite = (v_data < 0);
-					uint v_opposite = (uint)abs(v_data) - 1;
-
-					if (inv_opposite == inv_indices) {
-						/* Don't share edge if triangles have non matching winding. */
-						GPU_indexbuf_add_line_adj_verts(&elb, v0, v1, v2, v0);
-						GPU_indexbuf_add_line_adj_verts(&elb, v_opposite, v1, v2, v_opposite);
-						cache->is_manifold = false;
-					}
-					else {
-						GPU_indexbuf_add_line_adj_verts(&elb, v0, v1, v2, v_opposite);
-					}
+					GPU_indexbuf_add_line_adj_verts(&elb, v0, v1, v2, v_opposite);
 				}
 			}
 		}
-		/* Create edges for remaning non manifold edges. */
-		EdgeHashIterator *ehi;
-		for (ehi = BLI_edgehashIterator_new(eh);
-		     BLI_edgehashIterator_isDone(ehi) == false;
-		     BLI_edgehashIterator_step(ehi))
-		{
-			uint v1, v2;
-			int v_data = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi));
-			if (v_data == NO_EDGE) {
-				continue;
-			}
-			BLI_edgehashIterator_getKey(ehi, &v1, &v2);
-			uint v0 = (uint)abs(v_data) - 1;
-			if (v_data < 0) { /* inv_opposite  */
-				SWAP(uint, v1, v2);
-			}
-			GPU_indexbuf_add_line_adj_verts(&elb, v0, v1, v2, v0);
-			cache->is_manifold = false;
+	}
+	/* Create edges for remaning non manifold edges. */
+	EdgeHashIterator *ehi;
+	for (ehi = BLI_edgehashIterator_new(eh);
+	     BLI_edgehashIterator_isDone(ehi) == false;
+	     BLI_edgehashIterator_step(ehi))
+	{
+		uint v1, v2;
+		int v_data = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi));
+		if (v_data == NO_EDGE) {
+			continue;
 		}
-		BLI_edgehashIterator_free(ehi);
-		BLI_edgehash_free(eh, NULL);
-
-		cache->edges_adjacency = GPU_indexbuf_build(&elb);
+		BLI_edgehashIterator_getKey(ehi, &v1, &v2);
+		uint v0 = (uint)abs(v_data) - 1;
+		if (v_data < 0) { /* inv_opposite  */
+			SWAP(uint, v1, v2);
+		}
+		GPU_indexbuf_add_line_adj_verts(&elb, v0, v1, v2, v0);
+		*r_is_manifold = false;
 	}
+	BLI_edgehashIterator_free(ehi);
+	BLI_edgehash_free(eh, NULL);
 
-	return cache->edges_adjacency;
+	GPU_indexbuf_build_in_place(&elb, ibo);
 }
 #undef NO_EDGE
 
@@ -4516,23 +4542,13 @@ GPUBatch *DRW_mesh_batch_cache_get_edge_detection(Mesh *me, bool *r_is_manifold)
 {
 	MeshBatchCache *cache = mesh_batch_cache_get(me);
 
-	if (cache->edge_detection == NULL) {
-		const int options = MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI;
-
-		MeshRenderData *rdata = mesh_render_data_create(me, options);
-
-		cache->edge_detection = GPU_batch_create_ex(
-		        GPU_PRIM_LINES_ADJ, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache),
-		        mesh_batch_cache_get_edges_adjacency(rdata, cache), 0);
-
-		mesh_render_data_free(rdata);
-	}
-
 	if (r_is_manifold) {
+		/* Even if is_manifold is not correct (not updated),
+		 * the default (not manifold) is just the worst case. */
 		*r_is_manifold = cache->is_manifold;
 	}
 
-	return cache->edge_detection;
+	return DRW_batch_request(&cache->batch.edge_detection);
 }
 
 GPUBatch *DRW_mesh_batch_cache_get_wireframes_face(Mesh *me)
@@ -5353,6 +5369,10 @@ void DRW_mesh_batch_cache_create_requested(Object *ob, Mesh *me)
 		DRW_ibo_request(cache->batch.all_edges, &cache->ibo.edges_lines);
 		DRW_vbo_request(cache->batch.all_edges, &cache->ordered.pos_nor);
 	}
+	if (DRW_batch_requested(cache->batch.edge_detection, GPU_PRIM_LINES_ADJ)) {
+		DRW_ibo_request(cache->batch.edge_detection, &cache->ibo.edges_adj_lines);
+		DRW_vbo_request(cache->batch.edge_detection, &cache->ordered.pos_nor);
+	}
 	if (DRW_batch_requested(cache->batch.surface_weights, GPU_PRIM_TRIS)) {
 		DRW_ibo_request(cache->batch.surface_weights, &cache->ibo.surf_tris);
 		DRW_vbo_request(cache->batch.surface_weights, &cache->ordered.pos_nor);
@@ -5436,6 +5456,7 @@ void DRW_mesh_batch_cache_create_requested(Object *ob, Mesh *me)
 	DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.loops_tris, MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI);
 	DRW_ADD_FLAG_FROM_IBO_RE

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list