A via fence generator plugin for pcbnew


For the integration into KiCad i thought there might be a way to select traces in pcbnew. As I could not figure out how to do so, I suppose there is no way to select tracks or line segments in pcbnew?

In GAL you can select a track segment and then select trivial connection … then you will have your track selected…

For a kicad integration you can have a look at this topic

@jsreynaud is also the author of Action Plugin


Nice, thanks. Unfortunately I could not get the OpenGL mode to work in the Linux Mint 18.1 VirtualBox VM. 3D Passthrough is activated and the guest drivers are working… However when entering the OpenGL mode, it freezes for some time and fails on me saying “Error: Attaching Renderbuffer: Invalid Enum”. Console outputs “OpenGL Warning: vboxCall failed with VBox status code -54”… Hm anyway.

I will check the python plugins you mentioned. There should be some good pointers on how I should do it.

What I could not figure out yet is, how the interface to getting tracks via the python API from pcbnew works. I only need a way to access the tracks so that I can fill a list of x,y points for each track on a layer.

I have updated the python repository, it can now handle multiple paths :sunglasses: go have a look at the example png image.


for some function OpenGL Gal mode is the only way to go (more python functions are exposed)…

I can run kicad dev with GAL under VirtualBox and Ubuntu (main OS windows)

you can find an auto generated python API doc here

and a useful topic


Find attached a (very) basic version of a ViaFence plugin for KiCad.
ViaFence.py (4.3 KB)

It use a really basic algo.
@skuep you can use it to implement your algo if you want (if you don’t have do the job yet ;)). I can also do this… As you want…

I really interested about this feature…
There are some “TODO”:

  • Need a better algo (@skuep’s one ?)
  • add a WX interface to choose some fence parameters (including size, spacing, net name…)
  • avoid collision with other elements (tracks, pads, denied areas…)
  • Using via instead of modules.

On this last point, during my previous tests it was not possible to add a via on a specific net… So I use modules :frowning:

To use it:

  • put the script inside python plugin directory
  • Select one or more tracks and choose “Via Fence” in “Tools => External plugins”


Hi @jsreynaud
I tried it on win10 latest build and when I select a track in GAL and launch the “Via Fence” I got a crash…
Have you a simple board example to test it?



In KiCad demo, the example ecc83-pp_v2.kicad_pcb (40.5 KB)
Perhaps you don’t have any net named “GND” in your pcb ?
If not, this script crash. You can change the net name in .py file directly (line 23).
There is no error controls (yet ;))…


ok, that was it! :wink:

it is already a good start!
I think that @skuep may easily customize it…

I agree with your TODO except for Vias…
ATM the only way that is guaranteeing a DRC result is through Pads as you did… stitching vias are far away from dev code…

and the via stitching action script from @jsreynaud


Hey everyone,
I have not looked into the forums in the meantime, sorry!
I just uploaded a new version, a rudimentary KiCad integration for testing purposes is now there (does not generate any real vias yet, just extracts the paths and does the thing). See my developers mailing list post:

Regarding the Via/Pad problem: I already stumbled upon that in your Via Stitching. However, I think it is beneficial to use a temporary component, because I think that you could give it a name like “via-fence-[net]” or something. Then if you go into the board after you have done some modifications and you would like to delete or redo the via-fencing, you can safely identify the old vias by their name. Right? Is there any downside to using components instead of vias?

@jsreynaud: Your approach was the first thing I had in mind also! But I really liked to have vias on a rounded arc so their offset to the trace is always the same. This is especially possible, when you want to use this thing for substrate integrated waveguides (see mailing list post). They are really sensitive against this, since the vias set the width of your waveguide and you don’t want that to change.

Now, how about the wx Interface :slight_smile: First things first: I am an algorithm guy, no GUI guy. But I would really like a nice small GUI where you can set some settings or values for the algorithm. How would you do that actually? Do you just use the python wx bindings and spin up your own GUI (with its own message loop?) or are there any fixtures in the pcbnew API to make GUI windows?

To avoid collision with other elements, I am also still unsure. Currently I am thinking to first let the algorithm do its thing and then filter out vias that make any collisions. I have seen in your via stitching code, that you have done this all by yourself, that must have been painful :frowning: . No other way, hm? I read somewhere in the API that there are some HitTest functions. Maybe one could use them? Just to be sure, there is no way to make a DRC test just on one specific via and see if it fails?

Best Regards


Yes my approach is really basic. It was just a frame work to implement a better algo…

Take a look at my example for via stitching:

I split it in 3 files:

  • FillArea.py: the algo class…
  • FillAreaDialog.py: it’s the interface (dialog based). Generated from FillAreaTpl.fbp (by using wxformbuilder)
  • FillAreaAction.py: Use Dialog and the algo class. It’s the entry point of the KiCad plugin…

KiField - How hard would it be to write a Windoze GUI for it?

Hey jsrenaud,
Thanks. I will have a look when I have time again. Next weekend or so?



A nice feature would it to be a able to fence differential pairs.
Maybe just allowing the user to fence only one side of the track, so in 2 operations you get the differential pair fenced.


Hi marcos,
That is a really good idea! From the top of my head this should not be too hard. If the two paths that are used as input baths are closer than twice the via offset, they should actually be merged into one polygon path.
I will test it!

@jsreynaud: Meanwhile, I am trying to find a good way to put multiple .py files belonging to one plugin into a sub directory, instead of just pasting it all into the ~/.kicad_plugin directory… Just to keep it tidy. But there seems to be a problem with the sys.path[0] variable which basically results into non-functional relativ imports in the python script. My current idea was to organize as such

+ plugin_a/
    - dialog.py
    - plugin_a.py
    - image_required_for_plugin_a.png
- "action_plugin_a.py" symlinked to "plugin_a/plugin_a.py"

Within plugin_a/plugin_a.py I then need to do

import dialog.* # or: from .dialog import Dialog

in order to import plugin_a/dialog.py. But this currently does not work, since on execution of the .py files on pcbnew startup, path[0] does not contain the path to the script that has been started (as it is defined by the specification).
Currently KiCAD pcbnew only supports a “flat” plugin directory, which is, in my opinion, very bad for larger plugin projects
See more detail here:

Best Regards :slight_smile:

EDIT: Come to think of it. Actually this would probably not work with the Windows Version of KiCAD, since there is no way for symlinks on Windows is there?


@skuep try

import sys, os
sys.path.insert(0,os.path.join(os.path.dirname(__file__), '.'))
from plugin_a import Dialog

and create an empty __init__.py file in the plugin_a directory.


Sorry, that looks too hacky to my eyes :slight_smile:

In the mean time I had a glance over the KiCAD sources and the way it is implemented actually explains the behaviour I described. Instead of executing a python interpreter to start the scripts, they are actually pulled in using imports. This actually changed the whole thing completely. Because now you can actually do this

+ ~/.kicad_plugins
    + action_plugin_a
       - __init__.py # containing pluginClass.register() at the end
       - otherstuff.py
       - image.png

as well as the well known

+ ~/.kicad_plugins
    - action_plugin_a.py # containing the pluginClass.register()

I like this even better. jsreynaud, maybe you could add this to your “how to write a pcbnew plugin” thing? The first structure could be really cool for bigger plugins, as mentioned.


Excellent work everybody, this Python API is one of the badly documented areas in KiCad


This is probably due to its novelty and very early beta-status :slight_smile:


Hey everyone,
Small update. I restructured the plugin as mentioned above. I am very satisfied right now. You can either just drop the folder into ~/.kicad_plugins or create a symlink of the folder to another place in your file system. The latter is what I am using for development purposes.

I also started working on a dialog.


@davidsrsb: We are currently discussing the documentation of the python interface in the developers mailing list. See here:

@jsreynaud: I believe you are already tracking the mailing list. Would you like to merge your “HOWTO” on Plugins in the documentation posted on the mailing list?

@marcos: Since it was easy to solve, I just tested and fixed support for differential-microstrip structures. You can see how it works in the GitHub Repo. Here are two screenshots:
In the first image, the via offset (the distance from the center of the trace to the center of the via) is bigger than the pitch of the two traces (center to center), the two tracks will be automatically merged by the algorithm and vias are placed correctly.
In the second image you can see, what happens if tracepitch is just over 2 * viaoffset, vias get squeezed in as desired.

:slight_smile: I am getting some confidence in the algorithm I implemented

Btw, you can now easily run tests on a stand-alone version of the plugin. See the GitHub Repo for details on how to do that.


@skuep: No problem you can copy this howto directly inside your document.
An other point is about _init_.py:
You can put the “register plugin” function in _init_.py or in the plugin himself. In this case you just have to import the plugin.
Both solutions work in fact…


Hi everyone,
@jsreynaud: Yes you are correct! However I personally think that it is more obvious to instantiate in the init function since this is the entry function. Otherwise the register() call might be too well hidden amongst all of the additional .py files.

I worked on the KiCad integration. Now there is a mostly functional fancy dialog, when you run the plugin from Pcbnew.
The generation of vias in Pcbnew is however still missing. I am unsure whether I should wait until the connectivity algorithm is merged into the master and then use free via placement instead of placing modules with pads inside.

What I also plan to do is to “filter” the generated Vias. I.e. test if they collide with a different net or test whether they are located within a zone of a specific net and remove the corresponding vias.