summaryrefslogtreecommitdiff
path: root/projects/gerbolyze/index.html
blob: 575a54cb20be6637adaa86f00f934385cb3bc35c (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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
<!DOCTYPE html>
<html><head>
    <meta charset="utf-8">
    <title>Gerbolyze | 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="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>Gerbolyze</h1>
<ul class="breadcrumbs">
    <li><a href="/">jaseg.de</a></li>
    <li><a href="/projects/">Projects</a></li><li><a href="/projects/gerbolyze/">Gerbolyze</a></li>
</ul>

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


<p>Gerbolyze renders SVG vector and PNG/JPG raster images into existing gerber PCB manufacturing files.
Vector data from SVG files is rendered losslessly <em>without</em> an intermediate rasterization/revectorization step.
Still, gerbolyze supports (almost) the full SVG 1.1 spec including complex, self-intersecting paths with holes,
patterns, dashes and transformations.</p>
<p>Raster images can either be vectorized through contour tracing (like gerbolyze v1.0 did) or they can be embedded using
high-resolution grayscale emulation while (mostly) guaranteeing trace/space design rules.</p>
<p>Try gerbolyze online at <a class="reference external" href="https://dyna.kokoroyukuma.de/gerboweb">https://dyna.kokoroyukuma.de/gerboweb</a></p>
<div class="figure">
<img alt="pics/pcbway_sample_02_small.jpg" src="pics/pcbway_sample_02_small.jpg" style="width: 800px;" />
<p class="caption">Drawing by <a class="reference external" href="https://twitter.com/fluffy2038/status/1317231121269104640">トーコ Toko</a> converted using Gerbolyze and printed at PCBWay.</p>
</div>
<p>Tooling for PCB art is quite limited in both open source and closed source ecosystems. Something as simple as putting a
pretty picture on a PCB can be an extremely tedious task. Depending on the PCB tool used, various arcane incantations
may be necessary and even modestly complex images will slow down most PCB tools to a crawl.</p>
<p>Gerbolyze solves this problem in a toolchain-agnostic way by directly vectorizing SVG vector and PNG or JPG bitmap files
onto existing gerber layers. Gerbolyze processes any spec-compliant SVG and &quot;gerbolyzes&quot; SVG vector data into a Gerber
spec-compliant form. Gerbolyze has been tested against both the leading open-source KiCAD toolchain and the
industry-standard Altium Designer. Gerbolyze is written with performance in mind and will happily vectorize tens of
thousands of primitives, generating tens of megabytes of gerber code without crapping itself. With gerbolyze you can
finally be confident that your PCB fab's toolchain will fall over before yours does if you overdo it with the high-poly
anime silkscreen.</p>
<p>Gerbolyze is based on <a class="reference external" href="https://gitlab.com/gerbolyze/gerbonara">gerbonara</a>.</p>
<img alt="pics/process-overview.png" src="pics/process-overview.png" style="width: 800px;" />
<div class="contents topic" id="contents">
<p class="topic-title">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#tl-dr-produce-high-quality-artistic-pcbs-in-three-easy-steps" id="toc-entry-1">Tl;dr: Produce high-quality artistic PCBs in three easy steps!</a></li>
<li><a class="reference internal" href="#quick-start-installation-any-platform" id="toc-entry-2">Quick Start Installation (Any Platform)</a></li>
<li><a class="reference internal" href="#speeding-up-gerbolyze-using-natively-built-binaries" id="toc-entry-3">Speeding up gerbolyze using natively-built binaries</a><ul>
<li><a class="reference internal" href="#build-from-source-any-distro" id="toc-entry-4">Build from source (any distro)</a></li>
</ul>
</li>
<li><a class="reference internal" href="#features" id="toc-entry-5">Features</a></li>
<li><a class="reference internal" href="#algorithm-overview" id="toc-entry-6">Algorithm Overview</a></li>
<li><a class="reference internal" href="#web-interface" id="toc-entry-7">Web interface</a></li>
<li><a class="reference internal" href="#command-line-usage" id="toc-entry-8">Command-line usage</a><ul>
<li><a class="reference internal" href="#gerbolyze-template" id="toc-entry-9"><tt class="docutils literal">gerbolyze template</tt></a><ul>
<li><a class="reference internal" href="#options" id="toc-entry-10">Options:</a></li>
</ul>
</li>
<li><a class="reference internal" href="#gerbolyze-paste" id="toc-entry-11"><tt class="docutils literal">gerbolyze paste</tt></a><ul>
<li><a class="reference internal" href="#options-1" id="toc-entry-12">Options:</a></li>
<li><a class="reference internal" href="#outline-layers-1" id="toc-entry-13">Outline layers</a></li>
<li><a class="reference internal" href="#subtraction-scripts" id="toc-entry-14">Subtraction scripts</a></li>
</ul>
</li>
<li><a class="reference internal" href="#svg-flatten-1" id="toc-entry-15"><tt class="docutils literal"><span class="pre">svg-flatten</span></tt></a><ul>
<li><a class="reference internal" href="#options-2" id="toc-entry-16">Options:</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#gerbolyze-image-vectorization" id="toc-entry-17">Gerbolyze image vectorization</a><ul>
<li><a class="reference internal" href="#vectorizer-poisson-disc-the-default" id="toc-entry-18"><tt class="docutils literal"><span class="pre">--vectorizer</span> <span class="pre">poisson-disc</span></tt> (the default)</a></li>
<li><a class="reference internal" href="#vectorizer-hex-grid" id="toc-entry-19"><tt class="docutils literal"><span class="pre">--vectorizer</span> <span class="pre">hex-grid</span></tt></a></li>
<li><a class="reference internal" href="#vectorizer-square-grid" id="toc-entry-20"><tt class="docutils literal"><span class="pre">--vectorizer</span> <span class="pre">square-grid</span></tt></a></li>
<li><a class="reference internal" href="#vectorizer-binary-contours" id="toc-entry-21"><tt class="docutils literal"><span class="pre">--vectorizer</span> <span class="pre">binary-contours</span></tt></a></li>
</ul>
</li>
<li><a class="reference internal" href="#gimp-halftone-preprocessing-guide" id="toc-entry-22">GIMP halftone preprocessing guide</a><ul>
<li><a class="reference internal" href="#import-your-desired-artwork" id="toc-entry-23">1 Import your desired artwork</a></li>
<li><a class="reference internal" href="#convert-the-image-to-grayscale" id="toc-entry-24">2 Convert the image to grayscale</a></li>
<li><a class="reference internal" href="#fine-tune-the-image-s-contrast" id="toc-entry-25">3 Fine-tune the image's contrast</a></li>
<li><a class="reference internal" href="#retouch-details" id="toc-entry-26">4 Retouch details</a></li>
<li><a class="reference internal" href="#run-the-newsprint-filter" id="toc-entry-27">5 Run the newsprint filter</a></li>
<li><a class="reference internal" href="#export-the-image-for-use-with-gerbolyze-vectorize" id="toc-entry-28">6 Export the image for use with <tt class="docutils literal">gerbolyze vectorize</tt></a></li>
</ul>
</li>
<li><a class="reference internal" href="#manufacturing-considerations" id="toc-entry-29">Manufacturing Considerations</a></li>
<li><a class="reference internal" href="#limitations" id="toc-entry-30">Limitations</a><ul>
<li><a class="reference internal" href="#svg-raster-features" id="toc-entry-31">SVG raster features</a></li>
<li><a class="reference internal" href="#gerber-pass-through" id="toc-entry-32">Gerber pass-through</a></li>
<li><a class="reference internal" href="#trace-space-design-rule-adherence" id="toc-entry-33">Trace/Space design rule adherence</a></li>
</ul>
</li>
<li><a class="reference internal" href="#gallery" id="toc-entry-34">Gallery</a></li>
<li><a class="reference internal" href="#licensing" id="toc-entry-35">Licensing</a></li>
</ul>
</div>
<div class="section" id="tl-dr-produce-high-quality-artistic-pcbs-in-three-easy-steps">
<h2><a class="toc-backref" href="#toc-entry-1">Tl;dr: Produce high-quality artistic PCBs in three easy steps!</a></h2>
<p>Gerbolyze works in three steps.</p>
<ol class="arabic">
<li><p class="first">Generate a scale-accurate template of the finished PCB from your CAD tool's gerber output:</p>
<pre class="code literal-block">
<span class="lineno"></span><span class="line">$ gerbolyze template --top template_top.svg [--bottom template_bottom.svg] my_gerber_dir
</span></pre>
</li>
<li><p class="first">Load the resulting template image <a class="reference external" href="https://inkscape.org/">Inkscape</a> or another SVG editing program. Put your artwork on the appropriate SVG
layer. Dark colors become filled gerber primitives, bright colors become unfilled primitives. You can directly put
raster images (PNG/JPG) into this SVG as well, just position and scale them like everything else. SVG clips work for
images, too. Masks are not supported.</p>
</li>
<li><p class="first">Vectorize the edited SVG template image drectly into the PCB's gerber files:</p>
<pre class="code literal-block">
<span class="lineno"></span><span class="line">$ gerbolyze paste --top template_top_edited.svg [--bottom ...] my_gerber_dir output_gerber_dir
</span></pre>
</li>
</ol>
</div>
<div class="section" id="quick-start-installation-any-platform">
<h2><a class="toc-backref" href="#toc-entry-2">Quick Start Installation (Any Platform)</a></h2>
<pre class="code shell literal-block">
<span class="lineno"></span><span class="line">python<span class="w"> </span>-m<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>--user<span class="w"> </span>gerbolyze
</span></pre>
<p>To uninstall, run</p>
<pre class="code shell literal-block">
<span class="lineno"></span><span class="line">python<span class="w"> </span>-m<span class="w"> </span>pip<span class="w"> </span>uninstall<span class="w"> </span>gerbolyze<span class="w"> </span>gerbonara<span class="w"> </span>resvg-wasi<span class="w"> </span>svg-flatten-wasi
</span></pre>
<p>To update, run</p>
<pre class="code shell literal-block">
<span class="lineno"></span><span class="line">python<span class="w"> </span>-m<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>--user<span class="w"> </span>--upgrade<span class="w"> </span>--upgrade-strategy<span class="w"> </span>eager<span class="w"> </span>gerbolyze
</span></pre>
</div>
<div class="section" id="speeding-up-gerbolyze-using-natively-built-binaries">
<h2><a class="toc-backref" href="#toc-entry-3">Speeding up gerbolyze using natively-built binaries</a></h2>
<p>This will install gerbolyze's binary dependency resvg and gerbolyze's svg-flatten utility as pre-built cross-platform
WASM binaries. When you first run gerbolyze, it will take some time (~30s) to link these binaries for your system. The
output is cached, so any future run is going to be fast.</p>
<p>WASM is slower than natively-built binaries. To speed up gerbolyze, you can natively build its two binary dependencies:</p>
<ol class="arabic simple">
<li>Install resvg natively using rust's cargo package manager: <tt class="docutils literal">cargo install resvg</tt></li>
<li>Install gerbolyze's svg-flatten utility natively. You can get pre-built binaries from gerbolyze's gitlab CI jobs <a class="reference external" href="https://gitlab.com/gerbolyze/gerbolyze/-/pipelines?scope=tags&amp;page=1">at
this link</a> by clicking the three dots on the
right next to the version you want. These pre-built binaries should work on any x86_64 linux since they are
statically linked. You can also build svg-flatten yourself by running <tt class="docutils literal">make</tt> inside the <tt class="docutils literal"><span class="pre">svg-flatten</span></tt> folder from
a gerbolyze checkout.</li>
</ol>
<p>Gerbolyze will pick up these binaries when installed in your <tt class="docutils literal">$PATH</tt>. resvg is also picked up when it is installed by
cargo in your home's <tt class="docutils literal"><span class="pre">~/.cargo</span></tt>, even if it's not in your <tt class="docutils literal">$PATH</tt>. You can override the resvg, usvg or svg-flatten
binary that gerbolyze uses by giving it the absoulute path to a binary in the <tt class="docutils literal">$RESVG</tt>, <tt class="docutils literal">$USVG</tt> and <tt class="docutils literal">$SVG_FLATTEN</tt>
environment variables.</p>
<div class="section" id="build-from-source-any-distro">
<h3><a class="toc-backref" href="#toc-entry-4">Build from source (any distro)</a></h3>
<pre class="code sh literal-block">
<span class="lineno"></span><span class="line">git<span class="w"> </span>clone<span class="w"> </span>--recurse-submodules<span class="w"> </span>https://git.jaseg.de/gerbolyze.git<span class="w"></span></span>
<span class="lineno"></span><span class="line"><span class="w"></span><span class="nb">cd</span><span class="w"> </span>gerbolyze<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>python3<span class="w"> </span>-m<span class="w"> </span>venv<span class="w"></span></span>
<span class="lineno"></span><span class="line"><span class="w"></span><span class="nb">source</span><span class="w"> </span>venv/bin/activate<span class="w"></span></span>
<span class="lineno"></span><span class="line"><span class="w"></span>python3<span class="w"> </span>setup.py<span class="w"> </span>install
</span></pre>
</div>
</div>
<div class="section" id="features">
<h2><a class="toc-backref" href="#toc-entry-5">Features</a></h2>
<p>Input on the left, output on the right.</p>
<img alt="pics/test_svg_readme_composited.png" src="pics/test_svg_readme_composited.png" style="width: 800px;" />
<ul class="simple">
<li>Almost full SVG 1.1 static spec coverage (!)<ul>
<li>Paths with beziers, self-intersections and holes</li>
<li>Strokes, even with dashes and markers</li>
<li>Pattern fills and strokes</li>
<li>Transformations and nested groups</li>
<li>Proper text rendering with support for complex text layout (e.g. Arabic)</li>
<li>&lt;image&gt; elements via either built-in vectorizer or built-in halftone processor</li>
<li>(some) CSS</li>
</ul>
</li>
<li>Writes Gerber, SVG or KiCAD S-Expression (<tt class="docutils literal">.kicad_mod</tt>) formats</li>
<li>Can export from top/bottom SVGs to a whole gerber layer stack at once with filename autodetection</li>
<li>Can export SVGs to <tt class="docutils literal">.kicad_mod</tt> files like svg2mod (but with full SVG support)</li>
<li>Beziers flattening with configurable tolerance using actual math!</li>
<li>Polygon intersection removal</li>
<li>Polygon hole removal (!)</li>
<li>Optionally vector-compositing of output: convert black/white/transparent image to black/transparent image</li>
<li>Renders SVG templates from input gerbers for accurate and easy scaling and positioning of artwork</li>
<li>layer masking with offset (e.g. all silk within 1mm of soldermask)</li>
<li>Can read gerbers from zip files</li>
<li>Limited SVG support for board outline layers (no fill/region support)</li>
<li>Dashed lines supported on board outline layers</li>
</ul>
<p>Gerbolyze is the end-to-end &quot;paste this svg into these gerbers&quot; command that handles all layers on both board sides at
once.  The heavy-duty computer geometry logic of gerbolyze is handled by the svg-flatten utility (<tt class="docutils literal"><span class="pre">svg-flatten</span></tt>
directory).  svg-flatten reads an SVG file and renders it into a variety of output formats. svg-flatten can be used like
a variant of the popular svg2mod that supports all of SVG and handles arbitrary input <tt class="docutils literal">&lt;path&gt;</tt> elements.</p>
</div>
<div class="section" id="algorithm-overview">
<h2><a class="toc-backref" href="#toc-entry-6">Algorithm Overview</a></h2>
<p>This is the algorithm gerbolyze uses to process a stack of gerbers.</p>
<ul class="simple">
<li>Map input files to semantic layers by their filenames</li>
<li>For each layer:<ul>
<li>load input gerber</li>
<li>Pass mask layers through <tt class="docutils literal">gerbv</tt> for conversion to SVG</li>
<li>Pass mask layers SVG through <tt class="docutils literal"><span class="pre">svg-flatten</span> <span class="pre">--dilate</span></tt></li>
<li>Pass input SVG through <tt class="docutils literal"><span class="pre">svg-flatten</span> <span class="pre">--only-groups</span> [layer]</tt></li>
<li>Overlay input gerber, mask and input svg</li>
<li>Write result to output gerber</li>
</ul>
</li>
</ul>
<p>This is the algorithm svg-flatten uses to process an SVG.</p>
<ul class="simple">
<li>pass input SVG through <a class="reference external" href="https://github.com/RazrFalcon/resvg">usvg</a></li>
<li>iterate depth-first through resulting SVG.<ul>
<li>for groups: apply transforms and clip and recurse</li>
<li>for images: Vectorize using selected vectorizer</li>
<li>for paths:<ul>
<li>flatten path using Cairo</li>
<li>remove self-intersections using Clipper</li>
<li>if stroke is set: process dash, then offset using Clipper</li>
<li>apply pattern fills</li>
<li>clip to clip-path</li>
<li>remove holes using Clipper</li>
</ul>
</li>
</ul>
</li>
<li>for KiCAD S-Expression export: vector-composite results using CavalierContours: subtract each clear output primitive
from all previous dark output primitives</li>
</ul>
</div>
<div class="section" id="web-interface">
<h2><a class="toc-backref" href="#toc-entry-7">Web interface</a></h2>
<p>You can try gerbolyze online at <a class="reference external" href="https://dyna.kokoroyukuma.de/gerboweb">https://dyna.kokoroyukuma.de/gerboweb</a></p>
<p>The web interface does not expose all of gerbolyze's bells and whistles, but it allows you to simply paste a single SVG
file on a board to try out gerbolyze. Upload your design on the web interface, then download the template for either the
top or bottom side, and put your artwork on the appropriate layer of that template using <a class="reference external" href="https://inkscape.org/">Inkscape</a>. Finally, upload the
modified template and let gerbolyze process your design.</p>
</div>
<div class="section" id="command-line-usage">
<h2><a class="toc-backref" href="#toc-entry-8">Command-line usage</a></h2>
<p id="command-line-usage-1">Generate SVG template from Gerber files:</p>
<pre class="code shell literal-block">
<span class="lineno"></span><span class="line">gerbolyze<span class="w"> </span>template<span class="w"> </span><span class="o">[</span>options<span class="o">]</span><span class="w"> </span><span class="o">[</span>--top<span class="p">|</span>--bottom<span class="o">]</span><span class="w"> </span>input_dir_or.zip<span class="w"> </span>output.svg
</span></pre>
<p>Render design from an SVG made with the template above into a set of gerber files:</p>
<pre class="code shell literal-block">
<span class="lineno"></span><span class="line">gerbolyze<span class="w"> </span>paste<span class="w"> </span><span class="o">[</span>options<span class="o">]</span><span class="w"> </span>artwork.svg<span class="w"> </span>input_dir_or.zip<span class="w"> </span>output_dir_or.zip
</span></pre>
<p>Use svg-flatten to convert an SVG file into Gerber or flattened SVG:</p>
<pre class="code shell literal-block">
<span class="lineno"></span><span class="line">svg-flatten<span class="w"> </span><span class="o">[</span>options<span class="o">]</span><span class="w"> </span>--format<span class="w"> </span><span class="o">[</span>gerber<span class="p">|</span>svg<span class="o">]</span><span class="w"> </span><span class="o">[</span>input_file.svg<span class="o">]</span><span class="w"> </span><span class="o">[</span>output_file<span class="o">]</span>
</span></pre>
<p>Use svg-flatten to convert an SVG file into the given layer of a KiCAD S-Expression (<tt class="docutils literal">.kicad_mod</tt>) file:</p>
<pre class="code shell literal-block">
<span class="lineno"></span><span class="line">svg-flatten<span class="w"> </span><span class="o">[</span>options<span class="o">]</span><span class="w"> </span>--format<span class="w"> </span>kicad<span class="w"> </span>--sexp-layer<span class="w"> </span>F.SilkS<span class="w"> </span>--sexp-mod-name<span class="w"> </span>My_Module<span class="w"> </span><span class="o">[</span>input_file.svg<span class="o">]</span><span class="w"> </span><span class="o">[</span>output_file<span class="o">]</span>
</span></pre>
<p>Use svg-flatten to convert an SVG file into a <tt class="docutils literal">.kicad_mod</tt> with SVG layers fed into separate KiCAD layers based on
their IDs like the popular <tt class="docutils literal">svg2mod</tt> is doing:</p>
<dl class="docutils">
<dt>Note:</dt>
<dd><p class="first">Right now, the input SVG's layers must have <em>ids</em> that match up KiCAD's s-exp layer names. Note that when you name
a layer in Inkscape that only sets a <tt class="docutils literal">name</tt> attribute, but does not change the ID. In order to change the ID in
Inkscape, you have to use Inkscape's &quot;object properties&quot; context menu function.</p>
<p>Also note that svg-flatten expects the layer names KiCAD uses in their S-Expression format. These are <em>different</em> to
the layer names KiCAD exposes in the UI (even though most of them match up!).</p>
<p class="last">For your convenience, there is an SVG template with all the right layer names and IDs located next to this README.</p>
</dd>
</dl>
<pre class="code shell literal-block">
<span class="lineno"></span><span class="line">svg-flatten<span class="w"> </span><span class="o">[</span>options<span class="o">]</span><span class="w"> </span>--format<span class="w"> </span>kicad<span class="w"> </span>--sexp-mod-name<span class="w"> </span>My_Module<span class="w"> </span><span class="o">[</span>input_file.svg<span class="o">]</span><span class="w"> </span><span class="o">[</span>output_file<span class="o">]</span>
</span></pre>
<div class="section" id="gerbolyze-template">
<h3><a class="toc-backref" href="#toc-entry-9"><tt class="docutils literal">gerbolyze template</tt></a></h3>
<p>Usage: <tt class="docutils literal">gerbolyze template [OPTIONS] INPUT</tt></p>
<p>Generate SVG template for gerbolyze paste from gerber files.</p>
<p>INPUT may be a gerber file, directory of gerber files or zip file with gerber files. The output file contains a preview
image of the input gerbers to allow you to position your artwork, as well as prepared Inkscape layers corresponding to
each gerber layer. Simply place your artwork in this SVG template using Inkscape. Starting in v3.0, gerbolyze
automatically keeps track of which board side (top or bottom) is contained in an SVG template.</p>
<div class="section" id="options">
<h4><a class="toc-backref" href="#toc-entry-10">Options:</a></h4>
<dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">--top</span> | <span class="pre">--bottom</span></tt></dt>
<dd>Output top or bottom side template. This affects both the preview image and the prepared Inkscape layers.</dd>
<dt><tt class="docutils literal"><span class="pre">--vector</span> | <span class="pre">--raster</span></tt></dt>
<dd>Embed preview renders into output file as SVG vector graphics instead of rendering them to PNG bitmaps. The
resulting preview may slow down your SVG editor.</dd>
<dt><tt class="docutils literal"><span class="pre">--raster-dpi</span> FLOAT</tt></dt>
<dd>DPI for rastering preview</dd>
<dt><tt class="docutils literal"><span class="pre">--bbox</span> TEXT</tt></dt>
<dd>Output file bounding box. Format: &quot;w,h&quot; to force [w] mm by [h] mm output canvas OR &quot;x,y,w,h&quot; to force [w] mm by [h]
mm output canvas with its bottom left corner at the given input gerber coördinates.</dd>
</dl>
</div>
</div>
<div class="section" id="gerbolyze-paste">
<h3><a class="toc-backref" href="#toc-entry-11"><tt class="docutils literal">gerbolyze paste</tt></a></h3>
<p>(see <a class="reference internal" href="#vectorization">below</a>)</p>
<p>Usage: <tt class="docutils literal">gerbolyze paste [OPTIONS] INPUT_GERBERS OVERLAY_SVG OUTPUT_GERBERS</tt></p>
<p>Render vector data and raster images from SVG file into gerbers. The SVG input file can be generated using <tt class="docutils literal">gerbolyze
template</tt> and contains the name and board side of each layer. Note that for board outline layers, handling slightly
differs from other layers as PCB fabs do not support filled Gerber regions on these layers.</p>
<div class="section" id="options-1">
<h4><a class="toc-backref" href="#toc-entry-12">Options:</a></h4>
<dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">--bbox</span> TEXT</tt></dt>
<dd>Output file bounding box. Format: &quot;w,h&quot; to force [w] mm by [h] mm output canvas OR &quot;x,y,w,h&quot; to force [w] mm by [h]
mm output canvas with its bottom left corner at the given input gerber coördinates. This <strong>must match the ``--bbox`` value given to
template</strong>!</dd>
<dt><tt class="docutils literal"><span class="pre">--subtract</span> TEXT</tt></dt>
<dd>Use user subtraction script from argument (see <a class="reference internal" href="#subtraction-script">below</a>)</dd>
<dt><tt class="docutils literal"><span class="pre">--no-subtract</span></tt></dt>
<dd>Disable subtraction (see <a class="reference internal" href="#subtraction-script">below</a>)</dd>
<dt><tt class="docutils literal"><span class="pre">--dilate</span> FLOAT</tt></dt>
<dd>Default dilation for subtraction operations in mm (see <a class="reference internal" href="#subtraction-script">below</a>)</dd>
<dt><tt class="docutils literal"><span class="pre">--trace-space</span> FLOAT</tt></dt>
<dd>Passed through to svg-flatten, see <a class="reference internal" href="#svg-flatten">below</a>.</dd>
<dt><tt class="docutils literal"><span class="pre">--vectorizer</span> TEXT</tt></dt>
<dd>Passed through to svg-flatten, see <a class="reference internal" href="#svg-flatten">its description below</a>. Also have a look at <a class="reference internal" href="#vectorization">the examples below</a>.</dd>
<dt><tt class="docutils literal"><span class="pre">--vectorizer-map</span> TEXT</tt></dt>
<dd>Passed through to svg-flatten, see <a class="reference internal" href="#svg-flatten">below</a>.</dd>
<dt><tt class="docutils literal"><span class="pre">--exclude-groups</span> TEXT</tt></dt>
<dd>Passed through to svg-flatten, see <a class="reference internal" href="#svg-flatten">below</a>.</dd>
</dl>
</div>
<div class="section" id="outline-layers-1">
<span id="outline-layers"></span><h4><a class="toc-backref" href="#toc-entry-13">Outline layers</a></h4>
<p>Outline layers require special handling since PCB fabs do not support filled G36/G37 polygons on these layers. The main
difference between normal layers and outline layers is how strokes are handled. On outline layers, strokes are
translated to normal Gerber draw commands (D01, D02 etc.) with an aperture set to the stroke's width instead of tracing
them to G36/G37 filled regions. This means that on outline layers, SVG end caps and line join types do not work: All
lines are redered with round joins and end caps.</p>
<p>One exception from this are patterns, which work as expected for both fills and strokes with full support for joins and
end caps.</p>
<p>Dashed strokes are supported on outline layers and can be used to make easy mouse bites.</p>
</div>
<div class="section" id="subtraction-scripts">
<span id="subtraction-script"></span><h4><a class="toc-backref" href="#toc-entry-14">Subtraction scripts</a></h4>
<img alt="pics/subtract_example.png" src="pics/subtract_example.png" style="width: 800px;" />
<p>Subtraction scripts tell <tt class="docutils literal">gerbolyze paste</tt> to remove an area around certain input layers to from an overlay layer.
When a input layer is given in the subtraction script, gerbolyze will dilate (extend outwards) everything on this input
layer and remove it from the target overlay layer. By default, Gerbolyze subtracts the mask layer from the silk layer to
make sure there are no silk primitives that overlap bare copper, and subtracts each input layer from its corresponding
overlay to make sure the two do not overlap. In the picture above you can see both at work: The overlay contains
halftone primitives all over the place. The subtraction script has cut out an area around all pads (mask layer) and all
existing silkscreen. You can turn off this behavior by passing <tt class="docutils literal"><span class="pre">--no-subtract</span></tt> or pass your own &quot;script&quot;.</p>
<p>The syntax of these scripts is:</p>
<pre class="code literal-block">
<span class="lineno"></span><span class="line">{target layer} -= {source layer} {dilation} [; ...]
</span></pre>
<p>The target layer must be <tt class="docutils literal"><span class="pre">out.{layer</span> name}</tt> and the source layer <tt class="docutils literal"><span class="pre">in.{layer</span> name}</tt>. The layer names are gerbolyze's
internal layer names, i.e.: <tt class="docutils literal">paste, silk, mask, copper, outline, drill</tt></p>
<p>The dilation value is optional, but can be a float with a leading <tt class="docutils literal">+</tt> or <tt class="docutils literal">-</tt>. If given, before subtraction the
source layer's features will be extended by that many mm. If not given, the dilation defaults to the value given by
<tt class="docutils literal"><span class="pre">--dilate</span></tt> if given or 0.1 mm otherwise. To disable dilation, simply pass <tt class="docutils literal">+0</tt> here.</p>
<p>Multiple commands can be separated by semicolons <tt class="docutils literal">;</tt> or line breaks.</p>
<p>The default subtraction script is:</p>
<pre class="code literal-block">
<span class="lineno"></span><span class="line">out.silk -= in.mask</span>
<span class="lineno"></span><span class="line">out.silk -= in.silk+0.5</span>
<span class="lineno"></span><span class="line">out.mask -= in.mask+0.5</span>
<span class="lineno"></span><span class="line">out.copper -= in.copper+0.5
</span></pre>
</div>
</div>
<div class="section" id="svg-flatten-1">
<span id="svg-flatten"></span><h3><a class="toc-backref" href="#toc-entry-15"><tt class="docutils literal"><span class="pre">svg-flatten</span></tt></a></h3>
<p>Usage: <tt class="docutils literal"><span class="pre">svg-flatten</span> <span class="pre">[OPTIONS]...</span> [INPUT_FILE] [OUTPUT_FILE]</tt></p>
<p>Specify <tt class="docutils literal">-</tt> for stdin/stdout.</p>
<div class="section" id="options-2">
<h4><a class="toc-backref" href="#toc-entry-16">Options:</a></h4>
<dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">-h,</span> <span class="pre">--help</span></tt></dt>
<dd>Print help and exit</dd>
<dt><tt class="docutils literal"><span class="pre">-v,</span> <span class="pre">--version</span></tt></dt>
<dd>Print version and exit</dd>
<dt><tt class="docutils literal"><span class="pre">-o,</span> <span class="pre">--format</span></tt></dt>
<dd>Output format. Supported: gerber, gerber-outline (for board outline layers), svg, s-exp (KiCAD S-Expression)</dd>
<dt><tt class="docutils literal"><span class="pre">-p,</span> <span class="pre">--precision</span></tt></dt>
<dd>Number of decimal places use for exported coordinates (gerber: 1-9, SVG: &gt;=0). Note that not all gerber viewers are
happy with too many digits. 5 or 6 is a reasonable choice.</dd>
<dt><tt class="docutils literal"><span class="pre">--clear-color</span></tt></dt>
<dd>SVG color to use in SVG output for &quot;clear&quot; areas (default: white)</dd>
<dt><tt class="docutils literal"><span class="pre">--dark-color</span></tt></dt>
<dd>SVG color to use in SVG output for &quot;dark&quot; areas (default: black)</dd>
<dt><tt class="docutils literal"><span class="pre">-f,</span> <span class="pre">--flip-gerber-polarity</span></tt></dt>
<dd>Flip polarity of all output gerber primitives for --format gerber.</dd>
<dt><tt class="docutils literal"><span class="pre">-d,</span> <span class="pre">--trace-space</span></tt></dt>
<dd>Minimum feature size of elements in vectorized graphics (trace/space) in mm. Default: 0.1mm.</dd>
<dt><tt class="docutils literal"><span class="pre">--no-header</span></tt></dt>
<dd>Do not export output format header/footer, only export the primitives themselves</dd>
<dt><tt class="docutils literal"><span class="pre">--flatten</span></tt></dt>
<dd>Flatten output so it only consists of non-overlapping white polygons. This perform composition at the vector level.
Potentially slow. This defaults to on when using KiCAD S-Exp export because KiCAD does not know polarity or colors.</dd>
<dt><tt class="docutils literal"><span class="pre">--no-flatten</span></tt></dt>
<dd>Disable automatic flattening for KiCAD S-Exp export</dd>
<dt><tt class="docutils literal"><span class="pre">--dilate</span></tt></dt>
<dd>Dilate output gerber primitives by this amount in mm. Used for masking out other layers.</dd>
<dt><tt class="docutils literal"><span class="pre">-g,</span> <span class="pre">--only-groups</span></tt></dt>
<dd>Comma-separated list of group IDs to export.</dd>
<dt><tt class="docutils literal"><span class="pre">-b,</span> <span class="pre">--vectorizer</span></tt></dt>
<dd>Vectorizer to use for bitmap images. One of poisson-disc (default), hex-grid, square-grid, binary-contours,
dev-null. Have a look at <a class="reference internal" href="#vectorization">the examples below</a>.</dd>
<dt><tt class="docutils literal"><span class="pre">--vectorizer-map</span></tt></dt>
<dd><p class="first">Map from image element id to vectorizer. Overrides --vectorizer.  Format: id1=vectorizer,id2=vectorizer,...</p>
<p class="last">You can use this to set a certain vectorizer for specific images, e.g. if you want to use both halftone
vectorization and contour tracing in the same SVG. Note that you can set an <tt class="docutils literal">&lt;image&gt;</tt> element's SVG ID from within
Inkscape though the context menu's Object Properties tool.</p>
</dd>
<dt><tt class="docutils literal"><span class="pre">--force-svg</span></tt></dt>
<dd>Force SVG input irrespective of file name</dd>
<dt><tt class="docutils literal"><span class="pre">--force-png</span></tt></dt>
<dd>Force bitmap graphics input irrespective of file name</dd>
<dt><tt class="docutils literal"><span class="pre">-s,</span> <span class="pre">--size</span></tt></dt>
<dd>Bitmap mode only: Physical size of output image in mm. Format: 12.34x56.78</dd>
<dt><tt class="docutils literal"><span class="pre">--sexp-mod-name</span></tt></dt>
<dd>Module name for KiCAD S-Exp output. This is a mandatory argument if using S-Exp output.</dd>
<dt><tt class="docutils literal"><span class="pre">--sexp-layer</span></tt></dt>
<dd>Layer for KiCAD S-Exp output. Defaults to auto-detect layers from SVG layer/top-level group IDs. If given, SVG
groups and layers are completely ignored and everything is simply vectorized into this layer, though you cna still
use <tt class="docutils literal"><span class="pre">-g</span></tt> for group selection.</dd>
<dt><tt class="docutils literal"><span class="pre">-a,</span> <span class="pre">--preserve-aspect-ratio</span></tt></dt>
<dd>Bitmap mode only: Preserve aspect ratio of image. Allowed values are meet, slice. Can also parse full SVG
preserveAspectRatio syntax.</dd>
<dt><tt class="docutils literal"><span class="pre">--no-usvg</span></tt></dt>
<dd>Do not preprocess input using usvg (do not use unless you know <em>exactly</em> what you're doing)</dd>
<dt><tt class="docutils literal"><span class="pre">--usvg-dpi</span></tt></dt>
<dd>Passed through to usvg's --dpi, in case the input file has different ideas of DPI than usvg has.</dd>
<dt><tt class="docutils literal"><span class="pre">--scale</span></tt></dt>
<dd>Scale input svg lengths by this factor (-o gerber only).</dd>
<dt><tt class="docutils literal"><span class="pre">-e,</span> <span class="pre">--exclude-groups</span></tt></dt>
<dd>Comma-separated list of group IDs to exclude from export. Takes precedence over --only-groups.</dd>
</dl>
</div>
</div>
</div>
<div class="section" id="gerbolyze-image-vectorization">
<span id="vectorization"></span><h2><a class="toc-backref" href="#toc-entry-17">Gerbolyze image vectorization</a></h2>
<p>Gerbolyze has two built-in strategies to translate pixel images into vector images. One is its built-in halftone
processor that tries to approximate grayscale. The other is its built-in binary vectorizer that traces contours in
black-and-white images. Below are examples for the four options.</p>
<p>The vectorizers can be used in isolation through <tt class="docutils literal"><span class="pre">svg-flatten</span></tt> with either an SVG input that contains an image or a
PNG/JPG input.</p>
<p>The vectorizer can be controlled globally using the <tt class="docutils literal"><span class="pre">--vectorizer</span></tt> flag in both <tt class="docutils literal">gerbolyze</tt> and <tt class="docutils literal"><span class="pre">svg-flatten</span></tt>. It
can also be set on a per-image basis in both using <tt class="docutils literal"><span class="pre">--vectorizer-map</span> [image svg <span class="pre">id]=[option][&quot;,&quot;</span> <span class="pre">...]</span></tt>.</p>
<!-- for f in vec_*.png; convert -background white -gravity center $f -resize 500x500 -extent 500x500 (basename -s .png $f)-square.png; end -->
<!-- for vec in hexgrid square poisson contours; convert vec_"$vec"_whole-square.png vec_"$vec"_detail-square.png -background transparent -splice 25x0+0+0 +append -chop 25x0+0+0 vec_"$vec"_composited.png; end -->
<div class="section" id="vectorizer-poisson-disc-the-default">
<h3><a class="toc-backref" href="#toc-entry-18"><tt class="docutils literal"><span class="pre">--vectorizer</span> <span class="pre">poisson-disc</span></tt> (the default)</a></h3>
<img alt="pics/vec_poisson_composited.png" src="pics/vec_poisson_composited.png" style="width: 800px;" />
</div>
<div class="section" id="vectorizer-hex-grid">
<h3><a class="toc-backref" href="#toc-entry-19"><tt class="docutils literal"><span class="pre">--vectorizer</span> <span class="pre">hex-grid</span></tt></a></h3>
<img alt="pics/vec_hexgrid_composited.png" src="pics/vec_hexgrid_composited.png" style="width: 800px;" />
</div>
<div class="section" id="vectorizer-square-grid">
<h3><a class="toc-backref" href="#toc-entry-20"><tt class="docutils literal"><span class="pre">--vectorizer</span> <span class="pre">square-grid</span></tt></a></h3>
<img alt="pics/vec_square_composited.png" src="pics/vec_square_composited.png" style="width: 800px;" />
</div>
<div class="section" id="vectorizer-binary-contours">
<h3><a class="toc-backref" href="#toc-entry-21"><tt class="docutils literal"><span class="pre">--vectorizer</span> <span class="pre">binary-contours</span></tt></a></h3>
<img alt="pics/vec_contours_composited.png" src="pics/vec_contours_composited.png" style="width: 800px;" />
<p>The binary contours vectorizer requires a black-and-white binary input image. As you can see, like every bitmap tracer
it will produce some artifacts. For artistic input this is usually not too bad as long as the input data is
high-resolution. Antialiased edges in the input image are not only OK, they may even help with an accurate
vectorization.</p>
</div>
</div>
<div class="section" id="gimp-halftone-preprocessing-guide">
<h2><a class="toc-backref" href="#toc-entry-22">GIMP halftone preprocessing guide</a></h2>
<p>Gerbolyze has its own built-in halftone processor, but you can also use the high-quality &quot;newsprint&quot; filter built into
<a class="reference external" href="https://gimp.org/">GIMP</a> instead if you like. This section will guide you through this. The PNG you get out of this can then be fed into
gerbolyze using <tt class="docutils literal"><span class="pre">--vectorizer</span> <span class="pre">binary-contours</span></tt>.</p>
<div class="section" id="import-your-desired-artwork">
<h3><a class="toc-backref" href="#toc-entry-23">1 Import your desired artwork</a></h3>
<p>Though anime or manga pictures are highly recommended, you can use any image including photographs. Be careful to select
a picture with comparatively low detail that remains recognizable at very low resolution. While working on a screen this
is hard to vizualize, but the grain resulting from the low resolution of a PCB's silkscreen is quite coarse.</p>
<img alt="screenshots/02import02.png" src="screenshots/02import02.png" style="width: 800px;" />
</div>
<div class="section" id="convert-the-image-to-grayscale">
<h3><a class="toc-backref" href="#toc-entry-24">2 Convert the image to grayscale</a></h3>
<img alt="screenshots/06grayscale.png" src="screenshots/06grayscale.png" style="width: 800px;" />
</div>
<div class="section" id="fine-tune-the-image-s-contrast">
<h3><a class="toc-backref" href="#toc-entry-25">3 Fine-tune the image's contrast</a></h3>
<p>To look well on the PCB, contrast is critical. If your source image is in color, you may have lost some contrast during
grayscale conversion. Now is the time to retouch that using the GIMP's color curve tool.</p>
<p>When using the GIMP's newsprint filter, bright grays close to white and dark grays close to black will cause very small
dots that might be beyond your PCB manufacturer's maximum resolution. To control this case, add small steps at the ends
of the grayscale value curve as shown (exaggerated) in the picture below. These steps saturate very bright grays to
white and very dark grays to black while preserving the values in the middle.</p>
<img alt="screenshots/08curve_cut.png" src="screenshots/08curve_cut.png" style="width: 800px;" />
</div>
<div class="section" id="retouch-details">
<h3><a class="toc-backref" href="#toc-entry-26">4 Retouch details</a></h3>
<p>Therer might be small details that don't look right yet, such as the image's background color or small highlights that
merge into the background now. You can manually change the color of any detail now using the GIMP's flood-fill tool.</p>
<p>If you don't want the image's background to show up on the final PCB at all, just make it black.</p>
<p>Particularly on low-resolution source images it may make sense to apply a blur with a radius similar to the following
newsprint filter's cell size (10px) to smooth out the dot pattern generated by the newsprint filter.</p>
<img alt="screenshots/09retouch.png" src="screenshots/09retouch.png" style="width: 800px;" />
<p>In the following example, I retouched the highlights in the hair of the character in the picture to make them completely
white instead of light-gray, so they still stand out nicely in the finished picture.</p>
<img alt="screenshots/10retouched.png" src="screenshots/10retouched.png" style="width: 800px;" />
</div>
<div class="section" id="run-the-newsprint-filter">
<h3><a class="toc-backref" href="#toc-entry-27">5 Run the newsprint filter</a></h3>
<p>Now, run the GIMP's newsprint filter, under filters, distorts, newsprint.</p>
<p>The first important settings is the spot size, which should be larger than your PCB's minimum detail size (about 10px
with <tt class="docutils literal">gerbolyze render</tt> default settings for good-quality silkscreen). In general the cheap and fast standard option of chinese PCB houses will require a larger detail size, but when you order specialty options like large size, 4-layer or non-green color along with a longer turnaround time you'll get much better-quality silk screen.</p>
<p>The second important setting is oversampling, which should be set to four or slightly higher. This improves the result
of the edge reconstruction of <tt class="docutils literal">gerbolyze vectorize</tt>.</p>
<img alt="screenshots/11newsprint.png" src="screenshots/11newsprint.png" style="width: 800px;" />
<p>The following are examples on the detail resulting from the newsprint filter.</p>
<img alt="screenshots/12newsprint.png" src="screenshots/12newsprint.png" style="width: 800px;" />
</div>
<div class="section" id="export-the-image-for-use-with-gerbolyze-vectorize">
<h3><a class="toc-backref" href="#toc-entry-28">6 Export the image for use with <tt class="docutils literal">gerbolyze vectorize</tt></a></h3>
<p>Simply export the image as a PNG file. Below are some pictures of the output <tt class="docutils literal">gerbolyze vectorize</tt> produced for this
example.</p>
<img alt="screenshots/14result_cut.png" src="screenshots/14result_cut.png" style="width: 800px;" />
<img alt="screenshots/15result_cut.png" src="screenshots/15result_cut.png" style="width: 800px;" />
</div>
</div>
<div class="section" id="manufacturing-considerations">
<h2><a class="toc-backref" href="#toc-entry-29">Manufacturing Considerations</a></h2>
<p>The main consideration when designing artwork for PCB processes is the processes' trace/space design rule. The two
things you can do here is one, to be creative with graphical parts of the design and avoid extremely narrow lines,
wedges or other thin features that will not come out well. Number two is to keep detail in raster images several times
larger than the manufacturing processes native capability. For example, to target a trace/space design rule of 100 µm,
the smallest detail in embedded raster graphics should not be much below 1mm.</p>
<p>Gerbolyze's halftone vectorizers have built-in support for trace/space design rules. While they can still produce small
artifacts that violate these rules, their output should be close enough to satifsy board houses and close enough for the
result to look good. The way gerbolyze does this is to clip the halftone cell's values to zero whenevery they get too
small, and to forcefully split or merge two neighboring cells when they get too close. While this process introduces
slight steps at the top and bottom of grayscale response, for most inputs these are not noticeable.</p>
<p>On the other hand, for SVG vector elements as well as for traced raster images, Gerbolyze cannot help with these design
rules. There is no heuristic that would allow Gerbolyze to non-destructively &quot;fix&quot; a design here, so all that's on the
roadmap here is to eventually include a gerber-level design rule checker.</p>
<p>As far as board houses go, I have made good experiences with the popular Chinese board houses. In my experience, JLC
will just produce whatever you send them with little fucks being given about design rule adherence or validity of the
input gerbers. This is great if you just want artistic circuit boards without much of a hassle, and you don't care if
they come out exactly as you imagined. The worst I've had happen was when an older version of gerbolyze generated
polygons with holes assuming standard fill-rule processing. The in the board house's online gerber viewer things looked
fine, and neither did they complain during file review. However, the resulting boards looked completely wrong because
all the dark halftones were missing.</p>
<p>PCBWay on the other hand has a much more rigurous file review process. They &lt;em&gt;will&lt;/em&gt; complain when you throw
illegal garbage gerbers at them, and they will helpfully guide you through your design rule violations. In this way you
get much more of a professional service from them and for designs that have to be functional their higher level of
scrutiny definitely is a good thing. For the design you saw in the first picture in this article, I ended up begging
them to just plot my files if it doesn't physically break their machines and to their credit, while they seemed unhappy
about it they did it and the result looks absolutely stunning.</p>
<p>PCBWay is a bit more expensive on their lowest-end offering than JLC, but I found that for anything else (large boards,
multi-layer, gold plating etc.) their prices match. PCBWay offers a much broader range of manufacturing options such as
flexible circuit boards, multi-layer boards, thick or thin substrates and high-temperature substrates.</p>
<p>When in doubt about how your design is going to come out on the board, do not hesitate to contact your board house. Most
of the end customer-facing online PCB services have a number of different factories that do a number of different
fabrication processes for them depending on order parameters. Places like PCBWay have exceptional quality control and
good customer service, but that is mostly focused on the technical aspects of the PCB. If you rely on visual aspects
like silkscreen uniformity or solder mask color that is a strong no concern to everyone else in the electronics
industry, you may find significant variations between manufacturers or even between orders with the same manufacturer
and you may encounter challenges communicating your requirements.</p>
</div>
<div class="section" id="limitations">
<h2><a class="toc-backref" href="#toc-entry-30">Limitations</a></h2>
<div class="section" id="svg-raster-features">
<h3><a class="toc-backref" href="#toc-entry-31">SVG raster features</a></h3>
<p>Currently, SVG masks and filters are not supported. Though SVG is marketed as a &quot;vector graphics format&quot;, these two
features are really raster primitives that all SVG viewers perform at the pixel level after rasterization. Since
supporting these would likely not end up looking like what you want, it is not a planned feature. If you need masks or
filters, simply export the relevant parts of the SVG as a PNG then include that in your template.</p>
</div>
<div class="section" id="gerber-pass-through">
<h3><a class="toc-backref" href="#toc-entry-32">Gerber pass-through</a></h3>
<p>Since gerbolyze has to composite your input gerbers with its own output, it has to fully parse and re-serialize them.
gerbolyze <a class="reference external" href="https://gitlab.com/gerbolyze/gerbonara">gerbonara</a> for all its gerber parsing needs. Thus, gerbonara will interpret your gerbers and output will be in
gerbonara's gerber &quot;dialect&quot;. If you find a corner case where this does not work and the output looks wrong, please file
a bug report with an example file on the <a class="reference external" href="https://gitlab.com/gerbolyze/gerbonara">gerbonara</a> bug tracker. <em>Always</em> check the output files for errors before
submitting them to production.</p>
<p>Gerbolyze is provided without any warranty, but still please open an issue or <a class="reference external" href="mailto:gerbolyze&#64;jaseg.de">send me an email</a> if you find any errors or inconsistencies.</p>
</div>
<div class="section" id="trace-space-design-rule-adherence">
<h3><a class="toc-backref" href="#toc-entry-33">Trace/Space design rule adherence</a></h3>
<p>While the grayscale halftone vectorizers do a reasonable job adhering to a given trace/space design rule, they can still
produce small parts of output that violate it. For the contour vectorizer as well as for all SVG primitives, you are
responsible for adhering to design rules yourself as there is no algorithm that gerboyze could use to &quot;fix&quot; its input.</p>
<p>A design rule checker is planned as a future addition to gerbolyze, but is not yet part of it. If in doubt, talk to your
fab and consider doing a test run of your design before ordering assembled boards ;)</p>
</div>
</div>
<div class="section" id="gallery">
<h2><a class="toc-backref" href="#toc-entry-34">Gallery</a></h2>
<img alt="pics/sample3.jpg" src="pics/sample3.jpg" style="width: 400px;" />
<p>For a demonstration of <tt class="docutils literal">gerbolyze convert</tt>, check out the <a class="reference external" href="https://dyna.kokoroyukuma.de/protos/">Gerbolyze Protoboard Index</a>, where you can download gerber
files for over 7.000 SMD and THT protoboard layouts.</p>
</div>
<div class="section" id="licensing">
<h2><a class="toc-backref" href="#toc-entry-35">Licensing</a></h2>
<p>This tool is licensed under the rather radical AGPLv3 license. Briefly, this means that you have to provide users of a
webapp using this tool in the backend with this tool's source.</p>
<p>I get that some people have issues with the AGPL. In case this license prevents you from using this software, please
send me <a class="reference external" href="mailto:agpl.sucks&#64;jaseg.de">an email</a> and I can grant you an exception. I want this software to be useful to as
many people as possible and I wouldn't want the license to be a hurdle to anyone. OTOH I see a danger of some cheap
board house just integrating a fork into their webpage without providing their changes back upstream, and I want to
avoid that so the default license is still AGPL.</p>
</div>
</div>
    </main><footer>
    Copyright © 2023 Jan Sebastian Götte
    / <a href="/about/">About</a>
    / <a href="/imprint/">Imprint</a>
</footer>
<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.`;
        </script>
    </body>
</html>