kopia lustrzana https://github.com/inkstitch/inkstitch
add tiles
rodzic
8cead6e3d9
commit
b76146aa91
|
@ -0,0 +1,136 @@
|
|||
import inkex
|
||||
from math import ceil, floor
|
||||
from networkx import Graph
|
||||
import os
|
||||
from shapely.geometry import LineString
|
||||
from shapely.prepared import prep
|
||||
|
||||
from .svg import apply_transforms
|
||||
from .utils import get_bundled_dir, guess_inkscape_config_path, Point
|
||||
from random import random
|
||||
|
||||
|
||||
class Tile:
|
||||
def __init__(self, path):
|
||||
self._load_tile(path)
|
||||
|
||||
def _load_tile(self, tile_path):
|
||||
tile_svg = inkex.load_svg(tile_path)
|
||||
self.name = self._get_name(tile_path)
|
||||
self._load_paths(tile_svg)
|
||||
self._load_dimensions(tile_svg)
|
||||
self._load_buffer_size(tile_svg)
|
||||
self._load_parallelogram(tile_svg)
|
||||
|
||||
def __repr__(self):
|
||||
return f"Tile({self.name}, {self.shift0}, {self.shift1})"
|
||||
|
||||
__str__ = __repr__
|
||||
|
||||
def _get_name(self, tile_path):
|
||||
return os.path.splitext(os.path.basename(tile_path))[0]
|
||||
|
||||
def _load_paths(self, tile_svg):
|
||||
path_elements = tile_svg.findall('.//svg:path', namespaces=inkex.NSS)
|
||||
self.tile = self._path_elements_to_line_strings(path_elements)
|
||||
# self.center, ignore, ignore = self._get_center_and_dimensions(self.tile)
|
||||
|
||||
def _load_dimensions(self, tile_svg):
|
||||
svg_element = tile_svg.getroot()
|
||||
self.width = svg_element.viewport_width
|
||||
self.height = svg_element.viewport_height
|
||||
|
||||
def _load_buffer_size(self, tile_svg):
|
||||
circle_elements = tile_svg.findall('.//svg:circle', namespaces=inkex.NSS)
|
||||
if circle_elements:
|
||||
self.buffer_size = circle_elements[0].radius
|
||||
else:
|
||||
self.buffer_size = 0
|
||||
|
||||
def _load_parallelogram(self, tile_svg):
|
||||
parallelogram_elements = tile_svg.findall(".//svg:*[@class='para']", namespaces=inkex.NSS)
|
||||
if parallelogram_elements:
|
||||
path_element = parallelogram_elements[0]
|
||||
path = apply_transforms(path_element.get_path(), path_element)
|
||||
subpaths = path.to_superpath()
|
||||
subpath = subpaths[0]
|
||||
points = [Point.from_tuple(p[1]) for p in subpath]
|
||||
self.shift0 = points[1] - points[0]
|
||||
self.shift1 = points[2] - points[1]
|
||||
else:
|
||||
self.shift0 = Point(self.width, 0)
|
||||
self.shift1 = Point(0, self.height)
|
||||
|
||||
def _path_elements_to_line_strings(self, path_elements):
|
||||
lines = []
|
||||
for path_element in path_elements:
|
||||
path = apply_transforms(path_element.get_path(), path_element)
|
||||
for subpath in path.to_superpath():
|
||||
# We only care about the endpoints of each subpath. They're
|
||||
# supposed to be simple line segments.
|
||||
lines.append([Point.from_tuple(subpath[0][1]), Point.from_tuple(subpath[-1][1])])
|
||||
|
||||
return lines
|
||||
|
||||
def _get_center_and_dimensions(self, shape):
|
||||
min_x, min_y, max_x, max_y = shape.bounds
|
||||
center = Point((max_x + min_x) / 2, (max_y + min_y) / 2)
|
||||
width = max_x - min_x
|
||||
height = max_y - min_y
|
||||
|
||||
return center, width, height
|
||||
|
||||
def translate_tile(self, shift):
|
||||
translated_tile = []
|
||||
|
||||
for start, end in self.tile:
|
||||
start += shift
|
||||
end += shift
|
||||
translated_tile.append((start.as_int().as_tuple(), end.as_int().as_tuple()))
|
||||
|
||||
return translated_tile
|
||||
|
||||
def to_graph(self, shape, only_inside=True, pad=True):
|
||||
"""Apply this tile to a shape, repeating as necessary.
|
||||
|
||||
Return value:
|
||||
networkx.Graph with edges corresponding to lines in the pattern.
|
||||
Each edge has an attribute 'line_string' with the LineString
|
||||
representation of this edge.
|
||||
"""
|
||||
shape_center, shape_width, shape_height = self._get_center_and_dimensions(shape)
|
||||
shape_diagonal = (shape_width ** 2 + shape_height ** 2) ** 0.5
|
||||
graph = Graph()
|
||||
|
||||
if pad:
|
||||
shape = shape.buffer(-self.buffer_size)
|
||||
|
||||
prepared_shape = prep(shape)
|
||||
|
||||
tiles0 = ceil(shape_diagonal / self.shift0.length()) + 2
|
||||
tiles1 = ceil(shape_diagonal / self.shift1.length()) + 2
|
||||
for repeat0 in range(floor(-tiles0 / 2), ceil(tiles0 / 2)):
|
||||
for repeat1 in range(floor(-tiles1 / 2), ceil(tiles1 / 2)):
|
||||
shift0 = repeat0 * self.shift0 + shape_center
|
||||
shift1 = repeat1 * self.shift1 + shape_center
|
||||
this_tile = self.translate_tile(shift0 + shift1)
|
||||
for line in this_tile:
|
||||
line_string = LineString(line)
|
||||
if not only_inside or prepared_shape.contains(line_string):
|
||||
graph.add_edge(line[0], line[1], line_string=line_string, weight=random() + 0.1)
|
||||
|
||||
return graph
|
||||
|
||||
|
||||
def all_tile_paths():
|
||||
return [os.path.join(guess_inkscape_config_path(), 'tiles'),
|
||||
get_bundled_dir('tiles')]
|
||||
|
||||
|
||||
def all_tiles():
|
||||
for tile_dir in all_tile_paths():
|
||||
try:
|
||||
for tile_file in sorted(os.listdir(tile_dir)):
|
||||
yield Tile(os.path.join(tile_dir, tile_file))
|
||||
except FileNotFoundError:
|
||||
pass
|
|
@ -0,0 +1,119 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="15mm"
|
||||
height="15mm"
|
||||
viewBox="0 0 56.692914 56.692914"
|
||||
id="svg8375"
|
||||
version="1.1"
|
||||
inkscape:version="1.2 (1:1.2.1+202207142221+cd75a1ee6d)"
|
||||
sodipodi:docname="diamond_square.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs8377" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="6.5412668"
|
||||
inkscape:cx="45.021861"
|
||||
inkscape:cy="42.499413"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="mm"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="705"
|
||||
inkscape:window-x="-4"
|
||||
inkscape:window-y="-4"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<metadata
|
||||
id="metadata8380">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
style="fill:#000000;stroke:#30ff00;stroke-width:1.13386;stop-color:#000000"
|
||||
d="M 0,0 H 18.897638"
|
||||
id="path315"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:#000000;stroke:#30ff00;stroke-width:1.13386;stop-color:#000000"
|
||||
d="M 0,18.897638 H 18.897638"
|
||||
id="path315-3"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:#000000;stroke:#30ff00;stroke-width:1.13386;stop-color:#000000"
|
||||
d="M 18.897638,0 V 18.897638"
|
||||
id="path1017"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:#000000;stroke:#30ff00;stroke-width:1.13386;stop-color:#000000"
|
||||
d="M 0,0 V 18.897638"
|
||||
id="path1095"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:#000000;stroke:#30ff00;stroke-width:1.13386;stop-color:#000000"
|
||||
d="M 28.346457,28.346457 H 47.244095"
|
||||
id="path315-6"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:#000000;stroke:#30ff00;stroke-width:1.13386;stop-color:#000000"
|
||||
d="M 28.346457,47.244095 H 47.244095"
|
||||
id="path315-3-7"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:#000000;stroke:#30ff00;stroke-width:1.13386;stop-color:#000000"
|
||||
d="M 47.244095,28.346457 V 47.244095"
|
||||
id="path1017-5"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:#000000;stroke:#30ff00;stroke-width:1.13386;stop-color:#000000"
|
||||
d="M 28.346457,28.346457 V 47.244095"
|
||||
id="path1095-3"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:#000000;stroke:#30ff00;stroke-width:1.13386;stop-color:#000000"
|
||||
d="m 18.897638,18.897638 9.448819,9.448819"
|
||||
id="path1097"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:#000000;stroke:#30ff00;stroke-width:1.13386;stop-color:#000000"
|
||||
d="m 28.346457,47.244095 -9.448819,9.448819"
|
||||
id="path1192"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:#000000;stroke:#30ff00;stroke-width:1.13386;stop-color:#000000"
|
||||
d="m 47.244095,47.244095 9.448819,9.448819"
|
||||
id="path1539"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:#000000;stroke:#30ff00;stroke-width:1.13386;stop-color:#000000"
|
||||
d="m 47.244095,28.346457 9.448819,-9.448819"
|
||||
id="path1541"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
</svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 3.9 KiB |
|
@ -0,0 +1,116 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="30mm"
|
||||
height="34.6410162mm"
|
||||
viewBox="0 0 113.38582677 130.9266754"
|
||||
id="svg8375"
|
||||
version="1.1"
|
||||
inkscape:version="1.2 (1:1.2.1+202207142221+cd75a1ee6d)"
|
||||
sodipodi:docname="hexagon.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs8377" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.682637"
|
||||
inkscape:cx="40.562155"
|
||||
inkscape:cy="63.526845"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="mm"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="705"
|
||||
inkscape:window-x="-4"
|
||||
inkscape:window-y="-4"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<metadata
|
||||
id="metadata8380">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(43.621862,47.396329)">
|
||||
<path
|
||||
style="display:inline;vector-effect:none;fill:none;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.03832"
|
||||
d="M -24.724225,18.068867 -43.621862,-14.665621"
|
||||
id="path463" />
|
||||
<path
|
||||
style="display:inline;vector-effect:none;fill:none;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.03832"
|
||||
d="M 13.07105,18.068867 H -24.724225"
|
||||
id="path461" />
|
||||
<path
|
||||
style="display:inline;vector-effect:none;fill:none;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.03832"
|
||||
d="M 31.968688,-14.665621 13.07105,18.068867"
|
||||
id="path58963" />
|
||||
<path
|
||||
style="display:inline;vector-effect:none;fill:none;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.03832"
|
||||
d="m -24.724225,-47.396329 -18.897637,32.730708"
|
||||
id="path457" />
|
||||
<path
|
||||
style="display:inline;vector-effect:none;fill:none;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.03832"
|
||||
d="M 13.07105,-47.396329 H -24.724225"
|
||||
id="path455" />
|
||||
<path
|
||||
style="display:inline;vector-effect:none;fill:none;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.03832"
|
||||
d="M 31.968688,-14.665621 13.07105,-47.396329"
|
||||
id="path453"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="display:inline;vector-effect:none;fill:none;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.03832"
|
||||
d="M 69.763962,-14.665621 H 31.968688"
|
||||
id="path58961"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="display:inline;vector-effect:none;fill:none;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.03832"
|
||||
d="M 31.968688,50.799575 H 69.763962"
|
||||
id="path449" />
|
||||
<path
|
||||
style="display:inline;vector-effect:none;fill:none;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.03832"
|
||||
d="M 13.07105,18.068867 31.968688,50.799575"
|
||||
id="path58542" />
|
||||
<path
|
||||
style="display:inline;vector-effect:none;fill:none;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.03832"
|
||||
d="m -43.621862,50.799575 18.897637,32.730707"
|
||||
id="path445" />
|
||||
<path
|
||||
style="display:inline;vector-effect:none;fill:none;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.03832"
|
||||
d="M -24.724225,18.068867 -43.621862,50.799575"
|
||||
id="path58987" />
|
||||
<path
|
||||
style="display:inline;vector-effect:none;fill:none;fill-rule:evenodd;stroke:#0000ff;stroke-width:1.03832"
|
||||
d="M 13.07105,83.530282 31.968688,50.799575"
|
||||
id="path58981" />
|
||||
<circle
|
||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ff0000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path1901"
|
||||
cx="-24.811083"
|
||||
cy="-47.329594"
|
||||
r="18.897638" />
|
||||
</g>
|
||||
</svg>
|
Po Szerokość: | Wysokość: | Rozmiar: 4.4 KiB |
Ładowanie…
Reference in New Issue