diff options
-rw-r--r-- | source/blender/blenkernel/BKE_subdiv.h | 12 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subdiv.c | 23 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subdiv_foreach.c | 17 |
3 files changed, 41 insertions, 11 deletions
diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h index 28b2942a70f..4ebb5d1ac66 100644 --- a/source/blender/blenkernel/BKE_subdiv.h +++ b/source/blender/blenkernel/BKE_subdiv.h @@ -144,6 +144,14 @@ typedef struct Subdiv { struct SubdivDisplacement *displacement_evaluator; /* Statistics for debugging. */ SubdivStats stats; + + /* Cached values, are not supposed to be accessed directly. */ + struct { + /* Indexed by base face index, element indicates total number of ptex + *faces created for preceding base faces. + */ + int *face_ptex_offset; + } cache_; } Subdiv; /* ================================ HELPERS ================================= */ @@ -180,4 +188,8 @@ void BKE_subdiv_displacement_attach_from_multires( void BKE_subdiv_displacement_detach(Subdiv *subdiv); +/* ============================ TOPOLOGY HELPERS ============================ */ + +int *BKE_subdiv_face_ptex_offset_get(Subdiv *subdiv); + #endif /* __BKE_SUBDIV_H__ */ diff --git a/source/blender/blenkernel/intern/subdiv.c b/source/blender/blenkernel/intern/subdiv.c index f847d62018a..82275b7305f 100644 --- a/source/blender/blenkernel/intern/subdiv.c +++ b/source/blender/blenkernel/intern/subdiv.c @@ -118,5 +118,28 @@ void BKE_subdiv_free(Subdiv *subdiv) openSubdiv_deleteTopologyRefiner(subdiv->topology_refiner); } BKE_subdiv_displacement_detach(subdiv); + if (subdiv->cache_.face_ptex_offset != NULL) { + MEM_freeN(subdiv->cache_.face_ptex_offset); + } MEM_freeN(subdiv); } + +int *BKE_subdiv_face_ptex_offset_get(Subdiv *subdiv) +{ + if (subdiv->cache_.face_ptex_offset != NULL) { + return subdiv->cache_.face_ptex_offset; + } + const int num_coarse_faces = + subdiv->topology_refiner->getNumFaces(subdiv->topology_refiner); + subdiv->cache_.face_ptex_offset = MEM_malloc_arrayN( + num_coarse_faces, sizeof(int), "subdiv face_ptex_offset"); + int ptex_offset = 0; + for (int face_index = 0; face_index < num_coarse_faces; face_index++) { + const int num_ptex_faces = + subdiv->topology_refiner->getNumFacePtexFaces( + subdiv->topology_refiner, face_index); + subdiv->cache_.face_ptex_offset[face_index] = ptex_offset; + ptex_offset += num_ptex_faces; + } + return subdiv->cache_.face_ptex_offset; +} diff --git a/source/blender/blenkernel/intern/subdiv_foreach.c b/source/blender/blenkernel/intern/subdiv_foreach.c index 8fa060f2931..5c53a0e4126 100644 --- a/source/blender/blenkernel/intern/subdiv_foreach.c +++ b/source/blender/blenkernel/intern/subdiv_foreach.c @@ -229,16 +229,13 @@ static void subdiv_foreach_ctx_init_offsets(SubdivForeachTaskContext *ctx) int vertex_offset = 0; int edge_offset = 0; int polygon_offset = 0; - int face_ptex_offset = 0; for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) { const MPoly *coarse_poly = &coarse_mpoly[poly_index]; const int num_ptex_faces_per_poly = num_ptex_faces_per_poly_get(coarse_poly); - ctx->face_ptex_offset[poly_index] = face_ptex_offset; ctx->subdiv_vertex_offset[poly_index] = vertex_offset; ctx->subdiv_edge_offset[poly_index] = edge_offset; ctx->subdiv_polygon_offset[poly_index] = polygon_offset; - face_ptex_offset += num_ptex_faces_per_poly; if (num_ptex_faces_per_poly == 1) { vertex_offset += resolution_2_squared; edge_offset += num_edges_per_ptex_face_get(resolution - 2) + @@ -265,7 +262,8 @@ static void subdiv_foreach_ctx_init_offsets(SubdivForeachTaskContext *ctx) } } -static void subdiv_foreach_ctx_init(SubdivForeachTaskContext *ctx) +static void subdiv_foreach_ctx_init(Subdiv *subdiv, + SubdivForeachTaskContext *ctx) { const Mesh *coarse_mesh = ctx->coarse_mesh; /* Allocate maps and offsets. */ @@ -285,15 +283,13 @@ static void subdiv_foreach_ctx_init(SubdivForeachTaskContext *ctx) coarse_mesh->totpoly, sizeof(*ctx->subdiv_polygon_offset), "subdiv_edge_offset"); - ctx->face_ptex_offset = MEM_malloc_arrayN(coarse_mesh->totpoly, - sizeof(*ctx->face_ptex_offset), - "face_ptex_offset"); /* Initialize all offsets. */ subdiv_foreach_ctx_init_offsets(ctx); /* Calculate number of geometry in the result subdivision mesh. */ subdiv_foreach_ctx_count(ctx); /* Re-set maps which were used at this step. */ BLI_BITMAP_SET_ALL(ctx->coarse_edges_used_map, false, coarse_mesh->totedge); + ctx->face_ptex_offset = BKE_subdiv_face_ptex_offset_get(subdiv); } static void subdiv_foreach_ctx_free(SubdivForeachTaskContext *ctx) @@ -303,7 +299,6 @@ static void subdiv_foreach_ctx_free(SubdivForeachTaskContext *ctx) MEM_freeN(ctx->subdiv_vertex_offset); MEM_freeN(ctx->subdiv_edge_offset); MEM_freeN(ctx->subdiv_polygon_offset); - MEM_freeN(ctx->face_ptex_offset); } /* ============================================================================= @@ -1982,16 +1977,16 @@ static void subdiv_foreach_finalize(void *__restrict userdata, } bool BKE_subdiv_foreach_subdiv_geometry( - struct Subdiv *UNUSED(subdiv), + Subdiv *subdiv, const SubdivForeachContext *context, const SubdivToMeshSettings *mesh_settings, - const struct Mesh *coarse_mesh) + const Mesh *coarse_mesh) { SubdivForeachTaskContext ctx = {0}; ctx.coarse_mesh = coarse_mesh; ctx.settings = mesh_settings; ctx.foreach_context = context; - subdiv_foreach_ctx_init(&ctx); + subdiv_foreach_ctx_init(subdiv, &ctx); if (context->topology_info != NULL) { if (!context->topology_info(context, ctx.num_subdiv_vertices, |