[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