1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
from copy import deepcopy
from shapely.geometry import Polygon
import inkex
from ..elements import AutoFill, Fill
from ..i18n import _
from ..svg import get_correction_transform
from .base import InkstitchExtension
class BreakApart(InkstitchExtension):
def effect(self): # noqa: C901
if not self.get_elements():
return
if not self.selected:
inkex.errormsg(_("Please select one or more fill areas to break apart."))
return
for element in self.elements:
if not isinstance(element, AutoFill) and not isinstance(element, Fill):
continue
if len(element.paths) <= 1:
continue
polygons = []
multipolygons = []
holes = []
for path in element.paths:
polygons.append(Polygon(path))
# sort paths by size and convert to polygons
polygons.sort(key=lambda polygon: polygon.area, reverse=True)
for shape in polygons:
if shape in holes:
continue
polygon_list = [shape]
for other in polygons:
if shape != other and shape.contains(other) and other not in holes:
# check if "other" is inside a hole, before we add it to the list
if any(p.contains(other) for p in polygon_list[1:]):
continue
polygon_list.append(other)
holes.append(other)
multipolygons.append(polygon_list)
self.element_to_nodes(multipolygons, element)
def element_to_nodes(self, multipolygons, element):
for polygons in multipolygons:
el = deepcopy(element)
d = ""
for polygon in polygons:
# copy element and replace path
el.node.set('id', self.uniqueId(element.node.get('id') + "_"))
d += "M"
for x, y in polygon.exterior.coords:
d += "%s,%s " % (x, y)
d += " "
d += "Z"
el.node.set('d', d)
el.node.set('transform', get_correction_transform(element.node))
element.node.getparent().insert(0, el.node)
element.node.getparent().remove(element.node)
|