Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2018-09-06 16:39:27 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2018-09-07 12:54:20 +0300
commitdfeff72af71c1f3a62805253e439cf8ffd3815e6 (patch)
treed9fdf5e9bd92bcc8e9682b3a4b5cb237723e2434
parentcbab3e1e908792a2c9aa1266805ba59e8368727a (diff)
Subdiv: Add ptex offsets to a subdiv structure
This is something what we need to know quite often from various places. Added it as a cached value in Subdiv itself, so it can be queried easily from any area. Shouldn't be a problem from memory usage point of view, it's 4MB per 1M faces coarse mesh. This is very low percentage of mesh itself, and even lower percentage of highres subdivided mesh.
-rw-r--r--source/blender/blenkernel/BKE_subdiv.h12
-rw-r--r--source/blender/blenkernel/intern/subdiv.c23
-rw-r--r--source/blender/blenkernel/intern/subdiv_foreach.c17
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,