whitequark / kicad-boardview

KiCAD to Boardview exporter reads KiCAD PCB layout files and writes ASCII Boardview files
BSD Zero Clause License
152 stars 23 forks source link

Failing at GetBoardPolygonOutlines(outlines, "") with KiCad 6 #8

Open TrooperN opened 2 years ago

TrooperN commented 2 years ago

When trying to convert a KiCad 6 kicad_pcb to brd, the conversion fails on line 45, in convert, pcb.GetBoardPolygonOutlines(outlines, "").

set-soft commented 2 years ago

Hi @TrooperN and @whitequark ! I don't think this is a bug, not at least in this project. Anyways, I was adapting the code in KiBot and here is the patch I'm comitting:

diff --git a/kibot/out_boardview.py b/kibot/out_boardview.py
index 54c2e9d..55cdc8e 100644
--- a/kibot/out_boardview.py
+++ b/kibot/out_boardview.py
@@ -48,9 +48,14 @@ def pad_sort_key(name):
 def convert(pcb, brd):
     # Board outline
     outlines = SHAPE_POLY_SET()
-    pcb.GetBoardPolygonOutlines(outlines, "")
-    outline = outlines.Outline(0)
-    outline_points = [outline.Point(n) for n in range(outline.PointCount())]
+    if GS.ki5():
+        pcb.GetBoardPolygonOutlines(outlines, "")
+        outline = outlines.Outline(0)
+        outline_points = [outline.Point(n) for n in range(outline.PointCount())]
+    else:
+        pcb.GetBoardPolygonOutlines(outlines)
+        outline = outlines.Outline(0)
+        outline_points = [outline.GetPoint(n) for n in range(outline.GetPointCount())]
     outline_maxx = max(map(lambda p: p.x, outline_points))
     outline_maxy = max(map(lambda p: p.y, outline_points))

@@ -77,18 +82,18 @@ def convert(pcb, brd):
     brd.write("NETS: {count}\n"
               .format(count=len(net_items)))
     for net_item in net_items:
+        code = net_item.GetNet() if GS.ki5() else net_item.GetNetCode()
         brd.write("{code} {name}\n"
-                  .format(code=net_item.GetNet(),
+                  .format(code=code,
                           name=net_item.GetNetname().replace(" ", u"\u00A0")))
     brd.write("\n")

     # Parts
-    module_list = pcb.GetModules()
+    module_list = GS.get_modules()
     modules = []
-    while module_list:
-        if not skip_module(module_list):
-            modules.append(module_list)
-        module_list = module_list.Next()
+    for m in module_list:
+        if not skip_module(m):
+            modules.append(m)

     brd.write("PARTS: {count}\n".format(count=len(modules)))
     pin_at = 0
@@ -106,14 +111,13 @@ def convert(pcb, brd):
     brd.write("\n")

     # Pins
-    module_list = pcb.GetModules()
+    module_list = GS.get_modules()
     pads = []
-    while module_list:
-        if not skip_module(module_list):
-            pads_list = module_list.PadsList()
+    for m in module_list:
+        if not skip_module(m):
+            pads_list = m.Pads()
             for pad in sorted(pads_list, key=lambda pad: pad_sort_key(pad.GetName())):
                 pads.append(pad)
-        module_list = module_list.Next()

     brd.write("PINS: {count}\n".format(count=len(pads)))
     for pad in pads:
@@ -126,14 +130,13 @@ def convert(pcb, brd):
     brd.write("\n")

     # Nails
-    module_list = pcb.GetModules()
+    module_list = GS.get_modules()
     testpoints = []
-    while module_list:
-        if not skip_module(module_list, tp=True):
-            pads_list = module_list.PadsList()
+    for m in module_list:
+        if not skip_module(m, tp=True):
+            pads_list = m.Pads()
             for pad in sorted(pads_list, key=lambda pad: pad_sort_key(pad.GetName())):
-                testpoints.append((module_list, pad))
-        module_list = module_list.Next()
+                testpoints.append((m, pad))

     brd.write("NAILS: {count}\n".format(count=len(testpoints)))
     for module, pad in testpoints:

The GS.ki5() returns true for KiCad 5 and GS.get_modules() is this:

    @staticmethod
    def get_modules():
        if GS.ki6():  # pragma: no cover (Ki6)
            return GS.board.GetFootprints()
        return GS.board.GetModules()

In a quick test it looks like this patch works for the glasgow board.

TrooperN commented 2 years ago

Hello!

I updated my pcbnew2boardview.py with these changes. Everything seems to be working now!

neosoyo commented 2 years ago

i'm trying to use the patch of @set-soft but still got error on skip_module function:

Traceback (most recent call last): File "/home/sbonb/git/kicad-boardview/pcbnew2boardview.py", line 158, in <module> main() File "/home/sbonb/git/kicad-boardview/pcbnew2boardview.py", line 154, in main convert(pcbnew.LoadBoard(args.kicad_pcb_file), args.brd_file) File "/home/sbonb/git/kicad-boardview/pcbnew2boardview.py", line 80, in convert if not skip_module(module_list): File "/home/sbonb/git/kicad-boardview/pcbnew2boardview.py", line 11, in skip_module refdes = module.GetReference() AttributeError: 'list' object has no attribute 'GetReference' seems to be a basic error but i can't figure out why...

TrooperN commented 2 years ago

This part:

 # Parts
    module_list = pcb.GetModules()
    modules = []
    while module_list:
        if not skip_module(module_list):
            modules.append(module_list)
        module_list = module_list.Next()

Needs to be changed to:

# Parts
    module_list = pcb.GetFootprints()
    modules = []
    for m in module_list:
        if not skip_module(m):
            modules.append(m)
neosoyo commented 2 years ago

got it! thanks, i really missed the subsequent alterations needed, this script is amazing! great work

this should be release as Kicad6 plugin package!

whitequark commented 8 months ago

this should be release as Kicad6 plugin package!

I don't know how to do this.

sabogalc commented 8 months ago

Idk how to publish KiCad add-ons either but would this help? https://dev-docs.kicad.org/en/addons/

whitequark commented 8 months ago

That does help, thanks.