Skip to content
Snippets Groups Projects
Commit e3f5cd8f authored by Bastien Montagne's avatar Bastien Montagne
Browse files

Updated io_mesh_uv_layout addon to work with bmesh.

Note: would have loved to add an option to export tesselated layout (instead of ngon one), but currently I often get mesh without tesselation, and seems there is no way to call ensure_tesselated from python...
parent 55d1a502
Branches
Tags
No related merge requests found
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
bl_info = { bl_info = {
"name": "UV Layout", "name": "UV Layout",
"author": "Campbell Barton, Matt Ebb", "author": "Campbell Barton, Matt Ebb",
"version": (1, 0), "version": (1, 1),
"blender": (2, 5, 8), "blender": (2, 6, 2),
"location": "Image-Window > UVs > Export UV Layout", "location": "Image-Window > UVs > Export UV Layout",
"description": "Export the UV layout as a 2D graphic", "description": "Export the UV layout as a 2D graphic",
"warning": "", "warning": "",
...@@ -103,6 +103,12 @@ class ExportUVLayout(bpy.types.Operator): ...@@ -103,6 +103,12 @@ class ExportUVLayout(bpy.types.Operator):
min=0.0, max=1.0, min=0.0, max=1.0,
default=0.25, default=0.25,
) )
tesselated = BoolProperty(
name="Tesselated UVs",
description="Export tesselated UVs instead of polygons ones",
default=False,
options={'HIDDEN'}, # As not working currently :/
)
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
...@@ -131,12 +137,12 @@ class ExportUVLayout(bpy.types.Operator): ...@@ -131,12 +137,12 @@ class ExportUVLayout(bpy.types.Operator):
return image_width, image_height return image_width, image_height
def _face_uv_iter(self, context, mesh): def _face_uv_iter(self, context, mesh, tesselated):
uv_layer = mesh.uv_textures.active.data uv_layer = mesh.uv_loop_layers.active.data
uv_layer_len = len(uv_layer) polys = mesh.polygons
if not self.export_all: if not self.export_all:
uv_tex = mesh.uv_textures.active.data
local_image = Ellipsis local_image = Ellipsis
if context.tool_settings.show_uv_local_view: if context.tool_settings.show_uv_local_view:
...@@ -144,23 +150,27 @@ class ExportUVLayout(bpy.types.Operator): ...@@ -144,23 +150,27 @@ class ExportUVLayout(bpy.types.Operator):
if space_data: if space_data:
local_image = space_data.image local_image = space_data.image
faces = mesh.faces for i, p in enumerate(polys):
for i in range(uv_layer_len):
uv_elem = uv_layer[i]
# context checks # context checks
if faces[i].select and (local_image is Ellipsis or if polys[i].select and local_image in {Ellipsis,
local_image == uv_elem.image): uv_tex[i].image}:
start = p.loop_start
end = start + p.loop_total
uvs = tuple((uv.uv[0], uv.uv[1])
for uv in uv_layer[start:end])
#~ uv = uv_elem.uv #~ uv = uv_elem.uv
#~ if False not in uv_elem.select_uv[:len(uv)]: #~ if False not in uv_elem.select_uv[:len(uv)]:
#~ yield (i, uv) #~ yield (i, uv)
# just write what we see. # just write what we see.
yield (i, uv_layer[i].uv) yield (i, uvs)
else: else:
# all, simple # all, simple
for i in range(uv_layer_len): for i, p in enumerate(polys):
yield (i, uv_layer[i].uv) start = p.loop_start
end = start + p.loop_total
uvs = tuple((uv.uv[0], uv.uv[1]) for uv in uv_layer[start:end])
yield (i, uvs)
def execute(self, context): def execute(self, context):
...@@ -192,7 +202,8 @@ class ExportUVLayout(bpy.types.Operator): ...@@ -192,7 +202,8 @@ class ExportUVLayout(bpy.types.Operator):
mesh = obj.data mesh = obj.data
func(fw, mesh, self.size[0], self.size[1], self.opacity, func(fw, mesh, self.size[0], self.size[1], self.opacity,
lambda: self._face_uv_iter(context, mesh)) # self.tesselated,
lambda: self._face_uv_iter(context, mesh, self.tesselated))
if self.modified: if self.modified:
bpy.data.meshes.remove(mesh) bpy.data.meshes.remove(mesh)
......
...@@ -39,7 +39,7 @@ def write(fw, mesh, image_width, image_height, opacity, face_iter_func): ...@@ -39,7 +39,7 @@ def write(fw, mesh, image_width, image_height, opacity, face_iter_func):
fw("1 setlinejoin\n") fw("1 setlinejoin\n")
fw("1 setlinecap\n") fw("1 setlinecap\n")
faces = mesh.faces polys = mesh.polygons
if opacity > 0.0: if opacity > 0.0:
for i, mat in enumerate(mesh.materials if mesh.materials else [None]): for i, mat in enumerate(mesh.materials if mesh.materials else [None]):
...@@ -67,7 +67,7 @@ def write(fw, mesh, image_width, image_height, opacity, face_iter_func): ...@@ -67,7 +67,7 @@ def write(fw, mesh, image_width, image_height, opacity, face_iter_func):
fw("%.5f %.5f lineto\n" % uv_scale) fw("%.5f %.5f lineto\n" % uv_scale)
fw("closepath\n") fw("closepath\n")
fw("DRAW_%d\n" % faces[i].material_index) fw("DRAW_%d\n" % polys[i].material_index)
# stroke only # stroke only
for i, uvs in face_iter_func(): for i, uvs in face_iter_func():
......
...@@ -35,60 +35,44 @@ def write(fw, mesh_source, image_width, image_height, opacity, face_iter_func): ...@@ -35,60 +35,44 @@ def write(fw, mesh_source, image_width, image_height, opacity, face_iter_func):
for mat_solid in material_solids: for mat_solid in material_solids:
mesh.materials.append(mat_solid) mesh.materials.append(mat_solid)
tot_verts = 0 polys_source = mesh_source.polygons
for f in mesh_source.faces:
tot_verts += len(f.vertices)
faces_source = mesh_source.faces
# get unique UV's in case there are many overlapping # get unique UV's in case there are many overlapping
# which slow down filling. # which slow down filling.
face_hash_3 = set() face_hash = {(uvs, polys_source[i].material_index)
face_hash_4 = set() for i, uvs in face_iter_func()}
for i, uv in face_iter_func():
material_index = faces_source[i].material_index
if len(uv) == 3:
face_hash_3.add((uv[0][0], uv[0][1],
uv[1][0], uv[1][1],
uv[2][0], uv[2][1], material_index))
else:
face_hash_4.add((uv[0][0], uv[0][1],
uv[1][0], uv[1][1],
uv[2][0], uv[2][1],
uv[3][0], uv[3][1], material_index))
# now set the faces coords and locations # now set the faces coords and locations
# build mesh data # build mesh data
mesh_new_vertices = [] mesh_new_vertices = []
mesh_new_materials = [] mesh_new_materials = []
mesh_new_face_vertices = [] mesh_new_polys_startloop = []
mesh_new_polys_totloop = []
mesh_new_loops_vertices = []
current_vert = 0 current_vert = 0
for face_data in face_hash_3: for uvs, mat_idx in face_hash:
mesh_new_vertices.extend([face_data[0], face_data[1], 0.0, num_verts = len(uvs)
face_data[2], face_data[3], 0.0, dummy = (0.0,) * num_verts
face_data[4], face_data[5], 0.0]) for uv in uvs:
mesh_new_face_vertices.extend([current_vert, current_vert + 1, mesh_new_vertices += (uv[0], uv[1], 0.0)
current_vert + 2, 0]) mesh_new_polys_startloop.append(current_vert)
mesh_new_materials.append(face_data[6]) mesh_new_polys_totloop.append(num_verts)
current_vert += 3 mesh_new_loops_vertices += range(current_vert,
for face_data in face_hash_4: current_vert + num_verts)
mesh_new_vertices.extend([face_data[0], face_data[1], 0.0, mesh_new_materials.append(mat_idx)
face_data[2], face_data[3], 0.0, current_vert += num_verts
face_data[4], face_data[5], 0.0,
face_data[6], face_data[7], 0.0]) mesh.vertices.add(current_vert)
mesh_new_face_vertices.extend([current_vert, current_vert + 1, mesh.loops.add(current_vert)
current_vert + 2, current_vert + 3]) mesh.polygons.add(len(mesh_new_polys_startloop))
mesh_new_materials.append(face_data[8])
current_vert += 4
mesh.vertices.add(len(mesh_new_vertices) // 3)
mesh.faces.add(len(mesh_new_face_vertices) // 4)
mesh.vertices.foreach_set("co", mesh_new_vertices) mesh.vertices.foreach_set("co", mesh_new_vertices)
mesh.faces.foreach_set("vertices_raw", mesh_new_face_vertices) mesh.loops.foreach_set("vertex_index", mesh_new_loops_vertices)
mesh.faces.foreach_set("material_index", mesh_new_materials) mesh.polygons.foreach_set("loop_start", mesh_new_polys_startloop)
mesh.polygons.foreach_set("loop_total", mesh_new_polys_totloop)
mesh.polygons.foreach_set("material_index", mesh_new_materials)
mesh.update(calc_edges=True) mesh.update(calc_edges=True)
......
...@@ -47,10 +47,10 @@ def write(fw, mesh, image_width, image_height, opacity, face_iter_func): ...@@ -47,10 +47,10 @@ def write(fw, mesh, image_width, image_height, opacity, face_iter_func):
else: else:
fill_settings.append(fill_default) fill_settings.append(fill_default)
faces = mesh.faces polys = mesh.polygons
for i, uvs in face_iter_func(): for i, uvs in face_iter_func():
try: # rare cases material index is invalid. try: # rare cases material index is invalid.
fill = fill_settings[faces[i].material_index] fill = fill_settings[polys[i].material_index]
except IndexError: except IndexError:
fill = fill_default fill = fill_default
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment