kopia lustrzana https://github.com/inkstitch/inkstitch
add lambda unwrapping to debug
rodzic
575fa98c66
commit
5a95e1d004
46
lib/debug.py
46
lib/debug.py
|
|
@ -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 = ""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
Ładowanie…
Reference in New Issue