3 # ##### BEGIN GPL LICENSE BLOCK #####
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software Foundation,
17 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110- 1301, USA.
19 # ##### END GPL LICENSE BLOCK #####
23 # ----------------------------------------------------------
24 # Author: Stephen Leger (s-leger)
26 # ----------------------------------------------------------
33 def _start(context
, o
):
35 private, start bmesh editing of active object
37 o
.select_set(state
=True)
38 context
.view_layer
.objects
.active
= o
39 bpy
.ops
.object.mode_set(mode
='EDIT')
40 bm
= bmesh
.from_edit_mesh(o
.data
)
41 bm
.verts
.ensure_lookup_table()
42 bm
.faces
.ensure_lookup_table()
46 def bmesh_join(context
, o
, list_of_bmeshes
, normal_update
=False):
48 takes as input a list of bm references and outputs a single merged bmesh
49 allows an additional 'normal_update=True' to force _normal_ calculations.
51 bm
= BmeshEdit
._start
(context
, o
)
53 add_vert
= bm
.verts
.new
54 add_face
= bm
.faces
.new
55 add_edge
= bm
.edges
.new
57 for bm_to_add
in list_of_bmeshes
:
58 offset
= len(bm
.verts
)
60 for v
in bm_to_add
.verts
:
63 bm
.verts
.index_update()
64 bm
.verts
.ensure_lookup_table()
67 layer
= bm_to_add
.loops
.layers
.uv
.verify()
68 dest
= bm
.loops
.layers
.uv
.verify()
69 for face
in bm_to_add
.faces
:
70 f
= add_face(tuple(bm
.verts
[i
.index
+ offset
] for i
in face
.verts
))
71 f
.material_index
= face
.material_index
72 for j
, loop
in enumerate(face
.loops
):
73 f
.loops
[j
][dest
].uv
= loop
[layer
].uv
74 bm
.faces
.index_update()
77 for edge
in bm_to_add
.edges
:
78 edge_seq
= tuple(bm
.verts
[i
.index
+ offset
] for i
in edge
.verts
)
84 bm
.edges
.index_update()
87 for old_bm
in list_of_bmeshes
:
98 private, end bmesh editing of active object
101 bmesh
.update_edit_mesh(o
.data
, loop_triangles
=True)
102 bpy
.ops
.object.mode_set(mode
='OBJECT')
106 def _matids(bm
, matids
):
107 for i
, matid
in enumerate(matids
):
108 bm
.faces
[i
].material_index
= matid
112 layer
= bm
.loops
.layers
.uv
.verify()
114 for i
, face
in enumerate(bm
.faces
):
116 raise RuntimeError("Missing uvs for face {}".format(i
))
118 for j
, loop
in enumerate(face
.loops
):
120 raise RuntimeError("Missing uv {} for face {}".format(j
, i
))
121 loop
[layer
].uv
= uvs
[i
][j
]
124 def _verts(bm
, verts
):
125 for i
, v
in enumerate(verts
):
129 def buildmesh(context
, o
, verts
, faces
,
130 matids
=None, uvs
=None, weld
=False,
131 clean
=False, auto_smooth
=True, temporary
=False):
136 bm
= BmeshEdit
._start
(context
, o
)
141 bm
.verts
.index_update()
142 bm
.verts
.ensure_lookup_table()
145 bm
.faces
.new([bm
.verts
[i
] for i
in f
])
146 bm
.faces
.index_update()
147 bm
.faces
.ensure_lookup_table()
149 if matids
is not None:
150 BmeshEdit
._matids
(bm
, matids
)
153 BmeshEdit
._uvs
(bm
, uvs
)
159 bmesh
.ops
.remove_doubles(bm
, verts
=bm
.verts
, dist
=0.001)
160 BmeshEdit
._end
(bm
, o
)
161 bpy
.ops
.object.mode_set(mode
='EDIT')
162 bpy
.ops
.mesh
.select_all(action
='SELECT')
164 bpy
.ops
.mesh
.faces_shade_smooth()
165 o
.data
.use_auto_smooth
= True
167 bpy
.ops
.mesh
.faces_shade_flat()
169 bpy
.ops
.mesh
.delete_loose()
170 bpy
.ops
.object.mode_set(mode
='OBJECT')
173 def addmesh(context
, o
, verts
, faces
, matids
=None, uvs
=None, weld
=False, clean
=False, auto_smooth
=True):
174 bm
= BmeshEdit
._start
(context
, o
)
181 bm
.verts
.ensure_lookup_table()
184 bm
.faces
.new([bm
.verts
[nv
+ i
] for i
in f
])
186 bm
.faces
.ensure_lookup_table()
188 if matids
is not None:
189 for i
, matid
in enumerate(matids
):
190 bm
.faces
[nf
+ i
].material_index
= matid
193 layer
= bm
.loops
.layers
.uv
.verify()
194 for i
, face
in enumerate(bm
.faces
[nf
:]):
195 for j
, loop
in enumerate(face
.loops
):
196 loop
[layer
].uv
= uvs
[i
][j
]
199 bmesh
.ops
.remove_doubles(bm
, verts
=bm
.verts
, dist
=0.001)
200 BmeshEdit
._end
(bm
, o
)
201 bpy
.ops
.object.mode_set(mode
='EDIT')
202 bpy
.ops
.mesh
.select_all(action
='SELECT')
204 bpy
.ops
.mesh
.faces_shade_smooth()
205 o
.data
.use_auto_smooth
= True
207 bpy
.ops
.mesh
.faces_shade_flat()
209 bpy
.ops
.mesh
.delete_loose()
210 bpy
.ops
.object.mode_set(mode
='OBJECT')
213 def bevel(context
, o
,
215 offset_type
='OFFSET',
223 /* Bevel offset_type slot values */
233 bm
.verts
.ensure_lookup_table()
235 geom
= [v
for v
in bm
.verts
if v
.select
]
236 geom
.extend([ed
for ed
in bm
.edges
if ed
.select
])
239 geom
.extend(bm
.edges
[:])
244 offset_type
=offset_type
,
247 # vertex_only=vertex_only,
248 clamp_overlap
=clamp_overlap
,
255 def bissect(context
, o
,
259 use_snap_center
=False,
266 bm
.verts
.ensure_lookup_table()
268 geom
.extend(bm
.edges
[:])
269 geom
.extend(bm
.faces
[:])
271 bmesh
.ops
.bisect_plane(bm
,
276 use_snap_center
=False,
277 clear_outer
=clear_outer
,
278 clear_inner
=clear_inner
285 def solidify(context
, o
, amt
, floor_bottom
=False, altitude
=0):
288 bm
.verts
.ensure_lookup_table()
290 bmesh
.ops
.solidify(bm
, geom
=geom
, thickness
=amt
)
299 def verts(context
, o
, verts
):
301 update vertex position of active object
303 bm
= BmeshEdit
._start
(context
, o
)
304 BmeshEdit
._verts
(bm
, verts
)
305 BmeshEdit
._end
(bm
, o
)
308 def aspect(context
, o
, matids
, uvs
):
310 update material id and uvmap of active object
312 bm
= BmeshEdit
._start
(context
, o
)
313 BmeshEdit
._matids
(bm
, matids
)
314 BmeshEdit
._uvs
(bm
, uvs
)
315 BmeshEdit
._end
(bm
, o
)