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
This commit is contained in:
parent
e4b3fe4b69
commit
f371e633f9
Notes:
blender-bot
2023-02-14 05:50:03 +01:00
Referenced by issue #58298, Nurbs circle and curve dont draw in objectmode Referenced by issue #58107, Modified curves/surfaces/fonts do not show their evaluated mesh, only the displist.
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -2682,7 +2682,21 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
|
|||
break;
|
||||
}
|
||||
case OB_SURF:
|
||||
{
|
||||
if (hide_object_extra) {
|
||||
break;
|
||||
}
|
||||
struct GPUBatch *geom = DRW_cache_surf_edge_wire_get(ob);
|
||||
if (geom == NULL) {
|
||||
break;
|
||||
}
|
||||
if (theme_id == TH_UNDEFINED) {
|
||||
theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
|
||||
}
|
||||
DRWShadingGroup *shgroup = shgroup_theme_id_to_wire_or(sgl, theme_id, sgl->wire);
|
||||
DRW_shgroup_call_object_add(shgroup, geom, ob);
|
||||
break;
|
||||
}
|
||||
case OB_LATTICE:
|
||||
{
|
||||
if (ob != draw_ctx->object_edit && !BKE_object_is_in_editmode(ob)) {
|
||||
|
|
Loading…
Reference in New Issue