Gradient blocks (#2275)

* remove underlay
* set start and end commands for consecutive blocks with the same color
* keep previous params
* add option for manual input of end_row_spacing
pull/2280/head
Kaalleen 2023-05-08 17:21:51 +02:00 zatwierdzone przez GitHub
rodzic 59ac45d321
commit b3141a24b6
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
5 zmienionych plików z 61 dodań i 13 usunięć

Wyświetl plik

@ -392,7 +392,7 @@ def remove_legacy_param(element, command):
del element.node.attrib[attribute]
def add_commands(element, commands):
def add_commands(element, commands, pos=None):
svg = get_document(element.node)
for i, command in enumerate(commands):
@ -400,7 +400,8 @@ def add_commands(element, commands):
remove_legacy_param(element, command)
group = add_group(svg, element.node, command)
pos = get_command_pos(element, i, len(commands))
if pos is None:
pos = get_command_pos(element, i, len(commands))
symbol = add_symbol(svg, group, command, pos)
add_connector(svg, symbol, command, element)

Wyświetl plik

@ -5,7 +5,7 @@ from shapely import geometry as shgeo
from shapely.affinity import affine_transform, rotate
from shapely.ops import split
from ..svg import get_correction_transform
from ..svg import PIXELS_PER_MM, get_correction_transform
def gradient_shapes_and_attributes(element, shape):
@ -63,7 +63,7 @@ def gradient_shapes_and_attributes(element, shape):
shape_rest.append(poly)
shape = shgeo.MultiPolygon(shape_rest)
previous_color = color
end_row_spacing = element.row_spacing * 2
end_row_spacing = element.row_spacing / PIXELS_PER_MM * 2
# add left over shape(s)
if shape:
if offset_outside_shape:

Wyświetl plik

@ -20,7 +20,7 @@ class DuplicateParams(InkstitchExtension):
return
copy_from = objects.first()
copy_from_attribs = self.get_inkstitch_attributes(copy_from)
copy_from_attribs = get_inkstitch_attributes(copy_from)
copy_to = objects
@ -28,7 +28,7 @@ class DuplicateParams(InkstitchExtension):
for element in copy_to:
if element == copy_to.first():
continue
copy_to_attribs = self.get_inkstitch_attributes(element)
copy_to_attribs = get_inkstitch_attributes(element)
for attrib in copy_to_attribs:
element.pop(attrib)
@ -37,5 +37,6 @@ class DuplicateParams(InkstitchExtension):
for element in copy_to:
element.attrib[attrib] = copy_from_attribs[attrib]
def get_inkstitch_attributes(self, node):
return {k: v for k, v in node.attrib.iteritems() if NSS['inkstitch'] in k}
def get_inkstitch_attributes(node):
return {k: v for k, v in node.attrib.iteritems() if NSS['inkstitch'] in k}

Wyświetl plik

@ -5,21 +5,31 @@
from math import degrees
from inkex import PathElement, errormsg
from inkex import DirectedLineSegment, PathElement, errormsg
from shapely.geometry import Point
from shapely.ops import nearest_points
from ..commands import add_commands
from ..elements import FillStitch
from ..elements.gradient_fill import gradient_shapes_and_attributes
from ..i18n import _
from ..svg import get_correction_transform
from ..svg.tags import INKSTITCH_ATTRIBS
from .base import InkstitchExtension
from .commands import CommandsExtension
from .duplicate_params import get_inkstitch_attributes
class GradientBlocks(InkstitchExtension):
class GradientBlocks(CommandsExtension):
'''
This will break apart fill objects with a gradient fill into solid color blocks with end_row_spacing.
'''
COMMANDS = ['fill_start', 'fill_end']
def __init__(self, *args, **kwargs):
CommandsExtension.__init__(self, *args, **kwargs)
self.arg_parser.add_argument("-e", "--end-row-spacing", type=float, default=0.0, dest="end_row_spacing")
def effect(self):
if not self.svg.selection:
errormsg(_("Please select at least one object with a gradient fill."))
@ -42,8 +52,12 @@ class GradientBlocks(InkstitchExtension):
# reverse order so we can always insert with the same index number
fill_shapes.reverse()
attributes.reverse()
previous_color = None
previous_element = None
for i, shape in enumerate(fill_shapes):
style['fill'] = attributes[i]['color']
color = attributes[i]['color']
style['fill'] = color
end_row_spacing = attributes[i]['end_row_spacing'] or None
angle = degrees(attributes[i]['angle'])
d = "M " + " ".join([f'{x}, {y}' for x, y in list(shape.exterior.coords)]) + " Z"
@ -54,15 +68,41 @@ class GradientBlocks(InkstitchExtension):
"d": d,
INKSTITCH_ATTRIBS['angle']: f'{angle: .2f}'
})
# apply parameters from original element
params = get_inkstitch_attributes(element.node)
for attrib in params:
block.attrib[attrib] = str(element.node.attrib[attrib])
# set end_row_spacing
if end_row_spacing:
if self.options.end_row_spacing != 0:
end_row_spacing = self.options.end_row_spacing
block.set('inkstitch:end_row_spacing_mm', f'{end_row_spacing: .2f}')
block.set('inkstitch:underpath', False)
# disable underlay and underpath
block.set('inkstitch:fill_underlay', False)
block.set('inkstitch:underpath', False)
parent.insert(index, block)
if previous_color == color:
current = FillStitch(block)
previous = FillStitch(previous_element)
nearest = nearest_points(current.shape, previous.shape)
pos_current = self._get_command_postion(current, nearest[0])
pos_previous = self._get_command_postion(previous, nearest[1])
add_commands(current, ['fill_end'], pos_current)
add_commands(previous, ['fill_start'], pos_previous)
previous_color = color
previous_element = block
parent.remove(element.node)
def has_gradient_color(self, element):
return element.color.startswith('url') and "linearGradient" in element.color
def _get_command_postion(self, fill, point):
center = fill.shape.centroid
line = DirectedLineSegment((center.x, center.y), (point.x, point.y))
pos = line.point_at_length(line.length + 20)
return Point(pos)
if __name__ == '__main__':
e = GradientBlocks()

Wyświetl plik

@ -11,6 +11,12 @@
</submenu>
</effects-menu>
</effect>
<param name="end-row-spacing"
gui-text="End row spacing"
gui-description="Set to zero to use twice the row spacing value"
type="float"
min="0" max="100"
indents="1">0.5</param>
<script>
{{ command_tag | safe }}
</script>