kopia lustrzana https://github.com/inkstitch/inkstitch
group patterns
rodzic
d6df8084f4
commit
c602c4c517
|
@ -46,10 +46,12 @@ COMMANDS = {
|
|||
# L10N command attached to an object
|
||||
"satin_cut_point": N_("Satin cut point (use with Cut Satin Column)"),
|
||||
|
||||
|
||||
# L10N command that affects a layer
|
||||
"ignore_layer": N_("Ignore layer (do not stitch any objects in this layer)"),
|
||||
|
||||
# L10N command that affects a group
|
||||
"pattern_group": N_("Strokes in this group will be interpretet as a pattern"),
|
||||
|
||||
# L10N command that affects entire document
|
||||
"origin": N_("Origin for exported embroidery files"),
|
||||
|
||||
|
@ -58,6 +60,7 @@ COMMANDS = {
|
|||
}
|
||||
|
||||
OBJECT_COMMANDS = ["fill_start", "fill_end", "satin_start", "satin_end", "stop", "trim", "ignore_object", "satin_cut_point"]
|
||||
GROUP_COMMANDS = ["pattern_group"]
|
||||
LAYER_COMMANDS = ["ignore_layer"]
|
||||
GLOBAL_COMMANDS = ["origin", "stop_position"]
|
||||
|
||||
|
@ -184,6 +187,12 @@ def find_commands(node):
|
|||
return commands
|
||||
|
||||
|
||||
def group_commands(node, command):
|
||||
xpath = "./ancestor::svg:g/svg:use[@xlink:href='#inkstitch_%(command)s']" % dict(id=node.get('id'), command=command)
|
||||
group_command = node.xpath(xpath, namespaces=inkex.NSS)
|
||||
return group_command
|
||||
|
||||
|
||||
def layer_commands(layer, command):
|
||||
"""Find standalone (unconnected) command symbols in this layer."""
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
from copy import deepcopy
|
||||
from itertools import chain
|
||||
|
||||
from inkex import paths
|
||||
from inkex import paths, NSS
|
||||
from shapely import affinity as shaffinity
|
||||
from shapely import geometry as shgeo
|
||||
from shapely.ops import nearest_points
|
||||
|
@ -14,6 +14,7 @@ from shapely.ops import nearest_points
|
|||
from ..i18n import _
|
||||
from ..svg import (PIXELS_PER_MM, apply_transforms, line_strings_to_csp,
|
||||
point_lists_to_csp)
|
||||
from ..svg.tags import EMBROIDERABLE_TAGS
|
||||
from ..utils import Point, cache, collapse_duplicate_point, cut
|
||||
from .element import EmbroideryElement, Patch, param
|
||||
from .validation import ValidationError, ValidationWarning
|
||||
|
@ -577,10 +578,13 @@ class SatinColumn(EmbroideryElement):
|
|||
return SatinColumn(node)
|
||||
|
||||
def get_patterns(self):
|
||||
xpath = ".//*[@inkstitch:pattern='%(id)s']" % dict(id=self.node.get('id'))
|
||||
patterns = self.node.getroottree().getroot().xpath(xpath)
|
||||
xpath = "./ancestor::svg:g[svg:use[@xlink:href='#inkstitch_pattern_group']]//*[not(@inkstitch:satin_column='true')]"
|
||||
patterns = self.node.xpath(xpath, namespaces=NSS)
|
||||
line_strings = []
|
||||
for pattern in patterns:
|
||||
# TODO: exclude fills in case we will want to use them with the pattern too
|
||||
if pattern.tag not in EMBROIDERABLE_TAGS:
|
||||
continue
|
||||
d = pattern.get_path()
|
||||
path = paths.Path(d).to_superpath()
|
||||
path = apply_transforms(path, pattern)
|
||||
|
|
|
@ -17,6 +17,7 @@ from .polyline import Polyline
|
|||
from .satin_column import SatinColumn
|
||||
from .stroke import Stroke
|
||||
from .text import TextObject
|
||||
from ..commands import group_commands
|
||||
|
||||
|
||||
def node_to_elements(node): # noqa: C901
|
||||
|
@ -29,7 +30,8 @@ def node_to_elements(node): # noqa: C901
|
|||
elif node.tag == SVG_PATH_TAG and not node.get('d', ''):
|
||||
return [EmptyDObject(node)]
|
||||
|
||||
elif node.get(INKSTITCH_ATTRIBS['pattern']):
|
||||
# TODO: exclude fills
|
||||
elif group_commands(node, 'pattern_group') and not node.get(INKSTITCH_ATTRIBS['satin_column']):
|
||||
return [PatternObject(node)]
|
||||
|
||||
elif node.tag in EMBROIDERABLE_TAGS:
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
from lib.extensions.troubleshoot import Troubleshoot
|
||||
|
||||
from .apply_satin_pattern import ApplySatinPattern
|
||||
from .auto_satin import AutoSatin
|
||||
from .break_apart import BreakApart
|
||||
from .cleanup import Cleanup
|
||||
|
@ -46,7 +45,6 @@ __all__ = extensions = [StitchPlanPreview,
|
|||
GlobalCommands,
|
||||
ConvertToSatin,
|
||||
CutSatin,
|
||||
ApplySatinPattern,
|
||||
AutoSatin,
|
||||
Lettering,
|
||||
LetteringGenerateJson,
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
# Authors: see git history
|
||||
#
|
||||
# Copyright (c) 2021 Authors
|
||||
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
|
||||
|
||||
import inkex
|
||||
from lxml import etree
|
||||
|
||||
from ..elements import SatinColumn
|
||||
from ..i18n import _
|
||||
from ..svg.tags import INKSTITCH_ATTRIBS, SVG_DEFS_TAG
|
||||
from .base import InkstitchExtension
|
||||
|
||||
|
||||
class ApplySatinPattern(InkstitchExtension):
|
||||
# Add inkstitch:pattern attribute to selected patterns. The patterns will be projected on a satin column, which must be in the selection too
|
||||
|
||||
def effect(self):
|
||||
if not self.get_elements():
|
||||
return
|
||||
|
||||
if not self.svg.selected or not any(isinstance(item, SatinColumn) for item in self.elements) or len(self.svg.selected) < 2:
|
||||
inkex.errormsg(_("Please select at least one satin column and a pattern."))
|
||||
return
|
||||
|
||||
if sum(isinstance(item, SatinColumn) for item in self.elements) > 1:
|
||||
inkex.errormsg(_("Please select only one satin column."))
|
||||
return
|
||||
|
||||
satin_id = self.get_satin_column().node.get('id', None)
|
||||
patterns = self.get_patterns()
|
||||
|
||||
for pattern in patterns:
|
||||
pattern.node.set(INKSTITCH_ATTRIBS['pattern'], satin_id)
|
||||
self.set_marker(pattern.node)
|
||||
|
||||
def get_satin_column(self):
|
||||
return list(filter(lambda satin: isinstance(satin, SatinColumn), self.elements))[0]
|
||||
|
||||
def get_patterns(self):
|
||||
return list(filter(lambda satin: not isinstance(satin, SatinColumn), self.elements))
|
||||
|
||||
def set_marker(self, node):
|
||||
document = node.getroottree().getroot()
|
||||
xpath = ".//marker[@id='inkstitch-pattern-marker']"
|
||||
pattern_marker = document.xpath(xpath)
|
||||
if not pattern_marker:
|
||||
# get or create def element
|
||||
defs = document.find(SVG_DEFS_TAG)
|
||||
if defs is None:
|
||||
defs = etree.SubElement(document, SVG_DEFS_TAG)
|
||||
|
||||
# insert marker
|
||||
marker = """<marker
|
||||
refX="5"
|
||||
refY="2.5"
|
||||
orient="auto"
|
||||
id="inkstitch-pattern-marker">
|
||||
<g
|
||||
id="inkstitch-pattern-group">
|
||||
<path
|
||||
style="fill:#fafafa;stroke:#ffbe00;stroke-width:0.3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:1, 0.5;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 5.05952,2.58154 c 0,1.35905 -1.10173,2.4608 -2.46079,2.4608 -1.35905,0 -2.46079,-1.10175 -2.46079,-2.4608 0,-0.65262 0.259271,-1.27856 0.720751,-1.74004 C 1.32018,0.38002 1.94609,0.120749 2.59873,0.120749 c 1.35906,0 2.46079,1.101751 2.46079,2.460791 z"
|
||||
id="inkstitch-pattern-marker-circle" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.1;stroke-linecap:round;stroke-miterlimit:4;"
|
||||
id="inkstitch-pattern-marker-spiral"
|
||||
d="M 2.45807,2.80588 C 2.35923,2.84009 2.28168,2.72985 2.27863,2.64621 2.27369,2.48274 2.43336,2.37629 2.58086,2.3877 2.8006,2.40291 2.94012,2.6234 2.91389,2.83249 2.87853,3.11001 2.59683,3.28488 2.3292,3.24307 1.99161,3.18604 1.78366,2.84389 1.84297,2.51695 1.9152,2.11778 2.32311,1.87448 2.70974,1.95431 3.16593,2.04175 3.44307,2.51315 3.34955,2.96175 3.24121,3.47497 2.70594,3.7867 2.2007,3.67645 1.62589,3.551 1.27919,2.95034 1.4073,2.3877 1.551,1.75283 2.21439,1.37266 2.83823,1.51713 3.53165,1.67679 3.94793,2.40671 3.78522,3.0872 3.60616,3.83992 2.81504,4.29232 2.07221,4.11364 1.26018,3.91595 0.773949,3.06059 0.971634,2.25844 1.18605,1.38787 2.10528,0.867047 2.96711,1.07994 3.89775,1.31184 4.45317,2.29646 4.22089,3.21645 4.20112,3.29629 4.17565,3.37612 4.14523,3.45216" />
|
||||
</g>
|
||||
</marker>""" # noqa: E501
|
||||
defs.append(etree.fromstring(marker))
|
||||
|
||||
# attach marker to node
|
||||
style = node.get('style', '').split(";")
|
||||
import sys
|
||||
print(style, file=sys.stderr)
|
||||
style = [i for i in style if not i.startswith('marker-start')]
|
||||
style.append('marker-start:url(#inkstitch-pattern-marker)')
|
||||
node.set('style', ";".join(style))
|
|
@ -12,7 +12,7 @@ import inkex
|
|||
from lxml import etree
|
||||
from stringcase import snakecase
|
||||
|
||||
from ..commands import is_command, layer_commands
|
||||
from ..commands import is_command, layer_commands, group_commands
|
||||
from ..elements import EmbroideryElement, nodes_to_elements
|
||||
from ..elements.clone import is_clone
|
||||
from ..i18n import _
|
||||
|
@ -171,9 +171,12 @@ class InkstitchExtension(inkex.Effect):
|
|||
if selected:
|
||||
if node.tag == SVG_GROUP_TAG:
|
||||
pass
|
||||
elif (node.tag in EMBROIDERABLE_TAGS or is_clone(node)) and not node.get(INKSTITCH_ATTRIBS['pattern']):
|
||||
elif ((node.tag in EMBROIDERABLE_TAGS or is_clone(node)) and not
|
||||
(len(list(group_commands(node, 'pattern_group'))) and not node.get(INKSTITCH_ATTRIBS['satin_column']))):
|
||||
nodes.append(node)
|
||||
elif troubleshoot and (node.tag in NOT_EMBROIDERABLE_TAGS or node.get(INKSTITCH_ATTRIBS['pattern'])):
|
||||
# add images, text and patterns for the troubleshoot extension
|
||||
elif (troubleshoot and (node.tag in NOT_EMBROIDERABLE_TAGS or
|
||||
(len(list(group_commands(node, 'pattern_group'))) and not node.get(INKSTITCH_ATTRIBS['satin_column'])))):
|
||||
nodes.append(node)
|
||||
|
||||
return nodes
|
||||
|
|
|
@ -58,6 +58,21 @@
|
|||
id="title9425">Ink/Stitch Commands</title>
|
||||
<defs
|
||||
id="defs8377">
|
||||
<symbol
|
||||
id="inkstitch_pattern_group">
|
||||
<title
|
||||
id="inkstitch_title9428">Pattern group</title>
|
||||
<path
|
||||
id="inkstitch_circle13166"
|
||||
d="m 9.220113,0.0792309 c -1.9e-6,5.106729 -4.1398241,9.24655 -9.246553,9.24655 -5.1067293,0 -9.2465521,-4.139821 -9.246554,-9.24655 1e-7,-2.452338 0.9741879,-4.804235 2.7082531,-6.538301 1.7340653,-1.734065 4.0859624,-2.708252 6.5383009,-2.708252 5.1067301,0 9.2465528,4.139823 9.246553,9.246553 0,0 0,0 0,0"
|
||||
style="opacity:1;vector-effect:none;fill:#fafafa;fill-opacity:1;fill-rule:evenodd;stroke:#003399;stroke-width:1.06500006;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3.19500017, 3.19500017;stroke-dashoffset:0;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="opacity:1;fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;paint-order:fill markers stroke"
|
||||
d="m -0.55128037,0.95833812 c -0.40285999,0.22036398 -0.82508003,-0.183557 -0.90661003,-0.560037 -0.1499,-0.692211 0.46187004,-1.28184699 1.11359003,-1.35201699 0.96741,-0.10416303 1.74798997,0.74237599 1.79742997,1.66713199 0.0663,1.24036698 -1.02338997,2.21768898 -2.22067996,2.24284098 -1.51274004,0.03178 -2.68913004,-1.304567 -2.68826004,-2.77422898 10e-4,-1.78491502 1.58583,-3.16155802 3.32778003,-3.13366302 2.05701997,0.03294 3.63459997,1.867131 3.57906997,3.88132402 -0.0642,2.32909498 -2.14846,4.10805198 -4.43486996,4.02448698 -2.60115004,-0.09507 -4.58179004,-2.429829 -4.46990004,-4.98841998 0.12565,-2.87321502 2.71121,-5.05573202 5.54197003,-4.91531002 3.14526997,0.156023 5.52982997,2.992595 5.36071997,6.095516 -0.18624,3.417327 -3.27399,6.004045 -6.64906,5.806133 -3.68939,-0.216344 -6.47835,-3.555403 -6.25154,-7.20261198 0.24635,-3.96144502 3.83681,-6.95273902 7.75616003,-6.69695602 4.23349997,0.276286 7.42717997,4.118238 7.14235997,8.309708 -0.0245,0.360257 -0.0734,0.718834 -0.14624,1.0725"
|
||||
id="inkstitch_spiral5371-3"
|
||||
inkscape:connector-curvature="0" />
|
||||
</symbol>
|
||||
<symbol
|
||||
id="inkstitch_fill_end">
|
||||
<title
|
||||
|
@ -334,6 +349,14 @@
|
|||
width="100%"
|
||||
height="100%"
|
||||
transform="translate(37.82169,75.511319)" />
|
||||
<use
|
||||
xlink:href="#inkstitch_pattern_group"
|
||||
id="use9462"
|
||||
x="0"
|
||||
y="0"
|
||||
width="100%"
|
||||
height="100%"
|
||||
transform="translate(189.0002,37.680421)" />
|
||||
<use
|
||||
xlink:href="#inkstitch_trim"
|
||||
id="use9461"
|
||||
|
|
Przed Szerokość: | Wysokość: | Rozmiar: 43 KiB Po Szerokość: | Wysokość: | Rozmiar: 45 KiB |
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
|
||||
<name>{% trans %}Apply Satin Pattern{% endtrans %}</name>
|
||||
<id>org.inkstitch.apply_satin_pattern.{{ locale }}</id>
|
||||
<param name="extension" type="string" gui-hidden="true">apply_satin_pattern</param>
|
||||
<effect>
|
||||
<object-type>all</object-type>
|
||||
<effects-menu>
|
||||
<submenu name="Ink/Stitch">
|
||||
<submenu name="{% trans %}Satin Tools{% endtrans %}" />
|
||||
</submenu>
|
||||
</effects-menu>
|
||||
</effect>
|
||||
<script>
|
||||
{{ command_tag | safe }}
|
||||
</script>
|
||||
</inkscape-extension>
|
Ładowanie…
Reference in New Issue