Copy Copper Zone via python scripting

As the title says, I’m trying to copy/move Copper Zones (“filled zones”) via the python interface.
Does anyone know how should I go about it?

I can do it with footprints, but I can’t find any pointers on how to do it with zones.

For reference, here’s the code I use to duplicate an existing footprint:

l = pcbnew.MODULE(led)           # led is a module (footprint) object
board.Add(l)
l.SetPosition(drw.GetPosition())  # align a footprint to a circle on the cmts.user layer

I just tried this and it worked (b is a board object)

z = b.Zones()[0]
z
<pcbnew.ZONE_CONTAINER; proxy of <Swig Object of type 'ZONE_CONTAINER *' at 0x7faf462e1270> >
zz = pcbnew.ZONE_CONTAINER(z)
zz
<pcbnew.ZONE_CONTAINER; proxy of <Swig Object of type 'ZONE_CONTAINER *' at 0x7faf462e11b0> >
b.Add(zz)
zz.SetPosition(z.GetPosition())
zz.SetLayer(pcbnew.B_Cu)
2 Likes

Thanks!
It works but I can’t see the shape until I restart pcbnew, do you know why that happens?
When doing the above code for the footprints, I can view the changes imediatly.

It worked for me but I tried it on a nightly build and I also did pcbnew.Refresh(). If refresh() doesn’t make it appear for you it must be a bug in stable release and you will have to restart pcbnew until that fix reaches stable.

Yeah, pcbnew.Refresh() did the trick, thanks!

I’m still having some issues when using this inside a for loop but I’ll have to dig a little more into the issue.

1 Like

Yeah, for running scripts from pcbnew python console pcbnew.Refresh() is a must. Otherwise for code examples with the pybnew python API you should look at the action plugins:




1 Like

OK, I kinda figured out why my pcbnew.Refresh() wasn’t working… it actually was but the copies of the zones were being placed in the same position of the original zone (which is expected).

The problem I’m facing now is that newzone.SetPosition(pcbnew.wxPoint(newpos_x, newpos_y)) doesn’t seem to be working (it’s still placing zones on top of the original one).

I think I’m calculating the positions correctly. I calculate the difference between the original and target positions and add this difference to the original position of each zone I’m copying so they maintain their relative position.

Here’s an example:

VECTOR (-18058581, 68114760)
CURRPOS 388400000 1600000
NEWPOS 370341419 69714760

And then I set the position of the new zone to NEWPOS: newzone.SetPosition(pcbnew.wxPoint(newpos_x, newpos_y))

Do you know why the zones still end up all stacked together in one place?

What am I missing?

Looks like zones don’t have a position, they are just defined by their outline polygon.
To move a zone you will have to edit it’s outline.
There are some plugins that create zones for teardrops for example, you should be able to find some useful code there.

This is how I duplicate zones. You can move the zone vie .Move method, which handles all the backend stuff required. You only need to supply it with a move vector (by how much you want it to move in x and y direction)

@qu1ck, that makes sense.
I guess that the fact that zone objects have GetPosition() and SetPosition() parameters threw me off track.

@MitjaN, awesome!
I wasn’t aware of the .Move() method. That worked perfectly and I think that allows me to generalize my function to work with footprints and zones at the same time which is great!

You just saved me a couple hours of copying/pasting. Thanks!

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