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(¶llel_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, ¶llel_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(¶llel_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, ¶llel_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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs