summaryrefslogtreecommitdiff
path: root/lib/elements
diff options
context:
space:
mode:
authorKaalleen <36401965+kaalleen@users.noreply.github.com>2024-03-26 07:10:40 +0100
committerGitHub <noreply@github.com>2024-03-26 07:10:40 +0100
commit8e70f3d2feaab8a14f775a5ef84002bdab9688f0 (patch)
treef34d46ead8eb8d15317dc98de4113ccaf8acd0e9 /lib/elements
parentea394f6d3b7de3bc0818b6a9921f64e8bcbc4fbf (diff)
Add object based min stitch length (#2792)
* add object based min stitch length (overwrites global) * add object based minimum jump stitch (overwrites global) * rename patches to stitch_groups
Diffstat (limited to 'lib/elements')
-rw-r--r--lib/elements/element.py28
-rw-r--r--lib/elements/empty_d_object.py2
-rw-r--r--lib/elements/fill_stitch.py54
-rw-r--r--lib/elements/image.py2
-rw-r--r--lib/elements/marker.py2
-rw-r--r--lib/elements/polyline.py8
-rw-r--r--lib/elements/satin_column.py88
-rw-r--r--lib/elements/stroke.py48
-rw-r--r--lib/elements/text.py2
9 files changed, 139 insertions, 95 deletions
diff --git a/lib/elements/element.py b/lib/elements/element.py
index 7145571b..6c2fa15a 100644
--- a/lib/elements/element.py
+++ b/lib/elements/element.py
@@ -219,6 +219,28 @@ class EmbroideryElement(object):
return width * self.stroke_scale
@property
+ @param('min_stitch_length_mm',
+ _('Minimum stitch length'),
+ tooltip=_('Overwrite global minimum stitch length setting. Shorter stitches than that will be removed.'),
+ type='float',
+ default=None,
+ sort_index=48)
+ @cache
+ def min_stitch_length(self):
+ return self.get_float_param("min_stitch_length_mm")
+
+ @property
+ @param('min_jump_stitch_length_mm',
+ _('Minimum jump stitch length'),
+ tooltip=_('Overwrite global minimum jump stitch length setting. Shorter distances to the next object will have no lock stitches.'),
+ type='float',
+ default=None,
+ sort_index=49)
+ @cache
+ def min_jump_stitch_length(self):
+ return self.get_float_param("min_jump_stitch_length_mm")
+
+ @property
@param('ties',
_('Allow lock stitches'),
tooltip=_('Tie thread at the beginning and/or end of this object. '
@@ -472,7 +494,7 @@ class EmbroideryElement(object):
return lock_start, lock_end
- def to_stitch_groups(self, last_patch):
+ def to_stitch_groups(self, last_stitch_group):
raise NotImplementedError("%s must implement to_stitch_groups()" % self.__class__.__name__)
@debug.time
@@ -576,6 +598,10 @@ class EmbroideryElement(object):
stitch_groups[-1].trim_after = self.has_command("trim") or self.trim_after
stitch_groups[-1].stop_after = self.has_command("stop") or self.stop_after
+ for stitch_group in stitch_groups:
+ stitch_group.min_jump_stitch_length = self.min_jump_stitch_length
+ stitch_group.set_minimum_stitch_length(self.min_stitch_length)
+
self._save_cached_stitch_groups(stitch_groups, previous_stitch)
debug.log(f"ending {self.node.get('id')} {self.node.get(INKSCAPE_LABEL)}")
diff --git a/lib/elements/empty_d_object.py b/lib/elements/empty_d_object.py
index 6f010488..c2e56eac 100644
--- a/lib/elements/empty_d_object.py
+++ b/lib/elements/empty_d_object.py
@@ -27,5 +27,5 @@ class EmptyDObject(EmbroideryElement):
def shape(self):
return
- def to_stitch_groups(self, last_patch):
+ def to_stitch_groups(self, last_stitch_group):
return []
diff --git a/lib/elements/fill_stitch.py b/lib/elements/fill_stitch.py
index 203c9fe8..9ba649d7 100644
--- a/lib/elements/fill_stitch.py
+++ b/lib/elements/fill_stitch.py
@@ -714,7 +714,7 @@ class FillStitch(EmbroideryElement):
def get_starting_point(self, previous_stitch_group):
# If there is a "fill_start" Command, then use that; otherwise pick
- # the point closest to the end of the last patch.
+ # the point closest to the end of the last stitch_group.
if self.get_command('fill_start'):
return self.get_command('fill_start').target_point
@@ -792,18 +792,23 @@ class FillStitch(EmbroideryElement):
return stitch_groups
def do_legacy_fill(self):
- stitch_lists = legacy_fill(self.shape,
- self.angle,
- self.row_spacing,
- self.end_row_spacing,
- self.max_stitch_length,
- self.flip,
- self.staggers,
- self.skip_last)
- return [StitchGroup(stitches=stitch_list,
- color=self.color,
- force_lock_stitches=self.force_lock_stitches,
- lock_stitches=self.lock_stitches) for stitch_list in stitch_lists]
+ stitch_lists = legacy_fill(
+ self.shape,
+ self.angle,
+ self.row_spacing,
+ self.end_row_spacing,
+ self.max_stitch_length,
+ self.flip,
+ self.staggers,
+ self.skip_last
+ )
+
+ return [StitchGroup(
+ stitches=stitch_list,
+ color=self.color,
+ force_lock_stitches=self.force_lock_stitches,
+ lock_stitches=self.lock_stitches
+ ) for stitch_list in stitch_lists]
def do_underlay(self, shape, starting_point):
color = self.color
@@ -833,7 +838,7 @@ class FillStitch(EmbroideryElement):
starting_point = underlay.stitches[-1]
return [stitch_groups, starting_point]
- def do_auto_fill(self, shape, last_patch, starting_point, ending_point):
+ def do_auto_fill(self, shape, last_stitch_group, starting_point, ending_point):
stitch_group = StitchGroup(
color=self.color,
tags=("auto_fill", "auto_fill_top"),
@@ -851,10 +856,12 @@ class FillStitch(EmbroideryElement):
self.skip_last,
starting_point,
ending_point,
- self.underpath))
+ self.underpath
+ )
+ )
return [stitch_group]
- def do_contour_fill(self, polygon, last_patch, starting_point):
+ def do_contour_fill(self, polygon, last_stitch_group, starting_point):
if not starting_point:
starting_point = (0, 0)
starting_point = shgeo.Point(starting_point)
@@ -894,17 +901,17 @@ class FillStitch(EmbroideryElement):
tags=("auto_fill", "auto_fill_top"),
stitches=stitches,
force_lock_stitches=self.force_lock_stitches,
- lock_stitches=self.lock_stitches,)
+ lock_stitches=self.lock_stitches)
stitch_groups.append(stitch_group)
return stitch_groups
- def do_guided_fill(self, shape, last_patch, starting_point, ending_point):
+ def do_guided_fill(self, shape, last_stitch_group, starting_point, ending_point):
guide_line = self._get_guide_lines()
# No guide line: fallback to normal autofill
if not guide_line:
- return self.do_auto_fill(shape, last_patch, starting_point, ending_point)
+ return self.do_auto_fill(shape, last_stitch_group, starting_point, ending_point)
stitch_group = StitchGroup(
color=self.color,
@@ -947,11 +954,11 @@ class FillStitch(EmbroideryElement):
tags=("meander_fill", "meander_fill_top"),
stitches=meander_fill(self, shape, original_shape, i, starting_point, ending_point),
force_lock_stitches=self.force_lock_stitches,
- lock_stitches=self.lock_stitches,
+ lock_stitches=self.lock_stitches
)
return [stitch_group]
- def do_circular_fill(self, shape, last_patch, starting_point, ending_point):
+ def do_circular_fill(self, shape, last_stitch_group, starting_point, ending_point):
# get target position
command = self.get_command('ripple_target')
if command:
@@ -983,8 +990,9 @@ class FillStitch(EmbroideryElement):
tags=("circular_fill", "auto_fill_top"),
stitches=stitches,
force_lock_stitches=self.force_lock_stitches,
- lock_stitches=self.lock_stitches,)
+ lock_stitches=self.lock_stitches
+ )
return [stitch_group]
- def do_linear_gradient_fill(self, shape, last_patch, start, end):
+ def do_linear_gradient_fill(self, shape, last_stitch_group, start, end):
return linear_gradient_fill(self, shape, start, end)
diff --git a/lib/elements/image.py b/lib/elements/image.py
index 73a46871..9352a73a 100644
--- a/lib/elements/image.py
+++ b/lib/elements/image.py
@@ -29,5 +29,5 @@ class ImageObject(EmbroideryElement):
def validation_warnings(self):
yield ImageTypeWarning(self.center())
- def to_stitch_groups(self, last_patch):
+ def to_stitch_groups(self, last_stitch_group):
return []
diff --git a/lib/elements/marker.py b/lib/elements/marker.py
index 574ce91e..7085d31f 100644
--- a/lib/elements/marker.py
+++ b/lib/elements/marker.py
@@ -28,5 +28,5 @@ class MarkerObject(EmbroideryElement):
repr_point = next(inkex.Path(self.parse_path()).end_points)
yield MarkerWarning(repr_point)
- def to_stitch_groups(self, last_patch):
+ def to_stitch_groups(self, last_stitch_group):
return []
diff --git a/lib/elements/polyline.py b/lib/elements/polyline.py
index 4bc71dc0..9d17132a 100644
--- a/lib/elements/polyline.py
+++ b/lib/elements/polyline.py
@@ -94,10 +94,10 @@ class Polyline(EmbroideryElement):
def validation_warnings(self):
yield PolylineWarning(self.path[0][0][0])
- def to_stitch_groups(self, last_patch):
- patch = StitchGroup(color=self.color, lock_stitches=(None, None))
+ def to_stitch_groups(self, last_stitch_group):
+ stitch_group = StitchGroup(color=self.color, lock_stitches=(None, None))
for stitch in self.stitches:
- patch.add_stitch(Point(*stitch))
+ stitch_group.add_stitch(Point(*stitch))
- return [patch]
+ return [stitch_group]
diff --git a/lib/elements/satin_column.py b/lib/elements/satin_column.py
index 10de9f82..ec999ec7 100644
--- a/lib/elements/satin_column.py
+++ b/lib/elements/satin_column.py
@@ -1145,7 +1145,8 @@ class SatinColumn(EmbroideryElement):
stitch_group = StitchGroup(
color=self.color,
tags=("satin_column", "satin_column_underlay", "satin_contour_underlay"),
- stitches=first_side)
+ stitches=first_side
+ )
self.add_running_stitches(first_side[-1], second_side[0], stitch_group)
stitch_group.stitches += second_side
@@ -1172,7 +1173,8 @@ class SatinColumn(EmbroideryElement):
return StitchGroup(
color=self.color,
tags=("satin_column", "satin_column_underlay", "satin_center_walk"),
- stitches=stitches)
+ stitches=stitches
+ )
def do_zigzag_underlay(self):
# zigzag underlay, usually done at a much lower density than the
@@ -1185,7 +1187,7 @@ class SatinColumn(EmbroideryElement):
# "German underlay" described here:
# http://www.mrxstitch.com/underlay-what-lies-beneath-machine-embroidery/
- patch = StitchGroup(color=self.color)
+ stitch_group = StitchGroup(color=self.color)
pairs = self.plot_points_on_rails(self.zigzag_underlay_spacing / 2.0,
-self.zigzag_underlay_inset_px,
@@ -1206,12 +1208,12 @@ class SatinColumn(EmbroideryElement):
if last_point.distance(point) > max_len:
split_points = running_stitch.split_segment_even_dist(last_point, point, max_len)
for p in split_points:
- patch.add_stitch(p)
+ stitch_group.add_stitch(p)
last_point = point
- patch.add_stitch(point)
+ stitch_group.add_stitch(point)
- patch.add_tags(("satin_column", "satin_column_underlay", "satin_zigzag_underlay"))
- return patch
+ stitch_group.add_tags(("satin_column", "satin_column_underlay", "satin_zigzag_underlay"))
+ return stitch_group
def do_satin(self):
# satin: do a zigzag pattern, alternating between the paths. The
@@ -1222,7 +1224,7 @@ class SatinColumn(EmbroideryElement):
# print >> dbg, "satin", self.zigzag_spacing, self.pull_compensation
- patch = StitchGroup(color=self.color)
+ stitch_group = StitchGroup(color=self.color)
# pull compensation is automatically converted from mm to pixels by get_float_param
pairs = self.plot_points_on_rails(
@@ -1248,25 +1250,25 @@ class SatinColumn(EmbroideryElement):
split_points, _ = self.get_split_points(
last_point, a, last_short_point, a_short, max_stitch_length, last_count,
length_sigma, random_phase, min_split_length, prng.join_args(seed, 'satin-split', 2 * i), row_num=2 * i, from_end=True)
- patch.add_stitches(split_points, ("satin_column", "satin_split_stitch"))
+ stitch_group.add_stitches(split_points, ("satin_column", "satin_split_stitch"))
- patch.add_stitch(a_short)
- patch.stitches[-1].add_tags(("satin_column", "satin_column_edge"))
+ stitch_group.add_stitch(a_short)
+ stitch_group.stitches[-1].add_tags(("satin_column", "satin_column_edge"))
split_points, last_count = self.get_split_points(
a, b, a_short, b_short, max_stitch_length, None,
length_sigma, random_phase, min_split_length, prng.join_args(seed, 'satin-split', 2 * i + 1), row_num=2 * i + 1)
- patch.add_stitches(split_points, ("satin_column", "satin_split_stitch"))
+ stitch_group.add_stitches(split_points, ("satin_column", "satin_split_stitch"))
- patch.add_stitch(b_short)
- patch.stitches[-1].add_tags(("satin_column", "satin_column_edge"))
+ stitch_group.add_stitch(b_short)
+ stitch_group.stitches[-1].add_tags(("satin_column", "satin_column_edge"))
last_point = b
last_short_point = b_short
if self._center_walk_is_odd():
- patch.stitches = list(reversed(patch.stitches))
+ stitch_group.stitches = list(reversed(stitch_group.stitches))
- return patch
+ return stitch_group
def do_e_stitch(self):
# e stitch: do a pattern that looks like the letter "E". It looks like
@@ -1274,7 +1276,7 @@ class SatinColumn(EmbroideryElement):
#
# _|_|_|_|_|_|_|_|_|_|_|_|
- patch = StitchGroup(color=self.color)
+ stitch_group = StitchGroup(color=self.color)
pairs = self.plot_points_on_rails(
self.zigzag_spacing,
@@ -1302,21 +1304,21 @@ class SatinColumn(EmbroideryElement):
# zigzag spacing is wider than stitch length, subdivide
if last_point is not None and max_stitch_length is not None and self.zigzag_spacing > max_stitch_length:
points, _ = self.get_split_points(last_point, left, last_point, left, max_stitch_length)
- patch.add_stitches(points)
+ stitch_group.add_stitches(points)
- patch.add_stitch(a_short, ("edge", "left"))
- patch.add_stitches(split_points, ("split_stitch",))
- patch.add_stitch(b_short, ("edge",))
- patch.add_stitches(split_points[::-1], ("split_stitch",))
- patch.add_stitch(a_short, ("edge",))
+ stitch_group.add_stitch(a_short, ("edge", "left"))
+ stitch_group.add_stitches(split_points, ("split_stitch",))
+ stitch_group.add_stitch(b_short, ("edge",))
+ stitch_group.add_stitches(split_points[::-1], ("split_stitch",))
+ stitch_group.add_stitch(a_short, ("edge",))
last_point = a_short
if self._center_walk_is_odd():
- patch.stitches = list(reversed(patch.stitches))
+ stitch_group.stitches = list(reversed(stitch_group.stitches))
- patch.add_tags(("satin_column", "e_stitch"))
- return patch
+ stitch_group.add_tags(("satin_column", "e_stitch"))
+ return stitch_group
def do_s_stitch(self):
# S stitch: do a pattern that looks like the letter "S". It looks like
@@ -1324,7 +1326,7 @@ class SatinColumn(EmbroideryElement):
# _ _ _ _ _ _
# _| |_| |_| |_| |_| |_| |
- patch = StitchGroup(color=self.color)
+ stitch_group = StitchGroup(color=self.color)
pairs = self.plot_points_on_rails(
self.zigzag_spacing,
@@ -1357,17 +1359,17 @@ class SatinColumn(EmbroideryElement):
if last_point is not None and max_stitch_length is not None and self.zigzag_spacing > max_stitch_length:
initial_points, _ = self.get_split_points(last_point, points[0], last_point, points[0], max_stitch_length)
- patch.add_stitches(points)
+ stitch_group.add_stitches(points)
last_point = points[-1]
if self._center_walk_is_odd():
- patch.stitches = list(reversed(patch.stitches))
+ stitch_group.stitches = list(reversed(stitch_group.stitches))
- patch.add_tags(("satin", "s_stitch"))
- return patch
+ stitch_group.add_tags(("satin", "s_stitch"))
+ return stitch_group
def do_zigzag(self):
- patch = StitchGroup(color=self.color)
+ stitch_group = StitchGroup(color=self.color)
# calculate pairs at double the requested density
pairs = self.plot_points_on_rails(
@@ -1401,24 +1403,24 @@ class SatinColumn(EmbroideryElement):
split_points, _ = self.get_split_points(
last_point, a, last_point_short, a_short, max_stitch_length, None,
length_sigma, random_phase, min_split_length, prng.join_args(seed, 'satin-split', 2 * i), row_num=2 * i, from_end=True)
- patch.add_stitches(split_points, ("satin_column", "zigzag_split_stitch"))
+ stitch_group.add_stitches(split_points, ("satin_column", "zigzag_split_stitch"))
- patch.add_stitch(a_short)
+ stitch_group.add_stitch(a_short)
split_points, _ = self.get_split_points(
a, b, a_short, b_short, max_stitch_length, None,
length_sigma, random_phase, min_split_length, prng.join_args(seed, 'satin-split', 2 * i + 1), row_num=2 * i + 1)
- patch.add_stitches(split_points, ("satin_column", "zigzag_split_stitch"))
+ stitch_group.add_stitches(split_points, ("satin_column", "zigzag_split_stitch"))
- patch.add_stitch(b_short)
+ stitch_group.add_stitch(b_short)
last_point = b
last_point_short = b_short
if self._center_walk_is_odd():
- patch.stitches = list(reversed(patch.stitches))
+ stitch_group.stitches = list(reversed(stitch_group.stitches))
- return patch
+ return stitch_group
def get_split_points(self, *args, **kwargs):
if self.split_method == "default":
@@ -1526,15 +1528,17 @@ class SatinColumn(EmbroideryElement):
stitch_group += next_stitch_group
return stitch_group
- def to_stitch_groups(self, last_patch=None):
+ def to_stitch_groups(self, last_stitch_group=None):
# Stitch a variable-width satin column, zig-zagging between two paths.
# The algorithm will draw zigzags between each consecutive pair of
# beziers. The boundary points between beziers serve as "checkpoints",
# allowing the user to control how the zigzags flow around corners.
- stitch_group = StitchGroup(color=self.color,
- force_lock_stitches=self.force_lock_stitches,
- lock_stitches=self.lock_stitches)
+ stitch_group = StitchGroup(
+ color=self.color,
+ force_lock_stitches=self.force_lock_stitches,
+ lock_stitches=self.lock_stitches
+ )
if self.center_walk_underlay:
stitch_group += self.do_center_walk()
diff --git a/lib/elements/stroke.py b/lib/elements/stroke.py
index a4df5118..2ce02dbd 100644
--- a/lib/elements/stroke.py
+++ b/lib/elements/stroke.py
@@ -443,11 +443,10 @@ class Stroke(EmbroideryElement):
# `self.zigzag_spacing` is the length for a zig and a zag
# together (a V shape). Start with running stitch at half
# that length:
- patch = self.running_stitch(path, zigzag_spacing / 2.0, self.running_stitch_tolerance)
+ stitch_group = self.running_stitch(path, zigzag_spacing / 2.0, self.running_stitch_tolerance)
+ stitch_group.stitches = zigzag_stitch(stitch_group.stitches, zigzag_spacing, stroke_width, pull_compensation)
- patch.stitches = zigzag_stitch(patch.stitches, zigzag_spacing, stroke_width, pull_compensation)
-
- return patch
+ return stitch_group
def running_stitch(self, path, stitch_length, tolerance):
stitches = running_stitch(path, stitch_length, tolerance)
@@ -463,7 +462,12 @@ class Stroke(EmbroideryElement):
repeated_stitches.extend(this_path)
- return StitchGroup(self.color, repeated_stitches, lock_stitches=self.lock_stitches, force_lock_stitches=self.force_lock_stitches)
+ return StitchGroup(
+ self.color,
+ stitches=repeated_stitches,
+ lock_stitches=self.lock_stitches,
+ force_lock_stitches=self.force_lock_stitches
+ )
def apply_max_stitch_length(self, path):
# apply max distances
@@ -491,16 +495,16 @@ class Stroke(EmbroideryElement):
def do_bean_repeats(self, stitches):
return bean_stitch(stitches, self.bean_stitch_repeats)
- def to_stitch_groups(self, last_patch): # noqa: C901
- patches = []
+ def to_stitch_groups(self, last_stitch_group): # noqa: C901
+ stitch_groups = []
# ripple stitch
if self.stroke_method == 'ripple_stitch':
- patch = self.ripple_stitch()
- if patch:
+ stitch_group = self.ripple_stitch()
+ if stitch_group:
if any(self.bean_stitch_repeats):
- patch.stitches = self.do_bean_repeats(patch.stitches)
- patches.append(patch)
+ stitch_group.stitches = self.do_bean_repeats(stitch_group.stitches)
+ stitch_groups.append(stitch_group)
else:
for path in self.paths:
path = [Point(x, y) for x, y in path]
@@ -514,24 +518,26 @@ class Stroke(EmbroideryElement):
else:
# manual stitch disables lock stitches unless they force them
lock_stitches = (None, None)
- patch = StitchGroup(color=self.color,
- stitches=path,
- lock_stitches=lock_stitches,
- force_lock_stitches=self.force_lock_stitches)
+ stitch_group = StitchGroup(
+ color=self.color,
+ stitches=path,
+ lock_stitches=lock_stitches,
+ force_lock_stitches=self.force_lock_stitches
+ )
# simple satin
elif self.stroke_method == 'zigzag_stitch':
- patch = self.simple_satin(path, self.zigzag_spacing, self.stroke_width, self.pull_compensation)
+ stitch_group = self.simple_satin(path, self.zigzag_spacing, self.stroke_width, self.pull_compensation)
# running stitch
else:
- patch = self.running_stitch(path, self.running_stitch_length, self.running_stitch_tolerance)
+ stitch_group = self.running_stitch(path, self.running_stitch_length, self.running_stitch_tolerance)
# bean stitch
if any(self.bean_stitch_repeats):
- patch.stitches = self.do_bean_repeats(patch.stitches)
+ stitch_group.stitches = self.do_bean_repeats(stitch_group.stitches)
- if patch:
- patches.append(patch)
+ if stitch_group:
+ stitch_groups.append(stitch_group)
- return patches
+ return stitch_groups
@cache
def get_guide_line(self):
diff --git a/lib/elements/text.py b/lib/elements/text.py
index 8a3846c0..4203c8f9 100644
--- a/lib/elements/text.py
+++ b/lib/elements/text.py
@@ -29,5 +29,5 @@ class TextObject(EmbroideryElement):
def validation_warnings(self):
yield TextTypeWarning(self.pointer())
- def to_stitch_groups(self, last_patch):
+ def to_stitch_groups(self, last_stitch_group):
return []