Page MenuHome

Skin Modifier not applied to Array Modifier Start & End Caps
Closed, ArchivedPublic

Description

Skin Modifier not applied to Array Modifier Start & End Caps

System Information
Operating system: Windows-7-6.1.7601-SP1 64 Bits
Graphics card: GeForce GTX 1070/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 440.97

Blender Version
Broken: version: 2.82 (sub 7), branch: master, commit date: 2020-02-12 16:20, hash: rB77d23b0bd76f
Also tried in 2.83 alpha blender-2.83-fbe81db29a28-windows64, 2.81b and 2.79.
Worked: Not in any Blender version I have access to.

Short description of error
When adding a skin modifier to an array with start and end caps, the skin modifier does not extend around the caps.

Exact steps for others to reproduce the error
Default Blend file - add three planes.
Add array modifier to Plane.
Set array modifier start cap as Plane.001 and end cap as Plane.002 and enable Merge.
Add skin modifier.
Skin Modifier will only be applied to the arrayed object, not the start/end caps, with spears at the joins.

To see expected outcome: Apply array modifier. Remove and re-add Skin modifier.

Example blend file attached with fence model.
Maybe related to T59770 but Blender does not crash, it just doesn't add the skin properly.

Event Timeline

The problem here is that the skin radius of the caps' vertices are not initialized.
This patch would allow them to be initialized:

1diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
2index ae2f5231e25..34fb4fcacab 100644
3--- a/source/blender/blenkernel/BKE_mesh.h
4+++ b/source/blender/blenkernel/BKE_mesh.h
5@@ -26,6 +26,7 @@
6 /* defines BLI_INLINE */
7 #include "BLI_compiler_compat.h"
8
9+enum eCDAllocType;
10 struct BLI_Stack;
11 struct BMEditMesh;
12 struct BMesh;
13@@ -124,7 +125,8 @@ struct Mesh *BKE_mesh_new_nomain_from_template_ex(const struct Mesh *me_src,
14 int tessface_len,
15 int loops_len,
16 int polys_len,
17- struct CustomData_MeshMasks mask);
18+ struct CustomData_MeshMasks mask,
19+ enum eCDAllocType alloctype);
20
21 void BKE_mesh_eval_delete(struct Mesh *me_eval);
22
23diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
24index 127acf0e464..aadd6d85293 100644
25--- a/source/blender/blenkernel/intern/mesh.c
26+++ b/source/blender/blenkernel/intern/mesh.c
27@@ -727,7 +727,8 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
28 int tessface_len,
29 int loops_len,
30 int polys_len,
31- CustomData_MeshMasks mask)
32+ CustomData_MeshMasks mask,
33+ enum eCDAllocType alloctype)
34 {
35 /* Only do tessface if we are creating tessfaces or copying from mesh with only tessfaces. */
36 const bool do_tessface = (tessface_len || ((me_src->totface != 0) && (me_src->totpoly == 0)));
37@@ -745,12 +746,12 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
38 me_dst->cd_flag = me_src->cd_flag;
39 BKE_mesh_copy_settings(me_dst, me_src);
40
41- CustomData_copy(&me_src->vdata, &me_dst->vdata, mask.vmask, CD_CALLOC, verts_len);
42- CustomData_copy(&me_src->edata, &me_dst->edata, mask.emask, CD_CALLOC, edges_len);
43- CustomData_copy(&me_src->ldata, &me_dst->ldata, mask.lmask, CD_CALLOC, loops_len);
44- CustomData_copy(&me_src->pdata, &me_dst->pdata, mask.pmask, CD_CALLOC, polys_len);
45+ CustomData_copy(&me_src->vdata, &me_dst->vdata, mask.vmask, alloctype, verts_len);
46+ CustomData_copy(&me_src->edata, &me_dst->edata, mask.emask, alloctype, edges_len);
47+ CustomData_copy(&me_src->ldata, &me_dst->ldata, mask.lmask, alloctype, loops_len);
48+ CustomData_copy(&me_src->pdata, &me_dst->pdata, mask.pmask, alloctype, polys_len);
49 if (do_tessface) {
50- CustomData_copy(&me_src->fdata, &me_dst->fdata, mask.fmask, CD_CALLOC, tessface_len);
51+ CustomData_copy(&me_src->fdata, &me_dst->fdata, mask.fmask, alloctype, tessface_len);
52 }
53 else {
54 mesh_tessface_clear_intern(me_dst, false);
55@@ -771,8 +772,14 @@ Mesh *BKE_mesh_new_nomain_from_template(const Mesh *me_src,
56 int loops_len,
57 int polys_len)
58 {
59- return BKE_mesh_new_nomain_from_template_ex(
60- me_src, verts_len, edges_len, tessface_len, loops_len, polys_len, CD_MASK_EVERYTHING);
61+ return BKE_mesh_new_nomain_from_template_ex(me_src,
62+ verts_len,
63+ edges_len,
64+ tessface_len,
65+ loops_len,
66+ polys_len,
67+ CD_MASK_EVERYTHING,
68+ CD_CALLOC);
69 }
70
71 void BKE_mesh_eval_delete(struct Mesh *mesh_eval)
72diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c
73index 6c9cd72363a..15173eb735e 100644
74--- a/source/blender/blenkernel/intern/subdiv_mesh.c
75+++ b/source/blender/blenkernel/intern/subdiv_mesh.c
76@@ -506,8 +506,14 @@ static bool subdiv_mesh_topology_info(const SubdivForeachContext *foreach_contex
77 mask.lmask &= ~CD_MASK_MULTIRES_GRIDS;
78
79 SubdivMeshContext *subdiv_context = foreach_context->user_data;
80- subdiv_context->subdiv_mesh = BKE_mesh_new_nomain_from_template_ex(
81- subdiv_context->coarse_mesh, num_vertices, num_edges, 0, num_loops, num_polygons, mask);
82+ subdiv_context->subdiv_mesh = BKE_mesh_new_nomain_from_template_ex(subdiv_context->coarse_mesh,
83+ num_vertices,
84+ num_edges,
85+ 0,
86+ num_loops,
87+ num_polygons,
88+ mask,
89+ CD_CALLOC);
90 subdiv_mesh_ctx_cache_custom_data_layers(subdiv_context);
91 subdiv_mesh_prepare_accumulator(subdiv_context, num_vertices);
92 return true;
93diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
94index f8f8ea49676..729957949c6 100644
95--- a/source/blender/modifiers/intern/MOD_array.c
96+++ b/source/blender/modifiers/intern/MOD_array.c
97@@ -499,9 +499,19 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
98 result_nloops = chunk_nloops * count + start_cap_nloops + end_cap_nloops;
99 result_npolys = chunk_npolys * count + start_cap_npolys + end_cap_npolys;
100
101+ /* If there are caps, we need to initialize the customdata values since they may not be copied.
102+ * TODO: Initialize only customdatas that are not in the caps. */
103+ eCDAllocType alloctype = (start_cap_mesh || end_cap_mesh) ? CD_DEFAULT : CD_CALLOC;
104+
105 /* Initialize a result dm */
106- result = BKE_mesh_new_nomain_from_template(
107- mesh, result_nverts, result_nedges, 0, result_nloops, result_npolys);
108+ result = BKE_mesh_new_nomain_from_template_ex(mesh,
109+ result_nverts,
110+ result_nedges,
111+ 0,
112+ result_nloops,
113+ result_npolys,
114+ CD_MASK_EVERYTHING,
115+ alloctype);
116 result_dm_verts = result->mvert;
117
118 if (use_merge) {

But then we would have another problem. You cannot edit the skin radius of the vertices in the caps.

So that would not bring any advantage.
So it seems that there is no simple solution to this. And the code works as designed.