padne.kicad

Loading of KiCad projects and their conversion to our internal representation.

Attributes

Classes

StackupItem

Stackup

Directive

Represents a single directive in the schematic.

Endpoint

LayerPoint

PadIndex

This class effectively serves as a mapper from Endpoint to a bunch of LayerPoints

BaseLumpedSpec

Represents a base class that specifies a _single_ lumped element

ResistorSpec

Represents a base class that specifies a _single_ lumped element

VoltageSourceSpec

Represents a base class that specifies a _single_ lumped element

CurrentSourceSpec

Represents a base class that specifies a _single_ lumped element

RegulatorSpec

Represents a base class that specifies a _single_ lumped element

ProbeSpec

Specifies pads at which a mesh vertex must be forced, without adding any

CopperSpec

Copper process parameters for the project. All lengths are in mm.

ViaSpec

Specifies a via in the PCB.

KiCadProject

Represents a KiCad project with paths to its component files.

Directives

Accumulates different directive types that can be present in the schematic.

SchemaInstance

Represents a schematic instance in the hierarchy.

PlottedGerberLayer

Functions

find_pcbnew_module(→ Any)

Find and return the pcbnew module using multiple strategies.

is_kicad_version_at_least(→ bool)

nm_to_mm(→ float)

copper_layers(→ Iterator[int])

Iterate over layer IDs of copper layers in the given KiCad board.

extract_stackup_from_kicad_pcb(→ Stackup)

Extract the stackup from a KiCad PCB file.

extract_via_specs_from_pcb(→ list[ViaSpec])

Extract via specifications from a KiCad PCB.

extract_tht_pad_specs_from_pcb(→ list[ViaSpec])

Extract through-hole pad specifications from a KiCad PCB.

parse_endpoint(→ Endpoint)

Parse an endpoint in the format DESIGNATOR.PAD.

process_directives(→ Directives)

build_schema_hierarchy(→ SchemaInstance)

Build the complete schematic hierarchy starting from a root schematic.

flatten_schema_hierarchy(→ list[SchemaInstance])

Flatten a schema hierarchy into a list of all instances.

extract_directives_from_text(→ list[Directive])

Extract directives from a text string that may contain multiple lines.

extract_directives_from_schema(→ list[Directive])

extract_directives_from_hierarchy(→ list[Directive])

Extract all directives from a schematic hierarchy.

render_gerbers_from_kicad(→ list[PlottedGerberLayer])

Plot the given layers of a KiCad board to Gerbers and convert them to

plot_board_layer_to_gerber(board, layer_id, output_path)

Plot a single layer of a KiCad board to a Gerber file at output_path.

extract_layers_from_gerbers(→ list[PlottedGerberLayer])

Extract geometry from Gerber files and create PlottedGerberLayer objects.

extract_board_outline(...)

Extract board outline from a KiCad PCB. This uses the internal KiCad outline processing.

process_via_spec(→ list[padne.problem.Network])

punch_via_holes(→ list[PlottedGerberLayer])

verify_stackup_contains_all_layers(→ bool)

Return whether all plotted layers are contained within the stackup.

construct_layer_dict(→ dict[str, padne.problem.Layer])

Construct a dictionary mapping layer names to Layer objects.

clip_layer_with_outline(→ PlottedGerberLayer)

Clip a plotted layer's geometry with the board outline.

erode_layers_by_undercut(→ list[PlottedGerberLayer])

Shrink every copper edge by the etch undercut (in mm).

load_kicad_project(→ padne.problem.Problem)

Load a KiCad project and create a Problem object for PDN simulation.

Module Contents

padne.kicad.log[source]
padne.kicad.find_pcbnew_module() → Any[source]

Find and return the pcbnew module using multiple strategies.

Strategy order: 1. Try direct import of pcbnew (works when running inside KiCad or with system Python) 2. Try using kigadgets.get_pcbnew_module() (works in virtual environments)

Returns:

The pcbnew module

Raises:

ImportError: If pcbnew cannot be found via any method

padne.kicad.pcbnew[source]
padne.kicad.COPPER_CONDUCTIVITY = 59500.0[source]
padne.kicad.VIA_PLATING_THICKNESS = 0.025[source]
padne.kicad.is_kicad_version_at_least(major: int, minor: int) → bool[source]
padne.kicad.nm_to_mm(f: float) → float[source]
class padne.kicad.StackupItem[source]
class Type(*args, **kwds)[source]

Bases: enum.Enum

Create a collection of name/value pairs.

Example enumeration:

>>> class Color(Enum):
...     RED = 1
...     BLUE = 2
...     GREEN = 3

Access them by:

  • attribute access:

    >>> Color.RED
    <Color.RED: 1>
    
  • value lookup:

    >>> Color(1)
    <Color.RED: 1>
    
  • name lookup:

    >>> Color['RED']
    <Color.RED: 1>
    

Enumerations can be iterated over, and know how many members they have:

>>> len(Color)
3
>>> list(Color)
[<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]

Methods can be added to enumerations, and members can have their own attributes – see the documentation for details.

DIELECTRIC = 'DIELECTRIC'[source]
COPPER = 'COPPER'[source]
name: str[source]
thickness: float[source]
conductivity: float | None = None[source]
property conductance[source]
class padne.kicad.Stackup[source]
items: list[StackupItem][source]
index_by_name(name: str) → int[source]
item_by_name(name: str) → StackupItem[source]
padne.kicad.copper_layers(board: pcbnew) → Iterator[int][source]

Iterate over layer IDs of copper layers in the given KiCad board.

padne.kicad.extract_stackup_from_kicad_pcb(board: pcbnew, copper_conductivity: float = COPPER_CONDUCTIVITY) → Stackup[source]

Extract the stackup from a KiCad PCB file.

Args:

board: KiCad board object copper_conductivity: Copper conductivity in S/mm

class padne.kicad.Directive[source]

Represents a single directive in the schematic.

name: str[source]
params: dict[str, str][source]
classmethod parse(directive: str) → Directive[source]

Parse a directive string with key-value pairs into a Directive object.

Format: !padne DIRECTIVE_NAME key1=value1 key2=value2 …

Args:

directive: The directive string to parse

Returns:

A Directive object with the parsed name and parameters

Raises:

ValueError: If the directive format is invalid

class padne.kicad.Endpoint[source]
designator: str[source]
pad: str[source]
class padne.kicad.LayerPoint[source]
layer: str[source]
point: shapely.geometry.Point[source]
class padne.kicad.PadIndex[source]

This class effectively serves as a mapper from Endpoint to a bunch of LayerPoints that can then be used to construct a problem.Connection object.

mapping: dict[Endpoint, list[LayerPoint]][source]
find_by_endpoint(ep: Endpoint) → list[LayerPoint][source]
find_by_endpoints(eps: Iterable[Endpoint]) → list[LayerPoint][source]
load_surface_pads(board: pcbnew, layer_dict: dict[str, padne.problem.Layer]) → None[source]

Load all surface pads from the given PCB board into the mapping. These are SMD pads and connect pads (edge connector fingers, mounting hole rings), which are the same copper without a paste aperture. Validates that connection points fall within the final layer geometry.

Args:

board: The PCB board to extract surface pads from layer_dict: Dictionary of final layer geometries for validation

insert_via_specs(via_specs: list[ViaSpec], layer_dict: dict[str, padne.problem.Layer]) → None[source]

Insert via specifications into the mapping. Uses all boundary points of the via shape for all layers it connects.

Args:

via_specs: List of via specifications to insert layer_dict: Dictionary of final layer geometries for validation

class padne.kicad.BaseLumpedSpec[source]

Represents a base class that specifies a _single_ lumped element being wired to a bunch of pads on the PCB.

endpoints: dict[str, list[Endpoint]][source]
values: dict[str, float][source]
coupling: float = 0.001[source]
endpoint_names: ClassVar[dict[str, str]][source]
value_names: ClassVar[dict[str, str | None]][source]
lumped_type: ClassVar[type | None] = None[source]
default_values: ClassVar[dict[str, float]][source]
classmethod from_directive(directive: Directive) → BaseLumpedSpec[source]

Parse a directive into a BaseLumpedSpec object.

Args:

directive: The directive to parse

Returns:

A BaseLumpedSpec object with parsed endpoints and values

construct(pad_index: PadIndex, layer_dict: dict[str, padne.problem.Layer]) → padne.problem.Network[source]

Constructs a problem.Network containing the lumped element from the current specification, wired up to its pads.

class padne.kicad.ResistorSpec[source]

Bases: BaseLumpedSpec

Represents a base class that specifies a _single_ lumped element being wired to a bunch of pads on the PCB.

endpoint_names[source]
value_names[source]
lumped_type[source]
class padne.kicad.VoltageSourceSpec[source]

Bases: BaseLumpedSpec

Represents a base class that specifies a _single_ lumped element being wired to a bunch of pads on the PCB.

endpoint_names[source]
value_names[source]
default_values[source]
lumped_type[source]
construct(pad_index: PadIndex, layer_dict: dict[str, padne.problem.Layer]) → padne.problem.Network[source]

Custom construct method for voltage sources that properly handles multiple endpoints without introducing coupling resistance.

Strategy: 1. Create main voltage source between first positive and first negative endpoints 2. Create 0V voltage sources to connect additional endpoints to the first ones

class padne.kicad.CurrentSourceSpec[source]

Bases: BaseLumpedSpec

Represents a base class that specifies a _single_ lumped element being wired to a bunch of pads on the PCB.

endpoint_names[source]
value_names[source]
lumped_type[source]
class padne.kicad.RegulatorSpec[source]

Bases: BaseLumpedSpec

Represents a base class that specifies a _single_ lumped element being wired to a bunch of pads on the PCB.

endpoint_names[source]
value_names[source]
lumped_type[source]
class padne.kicad.ProbeSpec[source]

Specifies pads at which a mesh vertex must be forced, without adding any electrical element. Each pad becomes a single-connection Network so the mesher seeds a vertex exactly at the pad center.

endpoints: list[Endpoint] = [][source]
classmethod from_directive(directive: Directive) → ProbeSpec[source]
construct(pad_index: PadIndex, layer_dict: dict[str, padne.problem.Layer]) → list[padne.problem.Network][source]
class padne.kicad.CopperSpec[source]

Copper process parameters for the project. All lengths are in mm.

conductivity: float = 59500.0[source]
undercut: float = 0.0[source]
plating: float = 0.025[source]
classmethod from_directive(directive: Directive) → CopperSpec[source]

Parse a COPPER directive. Directive values are in SI units (S/m, m) and are converted to the internal S/mm and mm here.

Raises:

ValueError: If a parameter is out of range

class padne.kicad.ViaSpec[source]

Specifies a via in the PCB.

point: shapely.geometry.Point[source]
drill_diameter: float[source]
layer_names: list[str][source]
endpoint: Endpoint | None = None[source]
shape: shapely.geometry.Polygon[source]
compute_resistance(length: float, plating_thickness: float, conductivity: float) → float[source]

Compute via resistance using hollow cylinder model.

Args:

length: Via length in mm plating_thickness: Copper plating thickness in mm conductivity: Copper conductivity in S/mm

Returns:

Resistance in ohms

class padne.kicad.KiCadProject[source]

Represents a KiCad project with paths to its component files.

pro_path: pathlib.Path[source]
pcb_path: pathlib.Path[source]
sch_path: pathlib.Path[source]
property name: str[source]

Get the project name (stem of the project file).

classmethod from_pro_file(pro_file_path: pathlib.Path) → KiCadProject[source]

Create a KiCadProject from a .kicad_pro file path.

Args:

pro_file_path: Path to the KiCad project file (*.kicad_pro)

Returns:

A KiCadProject instance with validated file paths

Raises:

FileNotFoundError: If any required files are missing

padne.kicad.extract_via_specs_from_pcb(board: pcbnew) → list[ViaSpec][source]

Extract via specifications from a KiCad PCB.

Args:

board: The KiCad board object

Returns:

A list of ViaSpec objects containing information about vias in the PCB

padne.kicad.extract_tht_pad_specs_from_pcb(board: pcbnew) → list[ViaSpec][source]

Extract through-hole pad specifications from a KiCad PCB.

Args:

board: The KiCad board object

Returns:

A list of ViaSpec objects representing through-hole pads in the PCB

class padne.kicad.Directives[source]

Accumulates different directive types that can be present in the schematic.

lumped_specs: list[BaseLumpedSpec][source]
copper_spec: CopperSpec | None = None[source]
probe_specs: list[ProbeSpec] = [][source]
class padne.kicad.SchemaInstance[source]

Represents a schematic instance in the hierarchy.

file_path: pathlib.Path[source]
sheet_name: str[source]
parsed_sexp: Any[source]
child_instances: list[SchemaInstance] = [][source]
padne.kicad.parse_endpoint(token: str) → Endpoint[source]

Parse an endpoint in the format DESIGNATOR.PAD. For example, “R1.1” will become Endpoint(designator=”R1”, pad=”1”).

padne.kicad.process_directives(directives: list[Directive]) → Directives[source]
padne.kicad.build_schema_hierarchy(sch_file_path: pathlib.Path, sheet_name: str = 'Root') → SchemaInstance[source]

Build the complete schematic hierarchy starting from a root schematic.

padne.kicad.flatten_schema_hierarchy(schema_instance: SchemaInstance) → list[SchemaInstance][source]

Flatten a schema hierarchy into a list of all instances.

Args:

schema_instance: Root schema instance

Returns:

List of all schema instances in the hierarchy (root first, then children)

padne.kicad.extract_directives_from_text(text: str) → list[Directive][source]

Extract directives from a text string that may contain multiple lines.

Each line is stripped of whitespace and checked if it starts with ‘!padne’. Lines that don’t start with ‘!padne’ are ignored.

Note: KiCad standardizes newlines to ‘

‘ in .kicad_sch files regardless of the

platform, so we can safely use splitlines() without worrying about mixed endings.

Args:

text: The text string to parse for directives

Returns:

List of Directive objects found in the text

padne.kicad.extract_directives_from_schema(instance: SchemaInstance) → list[Directive][source]
padne.kicad.extract_directives_from_hierarchy(schema_instance: SchemaInstance) → list[Directive][source]

Extract all directives from a schematic hierarchy.

Args:

schema_instance: Root of the schematic hierarchy

Returns:

List of all directives found in the hierarchy (deduplicated by file path)

class padne.kicad.PlottedGerberLayer[source]
name: str[source]
layer_id: int[source]
geometry: shapely.geometry.MultiPolygon[source]
padne.kicad.render_gerbers_from_kicad(board: pcbnew, layer_ids: Iterable[int]) → list[PlottedGerberLayer][source]

Plot the given layers of a KiCad board to Gerbers and convert them to PlottedGerberLayer objects.

padne.kicad.plot_board_layer_to_gerber(board: pcbnew, layer_id: int, output_path: pathlib.Path)[source]

Plot a single layer of a KiCad board to a Gerber file at output_path.

padne.kicad.extract_layers_from_gerbers(board, gerber_layers: dict[int, pathlib.Path]) → list[PlottedGerberLayer][source]

Extract geometry from Gerber files and create PlottedGerberLayer objects.

Args:

board: KiCad board object (for layer names) gerber_layers: Dictionary mapping layer IDs to paths of Gerber files

Returns:

List of PlottedGerberLayer objects

padne.kicad.extract_board_outline(board: pcbnew) → shapely.geometry.MultiPolygon | None[source]

Extract board outline from a KiCad PCB. This uses the internal KiCad outline processing.

padne.kicad.process_via_spec(via_spec: ViaSpec, layer_dict: dict[str, padne.problem.Layer], stackup: Stackup, plating_thickness: float) → list[padne.problem.Network][source]
padne.kicad.punch_via_holes(plotted_layers: list[PlottedGerberLayer], via_specs: list[ViaSpec]) → list[PlottedGerberLayer][source]
padne.kicad.verify_stackup_contains_all_layers(stackup: Stackup, plotted_layers: list[PlottedGerberLayer]) → bool[source]

Return whether all plotted layers are contained within the stackup.

padne.kicad.construct_layer_dict(plotted_layers: list[PlottedGerberLayer], stackup: Stackup) → dict[str, padne.problem.Layer][source]

Construct a dictionary mapping layer names to Layer objects.

padne.kicad.clip_layer_with_outline(plotted_layer: PlottedGerberLayer, outline: shapely.geometry.MultiPolygon) → PlottedGerberLayer[source]

Clip a plotted layer’s geometry with the board outline.

padne.kicad.erode_layers_by_undercut(plotted_layers: list[PlottedGerberLayer], undercut: float) → list[PlottedGerberLayer][source]

Shrink every copper edge by the etch undercut (in mm).

padne.kicad.load_kicad_project(pro_file_path: pathlib.Path) → padne.problem.Problem[source]

Load a KiCad project and create a Problem object for PDN simulation.

Args:

pro_file_path: Path to the KiCad project file (*.kicad_pro)

Returns:

A Problem object containing layers and lumped elements

Raises:

FileNotFoundError: If required files are missing ValueError: If the project contains invalid data