Support Forum

Problem with toPolygonSelect and Python API



Tuesday 19th March 2019
Hello, In the Python API, I think there is a bug with the "toPolygonSelect()" method from the cell objects. When you do that to elements, new elements are created instead of converting them in place. For instance : ``` import LayoutScript as lsc layout = lsc.project.newLayout() topcell = layout.drawing.currentCell topcell.cellName = "TOP" layer1 = 1 layer100 = 100 box_polygon_element = topcell.addBox(-250, 750, 500, 750, layer1) print(box_polygon_element.getPoints().size()) # This returns 2 since it is a box box_polygon_element.selectAll() topcell.toPolygonSelect() box_polygon_element.deselectAll() print(box_polygon_element.getPoints().size()) # This returns 0 ``` In a above code, since there is only one element, it is easy to find the new element and assign it back to `box_polygon_element`. However, when there is already a lot of element, this become very hard to do. For now, to avoid this problem, I move the elements on a new layer before doing the conversion, I move them back afterward and then reasign them. It works, but it is quite inelegant. Thanks for your help! Regards, Guillaume
Jürgen
LayoutEditorFull
Wednesday 20th March 2019
Hi Guillaume, that is not a bug, that's the intended behavior. With the line topcell.addBox(...); you will get a box object. The conversion will replace the box object with a polygon object, the box object is no longer valid and any access to it will result in a null. In general you should not store any shape elements for later reuse. Many features like *undo* or *group* will make these pointers invalid. The *element* class should only use in the way: create/pick the element and directly do the required modification/selection.


Friday 22nd March 2019
Hello Jürgen, Thanks for the reply!! I understand the API a bit better now. The intended behavior is a bit off, because after the `toPolygonSelect()` the `box_polygon_element` variable is still of type `LayoutScript.element` instead of `NoneType`. ``` box_polygon_element.selectAll() topcell.toPolygonSelect() box_polygon_element.deselectAll() print(type(box_polygon_element)) # This returns: < class 'LayoutScript.element' > instead of < class 'NoneType' > ``` This explain a bit where my confusion about element objects comes from. My problem with the conversion from box to polygon comes from the fact that I need to get a 5 points `pointArray` object to perform boolean operations (with the `booleanHandler` methods that starts with "perform"). To do the conversion right now, I do the following : ``` box_polygon_element.selectAll() # The box is on layer 1 topcell.moveToLayerSelect(layer100) # The layer 100 is empty topcell.toPolygonSelect() topcell.selectLayer(layer100) box_polygon_element = topcell.selectedElement(None) # Get the reference back topcell.moveToLayerSelect(layer1) layout.drawing.deselectAll() ## Perform the boolean operation using the box_polygon_element.getPoints() method ``` I'm trying to show other users how to use the Python API and I find this code a bit confusing. Is-there a method to get the newest element created? Otherwise, it would be useful to have a method to get the converted elements a bit like the `booleanHandler.getResultingPolygon()` method. Another solution to the box/boolean problem would be to have a method for boxes that returns a `pointArray` as if it was a polygon. I know I can do that myself with a simple function, but I think that would be a useful addition to the LayoutEditor API. Thanks again! Guillaume
Jürgen
LayoutEditorFull
Sunday 24th March 2019
Hi Guillaume, I understand. The *print* effect is due to the python interface generation and cannot be avoided. A code with the same effect can be made shorter: ```python box_polygon_element.selectAll() layout.booleanTool.setA() #selected elements will be added to the boolean tool ``` To make it even simpler we will add these methods with the next update of the LayoutEditor: ```c++ void booleanHandler::addA(rect r); void booleanHandler::addB(rect r); void booleanHandler::addA(element *e); void booleanHandler::addB(element *e); ``` So you can use with the next update: ```python layout.booleanTool.addA(box_polygon_element) #or alternative r=rect() r.set(1,2,3,4) layout.booleanTool.addA(r) ``` You are welcome! Jürgen


Monday 25th March 2019
Oh! Yes. The code will be a lot cleaner with those new methods. Thanks again for your help! Guillaume