## Layer addressing

When an action or configuration file requires a layer or layer group to be specified, it is usually done using the layer address or layer group address syntax specified below.

However, some old actions still require the raw id or name of a layer or layer group; in that case, the addressing syntax will not work and the required data has to be specified as is, without any prefix.

### Layer group address

The layer group address is used to name one or more matching layer group(s). If the code needs only one layer group and the address matches multiple, always the first match is used (the layer group with the lowest ID).

A layer group address contains at most two parts: the base address and optional supplements. The full version is base(supplements), but supplements can be omitted so base alone is also valid.

The base part is one of the following syntaxes:

syntax | description | example
--- | --- | ---
@groupname | find groups by their user assigned name (case sensitive string match) | @mysignal matches groups whose name is "mysignal"
location-material | find groups by their location and material | bottom-copper matches groups that are on the bottom side and are of copper
type[-type...] | same as location-material: types can really be used in any amount and any order, but matching groups have to match all types specified | mask matches any group that is a solder mask
type:offs | offs is a positive integer; use the Nth group of that type from top | copper:2 matches the second copper layer group from the top; offs is counted from 1, +1 meaning top surface layer
type:-offs | -offs is a negative integer; use the Nth group of that type from bottom | copper:-3 matches the third copper layer group from the bottom; offs is counted from 1, -1 meaning bottom surface layer
#group_id | index by the ID of the group; useful for scripting | #4 picks group 4, counting from 0

When supplements are specified, it's a comma separated list of key=value pairs. Available supplements are:

- purpose: specify matching layer group purpose field
- bloat: bloat or shrink objects by the specified value (e.g. 1mm), when transformations are available
- partial: only export objects with the EXPORTSEL flag set, when doing an export
- wireframe: draw layer with wireframe objects instead of solid objects
- thin_draw: draw layer with thin centerline objects instead of solid objects (implies thin_draw_poly)
- thin_draw_poly: draw layer with thin contour polygons instead of solid polygons
- check_planes: draw only (clipped) polygons
- flag_color: if the exporter supports colors, highlight objects that are found, selected or warned with screen color
- hide_floaters: omit rendering subcircuit floaters; warning: floaters are not only silk refdes text
- (TODO: supplement for inversion)

Supplement examples:

top-doc(purpose=assy) | the explicit top assembly layer group (by type)
top-virtual(purpose=assy) | the autogenerated top assembly layer group (by type); this works only if there is no explicit assy layer (legacy designs)
top-paste(bloat=0.1mm) | when using the address in CAM, export the top paste group with all objects bloated up by 0.1mm
virtual(purpose=pdrill) | for example in CAM: export plated drilled holes (padstack side effects, but no slots)
virtual(purpose=pdrill,bloat=0.1mm) | the above two combined

### Layer address

The layer address is used to name one or more matching layer(s). If the code needs only one layer and the address matches multiple, always the first match is used (the layer with the lowest ID). Note: layers are not indexed in physical stack order.

There are two kind of layer addresses: direct and through-group.

The direct address has only two variants:

syntax | description | example
--- | --- | ---
#idx | layer index (the internal, unique numbering, from 0) | #0 matches the first layer; useful only if the layer index was resolved earlier
@name | layer name - case sensitive match of user assigned layer name | @mysignal matches layers with name "mysignal"
¤t | the currently selected layer | ¤t

The through grup address has a group address, a slash and a local layer address. Counts are always from 1 (first layer within the group is count 1). It is one of:

syntax | description | example
--- | --- | ---
group/#count | layer index within the group | top-copper/#2 matches the second layer in the top copper group
group/#-count | layer index within the group | top-copper/#-1 matches the last layer in the top copper group
group/#count+ | layer index within the group, considering only positive layers | top-silk/#2 matches the second positive layer in the top silk group
group/#-count+ | layer index within the group counted back from the last, considering only positive layers | top-silk/#-1+ matches the last positive layer in the top silk group
group/#count- | layer index within the group, considering only negative (sub) layers | top-silk/#2- matches the second negative (sub) layer in the top silk group
group/#-count- | layer index within the group counted back from the last, considering only negative (sub) layers | top-silk/#-1- matches the last negative (sub) layer in the top silk group
group/@name | user assigned layer name matches name (only the group's layers are considered) | top-copper/@gnd matches the layer called "gnd" within the top copper group

Note: the full group addressing syntax can be used, so

    top-doc(purpose=assy)/#-1

works and means "fetch the first top documentation layer group whose purpose is assy and pick the last layer in that group".

### Best practices

Avoid addressing by user assigned name (the @ syntax): that scheme is fragile and unique names are not guaranteed.

When addressing a layer for the first time, it is best to use the group-type/#count syntax (e.g. top-copper/#1 for the first layer of the top copper group).

If a lot of accesses to the same layer is required (and the layer stack is not changed during the operation) the best strategy is to resolve the layer once , using e.g. the group-type/#count, then remember its layer idx and use the faster #idx addressing for subsequent access.