diff options
-rw-r--r-- | release/scripts/startup/bl_ui/space_view3d_toolbar.py | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_pbvh.h | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pbvh.c | 29 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pbvh_intern.h | 3 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_data.c | 53 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_sculpt_paint.c | 8 |
7 files changed, 89 insertions, 13 deletions
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 351b72f79fb..6aaeec3f3cf 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -903,6 +903,8 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel): col = flow.column() col.prop(sculpt, "show_low_resolution") col = flow.column() + col.prop(sculpt, "use_sculpt_delay_updates") + col = flow.column() col.prop(sculpt, "use_deform_only") col = flow.column() diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 2020d45ae86..a59ce816e26 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -81,6 +81,9 @@ typedef struct PBVHFrustumPlanes { int num_planes; } PBVHFrustumPlanes; +void BKE_pbvh_set_frustum_planes(PBVH *bvh, PBVHFrustumPlanes *planes); +void BKE_pbvh_get_frustum_planes(PBVH *bvh, PBVHFrustumPlanes *planes); + /* Callbacks */ /* returns 1 if the search should continue from this node, 0 otherwise */ @@ -190,7 +193,8 @@ 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, + PBVHFrustumPlanes *update_frustum, + PBVHFrustumPlanes *draw_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 879f1e507ba..06622f0d009 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -2683,7 +2683,8 @@ static bool pbvh_draw_search_cb(PBVHNode *node, void *data_v) void BKE_pbvh_draw_cb(PBVH *bvh, bool show_vcol, bool update_only_visible, - PBVHFrustumPlanes *frustum, + PBVHFrustumPlanes *update_frustum, + PBVHFrustumPlanes *draw_frustum, void (*draw_fn)(void *user_data, GPU_PBVH_Buffers *buffers), void *user_data) { @@ -2704,7 +2705,7 @@ void BKE_pbvh_draw_cb(PBVH *bvh, } /* Gather visible nodes. */ - PBVHDrawSearchData data = {.frustum = frustum, .accum_update_flag = 0}; + PBVHDrawSearchData data = {.frustum = update_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)) { @@ -2722,7 +2723,15 @@ void BKE_pbvh_draw_cb(PBVH *bvh, } node->flag &= ~(PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers); + } + + MEM_SAFE_FREE(nodes); + + PBVHDrawSearchData draw_data = {.frustum = draw_frustum, .accum_update_flag = 0}; + BKE_pbvh_search_gather(bvh, pbvh_draw_search_cb, &draw_data, &nodes, &totnode); + for (int a = 0; a < totnode; a++) { + PBVHNode *node = nodes[a]; if (!(node->flag & PBVH_FullyHidden)) { draw_fn(user_data, node->draw_buffers); } @@ -2998,6 +3007,22 @@ void pbvh_show_face_sets_set(PBVH *bvh, bool show_face_sets) bvh->show_face_sets = show_face_sets; } +void BKE_pbvh_set_frustum_planes(PBVH *bvh, PBVHFrustumPlanes *planes) +{ + bvh->num_planes = planes->num_planes; + for (int i = 0; i < bvh->num_planes; i++) { + copy_v4_v4(bvh->planes[i], planes->planes[i]); + } +} + +void BKE_pbvh_get_frustum_planes(PBVH *bvh, PBVHFrustumPlanes *planes) +{ + planes->num_planes = bvh->num_planes; + for (int i = 0; i < planes->num_planes; i++) { + copy_v4_v4(planes->planes[i], bvh->planes[i]); + } +} + void BKE_pbvh_parallel_range_settings(PBVHParallelSettings *settings, bool use_threading, int totnode) diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h index 21cb5649330..d3e42ac7705 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.h +++ b/source/blender/blenkernel/intern/pbvh_intern.h @@ -168,6 +168,9 @@ struct PBVH { int cd_vert_node_offset; int cd_face_node_offset; + float planes[6][4]; + int num_planes; + struct BMLog *bm_log; struct SubdivCCG *subdiv_ccg; }; diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index 94a3e9e8343..1d1ca575b02 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -884,7 +884,11 @@ static float sculpt_debug_colors[9][4] = { static void sculpt_draw_cb(DRWSculptCallbackData *scd, GPU_PBVH_Buffers *buffers) { + if (!buffers) { + return; + } + /* Meh... use_mask is a bit misleading here. */ if (scd->use_mask && !GPU_pbvh_buffers_has_overlays(buffers)) { return; } @@ -958,24 +962,52 @@ static void drw_sculpt_generate_calls(DRWSculptCallbackData *scd, bool use_vcol) const DRWContextState *drwctx = DRW_context_state_get(); RegionView3D *rv3d = drwctx->rv3d; + const bool navigating = rv3d && (rv3d->rflag & RV3D_NAVIGATING); + + Paint *p = NULL; + if (drwctx->evil_C != NULL) { + p = BKE_paint_get_active_from_context(drwctx->evil_C); + } /* Frustum planes to show only visible PBVH nodes. */ - float planes[6][4]; - drw_sculpt_get_frustum_planes(scd->ob, planes); - PBVHFrustumPlanes frustum = {.planes = planes, .num_planes = 6}; + float update_planes[6][4]; + float draw_planes[6][4]; + PBVHFrustumPlanes update_frustum; + PBVHFrustumPlanes draw_frustum; + + if (p && (p->flags & PAINT_SCULPT_DELAY_UPDATES)) { + update_frustum.planes = update_planes; + update_frustum.num_planes = 6; + BKE_pbvh_get_frustum_planes(pbvh, &update_frustum); + if (!navigating) { + drw_sculpt_get_frustum_planes(scd->ob, update_planes); + update_frustum.planes = update_planes; + update_frustum.num_planes = 6; + BKE_pbvh_set_frustum_planes(pbvh, &update_frustum); + } + } + else { + drw_sculpt_get_frustum_planes(scd->ob, update_planes); + update_frustum.planes = update_planes; + update_frustum.num_planes = 6; + } + + drw_sculpt_get_frustum_planes(scd->ob, draw_planes); + draw_frustum.planes = draw_planes; + draw_frustum.num_planes = 6; /* Fast mode to show low poly multires while navigating. */ scd->fast_mode = false; - if (drwctx->evil_C != NULL) { - Paint *p = BKE_paint_get_active_from_context(drwctx->evil_C); - if (p && (p->flags & PAINT_FAST_NAVIGATE)) { - scd->fast_mode = rv3d && (rv3d->rflag & RV3D_NAVIGATING); - } + if (p && (p->flags & PAINT_FAST_NAVIGATE)) { + scd->fast_mode = rv3d && (rv3d->rflag & RV3D_NAVIGATING); } /* 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); + bool update_only_visible = rv3d && !(rv3d->rflag & RV3D_PAINTING); + if (p && (p->flags & PAINT_SCULPT_DELAY_UPDATES)) { + update_only_visible = true; + } Mesh *mesh = scd->ob->data; BKE_pbvh_update_normals(pbvh, mesh->runtime.subdiv_ccg); @@ -983,7 +1015,8 @@ static void drw_sculpt_generate_calls(DRWSculptCallbackData *scd, bool use_vcol) BKE_pbvh_draw_cb(pbvh, use_vcol, update_only_visible, - &frustum, + &update_frustum, + &draw_frustum, (void (*)(void *, GPU_PBVH_Buffers *))sculpt_draw_cb, scd); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 62640a2ce54..f4834355223 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -2137,6 +2137,7 @@ typedef enum ePaintFlags { PAINT_FAST_NAVIGATE = (1 << 1), PAINT_SHOW_BRUSH_ON_SURFACE = (1 << 2), PAINT_USE_CAVITY_MASK = (1 << 3), + PAINT_SCULPT_DELAY_UPDATES = (1 << 4), } ePaintFlags; /* Paint.symmetry_flags diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index f1a5cb79db4..f2d5c465dac 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -617,6 +617,14 @@ static void rna_def_paint(BlenderRNA *brna) prop, "Fast Navigate", "For multires, show low resolution while navigating the view"); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + prop = RNA_def_property(srna, "use_sculpt_delay_updates", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", PAINT_SCULPT_DELAY_UPDATES); + RNA_def_property_ui_text( + prop, + "Delay Viewport Updates", + "Update the geometry when it enters the view, providing faster view navigation"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + prop = RNA_def_property(srna, "input_samples", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "num_input_samples"); RNA_def_property_ui_range(prop, 1, PAINT_MAX_INPUT_SAMPLES, 1, -1); |