Welcome to PCBmodE’s documentation!¶
Contents:
Introduction¶
What is PCBmodE?¶
PCBmodE is a Python script that takes input JSON files and converts them into an Inkscape SVG that represents a printed circuit board. PCBmodE can then convert the SVG it generated into Gerber and Excellon files for manufacturing.
How is PCBmodE different?¶
PCBmodE was conceived as a circuit design tool that allows the designer freedom to put any arbitrary shape on any layer of the board. While it is possible to add graphical elements to other PCB design tools by additional scripts and general arm-twisting, PCBmodE is purposefully designed and architected for that purpose.
PCBmodE uses open and widely used formats (SVG, JSON) together with open source tools (Python, Inkscape) without proprietary elements (Gerber is an exception, although the standard is public). It also provides a fresh take on circuit design and opens new uses for the circuit board manufacturing medium.
PCBmodE is free and open source under the GPL 3 license.
What PCBmodE isn’t¶
PCBmodE isn’t a general-purpose replacement for other PCB design tools like KiCad, EAGLE, Altium, etc. For example, it does not currently have a notion of a netlist or schematics, have design rule checks.
Workflow¶
- PCBmodE is a script that uses Inkscaoe as a graphical interface. So
- you can think of PCBmodE as a wrapper around Inkscape.
To get a feel for how to work with PCBmodE, here’s a typical design workflow:
- Edit JSON files with a text editor for adding components, placing them, etc.
- Run PCBmodE to generate the board’s Inkscape SVG
- Open the generated SVG in Inkscape
- Make modifications in Inkscape, such as routing, vias, and component positioning
- Run PCBmodE to extract these changes; this will put those changes back to the input JSON files
During development you’d go through many iterations of steps 1 to 5. Then when you’re ready,
- Run PCBmodE to generate Gerbers from the board’s SVG
It is possible to design a complete circuit board in a text editor without using Inkscape at all! The most challanging part would be generating (using scripts), or hand crafting SVG paths for the routing.
Tip
Inkscape does not reload SVGs when they change on the disc
after PCBmodE regenerated them. To reload quickly, press
ALT+f
and the v
.
Tip
Until you get used to it the extraction process may not do
what you’d expect. One trick is to extract and then run
PCBmodE with also generating Gerbers (--fab
switch). Then review the Gerbers instead of reloading the SVG
to notice that your changed are gone. It might also be
practical to design in a separate Inkscape window and then
copy over the shapes to the design’s SVG.
Setup¶
We test PCBmodE with Python 3.7 under Linux, but it may or may not work on other operating systems.
It comes in the form of a installable tool called pcbmode
which is
run from the command line.
What you’ll need¶
- Python 3.7+
- Inkscape 1.0+
- Text editor
Installation in a virtual environment¶
Use a virtual environment to keep PCBmodE in its own isolated
environments, for example Python3’s venv
. If you don’t have
venv
, get it like this:
sudo apt-get install python3-venv
These instructions describe how to build PCBmodE for use in a virtual environment. To be able to build python-lxml (one of PCBmodE’s dependencies) you need to install some system-level development packages. On Debian based systems these are installed like this:
sudo apt-get install libxml2-dev libxslt1-dev python-dev
Note
You’re reading the documentation for version 5 of PCBmodE, ‘Cinco’. The link below will get you that branch while we’re working on it, and before its release.
Get the PCBModE source from GitHub.
git clone https://github.com/boldport/pcbmode/tree/cinco-master
Now run these commands to create a virtual environment, for example in
the directory pcbmode-env/
next to pcbmode/
. Then create the
virtual environment like this:
python3 -m venv pcbmode-env
source pcbmode-env/bin/activate
cd pcbmode
where you can replace pcbmode-env
with a name of your chooseing. If you want
to install PCBmodE, run
pip install .
but if you want to develop it, run
pip install --editable .
After installation, PCBmodE will be available in your path as an
executable pcbmode
. But since it was installed in a virtual environment,
the pcbmode
command will only be available in your path after
running source pcbmode-env/bin/activate
and will no longer be in
your path after running deactivate
, which gets you out of the
virtual environment. You will need to activate the virtual environment each
time you want to run pcbmode
from a new terminal window.
Packages are not installed globally, so to start from scratch you can just follow these steps:
deactivate # skip if pcbmode-env is not active
rm -r pcbmode-env
cd pcbmode
git clean -dfX # erases any untracked files (build files etc). Save your work!
Running PCBmodE¶
Tip
To see all the options that PCBmodE supports, use pcbmode
--help
To make a create an SVG of your board you’d use a command like this:
pcbmode -b <board-name>.json -m
where board-name.json
is your board file. If you’re nor running pcbmode
at the path where board.json
is, you’ll need to specify the path to it,
like this for example:
boards/<project-name>/<board-name>.json
Youre board-name.json
will tell PCBmodE where the rest of the file are,
for example
"project-params":
{
"input":
{
"routing-file": "board-routing.json",
"svg-file": "build/gent-pcbmode-v5-test.svg"
},
"output":
{
"svg-file": "build/gent-pcbmode-v5-test.svg",
"gerber-preamble": "build/prod/gent-pcbmode-v5-test_"
}
}
Again, you’ll need to specify the path where PCBmodE should expect file and
place files relative to the path where board-name.json
is.
Where component and shape files are are defined in pcbmode_config.json
.
PCBmodE will load its default settings and override it with settings in a
local config/pcbmode_config.json
if it exists.
The defaults for where to find component and shape files are the following:
"shapes":
{
"path": "shapes"
},
"components":
{
"path": "components"
}
So here’s one way to organise the build environment
beautiful-pcbs/
pcbmode-env/
pcbmode/
boards/
my-board/ # a PCB project
my-board.json
my-board_routing.json
components/
shapes/
docs/
...
cordwood/ # another PCB project
...
To make the my-board
board from the beautiful-pcbs
path, run
pcbmode -b boards/my-board/my-board.json -m
and then open the SVG with Inkscape
inkscape beautiful-pcbs/boards/my-board/build/my-board.svg
If the SVG opens you’re good to go!
Note
PCBmodE processes a lot of shapes on the first time it is run, so it will take a noticeable amount. This time will be dramatically reduced on subsequent invocations since PCBmodE caches the shapes in a datafile within the project’s build directory.
Style¶
PCBmodE seperates the shapes and their visual apperance in the SVG. This means that visual changes can be applied to the entore design without touching the shapes themselves, unless they differ from the overall setting. The styles are defined in CSS stylesheet classes.
Classes¶
.board
Sets the global look of the SVG.
.origin
.outline
, .dimensions
Converted to paths
.drills
.pad-labels
Unless disabled, PCBmodE will put a small pad label under each component pad. This is an SVG text element.
<pcb-layer>-<sheet>
Where <pcb-layer>
are PCB layers such as top
, bottom
, or internal-<num>
.
<sheet>
is an additional ‘layer’ associated with a pcb-layer: placement
, assembly
,
conductor
, silkscreen
, soldermask
, and solderpaste
.
<pcb-layer>-conductor-<type>
An additional level applies to conductor
layers where type
is: routing
,
pads
, and pours
.
.drill-index
, .drill-index-symbol
, .drill-index-symbol-text
Defined the look of the drill index
.layer-index
Defined the look of the layer index
Components¶
Components are the building blocks of the board. In fact, they are used for placing any element on board, except for routes. A via is a ‘component’, and a copper pour is defined within a ‘component’ and then instantiated into the board’s JSON file.
Defining components¶
Components are defined in their own JSON file. The skeleton of this file is the following
{
"pins":
{
},
"layout":
{
"silkscreen":
{
},
"assembly":
{
}
},
"pads":
{
}
}
pins
is where the pins of a components are ‘instantiated’. pads
contain what pads or pins are in terms of their shapes and drills. Each ‘pin’ instantiates a ‘pad’ from pads''. ``layout
contain silkscreen and assembly shapes.
pins¶
Here’s what a component with two pins looks like
{
"pins":
{
"1":
{
"layout":
{
"pad": "pad",
"location": [-1.27, 0],
"show-label": false
}
},
"2-TH":
{
"layout":
{
"pad": "pad",
"location": [1.27, 0],
"label": "PWR",
"show-label": true
}
}
}
}
Each pin has a unique key – 1
and 2-TH
above – that does not necessarily need to be a number. pad
instantiates the type of landing pad to use, which is defined in the pads'' section. ``location
is the position of the pin relative to the centre of the component.
PCBmodE can discreetly place a label at the centre of the pin (this is viewable when zooming in on the pin). The label can be defined using label
, or if label
is missing, the key will be used instead. To not place the label use "show-label": false
.
pads¶
Pads define the shape of pins. Here’s a definition for a simple throughole capacitor
{
"pins": {
"1": {
"layout": {
"pad": "th-sq",
"location": [-2, 0]
}
},
"2": {
"layout":
{
"pad": "th",
"location": [2, 0]
}
}
},
"layout": {
"silkscreen": {
"shapes": [
{
"type": "path",
"value": "m -10.515586,19.373448 c -0.214789,0.0199 -0.437288,0.01645 -0.664669,-0.0017 m -0.514055,0.01247 c -0.202682,0.02292 -0.412185,0.02382 -0.626017,0.01069 m 1.56129,1.209208 c -0.557685,-0.851271 -0.665205,-1.634778 -0.04126,-2.443953 m -0.82831,2.449655 c -0.07502,-0.789306 -0.06454,-1.60669 1.98e-4,-2.441891",
"location": [0, 0],
"style": "stroke"
}
]
},
"assembly": {
"shapes": [
{
"type": "rect",
"width": 2.55,
"height": 1.4
}
]
}
},
"pads": {
"th": {
"shapes": [
{
"type": "circle",
"layers": ["top", "bottom"],
"outline": 0,
"diameter": 1.9,
"offset": [0, 0]
}
],
"drills": [
{
"diameter": 1
}
]
},
"th-sq": {
"shapes": [
{
"type": "rect",
"layers": ["top", "bottom"],
"width": 1.9,
"height": 1.9,
"offset": [0, 0],
"radii": { "tl": 0.3,"bl": 0.3,"tr": 0.3,"br": 0.3 }
}
],
"drills": [
{
"diameter": 1
}
]
}
}
}
This would result in this component

Here’s a more complex footprint for a battery holder on an ocean-themed board
{
"pins": {
"POS-1": {
"layout":
{
"pad": "pad",
"location": [13.3, 0],
"rotate": 95
}
},
"NEG": {
"layout": {
"pad": "pad",
"location": [0, 0]
}
},
"POS-2": {
"layout": {
"pad": "pad",
"location": [-13.3, 0],
"rotate": -95
}
}
},
"layout": {
"assembly": {
"shapes": [
{
"type": "rect",
"layers": ["top"],
"width": 21.1,
"height": 19.9,
"offset": [0, 0]
}
]
}
},
"pads": {
"pad": {
"shapes": [
{
"type": "path",
"style": "fill",
"scale": 1,
"layers": ["top"],
"value": "M 30.090397,29.705755 28.37226,29.424698 c 0,0 2.879054,-2.288897 4.991896,-2.270979 2.611383,0.02215 2.971834,2.016939 2.971834,2.016939 l 2.261927,-1.675577 -0.816738,2.741522 0.747218,2.459909 -2.119767,-1.518159 c 0,0 -0.605255,1.760889 -3.359198,1.739078 C 31.737346,32.90704 28.38105,30.56764 28.38105,30.56764 z",
"soldermask": [
{
"type": "path",
"style": "fill",
"scale": 1,
"rotate": 10,
"layers": ["top"],
"value": "M 30.090397,29.705755 28.37226,29.424698 c 0,0 2.879054,-2.288897 4.991896,-2.270979 2.611383,0.02215 2.971834,2.016939 2.971834,2.016939 l 2.261927,-1.675577 -0.816738,2.741522 0.747218,2.459909 -2.119767,-1.518159 c 0,0 -0.605255,1.760889 -3.359198,1.739078 C 31.737346,32.90704 28.38105,30.56764 28.38105,30.56764 z"
},
{
"type": "path",
"style": "fill",
"scale": 0.5,
"rotate": 20,
"location": [0, 4.7],
"layers": ["top"],
"value": "M 30.090397,29.705755 28.37226,29.424698 c 0,0 2.879054,-2.288897 4.991896,-2.270979 2.611383,0.02215 2.971834,2.016939 2.971834,2.016939 l 2.261927,-1.675577 -0.816738,2.741522 0.747218,2.459909 -2.119767,-1.518159 c 0,0 -0.605255,1.760889 -3.359198,1.739078 C 31.737346,32.90704 28.38105,30.56764 28.38105,30.56764 z"
}
]
},
{
"type": "circle",
"layers": ["bottom"],
"outline": 0,
"diameter": 2.3,
"offset": [0, 0]
}
],
"drills": [
{
"diameter": 1.2
}
]
}
}
}
This will what it looks like

Notice that you can define multiple shapes for the soldermask that are independent of the shape of the shape of the copper.
To control how soldermask shapes are placed, you have the following options:
- No
soldermask
definition will assume default placement. The buffers and multipliers are defined in the board’s JSON file "soldermask": []
will not place a soldermask shape"soldermask": [{...},{...},...]
as above will place custom shapes
Defining custom solderpaste shapes works in exactly the same way except that you’d use soldepaste
instead of soldermask
.
layout shapes¶
Placing components and shapes¶
Footprints for components and shapes are stored in their own directories within the project path (those can be changed in the configuration file).
This is an example of instantiating a component within the board’s JSON file
{
"components":
{
"J2":
{
"footprint": "my-part",
"layer": "top",
"location": [
36.7,
0
],
"rotate": -90,
"show": true,
"silkscreen": {
"refdef": {
"location": [
-7.2,
2.16
],
"rotate": 0,
"rotate-with-component": false,
"show": true
},
"shapes": {
"show": true
}
}
}
}
}
The key of each component – J2
above – record is the component’s reference designator, or in PCBmodE-speak, ‘refdef’. Note that as opposed to shape
types, here layer
can only accept one layer.
silkscreen
is optional, but allows control over the placement of the reference designator, and whether shapes are placed or not.
Note
The sharp-minded amongst you will notice that ‘refdef’ is not exactly short form of ‘reference designator’. I noticed that fact only in version 3.0 of PCBmodE, way too far to change it. So I embraced this folly and it will forever be.
Shapes¶
Shapes are the building blocks of PCBmodE. Here’s an example of how a definition of
a path
type looks like:
{
"type": "path",
"layers": ["top, "bottom"],
"location": [3.1, -5.667],
"style": "stroke-width:1.2;",
"d": "m -48.3,0 0,-5.75 c 0,-1.104569 0.895431,-2 2,-2 0,0 11.530272,-0.555504 17.300001,-0.5644445 10.235557,-0.015861 20.4577816,0.925558 30.6933324,0.9062128 C 10.767237,-7.4253814 19.826085,-8.3105055 28.900004,-8.3144445 34.703053,-8.3169636 46.3,-7.75 46.3,-7.75 c 1.103988,0.035813 2,0.895431 2,2 l 0,5.75 0,5.75 c 0,1.104569 -0.895431,2 -2,2 0,0 -11.596947,0.5669636 -17.399996,0.5644445 C 19.826085,8.3105055 10.767237,7.4253814 1.6933334,7.4082317 -8.5422174,7.3888865 -18.764442,8.3303051 -28.999999,8.3144445 -34.769728,8.305504 -46.3,7.75 -46.3,7.75 c -1.103982,-0.036019 -2,-0.895431 -2,-2 l 0,-5.75"
}
This will place the SVG path defined in d
shown as stroke with width 1.2 mm
at
location [3.1,5.667]
. The shape will be placed on the top and bottom layers of the PCB.
Shape properties¶
Fills and strokes¶
By default PCBmodE assumes that a shape is a ‘fill’ without a ‘stroke’. If the shape you want to place is a ‘fill’ there’s no need to tell PCBmodE that. But if you’d like to place a ‘stroked’ shape, then you need to add:
"style": "stroke-width:<width>;"
just like adding a CSS property. PCBmodE will only pay attention to stroke-width
in the style
property; all the others will be discarded when the SVG is extracted.
Buffer to pour¶
buffer-to-pour
defines the distance from the edge of the filled or stroked shape to
a pour. This overrides global settings defined in the board’s JSON, or PCBmodE’s
defaults if those are not defined locally.
Location¶
Location is defined as an x
, y
coordinate
"location": [<x>m <y>]
The location definition is relative to the hierarchy. So if you’re defining a pad, the location is relative to the footprint’s center.
Default: [0,0]
.
Layers¶
A list of which layers to put the shape in
"layers": ["top", "bottom"]
Even if the shape is placed in a single layer, it needs to be defined as a list
"layers": ["bottom"]
Default: ["top"]
.
Rotation¶
Default: 0.
Scale¶
Default: 1.
Shape types¶
You must define a shape type
with each shape definition.
Rectangle¶
{
"type": "rect",
"width": 1.7,
"height": 1.7,
"radii": {"tl": 0,
"tr": 0.3,
"bl": 0.3,
"br": 0.3}
}
- type
rect
: place a rectangle- width
- int/float: width of the rectangle
- height
- int/float: height of the rectangle
- radii (optional)
- dict: radius of round corners
tl
: top left radius,tr
: top right radius,bl
: bottom left radius,br
: bottom right radius,
Circle¶
{
"type": "circle",
"diameter": 1.7,
}
- type
circle
: place a circle- diameter
- float: diameter of circle
Path¶
{
"type": "path",
"d": "m -48.3,0 0,-5.75 c 0,-1.104569 0.895431,-2 2,-2 0,0 11.530272,-0.555504 17.300001,-0.5644445 10.235557,-0.015861 20.4577816,0.925558 30.6933324,0.9062128 C 10.767237,-7.4253814 19.826085,-8.3105055 28.900004,-8.3144445 34.703053,-8.3169636 46.3,-7.75 46.3,-7.75 c 1.103988,0.035813 2,0.895431 2,2 l 0,5.75 0,5.75 c 0,1.104569 -0.895431,2 -2,2 0,0 -11.596947,0.5669636 -17.399996,0.5644445 C 19.826085,8.3105055 10.767237,7.4253814 1.6933334,7.4082317 -8.5422174,7.3888865 -18.764442,8.3303051 -28.999999,8.3144445 -34.769728,8.305504 -46.3,7.75 -46.3,7.75 c -1.103982,-0.036019 -2,-0.895431 -2,-2 l 0,-5.75"
}
- type
path
: place an SVG path- d
- path: in SVG this is the
d
property of a<path>
Copper pours¶
A copper pour covers the surface area of a board with copper while maintaining a certain buffer from other copper features, such as routes and pads. A ‘bridge’ can connect between a copper feature and a pour.
Defining pours¶
Pours are defined in their own section in the board’s JSON under shapes
{
"shapes": {
"pours":
[
{
"layers": [
"bottom",
"top"
],
"type": "layer"
}
]
}
}
The above will place a pour over the entire top and bottom layer of the board. It’s possible to pour a specific shape, and that’s done just like any other shape definition.
Warning
Since PCBmodE does not have a netlist, those bridges need to be added manually, and careful attention needs to be paid to prevent shorts – there’s no DRC!
Tip
Even if you’re pouring over a single layer, the layers
definition only accepts a list, so you’d use ["bottom"]
, not "bottom"
.
Defining buffers¶
The global settings for the buffer size between the pour and a feature is defined in the board’s JSON file, as follows:
"distances": {
"from-pour-to": {
"drill": 0.4,
"outline": 0.25,
"pad": 0.4,
"route": 0.25
}
}
If this block, or any of its definitions, is missing, defaults will be used.
These global settings can be overridden for every shape and route. For routes, it’s done using the pcbmode:buffer-to-pour
definition, as described in Routing. For shapes it’s done using the buffer-to-pour
definition, as described in Shapes.
Text¶
One of the unique features of PCBmodE is that any font – as long as it is in SVG form – can be used for any text on the board.
Fonts¶
SVG fonts have an SVG path for every glyph, and other useful information about how to place the font so the glyphs align. PCBmodE uses that information to place text on the board’s layers.
The folder in which PCBmodE looks for a font is defined in the the configuration file pcbmode_config.json
.
{
"locations":
{
"boards": "boards/",
"components": "components/",
"fonts": "fonts/",
"build": "build/",
"styles": "styles/"
}
}
When looking for a font file, PCBmodE will first look at the local project folder and then where pcbmode.py
is.
Tip
When you find a font that you’d like to use, search for an SVG version of it. Many fonts at http://www.fontsquirrel.com have an SVG version for download.
Defining text¶
A text definition looks like the following
{
"type": "text",
"layers": ["bottom"],
"font-family": "Overlock-Regular-OTF-webfont",
"font-size": "1.5mm",
"letter-spacing": "0mm",
"line-height": "1.5mm",
"location": [
-32.39372,
-33.739699
],
"rotate": 0,
"style": "fill",
"value": "Your text\nhere!"
}
- type
text
: place a text element- layers (optional; default
["top"]
) - list: layers to place the shape on (even if placing on a single layer, the definition needs to be in a form of a list)
- font-family
- text: The name of the font file, without the
.svg
- font-size
- float: font size in mm (the
mm
must be present) - value
- text: the text to display; use
\n
for newline - letter-spacing (optional; default
0mm
) - float: positive/negative value increases/decreases the spacing.
0mm
maintains the natural spacing defined by the font - line-height (optional; defaults to
font-size
) - float: the distance between lines; a negative value is allowed
- location (optional; default
[0, 0]
) - list:
x
andy
to place the center of the text object - rotate (optional; default
0
) - float: rotation, clock-wise degrees
- style (optional; default depends on sheet)
stroke
orfill
: style of the shape- stroke-width (optional; default depends on sheet; ignored unless
style
isstroke
) - float: stroke width
Routing¶
Routing, of course, is an essential part of a circuit board. PCBmodE does not have an auto-router, and routing is typically done in Inkscape, although theoretically, routing can be added manually in a text editor. All routing shapes reside in the routing SVG layer of each PCB layer.
Important
Make sure that you place the routes and vias on the routing SVG layer of the desired PCB layer. To choose that layer either click on an element in the layer or open the layer pane by pressing CTRL+SHIFT+L
.
Important
In order to place routes, make sure that Inkscape is set to ‘optimise’ paths by going to File->Inkscape Preferences->Transforms
and choosing optimised
under Store transformation
.
Adding routes¶
Choose the desired routing SVG layer. Using the Bezier tool (SHIFT+F6
) to draw a shape.
For a filled shape, make sure that it is a closed path and in the Fill and stroke
pane (SHIFT+CTRL+F
) click on the flat color
button on the Fill
tab, and the No paint
(marked with an X
) on the Stroke point
tab.
For a stroke, in the Fill and stroke
pane (SHIFT+CTRL+F
) click on the No paint
button on the Fill
tab, and the Flat color
on the Stroke point
tab. Adjust the stroke thickness on the Stroke style
tab.
Note
Shapes can be either stroke or fill, not both. If you’d like a filled and stroked shape, you’ll need to create two shapes.
Finally, you must move the shape with the mouse or with the arrows.
Note
When creating a new shape Inkscape adds a matrix transform, which is removed when the shape is moved because of the optimise
settings as described above. This minor inconvenience is a compromise that greatly simplifies the extraction process.
If the route is placed where there is a copper pour, it will automatically have a buffer around it that’s defined in the board’s configuration. Sometimes, it is desirable to reduce or increase this buffer, or eliminate it completely in order to create a bridge (for example when connecting a via to a pour). This is how it is done:
- Choose the route
- Open Inkscape’s XML editor (
SHIFT+CTRL+X
) - On the bottom right, next to
set
remove what’s there and type inpcbmode:buffer-to-pour
- In the box below type in the buffer in millimeters (don’t add ‘mm’) that you’d like, or
0
for none - Press
set
orCTRL+ENTER
to save that property
Tip
Once you’ve created one route, you can simply cut-and-paste it and edit it using the node tool without an additional settings. You can even cut-and-paste routes from a different design.
Adding vias¶
Vias are components just like any other. There are placed just like other components, but in the routing file ``<design_name>_routing.json”, not the main board’s JSON.
You can assign a unique key to the via, but that will be over-written by a hash when extracted.
Note
Since vias are components, anything could be a via, so if it makes sense to place a 2x2 0.1” header as a “via”, that’s possible.
Important
Don’t forget to extract the changes!
Extraction¶
One of the common steps of the PCBmodE workflow is extracting information from the SVG and storing it in primary JSON files.
The following will be extracted from the SVG:
- Routing shapes and location
- Vias’ location
- Components’ location and rotation
- Documentation elements’ location
- Drill index location
That’s it.
Note
It’s quite likely that more information will be extracted in the future to make the design process require fewer steps. Architecturally, however, the use of a GUI is meant only to assist the textual design process, not replace it.
Other information needs to be entered manually with a text editor. A great tool in this process is Inkscape’s built-in XML editor (open with SHIFT+CTRL+X
) which allows you to see the path definition of shape (the d
property) and copy it over to the JSON file.
Tip
Since some shapes (pours, silkscreen, etc.) are not extracted, it’s sometimes a bit of a guesswork to get the location just right. To do that in a single iteration, use the XML editor to change the transform of the shape (press CTRL+ENTER
to apply) until the position is right. Then copy over the coordinates for that shape to the JSON file. Note that Inkscape inverts the y-axis coordinate, so when entering it into the JSON invert it back.
Layer control¶
When opening a PCBmodE SVG in Inkscape, the board’s layers can be manipulated by opening the layer pane (CTRL+SHIFT+L
). Each layer can then be set to be hidden/visible or editable/locked. The default for each layer is defined in utils/svg.py
layer_control = {
"copper": {
"hidden": False, "locked": False,
"pours": { "hidden": False, "locked": True },
"pads": { "hidden": False, "locked": False },
"routing": { "hidden": False, "locked": False }
},
"soldermask": { "hidden": False, "locked": False },
"solderpaste": { "hidden": True, "locked": True },
"silkscreen": { "hidden": False, "locked": False },
"assembly": { "hidden": False, "locked": False },
"documentation": { "hidden": False, "locked": False },
"dimensions": { "hidden": False, "locked": True },
"origin": { "hidden": False, "locked": True },
"drills": { "hidden": False, "locked": False },
"outline": { "hidden": False, "locked": True }
}
but can be overridden in the board’s configuration file. So, for example, if we wish to have the solderpaste layers visible when the SVG is generated, we’d add
{
"layer-control":
{
"solderpaste": { "hidden": false, "locked": true }
}
}
Or if we’d like the outline to be editable (instead of the default ‘locked’) we’d add
{
"layer-control":
{
"solderpaste": { "hidden": false, "locked": true },
"outline": { "hidden": false, "locked": false }
}
}
Tip
The reason that some layers are locked by default – ‘outline’ is a good example – is because they are not edited regularly, but span the entire board so very often take focus when selecting objects. Locking them puts them out of the way until an edit is required.