summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/debug.py46
-rw-r--r--lib/stitches/meander_fill.py9
2 files changed, 49 insertions, 6 deletions
diff --git a/lib/debug.py b/lib/debug.py
index 94d32cea..4751e6af 100644
--- a/lib/debug.py
+++ b/lib/debug.py
@@ -21,12 +21,46 @@ from .svg.tags import INKSCAPE_GROUPMODE, INKSCAPE_LABEL
def check_enabled(func):
def decorated(self, *args, **kwargs):
if self.enabled:
- func(self, *args, **kwargs)
+ return func(self, *args, **kwargs)
+
+ return decorated
+
+
+def _unwrap(arg):
+ if callable(arg):
+ return arg()
+ else:
+ return arg
+
+
+def unwrap_arguments(func):
+ def decorated(self, *args, **kwargs):
+ unwrapped_args = [_unwrap(arg) for arg in args]
+ unwrapped_kwargs = {name: _unwrap(value) for name, value in kwargs.items()}
+
+ return func(self, *unwrapped_args, **unwrapped_kwargs)
return decorated
class Debug(object):
+ """Tools to help debug Ink/Stitch
+
+ This class contains methods to log strings and SVG elements. Strings are
+ logged to debug.log, and SVG elements are stored in debug.svg to aid in
+ debugging stitch algorithms.
+
+ All functionality is gated by self.enabled. If debugging is not enabled,
+ then debug calls will consume very few resources. Any method argument
+ can be a callable, in which case it is called and the return value is
+ logged instead. This way one can log potentially expensive expressions
+ by wrapping them in a lambda:
+
+ debug.log(lambda: some_expensive_function(some_argument))
+
+ The lambda is only called if debugging is enabled.
+ """
+
def __init__(self):
self.enabled = False
self.last_log_time = None
@@ -145,6 +179,7 @@ class Debug(object):
tree.write(debug_svg)
@check_enabled
+ @unwrap_arguments
def add_layer(self, name="Debug"):
layer = etree.Element("g", {
INKSCAPE_GROUPMODE: "layer",
@@ -155,6 +190,7 @@ class Debug(object):
self.current_layer = layer
@check_enabled
+ @unwrap_arguments
def open_group(self, name="Group"):
group = etree.Element("g", {
INKSCAPE_LABEL: name
@@ -164,11 +200,13 @@ class Debug(object):
self.group_stack.append(group)
@check_enabled
+ @unwrap_arguments
def close_group(self):
if self.group_stack:
self.group_stack.pop()
@check_enabled
+ @unwrap_arguments
def log(self, message, *args):
if self.last_log_time:
message = "(+%s) %s" % (datetime.now() - self.last_log_time, message)
@@ -201,6 +239,7 @@ class Debug(object):
return decorated
@check_enabled
+ @unwrap_arguments
def log_svg_element(self, element):
if self.current_layer is None:
self.add_layer()
@@ -211,11 +250,13 @@ class Debug(object):
self.current_layer.append(element)
@check_enabled
+ @unwrap_arguments
def log_line_string(self, line_string, name=None, color=None):
"""Add a Shapely LineString to the SVG log."""
self.log_line_strings([line_string], name, color)
@check_enabled
+ @unwrap_arguments
def log_line_strings(self, line_strings, name=None, color=None):
path = line_strings_to_path(line_strings)
path.set('style', str(inkex.Style({"stroke": color or "#000000", "stroke-width": "0.3", "fill": None})))
@@ -226,6 +267,7 @@ class Debug(object):
self.log_svg_element(path)
@check_enabled
+ @unwrap_arguments
def log_line(self, start, end, name="line", color=None):
self.log_svg_element(etree.Element("path", {
"d": "M%s,%s %s,%s" % (start + end),
@@ -234,6 +276,7 @@ class Debug(object):
}))
@check_enabled
+ @unwrap_arguments
def log_point(self, point, name="point", color=None):
self.log_svg_element(etree.Element("circle", {
"cx": str(point.x),
@@ -243,6 +286,7 @@ class Debug(object):
}))
@check_enabled
+ @unwrap_arguments
def log_graph(self, graph, name="Graph", color=None):
d = ""
diff --git a/lib/stitches/meander_fill.py b/lib/stitches/meander_fill.py
index 81efa398..6b3df0e3 100644
--- a/lib/stitches/meander_fill.py
+++ b/lib/stitches/meander_fill.py
@@ -7,7 +7,7 @@ from .. import tiles
from ..debug import debug
from ..stitch_plan import Stitch
from ..utils import smooth_path
-from ..utils.geometry import Point as InkStitchPoint
+from ..utils.geometry import Point as InkStitchPoint, ensure_geometry_collection
from ..utils.list import poprandom
from ..utils.prng import iter_uniform_floats
@@ -20,11 +20,10 @@ def meander_fill(fill, shape, shape_index, starting_point, ending_point):
debug.log(f"tile name: {tile.name}")
- # from ..utils.geometry import ensure_geometry_collection
- # debug.log_line_strings(ensure_geometry_collection(shape.boundary).geoms, 'Meander shape')
+ debug.log_line_strings(lambda: ensure_geometry_collection(shape.boundary).geoms, 'Meander shape')
graph = tile.to_graph(shape, fill.meander_scale, fill.meander_padding)
- # debug.log_graph(graph, 'Meander graph')
- # debug.log(f"graph connected? {nx.is_connected(graph)}")
+ debug.log_graph(graph, 'Meander graph')
+ debug.log(lambda: f"graph connected? {nx.is_connected(graph)}")
start, end = find_starting_and_ending_nodes(graph, shape, starting_point, ending_point)
rng = iter_uniform_floats(fill.random_seed, 'meander-fill', shape_index)