[Bf-blender-cvs] [dfeff72af71] blender2.8: Subdiv: Add ptex offsets to a subdiv structure

Sergey Sharybin noreply at git.blender.org
Fri Sep 7 11:56:28 CEST 2018


Commit: dfeff72af71c1f3a62805253e439cf8ffd3815e6
Author: Sergey Sharybin
Date:   Thu Sep 6 15:39:27 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBdfeff72af71c1f3a62805253e439cf8ffd3815e6

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.

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

M	source/blender/blenkernel/BKE_subdiv.h
M	source/blender/blenkernel/intern/subdiv.c
M	source/blender/blenkernel/intern/subdiv_foreach.c

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

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,



More information about the Bf-blender-cvs mailing list