yaqwsx / PcbDraw

Convert your KiCAD board into a nicely looking 2D drawing suitable for pinout diagrams
MIT License
1.13k stars 90 forks source link

PcbDraw fails on negative coordinates #53

Closed aklomp closed 3 years ago

aklomp commented 4 years ago

Found and fixed this issue when trying to render a board that is partly drawn using negative coordinates.

I'm relatively new to KiCAD, and couldn't figure out how to move the coordinate origin to the center of the workspace. I needed to draw a symmetrical board and didn't want to complicate the math, so my hack was to draw my board relative to the document origin in the top left. The resulting board uses negative coordinates for half of its geometry. Running PcbNew (version 0.6.0, from the Arch repo) on this board produces the following error trace:

Traceback (most recent call last):
  File "/usr/bin/pcbdraw", line 33, in <module>
    sys.exit(load_entry_point('PcbDraw==0.6.0', 'console_scripts', 'pcbdraw')())
  File "/usr/lib/python3.8/site-packages/pcbdraw/pcbdraw.py", line 792, in main
    board_cont.append(get_board_substrate(board, style, not args.no_drillholes, args.back))
  File "/usr/lib/python3.8/site-packages/pcbdraw/pcbdraw.py", line 444, in get_board_substrate
    process(container, f, os.path.join(tmp, svg_file), colors, boardsize)
  File "/usr/lib/python3.8/site-packages/pcbdraw/pcbdraw.py", line 328, in process_board_substrate_base
    clipPath.append(get_board_polygon(extract_svg_content(read_svg_unique(source))))
  File "/usr/lib/python3.8/site-packages/pcbdraw/pcbdraw.py", line 276, in get_board_polygon
    elements.append(SvgPathItem(svg_element.attrib["d"]))
  File "/usr/lib/python3.8/site-packages/pcbdraw/pcbdraw.py", line 50, in __init__
    raise SyntaxError("Only paths with absolute position are supported")
SyntaxError: Only paths with absolute position are supported

I traced this down to the regexp in class SvgPathItem that tries to split the given SVG path. It doesn't handle the following input correctly:

M-6496.06 -6496.06 A2362.2 2362.2 0.0 0 0 -4133.86 -8858.27

The fix is trivial:

diff --git a/pcbdraw/pcbdraw.py b/pcbdraw/pcbdraw.py
index 843e8a9..ebdf9ae 100755
--- a/pcbdraw/pcbdraw.py
+++ b/pcbdraw/pcbdraw.py
@@ -45,7 +45,7 @@ float_re = r'([-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?)'

 class SvgPathItem:
     def __init__(self, path):
-        path = re.sub(r"([MLA])(\d+)", r"\1 \2", path)
+        path = re.sub(r"([MLA])(-?\d+)", r"\1 \2", path)
         path = re.split("[, ]", path)
         path = list(filter(lambda x: x, path))
         if path[0] != "M":

Now it works.

yaqwsx commented 3 years ago

Thanks, I added the change in 9a40720.

PS: Feel free to directly open a PR in the future.

aklomp commented 3 years ago

Thanks. The reason why I didn't make this a PR is because I hit this issue during my first time using this software, and didn't want to give the impression that I fully understood the effects of this change inside an unfamiliar codebase. I'll push a PR next time.