1 # SPDX-License-Identifier: GPL-2.0-or-later
4 def create_and_link_mesh(name
, faces
, face_nors
, points
, global_matrix
):
6 Create a blender mesh and object called name from a list of
7 *points* and *faces* and link it in the current scene.
11 from itertools
import chain
14 mesh
= bpy
.data
.meshes
.new(name
)
15 mesh
.from_pydata(points
, [], faces
)
18 # Note: we store 'temp' normals in loops, since validate() may alter final mesh,
19 # we can only set custom lnors *after* calling it.
20 mesh
.create_normals_split()
21 lnors
= tuple(chain(*chain(*zip(face_nors
, face_nors
, face_nors
))))
22 mesh
.loops
.foreach_set("normal", lnors
)
24 mesh
.transform(global_matrix
)
26 # update mesh to allow proper display
27 mesh
.validate(clean_customdata
=False) # *Very* important to not remove lnors here!
30 clnors
= array
.array('f', [0.0] * (len(mesh
.loops
) * 3))
31 mesh
.loops
.foreach_get("normal", clnors
)
33 mesh
.polygons
.foreach_set("use_smooth", [True] * len(mesh
.polygons
))
35 mesh
.normals_split_custom_set(tuple(zip(*(iter(clnors
),) * 3)))
36 mesh
.use_auto_smooth
= True
37 mesh
.free_normals_split()
41 obj
= bpy
.data
.objects
.new(name
, mesh
)
42 bpy
.context
.collection
.objects
.link(obj
)
43 bpy
.context
.view_layer
.objects
.active
= obj
47 def faces_from_mesh(ob
, global_matrix
, use_mesh_modifiers
=False):
49 From an object, return a generator over a list of faces.
51 Each faces is a list of his vertices. Each vertex is a tuple of
55 Apply the preview modifier to the returned liste
58 Split the quad into two triangles
63 # get the editmode data
65 ob
.update_from_editmode()
68 if use_mesh_modifiers
:
69 depsgraph
= bpy
.context
.evaluated_depsgraph_get()
70 mesh_owner
= ob
.evaluated_get(depsgraph
)
74 # Object.to_mesh() is not guaranteed to return a mesh.
76 mesh
= mesh_owner
.to_mesh()
83 mat
= global_matrix
@ ob
.matrix_world
87 mesh
.calc_loop_triangles()
89 vertices
= mesh
.vertices
91 for tri
in mesh
.loop_triangles
:
92 yield [vertices
[index
].co
.copy() for index
in tri
.vertices
]
94 mesh_owner
.to_mesh_clear()