[Bf-extensions-cvs] [c77df14] master: Updated io_export_paper_model.py from upstream master

Sybren A. Stüvel noreply at git.blender.org
Tue Sep 13 14:47:38 CEST 2016


Commit: c77df1453ba1c0f635c1ea2260698eaa35eef143
Author: Sybren A. Stüvel
Date:   Tue Sep 13 14:47:27 2016 +0200
Branches: master
https://developer.blender.org/rBACc77df1453ba1c0f635c1ea2260698eaa35eef143

Updated io_export_paper_model.py from upstream master

https://raw.githubusercontent.com/addam/Export-Paper-Model-from-Blender/master/io_export_paper_model.py
revision 13d8334 to be exact. I've taken the file as-is, with the
exception of the removal of trailing whitespace.

===================================================================

M	io_export_paper_model.py

===================================================================

diff --git a/io_export_paper_model.py b/io_export_paper_model.py
index e9751e8..225b17e 100644
--- a/io_export_paper_model.py
+++ b/io_export_paper_model.py
@@ -27,7 +27,7 @@ bl_info = {
     "category": "Import-Export",
     "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
                 "Scripts/Import-Export/Paper_Model",
-    "tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
+    "tracker_url": "https://developer.blender.org/T38441"
 }
 
 #### TODO:
@@ -57,7 +57,7 @@ import bl_operators
 import bgl
 import mathutils as M
 from re import compile as re_compile
-from itertools import chain
+from itertools import chain, repeat
 from math import pi
 
 try:
@@ -81,7 +81,7 @@ def first_letters(text):
     """Iterator over the first letter of each word"""
     for match in first_letters.pattern.finditer(text):
         yield text[match.start()]
-first_letters.pattern = re_compile("(?<!\w)[\w]")
+first_letters.pattern = re_compile("((?<!\w)\w)|\d")
 
 
 def is_upsidedown_wrong(name):
@@ -175,21 +175,29 @@ class Unfolder:
 
     def copy_island_names(self, island_list):
         """Copy island label and abbreviation from the best matching island in the list"""
-        orig_list = {(frozenset(face.id for face in item.faces), item.label, item.abbreviation) for item in island_list}
-        for island in self.mesh.islands:
+        orig_islands = [{face.id for face in item.faces} for item in island_list]
+        matching = list()
+        for i, island in enumerate(self.mesh.islands):
             islfaces = {uvface.face.index for uvface in island.faces}
-            match = max(orig_list, key=lambda item: islfaces.intersection(item[0]))
-            island.label = match[1]
-            island.abbreviation = match[2]
+            matching.extend((len(islfaces.intersection(item)), i, j) for j, item in enumerate(orig_islands))
+        matching.sort(reverse=True)
+        available_new = [True for island in self.mesh.islands]
+        available_orig = [True for item in island_list]
+        for face_count, i, j in matching:
+            if available_new[i] and available_orig[j]:
+                available_new[i] = available_orig[j] = False
+                self.mesh.islands[i].label = island_list[j].label
+                self.mesh.islands[i].abbreviation = island_list[j].abbreviation
 
     def save(self, properties):
         """Export the document"""
         # Note about scale: input is direcly in blender length
         # Mesh.scale_islands multiplies everything by a user-defined ratio
-        # SVG object multiplies everything by 1000 (output in millimeters)
+        # exporters (SVG or PDF) multiply everything by 1000 (output in millimeters)
+        Exporter = SVG if properties.file_format == 'SVG' else PDF
         filepath = properties.filepath
-        if filepath.lower().endswith((".svg", ".png")):
-            filepath = filepath[0:-4]
+        extension = properties.file_format.lower()
+        filepath = bpy.path.ensure_ext(filepath, "." + extension)
         # page size in meters
         page_size = M.Vector((properties.output_size_x, properties.output_size_y))
         # printable area size in meters
@@ -206,14 +214,14 @@ class Unfolder:
 
         text_height = properties.sticker_width if (properties.do_create_numbers and len(self.mesh.islands) > 1) else 0
         aspect_ratio = printable_size.x / printable_size.y
-        # finalizing islands will scale everything so that the page height is 1
         # title height must be somewhat larger that text size, glyphs go below the baseline
         self.mesh.finalize_islands(title_height=text_height * 1.2)
         self.mesh.fit_islands(cage_size=printable_size)
 
         if properties.output_type != 'NONE':
             # bake an image and save it as a PNG to disk or into memory
-            use_separate_images = properties.image_packing in ('ISLAND_LINK', 'ISLAND_EMBED')
+            image_packing = properties.image_packing if properties.file_format == 'SVG' else 'ISLAND_EMBED'
+            use_separate_images = image_packing in ('ISLAND_LINK', 'ISLAND_EMBED')
             tex = self.mesh.save_uv(cage_size=printable_size, separate_image=use_separate_images, tex=self.tex)
             if not tex:
                 raise UnfoldError("The mesh has no UV Map slots left. Either delete a UV Map or export the net without textures.")
@@ -224,12 +232,12 @@ class Unfolder:
             rd.use_bake_selected_to_active = (properties.output_type == 'SELECTED_TO_ACTIVE')
 
             rd.bake_margin, rd.bake_distance, rd.bake_bias, rd.use_bake_to_vertex_color, rd.use_bake_clear = 0, 0, 0.001, False, False
-            if properties.image_packing == 'PAGE_LINK':
+            if image_packing == 'PAGE_LINK':
                 self.mesh.save_image(tex, printable_size * ppm, filepath)
-            elif properties.image_packing == 'ISLAND_LINK':
-                self.mesh.save_separate_images(tex, printable_size.y * ppm, filepath)
-            elif properties.image_packing == 'ISLAND_EMBED':
-                self.mesh.save_separate_images(tex, printable_size.y * ppm, filepath, do_embed=True)
+            elif image_packing == 'ISLAND_LINK':
+                self.mesh.save_separate_images(tex, ppm, filepath)
+            elif image_packing == 'ISLAND_EMBED':
+                self.mesh.save_separate_images(tex, ppm, filepath, embed=Exporter.encode_image)
 
             # revoke settings
             rd.bake_type, rd.use_bake_to_vertex_color, rd.use_bake_selected_to_active, rd.bake_distance, rd.bake_bias, rd.bake_margin, rd.use_bake_clear = recall
@@ -237,11 +245,10 @@ class Unfolder:
                 tex.active = True
                 bpy.ops.mesh.uv_texture_remove()
 
-        svg = SVG(page_size, properties.style, (properties.output_type == 'NONE'))
-        svg.do_create_stickers = properties.do_create_stickers
-        svg.margin = properties.output_margin
-        svg.text_size = properties.sticker_width
-        svg.write(self.mesh, filepath)
+        exporter = Exporter(page_size, properties.style, properties.output_margin, (properties.output_type == 'NONE'))
+        exporter.do_create_stickers = properties.do_create_stickers
+        exporter.text_size = properties.sticker_width
+        exporter.write(self.mesh, filepath)
 
 
 class Mesh:
@@ -558,20 +565,7 @@ class Mesh:
                 image.user_clear()
                 bpy.data.images.remove(image)
 
-    def save_separate_images(self, tex, scale, filepath, do_embed=False):
-        assert(os_path)  # check the module was imported
-        if do_embed:
-            import tempfile
-            import base64
-        else:
-            from os import mkdir
-            image_dir = filepath
-            try:
-                mkdir(image_dir)
-            except OSError:
-                # image_dir already existed
-                pass
-
+    def save_separate_images(self, tex, scale, filepath, embed=None):
         texfaces = tex.data
         # omitting these 3 lines causes a "Circular reference in texture stack" error
         for island in self.islands:
@@ -579,34 +573,26 @@ class Mesh:
                 texfaces[uvface.face.index].image = None
 
         for i, island in enumerate(self.islands, 1):
-            if do_embed:
-                tempfile_manager = tempfile.NamedTemporaryFile("rb", suffix=".png")
-                image_path = tempfile_manager.name
-                image_name = os_path.basename(tempfile_manager.name)
-                # note: image_path exists by now and Blender will overwrite it;
-                # we will read later from the same file
-            else:
-                image_path = os_path.join(image_dir, "island{}.png".format(i))
-                image_name = "{} isl{}".format(self.data.name[:15], i)
+            image_name = "{} isl{}".format(self.data.name[:15], i)
             image = create_blank_image(image_name, island.bounding_box * scale, alpha=0)
-            image.filepath_raw = image_path
             for uvface in island.faces:
                 texfaces[uvface.face.index].image = image
+            bpy.ops.object.bake_image()
 
-            try:
-                bpy.ops.object.bake_image()
-                image.save()
-            finally:
-                for uvface in island.faces:
-                    texfaces[uvface.face.index].image = None
-                image.user_clear()
-                bpy.data.images.remove(image)
-
-            if do_embed:
-                with tempfile_manager as imgfile:
-                    island.embedded_image = base64.encodebytes(imgfile.read()).decode('ascii')
+            if embed:
+                island.embedded_image = embed(image)
             else:
-                island.image_path = image_path
+                from os import makedirs
+                image_dir = filepath
+                makedirs(image_dir, exist_ok=True)
+                image_path = os_path.join(image_dir, "island{}.png".format(i))
+                image.filepath_raw = image_path
+                image.save()
+                island.image_path = image.path
+            for uvface in island.faces:
+                texfaces[uvface.face.index].image = None
+            image.user_clear()
+            bpy.data.images.remove(image)
 
 
 class Vertex:
@@ -1258,23 +1244,41 @@ class Sticker:
 
         other_first, other_second = (other.va, other.vb) if not other.uvface.flipped else (other.vb, other.va)
         other_edge = other_second.co - other_first.co
+
         # angle a is at vertex uvedge.va, b is at uvedge.vb
         cos_a = cos_b = 0.5
         sin_a = sin_b = 0.75**0.5
         # len_a is length of the side adjacent to vertex a, len_b likewise
         len_a = len_b = sticker_width / sin_a
+
         # fix overlaps with the most often neighbour - its sticking target
         if first_vertex == other_second:
             cos_a = max(cos_a, (edge*other_edge) / (edge.length**2))  # angles between pi/3 and 0
-            sin_a = abs(1 - cos_a**2)**0.5
-            len_b = min(len_a, (edge.length*sin_a) / (sin_a*cos_b + sin_b*cos_a))
-            len_a = 0 if sin_a == 0 else min(sticker_width / sin_a, (edge.length - len_b*cos_b) / cos_a)
  

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list