summaryrefslogtreecommitdiff
path: root/lib/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/__init__.py')
-rw-r--r--lib/__init__.py298
1 files changed, 0 insertions, 298 deletions
diff --git a/lib/__init__.py b/lib/__init__.py
index 2c0ee620..e69de29b 100644
--- a/lib/__init__.py
+++ b/lib/__init__.py
@@ -1,298 +0,0 @@
-#!/usr/bin/env python
-# http://www.achatina.de/sewing/main/TECHNICL.HTM
-
-import os
-import sys
-import gettext
-from copy import deepcopy
-import math
-import libembroidery
-from .utils import cache
-from .utils.geometry import Point
-
-import inkex
-import simplepath
-import simplestyle
-import simpletransform
-from bezmisc import bezierlength, beziertatlength, bezierpointatt
-from cspsubdiv import cspsubdiv
-import cubicsuperpath
-from shapely import geometry as shgeo
-
-
-# modern versions of Inkscape use 96 pixels per inch as per the CSS standard
-PIXELS_PER_MM = 96 / 25.4
-
-SVG_PATH_TAG = inkex.addNS('path', 'svg')
-SVG_POLYLINE_TAG = inkex.addNS('polyline', 'svg')
-SVG_DEFS_TAG = inkex.addNS('defs', 'svg')
-SVG_GROUP_TAG = inkex.addNS('g', 'svg')
-INKSCAPE_LABEL = inkex.addNS('label', 'inkscape')
-INKSCAPE_GROUPMODE = inkex.addNS('groupmode', 'inkscape')
-
-EMBROIDERABLE_TAGS = (SVG_PATH_TAG, SVG_POLYLINE_TAG)
-
-dbg = open(os.devnull, "w")
-
-translation = None
-_ = lambda message: message
-
-
-def localize():
- if getattr(sys, 'frozen', False):
- # we are in a pyinstaller installation
- locale_dir = sys._MEIPASS
- else:
- locale_dir = os.path.dirname(__file__)
-
- locale_dir = os.path.join(locale_dir, 'locales')
-
- global translation, _
-
- translation = gettext.translation("inkstitch", locale_dir, fallback=True)
- _ = translation.gettext
-
-localize()
-
-# cribbed from inkscape-silhouette
-def parse_length_with_units( str ):
-
- '''
- Parse an SVG value which may or may not have units attached
- This version is greatly simplified in that it only allows: no units,
- units of px, mm, and %. Everything else, it returns None for.
- There is a more general routine to consider in scour.py if more
- generality is ever needed.
- '''
-
- u = 'px'
- s = str.strip()
- if s[-2:] == 'px':
- s = s[:-2]
- elif s[-2:] == 'mm':
- u = 'mm'
- s = s[:-2]
- elif s[-2:] == 'pt':
- u = 'pt'
- s = s[:-2]
- elif s[-2:] == 'pc':
- u = 'pc'
- s = s[:-2]
- elif s[-2:] == 'cm':
- u = 'cm'
- s = s[:-2]
- elif s[-2:] == 'in':
- u = 'in'
- s = s[:-2]
- elif s[-1:] == '%':
- u = '%'
- s = s[:-1]
- try:
- v = float( s )
- except:
- raise ValueError(_("parseLengthWithUnits: unknown unit %s") % s)
-
- return v, u
-
-
-def convert_length(length):
- value, units = parse_length_with_units(length)
-
- if not units or units == "px":
- return value
-
- if units == 'pt':
- value /= 72
- units = 'in'
-
- if units == 'pc':
- value /= 6
- units = 'in'
-
- if units == 'cm':
- value *= 10
- units = 'mm'
-
- if units == 'mm':
- value = value / 25.4
- units = 'in'
-
- if units == 'in':
- # modern versions of Inkscape use CSS's 96 pixels per inch. When you
- # open an old document, inkscape will add a viewbox for you.
- return value * 96
-
- raise ValueError(_("Unknown unit: %s") % units)
-
-
-@cache
-def get_doc_size(svg):
- doc_width = convert_length(svg.get('width'))
- doc_height = convert_length(svg.get('height'))
-
- return doc_width, doc_height
-
-@cache
-def get_viewbox_transform(node):
- # somewhat cribbed from inkscape-silhouette
- doc_width, doc_height = get_doc_size(node)
-
- viewbox = node.get('viewBox').strip().replace(',', ' ').split()
-
- dx = -float(viewbox[0])
- dy = -float(viewbox[1])
- transform = simpletransform.parseTransform("translate(%f, %f)" % (dx, dy))
-
- try:
- sx = doc_width / float(viewbox[2])
- sy = doc_height / float(viewbox[3])
- scale_transform = simpletransform.parseTransform("scale(%f, %f)" % (sx, sy))
- transform = simpletransform.composeTransform(transform, scale_transform)
- except ZeroDivisionError:
- pass
-
- return transform
-
-@cache
-def get_stroke_scale(node):
- doc_width, doc_height = get_doc_size(node)
- viewbox = node.get('viewBox').strip().replace(',', ' ').split()
- return doc_width / float(viewbox[2])
-
-
-class Stitch(Point):
- def __init__(self, x, y, color=None, jump=False, stop=False, trim=False, no_ties=False):
- self.x = x
- self.y = y
- self.color = color
- self.jump = jump
- self.trim = trim
- self.stop = stop
- self.no_ties = no_ties
-
- def __repr__(self):
- return "Stitch(%s, %s, %s, %s, %s, %s, %s)" % (self.x, self.y, self.color, "JUMP" if self.jump else " ", "TRIM" if self.trim else " ", "STOP" if self.stop else " ", "NO TIES" if self.no_ties else " ")
-
-
-def make_thread(color):
- thread = libembroidery.EmbThread()
- thread.color = libembroidery.embColor_make(*color.rgb)
-
- thread.description = color.name
- thread.catalogNumber = ""
-
- return thread
-
-def add_thread(pattern, thread):
- """Add a thread to a pattern and return the thread's index"""
-
- libembroidery.embPattern_addThread(pattern, thread)
-
- return libembroidery.embThreadList_count(pattern.threadList) - 1
-
-def get_flags(stitch):
- flags = 0
-
- if stitch.jump:
- flags |= libembroidery.JUMP
-
- if stitch.trim:
- flags |= libembroidery.TRIM
-
- if stitch.stop:
- flags |= libembroidery.STOP
-
- return flags
-
-
-def _string_to_floats(string):
- floats = string.split(',')
- return [float(num) for num in floats]
-
-
-def get_origin(svg):
- # The user can specify the embroidery origin by defining two guides
- # named "embroidery origin" that intersect.
-
- namedview = svg.find(inkex.addNS('namedview', 'sodipodi'))
- all_guides = namedview.findall(inkex.addNS('guide', 'sodipodi'))
- label_attribute = inkex.addNS('label', 'inkscape')
- guides = [guide for guide in all_guides
- if guide.get(label_attribute, "").startswith("embroidery origin")]
-
- # document size used below
- doc_size = list(get_doc_size(svg))
-
- # convert the size from viewbox-relative to real-world pixels
- viewbox_transform = get_viewbox_transform(svg)
- simpletransform.applyTransformToPoint(simpletransform.invertTransform(viewbox_transform), doc_size)
-
- default = [doc_size[0] / 2.0, doc_size[1] / 2.0]
- simpletransform.applyTransformToPoint(viewbox_transform, default)
- default = Point(*default)
-
- if len(guides) < 2:
- return default
-
- # Find out where the guides intersect. Only pay attention to the first two.
- guides = guides[:2]
-
- lines = []
- for guide in guides:
- # inkscape's Y axis is reversed from SVG's, and the guide is in inkscape coordinates
- position = Point(*_string_to_floats(guide.get('position')))
- position.y = doc_size[1] - position.y
-
-
- # This one baffles me. I think inkscape might have gotten the order of
- # their vector wrong?
- parts = _string_to_floats(guide.get('orientation'))
- direction = Point(parts[1], parts[0])
-
- # We have a theoretically infinite line defined by a point on the line
- # and a vector direction. Shapely can only deal in concrete line
- # segments, so we'll pick points really far in either direction on the
- # line and call it good enough.
- lines.append(shgeo.LineString((position + 100000 * direction, position - 100000 * direction)))
-
- intersection = lines[0].intersection(lines[1])
-
- if isinstance(intersection, shgeo.Point):
- origin = [intersection.x, intersection.y]
- simpletransform.applyTransformToPoint(viewbox_transform, origin)
- return Point(*origin)
- else:
- # Either the two guides are the same line, or they're parallel.
- return default
-
-
-def write_embroidery_file(file_path, stitch_plan, svg):
- origin = get_origin(svg)
-
- pattern = libembroidery.embPattern_create()
-
- for color_block in stitch_plan:
- add_thread(pattern, make_thread(color_block.color))
-
- for stitch in color_block:
- if stitch.stop and stitch is not color_block.last_stitch:
- # A STOP stitch that is not at the end of a color block
- # occurs when the user specified "STOP after". "STOP" is the
- # same thing as a color change, and the user will assign a
- # special color at the machine that tells it to pause after.
- # We need to add another copy of the same color here so that
- # the stitches after the STOP are still the same color.
- add_thread(pattern, make_thread(color_block.color))
-
- flags = get_flags(stitch)
- libembroidery.embPattern_addStitchAbs(pattern, stitch.x - origin.x, stitch.y - origin.y, flags, 1)
-
- libembroidery.embPattern_addStitchAbs(pattern, stitch.x - origin.x, stitch.y - origin.y, libembroidery.END, 1)
-
- # convert from pixels to millimeters
- libembroidery.embPattern_scale(pattern, 1/PIXELS_PER_MM)
-
- # SVG and embroidery disagree on the direction of the Y axis
- libembroidery.embPattern_flipVertical(pattern)
-
- libembroidery.embPattern_write(pattern, file_path)