Creating a copper zone (ground plane) with pcbnew's Python API
Generate a copper zone connected to a net and trigger its fill by script, with pcbnew or KiCad's IPC API.
A ground plane drawn and filled by hand has to be redone after every routing change. By scripting the zone’s creation and fill, you get a reproducible ground plane that can be regenerated with a single command after each change.
Creating the zone
Instantiate a ZONE object, pick its layer, then add it to the board:
from pcbnew import ZONE, F_Cu
zone = ZONE(board)
zone.SetLayer(F_Cu)
board.Add(zone)With the IPC API, creation and layer selection happen in a single call:
from kicad import KiCad
kicad = KiCad()
board = kicad.get_board()
zone = board.create_zone(layer="F.Cu")Defining the outline
The outline is a SHAPE_POLY_SET you append the polygon’s vertices to, in internal units:
from pcbnew import SHAPE_POLY_SET, FromMM
outline = SHAPE_POLY_SET()
outline.NewOutline()
for x, y in [(0, 0), (50, 0), (50, 30), (0, 30)]:
outline.Append(FromMM(x), FromMM(y))
zone.SetOutline(outline)On the IPC API side, the outline is just a list of points in millimeters:
from kicad.geometry import Vector2
points = [(0, 0), (50, 0), (50, 30), (0, 30)]
zone.outline = [Vector2.from_mm(x, y) for x, y in points]
board.update_items(zone)Try it below: adjust width and height to see the zone’s outline change on the board.
Connecting the net and filling
Attach the zone to a net, then trigger the fill through ZONE_FILLER:
from pcbnew import ZONE_FILLER
zone.SetNet(board.FindNet("GND"))
filler = ZONE_FILLER(board)
filler.Fill(board.Zones())Same idea, with a global fill command on the IPC API side:
zone.net = board.get_net("GND")
board.update_items(zone)
board.refill_zones()Going further
This skeleton is easy to reuse to generate a full per-layer ground plane, carve out keep-out zones around sensitive components, or automatically re-trigger the fill after every routing change instead of clicking “Fill All Zones” by hand.