[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [26628] trunk/blender/release/scripts/op/ uv.py: patch [#20910] Support for exporting UV layouts to EPS files

Campbell Barton ideasman42 at gmail.com
Fri Feb 5 16:20:12 CET 2010


Revision: 26628
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=26628
Author:   campbellbarton
Date:     2010-02-05 16:20:12 +0100 (Fri, 05 Feb 2010)

Log Message:
-----------
patch [#20910] Support for exporting UV layouts to EPS files
also improved this so visible UVs are exported unless 'All UVs' is enabled, taking into account local-view and mesh face selection.

Modified Paths:
--------------
    trunk/blender/release/scripts/op/uv.py

Modified: trunk/blender/release/scripts/op/uv.py
===================================================================
--- trunk/blender/release/scripts/op/uv.py	2010-02-05 15:07:44 UTC (rev 26627)
+++ trunk/blender/release/scripts/op/uv.py	2010-02-05 15:20:12 UTC (rev 26628)
@@ -32,18 +32,31 @@
 
     path = StringProperty(name="File Path", description="File path used for exporting the SVG file", maxlen=1024, default="")
     check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
-    only_selected = BoolProperty(name="Only Selected", description="Export Only the selected UVs", default=False)
-
+    export_all = BoolProperty(name="All UV's", description="Export all UVs in this mesh (not just the visible ones)", default=False)
+    mode = EnumProperty(items=(
+                        ('SVG', "Scalable Vector Graphic (.svg)", "Export the UV layout to a vector SVG file."),
+                        ('EPS', "Encapsulate PostScript (.eps)", "Export the UV layout to a vector EPS file.")),
+                name="Format",
+                description="File format to export the UV layout to",
+                default='SVG')
+    
     def poll(self, context):
         obj = context.active_object
         return (obj and obj.type == 'MESH')
 
+    def _space_image(self, context):
+        space_data = context.space_data
+        if type(space_data) == bpy.types.SpaceImageEditor:
+            return space_data
+        else:
+            return None
+
     def _image_size(self, context, default_width=1024, default_height=1024):
         # fallback if not in image context.
         image_width, image_height = default_width, default_height
 
-        space_data = context.space_data
-        if type(space_data) == bpy.types.SpaceImageEditor:
+        space_data = self._space_image(context)
+        if space_data:
             image = space_data.image
             if image:
                 width, height = tuple(context.space_data.image.size)
@@ -53,6 +66,41 @@
 
         return image_width, image_height
 
+    def _face_uv_iter(self, context):
+        obj = context.active_object
+        mesh = obj.data
+        uv_layer = mesh.active_uv_texture.data
+        uv_layer_len = len(uv_layer)
+        
+        if not self.properties.export_all:
+            
+            local_image = Ellipsis
+
+            if context.tool_settings.uv_local_view:
+                space_data = self._space_image(context)
+                if space_data:
+                    local_image = space_data.image
+            
+            faces = mesh.faces
+            
+            for i in range(uv_layer_len):
+                uv_elem = uv_layer[i]
+                # context checks
+                if faces[i].selected and (local_image is Ellipsis or local_image == uv_elem.image):
+                    #~ uv = uv_elem.uv
+                    #~ if False not in uv_elem.uv_selected[:len(uv)]:
+                    #~     yield (i, uv)
+                    
+                    # just write what we see.
+                    yield (i, uv_layer[i].uv)
+        else:
+            # all, simple
+            for i in range(uv_layer_len):
+                yield (i, uv_layer[i].uv)
+        
+        
+        
+
     def execute(self, context):
         # for making an XML compatible string
         from xml.sax.saxutils import escape
@@ -64,71 +112,80 @@
             bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
 
         image_width, image_height = self._image_size(context)
-
         mesh = obj.data
+        faces = mesh.faces
 
-        active_uv_layer = None
-        for lay in mesh.uv_textures:
-            if lay.active:
-                active_uv_layer = lay.data
-                break
-
-        fuvs = [(uv.uv1, uv.uv2, uv.uv3, uv.uv4) for uv in active_uv_layer]
-        fuvs_cpy = [(uv[0].copy(), uv[1].copy(), uv[2].copy(), uv[3].copy()) for uv in fuvs]
-
-        # as a list
-        faces = mesh.faces[:]
-
-        fuvsel = [(False not in uv.uv_selected) for uv in active_uv_layer]
-
+        mode = self.properties.mode
+        
         file = open(self.properties.path, "w")
         fw = file.write
 
-        fw('<?xml version="1.0" standalone="no"?>\n')
-        fw('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" \n')
-        fw('  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n')
-        fw('<svg width="%dpx" height="%dpx" viewBox="0px 0px %dpx %dpx"\n' % (image_width, image_height, image_width, image_height))
-        fw('     xmlns="http://www.w3.org/2000/svg" version="1.1">\n')
+        if mode == 'SVG':
 
-        desc = "%s, %s, %s (Blender %s)" % (basename(bpy.data.filename), obj.name, mesh.name, bpy.app.version_string)
-        fw('<desc>%s</desc>\n' % escape(desc))
+            fw('<?xml version="1.0" standalone="no"?>\n')
+            fw('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" \n')
+            fw('  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n')
+            fw('<svg width="%dpx" height="%dpx" viewBox="0px 0px %dpx %dpx"\n' % (image_width, image_height, image_width, image_height))
+            fw('     xmlns="http://www.w3.org/2000/svg" version="1.1">\n')
+            desc = "%s, %s, %s (Blender %s)" % (basename(bpy.data.filename), obj.name, mesh.name, bpy.app.version_string)
+            fw('<desc>%s</desc>\n' % escape(desc))
+    
+            # svg colors
+            fill_settings = []
+            fill_default = 'fill="grey"'
+            for mat in mesh.materials if mesh.materials else [None]:
+                if mat:
+                    fill_settings.append('fill="rgb(%d, %d, %d)"' % tuple(int(c*255) for c in mat.diffuse_color))
+                else:
+                    fill_settings.append(fill_default)
 
-        # svg colors
-        fill_settings = []
-        fill_default = 'fill="grey"'
-        for mat in mesh.materials if mesh.materials else [None]:
-            if mat:
-                fill_settings.append('fill="rgb(%d, %d, %d)"' % tuple(int(c * 255) for c in mat.diffuse_color))
-            else:
-                fill_settings.append(fill_default)
+            for i, uvs in self._face_uv_iter(context):
+                try: # rare cases material index is invalid.
+                    fill = fill_settings[faces[i].material_index]
+                except IndexError:
+                    fill = fill_default
+    
+                fw('<polygon %s fill-opacity="0.5" stroke="black" stroke-width="1px" \n' % fill)
+                fw('  points="')
+                
+                for j, uv in enumerate(uvs):
+                    x, y = uv[0], 1.0 - uv[1]
+                    fw('%.3f,%.3f ' % (x * image_width, y * image_height))
+                fw('" />\n')
+            fw('\n')
+            fw('</svg>\n')
 
-        only_selected = self.properties.only_selected
+        elif mode == 'EPS':
+            fw('%!PS-Adobe-3.0 EPSF-3.0\n')
+            fw("%%%%Creator: Blender %s\n" % bpy.app.version_string)
+            fw('%%Pages: 1\n')
+            fw('%%Orientation: Portrait\n')
+            fw("%%%%BoundingBox: 0 0 %d %d\n" % (image_width, image_height))
+            fw("%%%%HiResBoundingBox: 0.0 0.0 %.4f %.4f\n" % (image_width, image_height))
+            fw('%%EndComments\n')
+            fw('%%Page: 1 1\n')
+            fw('0 0 translate\n')
+            fw('1.0 1.0 scale\n')
+            fw('0 0 0 setrgbcolor\n')
+            fw('[] 0 setdash\n')
+            fw('1 setlinewidth\n')
+            fw('1 setlinejoin\n')
+            fw('1 setlinecap\n')
+            fw('newpath\n')
+            
+            for i, uvs in self._face_uv_iter(context):
+                for j, uv in enumerate(uvs):
+                    x, y = uv[0], uv[1]
+                    if j==0:
+                        fw('%.5f %.5f moveto\n' % (x * image_width, y * image_height))
+                    else:
+                        fw('%.5f %.5f lineto\n' % (x * image_width, y * image_height))
+            
+            fw('closepath\n')
+            fw('stroke\n')
+            fw('showpage\n')
+            fw('%%EOF\n')
 
-        for i, uv in enumerate(active_uv_layer):
-
-            if only_selected and False in uv.uv_selected:
-                continue
-
-            if len(faces[i].verts) == 3:
-                uvs = uv.uv1, uv.uv2, uv.uv3
-            else:
-                uvs = uv.uv1, uv.uv2, uv.uv3, uv.uv4
-
-            try: # rare cases material index is invalid.
-                fill = fill_settings[faces[i].material_index]
-            except IndexError:
-                fill = fill_default
-
-            fw('<polygon %s fill-opacity="0.5" stroke="black" stroke-width="1px" \n' % fill)
-            fw('  points="')
-
-            for j, uv in enumerate(uvs):
-                x, y = uv.x, 1.0 - uv.y
-                fw('%.3f,%.3f ' % (x * image_width, y * image_height))
-            fw('" />\n')
-        fw('\n')
-        fw('</svg>\n')
-
         if is_editmode:
             bpy.ops.object.mode_set(mode='EDIT', toggle=False)
 





More information about the Bf-blender-cvs mailing list