summaryrefslogtreecommitdiff
path: root/projects/gerbonara/index.html
blob: 204c74c058abb7e7811807867e7047bc1512e74b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
<!DOCTYPE html>
<html><head>
    <meta charset="utf-8">
    <title>Gerbonara | Home</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="color-scheme" content="dark light">
    <link rel="stylesheet" href="/style.css">
</head>
<body><nav>
    <div class="internal">
        
        <a href="/" title="Home">Home</a>
        <a href="/blog/" title="Blog">Blog</a>
        <a href="/projects/" title="Projects">Projects</a>
        <a href="/about/" title="About">About</a>
    </div>
    <div class="search">
        <div id="search"></div>
    </div>
    <div class="external">
        <a href="https://git.jaseg.de/" title="cgit">cgit</a>
        <a href="https://github.com/jaseg" title="Github">Github</a>
        <a href="https://gitlab.com/neinseg" title="Gitlab">Gitlab</a>
        <a href="https://chaos.social/@jaseg" title="Mastodon">Mastodon</a>
    </span>
</nav>

    <header>
        <h1>Gerbonara</h1>
<ul class="breadcrumbs">
    <li><a href="/">jaseg.de</a></li>
    <li><a href="/projects/">Projects</a></li><li><a href="/projects/gerbonara/">Gerbonara</a></li>
</ul>

    </header>
    <main data-pagefind-body>
        <div class="links">
            <a href="https://git.jaseg.de/gerbonara.git">Sources</a>
            <a href="https://gitlab.com/gerbolyze/gerbonara/issues">Issues</a>
            <a href="https://gerbolyze.gitlab.io/gerbonara">Docs</a>
            <a href="https://pypi.org/project/gerbonara">PyPI</a>
        </div>
        <div class="document">


<p>Gerbonara is a library to read, modify and write PCB manufacturing files such as Gerber, Excellon and IPC-356 through a
pythonic API. Gerbonara can open a folder of manufacturing files, and parse file names and metadata to figure out which
file contains what. Gerbonara is tested using an extensive library of real-world example files from CAD tools including
KiCAD, Altium, Eagle, Allegro, gEDA, Fritzing, Siemens/Mentor Graphics PADS, and Target3001!.</p>
<p>Gerbonara's API is built on two principles:</p>
<dl class="docutils">
<dt><strong>Meaningful, object-oriented API</strong></dt>
<dd>Gerbonara abstracts away the details of the underlying file format such as tool indices, coordinate notation and
graphical state, and presents meaningful &quot;graphical objects&quot; such as a <cite>primitives.Line</cite>,
<cite>primitives.Arc</cite>, or <cite>Region</cite> through its API. These objects can be easily created,
manipulated or deleted from code without breaking anything else. You can even copy graphical objects between files,
and Gerbonara will automatically convert coordinate format, units etc. for you. <cite>GerberFile</cite> and
<cite>ExcellonFile</cite> use the same types of <cite>graphic objects &lt;object-api&gt;</cite>, so objects can be directly
copied between file types without conversion.</dd>
<dt><strong>Unit-safety</strong></dt>
<dd>Gerbonara embeds physical <cite>LengthUnit</cite> information in all objects. The high-level API such as
<cite>LayerStack.merge</cite> or <cite>GerberFile.offset</cite> accepts arguments with an explicitly given unit and
automatically converts them as needed. Objects can be copied between <cite>GerberFile</cite> instances and unit
conversion will be handled transparently in the background.</dd>
</dl>
<p>Gerbonara was started as an extensive refactoring of the <a class="reference external" href="https://github.com/opiopan/pcb-tools-extension">pcb-tools</a> and <a class="reference external" href="https://github.com/curtacircuitos/pcb-tools/issues">pcb-tools-extension</a> packages. Both of these
have statement-based APIs, that is, they parse input files into one python object for every line in the file. This means
that when saving files they can recreate the input file almost byte by byte, but manipulating a file by changing
statements without breaking things is <em>hard</em>.</p>
<p>Gerbonara powers <a class="reference external" href="https://github.com/jaseg/gerbolyze">gerbolyze</a>, a tool for converting <a class="reference external" href="https://en.wikipedia.org/wiki/Scalable_Vector_Graphics">SVG</a> vector graphics files into Gerber, and embedding <a class="reference external" href="https://en.wikipedia.org/wiki/Scalable_Vector_Graphics">SVG</a> into
existing Gerber files exported from a normal PCB tool for artistic purposes.</p>
<div class="section" id="features">
<h2>Features</h2>
<blockquote>
<ul class="simple">
<li>File I/O
* Gerber, Excellon (drill file), IPC-356 (netlist) read and write
* supports file-level operations: offset, rotate, merge for all file types</li>
<li>Modification API (<cite>GraphicObject</cite>)</li>
<li>Rendering API (<cite>GraphicPrimitive</cite>)</li>
<li>SVG export</li>
<li>Full aperture macro support, including transformations (offset, rotation)</li>
</ul>
</blockquote>
</div>
<div class="section" id="quick-start">
<h2>Quick Start</h2>
<p>First, install gerbonara from PyPI using pip:</p>
<pre class="code shell literal-block">
<span class="lineno"></span><span class="line">pip<span class="w"> </span>install<span class="w"> </span>--user<span class="w"> </span>gerbonara
</span></pre>
<p>Then, you are ready to read and write gerber files:</p>
<pre class="code python literal-block">
<span class="lineno"></span><span class="line"><span class="kn">from</span> <span class="nn">gerbonara</span> <span class="kn">import</span> <span class="n">LayerStack</span><span class="w"></span></span>
<span class="lineno"></span><span class="line"><span class="w"></span></span>
<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">stack</span> <span class="o">=</span> <span class="n">LayerStack</span><span class="o">.</span><span class="n">from_directory</span><span class="p">(</span><span class="s1">'output/gerber'</span><span class="p">)</span><span class="w"></span></span>
<span class="lineno"></span><span class="line"><span class="w"></span><span class="n">w</span><span class="p">,</span> <span class="n">h</span> <span class="o">=</span> <span class="n">stack</span><span class="o">.</span><span class="n">outline</span><span class="o">.</span><span class="n">size</span><span class="p">(</span><span class="s1">'mm'</span><span class="p">)</span><span class="w"></span></span>
<span class="lineno"></span><span class="line"><span class="w"></span><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'Board size is </span><span class="si">{</span><span class="n">w</span><span class="si">:</span><span class="s1">.1f</span><span class="si">}</span><span class="s1"> mm x </span><span class="si">{</span><span class="n">h</span><span class="si">:</span><span class="s1">.1f</span><span class="si">}</span><span class="s1"> mm'</span><span class="p">)</span>
</span></pre>
</div>
<div class="section" id="command-line-interface">
<h2>Command-Line Interface</h2>
<p>Gerbonara comes with a <cite>built-in command-line interface&lt;cli-doc&gt;</cite> that has functions for analyzing, rendering,
modifying, and merging Gerber files. To access it, use either the <tt class="docutils literal">gerbonara</tt> command that is part of the python
package, or run <tt class="docutils literal">python <span class="pre">-m</span> gerbonara</tt> For a list of functions or help on their usage, you can use:</p>
<pre class="code console literal-block">
<span class="lineno"></span><span class="line"><span class="gp">$ </span>python<span class="w"> </span>-m<span class="w"> </span>gerbonara<span class="w"> </span>--help<span class="w"></span></span>
<span class="lineno"></span><span class="line"><span class="w"></span><span class="go">[...]</span></span>
<span class="lineno"></span><span class="line"><span class="go"></span><span class="gp">$ </span>python<span class="w"> </span>-m<span class="w"> </span>gerbonara<span class="w"> </span>render<span class="w"> </span>--help
</span></pre>
</div>
<div class="section" id="development">
<h2>Development</h2>
<p>Gerbonara is developed on Gitlab under the gerbolyze org:</p>
<p><a class="reference external" href="https://gitlab.com/gerbolyze/gerbonara/">https://gitlab.com/gerbolyze/gerbonara/</a></p>
<p>A mirror of the repository can be found at:</p>
<p><a class="reference external" href="https://git.jaseg.de/gerbonara">https://git.jaseg.de/gerbonara</a></p>
<p>Our issue tracker is also on Gitlab:</p>
<p><a class="reference external" href="https://gitlab.com/gerbolyze/gerbonara/-/issues">https://gitlab.com/gerbolyze/gerbonara/-/issues</a></p>
<p>The documentation can be found at gitlab:</p>
<p><a class="reference external" href="https://gerbolyze.gitlab.io/gerbonara/">https://gerbolyze.gitlab.io/gerbonara/</a></p>
<p>With Gerbonara, we aim to support as many different format variants as possible. If you have a file that Gerbonara can't
open, please file an issue on our issue tracker. Even if Gerbonara can open all your files, for regression testing we
are very interested in example files generated by any CAD or CAM tool that is not already on the list of supported
tools.</p>
</div>
<div class="section" id="supported-cad-tools">
<h2>Supported CAD Tools</h2>
<p>Compatibility with the output of these CAD tools is tested as part of our test suite using example files generated by
these tools. Note that not all of these tools come with default Gerber file naming rules, so YMMV if your Gerbers use
some non-standard naming convention.</p>
<blockquote>
<ul class="simple">
<li>Allegro</li>
<li>Altium</li>
<li>Diptrace</li>
<li>Eagle</li>
<li>EasyEDA</li>
<li>Fritzing</li>
<li>gEDA</li>
<li>KiCAD</li>
<li>pcb-rnd</li>
<li>Siemens / Mentor Graphics Xpedition</li>
<li>Siemens PADS</li>
<li>Target 3001!</li>
<li>Upverter</li>
<li>Zuken CR-8000</li>
</ul>
</blockquote>
</div>
</div>
    </main><footer>
    Copyright © 2023 Jan Sebastian Götte
    / <a href="/about/">About</a>
    / <a href="/imprint/">Imprint</a>
</footer>
<script src="/pagefind/pagefind-ui.js"></script>
        <script>
            if(navigator.getEnvironmentIntegrity!==undefined)document.querySelector('body').innerHTML=`<h1>Your browser
            contains Google DRM</h1>"Web Environment Integrity" is a Google euphemism for a DRM that is designed to
            prevent ad-blocking, and which Google has forced into their browsers against widespread public opposition.
                In support of an open web, this website does not function with this DRM. Please install a browser such
            as <a href="https://www.mozilla.org/en-US/firefox/new/">Firefox</a> that respects your freedom and supports
            ad blockers.`;

            window.addEventListener('DOMContentLoaded', (event) => {
                new PagefindUI({element: "#search", showSubResults: true});
            });
        </script>
    </body>
</html>