diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-12-14 17:23:13 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-12-14 18:17:29 +0300 |
commit | f371e633f9428e767dce4aab59b5f30c78f2b66f (patch) | |
tree | 9d632bb0f7105bad95a10581dbfe0fa904d3e989 /source/blender/draw/intern | |
parent | e4b3fe4b690689357f81e58442d9bdf77e502124 (diff) |
Curve Batch Cache: Add support for loose edges and curve/surf modifier
Fixes T58298 Nurbs circle and curve dont draw in objectmode
Fixes T58107 Modified curves/surfaces/fonts do not show their eval mesh
Diffstat (limited to 'source/blender/draw/intern')
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 145 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.h | 6 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl.h | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_curve.c | 55 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_mesh.c | 6 |
5 files changed, 178 insertions, 36 deletions
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 9186191cea5..bbf84d549a2 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -718,8 +718,14 @@ GPUBatch *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' */ + case OB_CURVE: + return DRW_cache_curve_loose_edges_get(ob); + case OB_SURF: + return DRW_cache_surf_loose_edges_get(ob); + case OB_FONT: + return DRW_cache_text_loose_edges_get(ob); + case OB_MBALL: + /* Cannot have any loose edge */ default: return NULL; } @@ -3227,7 +3233,29 @@ GPUBatch *DRW_cache_curve_surface_get(Object *ob) BLI_assert(ob->type == OB_CURVE); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_triangles_with_normals(cu); + struct Mesh *mesh_eval = ob->runtime.mesh_eval; + if (mesh_eval != NULL) { + return DRW_mesh_batch_cache_get_triangles_with_normals(mesh_eval, true); + } + else { + return DRW_curve_batch_cache_get_triangles_with_normals(cu); + } +} + +GPUBatch *DRW_cache_curve_loose_edges_get(Object *ob) +{ + BLI_assert(ob->type == OB_CURVE); + + struct Curve *cu = ob->data; + struct Mesh *mesh_eval = ob->runtime.mesh_eval; + if (mesh_eval != NULL) { + return DRW_mesh_batch_cache_get_loose_edges_with_normals(mesh_eval); + } + else { + /* TODO */ + UNUSED_VARS(cu); + return NULL; + } } GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob) @@ -3235,7 +3263,13 @@ GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob) BLI_assert(ob->type == OB_CURVE); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_wireframes_face(cu); + struct Mesh *mesh_eval = ob->runtime.mesh_eval; + if (mesh_eval != NULL) { + return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval); + } + else { + return DRW_curve_batch_cache_get_wireframes_face(cu); + } } /* Return list of batches */ @@ -3245,7 +3279,13 @@ GPUBatch **DRW_cache_curve_surface_shaded_get( BLI_assert(ob->type == OB_CURVE); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); + struct Mesh *mesh_eval = ob->runtime.mesh_eval; + if (mesh_eval != NULL) { + return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len, true, NULL, NULL, NULL); + } + else { + return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); + } } /** \} */ @@ -3294,20 +3334,49 @@ GPUBatch *DRW_cache_text_surface_get(Object *ob) { BLI_assert(ob->type == OB_FONT); struct Curve *cu = ob->data; + struct Mesh *mesh_eval = ob->runtime.mesh_eval; if (cu->editfont && (cu->flag & CU_FAST)) { return NULL; } - return DRW_curve_batch_cache_get_triangles_with_normals(cu); + if (mesh_eval != NULL) { + return DRW_mesh_batch_cache_get_triangles_with_normals(mesh_eval, true); + } + else { + return DRW_curve_batch_cache_get_triangles_with_normals(cu); + } +} + +GPUBatch *DRW_cache_text_loose_edges_get(Object *ob) +{ + BLI_assert(ob->type == OB_FONT); + struct Curve *cu = ob->data; + struct Mesh *mesh_eval = ob->runtime.mesh_eval; + if (cu->editfont && (cu->flag & CU_FAST)) { + return NULL; + } + if (mesh_eval != NULL) { + return DRW_mesh_batch_cache_get_loose_edges_with_normals(mesh_eval); + } + else { + /* TODO */ + return NULL; + } } GPUBatch *DRW_cache_text_face_wireframe_get(Object *ob) { BLI_assert(ob->type == OB_FONT); struct Curve *cu = ob->data; + struct Mesh *mesh_eval = ob->runtime.mesh_eval; if (cu->editfont && (cu->flag & CU_FAST)) { return NULL; } - return DRW_curve_batch_cache_get_wireframes_face(cu); + if (mesh_eval != NULL) { + return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval); + } + else { + return DRW_curve_batch_cache_get_wireframes_face(cu); + } } GPUBatch **DRW_cache_text_surface_shaded_get( @@ -3315,10 +3384,16 @@ GPUBatch **DRW_cache_text_surface_shaded_get( { BLI_assert(ob->type == OB_FONT); struct Curve *cu = ob->data; + struct Mesh *mesh_eval = ob->runtime.mesh_eval; if (cu->editfont && (cu->flag & CU_FAST)) { return NULL; } - return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); + if (mesh_eval != NULL) { + return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len, true, NULL, NULL, NULL); + } + else { + return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); + } } /** \} */ @@ -3333,7 +3408,21 @@ GPUBatch *DRW_cache_surf_surface_get(Object *ob) BLI_assert(ob->type == OB_SURF); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_triangles_with_normals(cu); + struct Mesh *mesh_eval = ob->runtime.mesh_eval; + if (mesh_eval != NULL) { + return DRW_mesh_batch_cache_get_triangles_with_normals(mesh_eval, true); + } + else { + return DRW_curve_batch_cache_get_triangles_with_normals(cu); + } +} + +GPUBatch *DRW_cache_surf_edge_wire_get(Object *ob) +{ + BLI_assert(ob->type == OB_SURF); + + struct Curve *cu = ob->data; + return DRW_curve_batch_cache_get_wire_edge(cu); } GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob) @@ -3341,7 +3430,29 @@ GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob) BLI_assert(ob->type == OB_SURF); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_wireframes_face(cu); + struct Mesh *mesh_eval = ob->runtime.mesh_eval; + if (mesh_eval != NULL) { + return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval); + } + else { + return DRW_curve_batch_cache_get_wireframes_face(cu); + } +} + +GPUBatch *DRW_cache_surf_loose_edges_get(Object *ob) +{ + BLI_assert(ob->type == OB_SURF); + + struct Curve *cu = ob->data; + struct Mesh *mesh_eval = ob->runtime.mesh_eval; + if (mesh_eval != NULL) { + return DRW_mesh_batch_cache_get_loose_edges_with_normals(mesh_eval); + } + else { + /* TODO */ + UNUSED_VARS(cu); + return NULL; + } } /* Return list of batches */ @@ -3351,7 +3462,13 @@ GPUBatch **DRW_cache_surf_surface_shaded_get( BLI_assert(ob->type == OB_SURF); struct Curve *cu = ob->data; - return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); + struct Mesh *mesh_eval = ob->runtime.mesh_eval; + if (mesh_eval != NULL) { + return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len, true, NULL, NULL, NULL); + } + else { + return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len); + } } /** \} */ @@ -3732,13 +3849,17 @@ bool DRW_vbo_requested(GPUVertBuf *vbo) void drw_batch_cache_generate_requested(Object *ob) { + struct Mesh *mesh_eval = ob->runtime.mesh_eval; switch (ob->type) { case OB_MESH: - DRW_mesh_batch_cache_create_requested(ob); + DRW_mesh_batch_cache_create_requested(ob, (Mesh *)ob->data); break; case OB_CURVE: case OB_FONT: case OB_SURF: + if (mesh_eval) { + DRW_mesh_batch_cache_create_requested(ob, mesh_eval); + } DRW_curve_batch_cache_create_requested(ob); break; /* TODO all cases */ diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 39743b705ae..bfa672ea04c 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -153,6 +153,7 @@ struct GPUBatch *DRW_cache_curve_surface_get(struct Object *ob); struct GPUBatch **DRW_cache_curve_surface_shaded_get( struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len); struct GPUBatch *DRW_cache_curve_surface_verts_get(struct Object *ob); +struct GPUBatch *DRW_cache_curve_loose_edges_get(struct Object *ob); struct GPUBatch *DRW_cache_curve_edge_wire_get(struct Object *ob); struct GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob); /* edit-mode */ @@ -161,8 +162,9 @@ struct GPUBatch *DRW_cache_curve_edge_overlay_get(struct Object *ob); struct GPUBatch *DRW_cache_curve_vert_overlay_get(struct Object *ob, bool handles); /* Font */ -struct GPUBatch *DRW_cache_text_edge_wire_get(struct Object *ob); struct GPUBatch *DRW_cache_text_surface_get(struct Object *ob); +struct GPUBatch *DRW_cache_text_loose_edges_get(struct Object *ob); +struct GPUBatch *DRW_cache_text_edge_wire_get(struct Object *ob); struct GPUBatch **DRW_cache_text_surface_shaded_get( struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len); struct GPUBatch *DRW_cache_text_face_wireframe_get(Object *ob); @@ -172,6 +174,8 @@ struct GPUBatch *DRW_cache_text_select_overlay_get(struct Object *ob); /* Surface */ struct GPUBatch *DRW_cache_surf_surface_get(struct Object *ob); +struct GPUBatch *DRW_cache_surf_edge_wire_get(struct Object *ob); +struct GPUBatch *DRW_cache_surf_loose_edges_get(struct Object *ob); struct GPUBatch **DRW_cache_surf_surface_shaded_get( struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len); struct GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob); diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index 114d694041e..9fef5a78496 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -119,7 +119,7 @@ void DRW_mesh_weight_state_copy(struct DRW_MeshWeightState *wstate_dst, const st bool DRW_mesh_weight_state_compare(const struct DRW_MeshWeightState *a, const struct DRW_MeshWeightState *b); /* Mesh */ -void DRW_mesh_batch_cache_create_requested(struct Object *ob); +void DRW_mesh_batch_cache_create_requested(struct Object *ob, struct Mesh *me); struct GPUBatch **DRW_mesh_batch_cache_get_surface_shaded( struct Mesh *me, struct GPUMaterial **gpumat_array, uint gpumat_array_len, bool use_hide, diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.c index 1d142053126..06aafb547f9 100644 --- a/source/blender/draw/intern/draw_cache_impl_curve.c +++ b/source/blender/draw/intern/draw_cache_impl_curve.c @@ -35,7 +35,7 @@ #include "DNA_curve_types.h" #include "BKE_curve.h" - +#include "BKE_displist.h" #include "BKE_font.h" #include "GPU_batch.h" @@ -105,21 +105,22 @@ static void curve_render_wire_verts_edges_len_get( BLI_assert(r_vert_len || r_edge_len); int vert_len = 0; int edge_len = 0; - *r_curve_len = 0; + int curve_len = 0; for (const BevList *bl = ob_curve_cache->bev.first; bl; bl = bl->next) { if (bl->nr > 0) { const bool is_cyclic = bl->poly != -1; - /* Curve */ - *r_curve_len += 1; - - /* verts */ + edge_len += (is_cyclic) ? bl->nr : bl->nr - 1; vert_len += bl->nr; - - /* edges */ - edge_len += bl->nr; - if (!is_cyclic) { - edge_len -= 1; - } + curve_len += 1; + } + } + for (const DispList *dl = ob_curve_cache->disp.first; dl; dl = dl->next) { + if (ELEM(dl->type, DL_SEGM, DL_POLY)) { + BLI_assert(dl->parts == 1); + const bool is_cyclic = dl->type == DL_POLY; + edge_len += (is_cyclic) ? dl->nr : dl->nr - 1; + vert_len += dl->nr; + curve_len += 1; } } if (r_vert_len) { @@ -128,6 +129,9 @@ static void curve_render_wire_verts_edges_len_get( if (r_edge_len) { *r_edge_len = edge_len; } + if (r_curve_len) { + *r_curve_len = curve_len; + } } static int curve_render_normal_len_get(const ListBase *lb, const CurveCache *ob_curve_cache) @@ -345,7 +349,6 @@ static void curve_cd_calc_used_gpu_layers(int *cd_layers, struct GPUMaterial **g typedef struct CurveBatchCache { struct { - /* Split by normals if necessary. */ GPUVertBuf *pos_nor; GPUVertBuf *curves_pos; } ordered; @@ -570,6 +573,13 @@ static void curve_create_curves_pos(CurveRenderData *rdata, GPUVertBuf *vbo_curv GPU_vertbuf_attr_set(vbo_curves_pos, attr_id.pos, v_idx, bevp->vec); } } + for (const DispList *dl = rdata->ob_curve_cache->disp.first; dl; dl = dl->next) { + if (ELEM(dl->type, DL_SEGM, DL_POLY)) { + for (int i = 0; i < dl->nr; v_idx++, i++) { + GPU_vertbuf_attr_set(vbo_curves_pos, attr_id.pos, v_idx, &((float(*)[3])dl->verts)[i]); + } + } + } BLI_assert(v_idx == vert_len); } @@ -601,7 +611,19 @@ static void curve_create_curves_lines(CurveRenderData *rdata, GPUIndexBuf *ibo_c GPU_indexbuf_add_primitive_restart(&elb); v_idx += bl->nr; } - + for (const DispList *dl = rdata->ob_curve_cache->disp.first; dl; dl = dl->next) { + if (ELEM(dl->type, DL_SEGM, DL_POLY)) { + const bool is_cyclic = dl->type == DL_POLY; + if (is_cyclic) { + GPU_indexbuf_add_generic_vert(&elb, v_idx + (dl->nr - 1)); + } + for (int i = 0; i < dl->nr; i++) { + GPU_indexbuf_add_generic_vert(&elb, v_idx + i); + } + GPU_indexbuf_add_primitive_restart(&elb); + v_idx += dl->nr; + } + } GPU_indexbuf_build_in_place(&elb, ibo_curve_lines); } @@ -1002,10 +1024,7 @@ void DRW_curve_batch_cache_create_requested(Object *ob) #ifdef DEBUG /* Make sure all requested batches have been setup. */ for (int i = 0; i < sizeof(cache->batch) / sizeof(void *); ++i) { - GPUBatch **batch = (GPUBatch **)&cache->batch; - if (batch[i] != NULL) { - BLI_assert(batch[i]->verts[0] != NULL); - } + BLI_assert(!DRW_batch_requested(((GPUBatch **)&cache->batch)[i], 0)); } #endif diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 66eab91b15e..9fff11d1a68 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -5761,13 +5761,11 @@ void DRW_mesh_cache_uvedit( /** \name Grouped batch generation * \{ */ -void DRW_mesh_batch_cache_create_requested(Object *ob) +/* Can be called for any surface type. Mesh *me is the final mesh. */ +void DRW_mesh_batch_cache_create_requested(Object *UNUSED(ob), Mesh *me) { - BLI_assert(ob->type == OB_MESH); - const bool use_hide = false; /* TODO */ - Mesh *me = (Mesh *)ob->data; MeshBatchCache *cache = mesh_batch_cache_get(me); /* Init batches and request VBOs & IBOs */ |