Pcbnew 7: How to create filled polygon with Python API?

I’m trying to create a filled polygon in pcbnew 7.0.8 using the Python API, like the “Draw a graphic polygon (Ctrl+Shift+P)” tool does in the GUI.

I’ve tried variations of the suggestions at the following sources, but even after adapting as best as I can for the v7 API, I end up with zones (or can’t get it to work at all)… and never a filled polygon:

[also others… but I’m not allowed to link to more than two]

How can I turn a set of points into a filled polygon in pcbnew v7 using Python?

If you end up with zones that’s probably because you are creating zones. If you want a simple graphic shape then you need to create a PCB_SHAPE and pass SHAPE_T_POLY as type. Working with it later is similar to zones so if you get stuck, ask away.

Reference:

https://docs.kicad.org/doxygen-python-7.0/classpcbnew_1_1PCB__SHAPE.html
https://docs.kicad.org/doxygen-python-7.0/classpcbnew_1_1EDA__SHAPE.html

Take a look at GetPolyShape() and the type it returns.

Thanks for replying.

I see now where I can SetFilled(), but I’m still not sure how to actually a workable PCB_SHAPE from a SHAPE_LINE_CHAIN in the first place. (For that matter, I don’t see how to get a SHAPE_T_POLY from anything, either…)

Here’s what I have:

#### DOES NOT WORK ####
import pcbnew
from pcbnew import FromMM
board = pcbnew.GetBoard()

pts = [
	# in mm
	(0, 0),
	(10, 10),
	(10, -10),
	(0, 0)
]
pts = [(FromMM(x), FromMM(y)) for (x,y) in pts]

chain = pcbnew.SHAPE_LINE_CHAIN()
for (x,y) in pts:
	chain.Append(x, y)
chain.SetClosed(True)
sps = pcbnew.SHAPE_POLY_SET()
sps.AddOutline(chain)

ps = pcbnew.PCB_SHAPE(board)
ps.SetPolyShape(sps)
ps.SetFilled(True)

board.Add(ps)
pcbnew.Refresh()

Right now this code just creates a single line segment of zero length at the origin.

The reference I linked has a search function, if you enter SHAPE_T_POLY in it it will bring you to the field definition, it’s directly in pcbnew module. So your constructor should look like

pcbnew.PCB_SHAPE(board, pcbnew.SHAPE_T_POLY)

everything else seems right at first glance, probably the above is the only piece you are missing.

2 Likes

That was it, thanks!
I thought I needed an object of that type—but I needed to specify it as the type for PCB_SHAPE.

Here’s a working example for posterity:

import pcbnew
from pcbnew import FromMM
board = pcbnew.GetBoard()

pts = [
	# in mm
	(0, 0),
	(10, 10),
	(10, -10),
	(0, 0)
]
pts = [(FromMM(x), FromMM(y)) for (x,y) in pts]

sps = pcbnew.SHAPE_POLY_SET()
chain = pcbnew.SHAPE_LINE_CHAIN()
for (x,y) in pts:
	chain.Append(x, y)
chain.SetClosed(True)
sps.AddOutline(chain)

ps = pcbnew.PCB_SHAPE(board, pcbnew.SHAPE_T_POLY)
ps.SetPolyShape(sps)
ps.SetFilled(True)

board.Add(ps)
pcbnew.Refresh()
5 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.