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.
This commit is contained in:
Hans Goudey
2023-04-28 10:05:57 -04:00
parent b87ccedd75
commit 5a1013f6a8
2 changed files with 38 additions and 0 deletions

View File

@@ -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) ||

View File

@@ -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;