pcb-rnd knowledge pool


subcircuit: how does this clean things up today

subc2 by Tibor 'Igor2' Palinkas on 2017-06-29

Tags: insight, subc, subcircuit, layer, tree, model, data model, data

node source



Abstract: Explain how the internal data structure is being turned from a flat model into a tree model using subcircuits. Describe the new 'bound' layer model introduced for subcircuits.



Subcircuits use pcb_data_t to store their children objects. This is the same struct that pcb_board_t uses for a PCB board and the same struct that makes up a paste buffer.

Elements (footprints) on the other hand were designed to use custom structs. That is the reason for all the restrictions on what an element can be built of. These element-restrictions do not exist for subcircuits.

This helps cleaning up the broken internal data model of original pcb: there's only one way to make a new level of the data tree for holding drawing primitives, and it is pcb_data_t. This lets the code traverse the tree from the root toward the leaves.


Symmetrically, each object now properly references its parent. Today this lets the code:

This is another important step in cleaning up the broken internal data model we inherited.


Some exporters need to build a list of unique element references - that is, if the board uses 15 instances of 1206, the exporter would need to recognize that and store only one copy and 15 references. This is done with a special hashing algorithm that "reverse engineers" the elements and try to figure if two elements are really the same, even tho they are rotated.

With subcircuits, this won't be done in such a complicated, indirect way because subcircuits get an unique ID when they are born and copies share the same UID. The UID is "globally" unique; that means it's not only unique within a board or within a library or within an installation or system. If users share their subcircuit libs, the same 1206 got from the same lib will have the same UID on all copies and boards and it will be trivial to determine whether two subcircuits are really the same.

aux layer and vectors

Another crucial misfeature of elements is the lack of rotation and mirror information. That is, if the user places an element on a board and the element is rotated or moved to the other side, it is just modified in the data model as if it was the natural orientation of the element. In other words, looking at an element in the original geda/PCB model, it is impossible to reliably determine the rotation. All the pick&place exporters are just making educate guesses with a lot of limitations, e.g. only N*90 degree rotations can be detected properly.

In subcircuits there is a layer called 'aux', which contains line objects labelled with attributes. The aux layer doesn't turn into copper, silk, paste or mask, it's rather a documentation layer. The lines it hosts undergo all transformations the host subcircuit undergoes: if the parent is rotated, all lines are rotated. When a new subcircuit is created, a few line objects like the origin point and two lines (unity-vectors in X and Y directions) are automatically placed on the aux layer.

Whenever the rotation needs to be determined, the code can just look at what happened to these X and Y unity vectors knowing how they looked originally and calculates the rotation to a fraction of a degree. Without any heuristics or guesses.

How is it better than just storing the transformations:

bound layers

Paste buffers and subcircuits don't really have a layer stack, because they are board-independent. Paste buffers need to be able to copy random objects on random layers from one board to another, even if the boards have different layer stacks, in a sensible way. The original code (and current mainline code) has hardwired layer references in pcb_data_t, which means this is impossible; any paste-buffer copy will work properly only if the source and target boards have the same layer stack.

A sensible way to solve this problem is to remember layer binding patterns instead of specific fixed layers. A fixed layer reference is like "layer 4" and is always referring to the current layer stack. One board may have bottom silk as layer 4, while another board may have an internal copper layer or the outline layer as layer 4.

A layer binding pattern is something like a recipe on how to find the best match for a layer, e.g. "a top copper layer", or "the second internal copper layer counted from the top copper layer", or "a positively drawn mask layer on the top side". Subcircuits and buffers in pcb-rnd use such layer binding patterns. When a board object becomes part of a subcircuit or is copied into a paste buffer, the code abstracts the board specific layer binding into such a generic pattern. When the subcircuit or buffer is then copied back to a board, the code finds the best fit layer. This is called layer resolution. (The original layer binding patterns are also kept in subcircuits, so multiple abstractions and resolutions won't degrade the match pattern.)

on-screen indication of subc

Subcircuits are optionally indicated with a dashed rectangle at their bounding box and their origin diamond. Old elements rely on silk screen outline and sometimes largish elements without a clear silk screen box may include remote pins that make the element much larger than they first appear. The only way to figure the bounding box is grabbing the element - which most often happens by accident, not suspecting some free space in the middle of the board is really under a large element. This problem is fixed with the subcircuit bounding box visualization.

Two new virtual layers are introduced:

layer side effects

When an element is rendered, a thin black diamond is drawn on screen. This diamond looks like if it was on the silk screen - it always has the same color as the corresponding silk screen.

Subcircuits use a separate virtual layer ("subcircuit parts") and a different color (red by default) for drawing the diamond and a dashed bounding box around the subcircuit. This makes it easier to see what's auto-generated eye-candy and what's really on the silk screen