add lambda unwrapping to debug

pull/1803/head
Lex Neva 2023-01-28 22:09:34 -05:00
rodzic 575fa98c66
commit 5a95e1d004
2 zmienionych plików z 49 dodań i 6 usunięć

Wyświetl plik

@ -21,12 +21,46 @@ from .svg.tags import INKSCAPE_GROUPMODE, INKSCAPE_LABEL
def check_enabled(func): def check_enabled(func):
def decorated(self, *args, **kwargs): def decorated(self, *args, **kwargs):
if self.enabled: 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 return decorated
class Debug(object): 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): def __init__(self):
self.enabled = False self.enabled = False
self.last_log_time = None self.last_log_time = None
@ -145,6 +179,7 @@ class Debug(object):
tree.write(debug_svg) tree.write(debug_svg)
@check_enabled @check_enabled
@unwrap_arguments
def add_layer(self, name="Debug"): def add_layer(self, name="Debug"):
layer = etree.Element("g", { layer = etree.Element("g", {
INKSCAPE_GROUPMODE: "layer", INKSCAPE_GROUPMODE: "layer",
@ -155,6 +190,7 @@ class Debug(object):
self.current_layer = layer self.current_layer = layer
@check_enabled @check_enabled
@unwrap_arguments
def open_group(self, name="Group"): def open_group(self, name="Group"):
group = etree.Element("g", { group = etree.Element("g", {
INKSCAPE_LABEL: name INKSCAPE_LABEL: name
@ -164,11 +200,13 @@ class Debug(object):
self.group_stack.append(group) self.group_stack.append(group)
@check_enabled @check_enabled
@unwrap_arguments
def close_group(self): def close_group(self):
if self.group_stack: if self.group_stack:
self.group_stack.pop() self.group_stack.pop()
@check_enabled @check_enabled
@unwrap_arguments
def log(self, message, *args): def log(self, message, *args):
if self.last_log_time: if self.last_log_time:
message = "(+%s) %s" % (datetime.now() - self.last_log_time, message) message = "(+%s) %s" % (datetime.now() - self.last_log_time, message)
@ -201,6 +239,7 @@ class Debug(object):
return decorated return decorated
@check_enabled @check_enabled
@unwrap_arguments
def log_svg_element(self, element): def log_svg_element(self, element):
if self.current_layer is None: if self.current_layer is None:
self.add_layer() self.add_layer()
@ -211,11 +250,13 @@ class Debug(object):
self.current_layer.append(element) self.current_layer.append(element)
@check_enabled @check_enabled
@unwrap_arguments
def log_line_string(self, line_string, name=None, color=None): def log_line_string(self, line_string, name=None, color=None):
"""Add a Shapely LineString to the SVG log.""" """Add a Shapely LineString to the SVG log."""
self.log_line_strings([line_string], name, color) self.log_line_strings([line_string], name, color)
@check_enabled @check_enabled
@unwrap_arguments
def log_line_strings(self, line_strings, name=None, color=None): def log_line_strings(self, line_strings, name=None, color=None):
path = line_strings_to_path(line_strings) path = line_strings_to_path(line_strings)
path.set('style', str(inkex.Style({"stroke": color or "#000000", "stroke-width": "0.3", "fill": None}))) 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) self.log_svg_element(path)
@check_enabled @check_enabled
@unwrap_arguments
def log_line(self, start, end, name="line", color=None): def log_line(self, start, end, name="line", color=None):
self.log_svg_element(etree.Element("path", { self.log_svg_element(etree.Element("path", {
"d": "M%s,%s %s,%s" % (start + end), "d": "M%s,%s %s,%s" % (start + end),
@ -234,6 +276,7 @@ class Debug(object):
})) }))
@check_enabled @check_enabled
@unwrap_arguments
def log_point(self, point, name="point", color=None): def log_point(self, point, name="point", color=None):
self.log_svg_element(etree.Element("circle", { self.log_svg_element(etree.Element("circle", {
"cx": str(point.x), "cx": str(point.x),
@ -243,6 +286,7 @@ class Debug(object):
})) }))
@check_enabled @check_enabled
@unwrap_arguments
def log_graph(self, graph, name="Graph", color=None): def log_graph(self, graph, name="Graph", color=None):
d = "" d = ""

Wyświetl plik

@ -7,7 +7,7 @@ from .. import tiles
from ..debug import debug from ..debug import debug
from ..stitch_plan import Stitch from ..stitch_plan import Stitch
from ..utils import smooth_path 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.list import poprandom
from ..utils.prng import iter_uniform_floats 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}") debug.log(f"tile name: {tile.name}")
# from ..utils.geometry import ensure_geometry_collection debug.log_line_strings(lambda: ensure_geometry_collection(shape.boundary).geoms, 'Meander shape')
# debug.log_line_strings(ensure_geometry_collection(shape.boundary).geoms, 'Meander shape')
graph = tile.to_graph(shape, fill.meander_scale, fill.meander_padding) graph = tile.to_graph(shape, fill.meander_scale, fill.meander_padding)
# debug.log_graph(graph, 'Meander graph') debug.log_graph(graph, 'Meander graph')
# debug.log(f"graph connected? {nx.is_connected(graph)}") debug.log(lambda: f"graph connected? {nx.is_connected(graph)}")
start, end = find_starting_and_ending_nodes(graph, shape, starting_point, ending_point) start, end = find_starting_and_ending_nodes(graph, shape, starting_point, ending_point)
rng = iter_uniform_floats(fill.random_seed, 'meander-fill', shape_index) rng = iter_uniform_floats(fill.random_seed, 'meander-fill', shape_index)