diff options
author | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2022-03-02 17:10:26 +0300 |
---|---|---|
committer | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2022-03-02 17:19:55 +0300 |
commit | 6883c47bb5930be5a95d1c2e8e06fce2d3b68681 (patch) | |
tree | 9c5fc32c03e6994a33827f2e7eaaa6d857f5554d /source/blender/blenkernel/intern | |
parent | 4a95c3466fafcd3e9116cd0d7fdcc63f2dc38bd2 (diff) |
Fix T94729: GPU subdivision does not support meshes without polygons
There are two issues revealed in the bug report:
- the GPU subdivision does not support meshes with only loose geometry
- the loose geometry is not subdivided
For the first case, checks are added to ensure we still fill the
buffers with loose geometry even if no polygons are present.
For the second case, this adds
`BKE_subdiv_mesh_interpolate_position_on_edge` which encapsulates the
loose vertex interpolation mechanism previously found in
`subdiv_mesh_vertex_of_loose_edge`.
The subdivided loose geometry is stored in a new specific data structure
`DRWSubdivLooseGeom` so as to not pollute `MeshExtractLooseGeom`. These
structures store the corresponding coarse element data, which will be
used for filling GPU buffers appropriately.
Differential Revision: https://developer.blender.org/D14171
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/subdiv_mesh.c | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index 333755e0899..95d74b56395 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -946,11 +946,10 @@ static void subdiv_mesh_vertex_loose(const SubdivForeachContext *foreach_context /* Get neighbor edges of the given one. * - neighbors[0] is an edge adjacent to edge->v1. * - neighbors[1] is an edge adjacent to edge->v2. */ -static void find_edge_neighbors(const SubdivMeshContext *ctx, +static void find_edge_neighbors(const Mesh *coarse_mesh, const MEdge *edge, const MEdge *neighbors[2]) { - const Mesh *coarse_mesh = ctx->coarse_mesh; const MEdge *coarse_medge = coarse_mesh->medge; neighbors[0] = NULL; neighbors[1] = NULL; @@ -980,12 +979,11 @@ static void find_edge_neighbors(const SubdivMeshContext *ctx, } } -static void points_for_loose_edges_interpolation_get(SubdivMeshContext *ctx, +static void points_for_loose_edges_interpolation_get(const Mesh *coarse_mesh, const MEdge *coarse_edge, const MEdge *neighbors[2], float points_r[4][3]) { - const Mesh *coarse_mesh = ctx->coarse_mesh; const MVert *coarse_mvert = coarse_mesh->mvert; /* Middle points corresponds to the edge. */ copy_v3_v3(points_r[1], coarse_mvert[coarse_edge->v1].co); @@ -1018,6 +1016,30 @@ static void points_for_loose_edges_interpolation_get(SubdivMeshContext *ctx, } } +void BKE_subdiv_mesh_interpolate_position_on_edge(const Mesh *coarse_mesh, + const MEdge *coarse_edge, + const bool is_simple, + const float u, + float pos_r[3]) +{ + if (is_simple) { + const MVert *coarse_mvert = coarse_mesh->mvert; + const MVert *vert_1 = &coarse_mvert[coarse_edge->v1]; + const MVert *vert_2 = &coarse_mvert[coarse_edge->v2]; + interp_v3_v3v3(pos_r, vert_1->co, vert_2->co, u); + } + else { + /* Find neighbors of the coarse edge. */ + const MEdge *neighbors[2]; + find_edge_neighbors(coarse_mesh, coarse_edge, neighbors); + float points[4][3]; + points_for_loose_edges_interpolation_get(coarse_mesh, coarse_edge, neighbors, points); + float weights[4]; + key_curve_position_weights(u, weights, KEY_BSPLINE); + interp_v3_v3v3v3v3(pos_r, points[0], points[1], points[2], points[3], weights); + } +} + static void subdiv_mesh_vertex_of_loose_edge_interpolate(SubdivMeshContext *ctx, const MEdge *coarse_edge, const float u, @@ -1054,9 +1076,6 @@ static void subdiv_mesh_vertex_of_loose_edge(const struct SubdivForeachContext * Mesh *subdiv_mesh = ctx->subdiv_mesh; MVert *subdiv_mvert = subdiv_mesh->mvert; const bool is_simple = ctx->subdiv->settings.is_simple; - /* Find neighbors of the current loose edge. */ - const MEdge *neighbors[2]; - find_edge_neighbors(ctx, coarse_edge, neighbors); /* Interpolate custom data when not an end point. * This data has already been copied from the original vertex by #subdiv_mesh_vertex_loose. */ if (!ELEM(u, 0.0, 1.0)) { @@ -1064,19 +1083,8 @@ static void subdiv_mesh_vertex_of_loose_edge(const struct SubdivForeachContext * } /* Interpolate coordinate. */ MVert *subdiv_vertex = &subdiv_mvert[subdiv_vertex_index]; - if (is_simple) { - const MVert *coarse_mvert = coarse_mesh->mvert; - const MVert *vert_1 = &coarse_mvert[coarse_edge->v1]; - const MVert *vert_2 = &coarse_mvert[coarse_edge->v2]; - interp_v3_v3v3(subdiv_vertex->co, vert_1->co, vert_2->co, u); - } - else { - float points[4][3]; - points_for_loose_edges_interpolation_get(ctx, coarse_edge, neighbors, points); - float weights[4]; - key_curve_position_weights(u, weights, KEY_BSPLINE); - interp_v3_v3v3v3v3(subdiv_vertex->co, points[0], points[1], points[2], points[3], weights); - } + BKE_subdiv_mesh_interpolate_position_on_edge( + coarse_mesh, coarse_edge, is_simple, u, subdiv_vertex->co); /* Reset flags and such. */ subdiv_vertex->flag = 0; /* TODO(sergey): This matches old behavior, but we can as well interpolate |