# pcb-rnd modularization

## Why bother...

I believe good software should be modular. This is especially important in the context of large software, such as CAD applications. There should be a thin core that can model the world and provide the basic operations defined on it but anything else should go in separate modules.

Fortunately PCB already had a strong infrastructure supporting this idea. It has dynamic loadable plugins and the GUI and exporters are in separate HID modules. While working on pcb-gpmi and later pcb-rnd, I added the gpmi module as a separate plugin.

In version 1.0.8 to 1.1.0 a considerable chunk of core code has been moved into core plugins. A core plugin is just a plugin that is maintained together with the core, in the same repository, still the code is somewhat detached from the core. More importantly, the user can choose, for each plugin, separately:

- to compile it as a buildin (static-link it into the pcb executable)
- to compile it as a plugin (dynamic-link it runtime, if the .so is installed in the plugins/ directory)
- to disable the plugin, so it is not compiled at all

I believe such modularization has benefits on multiple levels:

- it is possible to compile smaller, potentially faster executables by omitting features the specific user would never use anyway
- in a distribution dynamic-link plugins can be distributed as separate packages providing the user with the option to decide what features to install
- such plugins have to have some sort of APIs if they want to reference each other or if the code needs to reference them; such an API may not (and often did not) exist when the code is part of the core

## Progress in charts

### Before-after

All numbers are in SLOC and are acquired running sloccount on the given directory. While lines of code alone is not a true measure of complexity, it's a good estimation. The slices of pie charts are the major components of the pcb-rnd executable.

Before modularization: pcb-rnd version 1.0.7 Note: gpmi was already a plugin |  | After modularization: current pcb-rnd Note: gpmi is part of the "plugins" slice

### Zooming on to the plugins

total size per class

IO plugins

feature plugins

export plugins

HID plugins

import plugins

library plugins

footprint plugins

(Red means the plugin doesn't really work).

## Progress in numbers

Below is a table with the summary of core plugins.

module | size [sloc] | status | configure default | class | description
--- | --- | --- | --- | --- | ---
acompnet | 75 | WIP | disable | feature | Auto-complete the current network. A very limited autorouter/assistant.
autocrop | 52 | works | buildin | feature | Reduce the board dimensions to just enclose the objects on the board.
autoplace | 672 | works | buildin | feature | Automatically place subcircuits.
autoroute | 4358 | works | buildin | feature | Automatically route selected or all rats. This is the original autorouter.
boardflip | 167 | (doesn't update rtrees) | buildin | feature | All objects on the board are up-down flipped.
diag | 613 | works | disable | feature | Actions for pcb-rnd core diagnostics, intended for developers. These are not in core because end users normally don't need these. As a plugin, due to dynamic loading, it can be dropped on an existing pcb-rnd installation with minimal risk of scaring away a reproducible bug.
dialogs | 1138 | works | disable | feature | Interactive core functionality: HID-independent GUI dialogs (enabled by GUI HIDs)
distalign | 433 | works | buildin | feature | Introducing Align() and Distribute(), which work much like the similarly named functions in Visio. Given that PCB does not have the concept of "first selected object" to draw on, the reference points can be selected by arguments.
distaligntext | 469 | works | buildin | feature | Same as distalign, operates on text objects.
djopt | 2255 | works | buildin | feature | Various board optimization algorithms.
draw_csect | 741 | works | disable | feature | Draw cross section and layer map.
draw_fab | 282 | works | buildin | feature | Draw the fab layer (for various exporters).
draw_fontsel | 188 | works | disable | feature | Draw the font selector GUI
export_bboard | 439 | WIP | disable-all | export | Export breadboard
export_bom | 235 | works | buildin | export | Export bom (Bill of Materials)
export_dsn | 451 | works | buildin | export | Export specctra .dsn files
export_dxf | 595 | works | buildin | export | Export dxf
export_fidocadj | 279 | WIP | buildin | export | Export to FidoCadJ format (.fcd)
export_gcode | 2478 | works | buildin | export | Export to gcode
export_gerber | 1070 | works | buildin | export | Export to gerber
export_ipcd356 | 371 | works | buildin | export | IPC-D-356 Netlist export.
export_lpr | 104 | works | buildin | export | Export to lpr (using export_ps to generate postscript)
export_nelma | 678 | deprecated | disable | export | Export to nelma (Numerical capacitance calculator) - the 3rd party software, Nelma is not maintained any more.
export_openems | 1372 | WIP | disable | export | Export copper to OpenEMS simulation
export_openscad | 725 | WIP | buildin | export | Export openscad
export_png | 1382 | works | buildin | export | Export to png, gif and jpeg
export_ps | 1576 | works | buildin | export | Export postscript or embedded postscript.
export_stat | 295 | works | buildin | export | Export various board statistics in lihata format
export_svg | 654 | works | buildin | export | Scalable Vector Graphics (SVG) exporter
export_test | 94 | WIP | disable | export | A thin layer of code to dump exporter calls for testing the HID exporter API.
export_xy | 718 | works | buildin | export | Template based export of XY centroid subcircuit data e.g. for pick & place.
extedit | 305 | works | buildin | feature | invoke external program to edit parts of the current board
fontmode | 262 | works | buildin | feature | Font editing actions.
fp_board | 131 | WIP | buildin | fp | Footprint: load a board and expose all the unique subcircuits on that board as a footprint library
fp_fs | 424 | works | buildin | fp | Footprint: file system based implementation. Used to be called Newlib: load footprints from directories. Run external processes for the parametric footprints.
fp_wget | 628 | works | buildin | fp | Footprint: get static (file) footprints from the web, e.g. from http://gedasymbols.org
gpmi | 2799 | works | buildin | feature | Scriptable plugin system with about 10 scripting languages supported and dynamic load/unload of scripts that can manipulate the GUI, the board, can implement exporters, etc.
hid_batch | 324 | works | buildin | hid | HID without GUI: read actions from stdin.
hid_gtk2_gdk | 1227 | works | buildin | hid | GUI: GTK2 HID with GDK software rendering.
hid_gtk2_gl | 924 | works | buildin | hid | GUI: GTK2 with opengl rendering
hid_gtk3_cairo | 1131 | WIP | disable-all | hid | GUI: the GTK3 HID, using cairo for rendering
hid_gtk3_gl | 52 | WIP | disable-all | hid | GUI: the GTK3 HID, using gl for rendering
hid_lesstif | 6595 | works | buildin | hid | GUI: the lesstif HID.
hid_remote | 1185 | WIP | disable-all | hid | Remote access HID: implement a protocol and use it to relay between a core and a remote HID implementation.
import_dsn | 269 | works | buildin | import | Import specctra .dsn files
import_edif | 3628 | works | buildin | import | Import plugin for netlists in the EDIF format.
import_hpgl | 133 | works | buildin | import | Emulate a plotter and import the plot as lines, arcs and polygons.
import_ipcd356 | 378 | works | buildin | import | IPC-D-356 Netlist and pad centroid import
import_ltspice | 244 | works | buildin | import | Import the netlist and footprints from an ltspice .asc and .net pair of files
import_mentor_sch | 495 | works | buildin | import | Import Mentor Graphics Design Capture from flattened .edf netlist, using a parts conversion table.
import_mucs | 119 | works | buildin | import | Import lines and vias from MUCS unixplot .pl files
import_netlist | 141 | works | buildin | import | Import plugin for netlists in the classic pcb netlist format.
import_sch | 310 | works | buildin | import | Imports footprints and netlist data from the schematics (or some other source).
import_tinycad | 151 | works | buildin | import | Import the netlist and footprints from a tinycad netlist.
io_autotrax | 1578 | works | buildin | io | Import and export autotrax layouts and footprints.
io_eagle | 3902 | works | buildin | io | Load the design from eagle's xml and binary formats.
io_hyp | 4065 | works | buildin | io | Import plugin for hyperlynx geometry (no polygons yet).
io_kicad | 3478 | works | buildin | io | Load and save the design and footprints in Kicad's s-expression format - this is the new, currently preferred format in Kicad.
io_kicad_legacy | 878 | works | buildin | io | Export the design and footprints in Kicad's legacy format.
io_lihata | 3784 | works | buildin | io | Load and save the design and footprints in the lihata board format.
io_mentor_cell | 400 | WIP | disable | io | Load Mentor Graphics cell footprint library and make footprints available (e.g. for fp_board)
io_pcb | 2723 | works | buildin | io | Load and save the design and footprints in the original gEDA/PCB text format.
io_tedax | 831 | works | buildin | import | Import and export tEDAx netlists and footprints.
jostle | 432 | works | buildin | feature | Pushes lines out of the way.
lib_compat_help | 1155 | works | buildin | lib | a library of functions providing a simplified API compatibility layer, mainly for I/O plugins
lib_gensexpr | 13 | works | disable-all | lib | S-expression parser lib
lib_gtk_common | 10952 | works | disable-all | lib | hid_gtk* common code (regardless of gtk version or drawing mechanism: for both gtk2 and gtk3 and for both sw rendering and gl)
lib_gtk_config | 2395 | works | disable-all | lib | hid_gtk* preferences dialog common code (regardless of gtk version)
lib_gtk_hid | 1471 | works | disable-all | lib | Generic gtk HID implementation, independent of GTK version (2 vs. 3) and rendering engine. Mostly a dispatcher that fills in all the glue to connect the parts. An actual gtk HID implementation may use this lib or replace parts of it or the whole with local implementation.
lib_hid_common | 292 | works | disable-all | lib | hid_* common helper functions
lib_hid_gl | 1127 | works | disable-all | lib | generic openGL renderer shared among GUI HIDs
lib_legacy_func | 91 | works | buildin | lib | Random collection of old/obsolete (legacy) functions. 3rd party plugins may depend on them. This module implements C functions and variables and does not register actions or flags.
lib_netmap | 149 | works | disable-all | lib | create disposable cross-reference maps between all objects and all nets
lib_polyhelp | 703 | works | buildin | lib | functions to help plugins processing polygons and PolyHatch() action
loghid | 314 | WIP | disable | feature | Sits between a HID (or exporter) and the core and logs all core->plugin calls made through the HID structure.
millpath | 230 | WIP | disable | feature | Calculate and simulate toolpath for milling away opper
mincut | 886 | works | buildin | feature | Use the minimal cut algorithm to indicate shorts: instead of highlighting two random pins/pads, try to highlight the least number of objects that connect the two networks.
oldactions | 174 | works | disable | feature | Random collection of old/obsolete actions. Bell(): audible feedback, DumpLibrary(): print footprint library on stdout, a set of debug actions useful for writing pcb scripts: Debug(), DebugXY(), Return(). Old plugin actions to toggle or set settings that are now accessible via the unified config system (vendordrill, djopt)
polycombine | 209 | works | buildin | feature | The selected polygons are combined together according to the ordering of their points.
polystitch | 96 | works | buildin | feature | The polygon under the cursor (based on closest-corner) is stitched together with the polygon surrounding it on the same layer. Use with pstoedit conversions where there's a "hole" in the shape - select the hole.
propedit | 955 | works | buildin | feature | List and edit properties of a group of objects.
puller | 1731 | works | buildin | feature | Pull traces to minimize their length.
query | 1898 | works | buildin | feature | pcb-rnd query language: execute expressions on objects and rules for the programmed drc.
renumber | 331 | works | buildin | feature | Renumber subcircuits (renaming them) and generate a text file for back annotation.
report | 854 | works | buildin | feature | Report() and ReportObject() actions - print a report about design objects.
rubberband_orig | 1190 | works | buildin | feature | The original rubberband code.
shand_cmd | 214 | works | buildin | feature | vi-like command shorthands (1..3 character long commands)
shape | 686 | works | buildin | feature | Generate objects of regular shape (regular polygons, circle, round rect)
sketch_route | 28 | WIP | disable | feature | TODO

smartdisperse

172

works

buildin

feature

Improve the initial dispersion of subcircuits by choosing an order based on the netlist, rather than the arbitrary subcircuit order. This isn't the same as a global autoplace, it's more of a linear autoplace. It might make some useful local groupings. For example, you should not have to chase all over the board to find the resistor that goes with a given LED.

stroke | 121 | works | buildin | feature | Configurable gesture recognition with libstroke.
teardrops | 210 | works | buildin | feature | Draw teardrops on pins.
vendordrill | 517 | works | buildin | feature | Vendor drill mapping.

### Classes

Each plugin implements a class (rarely a set of classes). Classes are:

name | description
--- | ---
feature | random features directly accessible for the user, usually actions
lib | support code library for other plugins (core doesn't depend on these); functionality not directly accessible for the user but other plugins may depend on it
hid | Human Interface Device: interactive user interface, usually GUI
import | load alien formats into the design space
export | save (parts of) the design space in alien formats
fp | footprint (element) library implementation
io | native file format (save & load) implementation

### Status

Common status column values mean:

name | description
--- | ---
works | production quality code - configures, compiles, tested
WIP | work in progress: the plugin may be avaialble for testing but is not yet production quality
abandoned | unmaintained plugin; may be in working condition but there is no developer supporting it
deprecated | legacy plugin scheduled for removal; may still work but will soon be removed; if your workflow depends on it, please report ASAP

### Plugin dependency map