kopia lustrzana https://github.com/inkstitch/inkstitch
apply clip to stroke (#2283)
rodzic
9d5cc6013e
commit
c799b798bc
|
@ -23,6 +23,7 @@ from ..stitches import (auto_fill, circular_fill, contour_fill, guided_fill,
|
|||
legacy_fill)
|
||||
from ..stitches.meander_fill import meander_fill
|
||||
from ..svg import PIXELS_PER_MM, get_node_transform
|
||||
from ..svg.clip import get_clip_path
|
||||
from ..svg.tags import INKSCAPE_LABEL
|
||||
from ..utils import cache, version
|
||||
from ..utils.param import ParamOption
|
||||
|
@ -571,12 +572,9 @@ class FillStitch(EmbroideryElement):
|
|||
if self.node.clip is None:
|
||||
return self.original_shape
|
||||
|
||||
from .element import EmbroideryElement
|
||||
clip_element = EmbroideryElement(self.node.clip)
|
||||
clip_element.paths.sort(key=lambda point_list: shgeo.Polygon(point_list).area, reverse=True)
|
||||
polygon = shgeo.MultiPolygon([(clip_element.paths[0], clip_element.paths[1:])])
|
||||
clip_path = get_clip_path(self.node)
|
||||
try:
|
||||
intersection = polygon.intersection(self.original_shape)
|
||||
intersection = clip_path.intersection(self.original_shape)
|
||||
except TopologicalError:
|
||||
return self.original_shape
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
from math import ceil
|
||||
|
||||
import shapely.geometry
|
||||
import shapely.geometry as shgeo
|
||||
from inkex import Transform
|
||||
|
||||
from ..i18n import _
|
||||
|
@ -18,7 +18,9 @@ from ..threads import ThreadColor
|
|||
from ..utils import Point, cache
|
||||
from ..utils.param import ParamOption
|
||||
from .element import EmbroideryElement, param
|
||||
from ..svg.clip import get_clip_path
|
||||
from .validation import ValidationWarning
|
||||
from shapely.errors import TopologicalError
|
||||
|
||||
|
||||
class MultipleGuideLineWarning(ValidationWarning):
|
||||
|
@ -349,6 +351,7 @@ class Stroke(EmbroideryElement):
|
|||
def paths(self):
|
||||
path = self.parse_path()
|
||||
flattened = self.flatten(path)
|
||||
flattened = self._get_clipped_path(flattened)
|
||||
|
||||
# manipulate invalid path
|
||||
if len(flattened[0]) == 1:
|
||||
|
@ -366,8 +369,32 @@ class Stroke(EmbroideryElement):
|
|||
|
||||
@cache
|
||||
def as_multi_line_string(self):
|
||||
line_strings = [shapely.geometry.LineString(path) for path in self.paths]
|
||||
return shapely.geometry.MultiLineString(line_strings)
|
||||
line_strings = [shgeo.LineString(path) for path in self.paths]
|
||||
return shgeo.MultiLineString(line_strings)
|
||||
|
||||
def _get_clipped_path(self, paths):
|
||||
if self.node.clip is None:
|
||||
return paths
|
||||
|
||||
clip_path = get_clip_path(self.node)
|
||||
# path to linestrings
|
||||
line_strings = [shgeo.LineString(path) for path in paths]
|
||||
try:
|
||||
intersection = clip_path.intersection(shgeo.MultiLineString(line_strings))
|
||||
except TopologicalError:
|
||||
return paths
|
||||
|
||||
coords = []
|
||||
if intersection.is_empty:
|
||||
return paths
|
||||
elif isinstance(intersection, shgeo.MultiLineString):
|
||||
for c in [intersection for intersection in intersection.geoms if isinstance(intersection, shgeo.LineString)]:
|
||||
coords.append(c.coords)
|
||||
elif isinstance(intersection, shgeo.LineString):
|
||||
coords.append(intersection.coords)
|
||||
else:
|
||||
return paths
|
||||
return coords
|
||||
|
||||
def get_ripple_target(self):
|
||||
command = self.get_command('ripple_target')
|
||||
|
@ -431,7 +458,7 @@ class Stroke(EmbroideryElement):
|
|||
# apply max distances
|
||||
max_len_path = [path[0]]
|
||||
for points in zip(path[:-1], path[1:]):
|
||||
line = shapely.geometry.LineString(points)
|
||||
line = shgeo.LineString(points)
|
||||
dist = line.length
|
||||
if dist > self.max_stitch_length:
|
||||
num_subsections = ceil(dist / self.max_stitch_length)
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
# Authors: see git history
|
||||
#
|
||||
# Copyright (c) 2023 Authors
|
||||
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
|
||||
|
||||
from shapely.geometry import MultiPolygon, Polygon
|
||||
|
||||
from ..elements import EmbroideryElement
|
||||
|
||||
|
||||
def get_clip_path(node):
|
||||
# get clip and apply node transform
|
||||
clip = node.clip
|
||||
transform = node.composed_transform()
|
||||
clip.transform = transform
|
||||
clip_element = EmbroideryElement(clip)
|
||||
clip_element.paths.sort(key=lambda point_list: Polygon(point_list).area, reverse=True)
|
||||
return MultiPolygon([(clip_element.paths[0], clip_element.paths[1:])])
|
Ładowanie…
Reference in New Issue