kopia lustrzana https://github.com/inkstitch/inkstitch
add staggered and simple split satin
rodzic
cf2a1d6a3b
commit
2957615bf2
|
@ -94,16 +94,6 @@ class SatinColumn(EmbroideryElement):
|
|||
def satin_method(self):
|
||||
return self.get_param('satin_method', 'satin_column')
|
||||
|
||||
@property
|
||||
@param('max_stitch_length_mm',
|
||||
_('Maximum stitch length'),
|
||||
tooltip=_('Maximum stitch length for split stitches.'),
|
||||
type='float',
|
||||
unit="mm",
|
||||
sort_index=1)
|
||||
def max_stitch_length_px(self):
|
||||
return self.get_float_param("max_stitch_length_mm") or None
|
||||
|
||||
@property
|
||||
@param('random_width_decrease_percent',
|
||||
_('Random percentage of satin width decrease'),
|
||||
|
@ -133,18 +123,53 @@ class SatinColumn(EmbroideryElement):
|
|||
# peak-to-peak distance between zigzags
|
||||
return max(self.get_float_param("random_zigzag_spacing_percent", 0), 0) / 100
|
||||
|
||||
_split_methods = [ParamOption('default', _('Default')),
|
||||
ParamOption('simple', _('Simple')),
|
||||
ParamOption('staggered', _('Staggered'))]
|
||||
|
||||
@property
|
||||
@param('split_method',
|
||||
_('Split Method'),
|
||||
type='combo',
|
||||
default=0,
|
||||
options=_split_methods,
|
||||
sort_index=93)
|
||||
def split_method(self):
|
||||
return self.get_param('split_method', 'default')
|
||||
|
||||
@property
|
||||
@param('max_stitch_length_mm',
|
||||
_('Maximum stitch length'),
|
||||
tooltip=_('Maximum stitch length for split stitches.'),
|
||||
type='float',
|
||||
unit="mm",
|
||||
sort_index=94)
|
||||
def max_stitch_length_px(self):
|
||||
return self.get_float_param("max_stitch_length_mm") or None
|
||||
|
||||
@property
|
||||
@param('random_split_jitter_percent',
|
||||
_('Random jitter for split stitches'),
|
||||
tooltip=_('Randomizes split stitch length if random phase is enabled, stitch position if disabled.'),
|
||||
select_items=[('split_method', 'default')],
|
||||
default=0, type='float', unit="± %", sort_index=95)
|
||||
def random_split_jitter(self):
|
||||
return min(max(self.get_float_param("random_split_jitter_percent", 0), 0), 100) / 100
|
||||
|
||||
@property
|
||||
@param('random_split_phase',
|
||||
_('Random phase for split stitches'),
|
||||
tooltip=_('Controls whether split stitches are centered or with a random phase (which may increase stitch count).'),
|
||||
select_items=[('split_method', 'default')],
|
||||
default=False, type='boolean', sort_index=96)
|
||||
def random_split_phase(self):
|
||||
return self.get_boolean_param('random_split_phase')
|
||||
|
||||
@property
|
||||
@param('min_random_split_length_mm',
|
||||
_('Minimum length for random-phase split.'),
|
||||
_('Minimum length for random-phase split'),
|
||||
tooltip=_('Defaults to maximum stitch length. Smaller values allow for a transition between single-stitch and split-stitch.'),
|
||||
select_items=[('split_method', 'default')],
|
||||
default='', type='float', unit='mm', sort_index=97)
|
||||
def min_random_split_length_px(self):
|
||||
if self.max_stitch_length_px is None:
|
||||
|
@ -152,12 +177,16 @@ class SatinColumn(EmbroideryElement):
|
|||
return min(self.max_stitch_length_px, self.get_float_param('min_random_split_length_mm', self.max_stitch_length_px))
|
||||
|
||||
@property
|
||||
@param('random_split_jitter_percent',
|
||||
_('Random jitter for split stitches'),
|
||||
tooltip=_('Randomizes split stitch length if random phase is enabled, stitch position if disabled.'),
|
||||
default=0, type='float', unit="± %", sort_index=95)
|
||||
def random_split_jitter(self):
|
||||
return min(max(self.get_float_param("random_split_jitter_percent", 0), 0), 100) / 100
|
||||
@param('split_staggers',
|
||||
_('Stagger split stitches this many times before repeating'),
|
||||
# This tooltip is _exactly_ the same as the one for FillStitch.staggers, which
|
||||
# means it will be translated the same.
|
||||
tooltip=_('Length of the cycle by which successive stitch rows are staggered. '
|
||||
'Fractional values are allowed and can have less visible diagonals than integer values.'),
|
||||
select_items=[('split_method', 'staggered')],
|
||||
default=4, type='float', sort_index=98)
|
||||
def split_staggers(self):
|
||||
return self.get_float_param('split_staggers', 4)
|
||||
|
||||
@property
|
||||
@param('short_stitch_inset',
|
||||
|
@ -1110,7 +1139,7 @@ class SatinColumn(EmbroideryElement):
|
|||
if last_point is not None:
|
||||
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))
|
||||
length_sigma, random_phase, min_split_length, prng.join_args(seed, 'satin-split', 2 * i), 2 * i)
|
||||
patch.add_stitches(split_points, ("satin_column", "satin_split_stitch"))
|
||||
|
||||
patch.add_stitch(a_short)
|
||||
|
@ -1118,7 +1147,7 @@ class SatinColumn(EmbroideryElement):
|
|||
|
||||
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))
|
||||
length_sigma, random_phase, min_split_length, prng.join_args(seed, 'satin-split', 2 * i + 1), 2 * i + 1)
|
||||
patch.add_stitches(split_points, ("satin_column", "satin_split_stitch"))
|
||||
|
||||
patch.add_stitch(b_short)
|
||||
|
@ -1160,7 +1189,7 @@ class SatinColumn(EmbroideryElement):
|
|||
split_points, _ = self.get_split_points(
|
||||
left, right, a_short, b_short, max_stitch_length,
|
||||
None, length_sigma, random_phase, min_split_length,
|
||||
prng.join_args(seed, 'satin-split', 2 * i + 1))
|
||||
prng.join_args(seed, 'satin-split', 2 * i + 1), 2 * i + 1)
|
||||
|
||||
# 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:
|
||||
|
@ -1209,7 +1238,7 @@ class SatinColumn(EmbroideryElement):
|
|||
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))
|
||||
prng.join_args(seed, 'satin-split', i), i)
|
||||
points.extend(split_points)
|
||||
points.append(b_short)
|
||||
|
||||
|
@ -1229,7 +1258,16 @@ class SatinColumn(EmbroideryElement):
|
|||
patch.add_tags(("satin", "s_stitch"))
|
||||
return patch
|
||||
|
||||
def get_split_points(self, a, b, a_short, b_short, length, count=None, length_sigma=0.0, random_phase=False, min_split_length=None, seed=None):
|
||||
def get_split_points(self, *args, **kwargs):
|
||||
if self.split_method == "default":
|
||||
return self._get_split_points_default(*args, **kwargs)
|
||||
elif self.split_method == "simple":
|
||||
return self._get_split_points_simple(*args, **kwargs), None
|
||||
elif self.split_method == "staggered":
|
||||
return self._get_split_points_staggered(*args, **kwargs), None
|
||||
|
||||
def _get_split_points_default(self, a, b, a_short, b_short, length, count=None, length_sigma=0.0, random_phase=False, min_split_length=None,
|
||||
seed=None, row_num=0):
|
||||
if not length:
|
||||
return ([], None)
|
||||
if min_split_length is None:
|
||||
|
@ -1252,6 +1290,23 @@ class SatinColumn(EmbroideryElement):
|
|||
points = running_stitch.split_segment_even_dist(a, b, length, length_sigma, seed)
|
||||
return (points, len(points) + 1)
|
||||
|
||||
def _get_split_points_simple(self, *args, **kwargs):
|
||||
return self._get_split_points_staggered(*args, **kwargs, _staggers=1)
|
||||
|
||||
def _get_split_points_staggered(self, a, b, a_short, b_short, length, count=None, length_sigma=0.0, random_phase=False, min_split_length=None,
|
||||
seed=None, row_num=0, _staggers=None):
|
||||
if not length:
|
||||
return ([], None)
|
||||
|
||||
if _staggers is None:
|
||||
# This is only here to allow _get_split_points_simple to override
|
||||
_staggers = self.split_staggers
|
||||
|
||||
line = shgeo.LineString((a, b))
|
||||
a_short_projection = line.project(shgeo.Point(a_short))
|
||||
b_short_projection = line.project(shgeo.Point(b_short))
|
||||
return running_stitch.split_segment_stagger_phase(a, b, length, _staggers, row_num, min=a_short_projection, max=b_short_projection)
|
||||
|
||||
def inset_short_stitches_sawtooth(self, pairs):
|
||||
min_dist = self.short_stitch_distance
|
||||
inset = min(self.short_stitch_inset, 0.5)
|
||||
|
@ -1266,7 +1321,7 @@ class SatinColumn(EmbroideryElement):
|
|||
continue
|
||||
dist = a.distance(b)
|
||||
inset_px = inset * dist
|
||||
if max_stitch_length and not self.random_split_phase:
|
||||
if self.split_method == "default" and max_stitch_length and not self.random_split_phase:
|
||||
# make sure inset is less than split etitch length
|
||||
inset_px = min(inset_px, max_stitch_length / 3)
|
||||
|
||||
|
|
|
@ -148,6 +148,8 @@ inkstitch_attribs = [
|
|||
'random_width_decrease_percent',
|
||||
'random_width_increase_percent',
|
||||
'random_zigzag_spacing_percent',
|
||||
'split_method',
|
||||
'split_staggers',
|
||||
'random_split_phase',
|
||||
'random_split_jitter_percent',
|
||||
'min_random_split_length_mm',
|
||||
|
|
Ładowanie…
Reference in New Issue