diff options
-rw-r--r-- | source/blender/blenkernel/BKE_pbvh.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pbvh.c | 27 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_data.c | 12 |
3 files changed, 30 insertions, 10 deletions
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index fa773ce78d9..426f81d889a 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -174,6 +174,7 @@ bool BKE_pbvh_node_find_nearest_to_ray(PBVH *bvh, void BKE_pbvh_draw_cb(PBVH *bvh, bool show_vcol, + bool update_only_visible, PBVHFrustumPlanes *frustum, void (*draw_fn)(void *user_data, struct GPU_PBVH_Buffers *buffers), void *user_data); diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 50ea4fb0b36..781e7b712d6 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -2287,6 +2287,7 @@ void BKE_pbvh_update_normals(PBVH *bvh, struct SubdivCCG *subdiv_ccg) */ typedef struct PBVHDrawSearchData { PBVHFrustumPlanes *frustum; + int accum_update_flag; } PBVHDrawSearchData; static bool pbvh_draw_search_cb(PBVHNode *node, void *data_v) @@ -2296,11 +2297,13 @@ static bool pbvh_draw_search_cb(PBVHNode *node, void *data_v) return false; } + data->accum_update_flag |= node->flag; return true; } void BKE_pbvh_draw_cb(PBVH *bvh, bool show_vcol, + bool update_only_visible, PBVHFrustumPlanes *frustum, void (*draw_fn)(void *user_data, GPU_PBVH_Buffers *buffers), void *user_data) @@ -2308,22 +2311,30 @@ void BKE_pbvh_draw_cb(PBVH *bvh, PBVHNode **nodes; int totnode; - /* Update all draw buffers. */ const int update_flag = PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers; - BKE_pbvh_search_gather(bvh, update_search_cb, POINTER_FROM_INT(update_flag), &nodes, &totnode); - if (totnode) { - pbvh_update_draw_buffers(bvh, nodes, totnode, show_vcol, update_flag); - } + if (!update_only_visible) { + /* Update all draw buffers, also those outside the view. */ + BKE_pbvh_search_gather(bvh, update_search_cb, POINTER_FROM_INT(update_flag), &nodes, &totnode); - if (nodes) { - MEM_freeN(nodes); + if (totnode) { + pbvh_update_draw_buffers(bvh, nodes, totnode, show_vcol, update_flag); + } + + if (nodes) { + MEM_freeN(nodes); + } } /* Gather visible nodes. */ - PBVHDrawSearchData data = {.frustum = frustum}; + PBVHDrawSearchData data = {.frustum = frustum, .accum_update_flag = 0}; BKE_pbvh_search_gather(bvh, pbvh_draw_search_cb, &data, &nodes, &totnode); + if (update_only_visible && (data.accum_update_flag & update_flag)) { + /* Update draw buffers in visible nodes. */ + pbvh_update_draw_buffers(bvh, nodes, totnode, show_vcol, data.accum_update_flag); + } + /* Draw. */ for (int a = 0; a < totnode; a++) { PBVHNode *node = nodes[a]; diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index e978ae44bcd..e3d4228ec33 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -923,11 +923,19 @@ static void drw_sculpt_generate_calls(DRWSculptCallbackData *scd, bool use_vcol) } } + /* Update draw buffers only for visible nodes while painting. + * But do update them otherwise so navigating stays smooth. */ + const bool update_only_visible = rv3d && (rv3d->rflag & RV3D_PAINTING); + Mesh *mesh = scd->ob->data; BKE_pbvh_update_normals(pbvh, mesh->runtime.subdiv_ccg); - BKE_pbvh_draw_cb( - pbvh, use_vcol, &frustum, (void (*)(void *, GPU_PBVH_Buffers *))sculpt_draw_cb, scd); + BKE_pbvh_draw_cb(pbvh, + use_vcol, + update_only_visible, + &frustum, + (void (*)(void *, GPU_PBVH_Buffers *))sculpt_draw_cb, + scd); if (SCULPT_DEBUG_BUFFERS) { int debug_node_nr = 0; |