I have two Pcells, let say a and b,
f_a = a.flatten()
f_b = b.flatten()
Now I want to do a subtraction operation on them f_a-f_b, just like the Menu Edit/Selection/Subtraction- Others From First. Could you tell me how to do it in Python?
Hi Matthias,
Thank you for your help.
The GUI operation is OK. Namely Pcells>flatten>boolean operations. The Pcells become polygons after the flatten operations.
Here I want to do this by script like this:
……
f_a = a.flatten()
f_b = b.flatten()
a_region = pya.Region(f_a)
b_region = pya.Region(f_b)
c=a-b
Run the script and the interpreter tells "no matching arguments in the pya.Region() function". I used print(f_a) and it told me the value of f_a is "None". I want to know how to get the handle of polygons (or the return value of a.flatten()).
This a way to do it though I am not sure if this is the most straightforward one.
scell = layout.convert_cell_to_static(pcell_var)
scell = layout.cell(scell)
it = layout.begin_shapes(scell, layout.layer(N,0)) # N is the the layer index
r = pya.Region(it) + pya.Region() # add an empty region to loose the reference to the cell
You end up with a standard region which can be used in boolean operations.
@Christian: thanks for this suggestion. If you put in two regions (even if derived from an iterator) into a boolean operation, they will become flat anyway. So you don't need to add the empty region.
But I need to say that once again: PCells and layout generation different worlds. PCells are supposed to bring in layout automation into the editor. They provide a complex interface to achieve this. But why would everybody use that interface when people are just interested in layout generation? All PCells build into KLayout are very simple (maybe apart from TEXT). So why spending so much effort in handling PCells when it's less effort and more flexible to code the layout generation itself? For example, a circle can be generated as a simple polygon and with a few lines of code, compared to many more if you want to use the CIRCLE PCell. IMHO, even TEXT is not big enough to justify the PCell handling complexity.
I completely agree. I use PCells only to generate text. With regards to the empty Region: I observed that the shapes are "cleaned" (no error but they disappear) when I delete the cell they are coming from.
One remark on the scripting engines. It would be very pythonic if the iterator object was actually an python iterator. Currently
for elem in layout.begin_shapes(scell, layout.layer(N,0)):
do_domething
yes, the TEXT PCell is everybody's darling ... Maybe I can mitigate the PCell instantiation issue by providing a text synthesizing function in the normal pya.Region (i.e. pya.Region.createGlyphs("MY TEXT")).
Your remark about the Python iterator is valid. Most of the simple sequences (like Shapes.each) are well mapped to Python iterators. But the RecursiveShapeIterator is a very versatile tool and can be configured in many respects. So it's beyond a normal iterator. And please don't emphasize "Pythonic" too much ... I intentionally provided two language bindings to overcome some tribal mentality. Plus, Python is not my personal favorite, but never mind ...
Any you're right. The Region is actually a reference to avoid creating unnecessary deep copies. But those are resolved whenever a modification happens. If you just want to store a region away, than your approach is a feasible and smart solution. If you want to perform boolean operations anyway, adding an empty region is simply overhead and you don't need to worry about any changes in the sources.
Comments
Hi,
use the
pya.Region
object. The "-" operator will do the subtraction. You can insert the results into your output cell.Matthias
Thank you for your help.
The GUI operation is OK. Namely Pcells>flatten>boolean operations. The Pcells become polygons after the flatten operations.
Here I want to do this by script like this:
……
f_a = a.flatten()
f_b = b.flatten()
a_region = pya.Region(f_a)
b_region = pya.Region(f_b)
c=a-b
Run the script and the interpreter tells "no matching arguments in the pya.Region() function". I used print(f_a) and it told me the value of f_a is "None". I want to know how to get the handle of polygons (or the return value of a.flatten()).
This a way to do it though I am not sure if this is the most straightforward one.
You end up with a standard region which can be used in boolean operations.
Hi all,
@Christian: thanks for this suggestion. If you put in two regions (even if derived from an iterator) into a boolean operation, they will become flat anyway. So you don't need to add the empty region.
But I need to say that once again: PCells and layout generation different worlds. PCells are supposed to bring in layout automation into the editor. They provide a complex interface to achieve this. But why would everybody use that interface when people are just interested in layout generation? All PCells build into KLayout are very simple (maybe apart from TEXT). So why spending so much effort in handling PCells when it's less effort and more flexible to code the layout generation itself? For example, a circle can be generated as a simple polygon and with a few lines of code, compared to many more if you want to use the CIRCLE PCell. IMHO, even TEXT is not big enough to justify the PCell handling complexity.
Matthias
Hi Matthias,
I completely agree. I use PCells only to generate text. With regards to the empty Region: I observed that the shapes are "cleaned" (no error but they disappear) when I delete the cell they are coming from.
One remark on the scripting engines. It would be very pythonic if the iterator object was actually an python iterator. Currently
generates an error.
Regards, Christian
Hi Christan,
yes, the TEXT PCell is everybody's darling ... Maybe I can mitigate the PCell instantiation issue by providing a text synthesizing function in the normal pya.Region (i.e. pya.Region.createGlyphs("MY TEXT")).
Your remark about the Python iterator is valid. Most of the simple sequences (like
Shapes.each
) are well mapped to Python iterators. But theRecursiveShapeIterator
is a very versatile tool and can be configured in many respects. So it's beyond a normal iterator. And please don't emphasize "Pythonic" too much ... I intentionally provided two language bindings to overcome some tribal mentality. Plus, Python is not my personal favorite, but never mind ...Any you're right. The Region is actually a reference to avoid creating unnecessary deep copies. But those are resolved whenever a modification happens. If you just want to store a region away, than your approach is a feasible and smart solution. If you want to perform boolean operations anyway, adding an empty region is simply overhead and you don't need to worry about any changes in the sources.
Thanks,
Matthias