1 # ##### BEGIN GPL LICENSE BLOCK #####
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 # ##### END GPL LICENSE BLOCK #####
23 "author": "Campbell Barton, Matt Ebb",
25 "blender": (2, 75, 0),
26 "location": "Image-Window > UVs > Export UV Layout",
27 "description": "Export the UV layout as a 2D graphic",
29 "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Import-Export/UV_Layout",
30 "support": 'OFFICIAL',
31 "category": "Import-Export",
35 # @todo write the wiki page
39 if "export_uv_eps" in locals():
40 importlib
.reload(export_uv_eps
)
41 if "export_uv_png" in locals():
42 importlib
.reload(export_uv_png
)
43 if "export_uv_svg" in locals():
44 importlib
.reload(export_uv_svg
)
48 from bpy
.props
import (
57 class ExportUVLayout(bpy
.types
.Operator
):
58 """Export UV layout to file"""
60 bl_idname
= "uv.export_layout"
61 bl_label
= "Export UV Layout"
62 bl_options
= {'REGISTER', 'UNDO'}
64 filepath
= StringProperty(
67 check_existing
= BoolProperty(
68 name
="Check Existing",
69 description
="Check and warn on overwriting existing files",
73 export_all
= BoolProperty(
75 description
="Export all UVs in this mesh (not just visible ones)",
78 modified
= BoolProperty(
80 description
="Exports UVs from the modified mesh",
84 items
=(('SVG', "Scalable Vector Graphic (.svg)",
85 "Export the UV layout to a vector SVG file"),
86 ('EPS', "Encapsulate PostScript (.eps)",
87 "Export the UV layout to a vector EPS file"),
88 ('PNG', "PNG Image (.png)",
89 "Export the UV layout to a bitmap image"),
92 description
="File format to export the UV layout to",
95 size
= IntVectorProperty(
99 description
="Dimensions of the exported file",
101 opacity
= FloatProperty(
105 description
="Set amount of opacity for exported UV layout"
107 tessellated
= BoolProperty(
108 name
="Tessellated UVs",
109 description
="Export tessellated UVs instead of polygons ones",
111 options
={'HIDDEN'}, # As not working currently :/
115 def poll(cls
, context
):
116 obj
= context
.active_object
117 return (obj
and obj
.type == 'MESH' and obj
.data
.uv_textures
)
119 def _space_image(self
, context
):
120 space_data
= context
.space_data
121 if isinstance(space_data
, bpy
.types
.SpaceImageEditor
):
126 def _image_size(self
, context
, default_width
=1024, default_height
=1024):
127 # fallback if not in image context.
128 image_width
, image_height
= default_width
, default_height
130 space_data
= self
._space
_image
(context
)
132 image
= space_data
.image
134 width
, height
= tuple(context
.space_data
.image
.size
)
135 # in case no data is found.
137 image_width
, image_height
= width
, height
139 return image_width
, image_height
141 def _face_uv_iter(self
, context
, mesh
, tessellated
):
142 uv_layer
= mesh
.uv_layers
.active
.data
143 polys
= mesh
.polygons
145 if not self
.export_all
:
146 uv_tex
= mesh
.uv_textures
.active
.data
147 local_image
= Ellipsis
149 if context
.tool_settings
.show_uv_local_view
:
150 space_data
= self
._space
_image
(context
)
152 local_image
= space_data
.image
154 for i
, p
in enumerate(polys
):
156 if polys
[i
].select
and local_image
in {Ellipsis,
159 end
= start
+ p
.loop_total
160 uvs
= tuple((uv
.uv
[0], uv
.uv
[1])
161 for uv
in uv_layer
[start
:end
])
163 # just write what we see.
167 for i
, p
in enumerate(polys
):
169 end
= start
+ p
.loop_total
170 uvs
= tuple((uv
.uv
[0], uv
.uv
[1]) for uv
in uv_layer
[start
:end
])
173 def execute(self
, context
):
175 obj
= context
.active_object
176 is_editmode
= (obj
.mode
== 'EDIT')
178 bpy
.ops
.object.mode_set(mode
='OBJECT', toggle
=False)
182 filepath
= self
.filepath
183 filepath
= bpy
.path
.ensure_ext(filepath
, "." + mode
.lower())
184 file = open(filepath
, "w")
188 from . import export_uv_eps
189 func
= export_uv_eps
.write
191 from . import export_uv_png
192 func
= export_uv_png
.write
194 from . import export_uv_svg
195 func
= export_uv_svg
.write
198 mesh
= obj
.to_mesh(context
.scene
, True, 'PREVIEW')
202 func(fw
, mesh
, self
.size
[0], self
.size
[1], self
.opacity
,
203 lambda: self
._face
_uv
_iter
(context
, mesh
, self
.tessellated
))
206 bpy
.data
.meshes
.remove(mesh
)
209 bpy
.ops
.object.mode_set(mode
='EDIT', toggle
=False)
215 def check(self
, context
):
216 filepath
= bpy
.path
.ensure_ext(self
.filepath
, "." + self
.mode
.lower())
217 if filepath
!= self
.filepath
:
218 self
.filepath
= filepath
223 def invoke(self
, context
, event
):
225 self
.size
= self
._image
_size
(context
)
226 self
.filepath
= os
.path
.splitext(bpy
.data
.filepath
)[0]
227 wm
= context
.window_manager
228 wm
.fileselect_add(self
)
229 return {'RUNNING_MODAL'}
232 def menu_func(self
, context
):
233 self
.layout
.operator(ExportUVLayout
.bl_idname
)
237 bpy
.utils
.register_module(__name__
)
238 bpy
.types
.IMAGE_MT_uvs
.append(menu_func
)
242 bpy
.utils
.unregister_module(__name__
)
243 bpy
.types
.IMAGE_MT_uvs
.remove(menu_func
)
245 if __name__
== "__main__":