summaryrefslogtreecommitdiff
path: root/lib/extensions/jump_to_trim.py
blob: 2944c79a63bb28dbbbfed3bc12a49f9d4ffe2681 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# Authors: see git history
#
# Copyright (c) 2024 Authors
# Licensed under the GNU GPL version 3.0 or later.  See the file LICENSE for details.

from inkex import Boolean, DirectedLineSegment

from ..commands import add_commands
from ..svg import PIXELS_PER_MM
from .base import InkstitchExtension


class JumpToTrim(InkstitchExtension):
    """Adds a trim command to avoid jump stitches."""

    def __init__(self, *args, **kwargs):
        InkstitchExtension.__init__(self, *args, **kwargs)
        self.arg_parser.add_argument("--tab")

        self.arg_parser.add_argument("-i", "--minimum-jump-length", type=float, default=3.0, dest="min_jump")
        self.arg_parser.add_argument("-a", "--maximum-jump-length", type=float, default=0, dest="max_jump")
        self.arg_parser.add_argument("-t", "--use-command-symbols", type=Boolean, default=False, dest="use_command_symbols")

    def effect(self):
        self._set_selection()
        self.get_elements()

        next_elements = [None]
        if len(self.elements) > 1:
            next_elements = self.elements[1:] + next_elements
        last_element = None
        last_stitch_group = None
        for element, next_element in zip(self.elements, next_elements):
            last = last_element
            last_element = element
            stitch_groups = element.embroider(last_stitch_group, next_element)
            if not stitch_groups:
                continue

            stitch_group = stitch_groups[0]
            if last_stitch_group is None or stitch_group.color != last_stitch_group.color:
                last_stitch_group = stitch_groups[-1]
                continue

            start = last_stitch_group.stitches[-1]
            end = stitch_group.stitches[0]

            last_stitch_group = stitch_groups[-1]

            distance = DirectedLineSegment((start.x, start.y), (end.x, end.y)).length

            # do not add a trim command if the distance is smaller than min_jump setting
            if distance < self.options.min_jump * PIXELS_PER_MM:
                continue
            # do not add a trim command if the distance is longer than max_jump setting
            if self.options.max_jump > 0 and distance > self.options.max_jump * PIXELS_PER_MM:
                continue
            if last is not None:
                self._add_trim(last)

    def _add_trim(self, element):
        # skip if the element already has a trim command in one way or the other
        if element.has_command("trim") or element.trim_after:
            return

        if self.options.use_command_symbols:
            add_commands(element, ["trim"])
        else:
            element.node.set('inkstitch:trim_after', True)

    def _set_selection(self):
        if not self.svg.selection:
            self.svg.selection.clear()


if __name__ == '__main__':
    JumpToTrim().run()