kopia lustrzana https://github.com/inkstitch/inkstitch
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_spacingpull/2280/head
rodzic
59ac45d321
commit
b3141a24b6
|
@ -392,7 +392,7 @@ def remove_legacy_param(element, command):
|
||||||
del element.node.attrib[attribute]
|
del element.node.attrib[attribute]
|
||||||
|
|
||||||
|
|
||||||
def add_commands(element, commands):
|
def add_commands(element, commands, pos=None):
|
||||||
svg = get_document(element.node)
|
svg = get_document(element.node)
|
||||||
|
|
||||||
for i, command in enumerate(commands):
|
for i, command in enumerate(commands):
|
||||||
|
@ -400,6 +400,7 @@ def add_commands(element, commands):
|
||||||
remove_legacy_param(element, command)
|
remove_legacy_param(element, command)
|
||||||
|
|
||||||
group = add_group(svg, element.node, command)
|
group = add_group(svg, element.node, command)
|
||||||
|
if pos is None:
|
||||||
pos = get_command_pos(element, i, len(commands))
|
pos = get_command_pos(element, i, len(commands))
|
||||||
symbol = add_symbol(svg, group, command, pos)
|
symbol = add_symbol(svg, group, command, pos)
|
||||||
add_connector(svg, symbol, command, element)
|
add_connector(svg, symbol, command, element)
|
||||||
|
|
|
@ -5,7 +5,7 @@ from shapely import geometry as shgeo
|
||||||
from shapely.affinity import affine_transform, rotate
|
from shapely.affinity import affine_transform, rotate
|
||||||
from shapely.ops import split
|
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):
|
def gradient_shapes_and_attributes(element, shape):
|
||||||
|
@ -63,7 +63,7 @@ def gradient_shapes_and_attributes(element, shape):
|
||||||
shape_rest.append(poly)
|
shape_rest.append(poly)
|
||||||
shape = shgeo.MultiPolygon(shape_rest)
|
shape = shgeo.MultiPolygon(shape_rest)
|
||||||
previous_color = color
|
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)
|
# add left over shape(s)
|
||||||
if shape:
|
if shape:
|
||||||
if offset_outside_shape:
|
if offset_outside_shape:
|
||||||
|
|
|
@ -20,7 +20,7 @@ class DuplicateParams(InkstitchExtension):
|
||||||
return
|
return
|
||||||
|
|
||||||
copy_from = objects.first()
|
copy_from = objects.first()
|
||||||
copy_from_attribs = self.get_inkstitch_attributes(copy_from)
|
copy_from_attribs = get_inkstitch_attributes(copy_from)
|
||||||
|
|
||||||
copy_to = objects
|
copy_to = objects
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ class DuplicateParams(InkstitchExtension):
|
||||||
for element in copy_to:
|
for element in copy_to:
|
||||||
if element == copy_to.first():
|
if element == copy_to.first():
|
||||||
continue
|
continue
|
||||||
copy_to_attribs = self.get_inkstitch_attributes(element)
|
copy_to_attribs = get_inkstitch_attributes(element)
|
||||||
for attrib in copy_to_attribs:
|
for attrib in copy_to_attribs:
|
||||||
element.pop(attrib)
|
element.pop(attrib)
|
||||||
|
|
||||||
|
@ -37,5 +37,6 @@ class DuplicateParams(InkstitchExtension):
|
||||||
for element in copy_to:
|
for element in copy_to:
|
||||||
element.attrib[attrib] = copy_from_attribs[attrib]
|
element.attrib[attrib] = copy_from_attribs[attrib]
|
||||||
|
|
||||||
def get_inkstitch_attributes(self, node):
|
|
||||||
|
def get_inkstitch_attributes(node):
|
||||||
return {k: v for k, v in node.attrib.iteritems() if NSS['inkstitch'] in k}
|
return {k: v for k, v in node.attrib.iteritems() if NSS['inkstitch'] in k}
|
||||||
|
|
|
@ -5,21 +5,31 @@
|
||||||
|
|
||||||
from math import degrees
|
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 import FillStitch
|
||||||
from ..elements.gradient_fill import gradient_shapes_and_attributes
|
from ..elements.gradient_fill import gradient_shapes_and_attributes
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from ..svg import get_correction_transform
|
from ..svg import get_correction_transform
|
||||||
from ..svg.tags import INKSTITCH_ATTRIBS
|
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.
|
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):
|
def effect(self):
|
||||||
if not self.svg.selection:
|
if not self.svg.selection:
|
||||||
errormsg(_("Please select at least one object with a gradient fill."))
|
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
|
# reverse order so we can always insert with the same index number
|
||||||
fill_shapes.reverse()
|
fill_shapes.reverse()
|
||||||
attributes.reverse()
|
attributes.reverse()
|
||||||
|
|
||||||
|
previous_color = None
|
||||||
|
previous_element = None
|
||||||
for i, shape in enumerate(fill_shapes):
|
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
|
end_row_spacing = attributes[i]['end_row_spacing'] or None
|
||||||
angle = degrees(attributes[i]['angle'])
|
angle = degrees(attributes[i]['angle'])
|
||||||
d = "M " + " ".join([f'{x}, {y}' for x, y in list(shape.exterior.coords)]) + " Z"
|
d = "M " + " ".join([f'{x}, {y}' for x, y in list(shape.exterior.coords)]) + " Z"
|
||||||
|
@ -54,15 +68,41 @@ class GradientBlocks(InkstitchExtension):
|
||||||
"d": d,
|
"d": d,
|
||||||
INKSTITCH_ATTRIBS['angle']: f'{angle: .2f}'
|
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 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:end_row_spacing_mm', f'{end_row_spacing: .2f}')
|
||||||
|
# disable underlay and underpath
|
||||||
|
block.set('inkstitch:fill_underlay', False)
|
||||||
block.set('inkstitch:underpath', False)
|
block.set('inkstitch:underpath', False)
|
||||||
parent.insert(index, block)
|
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)
|
parent.remove(element.node)
|
||||||
|
|
||||||
def has_gradient_color(self, element):
|
def has_gradient_color(self, element):
|
||||||
return element.color.startswith('url') and "linearGradient" in element.color
|
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__':
|
if __name__ == '__main__':
|
||||||
e = GradientBlocks()
|
e = GradientBlocks()
|
||||||
|
|
|
@ -11,6 +11,12 @@
|
||||||
</submenu>
|
</submenu>
|
||||||
</effects-menu>
|
</effects-menu>
|
||||||
</effect>
|
</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>
|
<script>
|
||||||
{{ command_tag | safe }}
|
{{ command_tag | safe }}
|
||||||
</script>
|
</script>
|
||||||
|
|
Ładowanie…
Reference in New Issue