diff options
author | Hans Goudey <h.goudey@me.com> | 2022-09-05 19:56:34 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-09-05 19:56:34 +0300 |
commit | 05952aa94d33eeb504fa63618ba35c2bcc8bd19b (patch) | |
tree | c9ec37adf20c3c37ccaab44869220dcbe8e987a3 /source/blender/blenkernel/intern/subdiv_foreach.c | |
parent | 63cfc8f9f6d623f33b50c5c07976af2b22845713 (diff) |
Mesh: Remove redundant custom data pointers
For copy-on-write, we want to share attribute arrays between meshes
where possible. Mutable pointers like `Mesh.mvert` make that difficult
by making ownership vague. They also make code more complex by adding
redundancy.
The simplest solution is just removing them and retrieving layers from
`CustomData` as needed. Similar changes have already been applied to
curves and point clouds (e9f82d3dc7ee, 410a6efb747f). Removing use of
the pointers generally makes code more obvious and more reusable.
Mesh data is now accessed with a C++ API (`Mesh::edges()` or
`Mesh::edges_for_write()`), and a C API (`BKE_mesh_edges(mesh)`).
The CoW changes this commit makes possible are described in T95845
and T95842, and started in D14139 and D14140. The change also simplifies
the ongoing mesh struct-of-array refactors from T95965.
**RNA/Python Access Performance**
Theoretically, accessing mesh elements with the RNA API may become
slower, since the layer needs to be found on every random access.
However, overhead is already high enough that this doesn't make a
noticible differenc, and performance is actually improved in some
cases. Random access can be up to 10% faster, but other situations
might be a bit slower. Generally using `foreach_get/set` are the best
way to improve performance. See the differential revision for more
discussion about Python performance.
Cycles has been updated to use raw pointers and the internal Blender
mesh types, mostly because there is no sense in having this overhead
when it's already compiled with Blender. In my tests this roughly
halves the Cycles mesh creation time (0.19s to 0.10s for a 1 million
face grid).
Differential Revision: https://developer.blender.org/D15488
Diffstat (limited to 'source/blender/blenkernel/intern/subdiv_foreach.c')
-rw-r--r-- | source/blender/blenkernel/intern/subdiv_foreach.c | 85 |
1 files changed, 45 insertions, 40 deletions
diff --git a/source/blender/blenkernel/intern/subdiv_foreach.c b/source/blender/blenkernel/intern/subdiv_foreach.c index 80364561d01..ac402ceaca0 100644 --- a/source/blender/blenkernel/intern/subdiv_foreach.c +++ b/source/blender/blenkernel/intern/subdiv_foreach.c @@ -158,8 +158,8 @@ static void subdiv_foreach_ctx_count(SubdivForeachTaskContext *ctx) const int num_inner_vertices_per_noquad_patch = (no_quad_patch_resolution - 2) * (no_quad_patch_resolution - 2); const Mesh *coarse_mesh = ctx->coarse_mesh; - const MLoop *coarse_mloop = coarse_mesh->mloop; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); ctx->num_subdiv_vertices = coarse_mesh->totvert; ctx->num_subdiv_edges = coarse_mesh->totedge * (num_subdiv_vertices_per_coarse_edge + 1); /* Calculate extra vertices and edges created by non-loose geometry. */ @@ -225,7 +225,7 @@ static void subdiv_foreach_ctx_init_offsets(SubdivForeachTaskContext *ctx) ctx->edge_inner_offset = ctx->edge_boundary_offset + coarse_mesh->totedge * num_subdiv_edges_per_coarse_edge; /* "Indexed" offsets. */ - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); int vertex_offset = 0; int edge_offset = 0; int polygon_offset = 0; @@ -301,8 +301,9 @@ static void subdiv_foreach_corner_vertices_regular_do( { const float weights[4][2] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}}; const Mesh *coarse_mesh = ctx->coarse_mesh; - const MLoop *coarse_mloop = coarse_mesh->mloop; - const int coarse_poly_index = coarse_poly - coarse_mesh->mpoly; + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const int coarse_poly_index = coarse_poly - coarse_mpoly; const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; for (int corner = 0; corner < coarse_poly->totloop; corner++) { const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner]; @@ -342,8 +343,9 @@ static void subdiv_foreach_corner_vertices_special_do( bool check_usage) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const MLoop *coarse_mloop = coarse_mesh->mloop; - const int coarse_poly_index = coarse_poly - coarse_mesh->mpoly; + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const int coarse_poly_index = coarse_poly - coarse_mpoly; int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) { const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner]; @@ -407,7 +409,7 @@ static void subdiv_foreach_every_corner_vertices(SubdivForeachTaskContext *ctx, return; } const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) { const MPoly *coarse_poly = &coarse_mpoly[poly_index]; if (coarse_poly->totloop == 4) { @@ -432,11 +434,11 @@ static void subdiv_foreach_edge_vertices_regular_do(SubdivForeachTaskContext *ct const float inv_resolution_1 = 1.0f / (float)resolution_1; const int num_subdiv_vertices_per_coarse_edge = resolution - 2; const Mesh *coarse_mesh = ctx->coarse_mesh; - const MEdge *coarse_medge = coarse_mesh->medge; - const MLoop *coarse_mloop = coarse_mesh->mloop; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh); + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); const int coarse_poly_index = coarse_poly - coarse_mpoly; - const int poly_index = coarse_poly - coarse_mesh->mpoly; + const int poly_index = coarse_poly - coarse_mpoly; const int ptex_face_index = ctx->face_ptex_offset[poly_index]; for (int corner = 0; corner < coarse_poly->totloop; corner++) { const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner]; @@ -499,11 +501,11 @@ static void subdiv_foreach_edge_vertices_special_do(SubdivForeachTaskContext *ct const int num_vertices_per_ptex_edge = ((resolution >> 1) + 1); const float inv_ptex_resolution_1 = 1.0f / (float)(num_vertices_per_ptex_edge - 1); const Mesh *coarse_mesh = ctx->coarse_mesh; - const MEdge *coarse_medge = coarse_mesh->medge; - const MLoop *coarse_mloop = coarse_mesh->mloop; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh); + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); const int coarse_poly_index = coarse_poly - coarse_mpoly; - const int poly_index = coarse_poly - coarse_mesh->mpoly; + const int poly_index = coarse_poly - coarse_mpoly; const int ptex_face_start_index = ctx->face_ptex_offset[poly_index]; int ptex_face_index = ptex_face_start_index; for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) { @@ -595,7 +597,7 @@ static void subdiv_foreach_every_edge_vertices(SubdivForeachTaskContext *ctx, vo return; } const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) { const MPoly *coarse_poly = &coarse_mpoly[poly_index]; if (coarse_poly->totloop == 4) { @@ -616,7 +618,8 @@ static void subdiv_foreach_inner_vertices_regular(SubdivForeachTaskContext *ctx, const int resolution = ctx->settings->resolution; const float inv_resolution_1 = 1.0f / (float)(resolution - 1); const Mesh *coarse_mesh = ctx->coarse_mesh; - const int coarse_poly_index = coarse_poly - coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const int coarse_poly_index = coarse_poly - coarse_mpoly; const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; const int start_vertex_index = ctx->subdiv_vertex_offset[coarse_poly_index]; int subdiv_vertex_index = ctx->vertices_inner_offset + start_vertex_index; @@ -644,7 +647,8 @@ static void subdiv_foreach_inner_vertices_special(SubdivForeachTaskContext *ctx, const int ptex_face_resolution = ptex_face_resolution_get(coarse_poly, resolution); const float inv_ptex_face_resolution_1 = 1.0f / (float)(ptex_face_resolution - 1); const Mesh *coarse_mesh = ctx->coarse_mesh; - const int coarse_poly_index = coarse_poly - coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const int coarse_poly_index = coarse_poly - coarse_mpoly; int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; const int start_vertex_index = ctx->subdiv_vertex_offset[coarse_poly_index]; int subdiv_vertex_index = ctx->vertices_inner_offset + start_vertex_index; @@ -691,7 +695,7 @@ static void subdiv_foreach_inner_vertices(SubdivForeachTaskContext *ctx, static void subdiv_foreach_vertices(SubdivForeachTaskContext *ctx, void *tls, const int poly_index) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); const MPoly *coarse_poly = &coarse_mpoly[poly_index]; if (ctx->foreach_context->vertex_inner != NULL) { subdiv_foreach_inner_vertices(ctx, tls, coarse_poly); @@ -775,9 +779,9 @@ static void subdiv_foreach_edges_all_patches_regular(SubdivForeachTaskContext *c const MPoly *coarse_poly) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const MEdge *coarse_medge = coarse_mesh->medge; - const MLoop *coarse_mloop = coarse_mesh->mloop; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh); + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); const int poly_index = coarse_poly - coarse_mpoly; const int resolution = ctx->settings->resolution; const int start_vertex_index = ctx->vertices_inner_offset + @@ -856,9 +860,9 @@ static void subdiv_foreach_edges_all_patches_special(SubdivForeachTaskContext *c const MPoly *coarse_poly) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const MEdge *coarse_medge = coarse_mesh->medge; - const MLoop *coarse_mloop = coarse_mesh->mloop; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh); + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); const int poly_index = coarse_poly - coarse_mpoly; const int resolution = ctx->settings->resolution; const int ptex_face_resolution = ptex_face_resolution_get(coarse_poly, resolution); @@ -984,7 +988,7 @@ static void subdiv_foreach_edges_all_patches(SubdivForeachTaskContext *ctx, static void subdiv_foreach_edges(SubdivForeachTaskContext *ctx, void *tls, int poly_index) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); const MPoly *coarse_poly = &coarse_mpoly[poly_index]; subdiv_foreach_edges_all_patches(ctx, tls, coarse_poly); } @@ -994,7 +998,7 @@ static void subdiv_foreach_boundary_edges(SubdivForeachTaskContext *ctx, int coarse_edge_index) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const MEdge *coarse_medge = coarse_mesh->medge; + const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh); const MEdge *coarse_edge = &coarse_medge[coarse_edge_index]; const int resolution = ctx->settings->resolution; const int num_subdiv_vertices_per_coarse_edge = resolution - 2; @@ -1125,9 +1129,9 @@ static void subdiv_foreach_loops_regular(SubdivForeachTaskContext *ctx, const int resolution = ctx->settings->resolution; /* Base/coarse mesh information. */ const Mesh *coarse_mesh = ctx->coarse_mesh; - const MEdge *coarse_medge = coarse_mesh->medge; - const MLoop *coarse_mloop = coarse_mesh->mloop; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh); + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); const int coarse_poly_index = coarse_poly - coarse_mpoly; const int ptex_resolution = ptex_face_resolution_get(coarse_poly, resolution); const int ptex_inner_resolution = ptex_resolution - 2; @@ -1319,9 +1323,9 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx, const int resolution = ctx->settings->resolution; /* Base/coarse mesh information. */ const Mesh *coarse_mesh = ctx->coarse_mesh; - const MEdge *coarse_medge = coarse_mesh->medge; - const MLoop *coarse_mloop = coarse_mesh->mloop; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh); + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); const int coarse_poly_index = coarse_poly - coarse_mpoly; const int ptex_face_resolution = ptex_face_resolution_get(coarse_poly, resolution); const int ptex_face_inner_resolution = ptex_face_resolution - 2; @@ -1654,7 +1658,7 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx, static void subdiv_foreach_loops(SubdivForeachTaskContext *ctx, void *tls, int poly_index) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); const MPoly *coarse_poly = &coarse_mpoly[poly_index]; if (coarse_poly->totloop == 4) { subdiv_foreach_loops_regular(ctx, tls, coarse_poly); @@ -1676,7 +1680,7 @@ static void subdiv_foreach_polys(SubdivForeachTaskContext *ctx, void *tls, int p const int start_poly_index = ctx->subdiv_polygon_offset[poly_index]; /* Base/coarse mesh information. */ const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); const MPoly *coarse_poly = &coarse_mpoly[poly_index]; const int num_ptex_faces_per_poly = num_ptex_faces_per_poly_get(coarse_poly); const int ptex_resolution = ptex_face_resolution_get(coarse_poly, resolution); @@ -1731,7 +1735,8 @@ static void subdiv_foreach_vertices_of_loose_edges_task(void *__restrict userdat const float inv_resolution_1 = 1.0f / (float)resolution_1; const int num_subdiv_vertices_per_coarse_edge = resolution - 2; const Mesh *coarse_mesh = ctx->coarse_mesh; - const MEdge *coarse_edge = &coarse_mesh->medge[coarse_edge_index]; + const MEdge *coarse_edges = BKE_mesh_edges(coarse_mesh); + const MEdge *coarse_edge = &coarse_edges[coarse_edge_index]; /* Subdivision vertices which corresponds to edge's v1 and v2. */ const int subdiv_v1_index = ctx->vertices_corner_offset + coarse_edge->v1; const int subdiv_v2_index = ctx->vertices_corner_offset + coarse_edge->v2; @@ -1768,7 +1773,7 @@ static void subdiv_foreach_single_geometry_vertices(SubdivForeachTaskContext *ct return; } const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) { const MPoly *coarse_poly = &coarse_mpoly[poly_index]; subdiv_foreach_corner_vertices(ctx, tls, coarse_poly); @@ -1779,8 +1784,8 @@ static void subdiv_foreach_single_geometry_vertices(SubdivForeachTaskContext *ct static void subdiv_foreach_mark_non_loose_geometry(SubdivForeachTaskContext *ctx) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; - const MLoop *coarse_mloop = coarse_mesh->mloop; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) { const MPoly *coarse_poly = &coarse_mpoly[poly_index]; for (int corner = 0; corner < coarse_poly->totloop; corner++) { |