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:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/blenkernel/intern/subdiv_foreach.c
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/blenkernel/intern/subdiv_foreach.c')
-rw-r--r--source/blender/blenkernel/intern/subdiv_foreach.c3309
1 files changed, 1549 insertions, 1760 deletions
diff --git a/source/blender/blenkernel/intern/subdiv_foreach.c b/source/blender/blenkernel/intern/subdiv_foreach.c
index bb01bfd587a..98afbef6c0a 100644
--- a/source/blender/blenkernel/intern/subdiv_foreach.c
+++ b/source/blender/blenkernel/intern/subdiv_foreach.c
@@ -47,34 +47,32 @@
/* Number of ptex faces for a given polygon. */
BLI_INLINE int num_ptex_faces_per_poly_get(const MPoly *poly)
{
- return (poly->totloop == 4) ? 1 : poly->totloop;
+ return (poly->totloop == 4) ? 1 : poly->totloop;
}
BLI_INLINE int num_edges_per_ptex_face_get(const int resolution)
{
- return 2 * (resolution - 1) * resolution;
+ return 2 * (resolution - 1) * resolution;
}
BLI_INLINE int num_inner_edges_per_ptex_face_get(const int resolution)
{
- if (resolution < 2) {
- return 0;
- }
- return (resolution - 2) * resolution +
- (resolution - 1) * (resolution - 1);
+ if (resolution < 2) {
+ return 0;
+ }
+ return (resolution - 2) * resolution + (resolution - 1) * (resolution - 1);
}
/* Number of subdivision polygons per ptex face. */
BLI_INLINE int num_polys_per_ptex_get(const int resolution)
{
- return (resolution - 1) * (resolution - 1);
+ return (resolution - 1) * (resolution - 1);
}
/* Subdivision resolution per given polygon's ptex faces. */
BLI_INLINE int ptex_face_resolution_get(const MPoly *poly, int resolution)
{
- return (poly->totloop == 4) ? (resolution)
- : ((resolution >> 1) + 1);
+ return (poly->totloop == 4) ? (resolution) : ((resolution >> 1) + 1);
}
/* =============================================================================
@@ -82,46 +80,46 @@ BLI_INLINE int ptex_face_resolution_get(const MPoly *poly, int resolution)
*/
typedef struct SubdivForeachTaskContext {
- const Mesh *coarse_mesh;
- const SubdivToMeshSettings *settings;
- /* Callbacks. */
- const SubdivForeachContext *foreach_context;
- /* Counters of geometry in subdivided mesh, initialized as a part of
- * offsets calculation.
- */
- int num_subdiv_vertices;
- int num_subdiv_edges;
- int num_subdiv_loops;
- int num_subdiv_polygons;
- /* Offsets of various geometry in the subdivision mesh arrays. */
- int vertices_corner_offset;
- int vertices_edge_offset;
- int vertices_inner_offset;
- int edge_boundary_offset;
- int edge_inner_offset;
- /* Indexed by coarse polygon index, indicates offset in subdivided mesh
- * vertices, edges and polygons arrays, where first element of the poly
- * begins.
- */
- int *subdiv_vertex_offset;
- int *subdiv_edge_offset;
- int *subdiv_polygon_offset;
- /* Indexed by base face index, element indicates total number of ptex faces
- * created for preceding base faces.
- */
- int *face_ptex_offset;
- /* Bitmap indicating whether vertex was used already or not.
- * - During patch evaluation indicates whether coarse vertex was already
- * evaluated and its position on limit is already known.
- */
- BLI_bitmap *coarse_vertices_used_map;
- /* Bitmap indicating whether edge was used already or not. This includes:
- * - During context initialization it indicates whether subdivided vertices
- * for corresponding edge were already calculated or not.
- * - During patch evaluation it indicates whether vertices along this edge
- * were already evaluated.
- */
- BLI_bitmap *coarse_edges_used_map;
+ const Mesh *coarse_mesh;
+ const SubdivToMeshSettings *settings;
+ /* Callbacks. */
+ const SubdivForeachContext *foreach_context;
+ /* Counters of geometry in subdivided mesh, initialized as a part of
+ * offsets calculation.
+ */
+ int num_subdiv_vertices;
+ int num_subdiv_edges;
+ int num_subdiv_loops;
+ int num_subdiv_polygons;
+ /* Offsets of various geometry in the subdivision mesh arrays. */
+ int vertices_corner_offset;
+ int vertices_edge_offset;
+ int vertices_inner_offset;
+ int edge_boundary_offset;
+ int edge_inner_offset;
+ /* Indexed by coarse polygon index, indicates offset in subdivided mesh
+ * vertices, edges and polygons arrays, where first element of the poly
+ * begins.
+ */
+ int *subdiv_vertex_offset;
+ int *subdiv_edge_offset;
+ int *subdiv_polygon_offset;
+ /* Indexed by base face index, element indicates total number of ptex faces
+ * created for preceding base faces.
+ */
+ int *face_ptex_offset;
+ /* Bitmap indicating whether vertex was used already or not.
+ * - During patch evaluation indicates whether coarse vertex was already
+ * evaluated and its position on limit is already known.
+ */
+ BLI_bitmap *coarse_vertices_used_map;
+ /* Bitmap indicating whether edge was used already or not. This includes:
+ * - During context initialization it indicates whether subdivided vertices
+ * for corresponding edge were already calculated or not.
+ * - During patch evaluation it indicates whether vertices along this edge
+ * were already evaluated.
+ */
+ BLI_bitmap *coarse_edges_used_map;
} SubdivForeachTaskContext;
/* =============================================================================
@@ -130,26 +128,24 @@ typedef struct SubdivForeachTaskContext {
static void *subdiv_foreach_tls_alloc(SubdivForeachTaskContext *ctx)
{
- const SubdivForeachContext *foreach_context = ctx->foreach_context;
- void *tls = NULL;
- if (foreach_context->user_data_tls_size != 0) {
- tls = MEM_mallocN(foreach_context->user_data_tls_size, "tls");
- memcpy(tls,
- foreach_context->user_data_tls,
- foreach_context->user_data_tls_size);
- }
- return tls;
+ const SubdivForeachContext *foreach_context = ctx->foreach_context;
+ void *tls = NULL;
+ if (foreach_context->user_data_tls_size != 0) {
+ tls = MEM_mallocN(foreach_context->user_data_tls_size, "tls");
+ memcpy(tls, foreach_context->user_data_tls, foreach_context->user_data_tls_size);
+ }
+ return tls;
}
static void subdiv_foreach_tls_free(SubdivForeachTaskContext *ctx, void *tls)
{
- if (tls == NULL) {
- return;
- }
- if (ctx->foreach_context != NULL) {
- ctx->foreach_context->user_data_tls_free(tls);
- }
- MEM_freeN(tls);
+ if (tls == NULL) {
+ return;
+ }
+ if (ctx->foreach_context != NULL) {
+ ctx->foreach_context->user_data_tls_free(tls);
+ }
+ MEM_freeN(tls);
}
/* =============================================================================
@@ -159,171 +155,143 @@ static void subdiv_foreach_tls_free(SubdivForeachTaskContext *ctx, void *tls)
/* NOTE: Expects edge map to be zeroed. */
static void subdiv_foreach_ctx_count(SubdivForeachTaskContext *ctx)
{
- /* Reset counters. */
- ctx->num_subdiv_vertices = 0;
- ctx->num_subdiv_edges = 0;
- ctx->num_subdiv_loops = 0;
- ctx->num_subdiv_polygons = 0;
- /* Static geometry counters. */
- const int resolution = ctx->settings->resolution;
- const int no_quad_patch_resolution = ((resolution >> 1) + 1);
- const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
- const int num_inner_vertices_per_quad = (resolution - 2) * (resolution - 2);
- 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;
- 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 createdd by non-loose geometry. */
- 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);
- for (int corner = 0; corner < coarse_poly->totloop; corner++) {
- const MLoop *loop = &coarse_mloop[coarse_poly->loopstart + corner];
- const bool is_edge_used =
- BLI_BITMAP_TEST_BOOL(ctx->coarse_edges_used_map, loop->e);
- /* Edges which aren't counted yet. */
- if (!is_edge_used) {
- BLI_BITMAP_ENABLE(ctx->coarse_edges_used_map, loop->e);
- ctx->num_subdiv_vertices += num_subdiv_vertices_per_coarse_edge;
- }
- }
- /* Inner vertices of polygon. */
- if (num_ptex_faces_per_poly == 1) {
- ctx->num_subdiv_vertices += num_inner_vertices_per_quad;
- ctx->num_subdiv_edges +=
- num_edges_per_ptex_face_get(resolution - 2) +
- 4 * num_subdiv_vertices_per_coarse_edge;
- ctx->num_subdiv_polygons += num_polys_per_ptex_get(resolution);
- }
- else {
- ctx->num_subdiv_vertices +=
- 1 +
- num_ptex_faces_per_poly * (no_quad_patch_resolution - 2) +
- num_ptex_faces_per_poly * num_inner_vertices_per_noquad_patch;
- ctx->num_subdiv_edges +=
- num_ptex_faces_per_poly *
- (num_inner_edges_per_ptex_face_get(
- no_quad_patch_resolution - 1) +
- (no_quad_patch_resolution - 2) +
- num_subdiv_vertices_per_coarse_edge);
- if (no_quad_patch_resolution >= 3) {
- ctx->num_subdiv_edges += coarse_poly->totloop;
- }
- ctx->num_subdiv_polygons +=
- num_ptex_faces_per_poly *
- num_polys_per_ptex_get(no_quad_patch_resolution);
- }
- }
- /* Calculate extra vertices createdd by loose edges. */
- for (int edge_index = 0; edge_index < coarse_mesh->totedge; edge_index++) {
- if (!BLI_BITMAP_TEST_BOOL(ctx->coarse_edges_used_map, edge_index)) {
- ctx->num_subdiv_vertices += num_subdiv_vertices_per_coarse_edge;
- }
- }
- ctx->num_subdiv_loops = ctx->num_subdiv_polygons * 4;
+ /* Reset counters. */
+ ctx->num_subdiv_vertices = 0;
+ ctx->num_subdiv_edges = 0;
+ ctx->num_subdiv_loops = 0;
+ ctx->num_subdiv_polygons = 0;
+ /* Static geometry counters. */
+ const int resolution = ctx->settings->resolution;
+ const int no_quad_patch_resolution = ((resolution >> 1) + 1);
+ const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
+ const int num_inner_vertices_per_quad = (resolution - 2) * (resolution - 2);
+ 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;
+ 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 createdd by non-loose geometry. */
+ 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);
+ for (int corner = 0; corner < coarse_poly->totloop; corner++) {
+ const MLoop *loop = &coarse_mloop[coarse_poly->loopstart + corner];
+ const bool is_edge_used = BLI_BITMAP_TEST_BOOL(ctx->coarse_edges_used_map, loop->e);
+ /* Edges which aren't counted yet. */
+ if (!is_edge_used) {
+ BLI_BITMAP_ENABLE(ctx->coarse_edges_used_map, loop->e);
+ ctx->num_subdiv_vertices += num_subdiv_vertices_per_coarse_edge;
+ }
+ }
+ /* Inner vertices of polygon. */
+ if (num_ptex_faces_per_poly == 1) {
+ ctx->num_subdiv_vertices += num_inner_vertices_per_quad;
+ ctx->num_subdiv_edges += num_edges_per_ptex_face_get(resolution - 2) +
+ 4 * num_subdiv_vertices_per_coarse_edge;
+ ctx->num_subdiv_polygons += num_polys_per_ptex_get(resolution);
+ }
+ else {
+ ctx->num_subdiv_vertices += 1 + num_ptex_faces_per_poly * (no_quad_patch_resolution - 2) +
+ num_ptex_faces_per_poly * num_inner_vertices_per_noquad_patch;
+ ctx->num_subdiv_edges += num_ptex_faces_per_poly *
+ (num_inner_edges_per_ptex_face_get(no_quad_patch_resolution - 1) +
+ (no_quad_patch_resolution - 2) +
+ num_subdiv_vertices_per_coarse_edge);
+ if (no_quad_patch_resolution >= 3) {
+ ctx->num_subdiv_edges += coarse_poly->totloop;
+ }
+ ctx->num_subdiv_polygons += num_ptex_faces_per_poly *
+ num_polys_per_ptex_get(no_quad_patch_resolution);
+ }
+ }
+ /* Calculate extra vertices createdd by loose edges. */
+ for (int edge_index = 0; edge_index < coarse_mesh->totedge; edge_index++) {
+ if (!BLI_BITMAP_TEST_BOOL(ctx->coarse_edges_used_map, edge_index)) {
+ ctx->num_subdiv_vertices += num_subdiv_vertices_per_coarse_edge;
+ }
+ }
+ ctx->num_subdiv_loops = ctx->num_subdiv_polygons * 4;
}
static void subdiv_foreach_ctx_init_offsets(SubdivForeachTaskContext *ctx)
{
- const Mesh *coarse_mesh = ctx->coarse_mesh;
- const int resolution = ctx->settings->resolution;
- const int resolution_2 = resolution - 2;
- const int resolution_2_squared = resolution_2 * resolution_2;
- const int no_quad_patch_resolution = ((resolution >> 1) + 1);
- const int num_irregular_vertices_per_patch =
- (no_quad_patch_resolution - 2) * (no_quad_patch_resolution - 1);
- const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
- const int num_subdiv_edges_per_coarse_edge = resolution - 1;
- /* Constant offsets in arrays. */
- ctx->vertices_corner_offset = 0;
- ctx->vertices_edge_offset = coarse_mesh->totvert;
- ctx->vertices_inner_offset =
- ctx->vertices_edge_offset +
- coarse_mesh->totedge * num_subdiv_vertices_per_coarse_edge;
- ctx->edge_boundary_offset = 0;
- 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;
- int vertex_offset = 0;
- int edge_offset = 0;
- int polygon_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->subdiv_vertex_offset[poly_index] = vertex_offset;
- ctx->subdiv_edge_offset[poly_index] = edge_offset;
- ctx->subdiv_polygon_offset[poly_index] = polygon_offset;
- if (num_ptex_faces_per_poly == 1) {
- vertex_offset += resolution_2_squared;
- edge_offset += num_edges_per_ptex_face_get(resolution - 2) +
- 4 * num_subdiv_vertices_per_coarse_edge;
- polygon_offset += num_polys_per_ptex_get(resolution);
- }
- else {
- vertex_offset +=
- 1 +
- num_ptex_faces_per_poly * num_irregular_vertices_per_patch;
- edge_offset +=
- num_ptex_faces_per_poly *
- (num_inner_edges_per_ptex_face_get(
- no_quad_patch_resolution - 1) +
- (no_quad_patch_resolution - 2) +
- num_subdiv_vertices_per_coarse_edge);
- if (no_quad_patch_resolution >= 3) {
- edge_offset += coarse_poly->totloop;
- }
- polygon_offset +=
- num_ptex_faces_per_poly *
- num_polys_per_ptex_get(no_quad_patch_resolution);
- }
- }
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ const int resolution = ctx->settings->resolution;
+ const int resolution_2 = resolution - 2;
+ const int resolution_2_squared = resolution_2 * resolution_2;
+ const int no_quad_patch_resolution = ((resolution >> 1) + 1);
+ const int num_irregular_vertices_per_patch = (no_quad_patch_resolution - 2) *
+ (no_quad_patch_resolution - 1);
+ const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
+ const int num_subdiv_edges_per_coarse_edge = resolution - 1;
+ /* Constant offsets in arrays. */
+ ctx->vertices_corner_offset = 0;
+ ctx->vertices_edge_offset = coarse_mesh->totvert;
+ ctx->vertices_inner_offset = ctx->vertices_edge_offset +
+ coarse_mesh->totedge * num_subdiv_vertices_per_coarse_edge;
+ ctx->edge_boundary_offset = 0;
+ 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;
+ int vertex_offset = 0;
+ int edge_offset = 0;
+ int polygon_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->subdiv_vertex_offset[poly_index] = vertex_offset;
+ ctx->subdiv_edge_offset[poly_index] = edge_offset;
+ ctx->subdiv_polygon_offset[poly_index] = polygon_offset;
+ if (num_ptex_faces_per_poly == 1) {
+ vertex_offset += resolution_2_squared;
+ edge_offset += num_edges_per_ptex_face_get(resolution - 2) +
+ 4 * num_subdiv_vertices_per_coarse_edge;
+ polygon_offset += num_polys_per_ptex_get(resolution);
+ }
+ else {
+ vertex_offset += 1 + num_ptex_faces_per_poly * num_irregular_vertices_per_patch;
+ edge_offset += num_ptex_faces_per_poly *
+ (num_inner_edges_per_ptex_face_get(no_quad_patch_resolution - 1) +
+ (no_quad_patch_resolution - 2) + num_subdiv_vertices_per_coarse_edge);
+ if (no_quad_patch_resolution >= 3) {
+ edge_offset += coarse_poly->totloop;
+ }
+ polygon_offset += num_ptex_faces_per_poly * num_polys_per_ptex_get(no_quad_patch_resolution);
+ }
+ }
}
-static void subdiv_foreach_ctx_init(Subdiv *subdiv,
- SubdivForeachTaskContext *ctx)
+static void subdiv_foreach_ctx_init(Subdiv *subdiv, SubdivForeachTaskContext *ctx)
{
- const Mesh *coarse_mesh = ctx->coarse_mesh;
- /* Allocate maps and offsets. */
- ctx->coarse_vertices_used_map =
- BLI_BITMAP_NEW(coarse_mesh->totvert, "vertices used map");
- ctx->coarse_edges_used_map =
- BLI_BITMAP_NEW(coarse_mesh->totedge, "edges used map");
- ctx->subdiv_vertex_offset = MEM_malloc_arrayN(
- coarse_mesh->totpoly,
- sizeof(*ctx->subdiv_vertex_offset),
- "vertex_offset");
- ctx->subdiv_edge_offset = MEM_malloc_arrayN(
- coarse_mesh->totpoly,
- sizeof(*ctx->subdiv_edge_offset),
- "subdiv_edge_offset");
- ctx->subdiv_polygon_offset = MEM_malloc_arrayN(
- coarse_mesh->totpoly,
- sizeof(*ctx->subdiv_polygon_offset),
- "subdiv_edge_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);
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ /* Allocate maps and offsets. */
+ ctx->coarse_vertices_used_map = BLI_BITMAP_NEW(coarse_mesh->totvert, "vertices used map");
+ ctx->coarse_edges_used_map = BLI_BITMAP_NEW(coarse_mesh->totedge, "edges used map");
+ ctx->subdiv_vertex_offset = MEM_malloc_arrayN(
+ coarse_mesh->totpoly, sizeof(*ctx->subdiv_vertex_offset), "vertex_offset");
+ ctx->subdiv_edge_offset = MEM_malloc_arrayN(
+ coarse_mesh->totpoly, sizeof(*ctx->subdiv_edge_offset), "subdiv_edge_offset");
+ ctx->subdiv_polygon_offset = MEM_malloc_arrayN(
+ coarse_mesh->totpoly, sizeof(*ctx->subdiv_polygon_offset), "subdiv_edge_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)
{
- MEM_freeN(ctx->coarse_vertices_used_map);
- MEM_freeN(ctx->coarse_edges_used_map);
- MEM_freeN(ctx->subdiv_vertex_offset);
- MEM_freeN(ctx->subdiv_edge_offset);
- MEM_freeN(ctx->subdiv_polygon_offset);
+ MEM_freeN(ctx->coarse_vertices_used_map);
+ MEM_freeN(ctx->coarse_edges_used_map);
+ MEM_freeN(ctx->subdiv_vertex_offset);
+ MEM_freeN(ctx->subdiv_edge_offset);
+ MEM_freeN(ctx->subdiv_polygon_offset);
}
/* =============================================================================
@@ -333,479 +301,409 @@ static void subdiv_foreach_ctx_free(SubdivForeachTaskContext *ctx)
/* Traversal of corner vertices. They are coming from coarse vertices. */
static void subdiv_foreach_corner_vertices_regular_do(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly,
- SubdivForeachVertexFromCornerCb vertex_corner,
- bool check_usage)
+ SubdivForeachTaskContext *ctx,
+ void *tls,
+ const MPoly *coarse_poly,
+ SubdivForeachVertexFromCornerCb vertex_corner,
+ bool check_usage)
{
- 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 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];
- if (check_usage &&
- BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map,
- coarse_loop->v))
- {
- continue;
- }
- const int coarse_vertex_index = coarse_loop->v;
- const int subdiv_vertex_index =
- ctx->vertices_corner_offset + coarse_vertex_index;
- const float u = weights[corner][0];
- const float v = weights[corner][1];
- vertex_corner(
- ctx->foreach_context,
- tls,
- ptex_face_index,
- u, v,
- coarse_vertex_index,
- coarse_poly_index,
- 0,
- subdiv_vertex_index);
- }
+ 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 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];
+ if (check_usage &&
+ BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map, coarse_loop->v)) {
+ continue;
+ }
+ const int coarse_vertex_index = coarse_loop->v;
+ const int subdiv_vertex_index = ctx->vertices_corner_offset + coarse_vertex_index;
+ const float u = weights[corner][0];
+ const float v = weights[corner][1];
+ vertex_corner(ctx->foreach_context,
+ tls,
+ ptex_face_index,
+ u,
+ v,
+ coarse_vertex_index,
+ coarse_poly_index,
+ 0,
+ subdiv_vertex_index);
+ }
}
-static void subdiv_foreach_corner_vertices_regular(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly)
+static void subdiv_foreach_corner_vertices_regular(SubdivForeachTaskContext *ctx,
+ void *tls,
+ const MPoly *coarse_poly)
{
- subdiv_foreach_corner_vertices_regular_do(
- ctx, tls, coarse_poly, ctx->foreach_context->vertex_corner, true);
+ subdiv_foreach_corner_vertices_regular_do(
+ ctx, tls, coarse_poly, ctx->foreach_context->vertex_corner, true);
}
static void subdiv_foreach_corner_vertices_special_do(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly,
- SubdivForeachVertexFromCornerCb vertex_corner,
- bool check_usage)
+ SubdivForeachTaskContext *ctx,
+ void *tls,
+ const MPoly *coarse_poly,
+ SubdivForeachVertexFromCornerCb vertex_corner,
+ 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;
- 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];
- if (check_usage &&
- BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map,
- coarse_loop->v))
- {
- continue;
- }
- const int coarse_vertex_index = coarse_loop->v;
- const int subdiv_vertex_index =
- ctx->vertices_corner_offset + coarse_vertex_index;
- vertex_corner(
- ctx->foreach_context,
- tls,
- ptex_face_index,
- 0.0f, 0.0f,
- coarse_vertex_index,
- coarse_poly_index,
- corner,
- subdiv_vertex_index);
- }
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ const MLoop *coarse_mloop = coarse_mesh->mloop;
+ const int coarse_poly_index = coarse_poly - coarse_mesh->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];
+ if (check_usage &&
+ BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map, coarse_loop->v)) {
+ continue;
+ }
+ const int coarse_vertex_index = coarse_loop->v;
+ const int subdiv_vertex_index = ctx->vertices_corner_offset + coarse_vertex_index;
+ vertex_corner(ctx->foreach_context,
+ tls,
+ ptex_face_index,
+ 0.0f,
+ 0.0f,
+ coarse_vertex_index,
+ coarse_poly_index,
+ corner,
+ subdiv_vertex_index);
+ }
}
-static void subdiv_foreach_corner_vertices_special(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly)
+static void subdiv_foreach_corner_vertices_special(SubdivForeachTaskContext *ctx,
+ void *tls,
+ const MPoly *coarse_poly)
{
- subdiv_foreach_corner_vertices_special_do(
- ctx, tls, coarse_poly, ctx->foreach_context->vertex_corner, true);
+ subdiv_foreach_corner_vertices_special_do(
+ ctx, tls, coarse_poly, ctx->foreach_context->vertex_corner, true);
}
static void subdiv_foreach_corner_vertices(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
{
- if (coarse_poly->totloop == 4) {
- subdiv_foreach_corner_vertices_regular(ctx, tls, coarse_poly);
- }
- else {
- subdiv_foreach_corner_vertices_special(ctx, tls, coarse_poly);
- }
+ if (coarse_poly->totloop == 4) {
+ subdiv_foreach_corner_vertices_regular(ctx, tls, coarse_poly);
+ }
+ else {
+ subdiv_foreach_corner_vertices_special(ctx, tls, coarse_poly);
+ }
}
-static void subdiv_foreach_every_corner_vertices_regular(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly)
+static void subdiv_foreach_every_corner_vertices_regular(SubdivForeachTaskContext *ctx,
+ void *tls,
+ const MPoly *coarse_poly)
{
- subdiv_foreach_corner_vertices_regular_do(
- ctx, tls, coarse_poly,
- ctx->foreach_context->vertex_every_corner,
- false);
+ subdiv_foreach_corner_vertices_regular_do(
+ ctx, tls, coarse_poly, ctx->foreach_context->vertex_every_corner, false);
}
-static void subdiv_foreach_every_corner_vertices_special(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly)
+static void subdiv_foreach_every_corner_vertices_special(SubdivForeachTaskContext *ctx,
+ void *tls,
+ const MPoly *coarse_poly)
{
- subdiv_foreach_corner_vertices_special_do(
- ctx, tls, coarse_poly,
- ctx->foreach_context->vertex_every_corner,
- false);
+ subdiv_foreach_corner_vertices_special_do(
+ ctx, tls, coarse_poly, ctx->foreach_context->vertex_every_corner, false);
}
-static void subdiv_foreach_every_corner_vertices(
- SubdivForeachTaskContext *ctx,
- void *tls)
+static void subdiv_foreach_every_corner_vertices(SubdivForeachTaskContext *ctx, void *tls)
{
- if (ctx->foreach_context->vertex_every_corner == NULL) {
- return;
- }
- const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
- 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) {
- subdiv_foreach_every_corner_vertices_regular(ctx, tls, coarse_poly);
- }
- else {
- subdiv_foreach_every_corner_vertices_special(ctx, tls, coarse_poly);
- }
- }
+ if (ctx->foreach_context->vertex_every_corner == NULL) {
+ return;
+ }
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ 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) {
+ subdiv_foreach_every_corner_vertices_regular(ctx, tls, coarse_poly);
+ }
+ else {
+ subdiv_foreach_every_corner_vertices_special(ctx, tls, coarse_poly);
+ }
+ }
}
/* Traverse of edge vertices. They are coming from coarse edges. */
-static void subdiv_foreach_edge_vertices_regular_do(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly,
- SubdivForeachVertexFromEdgeCb vertex_edge,
- bool check_usage)
+static void subdiv_foreach_edge_vertices_regular_do(SubdivForeachTaskContext *ctx,
+ void *tls,
+ const MPoly *coarse_poly,
+ SubdivForeachVertexFromEdgeCb vertex_edge,
+ bool check_usage)
{
- const int resolution = ctx->settings->resolution;
- const int resolution_1 = resolution - 1;
- 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 int coarse_poly_index = coarse_poly - coarse_mpoly;
- const int poly_index = coarse_poly - coarse_mesh->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];
- const int coarse_edge_index = coarse_loop->e;
- if (check_usage &&
- BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_edges_used_map,
- coarse_edge_index))
- {
- continue;
- }
- const MEdge *coarse_edge = &coarse_medge[coarse_edge_index];
- const bool flip = (coarse_edge->v2 == coarse_loop->v);
- int subdiv_vertex_index =
- ctx->vertices_edge_offset +
- coarse_edge_index * num_subdiv_vertices_per_coarse_edge;
- for (int vertex_index = 0;
- vertex_index < num_subdiv_vertices_per_coarse_edge;
- vertex_index++, subdiv_vertex_index++)
- {
- float fac = (vertex_index + 1) * inv_resolution_1;
- if (flip) {
- fac = 1.0f - fac;
- }
- if (corner >= 2) {
- fac = 1.0f - fac;
- }
- float u, v;
- if ((corner & 1) == 0) {
- u = fac;
- v = (corner == 2) ? 1.0f : 0.0f;
- }
- else {
- u = (corner == 1) ? 1.0f : 0.0f;
- v = fac;
- }
- vertex_edge(
- ctx->foreach_context,
- tls,
- ptex_face_index,
- u, v,
- coarse_edge_index,
- coarse_poly_index,
- 0,
- subdiv_vertex_index);
- }
- }
+ const int resolution = ctx->settings->resolution;
+ const int resolution_1 = resolution - 1;
+ 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 int coarse_poly_index = coarse_poly - coarse_mpoly;
+ const int poly_index = coarse_poly - coarse_mesh->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];
+ const int coarse_edge_index = coarse_loop->e;
+ if (check_usage &&
+ BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_edges_used_map, coarse_edge_index)) {
+ continue;
+ }
+ const MEdge *coarse_edge = &coarse_medge[coarse_edge_index];
+ const bool flip = (coarse_edge->v2 == coarse_loop->v);
+ int subdiv_vertex_index = ctx->vertices_edge_offset +
+ coarse_edge_index * num_subdiv_vertices_per_coarse_edge;
+ for (int vertex_index = 0; vertex_index < num_subdiv_vertices_per_coarse_edge;
+ vertex_index++, subdiv_vertex_index++) {
+ float fac = (vertex_index + 1) * inv_resolution_1;
+ if (flip) {
+ fac = 1.0f - fac;
+ }
+ if (corner >= 2) {
+ fac = 1.0f - fac;
+ }
+ float u, v;
+ if ((corner & 1) == 0) {
+ u = fac;
+ v = (corner == 2) ? 1.0f : 0.0f;
+ }
+ else {
+ u = (corner == 1) ? 1.0f : 0.0f;
+ v = fac;
+ }
+ vertex_edge(ctx->foreach_context,
+ tls,
+ ptex_face_index,
+ u,
+ v,
+ coarse_edge_index,
+ coarse_poly_index,
+ 0,
+ subdiv_vertex_index);
+ }
+ }
}
-static void subdiv_foreach_edge_vertices_regular(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly)
+static void subdiv_foreach_edge_vertices_regular(SubdivForeachTaskContext *ctx,
+ void *tls,
+ const MPoly *coarse_poly)
{
- subdiv_foreach_edge_vertices_regular_do(
- ctx, tls, coarse_poly,
- ctx->foreach_context->vertex_edge,
- true);
+ subdiv_foreach_edge_vertices_regular_do(
+ ctx, tls, coarse_poly, ctx->foreach_context->vertex_edge, true);
}
-static void subdiv_foreach_edge_vertices_special_do(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly,
- SubdivForeachVertexFromEdgeCb vertex_edge,
- bool check_usage)
+static void subdiv_foreach_edge_vertices_special_do(SubdivForeachTaskContext *ctx,
+ void *tls,
+ const MPoly *coarse_poly,
+ SubdivForeachVertexFromEdgeCb vertex_edge,
+ bool check_usage)
{
- const int resolution = ctx->settings->resolution;
- const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
- 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 int coarse_poly_index = coarse_poly - coarse_mpoly;
- const int poly_index = coarse_poly - coarse_mesh->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++)
- {
- const MLoop *coarse_loop =
- &coarse_mloop[coarse_poly->loopstart + corner];
- const int coarse_edge_index = coarse_loop->e;
- if (check_usage &&
- BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_edges_used_map,
- coarse_edge_index))
- {
- continue;
- }
- const MEdge *coarse_edge = &coarse_medge[coarse_edge_index];
- const bool flip = (coarse_edge->v2 == coarse_loop->v);
- int subdiv_vertex_index =
- ctx->vertices_edge_offset +
- coarse_edge_index * num_subdiv_vertices_per_coarse_edge;
- int veretx_delta = 1;
- if (flip) {
- subdiv_vertex_index += num_subdiv_vertices_per_coarse_edge - 1;
- veretx_delta = -1;
- }
- for (int vertex_index = 1;
- vertex_index < num_vertices_per_ptex_edge;
- vertex_index++, subdiv_vertex_index += veretx_delta)
- {
- const float u = vertex_index * inv_ptex_resolution_1;
- vertex_edge(
- ctx->foreach_context,
- tls,
- ptex_face_index,
- u, 0.0f,
- coarse_edge_index,
- coarse_poly_index,
- corner,
- subdiv_vertex_index);
- }
- const int next_corner = (corner + 1) % coarse_poly->totloop;
- const int next_ptex_face_index = ptex_face_start_index + next_corner;
- for (int vertex_index = 1;
- vertex_index < num_vertices_per_ptex_edge - 1;
- vertex_index++, subdiv_vertex_index += veretx_delta)
- {
- const float v = 1.0f - vertex_index * inv_ptex_resolution_1;
- vertex_edge(
- ctx->foreach_context,
- tls,
- next_ptex_face_index,
- 0.0f, v,
- coarse_edge_index,
- coarse_poly_index,
- next_corner,
- subdiv_vertex_index);
- }
- }
+ const int resolution = ctx->settings->resolution;
+ const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
+ 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 int coarse_poly_index = coarse_poly - coarse_mpoly;
+ const int poly_index = coarse_poly - coarse_mesh->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++) {
+ const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner];
+ const int coarse_edge_index = coarse_loop->e;
+ if (check_usage &&
+ BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_edges_used_map, coarse_edge_index)) {
+ continue;
+ }
+ const MEdge *coarse_edge = &coarse_medge[coarse_edge_index];
+ const bool flip = (coarse_edge->v2 == coarse_loop->v);
+ int subdiv_vertex_index = ctx->vertices_edge_offset +
+ coarse_edge_index * num_subdiv_vertices_per_coarse_edge;
+ int veretx_delta = 1;
+ if (flip) {
+ subdiv_vertex_index += num_subdiv_vertices_per_coarse_edge - 1;
+ veretx_delta = -1;
+ }
+ for (int vertex_index = 1; vertex_index < num_vertices_per_ptex_edge;
+ vertex_index++, subdiv_vertex_index += veretx_delta) {
+ const float u = vertex_index * inv_ptex_resolution_1;
+ vertex_edge(ctx->foreach_context,
+ tls,
+ ptex_face_index,
+ u,
+ 0.0f,
+ coarse_edge_index,
+ coarse_poly_index,
+ corner,
+ subdiv_vertex_index);
+ }
+ const int next_corner = (corner + 1) % coarse_poly->totloop;
+ const int next_ptex_face_index = ptex_face_start_index + next_corner;
+ for (int vertex_index = 1; vertex_index < num_vertices_per_ptex_edge - 1;
+ vertex_index++, subdiv_vertex_index += veretx_delta) {
+ const float v = 1.0f - vertex_index * inv_ptex_resolution_1;
+ vertex_edge(ctx->foreach_context,
+ tls,
+ next_ptex_face_index,
+ 0.0f,
+ v,
+ coarse_edge_index,
+ coarse_poly_index,
+ next_corner,
+ subdiv_vertex_index);
+ }
+ }
}
-static void subdiv_foreach_edge_vertices_special(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly)
+static void subdiv_foreach_edge_vertices_special(SubdivForeachTaskContext *ctx,
+ void *tls,
+ const MPoly *coarse_poly)
{
- subdiv_foreach_edge_vertices_special_do(
- ctx, tls, coarse_poly,
- ctx->foreach_context->vertex_edge,
- true);
+ subdiv_foreach_edge_vertices_special_do(
+ ctx, tls, coarse_poly, ctx->foreach_context->vertex_edge, true);
}
-static void subdiv_foreach_edge_vertices(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly)
+static void subdiv_foreach_edge_vertices(SubdivForeachTaskContext *ctx,
+ void *tls,
+ const MPoly *coarse_poly)
{
- if (coarse_poly->totloop == 4) {
- subdiv_foreach_edge_vertices_regular(ctx, tls, coarse_poly);
- }
- else {
- subdiv_foreach_edge_vertices_special(ctx, tls, coarse_poly);
- }
+ if (coarse_poly->totloop == 4) {
+ subdiv_foreach_edge_vertices_regular(ctx, tls, coarse_poly);
+ }
+ else {
+ subdiv_foreach_edge_vertices_special(ctx, tls, coarse_poly);
+ }
}
-static void subdiv_foreach_every_edge_vertices_regular(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly)
+static void subdiv_foreach_every_edge_vertices_regular(SubdivForeachTaskContext *ctx,
+ void *tls,
+ const MPoly *coarse_poly)
{
- subdiv_foreach_edge_vertices_regular_do(
- ctx, tls, coarse_poly,
- ctx->foreach_context->vertex_every_edge,
- false);
+ subdiv_foreach_edge_vertices_regular_do(
+ ctx, tls, coarse_poly, ctx->foreach_context->vertex_every_edge, false);
}
-static void subdiv_foreach_every_edge_vertices_special(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly)
+static void subdiv_foreach_every_edge_vertices_special(SubdivForeachTaskContext *ctx,
+ void *tls,
+ const MPoly *coarse_poly)
{
- subdiv_foreach_edge_vertices_special_do(
- ctx, tls, coarse_poly,
- ctx->foreach_context->vertex_every_edge,
- false);
+ subdiv_foreach_edge_vertices_special_do(
+ ctx, tls, coarse_poly, ctx->foreach_context->vertex_every_edge, false);
}
-static void subdiv_foreach_every_edge_vertices(
- SubdivForeachTaskContext *ctx,
- void *tls)
+static void subdiv_foreach_every_edge_vertices(SubdivForeachTaskContext *ctx, void *tls)
{
- if (ctx->foreach_context->vertex_every_edge == NULL) {
- return;
- }
- const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
- 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) {
- subdiv_foreach_every_edge_vertices_regular(ctx, tls, coarse_poly);
- }
- else {
- subdiv_foreach_every_edge_vertices_special(ctx, tls, coarse_poly);
- }
- }
+ if (ctx->foreach_context->vertex_every_edge == NULL) {
+ return;
+ }
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ 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) {
+ subdiv_foreach_every_edge_vertices_regular(ctx, tls, coarse_poly);
+ }
+ else {
+ subdiv_foreach_every_edge_vertices_special(ctx, tls, coarse_poly);
+ }
+ }
}
/* Traversal of inner vertices, they are coming from ptex patches. */
-static void subdiv_foreach_inner_vertices_regular(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly)
+static void subdiv_foreach_inner_vertices_regular(SubdivForeachTaskContext *ctx,
+ void *tls,
+ const MPoly *coarse_poly)
{
- 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 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;
- for (int y = 1; y < resolution - 1; y++) {
- const float v = y * inv_resolution_1;
- for (int x = 1; x < resolution - 1; x++, subdiv_vertex_index++) {
- const float u = x * inv_resolution_1;
- ctx->foreach_context->vertex_inner(
- ctx->foreach_context,
- tls,
- ptex_face_index,
- u, v,
- coarse_poly_index, 0,
- subdiv_vertex_index);
- }
- }
+ 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 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;
+ for (int y = 1; y < resolution - 1; y++) {
+ const float v = y * inv_resolution_1;
+ for (int x = 1; x < resolution - 1; x++, subdiv_vertex_index++) {
+ const float u = x * inv_resolution_1;
+ ctx->foreach_context->vertex_inner(ctx->foreach_context,
+ tls,
+ ptex_face_index,
+ u,
+ v,
+ coarse_poly_index,
+ 0,
+ subdiv_vertex_index);
+ }
+ }
}
-static void subdiv_foreach_inner_vertices_special(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly)
+static void subdiv_foreach_inner_vertices_special(SubdivForeachTaskContext *ctx,
+ void *tls,
+ const MPoly *coarse_poly)
{
- const int resolution = ctx->settings->resolution;
- 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;
- 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;
- ctx->foreach_context->vertex_inner(
- ctx->foreach_context,
- tls,
- ptex_face_index,
- 1.0f, 1.0f,
- coarse_poly_index, 0,
- subdiv_vertex_index);
- subdiv_vertex_index++;
- for (int corner = 0;
- corner < coarse_poly->totloop;
- corner++, ptex_face_index++)
- {
- for (int y = 1; y < ptex_face_resolution - 1; y++) {
- const float v = y * inv_ptex_face_resolution_1;
- for (int x = 1;
- x < ptex_face_resolution; x++,
- subdiv_vertex_index++)
- {
- const float u = x * inv_ptex_face_resolution_1;
- ctx->foreach_context->vertex_inner(
- ctx->foreach_context,
- tls,
- ptex_face_index,
- u, v,
- coarse_poly_index, corner,
- subdiv_vertex_index);
- }
- }
- }
+ const int resolution = ctx->settings->resolution;
+ 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;
+ 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;
+ ctx->foreach_context->vertex_inner(ctx->foreach_context,
+ tls,
+ ptex_face_index,
+ 1.0f,
+ 1.0f,
+ coarse_poly_index,
+ 0,
+ subdiv_vertex_index);
+ subdiv_vertex_index++;
+ for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) {
+ for (int y = 1; y < ptex_face_resolution - 1; y++) {
+ const float v = y * inv_ptex_face_resolution_1;
+ for (int x = 1; x < ptex_face_resolution; x++, subdiv_vertex_index++) {
+ const float u = x * inv_ptex_face_resolution_1;
+ ctx->foreach_context->vertex_inner(ctx->foreach_context,
+ tls,
+ ptex_face_index,
+ u,
+ v,
+ coarse_poly_index,
+ corner,
+ subdiv_vertex_index);
+ }
+ }
+ }
}
-static void subdiv_foreach_inner_vertices(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly)
+static void subdiv_foreach_inner_vertices(SubdivForeachTaskContext *ctx,
+ void *tls,
+ const MPoly *coarse_poly)
{
- if (coarse_poly->totloop == 4) {
- subdiv_foreach_inner_vertices_regular(ctx, tls, coarse_poly);
- }
- else {
- subdiv_foreach_inner_vertices_special(ctx, tls, coarse_poly);
- }
+ if (coarse_poly->totloop == 4) {
+ subdiv_foreach_inner_vertices_regular(ctx, tls, coarse_poly);
+ }
+ else {
+ subdiv_foreach_inner_vertices_special(ctx, tls, coarse_poly);
+ }
}
/* Traverse all vertices which are emitted from given coarse polygon. */
-static void subdiv_foreach_vertices(SubdivForeachTaskContext *ctx,
- void *tls,
- const int poly_index)
+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_poly = &coarse_mpoly[poly_index];
- if (ctx->foreach_context->vertex_inner != NULL) {
- subdiv_foreach_inner_vertices(ctx, tls, coarse_poly);
- }
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MPoly *coarse_poly = &coarse_mpoly[poly_index];
+ if (ctx->foreach_context->vertex_inner != NULL) {
+ subdiv_foreach_inner_vertices(ctx, tls, coarse_poly);
+ }
}
/* =============================================================================
@@ -820,23 +718,16 @@ static int subdiv_foreach_edges_row(SubdivForeachTaskContext *ctx,
const int start_vertex_index,
const int num_edges_per_row)
{
- int subdiv_edge_index = start_subdiv_edge_index;
- int vertex_index = start_vertex_index;
- for (int edge_index = 0;
- edge_index < num_edges_per_row - 1;
- edge_index++, subdiv_edge_index++)
- {
- const int v1 = vertex_index;
- const int v2 = vertex_index + 1;
- ctx->foreach_context->edge(
- ctx->foreach_context,
- tls,
- coarse_edge_index,
- subdiv_edge_index,
- v1, v2);
- vertex_index += 1;
- }
- return subdiv_edge_index;
+ int subdiv_edge_index = start_subdiv_edge_index;
+ int vertex_index = start_vertex_index;
+ for (int edge_index = 0; edge_index < num_edges_per_row - 1; edge_index++, subdiv_edge_index++) {
+ const int v1 = vertex_index;
+ const int v2 = vertex_index + 1;
+ ctx->foreach_context->edge(
+ ctx->foreach_context, tls, coarse_edge_index, subdiv_edge_index, v1, v2);
+ vertex_index += 1;
+ }
+ return subdiv_edge_index;
}
/* TODO(sergey): Coarse edges are always NONE, consider getting rid of them. */
@@ -848,30 +739,23 @@ static int subdiv_foreach_edges_column(SubdivForeachTaskContext *ctx,
const int start_vertex_index,
const int num_edges_per_row)
{
- int subdiv_edge_index = start_subdiv_edge_index;
- int vertex_index = start_vertex_index;
- for (int edge_index = 0;
- edge_index < num_edges_per_row;
- edge_index++, subdiv_edge_index++)
- {
- int coarse_edge_index = ORIGINDEX_NONE;
- if (edge_index == 0) {
- coarse_edge_index = coarse_start_edge_index;
- }
- else if (edge_index == num_edges_per_row - 1) {
- coarse_edge_index = coarse_end_edge_index;
- }
- const int v1 = vertex_index;
- const int v2 = vertex_index + num_edges_per_row;
- ctx->foreach_context->edge(
- ctx->foreach_context,
- tls,
- coarse_edge_index,
- subdiv_edge_index,
- v1, v2);
- vertex_index += 1;
- }
- return subdiv_edge_index;
+ int subdiv_edge_index = start_subdiv_edge_index;
+ int vertex_index = start_vertex_index;
+ for (int edge_index = 0; edge_index < num_edges_per_row; edge_index++, subdiv_edge_index++) {
+ int coarse_edge_index = ORIGINDEX_NONE;
+ if (edge_index == 0) {
+ coarse_edge_index = coarse_start_edge_index;
+ }
+ else if (edge_index == num_edges_per_row - 1) {
+ coarse_edge_index = coarse_end_edge_index;
+ }
+ const int v1 = vertex_index;
+ const int v2 = vertex_index + num_edges_per_row;
+ ctx->foreach_context->edge(
+ ctx->foreach_context, tls, coarse_edge_index, subdiv_edge_index, v1, v2);
+ vertex_index += 1;
+ }
+ return subdiv_edge_index;
}
/* Defines edges between inner vertices of patch, and also edges to the
@@ -892,330 +776,250 @@ static int subdiv_foreach_edges_column(SubdivForeachTaskContext *ctx,
* This is illustrate which parts of geometry is created by code below.
*/
-static void subdiv_foreach_edges_all_patches_regular(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly)
+static void subdiv_foreach_edges_all_patches_regular(SubdivForeachTaskContext *ctx,
+ void *tls,
+ 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 int poly_index = coarse_poly - coarse_mpoly;
- const int resolution = ctx->settings->resolution;
- const int start_vertex_index =
- ctx->vertices_inner_offset +
- ctx->subdiv_vertex_offset[poly_index];
- const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
- int subdiv_edge_index =
- ctx->edge_inner_offset + ctx->subdiv_edge_offset[poly_index];
- /* Traverse bottom row of edges (0-1, 1-2). */
- subdiv_edge_index = subdiv_foreach_edges_row(
- ctx,
- tls,
- ORIGINDEX_NONE,
- subdiv_edge_index,
- start_vertex_index,
- resolution - 2);
- /* Traverse remaining edges. */
- for (int row = 0; row < resolution - 3; row++) {
- const int start_row_vertex_index =
- start_vertex_index + row * (resolution - 2);
- /* Traverse vertical columns.
- *
- * At first iteration it will be edges (0-3. 1-4, 2-5), then it
- * will be (3-6, 4-7, 5-8) and so on.
- */
- subdiv_edge_index = subdiv_foreach_edges_column(
- ctx,
- tls,
- ORIGINDEX_NONE,
- ORIGINDEX_NONE,
- subdiv_edge_index,
- start_row_vertex_index,
- resolution - 2);
- /* Create horizontal edge row.
- *
- * At first iteration it will be edges (3-4, 4-5), then it will be
- * (6-7, 7-8) and so on.
- */
- subdiv_edge_index = subdiv_foreach_edges_row(
- ctx,
- tls,
- ORIGINDEX_NONE,
- subdiv_edge_index,
- start_row_vertex_index + resolution - 2,
- resolution - 2);
- }
- /* Connect inner part of patch to boundary. */
- for (int corner = 0; corner < coarse_poly->totloop; corner++) {
- const MLoop *coarse_loop =
- &coarse_mloop[coarse_poly->loopstart + corner];
- const MEdge *coarse_edge = &coarse_medge[coarse_loop->e];
- const int start_edge_vertex = ctx->vertices_edge_offset +
- coarse_loop->e * num_subdiv_vertices_per_coarse_edge;
- const bool flip = (coarse_edge->v2 == coarse_loop->v);
- int side_start_index = start_vertex_index;
- int side_stride = 0;
- /* Calculate starting veretx of corresponding inner part of ptex. */
- if (corner == 0) {
- side_stride = 1;
- }
- else if (corner == 1) {
- side_start_index += resolution - 3;
- side_stride = resolution - 2;
- }
- else if (corner == 2) {
- side_start_index += num_subdiv_vertices_per_coarse_edge *
- num_subdiv_vertices_per_coarse_edge - 1;
- side_stride = -1;
- }
- else if (corner == 3) {
- side_start_index += num_subdiv_vertices_per_coarse_edge *
- (num_subdiv_vertices_per_coarse_edge - 1);
- side_stride = -(resolution - 2);
- }
- for (int i = 0; i < resolution - 2; i++, subdiv_edge_index++) {
- const int v1 = (flip)
- ? (start_edge_vertex + (resolution - i - 3))
- : (start_edge_vertex + i);
- const int v2 = side_start_index + side_stride * i;
- ctx->foreach_context->edge(
- ctx->foreach_context,
- tls,
- ORIGINDEX_NONE,
- subdiv_edge_index,
- v1, v2);
- }
- }
+ 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 int poly_index = coarse_poly - coarse_mpoly;
+ const int resolution = ctx->settings->resolution;
+ const int start_vertex_index = ctx->vertices_inner_offset +
+ ctx->subdiv_vertex_offset[poly_index];
+ const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
+ int subdiv_edge_index = ctx->edge_inner_offset + ctx->subdiv_edge_offset[poly_index];
+ /* Traverse bottom row of edges (0-1, 1-2). */
+ subdiv_edge_index = subdiv_foreach_edges_row(
+ ctx, tls, ORIGINDEX_NONE, subdiv_edge_index, start_vertex_index, resolution - 2);
+ /* Traverse remaining edges. */
+ for (int row = 0; row < resolution - 3; row++) {
+ const int start_row_vertex_index = start_vertex_index + row * (resolution - 2);
+ /* Traverse vertical columns.
+ *
+ * At first iteration it will be edges (0-3. 1-4, 2-5), then it
+ * will be (3-6, 4-7, 5-8) and so on.
+ */
+ subdiv_edge_index = subdiv_foreach_edges_column(ctx,
+ tls,
+ ORIGINDEX_NONE,
+ ORIGINDEX_NONE,
+ subdiv_edge_index,
+ start_row_vertex_index,
+ resolution - 2);
+ /* Create horizontal edge row.
+ *
+ * At first iteration it will be edges (3-4, 4-5), then it will be
+ * (6-7, 7-8) and so on.
+ */
+ subdiv_edge_index = subdiv_foreach_edges_row(ctx,
+ tls,
+ ORIGINDEX_NONE,
+ subdiv_edge_index,
+ start_row_vertex_index + resolution - 2,
+ resolution - 2);
+ }
+ /* Connect inner part of patch to boundary. */
+ for (int corner = 0; corner < coarse_poly->totloop; corner++) {
+ const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner];
+ const MEdge *coarse_edge = &coarse_medge[coarse_loop->e];
+ const int start_edge_vertex = ctx->vertices_edge_offset +
+ coarse_loop->e * num_subdiv_vertices_per_coarse_edge;
+ const bool flip = (coarse_edge->v2 == coarse_loop->v);
+ int side_start_index = start_vertex_index;
+ int side_stride = 0;
+ /* Calculate starting veretx of corresponding inner part of ptex. */
+ if (corner == 0) {
+ side_stride = 1;
+ }
+ else if (corner == 1) {
+ side_start_index += resolution - 3;
+ side_stride = resolution - 2;
+ }
+ else if (corner == 2) {
+ side_start_index += num_subdiv_vertices_per_coarse_edge *
+ num_subdiv_vertices_per_coarse_edge -
+ 1;
+ side_stride = -1;
+ }
+ else if (corner == 3) {
+ side_start_index += num_subdiv_vertices_per_coarse_edge *
+ (num_subdiv_vertices_per_coarse_edge - 1);
+ side_stride = -(resolution - 2);
+ }
+ for (int i = 0; i < resolution - 2; i++, subdiv_edge_index++) {
+ const int v1 = (flip) ? (start_edge_vertex + (resolution - i - 3)) : (start_edge_vertex + i);
+ const int v2 = side_start_index + side_stride * i;
+ ctx->foreach_context->edge(
+ ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, v1, v2);
+ }
+ }
}
-static void subdiv_foreach_edges_all_patches_special(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly)
+static void subdiv_foreach_edges_all_patches_special(SubdivForeachTaskContext *ctx,
+ void *tls,
+ 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 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);
- const int ptex_face_inner_resolution = ptex_face_resolution - 2;
- const int num_inner_vertices_per_ptex =
- (ptex_face_resolution - 1) * (ptex_face_resolution - 2);
- const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
- const int center_vertex_index =
- ctx->vertices_inner_offset +
- ctx->subdiv_vertex_offset[poly_index];
- const int start_vertex_index = center_vertex_index + 1;
- int subdiv_edge_index =
- ctx->edge_inner_offset + ctx->subdiv_edge_offset[poly_index];
- /* Traverse inner ptex edges. */
- for (int corner = 0; corner < coarse_poly->totloop; corner++) {
- const int start_ptex_face_vertex_index =
- start_vertex_index + corner * num_inner_vertices_per_ptex;
- /* Similar steps to regular patch case. */
- subdiv_edge_index = subdiv_foreach_edges_row(
- ctx,
- tls,
- ORIGINDEX_NONE,
- subdiv_edge_index,
- start_ptex_face_vertex_index,
- ptex_face_inner_resolution + 1);
- for (int row = 0; row < ptex_face_inner_resolution - 1; row++) {
- const int start_row_vertex_index =
- start_ptex_face_vertex_index +
- row * (ptex_face_inner_resolution + 1);
- subdiv_edge_index = subdiv_foreach_edges_column(
- ctx,
- tls,
- ORIGINDEX_NONE,
- ORIGINDEX_NONE,
- subdiv_edge_index,
- start_row_vertex_index,
- ptex_face_inner_resolution + 1);
- subdiv_edge_index = subdiv_foreach_edges_row(
- ctx,
- tls,
- ORIGINDEX_NONE,
- subdiv_edge_index,
- start_row_vertex_index + ptex_face_inner_resolution + 1,
- ptex_face_inner_resolution + 1);
- }
- }
- /* Create connections between ptex faces. */
- for (int corner = 0; corner < coarse_poly->totloop; corner++) {
- const int next_corner = (corner + 1) % coarse_poly->totloop;
- int current_patch_vertex_index =
- start_vertex_index + corner * num_inner_vertices_per_ptex +
- ptex_face_inner_resolution;
- int next_path_vertex_index =
- start_vertex_index + next_corner * num_inner_vertices_per_ptex +
- num_inner_vertices_per_ptex - ptex_face_resolution + 1;
- for (int row = 0;
- row < ptex_face_inner_resolution;
- row++, subdiv_edge_index++)
- {
- const int v1 = current_patch_vertex_index;
- const int v2 = next_path_vertex_index;
- ctx->foreach_context->edge(
- ctx->foreach_context,
- tls,
- ORIGINDEX_NONE,
- subdiv_edge_index,
- v1, v2);
- current_patch_vertex_index += ptex_face_inner_resolution + 1;
- next_path_vertex_index += 1;
- }
- }
- /* Create edges from center. */
- if (ptex_face_resolution >= 3) {
- for (int corner = 0;
- corner < coarse_poly->totloop;
- corner++, subdiv_edge_index++)
- {
- const int current_patch_end_vertex_index =
- start_vertex_index + corner * num_inner_vertices_per_ptex +
- num_inner_vertices_per_ptex - 1;
- const int v1 = center_vertex_index;
- const int v2 = current_patch_end_vertex_index;
- ctx->foreach_context->edge(
- ctx->foreach_context,
- tls,
- ORIGINDEX_NONE,
- subdiv_edge_index,
- v1, v2);
- }
- }
- /* Connect inner path of patch to boundary. */
- const MLoop *prev_coarse_loop =
- &coarse_mloop[coarse_poly->loopstart + coarse_poly->totloop - 1];
- for (int corner = 0; corner < coarse_poly->totloop; corner++) {
- const MLoop *coarse_loop =
- &coarse_mloop[coarse_poly->loopstart + corner];
- {
- const MEdge *coarse_edge = &coarse_medge[coarse_loop->e];
- const int start_edge_vertex = ctx->vertices_edge_offset +
- coarse_loop->e * num_subdiv_vertices_per_coarse_edge;
- const bool flip = (coarse_edge->v2 == coarse_loop->v);
- int side_start_index;
- if (ptex_face_resolution >= 3) {
- side_start_index =
- start_vertex_index + num_inner_vertices_per_ptex * corner;
- }
- else {
- side_start_index = center_vertex_index;
- }
- for (int i = 0; i < ptex_face_resolution - 1;
- i++,
- subdiv_edge_index++)
- {
- const int v1 = (flip)
- ? (start_edge_vertex + (resolution - i - 3))
- : (start_edge_vertex + i);
- const int v2 = side_start_index + i;
- ctx->foreach_context->edge(
- ctx->foreach_context,
- tls,
- ORIGINDEX_NONE,
- subdiv_edge_index,
- v1, v2);
- }
- }
- if (ptex_face_resolution >= 3) {
- const MEdge *coarse_edge = &coarse_medge[prev_coarse_loop->e];
- const int start_edge_vertex = ctx->vertices_edge_offset +
- prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge;
- const bool flip = (coarse_edge->v2 == coarse_loop->v);
- int side_start_index =
- start_vertex_index + num_inner_vertices_per_ptex * corner;
- for (int i = 0;
- i < ptex_face_resolution - 2;
- i++, subdiv_edge_index++)
- {
- const int v1 = (flip)
- ? (start_edge_vertex + (resolution - i - 3))
- : (start_edge_vertex + i);
- const int v2 = side_start_index +
- (ptex_face_inner_resolution + 1) * i;
- ctx->foreach_context->edge(
- ctx->foreach_context,
- tls,
- ORIGINDEX_NONE,
- subdiv_edge_index,
- v1, v2);
- }
- }
- prev_coarse_loop = coarse_loop;
- }
+ 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 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);
+ const int ptex_face_inner_resolution = ptex_face_resolution - 2;
+ const int num_inner_vertices_per_ptex = (ptex_face_resolution - 1) * (ptex_face_resolution - 2);
+ const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
+ const int center_vertex_index = ctx->vertices_inner_offset +
+ ctx->subdiv_vertex_offset[poly_index];
+ const int start_vertex_index = center_vertex_index + 1;
+ int subdiv_edge_index = ctx->edge_inner_offset + ctx->subdiv_edge_offset[poly_index];
+ /* Traverse inner ptex edges. */
+ for (int corner = 0; corner < coarse_poly->totloop; corner++) {
+ const int start_ptex_face_vertex_index = start_vertex_index +
+ corner * num_inner_vertices_per_ptex;
+ /* Similar steps to regular patch case. */
+ subdiv_edge_index = subdiv_foreach_edges_row(ctx,
+ tls,
+ ORIGINDEX_NONE,
+ subdiv_edge_index,
+ start_ptex_face_vertex_index,
+ ptex_face_inner_resolution + 1);
+ for (int row = 0; row < ptex_face_inner_resolution - 1; row++) {
+ const int start_row_vertex_index = start_ptex_face_vertex_index +
+ row * (ptex_face_inner_resolution + 1);
+ subdiv_edge_index = subdiv_foreach_edges_column(ctx,
+ tls,
+ ORIGINDEX_NONE,
+ ORIGINDEX_NONE,
+ subdiv_edge_index,
+ start_row_vertex_index,
+ ptex_face_inner_resolution + 1);
+ subdiv_edge_index = subdiv_foreach_edges_row(ctx,
+ tls,
+ ORIGINDEX_NONE,
+ subdiv_edge_index,
+ start_row_vertex_index +
+ ptex_face_inner_resolution + 1,
+ ptex_face_inner_resolution + 1);
+ }
+ }
+ /* Create connections between ptex faces. */
+ for (int corner = 0; corner < coarse_poly->totloop; corner++) {
+ const int next_corner = (corner + 1) % coarse_poly->totloop;
+ int current_patch_vertex_index = start_vertex_index + corner * num_inner_vertices_per_ptex +
+ ptex_face_inner_resolution;
+ int next_path_vertex_index = start_vertex_index + next_corner * num_inner_vertices_per_ptex +
+ num_inner_vertices_per_ptex - ptex_face_resolution + 1;
+ for (int row = 0; row < ptex_face_inner_resolution; row++, subdiv_edge_index++) {
+ const int v1 = current_patch_vertex_index;
+ const int v2 = next_path_vertex_index;
+ ctx->foreach_context->edge(
+ ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, v1, v2);
+ current_patch_vertex_index += ptex_face_inner_resolution + 1;
+ next_path_vertex_index += 1;
+ }
+ }
+ /* Create edges from center. */
+ if (ptex_face_resolution >= 3) {
+ for (int corner = 0; corner < coarse_poly->totloop; corner++, subdiv_edge_index++) {
+ const int current_patch_end_vertex_index = start_vertex_index +
+ corner * num_inner_vertices_per_ptex +
+ num_inner_vertices_per_ptex - 1;
+ const int v1 = center_vertex_index;
+ const int v2 = current_patch_end_vertex_index;
+ ctx->foreach_context->edge(
+ ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, v1, v2);
+ }
+ }
+ /* Connect inner path of patch to boundary. */
+ const MLoop *prev_coarse_loop = &coarse_mloop[coarse_poly->loopstart + coarse_poly->totloop - 1];
+ for (int corner = 0; corner < coarse_poly->totloop; corner++) {
+ const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner];
+ {
+ const MEdge *coarse_edge = &coarse_medge[coarse_loop->e];
+ const int start_edge_vertex = ctx->vertices_edge_offset +
+ coarse_loop->e * num_subdiv_vertices_per_coarse_edge;
+ const bool flip = (coarse_edge->v2 == coarse_loop->v);
+ int side_start_index;
+ if (ptex_face_resolution >= 3) {
+ side_start_index = start_vertex_index + num_inner_vertices_per_ptex * corner;
+ }
+ else {
+ side_start_index = center_vertex_index;
+ }
+ for (int i = 0; i < ptex_face_resolution - 1; i++, subdiv_edge_index++) {
+ const int v1 = (flip) ? (start_edge_vertex + (resolution - i - 3)) :
+ (start_edge_vertex + i);
+ const int v2 = side_start_index + i;
+ ctx->foreach_context->edge(
+ ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, v1, v2);
+ }
+ }
+ if (ptex_face_resolution >= 3) {
+ const MEdge *coarse_edge = &coarse_medge[prev_coarse_loop->e];
+ const int start_edge_vertex = ctx->vertices_edge_offset +
+ prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge;
+ const bool flip = (coarse_edge->v2 == coarse_loop->v);
+ int side_start_index = start_vertex_index + num_inner_vertices_per_ptex * corner;
+ for (int i = 0; i < ptex_face_resolution - 2; i++, subdiv_edge_index++) {
+ const int v1 = (flip) ? (start_edge_vertex + (resolution - i - 3)) :
+ (start_edge_vertex + i);
+ const int v2 = side_start_index + (ptex_face_inner_resolution + 1) * i;
+ ctx->foreach_context->edge(
+ ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, v1, v2);
+ }
+ }
+ prev_coarse_loop = coarse_loop;
+ }
}
-static void subdiv_foreach_edges_all_patches(
- SubdivForeachTaskContext *ctx,
- void *tls,
- const MPoly *coarse_poly)
+static void subdiv_foreach_edges_all_patches(SubdivForeachTaskContext *ctx,
+ void *tls,
+ const MPoly *coarse_poly)
{
- if (coarse_poly->totloop == 4) {
- subdiv_foreach_edges_all_patches_regular(ctx, tls, coarse_poly);
- }
- else {
- subdiv_foreach_edges_all_patches_special(ctx, tls, coarse_poly);
- }
+ if (coarse_poly->totloop == 4) {
+ subdiv_foreach_edges_all_patches_regular(ctx, tls, coarse_poly);
+ }
+ else {
+ subdiv_foreach_edges_all_patches_special(ctx, tls, coarse_poly);
+ }
}
-static void subdiv_foreach_edges(SubdivForeachTaskContext *ctx,
- void *tls,
- int poly_index)
+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_poly = &coarse_mpoly[poly_index];
- subdiv_foreach_edges_all_patches(ctx, tls, coarse_poly);
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MPoly *coarse_poly = &coarse_mpoly[poly_index];
+ subdiv_foreach_edges_all_patches(ctx, tls, coarse_poly);
}
-static void subdiv_foreach_boundary_edges(
- SubdivForeachTaskContext *ctx,
- void *tls,
- int coarse_edge_index)
+static void subdiv_foreach_boundary_edges(SubdivForeachTaskContext *ctx,
+ void *tls,
+ int coarse_edge_index)
{
- const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MEdge *coarse_medge = coarse_mesh->medge;
- 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;
- const int num_subdiv_edges_per_coarse_edge = resolution - 1;
- int subdiv_edge_index =
- ctx->edge_boundary_offset +
- coarse_edge_index * num_subdiv_edges_per_coarse_edge;
- int last_vertex_index = ctx->vertices_corner_offset + coarse_edge->v1;
- for (int i = 0;
- i < num_subdiv_edges_per_coarse_edge - 1;
- i++, subdiv_edge_index++)
- {
- const int v1 = last_vertex_index;
- const int v2 =
- ctx->vertices_edge_offset +
- coarse_edge_index * num_subdiv_vertices_per_coarse_edge +
- i;
- ctx->foreach_context->edge(
- ctx->foreach_context,
- tls,
- coarse_edge_index,
- subdiv_edge_index,
- v1, v2);
- last_vertex_index = v2;
- }
- const int v1 = last_vertex_index;
- const int v2 = ctx->vertices_corner_offset + coarse_edge->v2;
- ctx->foreach_context->edge(
- ctx->foreach_context,
- tls,
- coarse_edge_index,
- subdiv_edge_index,
- v1, v2);
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ const MEdge *coarse_medge = coarse_mesh->medge;
+ 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;
+ const int num_subdiv_edges_per_coarse_edge = resolution - 1;
+ int subdiv_edge_index = ctx->edge_boundary_offset +
+ coarse_edge_index * num_subdiv_edges_per_coarse_edge;
+ int last_vertex_index = ctx->vertices_corner_offset + coarse_edge->v1;
+ for (int i = 0; i < num_subdiv_edges_per_coarse_edge - 1; i++, subdiv_edge_index++) {
+ const int v1 = last_vertex_index;
+ const int v2 = ctx->vertices_edge_offset +
+ coarse_edge_index * num_subdiv_vertices_per_coarse_edge + i;
+ ctx->foreach_context->edge(
+ ctx->foreach_context, tls, coarse_edge_index, subdiv_edge_index, v1, v2);
+ last_vertex_index = v2;
+ }
+ const int v1 = last_vertex_index;
+ const int v2 = ctx->vertices_corner_offset + coarse_edge->v2;
+ ctx->foreach_context->edge(
+ ctx->foreach_context, tls, coarse_edge_index, subdiv_edge_index, v1, v2);
}
/* =============================================================================
@@ -1224,844 +1028,829 @@ static void subdiv_foreach_boundary_edges(
static void rotate_indices(const int rot, int *a, int *b, int *c, int *d)
{
- int values[4] = {*a, *b, *c, *d};
- *a = values[(0 - rot + 4) % 4];
- *b = values[(1 - rot + 4) % 4];
- *c = values[(2 - rot + 4) % 4];
- *d = values[(3 - rot + 4) % 4];
+ int values[4] = {*a, *b, *c, *d};
+ *a = values[(0 - rot + 4) % 4];
+ *b = values[(1 - rot + 4) % 4];
+ *c = values[(2 - rot + 4) % 4];
+ *d = values[(3 - rot + 4) % 4];
}
-static void subdiv_foreach_loops_of_poly(
- SubdivForeachTaskContext *ctx,
- void *tls,
- int subdiv_loop_start_index,
- const int ptex_face_index,
- const int coarse_poly_index,
- const int coarse_corner_index,
- const int rotation,
- /*const*/ int v0, /*const*/ int e0,
- /*const*/ int v1, /*const*/ int e1,
- /*const*/ int v2, /*const*/ int e2,
- /*const*/ int v3, /*const*/ int e3,
- const float u, const float v,
- const float du, const float dv)
+static void subdiv_foreach_loops_of_poly(SubdivForeachTaskContext *ctx,
+ void *tls,
+ int subdiv_loop_start_index,
+ const int ptex_face_index,
+ const int coarse_poly_index,
+ const int coarse_corner_index,
+ const int rotation,
+ /*const*/ int v0,
+ /*const*/ int e0,
+ /*const*/ int v1,
+ /*const*/ int e1,
+ /*const*/ int v2,
+ /*const*/ int e2,
+ /*const*/ int v3,
+ /*const*/ int e3,
+ const float u,
+ const float v,
+ const float du,
+ const float dv)
{
- rotate_indices(rotation, &v0, &v1, &v2, &v3);
- rotate_indices(rotation, &e0, &e1, &e2, &e3);
- ctx->foreach_context->loop(
- ctx->foreach_context,
- tls,
- ptex_face_index, u, v,
- ORIGINDEX_NONE,
- coarse_poly_index,
- coarse_corner_index,
- subdiv_loop_start_index + 0,
- v0, e0);
- ctx->foreach_context->loop(
- ctx->foreach_context,
- tls,
- ptex_face_index, u + du, v,
- ORIGINDEX_NONE,
- coarse_poly_index,
- coarse_corner_index,
- subdiv_loop_start_index + 1,
- v1, e1);
- ctx->foreach_context->loop(
- ctx->foreach_context,
- tls,
- ptex_face_index, u + du, v + dv,
- ORIGINDEX_NONE,
- coarse_poly_index,
- coarse_corner_index,
- subdiv_loop_start_index + 2,
- v2, e2);
- ctx->foreach_context->loop(
- ctx->foreach_context,
- tls,
- ptex_face_index, u, v + dv,
- ORIGINDEX_NONE,
- coarse_poly_index,
- coarse_corner_index,
- subdiv_loop_start_index + 3,
- v3, e3);
+ rotate_indices(rotation, &v0, &v1, &v2, &v3);
+ rotate_indices(rotation, &e0, &e1, &e2, &e3);
+ ctx->foreach_context->loop(ctx->foreach_context,
+ tls,
+ ptex_face_index,
+ u,
+ v,
+ ORIGINDEX_NONE,
+ coarse_poly_index,
+ coarse_corner_index,
+ subdiv_loop_start_index + 0,
+ v0,
+ e0);
+ ctx->foreach_context->loop(ctx->foreach_context,
+ tls,
+ ptex_face_index,
+ u + du,
+ v,
+ ORIGINDEX_NONE,
+ coarse_poly_index,
+ coarse_corner_index,
+ subdiv_loop_start_index + 1,
+ v1,
+ e1);
+ ctx->foreach_context->loop(ctx->foreach_context,
+ tls,
+ ptex_face_index,
+ u + du,
+ v + dv,
+ ORIGINDEX_NONE,
+ coarse_poly_index,
+ coarse_corner_index,
+ subdiv_loop_start_index + 2,
+ v2,
+ e2);
+ ctx->foreach_context->loop(ctx->foreach_context,
+ tls,
+ ptex_face_index,
+ u,
+ v + dv,
+ ORIGINDEX_NONE,
+ coarse_poly_index,
+ coarse_corner_index,
+ subdiv_loop_start_index + 3,
+ v3,
+ e3);
}
static void subdiv_foreach_loops_regular(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
{
- 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 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;
- const int num_subdiv_edges_per_coarse_edge = resolution - 1;
- const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
- const float inv_ptex_resolution_1 = 1.0f / (float)(ptex_resolution - 1);
- const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index];
- const int start_vertex_index =
- ctx->vertices_inner_offset +
- ctx->subdiv_vertex_offset[coarse_poly_index];
- const int start_edge_index =
- ctx->edge_inner_offset +
- ctx->subdiv_edge_offset[coarse_poly_index];
- const int start_poly_index = ctx->subdiv_polygon_offset[coarse_poly_index];
- const int start_loop_index = 4 * start_poly_index;
- const float du = inv_ptex_resolution_1;
- const float dv = inv_ptex_resolution_1;
- /* Hi-poly subdivided mesh. */
- int subdiv_loop_index = start_loop_index;
- /* Loops for inner part of ptex. */
- for (int y = 1; y < ptex_resolution - 2; y++) {
- const float v = y * inv_ptex_resolution_1;
- const int inner_y = y - 1;
- for (int x = 1; x < ptex_resolution - 2; x++, subdiv_loop_index += 4) {
- const int inner_x = x - 1;
- const float u = x * inv_ptex_resolution_1;
- /* Vertex indices ordered counter-clockwise. */
- const int v0 = start_vertex_index +
- (inner_y * ptex_inner_resolution + inner_x);
- const int v1 = v0 + 1;
- const int v2 = v0 + ptex_inner_resolution + 1;
- const int v3 = v0 + ptex_inner_resolution;
- /* Edge indices ordered counter-clockwise. */
- const int e0 = start_edge_index +
- (inner_y * (2 * ptex_inner_resolution - 1) + inner_x);
- const int e1 = e0 + ptex_inner_resolution;
- const int e2 = e0 + (2 * ptex_inner_resolution - 1);
- const int e3 = e0 + ptex_inner_resolution - 1;
- subdiv_foreach_loops_of_poly(
- ctx, tls, subdiv_loop_index, ptex_face_index,
- coarse_poly_index, 0,
- 0,
- v0, e0, v1, e1, v2, e2, v3, e3,
- u, v, du, dv);
- }
- }
- /* Loops for faces connecting inner ptex part with boundary. */
- const MLoop *prev_coarse_loop =
- &coarse_mloop[coarse_poly->loopstart + coarse_poly->totloop - 1];
- for (int corner = 0; corner < coarse_poly->totloop; corner++) {
- const MLoop *coarse_loop =
- &coarse_mloop[coarse_poly->loopstart + corner];
- const MEdge *coarse_edge = &coarse_medge[coarse_loop->e];
- const MEdge *prev_coarse_edge = &coarse_medge[prev_coarse_loop->e];
- const int start_edge_vertex = ctx->vertices_edge_offset +
- coarse_loop->e * num_subdiv_vertices_per_coarse_edge;
- const bool flip = (coarse_edge->v2 == coarse_loop->v);
- int side_start_index = start_vertex_index;
- int side_stride = 0;
- int v0 = ctx->vertices_corner_offset + coarse_loop->v;
- int v3, e3;
- int e2_offset, e2_stride;
- float u, v, delta_u, delta_v;
- if (prev_coarse_loop->v == prev_coarse_edge->v1) {
- v3 = ctx->vertices_edge_offset +
- prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge +
- num_subdiv_vertices_per_coarse_edge - 1;
- e3 = ctx->edge_boundary_offset +
- prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge +
- num_subdiv_edges_per_coarse_edge - 1;
- }
- else {
- v3 = ctx->vertices_edge_offset +
- prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge;
- e3 = ctx->edge_boundary_offset +
- prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge;
- }
- /* Calculate starting veretx of corresponding inner part of ptex. */
- if (corner == 0) {
- side_stride = 1;
- e2_offset = 0;
- e2_stride = 1;
- u = 0.0f;
- v = 0.0f;
- delta_u = du;
- delta_v = 0.0f;
- }
- else if (corner == 1) {
- side_start_index += resolution - 3;
- side_stride = resolution - 2;
- e2_offset = 2 * num_subdiv_edges_per_coarse_edge - 4;
- e2_stride = 2 * num_subdiv_edges_per_coarse_edge - 3;
- u = 1.0f - du;
- v = 0;
- delta_u = 0.0f;
- delta_v = dv;
- }
- else if (corner == 2) {
- side_start_index += num_subdiv_vertices_per_coarse_edge *
- num_subdiv_vertices_per_coarse_edge - 1;
- side_stride = -1;
- e2_offset = num_edges_per_ptex_face_get(resolution - 2) - 1;
- e2_stride = -1;
- u = 1.0f - du;
- v = 1.0f - dv;
- delta_u = -du;
- delta_v = 0.0f;
- }
- else if (corner == 3) {
- side_start_index += num_subdiv_vertices_per_coarse_edge *
- (num_subdiv_vertices_per_coarse_edge - 1);
- side_stride = -(resolution - 2);
- e2_offset = num_edges_per_ptex_face_get(resolution - 2) -
- (2 * num_subdiv_edges_per_coarse_edge - 3);
- e2_stride = -(2 * num_subdiv_edges_per_coarse_edge - 3);
- u = 0.0f;
- v = 1.0f - dv;
- delta_u = 0.0f;
- delta_v = -dv;
- }
- for (int i = 0; i < resolution - 2; i++, subdiv_loop_index += 4) {
- int v1;
- if (flip) {
- v1 = start_edge_vertex + (resolution - i - 3);
- }
- else {
- v1 = start_edge_vertex + i;
- }
- const int v2 = side_start_index + side_stride * i;
- int e0;
- if (flip) {
- e0 = ctx->edge_boundary_offset +
- coarse_loop->e * num_subdiv_edges_per_coarse_edge +
- num_subdiv_edges_per_coarse_edge - i - 1;
- }
- else {
- e0 = ctx->edge_boundary_offset +
- coarse_loop->e * num_subdiv_edges_per_coarse_edge +
- i;
- }
- int e1 = start_edge_index +
- num_edges_per_ptex_face_get(resolution - 2) +
- corner * num_subdiv_vertices_per_coarse_edge +
- i;
- int e2;
- if (i == 0) {
- e2 = start_edge_index +
- num_edges_per_ptex_face_get(resolution - 2) +
- ((corner - 1 + coarse_poly->totloop) %
- coarse_poly->totloop) *
- num_subdiv_vertices_per_coarse_edge +
- num_subdiv_vertices_per_coarse_edge - 1;
- }
- else {
- e2 = start_edge_index + e2_offset + e2_stride * (i - 1);
- }
- subdiv_foreach_loops_of_poly(
- ctx, tls, subdiv_loop_index, ptex_face_index,
- coarse_poly_index, corner,
- corner,
- v0, e0, v1, e1, v2, e2, v3, e3,
- u + delta_u * i, v + delta_v * i, du, dv);
- v0 = v1;
- v3 = v2;
- e3 = e1;
- }
- prev_coarse_loop = coarse_loop;
- }
+ 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 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;
+ const int num_subdiv_edges_per_coarse_edge = resolution - 1;
+ const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
+ const float inv_ptex_resolution_1 = 1.0f / (float)(ptex_resolution - 1);
+ const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index];
+ const int start_vertex_index = ctx->vertices_inner_offset +
+ ctx->subdiv_vertex_offset[coarse_poly_index];
+ const int start_edge_index = ctx->edge_inner_offset + ctx->subdiv_edge_offset[coarse_poly_index];
+ const int start_poly_index = ctx->subdiv_polygon_offset[coarse_poly_index];
+ const int start_loop_index = 4 * start_poly_index;
+ const float du = inv_ptex_resolution_1;
+ const float dv = inv_ptex_resolution_1;
+ /* Hi-poly subdivided mesh. */
+ int subdiv_loop_index = start_loop_index;
+ /* Loops for inner part of ptex. */
+ for (int y = 1; y < ptex_resolution - 2; y++) {
+ const float v = y * inv_ptex_resolution_1;
+ const int inner_y = y - 1;
+ for (int x = 1; x < ptex_resolution - 2; x++, subdiv_loop_index += 4) {
+ const int inner_x = x - 1;
+ const float u = x * inv_ptex_resolution_1;
+ /* Vertex indices ordered counter-clockwise. */
+ const int v0 = start_vertex_index + (inner_y * ptex_inner_resolution + inner_x);
+ const int v1 = v0 + 1;
+ const int v2 = v0 + ptex_inner_resolution + 1;
+ const int v3 = v0 + ptex_inner_resolution;
+ /* Edge indices ordered counter-clockwise. */
+ const int e0 = start_edge_index + (inner_y * (2 * ptex_inner_resolution - 1) + inner_x);
+ const int e1 = e0 + ptex_inner_resolution;
+ const int e2 = e0 + (2 * ptex_inner_resolution - 1);
+ const int e3 = e0 + ptex_inner_resolution - 1;
+ subdiv_foreach_loops_of_poly(ctx,
+ tls,
+ subdiv_loop_index,
+ ptex_face_index,
+ coarse_poly_index,
+ 0,
+ 0,
+ v0,
+ e0,
+ v1,
+ e1,
+ v2,
+ e2,
+ v3,
+ e3,
+ u,
+ v,
+ du,
+ dv);
+ }
+ }
+ /* Loops for faces connecting inner ptex part with boundary. */
+ const MLoop *prev_coarse_loop = &coarse_mloop[coarse_poly->loopstart + coarse_poly->totloop - 1];
+ for (int corner = 0; corner < coarse_poly->totloop; corner++) {
+ const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner];
+ const MEdge *coarse_edge = &coarse_medge[coarse_loop->e];
+ const MEdge *prev_coarse_edge = &coarse_medge[prev_coarse_loop->e];
+ const int start_edge_vertex = ctx->vertices_edge_offset +
+ coarse_loop->e * num_subdiv_vertices_per_coarse_edge;
+ const bool flip = (coarse_edge->v2 == coarse_loop->v);
+ int side_start_index = start_vertex_index;
+ int side_stride = 0;
+ int v0 = ctx->vertices_corner_offset + coarse_loop->v;
+ int v3, e3;
+ int e2_offset, e2_stride;
+ float u, v, delta_u, delta_v;
+ if (prev_coarse_loop->v == prev_coarse_edge->v1) {
+ v3 = ctx->vertices_edge_offset + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge +
+ num_subdiv_vertices_per_coarse_edge - 1;
+ e3 = ctx->edge_boundary_offset + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge +
+ num_subdiv_edges_per_coarse_edge - 1;
+ }
+ else {
+ v3 = ctx->vertices_edge_offset + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge;
+ e3 = ctx->edge_boundary_offset + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge;
+ }
+ /* Calculate starting veretx of corresponding inner part of ptex. */
+ if (corner == 0) {
+ side_stride = 1;
+ e2_offset = 0;
+ e2_stride = 1;
+ u = 0.0f;
+ v = 0.0f;
+ delta_u = du;
+ delta_v = 0.0f;
+ }
+ else if (corner == 1) {
+ side_start_index += resolution - 3;
+ side_stride = resolution - 2;
+ e2_offset = 2 * num_subdiv_edges_per_coarse_edge - 4;
+ e2_stride = 2 * num_subdiv_edges_per_coarse_edge - 3;
+ u = 1.0f - du;
+ v = 0;
+ delta_u = 0.0f;
+ delta_v = dv;
+ }
+ else if (corner == 2) {
+ side_start_index += num_subdiv_vertices_per_coarse_edge *
+ num_subdiv_vertices_per_coarse_edge -
+ 1;
+ side_stride = -1;
+ e2_offset = num_edges_per_ptex_face_get(resolution - 2) - 1;
+ e2_stride = -1;
+ u = 1.0f - du;
+ v = 1.0f - dv;
+ delta_u = -du;
+ delta_v = 0.0f;
+ }
+ else if (corner == 3) {
+ side_start_index += num_subdiv_vertices_per_coarse_edge *
+ (num_subdiv_vertices_per_coarse_edge - 1);
+ side_stride = -(resolution - 2);
+ e2_offset = num_edges_per_ptex_face_get(resolution - 2) -
+ (2 * num_subdiv_edges_per_coarse_edge - 3);
+ e2_stride = -(2 * num_subdiv_edges_per_coarse_edge - 3);
+ u = 0.0f;
+ v = 1.0f - dv;
+ delta_u = 0.0f;
+ delta_v = -dv;
+ }
+ for (int i = 0; i < resolution - 2; i++, subdiv_loop_index += 4) {
+ int v1;
+ if (flip) {
+ v1 = start_edge_vertex + (resolution - i - 3);
+ }
+ else {
+ v1 = start_edge_vertex + i;
+ }
+ const int v2 = side_start_index + side_stride * i;
+ int e0;
+ if (flip) {
+ e0 = ctx->edge_boundary_offset + coarse_loop->e * num_subdiv_edges_per_coarse_edge +
+ num_subdiv_edges_per_coarse_edge - i - 1;
+ }
+ else {
+ e0 = ctx->edge_boundary_offset + coarse_loop->e * num_subdiv_edges_per_coarse_edge + i;
+ }
+ int e1 = start_edge_index + num_edges_per_ptex_face_get(resolution - 2) +
+ corner * num_subdiv_vertices_per_coarse_edge + i;
+ int e2;
+ if (i == 0) {
+ e2 = start_edge_index + num_edges_per_ptex_face_get(resolution - 2) +
+ ((corner - 1 + coarse_poly->totloop) % coarse_poly->totloop) *
+ num_subdiv_vertices_per_coarse_edge +
+ num_subdiv_vertices_per_coarse_edge - 1;
+ }
+ else {
+ e2 = start_edge_index + e2_offset + e2_stride * (i - 1);
+ }
+ subdiv_foreach_loops_of_poly(ctx,
+ tls,
+ subdiv_loop_index,
+ ptex_face_index,
+ coarse_poly_index,
+ corner,
+ corner,
+ v0,
+ e0,
+ v1,
+ e1,
+ v2,
+ e2,
+ v3,
+ e3,
+ u + delta_u * i,
+ v + delta_v * i,
+ du,
+ dv);
+ v0 = v1;
+ v3 = v2;
+ e3 = e1;
+ }
+ prev_coarse_loop = coarse_loop;
+ }
}
static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx,
void *tls,
const MPoly *coarse_poly)
{
- 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 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;
- const float inv_ptex_resolution_1 =
- 1.0f / (float)(ptex_face_resolution - 1);
- const int num_inner_vertices_per_ptex =
- (ptex_face_resolution - 1) * (ptex_face_resolution - 2);
- const int num_inner_edges_per_ptex_face =
- num_inner_edges_per_ptex_face_get(
- ptex_face_inner_resolution + 1);
- const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
- const int num_subdiv_edges_per_coarse_edge = resolution - 1;
- const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index];
- const int center_vertex_index =
- ctx->vertices_inner_offset +
- ctx->subdiv_vertex_offset[coarse_poly_index];
- const int start_vertex_index = center_vertex_index + 1;
- const int start_inner_vertex_index = center_vertex_index + 1;
- const int start_edge_index = ctx->edge_inner_offset +
- ctx->subdiv_edge_offset[coarse_poly_index];
- const int start_poly_index = ctx->subdiv_polygon_offset[coarse_poly_index];
- const int start_loop_index = 4 * start_poly_index;
- const float du = inv_ptex_resolution_1;
- const float dv = inv_ptex_resolution_1;
- /* Hi-poly subdivided mesh. */
- int subdiv_loop_index = start_loop_index;
- for (int corner = 0; corner < coarse_poly->totloop; corner++) {
- const int corner_vertex_index =
- start_vertex_index + corner * num_inner_vertices_per_ptex;
- const int corner_edge_index =
- start_edge_index + corner * num_inner_edges_per_ptex_face;
- for (int y = 1; y < ptex_face_inner_resolution; y++) {
- const float v = y * inv_ptex_resolution_1;
- const int inner_y = y - 1;
- for (int x = 1;
- x < ptex_face_inner_resolution + 1;
- x++, subdiv_loop_index += 4)
- {
- const int inner_x = x - 1;
- const float u = x * inv_ptex_resolution_1;
- /* Vertex indices ordered counter-clockwise. */
- const int v0 =
- corner_vertex_index +
- (inner_y * (ptex_face_inner_resolution + 1) + inner_x);
- const int v1 = v0 + 1;
- const int v2 = v0 + ptex_face_inner_resolution + 2;
- const int v3 = v0 + ptex_face_inner_resolution + 1;
- /* Edge indices ordered counter-clockwise. */
- const int e0 = corner_edge_index +
- (inner_y * (2 * ptex_face_inner_resolution + 1) + inner_x);
- const int e1 = e0 + ptex_face_inner_resolution + 1;
- const int e2 = e0 + (2 * ptex_face_inner_resolution + 1);
- const int e3 = e0 + ptex_face_inner_resolution;
- subdiv_foreach_loops_of_poly(
- ctx, tls, subdiv_loop_index, ptex_face_index + corner,
- coarse_poly_index, corner,
- 0,
- v0, e0, v1, e1, v2, e2, v3, e3,
- u, v, du, dv);
- }
- }
- }
- /* Create connections between ptex faces. */
- for (int corner = 0; corner < coarse_poly->totloop; corner++) {
- const int next_corner = (corner + 1) % coarse_poly->totloop;
- const int corner_edge_index =
- start_edge_index + corner * num_inner_edges_per_ptex_face;
- const int next_corner_edge_index =
- start_edge_index + next_corner * num_inner_edges_per_ptex_face;
- int current_patch_vertex_index =
- start_inner_vertex_index +
- corner * num_inner_vertices_per_ptex +
- ptex_face_inner_resolution;
- int next_path_vertex_index =
- start_inner_vertex_index +
- next_corner * num_inner_vertices_per_ptex +
- num_inner_vertices_per_ptex - ptex_face_resolution + 1;
- int v0 = current_patch_vertex_index;
- int v1 = next_path_vertex_index;
- current_patch_vertex_index += ptex_face_inner_resolution + 1;
- next_path_vertex_index += 1;
- int e0 = start_edge_index +
- coarse_poly->totloop * num_inner_edges_per_ptex_face +
- corner * (ptex_face_resolution - 2);
- int e1 = next_corner_edge_index + num_inner_edges_per_ptex_face -
- ptex_face_resolution + 2;
- int e3 = corner_edge_index + 2 * ptex_face_resolution - 4;
- for (int row = 1;
- row < ptex_face_inner_resolution;
- row++, subdiv_loop_index += 4)
- {
- const int v2 = next_path_vertex_index;
- const int v3 = current_patch_vertex_index;
- const int e2 = e0 + 1;
- const float u = row * du;
- const float v = 1.0f - dv;
- subdiv_foreach_loops_of_poly(
- ctx, tls, subdiv_loop_index, ptex_face_index + next_corner,
- coarse_poly_index, next_corner,
- 3,
- v0, e0, v1, e1, v2, e2, v3, e3,
- u, v, du, dv);
- current_patch_vertex_index += ptex_face_inner_resolution + 1;
- next_path_vertex_index += 1;
- v0 = v3;
- v1 = v2;
- e0 = e2;
- e1 += 1;
- e3 += 2 * ptex_face_resolution - 3;
- }
- }
- /* Create loops from center. */
- if (ptex_face_resolution >= 3) {
- const int start_center_edge_index =
- start_edge_index +
- (num_inner_edges_per_ptex_face +
- ptex_face_inner_resolution) * coarse_poly->totloop;
- const int start_boundary_edge =
- start_edge_index +
- coarse_poly->totloop * num_inner_edges_per_ptex_face +
- ptex_face_inner_resolution - 1;
- for (int corner = 0, prev_corner = coarse_poly->totloop - 1;
- corner < coarse_poly->totloop;
- prev_corner = corner, corner++, subdiv_loop_index += 4)
- {
- const int corner_edge_index =
- start_edge_index +
- corner * num_inner_edges_per_ptex_face;
- const int current_patch_end_vertex_index =
- start_vertex_index + corner * num_inner_vertices_per_ptex +
- num_inner_vertices_per_ptex - 1;
- const int prev_current_patch_end_vertex_index =
- start_vertex_index + prev_corner *
- num_inner_vertices_per_ptex +
- num_inner_vertices_per_ptex - 1;
- const int v0 = center_vertex_index;
- const int v1 = prev_current_patch_end_vertex_index;
- const int v2 = current_patch_end_vertex_index - 1;
- const int v3 = current_patch_end_vertex_index;
- const int e0 = start_center_edge_index + prev_corner;
- const int e1 = start_boundary_edge +
- prev_corner * (ptex_face_inner_resolution);
- const int e2 = corner_edge_index +
- num_inner_edges_per_ptex_face - 1;
- const int e3 = start_center_edge_index + corner;
- const float u = 1.0f - du;
- const float v = 1.0f - dv;
- subdiv_foreach_loops_of_poly(
- ctx, tls, subdiv_loop_index,
- ptex_face_index + corner,
- coarse_poly_index, corner,
- 2,
- v0, e0, v1, e1, v2, e2, v3, e3,
- u, v, du, dv);
- }
- }
- /* Loops for faces connecting inner ptex part with boundary. */
- const MLoop *prev_coarse_loop =
- &coarse_mloop[coarse_poly->loopstart + coarse_poly->totloop - 1];
- for (int prev_corner = coarse_poly->totloop - 1, corner = 0;
- corner < coarse_poly->totloop;
- prev_corner = corner, corner++)
- {
- const MLoop *coarse_loop =
- &coarse_mloop[coarse_poly->loopstart + corner];
- const MEdge *coarse_edge = &coarse_medge[coarse_loop->e];
- const MEdge *prev_coarse_edge = &coarse_medge[prev_coarse_loop->e];
- const bool flip = (coarse_edge->v2 == coarse_loop->v);
- const int start_edge_vertex = ctx->vertices_edge_offset +
- coarse_loop->e * num_subdiv_vertices_per_coarse_edge;
- const int corner_vertex_index =
- start_vertex_index + corner * num_inner_vertices_per_ptex;
- const int corner_edge_index =
- start_edge_index + corner * num_inner_edges_per_ptex_face;
- /* Create loops for polygons along U axis. */
- int v0 = ctx->vertices_corner_offset + coarse_loop->v;
- int v3, e3;
- if (prev_coarse_loop->v == prev_coarse_edge->v1) {
- v3 = ctx->vertices_edge_offset +
- prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge +
- num_subdiv_vertices_per_coarse_edge - 1;
- e3 = ctx->edge_boundary_offset +
- prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge +
- num_subdiv_edges_per_coarse_edge - 1;
- }
- else {
- v3 = ctx->vertices_edge_offset +
- prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge;
- e3 = ctx->edge_boundary_offset +
- prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge;
- }
- for (int i = 0;
- i <= ptex_face_inner_resolution;
- i++, subdiv_loop_index += 4)
- {
- int v1;
- if (flip) {
- v1 = start_edge_vertex + (resolution - i - 3);
- }
- else {
- v1 = start_edge_vertex + i;
- }
- int v2;
- if (ptex_face_inner_resolution >= 1) {
- v2 = corner_vertex_index + i;
- }
- else {
- v2 = center_vertex_index;
- }
- int e0;
- if (flip) {
- e0 = ctx->edge_boundary_offset +
- coarse_loop->e * num_subdiv_edges_per_coarse_edge +
- num_subdiv_edges_per_coarse_edge - i - 1;
- }
- else {
- e0 = ctx->edge_boundary_offset +
- coarse_loop->e * num_subdiv_edges_per_coarse_edge +
- i;
- }
- int e1 = start_edge_index +
- corner * (2 * ptex_face_inner_resolution + 1);
- if (ptex_face_resolution >= 3) {
- e1 += coarse_poly->totloop * (num_inner_edges_per_ptex_face +
- ptex_face_inner_resolution + 1) +
- i;
- }
- int e2 = 0;
- if (i == 0 && ptex_face_resolution >= 3) {
- e2 = start_edge_index +
- coarse_poly->totloop *
- (num_inner_edges_per_ptex_face +
- ptex_face_inner_resolution + 1) +
- corner * (2 * ptex_face_inner_resolution + 1) +
- ptex_face_inner_resolution + 1;
- }
- else if (i == 0 && ptex_face_resolution < 3) {
- e2 = start_edge_index +
- prev_corner * (2 * ptex_face_inner_resolution + 1);
- }
- else {
- e2 = corner_edge_index + i - 1;
- }
- const float u = du * i;
- const float v = 0.0f;
- subdiv_foreach_loops_of_poly(
- ctx, tls, subdiv_loop_index, ptex_face_index + corner,
- coarse_poly_index, corner,
- 0,
- v0, e0, v1, e1, v2, e2, v3, e3,
- u, v, du, dv);
- v0 = v1;
- v3 = v2;
- e3 = e1;
- }
- /* Create loops for polygons along V axis. */
- const bool flip_prev = (prev_coarse_edge->v2 == coarse_loop->v);
- v0 = corner_vertex_index;
- if (prev_coarse_loop->v == prev_coarse_edge->v1) {
- v3 = ctx->vertices_edge_offset +
- prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge +
- num_subdiv_vertices_per_coarse_edge - 1;
- }
- else {
- v3 = ctx->vertices_edge_offset +
- prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge;
- }
- e3 = start_edge_index +
- coarse_poly->totloop *
- (num_inner_edges_per_ptex_face +
- ptex_face_inner_resolution + 1) +
- corner * (2 * ptex_face_inner_resolution + 1) +
- ptex_face_inner_resolution + 1;
- for (int i = 0;
- i <= ptex_face_inner_resolution - 1;
- i++, subdiv_loop_index += 4)
- {
- int v1;
- int e0, e1;
- if (i == ptex_face_inner_resolution - 1) {
- v1 = start_vertex_index +
- prev_corner * num_inner_vertices_per_ptex +
- ptex_face_inner_resolution;
- e1 = start_edge_index +
- coarse_poly->totloop *
- (num_inner_edges_per_ptex_face +
- ptex_face_inner_resolution + 1) +
- prev_corner * (2 * ptex_face_inner_resolution + 1) +
- ptex_face_inner_resolution;
- e0 = start_edge_index +
- coarse_poly->totloop * num_inner_edges_per_ptex_face +
- prev_corner * ptex_face_inner_resolution;
- }
- else {
- v1 = v0 + ptex_face_inner_resolution + 1;
- e0 = corner_edge_index + ptex_face_inner_resolution +
- i * (2 * ptex_face_inner_resolution + 1);
- e1 = e3 + 1;
- }
- int v2 = flip_prev ? v3 - 1 : v3 + 1;
- int e2;
- if (flip_prev) {
- e2 = ctx->edge_boundary_offset +
- prev_coarse_loop->e *
- num_subdiv_edges_per_coarse_edge +
- num_subdiv_edges_per_coarse_edge - 2 - i;
- }
- else {
- e2 = ctx->edge_boundary_offset +
- prev_coarse_loop->e *
- num_subdiv_edges_per_coarse_edge + 1 + i;
- }
- const float u = 0.0f;
- const float v = du * (i + 1);
- subdiv_foreach_loops_of_poly(
- ctx, tls, subdiv_loop_index, ptex_face_index + corner,
- coarse_poly_index, corner,
- 1,
- v0, e0, v1, e1, v2, e2, v3, e3,
- u, v, du, dv);
- v0 = v1;
- v3 = v2;
- e3 = e1;
- }
- prev_coarse_loop = coarse_loop;
- }
+ 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 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;
+ const float inv_ptex_resolution_1 = 1.0f / (float)(ptex_face_resolution - 1);
+ const int num_inner_vertices_per_ptex = (ptex_face_resolution - 1) * (ptex_face_resolution - 2);
+ const int num_inner_edges_per_ptex_face = num_inner_edges_per_ptex_face_get(
+ ptex_face_inner_resolution + 1);
+ const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
+ const int num_subdiv_edges_per_coarse_edge = resolution - 1;
+ const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index];
+ const int center_vertex_index = ctx->vertices_inner_offset +
+ ctx->subdiv_vertex_offset[coarse_poly_index];
+ const int start_vertex_index = center_vertex_index + 1;
+ const int start_inner_vertex_index = center_vertex_index + 1;
+ const int start_edge_index = ctx->edge_inner_offset + ctx->subdiv_edge_offset[coarse_poly_index];
+ const int start_poly_index = ctx->subdiv_polygon_offset[coarse_poly_index];
+ const int start_loop_index = 4 * start_poly_index;
+ const float du = inv_ptex_resolution_1;
+ const float dv = inv_ptex_resolution_1;
+ /* Hi-poly subdivided mesh. */
+ int subdiv_loop_index = start_loop_index;
+ for (int corner = 0; corner < coarse_poly->totloop; corner++) {
+ const int corner_vertex_index = start_vertex_index + corner * num_inner_vertices_per_ptex;
+ const int corner_edge_index = start_edge_index + corner * num_inner_edges_per_ptex_face;
+ for (int y = 1; y < ptex_face_inner_resolution; y++) {
+ const float v = y * inv_ptex_resolution_1;
+ const int inner_y = y - 1;
+ for (int x = 1; x < ptex_face_inner_resolution + 1; x++, subdiv_loop_index += 4) {
+ const int inner_x = x - 1;
+ const float u = x * inv_ptex_resolution_1;
+ /* Vertex indices ordered counter-clockwise. */
+ const int v0 = corner_vertex_index +
+ (inner_y * (ptex_face_inner_resolution + 1) + inner_x);
+ const int v1 = v0 + 1;
+ const int v2 = v0 + ptex_face_inner_resolution + 2;
+ const int v3 = v0 + ptex_face_inner_resolution + 1;
+ /* Edge indices ordered counter-clockwise. */
+ const int e0 = corner_edge_index +
+ (inner_y * (2 * ptex_face_inner_resolution + 1) + inner_x);
+ const int e1 = e0 + ptex_face_inner_resolution + 1;
+ const int e2 = e0 + (2 * ptex_face_inner_resolution + 1);
+ const int e3 = e0 + ptex_face_inner_resolution;
+ subdiv_foreach_loops_of_poly(ctx,
+ tls,
+ subdiv_loop_index,
+ ptex_face_index + corner,
+ coarse_poly_index,
+ corner,
+ 0,
+ v0,
+ e0,
+ v1,
+ e1,
+ v2,
+ e2,
+ v3,
+ e3,
+ u,
+ v,
+ du,
+ dv);
+ }
+ }
+ }
+ /* Create connections between ptex faces. */
+ for (int corner = 0; corner < coarse_poly->totloop; corner++) {
+ const int next_corner = (corner + 1) % coarse_poly->totloop;
+ const int corner_edge_index = start_edge_index + corner * num_inner_edges_per_ptex_face;
+ const int next_corner_edge_index = start_edge_index +
+ next_corner * num_inner_edges_per_ptex_face;
+ int current_patch_vertex_index = start_inner_vertex_index +
+ corner * num_inner_vertices_per_ptex +
+ ptex_face_inner_resolution;
+ int next_path_vertex_index = start_inner_vertex_index +
+ next_corner * num_inner_vertices_per_ptex +
+ num_inner_vertices_per_ptex - ptex_face_resolution + 1;
+ int v0 = current_patch_vertex_index;
+ int v1 = next_path_vertex_index;
+ current_patch_vertex_index += ptex_face_inner_resolution + 1;
+ next_path_vertex_index += 1;
+ int e0 = start_edge_index + coarse_poly->totloop * num_inner_edges_per_ptex_face +
+ corner * (ptex_face_resolution - 2);
+ int e1 = next_corner_edge_index + num_inner_edges_per_ptex_face - ptex_face_resolution + 2;
+ int e3 = corner_edge_index + 2 * ptex_face_resolution - 4;
+ for (int row = 1; row < ptex_face_inner_resolution; row++, subdiv_loop_index += 4) {
+ const int v2 = next_path_vertex_index;
+ const int v3 = current_patch_vertex_index;
+ const int e2 = e0 + 1;
+ const float u = row * du;
+ const float v = 1.0f - dv;
+ subdiv_foreach_loops_of_poly(ctx,
+ tls,
+ subdiv_loop_index,
+ ptex_face_index + next_corner,
+ coarse_poly_index,
+ next_corner,
+ 3,
+ v0,
+ e0,
+ v1,
+ e1,
+ v2,
+ e2,
+ v3,
+ e3,
+ u,
+ v,
+ du,
+ dv);
+ current_patch_vertex_index += ptex_face_inner_resolution + 1;
+ next_path_vertex_index += 1;
+ v0 = v3;
+ v1 = v2;
+ e0 = e2;
+ e1 += 1;
+ e3 += 2 * ptex_face_resolution - 3;
+ }
+ }
+ /* Create loops from center. */
+ if (ptex_face_resolution >= 3) {
+ const int start_center_edge_index = start_edge_index + (num_inner_edges_per_ptex_face +
+ ptex_face_inner_resolution) *
+ coarse_poly->totloop;
+ const int start_boundary_edge = start_edge_index +
+ coarse_poly->totloop * num_inner_edges_per_ptex_face +
+ ptex_face_inner_resolution - 1;
+ for (int corner = 0, prev_corner = coarse_poly->totloop - 1; corner < coarse_poly->totloop;
+ prev_corner = corner, corner++, subdiv_loop_index += 4) {
+ const int corner_edge_index = start_edge_index + corner * num_inner_edges_per_ptex_face;
+ const int current_patch_end_vertex_index = start_vertex_index +
+ corner * num_inner_vertices_per_ptex +
+ num_inner_vertices_per_ptex - 1;
+ const int prev_current_patch_end_vertex_index = start_vertex_index +
+ prev_corner * num_inner_vertices_per_ptex +
+ num_inner_vertices_per_ptex - 1;
+ const int v0 = center_vertex_index;
+ const int v1 = prev_current_patch_end_vertex_index;
+ const int v2 = current_patch_end_vertex_index - 1;
+ const int v3 = current_patch_end_vertex_index;
+ const int e0 = start_center_edge_index + prev_corner;
+ const int e1 = start_boundary_edge + prev_corner * (ptex_face_inner_resolution);
+ const int e2 = corner_edge_index + num_inner_edges_per_ptex_face - 1;
+ const int e3 = start_center_edge_index + corner;
+ const float u = 1.0f - du;
+ const float v = 1.0f - dv;
+ subdiv_foreach_loops_of_poly(ctx,
+ tls,
+ subdiv_loop_index,
+ ptex_face_index + corner,
+ coarse_poly_index,
+ corner,
+ 2,
+ v0,
+ e0,
+ v1,
+ e1,
+ v2,
+ e2,
+ v3,
+ e3,
+ u,
+ v,
+ du,
+ dv);
+ }
+ }
+ /* Loops for faces connecting inner ptex part with boundary. */
+ const MLoop *prev_coarse_loop = &coarse_mloop[coarse_poly->loopstart + coarse_poly->totloop - 1];
+ for (int prev_corner = coarse_poly->totloop - 1, corner = 0; corner < coarse_poly->totloop;
+ prev_corner = corner, corner++) {
+ const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner];
+ const MEdge *coarse_edge = &coarse_medge[coarse_loop->e];
+ const MEdge *prev_coarse_edge = &coarse_medge[prev_coarse_loop->e];
+ const bool flip = (coarse_edge->v2 == coarse_loop->v);
+ const int start_edge_vertex = ctx->vertices_edge_offset +
+ coarse_loop->e * num_subdiv_vertices_per_coarse_edge;
+ const int corner_vertex_index = start_vertex_index + corner * num_inner_vertices_per_ptex;
+ const int corner_edge_index = start_edge_index + corner * num_inner_edges_per_ptex_face;
+ /* Create loops for polygons along U axis. */
+ int v0 = ctx->vertices_corner_offset + coarse_loop->v;
+ int v3, e3;
+ if (prev_coarse_loop->v == prev_coarse_edge->v1) {
+ v3 = ctx->vertices_edge_offset + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge +
+ num_subdiv_vertices_per_coarse_edge - 1;
+ e3 = ctx->edge_boundary_offset + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge +
+ num_subdiv_edges_per_coarse_edge - 1;
+ }
+ else {
+ v3 = ctx->vertices_edge_offset + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge;
+ e3 = ctx->edge_boundary_offset + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge;
+ }
+ for (int i = 0; i <= ptex_face_inner_resolution; i++, subdiv_loop_index += 4) {
+ int v1;
+ if (flip) {
+ v1 = start_edge_vertex + (resolution - i - 3);
+ }
+ else {
+ v1 = start_edge_vertex + i;
+ }
+ int v2;
+ if (ptex_face_inner_resolution >= 1) {
+ v2 = corner_vertex_index + i;
+ }
+ else {
+ v2 = center_vertex_index;
+ }
+ int e0;
+ if (flip) {
+ e0 = ctx->edge_boundary_offset + coarse_loop->e * num_subdiv_edges_per_coarse_edge +
+ num_subdiv_edges_per_coarse_edge - i - 1;
+ }
+ else {
+ e0 = ctx->edge_boundary_offset + coarse_loop->e * num_subdiv_edges_per_coarse_edge + i;
+ }
+ int e1 = start_edge_index + corner * (2 * ptex_face_inner_resolution + 1);
+ if (ptex_face_resolution >= 3) {
+ e1 += coarse_poly->totloop *
+ (num_inner_edges_per_ptex_face + ptex_face_inner_resolution + 1) +
+ i;
+ }
+ int e2 = 0;
+ if (i == 0 && ptex_face_resolution >= 3) {
+ e2 = start_edge_index +
+ coarse_poly->totloop *
+ (num_inner_edges_per_ptex_face + ptex_face_inner_resolution + 1) +
+ corner * (2 * ptex_face_inner_resolution + 1) + ptex_face_inner_resolution + 1;
+ }
+ else if (i == 0 && ptex_face_resolution < 3) {
+ e2 = start_edge_index + prev_corner * (2 * ptex_face_inner_resolution + 1);
+ }
+ else {
+ e2 = corner_edge_index + i - 1;
+ }
+ const float u = du * i;
+ const float v = 0.0f;
+ subdiv_foreach_loops_of_poly(ctx,
+ tls,
+ subdiv_loop_index,
+ ptex_face_index + corner,
+ coarse_poly_index,
+ corner,
+ 0,
+ v0,
+ e0,
+ v1,
+ e1,
+ v2,
+ e2,
+ v3,
+ e3,
+ u,
+ v,
+ du,
+ dv);
+ v0 = v1;
+ v3 = v2;
+ e3 = e1;
+ }
+ /* Create loops for polygons along V axis. */
+ const bool flip_prev = (prev_coarse_edge->v2 == coarse_loop->v);
+ v0 = corner_vertex_index;
+ if (prev_coarse_loop->v == prev_coarse_edge->v1) {
+ v3 = ctx->vertices_edge_offset + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge +
+ num_subdiv_vertices_per_coarse_edge - 1;
+ }
+ else {
+ v3 = ctx->vertices_edge_offset + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge;
+ }
+ e3 = start_edge_index +
+ coarse_poly->totloop * (num_inner_edges_per_ptex_face + ptex_face_inner_resolution + 1) +
+ corner * (2 * ptex_face_inner_resolution + 1) + ptex_face_inner_resolution + 1;
+ for (int i = 0; i <= ptex_face_inner_resolution - 1; i++, subdiv_loop_index += 4) {
+ int v1;
+ int e0, e1;
+ if (i == ptex_face_inner_resolution - 1) {
+ v1 = start_vertex_index + prev_corner * num_inner_vertices_per_ptex +
+ ptex_face_inner_resolution;
+ e1 = start_edge_index +
+ coarse_poly->totloop *
+ (num_inner_edges_per_ptex_face + ptex_face_inner_resolution + 1) +
+ prev_corner * (2 * ptex_face_inner_resolution + 1) + ptex_face_inner_resolution;
+ e0 = start_edge_index + coarse_poly->totloop * num_inner_edges_per_ptex_face +
+ prev_corner * ptex_face_inner_resolution;
+ }
+ else {
+ v1 = v0 + ptex_face_inner_resolution + 1;
+ e0 = corner_edge_index + ptex_face_inner_resolution +
+ i * (2 * ptex_face_inner_resolution + 1);
+ e1 = e3 + 1;
+ }
+ int v2 = flip_prev ? v3 - 1 : v3 + 1;
+ int e2;
+ if (flip_prev) {
+ e2 = ctx->edge_boundary_offset + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge +
+ num_subdiv_edges_per_coarse_edge - 2 - i;
+ }
+ else {
+ e2 = ctx->edge_boundary_offset + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge +
+ 1 + i;
+ }
+ const float u = 0.0f;
+ const float v = du * (i + 1);
+ subdiv_foreach_loops_of_poly(ctx,
+ tls,
+ subdiv_loop_index,
+ ptex_face_index + corner,
+ coarse_poly_index,
+ corner,
+ 1,
+ v0,
+ e0,
+ v1,
+ e1,
+ v2,
+ e2,
+ v3,
+ e3,
+ u,
+ v,
+ du,
+ dv);
+ v0 = v1;
+ v3 = v2;
+ e3 = e1;
+ }
+ prev_coarse_loop = coarse_loop;
+ }
}
-static void subdiv_foreach_loops(SubdivForeachTaskContext *ctx,
- void *tls,
- int poly_index)
+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_poly = &coarse_mpoly[poly_index];
- if (coarse_poly->totloop == 4) {
- subdiv_foreach_loops_regular(ctx, tls, coarse_poly);
- }
- else {
- subdiv_foreach_loops_special(ctx, tls, coarse_poly);
- }
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MPoly *coarse_poly = &coarse_mpoly[poly_index];
+ if (coarse_poly->totloop == 4) {
+ subdiv_foreach_loops_regular(ctx, tls, coarse_poly);
+ }
+ else {
+ subdiv_foreach_loops_special(ctx, tls, coarse_poly);
+ }
}
/* =============================================================================
* Polygons traverse process.
*/
-static void subdiv_foreach_polys(SubdivForeachTaskContext *ctx,
- void *tls,
- int poly_index)
+static void subdiv_foreach_polys(SubdivForeachTaskContext *ctx, void *tls, int poly_index)
{
- const int resolution = ctx->settings->resolution;
- 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_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);
- const int num_polys_per_ptex = num_polys_per_ptex_get(ptex_resolution);
- const int num_loops_per_ptex = 4 * num_polys_per_ptex;
- const int start_loop_index = 4 * start_poly_index;
- /* Hi-poly subdivided mesh. */
- int subdiv_polyon_index = start_poly_index;
- for (int ptex_of_poly_index = 0;
- ptex_of_poly_index < num_ptex_faces_per_poly;
- ptex_of_poly_index++)
- {
- for (int subdiv_poly_index = 0;
- subdiv_poly_index < num_polys_per_ptex;
- subdiv_poly_index++, subdiv_polyon_index++)
- {
- const int loopstart = start_loop_index +
- (ptex_of_poly_index * num_loops_per_ptex) +
- (subdiv_poly_index * 4);
- ctx->foreach_context->poly(
- ctx->foreach_context,
- tls,
- poly_index,
- subdiv_polyon_index,
- loopstart, 4);
- }
- }
+ const int resolution = ctx->settings->resolution;
+ 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_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);
+ const int num_polys_per_ptex = num_polys_per_ptex_get(ptex_resolution);
+ const int num_loops_per_ptex = 4 * num_polys_per_ptex;
+ const int start_loop_index = 4 * start_poly_index;
+ /* Hi-poly subdivided mesh. */
+ int subdiv_polyon_index = start_poly_index;
+ for (int ptex_of_poly_index = 0; ptex_of_poly_index < num_ptex_faces_per_poly;
+ ptex_of_poly_index++) {
+ for (int subdiv_poly_index = 0; subdiv_poly_index < num_polys_per_ptex;
+ subdiv_poly_index++, subdiv_polyon_index++) {
+ const int loopstart = start_loop_index + (ptex_of_poly_index * num_loops_per_ptex) +
+ (subdiv_poly_index * 4);
+ ctx->foreach_context->poly(
+ ctx->foreach_context, tls, poly_index, subdiv_polyon_index, loopstart, 4);
+ }
+ }
}
/* =============================================================================
* Loose elements traverse process.
*/
-static void subdiv_foreach_loose_vertices_task(
- void *__restrict userdata,
- const int coarse_vertex_index,
- const ParallelRangeTLS *__restrict tls)
+static void subdiv_foreach_loose_vertices_task(void *__restrict userdata,
+ const int coarse_vertex_index,
+ const ParallelRangeTLS *__restrict tls)
{
- SubdivForeachTaskContext *ctx = userdata;
- if (BLI_BITMAP_TEST_BOOL(ctx->coarse_vertices_used_map,
- coarse_vertex_index))
- {
- /* Vertex is not loose, was handled when handling polygons. */
- return;
- }
- const int subdiv_vertex_index =
- ctx->vertices_corner_offset + coarse_vertex_index;
- ctx->foreach_context->vertex_loose(
- ctx->foreach_context,
- tls->userdata_chunk,
- coarse_vertex_index,
- subdiv_vertex_index);
+ SubdivForeachTaskContext *ctx = userdata;
+ if (BLI_BITMAP_TEST_BOOL(ctx->coarse_vertices_used_map, coarse_vertex_index)) {
+ /* Vertex is not loose, was handled when handling polygons. */
+ return;
+ }
+ const int subdiv_vertex_index = ctx->vertices_corner_offset + coarse_vertex_index;
+ ctx->foreach_context->vertex_loose(
+ ctx->foreach_context, tls->userdata_chunk, coarse_vertex_index, subdiv_vertex_index);
}
-static void subdiv_foreach_vertices_of_loose_edges_task(
- void *__restrict userdata,
- const int coarse_edge_index,
- const ParallelRangeTLS *__restrict tls)
+static void subdiv_foreach_vertices_of_loose_edges_task(void *__restrict userdata,
+ const int coarse_edge_index,
+ const ParallelRangeTLS *__restrict tls)
{
- SubdivForeachTaskContext *ctx = userdata;
- if (BLI_BITMAP_TEST_BOOL(ctx->coarse_edges_used_map, coarse_edge_index)) {
- /* Vertex is not loose, was handled when handling polygons. */
- return;
- }
- const int resolution = ctx->settings->resolution;
- const int resolution_1 = resolution - 1;
- 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];
- /* Subdivion 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;
- /* First subdivided inner vertex of the edge. */
- const int subdiv_start_vertex =
- ctx->vertices_edge_offset +
- coarse_edge_index * num_subdiv_vertices_per_coarse_edge;
- /* Perform interpolation. */
- for (int i = 0; i < resolution; i++) {
- const float u = i * inv_resolution_1;
- int subdiv_vertex_index;
- if (i == 0) {
- subdiv_vertex_index = subdiv_v1_index;
- }
- else if (i == resolution - 1) {
- subdiv_vertex_index = subdiv_v2_index;
- }
- else {
- subdiv_vertex_index = subdiv_start_vertex + (i - 1);
- }
- ctx->foreach_context->vertex_of_loose_edge(
- ctx->foreach_context,
- tls->userdata_chunk,
- coarse_edge_index,
- u,
- subdiv_vertex_index);
- }
+ SubdivForeachTaskContext *ctx = userdata;
+ if (BLI_BITMAP_TEST_BOOL(ctx->coarse_edges_used_map, coarse_edge_index)) {
+ /* Vertex is not loose, was handled when handling polygons. */
+ return;
+ }
+ const int resolution = ctx->settings->resolution;
+ const int resolution_1 = resolution - 1;
+ 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];
+ /* Subdivion 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;
+ /* First subdivided inner vertex of the edge. */
+ const int subdiv_start_vertex = ctx->vertices_edge_offset +
+ coarse_edge_index * num_subdiv_vertices_per_coarse_edge;
+ /* Perform interpolation. */
+ for (int i = 0; i < resolution; i++) {
+ const float u = i * inv_resolution_1;
+ int subdiv_vertex_index;
+ if (i == 0) {
+ subdiv_vertex_index = subdiv_v1_index;
+ }
+ else if (i == resolution - 1) {
+ subdiv_vertex_index = subdiv_v2_index;
+ }
+ else {
+ subdiv_vertex_index = subdiv_start_vertex + (i - 1);
+ }
+ ctx->foreach_context->vertex_of_loose_edge(
+ ctx->foreach_context, tls->userdata_chunk, coarse_edge_index, u, subdiv_vertex_index);
+ }
}
/* =============================================================================
* Subdivision process entry points.
*/
-static void subdiv_foreach_single_geometry_vertices(
- SubdivForeachTaskContext *ctx,
- void *tls)
+static void subdiv_foreach_single_geometry_vertices(SubdivForeachTaskContext *ctx, void *tls)
{
- if (ctx->foreach_context->vertex_corner == NULL) {
- return;
- }
- const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
- 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);
- subdiv_foreach_edge_vertices(ctx, tls, coarse_poly);
- }
+ if (ctx->foreach_context->vertex_corner == NULL) {
+ return;
+ }
+ const Mesh *coarse_mesh = ctx->coarse_mesh;
+ const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ 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);
+ subdiv_foreach_edge_vertices(ctx, tls, coarse_poly);
+ }
}
static void subdiv_foreach_single_thread_tasks(SubdivForeachTaskContext *ctx)
{
- /* NOTE: In theory, we can try to skip allocation of TLS here, but in
- * practice if the callbacks used here are not specified then TLS will not
- * be requested anyway. */
- void *tls = subdiv_foreach_tls_alloc(ctx);
- /* Passes to average displacement on the corner vertices
- * and boundary edges. */
- subdiv_foreach_every_corner_vertices(ctx, tls);
- subdiv_foreach_every_edge_vertices(ctx, tls);
- /* Run callbacks which are supposed to be run once per shared geometry. */
- subdiv_foreach_single_geometry_vertices(ctx, tls);
- subdiv_foreach_tls_free(ctx, tls);
+ /* NOTE: In theory, we can try to skip allocation of TLS here, but in
+ * practice if the callbacks used here are not specified then TLS will not
+ * be requested anyway. */
+ void *tls = subdiv_foreach_tls_alloc(ctx);
+ /* Passes to average displacement on the corner vertices
+ * and boundary edges. */
+ subdiv_foreach_every_corner_vertices(ctx, tls);
+ subdiv_foreach_every_edge_vertices(ctx, tls);
+ /* Run callbacks which are supposed to be run once per shared geometry. */
+ subdiv_foreach_single_geometry_vertices(ctx, tls);
+ subdiv_foreach_tls_free(ctx, tls);
}
-static void subdiv_foreach_task(
- void *__restrict userdata,
- const int poly_index,
- const ParallelRangeTLS *__restrict tls)
+static void subdiv_foreach_task(void *__restrict userdata,
+ const int poly_index,
+ const ParallelRangeTLS *__restrict tls)
{
- SubdivForeachTaskContext *ctx = userdata;
- /* Traverse hi-poly vertex coordinates and normals. */
- subdiv_foreach_vertices(ctx, tls->userdata_chunk, poly_index);
- /* Traverse mesh geometry for the given base poly index. */
- if (ctx->foreach_context->edge != NULL) {
- subdiv_foreach_edges(ctx, tls->userdata_chunk, poly_index);
- }
- if (ctx->foreach_context->loop != NULL) {
- subdiv_foreach_loops(ctx, tls->userdata_chunk, poly_index);
- }
- if (ctx->foreach_context->poly != NULL) {
- subdiv_foreach_polys(ctx, tls->userdata_chunk, poly_index);
- }
+ SubdivForeachTaskContext *ctx = userdata;
+ /* Traverse hi-poly vertex coordinates and normals. */
+ subdiv_foreach_vertices(ctx, tls->userdata_chunk, poly_index);
+ /* Traverse mesh geometry for the given base poly index. */
+ if (ctx->foreach_context->edge != NULL) {
+ subdiv_foreach_edges(ctx, tls->userdata_chunk, poly_index);
+ }
+ if (ctx->foreach_context->loop != NULL) {
+ subdiv_foreach_loops(ctx, tls->userdata_chunk, poly_index);
+ }
+ if (ctx->foreach_context->poly != NULL) {
+ subdiv_foreach_polys(ctx, tls->userdata_chunk, poly_index);
+ }
}
-static void subdiv_foreach_boundary_edges_task(
- void *__restrict userdata,
- const int edge_index,
- const ParallelRangeTLS *__restrict tls)
+static void subdiv_foreach_boundary_edges_task(void *__restrict userdata,
+ const int edge_index,
+ const ParallelRangeTLS *__restrict tls)
{
- SubdivForeachTaskContext *ctx = userdata;
- subdiv_foreach_boundary_edges(ctx, tls->userdata_chunk, edge_index);
+ SubdivForeachTaskContext *ctx = userdata;
+ subdiv_foreach_boundary_edges(ctx, tls->userdata_chunk, edge_index);
}
-static void subdiv_foreach_finalize(void *__restrict userdata,
- void *__restrict userdata_chunk)
+static void subdiv_foreach_finalize(void *__restrict userdata, void *__restrict userdata_chunk)
{
- SubdivForeachTaskContext *ctx = userdata;
- ctx->foreach_context->user_data_tls_free(userdata_chunk);
+ SubdivForeachTaskContext *ctx = userdata;
+ ctx->foreach_context->user_data_tls_free(userdata_chunk);
}
-bool BKE_subdiv_foreach_subdiv_geometry(
- Subdiv *subdiv,
- const SubdivForeachContext *context,
- const SubdivToMeshSettings *mesh_settings,
- const Mesh *coarse_mesh)
+bool BKE_subdiv_foreach_subdiv_geometry(Subdiv *subdiv,
+ const SubdivForeachContext *context,
+ const SubdivToMeshSettings *mesh_settings,
+ const Mesh *coarse_mesh)
{
- SubdivForeachTaskContext ctx = {0};
- ctx.coarse_mesh = coarse_mesh;
- ctx.settings = mesh_settings;
- ctx.foreach_context = context;
- subdiv_foreach_ctx_init(subdiv, &ctx);
- if (context->topology_info != NULL) {
- if (!context->topology_info(context,
- ctx.num_subdiv_vertices,
- ctx.num_subdiv_edges,
- ctx.num_subdiv_loops,
- ctx.num_subdiv_polygons))
- {
- subdiv_foreach_ctx_free(&ctx);
- return false;
- }
- }
- /* Run all the code which is not supposed to be run from threads. */
- subdiv_foreach_single_thread_tasks(&ctx);
- /* Threaded traversal of the rest of topology. */
- ParallelRangeSettings parallel_range_settings;
- BLI_parallel_range_settings_defaults(&parallel_range_settings);
- parallel_range_settings.userdata_chunk = context->user_data_tls;
- parallel_range_settings.userdata_chunk_size = context->user_data_tls_size;
- if (context->user_data_tls_free != NULL) {
- parallel_range_settings.func_finalize = subdiv_foreach_finalize;
- }
- BLI_task_parallel_range(0, coarse_mesh->totpoly,
- &ctx,
- subdiv_foreach_task,
- &parallel_range_settings);
- if (context->vertex_loose != NULL) {
- BLI_task_parallel_range(0, coarse_mesh->totvert,
- &ctx,
- subdiv_foreach_loose_vertices_task,
- &parallel_range_settings);
- }
- if (context->vertex_of_loose_edge != NULL) {
- BLI_task_parallel_range(0, coarse_mesh->totedge,
- &ctx,
- subdiv_foreach_vertices_of_loose_edges_task,
- &parallel_range_settings);
- }
- if (context->edge != NULL) {
- BLI_task_parallel_range(0, coarse_mesh->totedge,
- &ctx,
- subdiv_foreach_boundary_edges_task,
- &parallel_range_settings);
- }
- subdiv_foreach_ctx_free(&ctx);
- return true;
+ SubdivForeachTaskContext ctx = {0};
+ ctx.coarse_mesh = coarse_mesh;
+ ctx.settings = mesh_settings;
+ ctx.foreach_context = context;
+ subdiv_foreach_ctx_init(subdiv, &ctx);
+ if (context->topology_info != NULL) {
+ if (!context->topology_info(context,
+ ctx.num_subdiv_vertices,
+ ctx.num_subdiv_edges,
+ ctx.num_subdiv_loops,
+ ctx.num_subdiv_polygons)) {
+ subdiv_foreach_ctx_free(&ctx);
+ return false;
+ }
+ }
+ /* Run all the code which is not supposed to be run from threads. */
+ subdiv_foreach_single_thread_tasks(&ctx);
+ /* Threaded traversal of the rest of topology. */
+ ParallelRangeSettings parallel_range_settings;
+ BLI_parallel_range_settings_defaults(&parallel_range_settings);
+ parallel_range_settings.userdata_chunk = context->user_data_tls;
+ parallel_range_settings.userdata_chunk_size = context->user_data_tls_size;
+ if (context->user_data_tls_free != NULL) {
+ parallel_range_settings.func_finalize = subdiv_foreach_finalize;
+ }
+ BLI_task_parallel_range(
+ 0, coarse_mesh->totpoly, &ctx, subdiv_foreach_task, &parallel_range_settings);
+ if (context->vertex_loose != NULL) {
+ BLI_task_parallel_range(0,
+ coarse_mesh->totvert,
+ &ctx,
+ subdiv_foreach_loose_vertices_task,
+ &parallel_range_settings);
+ }
+ if (context->vertex_of_loose_edge != NULL) {
+ BLI_task_parallel_range(0,
+ coarse_mesh->totedge,
+ &ctx,
+ subdiv_foreach_vertices_of_loose_edges_task,
+ &parallel_range_settings);
+ }
+ if (context->edge != NULL) {
+ BLI_task_parallel_range(0,
+ coarse_mesh->totedge,
+ &ctx,
+ subdiv_foreach_boundary_edges_task,
+ &parallel_range_settings);
+ }
+ subdiv_foreach_ctx_free(&ctx);
+ return true;
}