diff options
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 19 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.h | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl.h | 1 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_mesh.c | 62 | ||||
-rw-r--r-- | source/blender/draw/modes/object_mode.c | 36 |
5 files changed, 100 insertions, 20 deletions
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 33fb801af5a..14addfe9bcb 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -526,6 +526,17 @@ void DRW_cache_object_face_wireframe_get( } } +Gwn_Batch *DRW_cache_object_loose_edges_get(struct Object *ob) +{ + switch (ob->type) { + case OB_MESH: + return DRW_cache_mesh_loose_edges_get(ob); + + /* TODO, should match 'DRW_cache_object_surface_get' */ + default: + return NULL; + } +} Gwn_Batch *DRW_cache_object_surface_get(Object *ob) { @@ -2614,6 +2625,14 @@ Gwn_Batch *DRW_cache_mesh_surface_get(Object *ob) return DRW_mesh_batch_cache_get_triangles_with_normals(me); } +Gwn_Batch *DRW_cache_mesh_loose_edges_get(Object *ob) +{ + BLI_assert(ob->type == OB_MESH); + + Mesh *me = ob->data; + return DRW_mesh_batch_cache_get_loose_edges_with_normals(me); +} + Gwn_Batch *DRW_cache_mesh_surface_weights_get(Object *ob) { BLI_assert(ob->type == OB_MESH); diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index e962d513c9b..7a1c14b5076 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -50,6 +50,7 @@ struct Gwn_Batch *DRW_cache_screenspace_circle_get(void); struct Gwn_Batch *DRW_cache_object_wire_outline_get(struct Object *ob); struct Gwn_Batch *DRW_cache_object_edge_detection_get(struct Object *ob, bool *r_is_manifold); struct Gwn_Batch *DRW_cache_object_surface_get(struct Object *ob); +struct Gwn_Batch *DRW_cache_object_loose_edges_get(struct Object *ob); struct Gwn_Batch **DRW_cache_object_surface_material_get( struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len, char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count); @@ -124,6 +125,7 @@ struct Gwn_Batch *DRW_cache_face_centers_get(struct Object *ob); struct Gwn_Batch *DRW_cache_mesh_wire_outline_get(struct Object *ob); struct Gwn_Batch *DRW_cache_mesh_edge_detection_get(struct Object *ob, bool *r_is_manifold); struct Gwn_Batch *DRW_cache_mesh_surface_get(struct Object *ob); +struct Gwn_Batch *DRW_cache_mesh_loose_edges_get(struct Object *ob); struct Gwn_Batch *DRW_cache_mesh_surface_weights_get(struct Object *ob); struct Gwn_Batch *DRW_cache_mesh_surface_vert_colors_get(struct Object *ob); struct Gwn_Batch *DRW_cache_mesh_surface_verts_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 8a8d41cb38a..0f990c72d01 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -108,6 +108,7 @@ struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(st struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(struct Mesh *me); struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me, bool use_hide, uint select_id_offset); struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_mask(struct Mesh *me, bool use_hide); +struct Gwn_Batch *DRW_mesh_batch_cache_get_loose_edges_with_normals(struct Mesh *me); struct Gwn_Batch *DRW_mesh_batch_cache_get_points_with_normals(struct Mesh *me); struct Gwn_Batch *DRW_mesh_batch_cache_get_all_verts(struct Mesh *me); struct Gwn_Batch *DRW_mesh_batch_cache_get_fancy_edges(struct Mesh *me); diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index d6651125b58..716a6b26696 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -1544,6 +1544,7 @@ typedef struct MeshBatchCache { Gwn_IndexBuf *edges_in_order; Gwn_IndexBuf *edges_adjacency; /* Store edges with adjacent vertices. */ Gwn_IndexBuf *triangles_in_order; + Gwn_IndexBuf *ledges_in_order; GPUTexture *pos_in_order_tx; /* Depending on pos_in_order */ @@ -1563,6 +1564,7 @@ typedef struct MeshBatchCache { Gwn_VertBuf *ed_vert_pos; Gwn_Batch *triangles_with_normals; + Gwn_Batch *ledges_with_normals; /* Skip hidden (depending on paint select mode) */ Gwn_Batch *triangles_with_weights; @@ -1823,6 +1825,7 @@ static void mesh_batch_cache_clear(Mesh *me) DRW_TEXTURE_FREE_SAFE(cache->pos_in_order_tx); GWN_INDEXBUF_DISCARD_SAFE(cache->edges_in_order); GWN_INDEXBUF_DISCARD_SAFE(cache->triangles_in_order); + GWN_INDEXBUF_DISCARD_SAFE(cache->ledges_in_order); GWN_VERTBUF_DISCARD_SAFE(cache->ed_tri_pos); GWN_VERTBUF_DISCARD_SAFE(cache->ed_tri_nor); @@ -3446,6 +3449,45 @@ static Gwn_IndexBuf *mesh_batch_cache_get_triangles_in_order(MeshRenderData *rda return cache->triangles_in_order; } + +static Gwn_IndexBuf *mesh_batch_cache_get_loose_edges(MeshRenderData *rdata, MeshBatchCache *cache) +{ + BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI)); + + if (cache->ledges_in_order == NULL) { + const int vert_len = mesh_render_data_verts_len_get(rdata); + const int edge_len = mesh_render_data_edges_len_get(rdata); + + /* Alloc max (edge_len) and upload only needed range. */ + Gwn_IndexBufBuilder elb; + GWN_indexbuf_init(&elb, GWN_PRIM_LINES, edge_len, vert_len); + + if (rdata->edit_bmesh) { + /* No need to support since edit mesh already draw them. + * But some engines may want them ... */ + BMesh *bm = rdata->edit_bmesh->bm; + BMIter eiter; + BMEdge *eed; + BM_ITER_MESH(eed, &eiter, bm, BM_EDGES_OF_MESH) { + if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && BM_edge_is_wire(eed)) { + GWN_indexbuf_add_line_verts(&elb, BM_elem_index_get(eed->v1), BM_elem_index_get(eed->v2)); + } + } + } + else { + for (int i = 0; i < edge_len; ++i) { + const MEdge *medge = &rdata->medge[i]; + if (medge->flag & ME_LOOSEEDGE) { + GWN_indexbuf_add_line_verts(&elb, medge->v1, medge->v2); + } + } + } + cache->ledges_in_order = GWN_indexbuf_build(&elb); + } + + return cache->ledges_in_order; +} + static Gwn_IndexBuf **mesh_batch_cache_get_triangles_in_order_split_by_material( MeshRenderData *rdata, MeshBatchCache *cache) { @@ -3671,7 +3713,7 @@ Gwn_Batch *DRW_mesh_batch_cache_get_all_edges(Mesh *me) cache->all_edges = GWN_batch_create( GWN_PRIM_LINES, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), - mesh_batch_cache_get_edges_in_order(rdata, cache)); + mesh_batch_cache_get_edges_in_order(rdata, cache)); mesh_render_data_free(rdata); } @@ -3715,6 +3757,24 @@ Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals(Mesh *me) return cache->triangles_with_normals; } +Gwn_Batch *DRW_mesh_batch_cache_get_loose_edges_with_normals(Mesh *me) +{ + MeshBatchCache *cache = mesh_batch_cache_get(me); + + if (cache->ledges_with_normals == NULL) { + const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY; + MeshRenderData *rdata = mesh_render_data_create(me, datatype); + + cache->ledges_with_normals = GWN_batch_create( + GWN_PRIM_LINES, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), + mesh_batch_cache_get_loose_edges(rdata, cache)); + + mesh_render_data_free(rdata); + } + + return cache->ledges_with_normals; +} + Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(Mesh *me, int defgroup) { MeshBatchCache *cache = mesh_batch_cache_get(me); diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index c6a90527f39..ff6fcdb83d2 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -2101,28 +2101,26 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) { if (ob != draw_ctx->object_edit) { Mesh *me = ob->data; - if (me->totpoly == 0) { - if (me->totedge == 0) { - struct Gwn_Batch *geom = DRW_cache_mesh_verts_get(ob); - if (geom) { - if (theme_id == TH_UNDEFINED) { - theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); - } - - DRWShadingGroup *shgroup = shgroup_theme_id_to_point_or(stl, theme_id, stl->g_data->points); - DRW_shgroup_call_object_add(shgroup, geom, ob); + if (me->totedge == 0) { + struct Gwn_Batch *geom = DRW_cache_mesh_verts_get(ob); + if (geom) { + if (theme_id == TH_UNDEFINED) { + theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); } + + DRWShadingGroup *shgroup = shgroup_theme_id_to_point_or(stl, theme_id, stl->g_data->points); + DRW_shgroup_call_object_add(shgroup, geom, ob); } - else { - struct Gwn_Batch *geom = DRW_cache_mesh_edges_get(ob); - if (geom) { - if (theme_id == TH_UNDEFINED) { - theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); - } - - DRWShadingGroup *shgroup = shgroup_theme_id_to_wire_or(stl, theme_id, stl->g_data->wire); - DRW_shgroup_call_object_add(shgroup, geom, ob); + } + else { + struct Gwn_Batch *geom = DRW_cache_mesh_loose_edges_get(ob); + if (geom) { + if (theme_id == TH_UNDEFINED) { + theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL); } + + DRWShadingGroup *shgroup = shgroup_theme_id_to_wire_or(stl, theme_id, stl->g_data->wire); + DRW_shgroup_call_object_add(shgroup, geom, ob); } } } |