]> git.mxchange.org Git - flightgear.git/blob - utils/Modeller/uv_export_svg.py
fd70aca29822547987fdb201d53b3f7ea66d2dff
[flightgear.git] / utils / Modeller / uv_export_svg.py
1 #!BPY
2
3 # """
4 # Name: 'SVG: Export UV layout to SVG file'
5 # Blender: 245
6 # Group: 'UV'
7 # Tooltip: 'Export selected objects to SVG file'
8 # """
9
10 __author__ = "Melchior FRANZ < mfranz # aon : at >"
11 __url__ = "http://members.aon.at/mfranz/flightgear/"
12 __version__ = "0.1"
13 __bpydoc__ = """\
14 Saves the UV mappings of all selected objects to an SVG file. The uv_import_svg.py
15 script can be used to re-import such a file. Each object and each group of adjacent
16 faces therein will be made a separate SVG group.
17 """
18
19 ID_SEPARATOR = '_.._'
20 FILL_COLOR = 'yellow'
21
22
23 import Blender, sys
24
25
26 class Abort(Exception):
27         def __init__(self, msg):
28                 self.msg = msg
29
30
31 def get_adjacent_faces(pool):
32         if not len(pool):
33                 return []
34
35         i, face = pool.popitem()
36         group = [face]
37
38         uvcoords = {}
39         for c in face.uv:
40                 uvcoords[(c[0], c[1])] = True
41
42         while True:
43                 found = []
44                 for face in pool.itervalues():
45                         for c in face.uv:
46                                 if (c[0], c[1]) in uvcoords:
47                                         for d in face.uv:
48                                                 uvcoords[(d[0], d[1])] = True
49                                         found.append(face)
50                                         break
51                 if not found:
52                         break
53                 for face in found:
54                         group.append(face)
55                         del pool[face.index]
56
57         return group
58
59
60 def write_svg(filename):
61         size = Blender.Draw.PupMenu("Image size%t|128|256|512|1024|2048|4096|8192")
62         if size < 0:
63                 raise Abort('no image size chosen')
64         size = 1 << (size + 6)
65
66         print "exporting to '%s' (size %d) ... " % (filename, size),
67         svg = open(filename, "w")
68         svg.write('<?xml version="1.0" standalone="no"?>\n')
69         svg.write('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n\n')
70         svg.write('<svg width="%spx" height="%spx" viewBox="0 0 %d %d" xmlns="http://www.w3.org/2000/svg"' \
71                         ' version="1.1" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">\n'
72                         % (size, size, size, size))
73         svg.write("\t<desc>uv_export_svg.py: %s</desc>\n" % filename);
74         svg.write('\t<rect x="0" y="0" width="%d" height="%d" fill="none" stroke="blue" stroke-width="%f"/>\n'
75                         % (size, size, 1.0))
76
77         unique_meshes = {}
78         for o in Blender.Scene.GetCurrent().objects.selected:
79                 if o.type != "Mesh":
80                         continue
81
82                 mesh = o.getData(mesh = 1)
83                 if not mesh.faceUV:
84                         continue
85                 if mesh.name in unique_meshes:
86                         continue
87                 unique_meshes[mesh.name] = True
88
89                 svg.write('\t<g style="fill:%s; stroke:black stroke-width:1px" inkscape:label="%s" ' \
90                                 'id="%s">\n' % (FILL_COLOR, o.name, o.name))
91
92                 pool = {}
93                 for f in mesh.faces:
94                         pool[f.index] = f
95
96                 groups = []
97                 while len(pool):
98                         groups.append(get_adjacent_faces(pool))
99
100                 for faces in groups:
101                         indent = '\t\t'
102                         if len(groups) > 1:
103                                 svg.write('\t\t<g>\n')
104                                 indent = '\t\t\t'
105                         for f in faces:
106                                 svg.write('%s<polygon id="%s%s%d" points="' % (indent, mesh.name, ID_SEPARATOR, f.index))
107                                 for p in f.uv:
108                                         svg.write('%.8f,%.8f ' % (p[0] * size, size - p[1] * size))
109                                 svg.write('"/>\n')
110                         if len(groups) > 1:
111                                 svg.write('\t\t</g>\n')
112
113                 svg.write("\t</g>\n")
114
115         svg.write('</svg>\n')
116         svg.close()
117         print "done."
118
119
120 def export(filename):
121         registry = {}
122         registry[basename] = Blender.sys.basename(filename)
123         Blender.Registry.SetKey("UVImportExportSVG", registry, False)
124
125         editmode = Blender.Window.EditMode()
126         if editmode:
127                 Blender.Window.EditMode(0)
128
129         try:
130                 write_svg(filename)
131         except Abort, e:
132                 print "Error:", e.msg, "  -> aborting ...\n"
133                 Blender.Draw.PupMenu("Error%t|" + e.msg)
134
135         if editmode:
136                 Blender.Window.EditMode(1)
137
138
139 active = Blender.Scene.GetCurrent().objects.active
140 (basename, extname) = Blender.sys.splitext(Blender.Get("filename"))
141 filename = Blender.sys.basename(basename) + "-" + active.name + ".svg"
142 Blender.Window.FileSelector(export, "Export to SVG", filename)
143