[Bf-blender-cvs] [482465e18aa] master: Improve multires performance.

Joseph Eagar noreply at git.blender.org
Tue Jun 8 00:11:39 CEST 2021


Commit: 482465e18aa7c9f74fcb90ec1002f157a580e240
Author: Joseph Eagar
Date:   Mon Jun 7 15:11:14 2021 -0700
Branches: master
https://developer.blender.org/rB482465e18aa7c9f74fcb90ec1002f157a580e240

Improve multires performance.

Added a new api function to stich multires grids
on specific faces in a mesh,
subdiv_ccg_average_faces_boundaries_and_corners,
and changed multires normal calc to use it.

VTune profiling showed that this was a major
performance hit once you get above 10,000 or so
base mesh faces and/or have a high number of
subdivision levels.

Here's a video comparing the difference. Note the
bpy.app_debug switch is not in the final commit.

{F10145323}

And the .blend file:

{F10145346}

Reviewed By: Sergey Sharybin (sergey)

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

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

M	release/datafiles/locale
M	release/scripts/addons
M	release/scripts/addons_contrib
M	source/blender/blenkernel/intern/subdiv_ccg.c
M	source/tools

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

diff --git a/release/datafiles/locale b/release/datafiles/locale
index 2cef4877edc..4833954c0ac 160000
--- a/release/datafiles/locale
+++ b/release/datafiles/locale
@@ -1 +1 @@
-Subproject commit 2cef4877edc40875978c4e95322bb5193f5815bf
+Subproject commit 4833954c0ac85cc407e1d5a153aa11b1d1823ec0
diff --git a/release/scripts/addons b/release/scripts/addons
index 27fe7f3a4f9..e25068ef471 160000
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@ -1 +1 @@
-Subproject commit 27fe7f3a4f964b53af436c4da4ddea337eff0c7e
+Subproject commit e25068ef471c6d6cd5ee64a2eef9b7d672c57029
diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib
index 5a82baad9f9..7d78c8a63f2 160000
--- a/release/scripts/addons_contrib
+++ b/release/scripts/addons_contrib
@@ -1 +1 @@
-Subproject commit 5a82baad9f986722104280e8354a4427d8e9eab1
+Subproject commit 7d78c8a63f2f4b146f9327ddc0d567a5921b94ea
diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c
index a59f9e0c633..5f732ba91ab 100644
--- a/source/blender/blenkernel/intern/subdiv_ccg.c
+++ b/source/blender/blenkernel/intern/subdiv_ccg.c
@@ -28,12 +28,14 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "BLI_ghash.h"
 #include "BLI_math_bits.h"
 #include "BLI_math_vector.h"
 #include "BLI_task.h"
 
 #include "BKE_DerivedMesh.h"
 #include "BKE_ccg.h"
+#include "BKE_global.h"
 #include "BKE_mesh.h"
 #include "BKE_subdiv.h"
 #include "BKE_subdiv_eval.h"
@@ -50,6 +52,11 @@ static void subdiv_ccg_average_inner_face_grids(SubdivCCG *subdiv_ccg,
                                                 CCGKey *key,
                                                 SubdivCCGFace *face);
 
+void subdiv_ccg_average_faces_boundaries_and_corners(SubdivCCG *subdiv_ccg,
+                                                     CCGKey *key,
+                                                     struct CCGFace **effected_faces,
+                                                     int num_effected_faces);
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -889,11 +896,12 @@ void BKE_subdiv_ccg_update_normals(SubdivCCG *subdiv_ccg,
     return;
   }
   subdiv_ccg_recalc_modified_inner_grid_normals(subdiv_ccg, effected_faces, num_effected_faces);
-  /* TODO(sergey): Only average elements which are adjacent to modified
-   * faces. */
+
   CCGKey key;
   BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
-  subdiv_ccg_average_all_boundaries_and_corners(subdiv_ccg, &key);
+
+  subdiv_ccg_average_faces_boundaries_and_corners(
+      subdiv_ccg, &key, effected_faces, num_effected_faces);
 }
 
 /** \} */
@@ -1032,6 +1040,9 @@ static void subdiv_ccg_average_inner_grids_task(void *__restrict userdata_v,
 typedef struct AverageGridsBoundariesData {
   SubdivCCG *subdiv_ccg;
   CCGKey *key;
+
+  /* Optional lookup table. Maps task index to index in `subdiv_ccg->adjacent_vertices`. */
+  int *adjacent_edge_index_map;
 } AverageGridsBoundariesData;
 
 typedef struct AverageGridsBoundariesTLSData {
@@ -1079,10 +1090,14 @@ static void subdiv_ccg_average_grids_boundary(SubdivCCG *subdiv_ccg,
 }
 
 static void subdiv_ccg_average_grids_boundaries_task(void *__restrict userdata_v,
-                                                     const int adjacent_edge_index,
+                                                     const int n,
                                                      const TaskParallelTLS *__restrict tls_v)
 {
   AverageGridsBoundariesData *data = userdata_v;
+  const int adjacent_edge_index = data->adjacent_edge_index_map ?
+                                      data->adjacent_edge_index_map[n] :
+                                      n;
+
   AverageGridsBoundariesTLSData *tls = tls_v->userdata_chunk;
   SubdivCCG *subdiv_ccg = data->subdiv_ccg;
   CCGKey *key = data->key;
@@ -1100,6 +1115,9 @@ static void subdiv_ccg_average_grids_boundaries_free(const void *__restrict UNUS
 typedef struct AverageGridsCornerData {
   SubdivCCG *subdiv_ccg;
   CCGKey *key;
+
+  /* Optional lookup table. Maps task range index to index in subdiv_ccg->adjacent_vertices*/
+  int *adjacent_vert_index_map;
 } AverageGridsCornerData;
 
 static void subdiv_ccg_average_grids_corners(SubdivCCG *subdiv_ccg,
@@ -1128,49 +1146,63 @@ static void subdiv_ccg_average_grids_corners(SubdivCCG *subdiv_ccg,
 }
 
 static void subdiv_ccg_average_grids_corners_task(void *__restrict userdata_v,
-                                                  const int adjacent_vertex_index,
+                                                  const int n,
                                                   const TaskParallelTLS *__restrict UNUSED(tls_v))
 {
   AverageGridsCornerData *data = userdata_v;
+  const int adjacent_vertex_index = data->adjacent_vert_index_map ?
+                                        data->adjacent_vert_index_map[n] :
+                                        n;
   SubdivCCG *subdiv_ccg = data->subdiv_ccg;
   CCGKey *key = data->key;
   SubdivCCGAdjacentVertex *adjacent_vertex = &subdiv_ccg->adjacent_vertices[adjacent_vertex_index];
   subdiv_ccg_average_grids_corners(subdiv_ccg, key, adjacent_vertex);
 }
 
-static void subdiv_ccg_average_all_boundaries(SubdivCCG *subdiv_ccg, CCGKey *key)
+static void subdiv_ccg_average_boundaries(SubdivCCG *subdiv_ccg,
+                                          CCGKey *key,
+                                          int *adjacent_edge_index_map,
+                                          int num_adjacent_edges)
 {
   TaskParallelSettings parallel_range_settings;
   BLI_parallel_range_settings_defaults(&parallel_range_settings);
   AverageGridsBoundariesData boundaries_data = {
-      .subdiv_ccg = subdiv_ccg,
-      .key = key,
-  };
+      .subdiv_ccg = subdiv_ccg, .key = key, .adjacent_edge_index_map = adjacent_edge_index_map};
   AverageGridsBoundariesTLSData tls_data = {NULL};
   parallel_range_settings.userdata_chunk = &tls_data;
   parallel_range_settings.userdata_chunk_size = sizeof(tls_data);
   parallel_range_settings.func_free = subdiv_ccg_average_grids_boundaries_free;
   BLI_task_parallel_range(0,
-                          subdiv_ccg->num_adjacent_edges,
+                          num_adjacent_edges,
                           &boundaries_data,
                           subdiv_ccg_average_grids_boundaries_task,
                           &parallel_range_settings);
 }
 
-static void subdiv_ccg_average_all_corners(SubdivCCG *subdiv_ccg, CCGKey *key)
+static void subdiv_ccg_average_all_boundaries(SubdivCCG *subdiv_ccg, CCGKey *key)
+{
+  subdiv_ccg_average_boundaries(subdiv_ccg, key, NULL, subdiv_ccg->num_adjacent_edges);
+}
+
+static void subdiv_ccg_average_corners(SubdivCCG *subdiv_ccg,
+                                       CCGKey *key,
+                                       int *adjacent_vert_index_map,
+                                       int num_adjacent_vertices)
 {
   TaskParallelSettings parallel_range_settings;
   BLI_parallel_range_settings_defaults(&parallel_range_settings);
   AverageGridsCornerData corner_data = {
-      .subdiv_ccg = subdiv_ccg,
-      .key = key,
-  };
+      .subdiv_ccg = subdiv_ccg, .key = key, .adjacent_vert_index_map = adjacent_vert_index_map};
   BLI_task_parallel_range(0,
-                          subdiv_ccg->num_adjacent_vertices,
+                          num_adjacent_vertices,
                           &corner_data,
                           subdiv_ccg_average_grids_corners_task,
                           &parallel_range_settings);
 }
+static void subdiv_ccg_average_all_corners(SubdivCCG *subdiv_ccg, CCGKey *key)
+{
+  subdiv_ccg_average_corners(subdiv_ccg, key, NULL, subdiv_ccg->num_adjacent_vertices);
+}
 
 static void subdiv_ccg_average_all_boundaries_and_corners(SubdivCCG *subdiv_ccg, CCGKey *key)
 {
@@ -1198,6 +1230,98 @@ void BKE_subdiv_ccg_average_grids(SubdivCCG *subdiv_ccg)
   subdiv_ccg_average_all_boundaries_and_corners(subdiv_ccg, &key);
 }
 
+static void subdiv_ccg_affected_face_adjacency(SubdivCCG *subdiv_ccg,
+                                               struct CCGFace **effected_faces,
+                                               int num_effected_faces,
+                                               GSet *r_adjacent_vertices,
+                                               GSet *r_adjacent_edges)
+{
+  Subdiv *subdiv = subdiv_ccg->subdiv;
+  OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
+
+  StaticOrHeapIntStorage face_vertices_storage;
+  StaticOrHeapIntStorage face_edges_storage;
+
+  static_or_heap_storage_init(&face_vertices_storage);
+  static_or_heap_storage_init(&face_edges_storage);
+
+  for (int i = 0; i < num_effected_faces; i++) {
+    SubdivCCGFace *face = (SubdivCCGFace *)effected_faces[i];
+    int face_index = face - subdiv_ccg->faces;
+    const int num_face_grids = face->num_grids;
+    const int num_face_edges = num_face_grids;
+    int *face_vertices = static_or_heap_storage_get(&face_vertices_storage, num_face_edges);
+    topology_refiner->getFaceVertices(topology_refiner, face_index, face_vertices);
+
+    /* Note that order of edges is same as order of MLoops, which also
+     * means it's the same as order of grids. */
+    int *face_edges = static_or_heap_storage_get(&face_edges_storage, num_face_edges);
+    topology_refiner->getFaceEdges(topology_refiner, face_index, face_edges);
+    for (int corner = 0; corner < num_face_edges; corner++) {
+      const int vertex_index = face_vertices[corner];
+      const int edge_index = face_edges[corner];
+
+      int edge_vertices[2];
+      topology_refiner->getEdgeVertices(topology_refiner, edge_index, edge_vertices);
+
+      SubdivCCGAdjacentEdge *adjacent_edge = &subdiv_ccg->adjacent_edges[edge_index];
+      BLI_gset_add(r_adjacent_edges, adjacent_edge);
+
+      SubdivCCGAdjacentVertex *adjacent_vertex = &subdiv_ccg->adjacent_vertices[vertex_index];
+      BLI_gset_add(r_adjacent_vertices, adjacent_vertex);
+    }
+  }
+
+  static_or_heap_storage_free(&face_vertices_storage);
+  static_or_heap_storage_free(&face_edges_storage);
+}
+
+void subdiv_ccg_average_faces_boundaries_and_corners(SubdivCCG *subdiv_ccg,
+                                              

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list