kopia lustrzana https://github.com/inkstitch/inkstitch
add random parameters to satin columns
rodzic
4285a6fb7f
commit
72b001e7c2
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 697 B |
|
@ -2,16 +2,15 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2010 Authors
|
# Copyright (c) 2010 Authors
|
||||||
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
|
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
|
||||||
|
import random
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
|
from inkex import paths
|
||||||
from shapely import affinity as shaffinity
|
from shapely import affinity as shaffinity
|
||||||
from shapely import geometry as shgeo
|
from shapely import geometry as shgeo
|
||||||
from shapely.ops import nearest_points
|
from shapely.ops import nearest_points
|
||||||
|
|
||||||
from inkex import paths
|
|
||||||
|
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from ..stitch_plan import StitchGroup
|
from ..stitch_plan import StitchGroup
|
||||||
from ..svg import line_strings_to_csp, point_lists_to_csp
|
from ..svg import line_strings_to_csp, point_lists_to_csp
|
||||||
|
@ -99,6 +98,46 @@ class SatinColumn(EmbroideryElement):
|
||||||
def max_stitch_length(self):
|
def max_stitch_length(self):
|
||||||
return self.get_float_param("max_stitch_length_mm") or None
|
return self.get_float_param("max_stitch_length_mm") or None
|
||||||
|
|
||||||
|
@property
|
||||||
|
@param('random_split_factor',
|
||||||
|
_('Random Split Factor'),
|
||||||
|
tooltip=_('randomize position for split stitches.'),
|
||||||
|
type='int', unit="%", sort_index=70)
|
||||||
|
def random_split_factor(self):
|
||||||
|
return min(max(self.get_int_param("random_split_factor", 0), 0), 100)
|
||||||
|
|
||||||
|
@property
|
||||||
|
@param('random_first_rail_factor_in',
|
||||||
|
_('First Rail Random Factor inside'),
|
||||||
|
tooltip=_('shorten stitch around first rail at most this percent.'),
|
||||||
|
type='int', unit="%", sort_index=60)
|
||||||
|
def random_first_rail_factor_in(self):
|
||||||
|
return min(max(self.get_int_param("random_first_rail_factor_in", 0), 0), 100)
|
||||||
|
|
||||||
|
@property
|
||||||
|
@param('random_first_rail_factor_out',
|
||||||
|
_('First Rail Random Factor outside'),
|
||||||
|
tooltip=_('lengthen stitch around first rail at most this percent.'),
|
||||||
|
type='int', unit="%", sort_index=61)
|
||||||
|
def random_first_rail_factor_out(self):
|
||||||
|
return max(self.get_int_param("random_first_rail_factor_out", 0), 0)
|
||||||
|
|
||||||
|
@property
|
||||||
|
@param('random_second_rail_factor_in',
|
||||||
|
_('Second Rail Random Factor inside'),
|
||||||
|
tooltip=_('shorten stitch around second rail at most this percent.'),
|
||||||
|
type='int', unit="%", sort_index=62)
|
||||||
|
def random_second_rail_factor_in(self):
|
||||||
|
return min(max(self.get_int_param("random_second_rail_factor_in", 0), 0), 100)
|
||||||
|
|
||||||
|
@property
|
||||||
|
@param('random_second_rail_factor_out',
|
||||||
|
_('Second Rail Random Factor outside'),
|
||||||
|
tooltip=_('lengthen stitch around second rail at most this percent.'),
|
||||||
|
type='int', unit="%", sort_index=63)
|
||||||
|
def random_second_rail_factor_out(self):
|
||||||
|
return max(self.get_int_param("random_second_rail_factor_out", 0), 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@param('short_stitch_inset',
|
@param('short_stitch_inset',
|
||||||
_('Short stitch inset'),
|
_('Short stitch inset'),
|
||||||
|
@ -132,6 +171,15 @@ class SatinColumn(EmbroideryElement):
|
||||||
# peak-to-peak distance between zigzags
|
# peak-to-peak distance between zigzags
|
||||||
return max(self.get_float_param("zigzag_spacing_mm", 0.4), 0.01)
|
return max(self.get_float_param("zigzag_spacing_mm", 0.4), 0.01)
|
||||||
|
|
||||||
|
@property
|
||||||
|
@param('random_zigzag_spacing',
|
||||||
|
_('Zig-zag spacing randomness(peak-to-peak)'),
|
||||||
|
tooltip=_('percentage of randomness of Peak-to-peak distance between zig-zags.'),
|
||||||
|
type='int', unit="%", sort_index=64)
|
||||||
|
def random_zigzag_spacing(self):
|
||||||
|
# peak-to-peak distance between zigzags
|
||||||
|
return max(self.get_int_param("random_zigzag_spacing", 0), 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@param(
|
@param(
|
||||||
'pull_compensation_percent',
|
'pull_compensation_percent',
|
||||||
|
@ -257,6 +305,10 @@ class SatinColumn(EmbroideryElement):
|
||||||
def zigzag_underlay_max_stitch_length(self):
|
def zigzag_underlay_max_stitch_length(self):
|
||||||
return self.get_float_param("zigzag_underlay_max_stitch_length_mm") or None
|
return self.get_float_param("zigzag_underlay_max_stitch_length_mm") or None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def use_seed(self):
|
||||||
|
return self.get_int_param("use_seed", 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@cache
|
@cache
|
||||||
def shape(self):
|
def shape(self):
|
||||||
|
@ -500,6 +552,22 @@ class SatinColumn(EmbroideryElement):
|
||||||
for rung in self.rungs:
|
for rung in self.rungs:
|
||||||
point_lists.append(self.flatten_subpath(rung))
|
point_lists.append(self.flatten_subpath(rung))
|
||||||
|
|
||||||
|
# If originally there were only two subpaths (no rungs) with same number of rails, we may the rails may now
|
||||||
|
# have two rails with different number of points, and still no rungs, let's add one.
|
||||||
|
|
||||||
|
if not self.rungs:
|
||||||
|
rails = [shgeo.LineString(reversed(self.flatten_subpath(rail))) for rail in self.rails]
|
||||||
|
rails.reverse()
|
||||||
|
path_list = rails
|
||||||
|
|
||||||
|
rung_start = path_list[0].interpolate(0.1)
|
||||||
|
rung_end = path_list[1].interpolate(0.1)
|
||||||
|
rung = shgeo.LineString((rung_start, rung_end))
|
||||||
|
# make it a bit bigger so that it definitely intersects
|
||||||
|
rung = shaffinity.scale(rung, 1.1, 1.1)
|
||||||
|
path_list.append(rung)
|
||||||
|
return (self._path_list_to_satins(path_list))
|
||||||
|
|
||||||
return self._csp_to_satin(point_lists_to_csp(point_lists))
|
return self._csp_to_satin(point_lists_to_csp(point_lists))
|
||||||
|
|
||||||
def apply_transform(self):
|
def apply_transform(self):
|
||||||
|
@ -789,8 +857,13 @@ class SatinColumn(EmbroideryElement):
|
||||||
old_center = new_center
|
old_center = new_center
|
||||||
|
|
||||||
if to_travel <= 0:
|
if to_travel <= 0:
|
||||||
add_pair(pos0, pos1)
|
|
||||||
to_travel = spacing
|
decalage0 = random.uniform(-self.random_first_rail_factor_in, self.random_first_rail_factor_out) / 100
|
||||||
|
decalage1 = random.uniform(-self.random_second_rail_factor_in, self.random_second_rail_factor_out) / 100
|
||||||
|
|
||||||
|
add_pair(pos0 + (pos0 - pos1) * decalage0, pos1 + (pos1 - pos0) * decalage1)
|
||||||
|
|
||||||
|
to_travel = spacing * (random.uniform(1, 1 + self.random_zigzag_spacing/100))
|
||||||
|
|
||||||
if to_travel > 0:
|
if to_travel > 0:
|
||||||
add_pair(pos0, pos1)
|
add_pair(pos0, pos1)
|
||||||
|
@ -842,8 +915,7 @@ class SatinColumn(EmbroideryElement):
|
||||||
|
|
||||||
patch = StitchGroup(color=self.color)
|
patch = StitchGroup(color=self.color)
|
||||||
|
|
||||||
sides = self.plot_points_on_rails(self.zigzag_underlay_spacing / 2.0,
|
sides = self.plot_points_on_rails(self.zigzag_underlay_spacing / 2.0, -self.zigzag_underlay_inset)
|
||||||
-self.zigzag_underlay_inset)
|
|
||||||
|
|
||||||
if self._center_walk_is_odd():
|
if self._center_walk_is_odd():
|
||||||
sides = [list(reversed(sides[0])), list(reversed(sides[1]))]
|
sides = [list(reversed(sides[0])), list(reversed(sides[1]))]
|
||||||
|
@ -953,7 +1025,12 @@ class SatinColumn(EmbroideryElement):
|
||||||
split_count = count or int(-(-distance // max_stitch_length))
|
split_count = count or int(-(-distance // max_stitch_length))
|
||||||
for i in range(split_count):
|
for i in range(split_count):
|
||||||
line = shgeo.LineString((left, right))
|
line = shgeo.LineString((left, right))
|
||||||
split_point = line.interpolate((i+1)/split_count, normalized=True)
|
|
||||||
|
random_move = 0
|
||||||
|
if self.random_split_factor and i != split_count-1:
|
||||||
|
random_move = random.uniform(-self.random_split_factor / 100, self.random_split_factor / 100)
|
||||||
|
|
||||||
|
split_point = line.interpolate((i + 1 + random_move) / split_count, normalized=True)
|
||||||
points.append(Point(split_point.x, split_point.y))
|
points.append(Point(split_point.x, split_point.y))
|
||||||
return [points, split_count]
|
return [points, split_count]
|
||||||
|
|
||||||
|
@ -978,6 +1055,16 @@ class SatinColumn(EmbroideryElement):
|
||||||
# beziers. The boundary points between beziers serve as "checkpoints",
|
# beziers. The boundary points between beziers serve as "checkpoints",
|
||||||
# allowing the user to control how the zigzags flow around corners.
|
# allowing the user to control how the zigzags flow around corners.
|
||||||
|
|
||||||
|
# If no seed is defined, compute one randomly using time to seed, otherwise, use stored seed
|
||||||
|
|
||||||
|
if self.use_seed == 0:
|
||||||
|
random.seed()
|
||||||
|
x = random.randint(1, 10000)
|
||||||
|
random.seed(x)
|
||||||
|
self.set_param("use_seed", x)
|
||||||
|
else:
|
||||||
|
random.seed(self.use_seed)
|
||||||
|
|
||||||
patch = StitchGroup(color=self.color)
|
patch = StitchGroup(color=self.color)
|
||||||
|
|
||||||
if self.center_walk_underlay:
|
if self.center_walk_underlay:
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import random
|
||||||
import sys
|
import sys
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from copy import copy
|
from copy import copy
|
||||||
|
@ -78,6 +79,9 @@ class ParamsTab(ScrolledPanel):
|
||||||
self.pencil_icon = wx.Image(os.path.join(get_resource_dir(
|
self.pencil_icon = wx.Image(os.path.join(get_resource_dir(
|
||||||
"icons"), "pencil_20x20.png")).ConvertToBitmap()
|
"icons"), "pencil_20x20.png")).ConvertToBitmap()
|
||||||
|
|
||||||
|
self.randomize_icon = wx.Image(os.path.join(get_resource_dir(
|
||||||
|
"icons"), "randomize_20x20.png")).ConvertToBitmap()
|
||||||
|
|
||||||
self.__set_properties()
|
self.__set_properties()
|
||||||
self.__do_layout()
|
self.__do_layout()
|
||||||
|
|
||||||
|
@ -187,6 +191,16 @@ class ParamsTab(ScrolledPanel):
|
||||||
|
|
||||||
return values
|
return values
|
||||||
|
|
||||||
|
def on_change_seed(self, event):
|
||||||
|
|
||||||
|
for node in self.nodes:
|
||||||
|
random.seed()
|
||||||
|
new_seed = random.randint(1, 10000)
|
||||||
|
node.set_param("use_seed", new_seed)
|
||||||
|
if self.on_change_hook:
|
||||||
|
self.on_change_hook(self)
|
||||||
|
event.Skip()
|
||||||
|
|
||||||
def apply(self):
|
def apply(self):
|
||||||
values = self.get_values()
|
values = self.get_values()
|
||||||
for node in self.nodes:
|
for node in self.nodes:
|
||||||
|
@ -379,6 +393,17 @@ class ParamsTab(ScrolledPanel):
|
||||||
self.inputs_to_params = {v: k for k, v in self.param_inputs.items()}
|
self.inputs_to_params = {v: k for k, v in self.param_inputs.items()}
|
||||||
|
|
||||||
box.Add(self.settings_grid, proportion=1, flag=wx.ALL, border=10)
|
box.Add(self.settings_grid, proportion=1, flag=wx.ALL, border=10)
|
||||||
|
|
||||||
|
add_seed_button = False
|
||||||
|
for param in self.params:
|
||||||
|
if param.name[:6] == "random":
|
||||||
|
add_seed_button = True
|
||||||
|
if add_seed_button:
|
||||||
|
self.change_seed_button = wx.Button(self, wx.ID_ANY, _("Change Seed"))
|
||||||
|
self.change_seed_button.Bind(wx.EVT_BUTTON, self.on_change_seed)
|
||||||
|
self.change_seed_button.SetBitmap(self.randomize_icon)
|
||||||
|
box.Add(self.change_seed_button, proportion=0, flag=wx.ALIGN_CENTER_HORIZONTAL, border=10)
|
||||||
|
|
||||||
self.SetSizer(box)
|
self.SetSizer(box)
|
||||||
self.update_choice_widgets()
|
self.update_choice_widgets()
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,13 @@ inkstitch_attribs = [
|
||||||
'pull_compensation_percent',
|
'pull_compensation_percent',
|
||||||
'pull_compensation_rails',
|
'pull_compensation_rails',
|
||||||
'stroke_first',
|
'stroke_first',
|
||||||
|
'random_split_factor',
|
||||||
|
'random_first_rail_factor_in',
|
||||||
|
'random_first_rail_factor_out',
|
||||||
|
'random_second_rail_factor_in',
|
||||||
|
'random_second_rail_factor_out',
|
||||||
|
'random_zigzag_spacing',
|
||||||
|
'use_seed',
|
||||||
# stitch_plan
|
# stitch_plan
|
||||||
'invisible_layers',
|
'invisible_layers',
|
||||||
# Legacy
|
# Legacy
|
||||||
|
|
Ładowanie…
Reference in New Issue