Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/subdiv_foreach.cc
| Show First 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | |||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Context which is passed to all threaded tasks | /** \name Context which is passed to all threaded tasks | ||||
| * \{ */ | * \{ */ | ||||
| struct SubdivForeachTaskContext { | struct SubdivForeachTaskContext { | ||||
| const Mesh *coarse_mesh; | const Mesh *coarse_mesh; | ||||
| const MEdge *coarse_edges; | const MEdge *coarse_edges; | ||||
| const MPoly *coarse_polys; | const MPoly *coarse_polys; | ||||
| const MLoop *coarse_loops; | const int *coarse_corner_verts; | ||||
| const int *coarse_corner_edges; | |||||
| const SubdivToMeshSettings *settings; | const SubdivToMeshSettings *settings; | ||||
| /* Callbacks. */ | /* Callbacks. */ | ||||
| const SubdivForeachContext *foreach_context; | const SubdivForeachContext *foreach_context; | ||||
| /* Counters of geometry in subdivided mesh, initialized as a part of | /* Counters of geometry in subdivided mesh, initialized as a part of | ||||
| * offsets calculation. | * offsets calculation. | ||||
| */ | */ | ||||
| int num_subdiv_vertices; | int num_subdiv_vertices; | ||||
| int num_subdiv_edges; | int num_subdiv_edges; | ||||
| ▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | |||||
| const Mesh *coarse_mesh = ctx->coarse_mesh; | const Mesh *coarse_mesh = ctx->coarse_mesh; | ||||
| ctx->num_subdiv_vertices = coarse_mesh->totvert; | ctx->num_subdiv_vertices = coarse_mesh->totvert; | ||||
| ctx->num_subdiv_edges = coarse_mesh->totedge * (num_subdiv_vertices_per_coarse_edge + 1); | ctx->num_subdiv_edges = coarse_mesh->totedge * (num_subdiv_vertices_per_coarse_edge + 1); | ||||
| /* Calculate extra vertices and edges created by non-loose geometry. */ | /* Calculate extra vertices and edges created by non-loose geometry. */ | ||||
| for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) { | for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) { | ||||
| const MPoly *coarse_poly = &ctx->coarse_polys[poly_index]; | const MPoly *coarse_poly = &ctx->coarse_polys[poly_index]; | ||||
| const int num_ptex_faces_per_poly = num_ptex_faces_per_poly_get(coarse_poly); | const int num_ptex_faces_per_poly = num_ptex_faces_per_poly_get(coarse_poly); | ||||
| for (int corner = 0; corner < coarse_poly->totloop; corner++) { | for (int corner = 0; corner < coarse_poly->totloop; corner++) { | ||||
| const MLoop *loop = &ctx->coarse_loops[coarse_poly->loopstart + corner]; | const int coarse_edge = ctx->coarse_corner_edges[coarse_poly->loopstart + corner]; | ||||
| const bool is_edge_used = BLI_BITMAP_TEST_BOOL(ctx->coarse_edges_used_map, loop->e); | const bool is_edge_used = BLI_BITMAP_TEST_BOOL(ctx->coarse_edges_used_map, coarse_edge); | ||||
| /* Edges which aren't counted yet. */ | /* Edges which aren't counted yet. */ | ||||
| if (!is_edge_used) { | if (!is_edge_used) { | ||||
| BLI_BITMAP_ENABLE(ctx->coarse_edges_used_map, loop->e); | BLI_BITMAP_ENABLE(ctx->coarse_edges_used_map, coarse_edge); | ||||
| ctx->num_subdiv_vertices += num_subdiv_vertices_per_coarse_edge; | ctx->num_subdiv_vertices += num_subdiv_vertices_per_coarse_edge; | ||||
| } | } | ||||
| } | } | ||||
| /* Inner vertices of polygon. */ | /* Inner vertices of polygon. */ | ||||
| if (num_ptex_faces_per_poly == 1) { | if (num_ptex_faces_per_poly == 1) { | ||||
| ctx->num_subdiv_vertices += num_inner_vertices_per_quad; | ctx->num_subdiv_vertices += num_inner_vertices_per_quad; | ||||
| ctx->num_subdiv_edges += num_edges_per_ptex_face_get(resolution - 2) + | ctx->num_subdiv_edges += num_edges_per_ptex_face_get(resolution - 2) + | ||||
| 4 * num_subdiv_vertices_per_coarse_edge; | 4 * num_subdiv_vertices_per_coarse_edge; | ||||
| ▲ Show 20 Lines • Show All 114 Lines • ▼ Show 20 Lines | |||||
| const MPoly *coarse_poly, | const MPoly *coarse_poly, | ||||
| SubdivForeachVertexFromCornerCb vertex_corner, | SubdivForeachVertexFromCornerCb vertex_corner, | ||||
| bool check_usage) | 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 float weights[4][2] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}}; | ||||
| const int coarse_poly_index = coarse_poly - ctx->coarse_polys; | const int coarse_poly_index = coarse_poly - ctx->coarse_polys; | ||||
| const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; | const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; | ||||
| for (int corner = 0; corner < coarse_poly->totloop; corner++) { | for (int corner = 0; corner < coarse_poly->totloop; corner++) { | ||||
| const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner]; | const int coarse_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + corner]; | ||||
| if (check_usage && | if (check_usage && | ||||
| BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map, coarse_loop->v)) { | BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map, coarse_vert)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| const int coarse_vertex_index = coarse_loop->v; | const int coarse_vertex_index = coarse_vert; | ||||
| const int subdiv_vertex_index = ctx->vertices_corner_offset + coarse_vertex_index; | const int subdiv_vertex_index = ctx->vertices_corner_offset + coarse_vertex_index; | ||||
| const float u = weights[corner][0]; | const float u = weights[corner][0]; | ||||
| const float v = weights[corner][1]; | const float v = weights[corner][1]; | ||||
| vertex_corner(ctx->foreach_context, | vertex_corner(ctx->foreach_context, | ||||
| tls, | tls, | ||||
| ptex_face_index, | ptex_face_index, | ||||
| u, | u, | ||||
| v, | v, | ||||
| Show All 17 Lines | |||||
| void *tls, | void *tls, | ||||
| const MPoly *coarse_poly, | const MPoly *coarse_poly, | ||||
| SubdivForeachVertexFromCornerCb vertex_corner, | SubdivForeachVertexFromCornerCb vertex_corner, | ||||
| bool check_usage) | bool check_usage) | ||||
| { | { | ||||
| const int coarse_poly_index = coarse_poly - ctx->coarse_polys; | const int coarse_poly_index = coarse_poly - ctx->coarse_polys; | ||||
| int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; | int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; | ||||
| for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) { | for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) { | ||||
| const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner]; | const int coarse_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + corner]; | ||||
| if (check_usage && | if (check_usage && | ||||
| BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map, coarse_loop->v)) { | BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_vertices_used_map, coarse_vert)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| const int coarse_vertex_index = coarse_loop->v; | const int coarse_vertex_index = coarse_vert; | ||||
| const int subdiv_vertex_index = ctx->vertices_corner_offset + coarse_vertex_index; | const int subdiv_vertex_index = ctx->vertices_corner_offset + coarse_vertex_index; | ||||
| vertex_corner(ctx->foreach_context, | vertex_corner(ctx->foreach_context, | ||||
| tls, | tls, | ||||
| ptex_face_index, | ptex_face_index, | ||||
| 0.0f, | 0.0f, | ||||
| 0.0f, | 0.0f, | ||||
| coarse_vertex_index, | coarse_vertex_index, | ||||
| coarse_poly_index, | coarse_poly_index, | ||||
| ▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| const int resolution = ctx->settings->resolution; | const int resolution = ctx->settings->resolution; | ||||
| const int resolution_1 = resolution - 1; | const int resolution_1 = resolution - 1; | ||||
| const float inv_resolution_1 = 1.0f / float(resolution_1); | const float inv_resolution_1 = 1.0f / float(resolution_1); | ||||
| const int num_subdiv_vertices_per_coarse_edge = resolution - 2; | const int num_subdiv_vertices_per_coarse_edge = resolution - 2; | ||||
| const int coarse_poly_index = coarse_poly - ctx->coarse_polys; | const int coarse_poly_index = coarse_poly - ctx->coarse_polys; | ||||
| const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; | const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; | ||||
| for (int corner = 0; corner < coarse_poly->totloop; corner++) { | for (int corner = 0; corner < coarse_poly->totloop; corner++) { | ||||
| const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner]; | const int coarse_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + corner]; | ||||
| const int coarse_edge_index = coarse_loop->e; | const int coarse_edge_index = ctx->coarse_corner_edges[coarse_poly->loopstart + corner]; | ||||
| if (check_usage && | if (check_usage && | ||||
| BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_edges_used_map, coarse_edge_index)) { | BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_edges_used_map, coarse_edge_index)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_index]; | const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_index]; | ||||
| const bool flip = (coarse_edge->v2 == coarse_loop->v); | const bool flip = (coarse_edge->v2 == coarse_vert); | ||||
| int subdiv_vertex_index = ctx->vertices_edge_offset + | int subdiv_vertex_index = ctx->vertices_edge_offset + | ||||
| coarse_edge_index * num_subdiv_vertices_per_coarse_edge; | coarse_edge_index * num_subdiv_vertices_per_coarse_edge; | ||||
| for (int vertex_index = 0; vertex_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++) { | vertex_index++, subdiv_vertex_index++) { | ||||
| float fac = (vertex_index + 1) * inv_resolution_1; | float fac = (vertex_index + 1) * inv_resolution_1; | ||||
| if (flip) { | if (flip) { | ||||
| fac = 1.0f - fac; | fac = 1.0f - fac; | ||||
| } | } | ||||
| Show All 39 Lines | |||||
| const int resolution = ctx->settings->resolution; | const int resolution = ctx->settings->resolution; | ||||
| const int num_subdiv_vertices_per_coarse_edge = resolution - 2; | const int num_subdiv_vertices_per_coarse_edge = resolution - 2; | ||||
| const int num_vertices_per_ptex_edge = ((resolution >> 1) + 1); | 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 float inv_ptex_resolution_1 = 1.0f / float(num_vertices_per_ptex_edge - 1); | ||||
| const int coarse_poly_index = coarse_poly - ctx->coarse_polys; | const int coarse_poly_index = coarse_poly - ctx->coarse_polys; | ||||
| const int ptex_face_start_index = ctx->face_ptex_offset[coarse_poly_index]; | const int ptex_face_start_index = ctx->face_ptex_offset[coarse_poly_index]; | ||||
| int ptex_face_index = ptex_face_start_index; | int ptex_face_index = ptex_face_start_index; | ||||
| for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) { | for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) { | ||||
| const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner]; | const int coarse_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + corner]; | ||||
| const int coarse_edge_index = coarse_loop->e; | const int coarse_edge_index = ctx->coarse_corner_edges[coarse_poly->loopstart + corner]; | ||||
| if (check_usage && | if (check_usage && | ||||
| BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_edges_used_map, coarse_edge_index)) { | BLI_BITMAP_TEST_AND_SET_ATOMIC(ctx->coarse_edges_used_map, coarse_edge_index)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_index]; | const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_index]; | ||||
| const bool flip = (coarse_edge->v2 == coarse_loop->v); | const bool flip = (coarse_edge->v2 == coarse_vert); | ||||
| int subdiv_vertex_index = ctx->vertices_edge_offset + | int subdiv_vertex_index = ctx->vertices_edge_offset + | ||||
| coarse_edge_index * num_subdiv_vertices_per_coarse_edge; | coarse_edge_index * num_subdiv_vertices_per_coarse_edge; | ||||
| int vertex_delta = 1; | int vertex_delta = 1; | ||||
| if (flip) { | if (flip) { | ||||
| subdiv_vertex_index += num_subdiv_vertices_per_coarse_edge - 1; | subdiv_vertex_index += num_subdiv_vertices_per_coarse_edge - 1; | ||||
| vertex_delta = -1; | vertex_delta = -1; | ||||
| } | } | ||||
| for (int vertex_index = 1; vertex_index < num_vertices_per_ptex_edge; | for (int vertex_index = 1; vertex_index < num_vertices_per_ptex_edge; | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| tls, | tls, | ||||
| ORIGINDEX_NONE, | ORIGINDEX_NONE, | ||||
| subdiv_edge_index, | subdiv_edge_index, | ||||
| start_row_vertex_index + resolution - 2, | start_row_vertex_index + resolution - 2, | ||||
| resolution - 2); | resolution - 2); | ||||
| } | } | ||||
| /* Connect inner part of patch to boundary. */ | /* Connect inner part of patch to boundary. */ | ||||
| for (int corner = 0; corner < coarse_poly->totloop; corner++) { | for (int corner = 0; corner < coarse_poly->totloop; corner++) { | ||||
| const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner]; | const int coarse_vert_index = ctx->coarse_corner_verts[coarse_poly->loopstart + corner]; | ||||
| const MEdge *coarse_edge = &ctx->coarse_edges[coarse_loop->e]; | const int coarse_edge_index = ctx->coarse_corner_edges[coarse_poly->loopstart + corner]; | ||||
| const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_index]; | |||||
| const int start_edge_vertex = ctx->vertices_edge_offset + | const int start_edge_vertex = ctx->vertices_edge_offset + | ||||
| coarse_loop->e * num_subdiv_vertices_per_coarse_edge; | coarse_edge_index * num_subdiv_vertices_per_coarse_edge; | ||||
| const bool flip = (coarse_edge->v2 == coarse_loop->v); | const bool flip = (coarse_edge->v2 == coarse_vert_index); | ||||
| int side_start_index = start_vertex_index; | int side_start_index = start_vertex_index; | ||||
| int side_stride = 0; | int side_stride = 0; | ||||
| /* Calculate starting vertex of corresponding inner part of ptex. */ | /* Calculate starting vertex of corresponding inner part of ptex. */ | ||||
| if (corner == 0) { | if (corner == 0) { | ||||
| side_stride = 1; | side_stride = 1; | ||||
| } | } | ||||
| else if (corner == 1) { | else if (corner == 1) { | ||||
| side_start_index += resolution - 3; | side_start_index += resolution - 3; | ||||
| ▲ Show 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | |||||
| num_inner_vertices_per_ptex - 1; | num_inner_vertices_per_ptex - 1; | ||||
| const int v1 = center_vertex_index; | const int v1 = center_vertex_index; | ||||
| const int v2 = current_patch_end_vertex_index; | const int v2 = current_patch_end_vertex_index; | ||||
| ctx->foreach_context->edge( | ctx->foreach_context->edge( | ||||
| ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, false, v1, v2); | ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, false, v1, v2); | ||||
| } | } | ||||
| } | } | ||||
| /* Connect inner path of patch to boundary. */ | /* Connect inner path of patch to boundary. */ | ||||
| const MLoop *prev_coarse_loop = | int prev_corner = coarse_poly->totloop - 1; | ||||
| &ctx->coarse_loops[coarse_poly->loopstart + coarse_poly->totloop - 1]; | |||||
| for (int corner = 0; corner < coarse_poly->totloop; corner++) { | for (int corner = 0; corner < coarse_poly->totloop; corner++) { | ||||
| const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner]; | const int coarse_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + corner]; | ||||
| const int coarse_edge_i = ctx->coarse_corner_edges[coarse_poly->loopstart + corner]; | |||||
| const int coarse_prev_edge = ctx->coarse_corner_edges[coarse_poly->loopstart + prev_corner]; | |||||
| { | { | ||||
| const MEdge *coarse_edge = &ctx->coarse_edges[coarse_loop->e]; | const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_i]; | ||||
| const int start_edge_vertex = ctx->vertices_edge_offset + | const int start_edge_vertex = ctx->vertices_edge_offset + | ||||
| coarse_loop->e * num_subdiv_vertices_per_coarse_edge; | coarse_edge_i * num_subdiv_vertices_per_coarse_edge; | ||||
| const bool flip = (coarse_edge->v2 == coarse_loop->v); | const bool flip = (coarse_edge->v2 == coarse_vert); | ||||
| int side_start_index; | int side_start_index; | ||||
| if (ptex_face_resolution >= 3) { | if (ptex_face_resolution >= 3) { | ||||
| side_start_index = start_vertex_index + num_inner_vertices_per_ptex * corner; | side_start_index = start_vertex_index + num_inner_vertices_per_ptex * corner; | ||||
| } | } | ||||
| else { | else { | ||||
| side_start_index = center_vertex_index; | side_start_index = center_vertex_index; | ||||
| } | } | ||||
| for (int i = 0; i < ptex_face_resolution - 1; i++, subdiv_edge_index++) { | for (int i = 0; i < ptex_face_resolution - 1; i++, subdiv_edge_index++) { | ||||
| const int v1 = (flip) ? (start_edge_vertex + (resolution - i - 3)) : | const int v1 = (flip) ? (start_edge_vertex + (resolution - i - 3)) : | ||||
| (start_edge_vertex + i); | (start_edge_vertex + i); | ||||
| const int v2 = side_start_index + i; | const int v2 = side_start_index + i; | ||||
| ctx->foreach_context->edge( | ctx->foreach_context->edge( | ||||
| ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, false, v1, v2); | ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, false, v1, v2); | ||||
| } | } | ||||
| } | } | ||||
| if (ptex_face_resolution >= 3) { | if (ptex_face_resolution >= 3) { | ||||
| const MEdge *coarse_edge = &ctx->coarse_edges[prev_coarse_loop->e]; | const MEdge *coarse_edge = &ctx->coarse_edges[coarse_prev_edge]; | ||||
| const int start_edge_vertex = ctx->vertices_edge_offset + | const int start_edge_vertex = ctx->vertices_edge_offset + | ||||
| prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge; | coarse_prev_edge * num_subdiv_vertices_per_coarse_edge; | ||||
| const bool flip = (coarse_edge->v2 == coarse_loop->v); | const bool flip = (coarse_edge->v2 == coarse_vert); | ||||
| int side_start_index = start_vertex_index + num_inner_vertices_per_ptex * corner; | 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++) { | for (int i = 0; i < ptex_face_resolution - 2; i++, subdiv_edge_index++) { | ||||
| const int v1 = (flip) ? (start_edge_vertex + (resolution - i - 3)) : | const int v1 = (flip) ? (start_edge_vertex + (resolution - i - 3)) : | ||||
| (start_edge_vertex + i); | (start_edge_vertex + i); | ||||
| const int v2 = side_start_index + (ptex_face_inner_resolution + 1) * i; | const int v2 = side_start_index + (ptex_face_inner_resolution + 1) * i; | ||||
| ctx->foreach_context->edge( | ctx->foreach_context->edge( | ||||
| ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, false, v1, v2); | ctx->foreach_context, tls, ORIGINDEX_NONE, subdiv_edge_index, false, v1, v2); | ||||
| } | } | ||||
| } | } | ||||
| prev_coarse_loop = coarse_loop; | prev_corner = corner; | ||||
| } | } | ||||
| } | } | ||||
| static void subdiv_foreach_edges_all_patches(SubdivForeachTaskContext *ctx, | static void subdiv_foreach_edges_all_patches(SubdivForeachTaskContext *ctx, | ||||
| void *tls, | void *tls, | ||||
| const MPoly *coarse_poly) | const MPoly *coarse_poly) | ||||
| { | { | ||||
| if (coarse_poly->totloop == 4) { | if (coarse_poly->totloop == 4) { | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| e3, | e3, | ||||
| u, | u, | ||||
| v, | v, | ||||
| du, | du, | ||||
| dv); | dv); | ||||
| } | } | ||||
| } | } | ||||
| /* Loops for faces connecting inner ptex part with boundary. */ | /* Loops for faces connecting inner ptex part with boundary. */ | ||||
| const MLoop *prev_coarse_loop = | int prev_corner_index = coarse_poly->totloop - 1; | ||||
| &ctx->coarse_loops[coarse_poly->loopstart + coarse_poly->totloop - 1]; | |||||
| for (int corner = 0; corner < coarse_poly->totloop; corner++) { | for (int corner = 0; corner < coarse_poly->totloop; corner++) { | ||||
| const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner]; | const int coarse_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + corner]; | ||||
| const MEdge *coarse_edge = &ctx->coarse_edges[coarse_loop->e]; | const int coarse_edge_i = ctx->coarse_corner_edges[coarse_poly->loopstart + corner]; | ||||
| const MEdge *prev_coarse_edge = &ctx->coarse_edges[prev_coarse_loop->e]; | const int coase_prev_vert = | ||||
| ctx->coarse_corner_verts[coarse_poly->loopstart + prev_corner_index]; | |||||
| const int coarse_prev_edge = | |||||
| ctx->coarse_corner_edges[coarse_poly->loopstart + prev_corner_index]; | |||||
| const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_i]; | |||||
| const MEdge *prev_coarse_edge = &ctx->coarse_edges[coarse_prev_edge]; | |||||
| const int start_edge_vertex = ctx->vertices_edge_offset + | const int start_edge_vertex = ctx->vertices_edge_offset + | ||||
| coarse_loop->e * num_subdiv_vertices_per_coarse_edge; | coarse_edge_i * num_subdiv_vertices_per_coarse_edge; | ||||
| const bool flip = (coarse_edge->v2 == coarse_loop->v); | const bool flip = (coarse_edge->v2 == coarse_vert); | ||||
| int side_start_index = start_vertex_index; | int side_start_index = start_vertex_index; | ||||
| int side_stride = 0; | int side_stride = 0; | ||||
| int v0 = ctx->vertices_corner_offset + coarse_loop->v; | int v0 = ctx->vertices_corner_offset + coarse_vert; | ||||
| int v3, e3; | int v3, e3; | ||||
| int e2_offset, e2_stride; | int e2_offset, e2_stride; | ||||
| float u, v, delta_u, delta_v; | float u, v, delta_u, delta_v; | ||||
| if (prev_coarse_loop->v == prev_coarse_edge->v1) { | if (coase_prev_vert == prev_coarse_edge->v1) { | ||||
| v3 = ctx->vertices_edge_offset + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge + | v3 = ctx->vertices_edge_offset + coarse_prev_edge * num_subdiv_vertices_per_coarse_edge + | ||||
| num_subdiv_vertices_per_coarse_edge - 1; | num_subdiv_vertices_per_coarse_edge - 1; | ||||
| e3 = ctx->edge_boundary_offset + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge + | e3 = ctx->edge_boundary_offset + coarse_prev_edge * num_subdiv_edges_per_coarse_edge + | ||||
| num_subdiv_edges_per_coarse_edge - 1; | num_subdiv_edges_per_coarse_edge - 1; | ||||
| } | } | ||||
| else { | else { | ||||
| v3 = ctx->vertices_edge_offset + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge; | v3 = ctx->vertices_edge_offset + coarse_prev_edge * num_subdiv_vertices_per_coarse_edge; | ||||
| e3 = ctx->edge_boundary_offset + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge; | e3 = ctx->edge_boundary_offset + coarse_prev_edge * num_subdiv_edges_per_coarse_edge; | ||||
| } | } | ||||
| /* Calculate starting vertex of corresponding inner part of ptex. */ | /* Calculate starting vertex of corresponding inner part of ptex. */ | ||||
| if (corner == 0) { | if (corner == 0) { | ||||
| side_stride = 1; | side_stride = 1; | ||||
| e2_offset = 0; | e2_offset = 0; | ||||
| e2_stride = 1; | e2_stride = 1; | ||||
| u = 0.0f; | u = 0.0f; | ||||
| v = 0.0f; | v = 0.0f; | ||||
| Show All 40 Lines | |||||
| v1 = start_edge_vertex + (resolution - i - 3); | v1 = start_edge_vertex + (resolution - i - 3); | ||||
| } | } | ||||
| else { | else { | ||||
| v1 = start_edge_vertex + i; | v1 = start_edge_vertex + i; | ||||
| } | } | ||||
| const int v2 = side_start_index + side_stride * i; | const int v2 = side_start_index + side_stride * i; | ||||
| int e0; | int e0; | ||||
| if (flip) { | if (flip) { | ||||
| e0 = ctx->edge_boundary_offset + coarse_loop->e * num_subdiv_edges_per_coarse_edge + | e0 = ctx->edge_boundary_offset + coarse_edge_i * num_subdiv_edges_per_coarse_edge + | ||||
| num_subdiv_edges_per_coarse_edge - i - 1; | num_subdiv_edges_per_coarse_edge - i - 1; | ||||
| } | } | ||||
| else { | else { | ||||
| e0 = ctx->edge_boundary_offset + coarse_loop->e * num_subdiv_edges_per_coarse_edge + i; | e0 = ctx->edge_boundary_offset + coarse_edge_i * num_subdiv_edges_per_coarse_edge + i; | ||||
| } | } | ||||
| int e1 = start_edge_index + num_edges_per_ptex_face_get(resolution - 2) + | int e1 = start_edge_index + num_edges_per_ptex_face_get(resolution - 2) + | ||||
| corner * num_subdiv_vertices_per_coarse_edge + i; | corner * num_subdiv_vertices_per_coarse_edge + i; | ||||
| int e2; | int e2; | ||||
| if (i == 0) { | if (i == 0) { | ||||
| e2 = start_edge_index + num_edges_per_ptex_face_get(resolution - 2) + | e2 = start_edge_index + num_edges_per_ptex_face_get(resolution - 2) + | ||||
| ((corner - 1 + coarse_poly->totloop) % coarse_poly->totloop) * | ((corner - 1 + coarse_poly->totloop) % coarse_poly->totloop) * | ||||
| num_subdiv_vertices_per_coarse_edge + | num_subdiv_vertices_per_coarse_edge + | ||||
| Show All 24 Lines | |||||
| loop_u, | loop_u, | ||||
| loop_v, | loop_v, | ||||
| du, | du, | ||||
| dv); | dv); | ||||
| v0 = v1; | v0 = v1; | ||||
| v3 = v2; | v3 = v2; | ||||
| e3 = e1; | e3 = e1; | ||||
| } | } | ||||
| prev_coarse_loop = coarse_loop; | prev_corner_index = corner; | ||||
| } | } | ||||
| } | } | ||||
| static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx, | static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx, | ||||
| void *tls, | void *tls, | ||||
| const MPoly *coarse_poly) | const MPoly *coarse_poly) | ||||
| { | { | ||||
| const int resolution = ctx->settings->resolution; | const int resolution = ctx->settings->resolution; | ||||
| ▲ Show 20 Lines • Show All 160 Lines • ▼ Show 20 Lines | |||||
| e3, | e3, | ||||
| u, | u, | ||||
| v, | v, | ||||
| du, | du, | ||||
| dv); | dv); | ||||
| } | } | ||||
| } | } | ||||
| /* Loops for faces connecting inner ptex part with boundary. */ | /* Loops for faces connecting inner ptex part with boundary. */ | ||||
| const MLoop *prev_coarse_loop = | |||||
| &ctx->coarse_loops[coarse_poly->loopstart + coarse_poly->totloop - 1]; | |||||
| for (int prev_corner = coarse_poly->totloop - 1, corner = 0; corner < coarse_poly->totloop; | for (int prev_corner = coarse_poly->totloop - 1, corner = 0; corner < coarse_poly->totloop; | ||||
| prev_corner = corner, corner++) { | prev_corner = corner, corner++) { | ||||
| const MLoop *coarse_loop = &ctx->coarse_loops[coarse_poly->loopstart + corner]; | const int coarse_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + corner]; | ||||
| const MEdge *coarse_edge = &ctx->coarse_edges[coarse_loop->e]; | const int coarse_edge_i = ctx->coarse_corner_edges[coarse_poly->loopstart + corner]; | ||||
| const MEdge *prev_coarse_edge = &ctx->coarse_edges[prev_coarse_loop->e]; | const int coase_prev_vert = ctx->coarse_corner_verts[coarse_poly->loopstart + prev_corner]; | ||||
| const bool flip = (coarse_edge->v2 == coarse_loop->v); | const int coarse_prev_edge = ctx->coarse_corner_edges[coarse_poly->loopstart + prev_corner]; | ||||
| const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_i]; | |||||
| const MEdge *prev_coarse_edge = &ctx->coarse_edges[coarse_prev_edge]; | |||||
| const bool flip = (coarse_edge->v2 == coarse_vert); | |||||
| const int start_edge_vertex = ctx->vertices_edge_offset + | const int start_edge_vertex = ctx->vertices_edge_offset + | ||||
| coarse_loop->e * num_subdiv_vertices_per_coarse_edge; | coarse_edge_i * num_subdiv_vertices_per_coarse_edge; | ||||
| const int corner_vertex_index = start_vertex_index + corner * num_inner_vertices_per_ptex; | 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; | const int corner_edge_index = start_edge_index + corner * num_inner_edges_per_ptex_face; | ||||
| /* Create loops for polygons along U axis. */ | /* Create loops for polygons along U axis. */ | ||||
| int v0 = ctx->vertices_corner_offset + coarse_loop->v; | int v0 = ctx->vertices_corner_offset + coarse_vert; | ||||
| int v3, e3; | int v3, e3; | ||||
| if (prev_coarse_loop->v == prev_coarse_edge->v1) { | if (coase_prev_vert == prev_coarse_edge->v1) { | ||||
| v3 = ctx->vertices_edge_offset + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge + | v3 = ctx->vertices_edge_offset + coarse_prev_edge * num_subdiv_vertices_per_coarse_edge + | ||||
| num_subdiv_vertices_per_coarse_edge - 1; | num_subdiv_vertices_per_coarse_edge - 1; | ||||
| e3 = ctx->edge_boundary_offset + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge + | e3 = ctx->edge_boundary_offset + coarse_prev_edge * num_subdiv_edges_per_coarse_edge + | ||||
| num_subdiv_edges_per_coarse_edge - 1; | num_subdiv_edges_per_coarse_edge - 1; | ||||
| } | } | ||||
| else { | else { | ||||
| v3 = ctx->vertices_edge_offset + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge; | v3 = ctx->vertices_edge_offset + coarse_prev_edge * num_subdiv_vertices_per_coarse_edge; | ||||
| e3 = ctx->edge_boundary_offset + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge; | e3 = ctx->edge_boundary_offset + coarse_prev_edge * num_subdiv_edges_per_coarse_edge; | ||||
| } | } | ||||
| for (int i = 0; i <= ptex_face_inner_resolution; i++, subdiv_loop_index += 4) { | for (int i = 0; i <= ptex_face_inner_resolution; i++, subdiv_loop_index += 4) { | ||||
| int v1; | int v1; | ||||
| if (flip) { | if (flip) { | ||||
| v1 = start_edge_vertex + (resolution - i - 3); | v1 = start_edge_vertex + (resolution - i - 3); | ||||
| } | } | ||||
| else { | else { | ||||
| v1 = start_edge_vertex + i; | v1 = start_edge_vertex + i; | ||||
| } | } | ||||
| int v2; | int v2; | ||||
| if (ptex_face_inner_resolution >= 1) { | if (ptex_face_inner_resolution >= 1) { | ||||
| v2 = corner_vertex_index + i; | v2 = corner_vertex_index + i; | ||||
| } | } | ||||
| else { | else { | ||||
| v2 = center_vertex_index; | v2 = center_vertex_index; | ||||
| } | } | ||||
| int e0; | int e0; | ||||
| if (flip) { | if (flip) { | ||||
| e0 = ctx->edge_boundary_offset + coarse_loop->e * num_subdiv_edges_per_coarse_edge + | e0 = ctx->edge_boundary_offset + coarse_edge_i * num_subdiv_edges_per_coarse_edge + | ||||
| num_subdiv_edges_per_coarse_edge - i - 1; | num_subdiv_edges_per_coarse_edge - i - 1; | ||||
| } | } | ||||
| else { | else { | ||||
| e0 = ctx->edge_boundary_offset + coarse_loop->e * num_subdiv_edges_per_coarse_edge + i; | e0 = ctx->edge_boundary_offset + coarse_edge_i * num_subdiv_edges_per_coarse_edge + i; | ||||
| } | } | ||||
| int e1 = start_edge_index + corner * (2 * ptex_face_inner_resolution + 1); | int e1 = start_edge_index + corner * (2 * ptex_face_inner_resolution + 1); | ||||
| if (ptex_face_resolution >= 3) { | if (ptex_face_resolution >= 3) { | ||||
| e1 += coarse_poly->totloop * | e1 += coarse_poly->totloop * | ||||
| (num_inner_edges_per_ptex_face + ptex_face_inner_resolution + 1) + | (num_inner_edges_per_ptex_face + ptex_face_inner_resolution + 1) + | ||||
| i; | i; | ||||
| } | } | ||||
| int e2 = 0; | int e2 = 0; | ||||
| Show All 30 Lines | |||||
| v, | v, | ||||
| du, | du, | ||||
| dv); | dv); | ||||
| v0 = v1; | v0 = v1; | ||||
| v3 = v2; | v3 = v2; | ||||
| e3 = e1; | e3 = e1; | ||||
| } | } | ||||
| /* Create loops for polygons along V axis. */ | /* Create loops for polygons along V axis. */ | ||||
| const bool flip_prev = (prev_coarse_edge->v2 == coarse_loop->v); | const bool flip_prev = (prev_coarse_edge->v2 == coarse_vert); | ||||
| v0 = corner_vertex_index; | v0 = corner_vertex_index; | ||||
| if (prev_coarse_loop->v == prev_coarse_edge->v1) { | if (coase_prev_vert == prev_coarse_edge->v1) { | ||||
| v3 = ctx->vertices_edge_offset + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge + | v3 = ctx->vertices_edge_offset + coarse_prev_edge * num_subdiv_vertices_per_coarse_edge + | ||||
| num_subdiv_vertices_per_coarse_edge - 1; | num_subdiv_vertices_per_coarse_edge - 1; | ||||
| } | } | ||||
| else { | else { | ||||
| v3 = ctx->vertices_edge_offset + prev_coarse_loop->e * num_subdiv_vertices_per_coarse_edge; | v3 = ctx->vertices_edge_offset + coarse_prev_edge * num_subdiv_vertices_per_coarse_edge; | ||||
| } | } | ||||
| e3 = start_edge_index + | e3 = start_edge_index + | ||||
| coarse_poly->totloop * (num_inner_edges_per_ptex_face + ptex_face_inner_resolution + 1) + | 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; | 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) { | for (int i = 0; i <= ptex_face_inner_resolution - 1; i++, subdiv_loop_index += 4) { | ||||
| int v1; | int v1; | ||||
| int e0, e1; | int e0, e1; | ||||
| if (i == ptex_face_inner_resolution - 1) { | if (i == ptex_face_inner_resolution - 1) { | ||||
| Show All 10 Lines | |||||
| v1 = v0 + ptex_face_inner_resolution + 1; | v1 = v0 + ptex_face_inner_resolution + 1; | ||||
| e0 = corner_edge_index + ptex_face_inner_resolution + | e0 = corner_edge_index + ptex_face_inner_resolution + | ||||
| i * (2 * ptex_face_inner_resolution + 1); | i * (2 * ptex_face_inner_resolution + 1); | ||||
| e1 = e3 + 1; | e1 = e3 + 1; | ||||
| } | } | ||||
| int v2 = flip_prev ? v3 - 1 : v3 + 1; | int v2 = flip_prev ? v3 - 1 : v3 + 1; | ||||
| int e2; | int e2; | ||||
| if (flip_prev) { | if (flip_prev) { | ||||
| e2 = ctx->edge_boundary_offset + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge + | e2 = ctx->edge_boundary_offset + coarse_prev_edge * num_subdiv_edges_per_coarse_edge + | ||||
| num_subdiv_edges_per_coarse_edge - 2 - i; | num_subdiv_edges_per_coarse_edge - 2 - i; | ||||
| } | } | ||||
| else { | else { | ||||
| e2 = ctx->edge_boundary_offset + prev_coarse_loop->e * num_subdiv_edges_per_coarse_edge + | e2 = ctx->edge_boundary_offset + coarse_prev_edge * num_subdiv_edges_per_coarse_edge + 1 + | ||||
| 1 + i; | i; | ||||
| } | } | ||||
| const float u = 0.0f; | const float u = 0.0f; | ||||
| const float v = du * (i + 1); | const float v = du * (i + 1); | ||||
| subdiv_foreach_loops_of_poly(ctx, | subdiv_foreach_loops_of_poly(ctx, | ||||
| tls, | tls, | ||||
| subdiv_loop_index, | subdiv_loop_index, | ||||
| ptex_face_index + corner, | ptex_face_index + corner, | ||||
| coarse_poly_index, | coarse_poly_index, | ||||
| Show All 10 Lines | |||||
| u, | u, | ||||
| v, | v, | ||||
| du, | du, | ||||
| dv); | dv); | ||||
| v0 = v1; | v0 = v1; | ||||
| v3 = v2; | v3 = v2; | ||||
| e3 = e1; | 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 MPoly *coarse_poly = &ctx->coarse_polys[poly_index]; | const MPoly *coarse_poly = &ctx->coarse_polys[poly_index]; | ||||
| if (coarse_poly->totloop == 4) { | if (coarse_poly->totloop == 4) { | ||||
| subdiv_foreach_loops_regular(ctx, tls, coarse_poly); | subdiv_foreach_loops_regular(ctx, tls, coarse_poly); | ||||
| ▲ Show 20 Lines • Show All 112 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| static void subdiv_foreach_mark_non_loose_geometry(SubdivForeachTaskContext *ctx) | static void subdiv_foreach_mark_non_loose_geometry(SubdivForeachTaskContext *ctx) | ||||
| { | { | ||||
| const Mesh *coarse_mesh = ctx->coarse_mesh; | const Mesh *coarse_mesh = ctx->coarse_mesh; | ||||
| for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) { | for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) { | ||||
| const MPoly *coarse_poly = &ctx->coarse_polys[poly_index]; | const MPoly *coarse_poly = &ctx->coarse_polys[poly_index]; | ||||
| for (int corner = 0; corner < coarse_poly->totloop; corner++) { | for (int corner = 0; corner < coarse_poly->totloop; corner++) { | ||||
| const MLoop *loop = &ctx->coarse_loops[coarse_poly->loopstart + corner]; | BLI_BITMAP_ENABLE(ctx->coarse_vertices_used_map, | ||||
| BLI_BITMAP_ENABLE(ctx->coarse_edges_used_map, loop->e); | ctx->coarse_corner_verts[coarse_poly->loopstart + corner]); | ||||
| BLI_BITMAP_ENABLE(ctx->coarse_vertices_used_map, loop->v); | BLI_BITMAP_ENABLE(ctx->coarse_edges_used_map, | ||||
| ctx->coarse_corner_verts[coarse_poly->loopstart + corner]); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void subdiv_foreach_single_thread_tasks(SubdivForeachTaskContext *ctx) | static void subdiv_foreach_single_thread_tasks(SubdivForeachTaskContext *ctx) | ||||
| { | { | ||||
| /* NOTE: In theory, we can try to skip allocation of TLS here, but in | /* 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 | * practice if the callbacks used here are not specified then TLS will not | ||||
| ▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | |||||
| const SubdivForeachContext *context, | const SubdivForeachContext *context, | ||||
| const SubdivToMeshSettings *mesh_settings, | const SubdivToMeshSettings *mesh_settings, | ||||
| const Mesh *coarse_mesh) | const Mesh *coarse_mesh) | ||||
| { | { | ||||
| SubdivForeachTaskContext ctx = {0}; | SubdivForeachTaskContext ctx = {0}; | ||||
| ctx.coarse_mesh = coarse_mesh; | ctx.coarse_mesh = coarse_mesh; | ||||
| ctx.coarse_edges = BKE_mesh_edges(coarse_mesh); | ctx.coarse_edges = BKE_mesh_edges(coarse_mesh); | ||||
| ctx.coarse_polys = BKE_mesh_polys(coarse_mesh); | ctx.coarse_polys = BKE_mesh_polys(coarse_mesh); | ||||
| ctx.coarse_loops = BKE_mesh_loops(coarse_mesh); | ctx.coarse_corner_verts = coarse_mesh->corner_verts().data(); | ||||
| ctx.coarse_corner_edges = coarse_mesh->corner_edges().data(); | |||||
| ctx.settings = mesh_settings; | ctx.settings = mesh_settings; | ||||
| ctx.foreach_context = context; | ctx.foreach_context = context; | ||||
| subdiv_foreach_ctx_init(subdiv, &ctx); | subdiv_foreach_ctx_init(subdiv, &ctx); | ||||
| if (context->topology_info != nullptr) { | if (context->topology_info != nullptr) { | ||||
| if (!context->topology_info(context, | if (!context->topology_info(context, | ||||
| ctx.num_subdiv_vertices, | ctx.num_subdiv_vertices, | ||||
| ctx.num_subdiv_edges, | ctx.num_subdiv_edges, | ||||
| ctx.num_subdiv_loops, | ctx.num_subdiv_loops, | ||||
| ▲ Show 20 Lines • Show All 52 Lines • Show Last 20 Lines | |||||