pcb-rnd hacking - how importers work


This document describes the common aspects of import code, be it an import_ plugin or the load part of an io_plugin, importing a footprint, loading a board or a netlist.

Data structures

The board is stored in pcb_board_t *. Some import code, like the one that loads a design (an io plugin's ->parse_pcb function), gets the target in an argument. (Other, non-import code usually operate on the global variable that represents the current board: pcb_board_t *PCB.).

In either case, pcb_board_t's most important field is pcb_data_t *data, which holds lists and vectors to store all objects on the board. When the target is a buffer (e.g. io plugin's ->parse_element function), it's a pcb_buffer_t *buf which also have a pcb_data_t *data containing the same data a board could.

A pcb_data_t struct in turn has three sets of important fields:

Each layer is a pcb_layer_t structure. A layer has the following fields:

Any code that needs to create objects should use the functions in obj_*.h. The functions that operate layer-independently usually get a destination as pcb_data_t, so they can operate both on boards and buffers. A typical example is pcb_pstk_t *pcb_pstk_new(pcb_data_t *data, ...) that returns NULL or the pointer to the new via that is already added to the corresponding list of data and in the rtree.

Layer object creation is done referencing the layer as pcb_layer_t *. A typical example is pcb_line_t *pcb_line_new(pcb_layer_t *layer...) which returns NULL on error or a pointer to the new line object created (inserted in the layer's line list, added to the rtree).

Code should avoid manipulating the lists and rtree structures directly.

Figure 1. simplified map of object related data structures
diamond: variable; rectangle: struct; round: struct field; green: drawing primitive

Extra steps around creating a new board

TODO: postproc, post*, other setup