[Bf-blender-cvs] [b8d9b5e3315] master: Sculpt: Delay Viewport Updates

Pablo Dobarro noreply at git.blender.org
Thu Apr 2 18:01:56 CEST 2020


Commit: b8d9b5e3315232bb157de43713ec2a54433cf9a6
Author: Pablo Dobarro
Date:   Thu Mar 12 17:51:39 2020 +0100
Branches: master
https://developer.blender.org/rBb8d9b5e3315232bb157de43713ec2a54433cf9a6

Sculpt: Delay Viewport Updates

In Blender 2.81 we update and draw all nodes inside the view planes.
When navigating with a pen tablet after an operation that tags the whole
mesh to update (like undo or inverting the mask), this introduces some
lag as nodes are updating when they enter the view. The viewport is not
fully responsive again until all nodes have entered the view after the
operation.

This commit delays nodes updates until the view navigation stops, so the
viewport navigation is always fully responsive. This introduces some
artifacts while navigating,  so it can be disabled if you don't want to
see them.

I'm storing the update planes in the PBVH. This way I can add support
for some tools to update in real-time only the nodes inside this plane
while running the operator, like the mesh filter.

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D6269

===================================================================

M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/draw/intern/draw_manager_data.c
M	source/blender/makesdna/DNA_scene_types.h
M	source/blender/makesrna/intern/rna_sculpt_paint.c

===================================================================

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);



More information about the Bf-blender-cvs mailing list