From ee352c968fd165fafd17adcc696e98bb0efa844a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 19 Jun 2023 21:40:59 -0400 Subject: [PATCH] Fix #109070: Creating mesh from Python skips setting faces sharp The default value of the "sharp_face" attribute is False like other boolean attributes. That mistakenly changed behavior in addons that created meshes with `Mesh.from_pydata`. To fix, add an argument with a default value that maintains the behavior from before, and add convenience, `shade_smooth` and `shade_flat` methods. --- scripts/modules/bpy_types.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/scripts/modules/bpy_types.py b/scripts/modules/bpy_types.py index 9d67805a481..9fb0e390b56 100644 --- a/scripts/modules/bpy_types.py +++ b/scripts/modules/bpy_types.py @@ -534,7 +534,7 @@ def ord_ind(i1, i2): class Mesh(bpy_types.ID): __slots__ = () - def from_pydata(self, vertices, edges, faces): + def from_pydata(self, vertices, edges, faces, shade_flat=True): """ Make a mesh from a list of vertices/edges/faces Until we have a nicer way to make geometry, use this. @@ -591,6 +591,9 @@ class Mesh(bpy_types.ID): self.polygons.foreach_set("loop_start", loop_starts) self.polygons.foreach_set("vertices", vertex_indices) + if shade_flat: + self.shade_flat() + if edges_len or faces_len: self.update( # Needed to either: @@ -605,6 +608,26 @@ class Mesh(bpy_types.ID): def edge_keys(self): return [ed.key for ed in self.edges] + def shade_flat(self): + """ + Render and display faces uniform, using face normals, + setting the "sharp_face" attribute true for every face + """ + sharp_faces = self.attributes.new("sharp_face", 'BOOLEAN', 'FACE') + for value in sharp_faces.data: + value.value = True + + def shade_smooth(self): + """ + Render and display faces smooth, using interpolated vertex normals, + removing the "sharp_face" attribute + """ + try: + attribute = self.attributes["sharp_face"] + self.attributes.remove(attribute) + except KeyError: + pass + class MeshEdge(StructRNA): __slots__ = ()