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:
authorHans Goudey <h.goudey@me.com>2022-02-18 20:40:55 +0300
committerHans Goudey <h.goudey@me.com>2022-02-18 20:40:55 +0300
commit07fbf3108b1eb111ddcc1f164f73b31520716147 (patch)
treed57a78a64fba3f4641b43a191d70300fe02bef23
parentc2016feadc8fe83565ea1e405e36221d05163e5b (diff)
parent82fc68ed90bf1429579eddd5df14caf60b791b45 (diff)
Merge branch 'blender-v3.1-release'
-rw-r--r--source/blender/blenkernel/intern/curve_to_mesh_convert.cc9
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc25
2 files changed, 24 insertions, 10 deletions
diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc
index 51edf4a6591..e62733e36ef 100644
--- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc
+++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc
@@ -172,7 +172,8 @@ static void spline_extrude_to_mesh_data(const ResultInfo &info,
}
}
- if (fill_caps && profile.is_cyclic()) {
+ const bool has_caps = fill_caps && profile.is_cyclic() && !spline.is_cyclic();
+ if (has_caps) {
const int poly_size = info.spline_edge_len * info.profile_edge_len;
const int cap_loop_offset = info.loop_offset + poly_size * 4;
const int cap_poly_offset = info.poly_offset + poly_size;
@@ -256,7 +257,8 @@ static inline int spline_extrude_loop_size(const Spline &curve,
const bool fill_caps)
{
const int tube = curve.evaluated_edges_size() * profile.evaluated_edges_size() * 4;
- const int caps = (fill_caps && profile.is_cyclic()) ? profile.evaluated_edges_size() * 2 : 0;
+ const bool has_caps = fill_caps && profile.is_cyclic() && !curve.is_cyclic();
+ const int caps = has_caps ? profile.evaluated_edges_size() * 2 : 0;
return tube + caps;
}
@@ -265,7 +267,8 @@ static inline int spline_extrude_poly_size(const Spline &curve,
const bool fill_caps)
{
const int tube = curve.evaluated_edges_size() * profile.evaluated_edges_size();
- const int caps = (fill_caps && profile.is_cyclic()) ? 2 : 0;
+ const bool has_caps = fill_caps && profile.is_cyclic() && !curve.is_cyclic();
+ const int caps = has_caps ? 2 : 0;
return tube + caps;
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc
index a526f4f9e65..f50c2ed5322 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc
@@ -272,7 +272,7 @@ static void create_vertex_poly_map(const Mesh &mesh,
* boundary vertex, the first and last polygon have a boundary edge connected to the vertex. The
* `r_shared_edges` array at index i is set to the index of the shared edge between the i-th and
* `(i+1)-th` sorted polygon. Similarly the `r_sorted_corners` array at index i is set to the
- * corner in the i-th sorted polygon.
+ * corner in the i-th sorted polygon. If the polygons couldn't be sorted, `false` is returned.
*
* How the faces are sorted (see diagrams below):
* (For this explanation we'll assume all faces are oriented clockwise)
@@ -321,7 +321,7 @@ static void create_vertex_poly_map(const Mesh &mesh,
* - Finally if we are in the normal case we also need to add the last "shared edge" to close the
* loop.
*/
-static void sort_vertex_polys(const Mesh &mesh,
+static bool sort_vertex_polys(const Mesh &mesh,
const int vertex_index,
const bool boundary_vertex,
const Span<EdgeType> edge_types,
@@ -330,7 +330,7 @@ static void sort_vertex_polys(const Mesh &mesh,
MutableSpan<int> r_sorted_corners)
{
if (connected_polygons.size() <= 2 && (!boundary_vertex || connected_polygons.size() == 0)) {
- return;
+ return true;
}
/* For each polygon store the two corners whose edge contains the vertex. */
@@ -434,8 +434,11 @@ static void sort_vertex_polys(const Mesh &mesh,
break;
}
}
-
- BLI_assert(j != connected_polygons.size());
+ if (j == connected_polygons.size()) {
+ /* The vertex is not manifold because the polygons around the vertex don't form a loop, and
+ * hence can't be sorted. */
+ return false;
+ }
std::swap(connected_polygons[i + 1], connected_polygons[j]);
std::swap(poly_vertex_corners[i + 1], poly_vertex_corners[j]);
@@ -445,6 +448,7 @@ static void sort_vertex_polys(const Mesh &mesh,
/* Shared edge between first and last polygon. */
r_shared_edges.last() = shared_edge_i;
}
+ return true;
}
/**
@@ -637,18 +641,25 @@ static void calc_dual_mesh(GeometrySet &geometry_set,
}
MutableSpan<int> loop_indices = vertex_poly_indices[i];
Array<int> sorted_corners(loop_indices.size());
+ bool vertex_ok = true;
if (vertex_types[i] == VertexType::Normal) {
Array<int> shared_edges(loop_indices.size());
- sort_vertex_polys(
+ vertex_ok = sort_vertex_polys(
mesh_in, i, false, edge_types, loop_indices, shared_edges, sorted_corners);
vertex_shared_edges[i] = shared_edges;
}
else {
Array<int> shared_edges(loop_indices.size() - 1);
- sort_vertex_polys(
+ vertex_ok = sort_vertex_polys(
mesh_in, i, true, edge_types, loop_indices, shared_edges, sorted_corners);
vertex_shared_edges[i] = shared_edges;
}
+ if (!vertex_ok) {
+ /* The sorting failed which means that the vertex is non-manifold and should be ignored
+ * further on. */
+ vertex_types[i] = VertexType::NonManifold;
+ continue;
+ }
vertex_corners[i] = sorted_corners;
}
});