Boolean operation in KLayout PCell generated wrong shapes

I tried to subtract one box from another to generate a hollow box PCell.
The following figure shows the results of using the KLayout built-in Macro development (left) and using an external python code interpreter Spyder (right). The python code for both ways are the same.

My question is: why the KLayout built-in Macro development tool generate a wrong result?
Can anyone help me out?

Here are the PCell code:

class BoxBoolean(pya.PCellDeclarationHelper):
    def __init__(self):
         super(BoxBoolean, self).__init__()
         self.param("layer", self.TypeLayer, "Box layer", default=pya.LayerInfo(1, 0))    
    def display_text_impl(self):
        return "Box boolean"    
    def produce_impl(self):        
        box1 = pya.DBox(0, 0, 10, 10)
        box2 = pya.DBox(3, 3, 7, 7)        
        r = pya.Region(box1) - pya.Region(box2)        
        self.cell.shapes(self.layer_layer).insert(r)

class MyLib(pya.Library):
    def __init__(self):
        self.description = "My PCell Library"    
        self.layout().register_pcell("BoxBoolean", BoxBoolean())    
        self.register("MyLib")

MyLib()

# PCell instance

ly = pya.Layout()
top_cell = ly.create_cell("TOP")
layer = ly.layer(1, 0)

parameters = {
"layer": pya.LayerInfo(1, 0),
}

cell = ly.create_cell("BoxBoolean", "MyLib", parameters)
top_cell.insert(pya.CellInstArray(cell.cell_index(), pya.DTrans()))

ly.write("pcell_instances.oas")

Comments

  • Hi chgli

    I think both case provides correct contours, however if the shape is generated by Pcell and using Region, KLayout will not turn the objects in Region into simple polygon right away (without cutline).

    If you turn the pcell into static, save it and open again, you'll see the shape will automatically haveing a cutline like the example on the right.

    To force the Pcell output simple polygon directly, you might need to loop the shapes in the region, convert it to simple_polygon, then add to the layer.

    class BoxBoolean(pya.PCellDeclarationHelper):
        def __init__(self):
             super(BoxBoolean, self).__init__()
             self.param("layer", self.TypeLayer, "Box layer", default=pya.LayerInfo(1, 0))    
        def display_text_impl(self):
            return "Box boolean"    
        def produce_impl(self):        
            box1 = pya.DBox(0, 0, 10, 10)
            box2 = pya.DBox(3, 3, 7, 7)        
            r = pya.Region(box1) - pya.Region(box2)    
    
            for p in r.each_merged():
                self.cell.shapes(self.layer_layer).insert(p.to_simple_polygon())
    
  • Hi RawrRanger,

    Thank you soooo much!
    Your are right. I need to convert the shapes in the region into polygon.
    I think the hollow box without a cutline is not appropriate for mask manufacturers, am I right?
    There is a minor error in the for loop. I have attached the corrected code below:

    class BoxBoolean(pya.PCellDeclarationHelper):
        def __init__(self):
             super(BoxBoolean, self).__init__()
             self.param("layer", self.TypeLayer, "Box layer", default=pya.LayerInfo(1, 0))    
        def display_text_impl(self):
            return "Box boolean"    
        def produce_impl(self):        
            box1 = pya.DBox(0, 0, 10, 10)
            box2 = pya.DBox(3, 3, 7, 7)        
            r = pya.Region(box1) - pya.Region(box2)    
    
            for p in r.each():
                self.cell.shapes(self.layer_layer).insert(p.to_simple_polygon())
    
  • edited July 2023

    @chgli The loop is not quite efficient, so it's not a general solution.

    I don't know why you call the boolean output "wrong". The polygon with the hole is the canonical representation. The only problem is that GDS and OASIS do not support polygons with holes. So they need to be converted upon writing.

    So there is no "wrong" and "right". Both layouts represent the same area. There is just a "GDS compatible way" and another "canonical" way. Conversions are very common - as long is the overall picture stays the same, I do not see an issue. Conversions cannot be avoided.

    Matthias

  • @Matthias Thank you for enlightening me.

Sign In or Register to comment.