pull/1254/head
Kaalleen 2021-06-30 14:05:13 +02:00
rodzic a152e1edea
commit 52d9ee6a6d
9 zmienionych plików z 91 dodań i 76 usunięć

Wyświetl plik

@ -9,10 +9,10 @@ from copy import deepcopy
import inkex import inkex
import tinycss2 import tinycss2
from inkex import bezier from inkex import bezier
from shapely import geometry as shgeo
from ..commands import find_commands from ..commands import find_commands
from ..i18n import _ from ..i18n import _
from ..patterns import apply_patterns
from ..svg import (PIXELS_PER_MM, apply_transforms, convert_length, from ..svg import (PIXELS_PER_MM, apply_transforms, convert_length,
get_node_transform) get_node_transform)
from ..svg.tags import (EMBROIDERABLE_TAGS, INKSCAPE_LABEL, INKSTITCH_ATTRIBS, from ..svg.tags import (EMBROIDERABLE_TAGS, INKSCAPE_LABEL, INKSTITCH_ATTRIBS,
@ -331,52 +331,6 @@ class EmbroideryElement(object):
else: else:
return None return None
@cache
def get_patterns(self):
xpath = "./parent::svg:g/*[contains(@style, 'marker-start:url(#inkstitch-pattern-marker)')]"
patterns = self.node.xpath(xpath, namespaces=inkex.NSS)
line_strings = []
for pattern in patterns:
if pattern.tag not in EMBROIDERABLE_TAGS:
continue
d = pattern.get_path()
path = inkex.paths.Path(d).to_superpath()
path = apply_transforms(path, pattern)
path = self.flatten(path)
lines = [shgeo.LineString(p) for p in path]
for line in lines:
line_strings.append(line)
return shgeo.MultiLineString(line_strings)
def _apply_patterns(self, patches):
patterns = self.get_patterns()
if not patterns:
return patches
patch_points = []
for patch in patches:
for i, stitch in enumerate(patch.stitches):
patch_points.append(stitch)
if i == len(patch.stitches) - 1:
continue
intersection_points = self._get_pattern_points(stitch, patch.stitches[i+1], patterns)
for point in intersection_points:
patch_points.append(point)
patch.stitches = patch_points
def _get_pattern_points(self, first, second, patterns):
points = []
for pattern in patterns:
intersection = shgeo.LineString([first, second]).intersection(pattern)
if isinstance(intersection, shgeo.Point):
points.append(Point(intersection.x, intersection.y))
if isinstance(intersection, shgeo.MultiPoint):
for point in intersection:
points.append(Point(point.x, point.y))
# sort points after their distance to left
points.sort(key=lambda point: point.distance(first))
return points
def strip_control_points(self, subpath): def strip_control_points(self, subpath):
return [point for control_before, point, control_after in subpath] return [point for control_before, point, control_after in subpath]
@ -409,7 +363,7 @@ class EmbroideryElement(object):
self.validate() self.validate()
patches = self.to_patches(last_patch) patches = self.to_patches(last_patch)
self._apply_patterns(patches) apply_patterns(patches, self.node)
for patch in patches: for patch in patches:
patch.tie_modus = self.ties patch.tie_modus = self.ties

Wyświetl plik

@ -6,7 +6,6 @@
import inkex import inkex
from ..i18n import _ from ..i18n import _
from ..svg.tags import EMBROIDERABLE_TAGS
from .element import EmbroideryElement from .element import EmbroideryElement
from .validation import ObjectTypeWarning from .validation import ObjectTypeWarning
@ -31,9 +30,3 @@ class PatternObject(EmbroideryElement):
def to_patches(self, last_patch): def to_patches(self, last_patch):
return [] return []
def is_pattern(node):
if node.tag not in EMBROIDERABLE_TAGS:
return False
return "marker-start:url(#inkstitch-pattern-marker)" in node.get('style', '')

Wyświetl plik

@ -4,6 +4,7 @@
# 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.
from ..commands import is_command from ..commands import is_command
from ..patterns import is_pattern
from ..svg.tags import (EMBROIDERABLE_TAGS, SVG_IMAGE_TAG, SVG_PATH_TAG, from ..svg.tags import (EMBROIDERABLE_TAGS, SVG_IMAGE_TAG, SVG_PATH_TAG,
SVG_POLYLINE_TAG, SVG_TEXT_TAG) SVG_POLYLINE_TAG, SVG_TEXT_TAG)
from .auto_fill import AutoFill from .auto_fill import AutoFill
@ -12,7 +13,7 @@ from .element import EmbroideryElement
from .empty_d_object import EmptyDObject from .empty_d_object import EmptyDObject
from .fill import Fill from .fill import Fill
from .image import ImageObject from .image import ImageObject
from .pattern import PatternObject, is_pattern from .pattern import PatternObject
from .polyline import Polyline from .polyline import Polyline
from .satin_column import SatinColumn from .satin_column import SatinColumn
from .stroke import Stroke from .stroke import Stroke

Wyświetl plik

@ -5,7 +5,6 @@
from lib.extensions.troubleshoot import Troubleshoot from lib.extensions.troubleshoot import Troubleshoot
from .apply_pattern import ApplyPattern
from .auto_satin import AutoSatin from .auto_satin import AutoSatin
from .break_apart import BreakApart from .break_apart import BreakApart
from .cleanup import Cleanup from .cleanup import Cleanup
@ -29,6 +28,7 @@ from .params import Params
from .print_pdf import Print from .print_pdf import Print
from .remove_embroidery_settings import RemoveEmbroiderySettings from .remove_embroidery_settings import RemoveEmbroiderySettings
from .reorder import Reorder from .reorder import Reorder
from .selection_to_pattern import SelectionToPattern
from .simulator import Simulator from .simulator import Simulator
from .stitch_plan_preview import StitchPlanPreview from .stitch_plan_preview import StitchPlanPreview
from .zip import Zip from .zip import Zip
@ -41,7 +41,7 @@ __all__ = extensions = [StitchPlanPreview,
Output, Output,
Zip, Zip,
Flip, Flip,
ApplyPattern, SelectionToPattern,
ObjectCommands, ObjectCommands,
LayerCommands, LayerCommands,
GlobalCommands, GlobalCommands,

Wyświetl plik

@ -15,8 +15,8 @@ from stringcase import snakecase
from ..commands import is_command, layer_commands from ..commands import is_command, layer_commands
from ..elements import EmbroideryElement, nodes_to_elements from ..elements import EmbroideryElement, nodes_to_elements
from ..elements.clone import is_clone from ..elements.clone import is_clone
from ..elements.pattern import is_pattern
from ..i18n import _ from ..i18n import _
from ..patterns import is_pattern
from ..svg import generate_unique_id from ..svg import generate_unique_id
from ..svg.tags import (CONNECTOR_TYPE, EMBROIDERABLE_TAGS, INKSCAPE_GROUPMODE, from ..svg.tags import (CONNECTOR_TYPE, EMBROIDERABLE_TAGS, INKSCAPE_GROUPMODE,
NOT_EMBROIDERABLE_TAGS, SVG_DEFS_TAG, SVG_GROUP_TAG) NOT_EMBROIDERABLE_TAGS, SVG_DEFS_TAG, SVG_GROUP_TAG)

Wyświetl plik

@ -11,8 +11,7 @@ from ..svg.tags import SVG_DEFS_TAG
from .base import InkstitchExtension from .base import InkstitchExtension
class ApplyPattern(InkstitchExtension): class SelectionToPattern(InkstitchExtension):
# This extension will mark selected
def effect(self): def effect(self):
if not self.get_elements(): if not self.get_elements():

66
lib/patterns.py 100644
Wyświetl plik

@ -0,0 +1,66 @@
# Authors: see git history
#
# Copyright (c) 2010 Authors
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
import inkex
from shapely import geometry as shgeo
from .svg import apply_transforms
from .svg.tags import EMBROIDERABLE_TAGS
from .utils import Point
def is_pattern(node):
if node.tag not in EMBROIDERABLE_TAGS:
return False
return "marker-start:url(#inkstitch-pattern-marker)" in node.get('style', '')
def apply_patterns(patches, node):
patterns = _get_patterns(node)
if not patterns:
return patches
patch_points = []
for patch in patches:
for i, stitch in enumerate(patch.stitches):
patch_points.append(stitch)
if i == len(patch.stitches) - 1:
continue
intersection_points = _get_pattern_points(stitch, patch.stitches[i+1], patterns)
for point in intersection_points:
patch_points.append(point)
patch.stitches = patch_points
def _get_patterns(node):
xpath = "./parent::svg:g/*[contains(@style, 'marker-start:url(#inkstitch-pattern-marker)')]"
patterns = node.xpath(xpath, namespaces=inkex.NSS)
line_strings = []
for pattern in patterns:
if pattern.tag not in EMBROIDERABLE_TAGS:
continue
d = pattern.get_path()
path = inkex.paths.Path(d).to_superpath()
path = apply_transforms(path, pattern)
inkex.bezier.cspsubdiv(path, 0.1)
path = [[point for control_before, point, control_after in subpath] for subpath in path]
lines = [shgeo.LineString(p) for p in path]
for line in lines:
line_strings.append(line)
return shgeo.MultiLineString(line_strings)
def _get_pattern_points(first, second, patterns):
points = []
for pattern in patterns:
intersection = shgeo.LineString([first, second]).intersection(pattern)
if isinstance(intersection, shgeo.Point):
points.append(Point(intersection.x, intersection.y))
if isinstance(intersection, shgeo.MultiPoint):
for point in intersection:
points.append(Point(point.x, point.y))
# sort points after their distance to left
points.sort(key=lambda point: point.distance(first))
return points

Wyświetl plik

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>{% trans %}Apply Pattern{% endtrans %}</name>
<id>org.inkstitch.apply_pattern.{{ locale }}</id>
<param name="extension" type="string" gui-hidden="true">apply_pattern</param>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu name="Ink/Stitch" />
</effects-menu>
</effect>
<script>
{{ command_tag | safe }}
</script>
</inkscape-extension>

Wyświetl plik

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>{% trans %}Selection to pattern{% endtrans %}</name>
<id>org.inkstitch.selection_to_pattern.{{ locale }}</id>
<param name="extension" type="string" gui-hidden="true">selection_to_pattern</param>
<effect>
<object-type>all</object-type>
<effects-menu>
<submenu name="Ink/Stitch">
<submenu name="{% trans %}Edit{% endtrans %}" />
</submenu>
</effects-menu>
</effect>
<script>
{{ command_tag | safe }}
</script>
</inkscape-extension>