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:
authorKévin Dietrich <kevin.dietrich@mailoo.org>2022-03-02 17:10:26 +0300
committerKévin Dietrich <kevin.dietrich@mailoo.org>2022-03-02 17:19:55 +0300
commit6883c47bb5930be5a95d1c2e8e06fce2d3b68681 (patch)
tree9c5fc32c03e6994a33827f2e7eaaa6d857f5554d /source/blender/blenkernel
parent4a95c3466fafcd3e9116cd0d7fdcc63f2dc38bd2 (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')
-rw-r--r--source/blender/blenkernel/BKE_subdiv_mesh.h9
-rw-r--r--source/blender/blenkernel/intern/subdiv_mesh.c48
2 files changed, 37 insertions, 20 deletions
diff --git a/source/blender/blenkernel/BKE_subdiv_mesh.h b/source/blender/blenkernel/BKE_subdiv_mesh.h
index 73a3e8ed02e..2eae5338ae0 100644
--- a/source/blender/blenkernel/BKE_subdiv_mesh.h
+++ b/source/blender/blenkernel/BKE_subdiv_mesh.h
@@ -30,6 +30,7 @@ extern "C" {
#endif
struct Mesh;
+struct MEdge;
struct Subdiv;
typedef struct SubdivToMeshSettings {
@@ -49,6 +50,14 @@ struct Mesh *BKE_subdiv_to_mesh(struct Subdiv *subdiv,
const SubdivToMeshSettings *settings,
const struct Mesh *coarse_mesh);
+/* Interpolate a position along the `coarse_edge` at the relative `u` coordinate. If `is_simple` is
+ * false, this will perform a B-Spline interpolation using the edge neighbors, otherwise a linear
+ * interpolation will be done base on the edge vertices. */
+void BKE_subdiv_mesh_interpolate_position_on_edge(const struct Mesh *coarse_mesh,
+ const struct MEdge *coarse_edge,
+ bool is_simple,
+ float u,
+ float pos_r[3]);
#ifdef __cplusplus
}
#endif
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