yaqwsx / KiKit

Automation tools for KiCAD
https://yaqwsx.github.io/KiKit
MIT License
1.54k stars 201 forks source link

Substrates added via appendSubstrate are not considered for buildPartitionLineFromBB #402

Open mqus opened 2 years ago

mqus commented 2 years ago

Prerequisites

KiKit version

kikit, version 1.0.5

KiCAD version

Version: (6.0.7), release build

Operating system

Archlinux

Description

I am panelizing multiple different pcbs via the python API. I have some smaller problems like adding the same pcb at different places (so the tabs should be different at some places) but apart from that everything went fine.

I now tried to add rails at the sides by simply adding another substrate via panel.appendSubstrate() after appending my boards and before generating the partition lines. But the substrate is not considered at all when generating the partition lines (as seen in the debug layer), which also leads to missing tabs on the sides (because kikit assumes that they are on the "outside"). I assume this is because the substrate is not appended to panel.substrates after adding it to the substrate polygon: https://github.com/yaqwsx/KiKit/blob/bdee246773f96285c39101dc450fec88a80cafff/kikit/panelize.py#L890-L898

(which is the list which is used to generate the partition lines). If I read https://github.com/yaqwsx/KiKit/blob/master/doc/understandingTabs.md right, then all substrates should be considered when generating the partition lines. The documentation of the method also mentions substrates, not boards.

To work around this, I also tried to use makeRailsLr but this method does not allow me to specify space between the rail and the boards, so it is a wrong candidate for me.

Steps to Reproduce

Download and extract the attached repro.zip and open the pcb in the folder panelize.

You can also generate it by calling main.py from within the panelize folder:

cd panelize
python main.py

As you may see, it is still a work-in-progress, the tabs do not align at some places and the rails are not complete at all. But the bug(?) should be visible. The problem is this rail/substrate: image

It does not have any partition line to its right and the main_board pcb should have tabs on the side facing it, but doesn't.

yaqwsx commented 2 years ago

The fact that substrates added via addSubstrate is actually correct. The partition line should be computed only between boards and it takes into account only board substrates.

When attaching rails or frame, the intended way is to pass boundarySubstrates to https://github.com/yaqwsx/KiKit/blob/bdee246773f96285c39101dc450fec88a80cafff/kikit/panelize.py#L1696

The boundary substrates should simulate a neighboring board, which is not there. The UI uses the following method to generate them: https://github.com/yaqwsx/KiKit/blob/bdee246773f96285c39101dc450fec88a80cafff/kikit/panelize_ui_impl.py#L382

The rails and framing methods expect that there are already all tabs generated (or half-tabs) and they simply attach rails or frame to the existing substrate.

mqus commented 2 years ago

But then its very confusing to call everything a substrate, when there are very different ones. I also can't simply add a wxRect to the buildPartitionLineFromBB boundarySubstrates, which is very odd. I don't even know which type I should enter there.

yaqwsx commented 2 years ago

A substrate is a piece of PCB in the context of KiKit. The substrate is represented by the Substrate class (which is just a thin wrapper around Shapely polygons adding some extra operations).

When you want to create a substrate from Shapely polygon, you can use the polygonToSubstrate method: https://github.com/yaqwsx/KiKit/blob/bdee246773f96285c39101dc450fec88a80cafff/kikit/panelize_ui_impl.py#L377

To create a rectangular Shapely polygon, you can use Shapely box method.

mqus commented 2 years ago

A substrate is a piece of PCB in the context of KiKit.

There is the substrate I can append (appendSubstrate) and then there are the substrates that are considered by buildPartitionLineFromBB, which you write above are only board substrates, but confusingly, the appended substrates (via the method) are part of the Panel.boardSubstrate attribute, but not of the Panel.substrates list. The documentation of buildPartitionLineFromBB states

Builds partition & backbone line from bounding boxes of the substrates. You can optionally pass extra substrates (e.g., for frame) [...]

which also makes no difference between those substrates or even says which kinds it respects. Something there is wrong, even if its just the documentation.

The https://github.com/yaqwsx/KiKit/blob/master/doc/understandingTabs.md page also talks about substrates, even if the autogeneration only considers boards (which would be a more fitting term imho).

The naming just does not add up.

yaqwsx commented 2 years ago

Thanks for the feedback, I really appreciate it. Indeed, we have a naming ambiguity. I tried to address it somewhat in the documentation. I plan to refactor it and add proper type annotations to the code.

Basically: we call every piece of a PCB/panel a substrate. Those are represented by the Substrate class. Often, if some operation (e.g., appendSubstrate) cares more about the shape than additional properties of substrates, it can also directly accept the shape in the form of Shapely polygon just to simplify things and avoid packing and unpacking.

The Panel class constructs a substrate of the whole panel - via appendBoard and appendSubstrate. The panel also keeps track of which parts of the substrate come from which source PCB (via keeping the source board substrates). This is needed for proper copper filling and, in the most recent version, for tab construction. Each source PCB substrate gets an associated partition line - a possibly open boundary of the area for which it is responsible. When tabs are generated, they are generated separately for each source PCB substrate up to the partition line.

The partition line can be open. That marks that no tabs should be constructed in this direction. This allows us to efficiently decide which tabs are needed and which are not (e.g., for PCB at the edge of the panel).