Fritzing Sketch File Format
Fritzing Sketch File Specification
21 November 2010
Introduction
A Fritzing "sketch" is a diagram with three views: breadboard, schematic, and pcb. In each view there are a number of parts, some of which are connected by wires or traces. There may be multiple instances of a given part. Most parts are visible in all three views, but some are not. Parts have a specific location, and wires have a pair of endpoint locations. A given individual part instance, or wire, may have an individual set of properties (such as color or resistance). All this information is stored in the sketch file.
File Structure
A Fritzing sketch file always starts with the <module> element and includes a fritzingVersion attribute.
After that it lists the three views, each with its own background color:
<view name="breadboardView" backgroundColor="#cccccc"/>
<view name="schematicView" backgroundColor="#ffffff"/>
<view name="pcbView" backgroundColor="#a0a8b3"/>
</views>
And then we get to the meat of the sketch file, the individual part and wire elements. These are known as "instances", and there is one instance per individual part. For example, if there are three resistors in the sketch, then there will be three instance elements, even though each instance references the same part. If there is one wire connecting a connector on one resistor to a connector on another resister , that will add a single wire instance. If a wire has a bendpoint, it will be listed as two instances (each additional bendpoint adds another instance). The structure of each instance is fairly complicated, since there is a lot of information to be stored. But overall the structure is simply a list:
<instance>
...
</instances>
After that the sketch file simply closes:
Part instance
Here's the instance element for the Red LED from the Blink example sketch:
<title>LED2</title>
<views>
<breadboardView layer="breadboard">
<geometry z="2.50002" x="135.089" y="59.556"/>
<connectors>
<connector connectorId="connector0" layer="breadboard">
<geometry x="0" y="0"/>
<connects>
<connect connectorId="connector1" modelIndex="45391" layer="breadboardbreadboard"/>
</connects>
</connector>
<connector connectorId="connector1" layer="breadboard">
<geometry x="0" y="0"/>
<connects>
<connect connectorId="connector2" modelIndex="45391" layer="breadboardbreadboard"/>
</connects>
</connector>
</connectors>
</breadboardView>
<pcbView layer="copper0">
<geometry z="6.50003" x="158.844" y="92.3148">
<transform m11="0" m12="-1" m13="0" m21="1" m22="0" m23="0" m31="0.225" m32="16.335" m33="1"/>
</geometry>
<connectors>
<connector connectorId="connector0" layer="copper0">
<geometry x="0" y="0"/>
<connects>
<connect connectorId="connector1" modelIndex="5534" layer="copper0trace"/>
<connect connectorId="connector1" modelIndex="45391" layer="copper0"/>
</connects>
</connector>
<connector connectorId="connector1" layer="copper0">
<geometry x="0" y="0"/>
<connects>
<connect connectorId="connector1" modelIndex="5535" layer="copper0trace"/>
<connect connectorId="connector2" modelIndex="45391" layer="copper0"/>
</connects>
</connector>
</connectors>
</pcbView>
<schematicView layer="schematic">
<geometry z="1.50001" x="477" y="186"/>
<connectors>
<connector connectorId="connector0" layer="schematic">
<geometry x="0" y="0"/>
<connects>
<connect connectorId="connector1" modelIndex="45391" layer="schematic"/>
<connect connectorId="connector1" modelIndex="112438" layer="schematicTrace"/>
</connects>
</connector>
<connector connectorId="connector1" layer="schematic">
<geometry x="0" y="0"/>
<connects>
<connect connectorId="connector2" modelIndex="45391" layer="schematic"/>
<connect connectorId="connector1" modelIndex="112420" layer="schematicTrace"/>
</connects>
</connector>
</connectors>
</schematicView>
</views>
</instance>
Pretty scary, eh? Let's start from the top. The moduleIdRef attribute is a reference to a part, in this case, a Red LED. Note that this is a reference: parts are stored in their own separate files, and not kept as part of a sketch. This makes sketch file sizes much smaller, and it means that if a part file is updated, the sketch will automatically be updated. This works nicely for core parts, since it's unlikely that anyone will be running Fritzing without access to the core parts. However, that makes sketches with custom parts a little tricky. For that we use "shareable sketch files"; more on these below.
Back to XML again, the modelIndex attribute is an internal reference; For example, other parts connected to this red LED will refer to it using the modelIndex 129028. Each instance is given a unique modelIndex number, so that any internal reference can only refer to one particular instance. The path attribute is only a hint, and no code relies on it. The next element contains the instance's title; the instance's title appears in the inspector window, or if the instance's part label is visible.
Next, the instance is split into view-dependent portions by the views element. Most instances will have three view elements--one each for breadboard, schematic, and pcb views. Starting around Fritzing 0.5, this will always be the case, however, with earlier versions of Fritzing, you can find instances which contain only a single view element. A trace wire, for example, will only appear in one view. The LED above appears in all three views and has three view elements. For example:
The view element is always one of breadboardView, schematicView or pcbView. The layer attribute has to do with which layer, in the given view, the instance's connectors are on. I think this attribute may no longer be in use, because each individual connector also has a layer element.
The geometry element for a part instance holds the part's position on the plane of the sketch, as well as its position in the z-order:
Parts with higher z are above parts with lower z.
The next element after geometry is connectors. Since connectors are already included in the definition of a part (and therefore can already found in a given part's .fzp file), the only connectors that are listed in the sketch file are the ones that are actually connected to something. In other words, the <connectors> element in the sketch tells which parts (or wires) are connected to which other parts (or wires).
If you look back up at the full instance element, you will see the connectors element defined for all three views. Here are the breadboard view connectors for the red LED:
<connector connectorId="connector0" layer="breadboard">
<geometry x="0" y="0"/>
<connects>
<connect connectorId="connector1" modelIndex="45391" layer="breadboardbreadboard"/>
</connects>
</connector>
<connector connectorId="connector1" layer="breadboard">
<geometry x="0" y="0"/>
<connects>
<connect connectorId="connector2" modelIndex="45391" layer="breadboardbreadboard"/>
</connects>
</connector>
</connectors>
Each connector element is from the point of view of the part. So the first line:
means that we're talking about the connector with the id "connector0" on the red LED which is in the breadboard layer. This connector is connected to a connector on the instance with modelIndex 45391. That connector has id "connector1" and is in the breadboardbreadboard layer. The second red LED connector is connected to "connector2" on the same part. Even though it's redundant, the part with modelIndex 45391 also has a connectors element, but from its own point of view (the red LED has modelIndex 129028):
<connector connectorId="connector1" layer="breadboardbreadboard">
<geometry x="0" y="0"/>
<connects>
<connect connectorId="connector0" modelIndex="129028" layer="breadboard"/>
</connects>
</connector>
<connector connectorId="connector2" layer="breadboardbreadboard">
<geometry x="0" y="0"/>
<connects>
<connect connectorId="connector1" modelIndex="129028" layer="breadboard"/>
</connects>
</connector>
</connectors>
It is possible for a connector to be connected to more than one other connector. In other words, the <connects> element may contain a list of <connect> elements. By the way, the <geometry> element inside the <connector> element is a historical artifact.
Wire instance
We've had a pretty thorough look at a part instance. For contrast, let's look at a wire instance:
<title>Wire9</title>
<views>
<pcbView layer="copper0trace">
<geometry z="7.50002" x="162.078" y="66.5868" x1="0" y1="0" x2="0.0302262" y2="33.976" wireFlags="36"/>
<wireExtras mils="24" color="#ff9400" opacity="1"/>
<connectors>
<connector connectorId="connector0" layer="copper0trace">
<geometry x="0" y="0"/>
<connects>
<connect connectorId="connector1" modelIndex="45391" layer="copper0"/>
</connects>
</connector>
<connector connectorId="connector1" layer="copper0trace">
<geometry x="0" y="0"/>
<connects>
<connect connectorId="connector0" modelIndex="129028" layer="copper0"/>
</connects>
</connector>
</connectors>
</pcbView>
</views>
</instance>
Note that this wire instance--a description of a trace--only exists in PCB view. That may change with Fritzing 0.5.
The <connectors> element functions the same way it does in a part instance (though with a wire, there will always be two connectors with id "connector0" and "connector1"). However, the <geometry> element is different between parts and wires, since parts need only a single position, whereas wires need two. Here are two such elements to compare, the first from the red LED, the second from the wire above:
<geometry z="7.50002" x="162.078" y="66.5868" x1="0" y1="0" x2="0.0302262" y2="33.976" wireFlags="36"/>
The z, x, and y attributes are the same for a wire as they are for a part, but why do wires have two more pairs of coordinates and not just one? This is for historical reasons. First note that the x1, x2, y1, and y2 coordinates are offset from the x and y coordinates. At one time the position of the wire (given by x and y) was independent of where the wire's two endpoints were. Nowadays, x1 and y1 will always be zero.
WireFlags are as follows: VirtualFlag = 1, RoutedFlag = 2, TraceFlag = 4, ObsoleteJumperFlag = 8, RatsnestFlag = 16, AutoroutableFlag = 32, NormalFlag = 64. A given wire may have multiple flags set. The meanings of these flags will change somewhat with Fritzing 0.5, but for the moment here is the story.
Note that since Fritzing 0.4.3, ratsnest/virtual wires are no longer saved with the sketch, so you will not find sketches from recent versions of Fritzing that use either VirtualFlag, RoutedFlag, or RatsnestFlag. JumperWires are also now obsolete so that flag is also no longer in use. If you are looking at an old Fritzing sketch file, all ratsnest wires are virtual and vice versa, so these two flags are effectively the same, and both were always set together (unless you go way way back). The Routed flag was set when a ratsnest has been routed (a trace had been drawn for that connection).
The TraceFlag is still in use, and traces right now only exist in either Schematic or PCB view. If a trace's AutoroutableFlag is set, it means that the autorouter can remove it before autorouting. The Normal flag refers to a breadboard wire. Normal wires are also found in Schematic and PCB view, but they are never visible.
The <wireExtras> element simply holds a few wire-instance-specific properties. "Mils" refers to the wire's thickness in 1/1000 inch units.
Odds and ends
We will deal with a few odds and ends, then conclude.
- First, here is an instance with some properties.
<property name="width" value="29.3511111111111"/>
<property name="height" value="27.0933333333333"/>
<title>PCB1</title>
<views>
<pcbView layer="board">
<geometry z="1.5" x="178" y="176"/>
</pcbView>
</views>
</instance>
<property name="resistance" value="22"/>
<property name="pin spacing" value="500 mil"/>
...
</instance>
- At the beginning, we briefly mentioned that since sketch files refer to parts by reference, that there could be an issue when people try to share sketches with custom parts. Our solution to this problem was to come up with a new format, ".fzz", which we call a shareable sketch. An fzz file is just a zip file with a renamed suffix. The zip folder contains a normal sketch file, plus all the files for each unique custom part--the part's fzp file and svg files. When the fzz file is loaded, the part files are copied into into your local user application storage area for Fritzing (which is different on each platform). The sketch then refers to the part as usual by its moduleIdRef.
- Bin files (.fzb) actually use the same structure as sketch files. However, there are no connections, and the <views> element is ignored. So really, bin files are just lists of simplified instances whose only important value is the moduleIDRef. For example, here is the first part of the core bin:
<title>Core</title>
<instances>
<instance moduleIdRef="ResistorModuleID" modelIndex="3" path=":/resources/parts/core/resistor.fzp">
<views>
<iconView layer="icon">
<geometry z="-1" x="-1" y="-1"></geometry>
</iconView>
</views>
</instance>
...
</instances>
</module>
Conclusion
That's it. Not so bad, really.
