

np12_l1 = nplus.interacting(nplus_edges.separation(pgate.edges.and(pcomp_edges), 0.32.um, euclidian).polygons(0.001.um))
which is (almost) nplus within 0.32um of pgate.
A different rule might be
np12_l1 = nplus.interacting(pgate.sized(0.32.um, size_inside(poly2), steps(3)))
The minimum poly2 spacing is 0.24um, which means sizing by 0.12um or greater can merge polygons. By splitting into 3 steps, we ensure that each growth will be about 0.11um < 0.12um.








np12_l1 = nplus.interacting(pgate.sized(0.32.um, size_inside(poly2), steps(3)).not(pgate))
Not sure if that makes any difference here. What would you opt for?
I'll try both implementations on a chip design to see if there are any regressions.
pgate because nplus can't overlap pcomp at all so if it was over pgate it would trigger another rule anyway.



1.1.1.
Taking a look at your other issue now.
& operator doesn't work like I think it does, but it should only take the overlap of the sized up version and the original metal and the original metal isn't close enough to cause a separation error ...
layer.sized(5).sized(-5)
You would think the outline will be the same afterwards, only some holes will be closed. However, that may not necessarily be the case, as you can see here: https://www.klayout.de/forum/discussion/comment/12132#Comment_12132
There might be something similar going on in our case.
Anyways, doing a debug dump on the layers right now.