[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