Hello,
I'm taking an octagon and shrinking it with the myShape.size( -int, var[6:0]) method
This understandably results in a folded shape with artifacts at the vertices outside of the desired final shape. I am not able to follow the existing documentation to figure out how to remove/clean the artifacts.
My Size function:
myinnerPolygon.size(-200000, 8) #I iteratively tried 0-8 for the angle operator
I tried this function which I thought would clean up the artifacts:
ep = pya.EdgeProcessor()
result = ep.simple_merge_p2p([ myinnerPolygon ], False, False, 1)
but did not see any improvement and I can't really follow the documentation well enough to understand the function.
Does anyone have a suggestion?
Comments
Hi,
I don't see an issue with the solution you proposed.
Here is a working example:
This prints:
That means: the original polygon is an octagon. After sizing the polygon is a complex one with the artefacts induced by the vertex treatment on negative sizing. So it's a bit more complex. After the merge step, the result is an array containing one polygon. That polygon again is an octagon. So from my point of view the solutions should work. The angle parameter should not matter in your case since octagon angles are not acute ones.
I should mention that there is a better object available for doing geometrical computations: the
Region
class is basically a collection of polygons. Collections of polygons are more natural objects for doing computations. In the general case for example the sizing operation may render zero (if the polygon vanishes) to many polygons (if parts of the original polygons vanish). Hence, a sizing operation is not a natural operation to be performed on a single polygon. But on a collection of polygons it is. Since a single polygon is just a special case of a collection, theRegion
class can be used to implement your application too:Which immediately renders the octagon:
Begin capable of handling the potential change in number of polygons, the
Region
class directly implements the polygon merging in the sizing step.Plus, the
Region
class has a lot more features than just sizing ...Matthias
>>poly = pya.Polygon(pts) needs to be part of the above posted solution before the first 'print' statement
I'm not sure the implementation of the pya.EdgeProcessor().simple_merge_p2p() method is the most intuitive. I've implemented it correctly below starting from drawn polygon and finishing with shrunken drawn polygon.
The syntax is not at all obvious without some debug and trial and error.
# Enter your Python code here
import pya
layout = pya.Layout()
cell = layout.create_cell("Octagon")
l1 = layout.layer(1, 0)
l2 = layout.layer(2, 0)
l3 = layout.layer(3, 0)
pts = []
pts.append(pya.Point(-1000, 300))
pts.append(pya.Point(-300, 1000))
pts.append(pya.Point(300, 1000))
pts.append(pya.Point(1000, 300))
pts.append(pya.Point(1000, -300))
pts.append(pya.Point(300, -1000))
pts.append(pya.Point(-300, -1000))
pts.append(pya.Point(-1000, -300))
print("Type(pts): " + str( type(pts)))
print((pts))
poly = pya.Polygon(pts)
print("Type(poly): " + str(type(poly)))
print("Original: "+str(poly))
poly_sized_m100 = poly.sized(-100)
print("Type(poly_sized_m100): " + str( type(poly_sized_m100)))
print("Post size: "+str(poly_sized_m100))
result = pya.EdgeProcessor().simple_merge_p2p([ poly_sized_m100 ], False, False, 1)
print ("Type(result): " + str(type(result))) #This returns a misleading result
print ("Type(result[0]): " + str(type(result[0]))) #This is the object we're looking for, but a strange index location
print("Post merge: ")
#Correct Object access
print(str(len(result)) + ": " + str(result[0]))
#Incorrect object type access, because 'result' appears to be an object with a 'string' of points at index [0], not a general array of points
for p in result:
print(str(p))
#It's not clear that EdgeProcessor should return a coordinates\
# string at result[0] vs. a working Object.Polygon() or an explicit list of Object.Point()
#I.e. it should operate more like a method or maybe the documentation should be more explicit
#The following strings fail, but are intuitive next steps:
#Fails: poly_sized_m100_clean = pya.Polygon(result)
#Fails: cell.shapes(l3).insert(result)
cell.shapes(l1).insert(poly)
cell.shapes(l2).insert(poly_sized_m100)
#This string is the implementation that works, although it is non-intuitive
cell.shapes(l3).insert(result[0]) #works
import os
user_profile = os.environ['USERPROFILE']
user_desktop = user_profile + "/Desktop/"
layout.write(user_desktop + "octagon.gds")
Hi,
you're right, the line was missing (lost in copy/paste) - I have edited the samples accordingly. Thanks for mentioning this.
But I don't see your point. What's the problem? The documentation clearly says
EdgeProcessor#simple_merge_p2p
takes and returns an ARRAY ofPolygon
objects. Not single ones. Boolean operations in general won't work on single polygons. For the reasons see my explanations above. And a polygon is an object, not an array of points. If you convert it to a string, then it becomes a string which lists the points. What's wrong about that?I tried to explain, that the
Region
class is easier to use. ForRegion
, the sizing and the Booleans are methods as you expect. Maybe you get happy with this one.Apart from that I never claimed the solution to be intuitive. What are you actually expecting? Free software, free support, top quality and performance, intuitive usage? Anything else? Maybe you should go for the commercial products like from the market leader: http://www.cadence.com (Dear CDS marketing department: this link is for free). Once you have signed their Platinum service contract, their AE's will be glad to help out. Plus they will be happy to offer trainings on their software. It's just a little more expensive than nothing.
Matthias
No offense intended. I'm just explaining my experience and trying to understand a new tool. I wouldn't have taken the time to debug and play with the scripts and write a post if I didn't like it.
And I do have Cadence and Synopsys and Mentor and all the support I can ever need.
The point is I like your tool and I'm trying to understand the nuances.
If you say you return an array of points, but the data is not in an array, it's in a string at array[0], that's not intuitive. It's not a personal knock. It's just a different way of doing something and I'm trying to understand so that I can be self sufficient in the future. I assume if you didn't want feedback, you wouldn't have asked for feedback or opened a forum.
Cheers.
+