From 5a1013f6a881d6bbacac1d2f49e5fbc56d236132 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 28 Apr 2023 10:05:57 -0400 Subject: [PATCH] Fix #106289: Copy optimal display edges in mirror, array modifiers These aren't propagated as attributes since interpolating them with the generic rules often gives strange results, and they're intended to as an optimization. Though theoretically it would be nice if this copying became more generic in the future. --- .../blender/blenkernel/intern/mesh_mirror.cc | 8 +++++ source/blender/modifiers/intern/MOD_array.cc | 30 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/source/blender/blenkernel/intern/mesh_mirror.cc b/source/blender/blenkernel/intern/mesh_mirror.cc index 7ad5b5d2907..ca787acbbf5 100644 --- a/source/blender/blenkernel/intern/mesh_mirror.cc +++ b/source/blender/blenkernel/intern/mesh_mirror.cc @@ -332,6 +332,14 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, result_corner_edges[i] += src_edges_num; } + if (!mesh->runtime->subsurf_optimal_display_edges.is_empty()) { + const blender::BoundedBitSpan src = mesh->runtime->subsurf_optimal_display_edges; + result->runtime->subsurf_optimal_display_edges.resize(result->totedge); + blender::MutableBoundedBitSpan dst = result->runtime->subsurf_optimal_display_edges; + dst.slice({0, src.size()}).copy_from(src); + dst.slice({src.size(), src.size()}).copy_from(src); + } + /* handle uvs, * let tessface recalc handle updating the MTFace data */ if (mmd->flag & (MOD_MIR_MIRROR_U | MOD_MIR_MIRROR_V) || diff --git a/source/blender/modifiers/intern/MOD_array.cc b/source/blender/modifiers/intern/MOD_array.cc index 3174c0eafc4..44b78ef370a 100644 --- a/source/blender/modifiers/intern/MOD_array.cc +++ b/source/blender/modifiers/intern/MOD_array.cc @@ -688,6 +688,36 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, } } + if (!use_merge && !mesh->runtime->subsurf_optimal_display_edges.is_empty()) { + const BoundedBitSpan src = mesh->runtime->subsurf_optimal_display_edges; + + result->runtime->subsurf_optimal_display_edges.resize(result->totedge); + MutableBoundedBitSpan dst = result->runtime->subsurf_optimal_display_edges; + for (const int i : IndexRange(count)) { + dst.slice({i * mesh->totedge, mesh->totedge}).copy_from(src); + } + + if (start_cap_mesh) { + MutableBitSpan cap_bits = dst.slice( + {result_nedges - start_cap_nedges - end_cap_nedges, start_cap_mesh->totedge}); + if (start_cap_mesh->runtime->subsurf_optimal_display_edges.is_empty()) { + cap_bits.set_all(true); + } + else { + cap_bits.copy_from(start_cap_mesh->runtime->subsurf_optimal_display_edges); + } + } + if (end_cap_mesh) { + MutableBitSpan cap_bits = dst.slice({result_nedges - end_cap_nedges, end_cap_mesh->totedge}); + if (end_cap_mesh->runtime->subsurf_optimal_display_edges.is_empty()) { + cap_bits.set_all(true); + } + else { + cap_bits.copy_from(end_cap_mesh->runtime->subsurf_optimal_display_edges); + } + } + } + last_chunk_start = (count - 1) * chunk_nverts; last_chunk_nverts = chunk_nverts;