mirror of
https://github.com/KLayout/klayout.git
synced 2026-08-29 17:30:09 +02:00
Merge pull request #1803 from KLayout/feature/issue-1790
Implemented a solution for issue #1790 (Support for recursive PCell i…
This commit is contained in:
Vendored
+77
-2
@@ -18,6 +18,7 @@
|
||||
|
||||
import pya
|
||||
import unittest
|
||||
import math
|
||||
import sys
|
||||
|
||||
class BoxPCell(pya.PCellDeclaration):
|
||||
@@ -77,7 +78,7 @@ class PCellTestLib(pya.Library):
|
||||
sb_cell = self.layout().cell(sb_index)
|
||||
sb_cell.shapes(l10).insert(pya.Box(0, 0, 100, 200))
|
||||
|
||||
# register us with the name "MyLib"
|
||||
# register us with the name "PCellTestLib"
|
||||
self.register("PCellTestLib")
|
||||
|
||||
|
||||
@@ -135,9 +136,62 @@ if "PCellDeclarationHelper" in pya.__dict__:
|
||||
# create the PCell declarations
|
||||
self.layout().register_pcell("Box2", BoxPCell2())
|
||||
|
||||
# register us with the name "MyLib"
|
||||
# register us with the name "PCellTestLib2"
|
||||
self.register("PCellTestLib2")
|
||||
|
||||
# A recursive PCell
|
||||
|
||||
class RecursivePCell(pya.PCellDeclarationHelper):
|
||||
|
||||
def __init__(self):
|
||||
|
||||
super(RecursivePCell, self).__init__()
|
||||
|
||||
self.param("layer", self.TypeLayer, "Layer", default = pya.LayerInfo(0, 0))
|
||||
self.param("line", self.TypeShape, "Line", default = pya.Edge(0, 0, 10000, 0))
|
||||
self.param("level", self.TypeInt, "Level", default = 1)
|
||||
|
||||
def display_text_impl(self):
|
||||
# provide a descriptive text for the cell
|
||||
return "RecursivePCell(L=" + str(self.layer) + ",E=" + str(pya.CplxTrans(self.layout.dbu) * self.line) + ",LVL=" + str(self.level)
|
||||
|
||||
def produce_impl(self):
|
||||
|
||||
# fetch the parameters
|
||||
l = self.layer_layer
|
||||
e = self.line
|
||||
|
||||
if self.level <= 0:
|
||||
self.cell.shapes(l).insert(e)
|
||||
return
|
||||
|
||||
d3 = e.d() * (1.0 / 3.0)
|
||||
d3n = pya.Vector(-d3.y, d3.x)
|
||||
|
||||
e1 = pya.Edge(e.p1, e.p1 + d3)
|
||||
e2 = pya.Edge(e1.p2, e1.p2 + d3 * 0.5 + d3n * math.cos(math.pi / 6))
|
||||
e3 = pya.Edge(e2.p2, e.p1 + d3 * 2.0)
|
||||
e4 = pya.Edge(e3.p2, e.p2)
|
||||
|
||||
for e in [ e1, e2, e3, e4 ]:
|
||||
t = pya.Trans(e.p1 - pya.Point())
|
||||
cc = self.layout.create_cell("RecursivePCell", { "layer": self.layer, "line": t.inverted() * e, "level": self.level - 1 })
|
||||
self.cell.insert(pya.CellInstArray(cc, t))
|
||||
|
||||
class PCellTestLib3(pya.Library):
|
||||
|
||||
def __init__(self):
|
||||
|
||||
# set the description
|
||||
self.description = "PCell test lib3"
|
||||
|
||||
# create the PCell declarations
|
||||
self.layout().register_pcell("RecursivePCell", RecursivePCell())
|
||||
|
||||
# register us with the name "PCellTestLib3"
|
||||
self.register("PCellTestLib3")
|
||||
|
||||
|
||||
|
||||
def inspect_LayerInfo(self):
|
||||
return "<" + str(self) + ">"
|
||||
@@ -501,6 +555,27 @@ class DBPCellTests(unittest.TestCase):
|
||||
|
||||
self.assertEqual(cell.begin_shapes_rec(ly.layer(5, 0)).shape().__str__(), "box (-100,-300;100,300)")
|
||||
|
||||
def test_9(self):
|
||||
|
||||
if not "PCellDeclarationHelper" in pya.__dict__:
|
||||
return
|
||||
|
||||
# instantiate and register the library
|
||||
tl = PCellTestLib3()
|
||||
|
||||
ly = pya.Layout(True)
|
||||
|
||||
li1 = find_layer(ly, "1/0")
|
||||
self.assertEqual(li1 == None, True)
|
||||
|
||||
c1 = ly.create_cell("c1")
|
||||
|
||||
c2 = ly.create_cell("RecursivePCell", "PCellTestLib3", { "layer": pya.LayerInfo(1, 0), "level": 4, "line": pya.Edge(0, 0, 20000, 0) })
|
||||
c1.insert(pya.CellInstArray(c2.cell_index(), pya.Trans()))
|
||||
|
||||
self.assertEqual(c2.display_title(), "PCellTestLib3.RecursivePCell(L=1/0,E=(0,0;20,0),LVL=4")
|
||||
self.assertEqual(str(c1.dbbox()), "(0,0;20,5.774)")
|
||||
|
||||
# run unit tests
|
||||
if __name__ == '__main__':
|
||||
suite = unittest.TestLoader().loadTestsFromTestCase(DBPCellTests)
|
||||
|
||||
Vendored
+89
@@ -170,6 +170,71 @@ if RBA.constants.member?(:PCellDeclarationHelper)
|
||||
|
||||
end
|
||||
|
||||
# A recursive PCell
|
||||
|
||||
class RecursivePCell < RBA::PCellDeclarationHelper
|
||||
|
||||
def initialize
|
||||
|
||||
super()
|
||||
|
||||
param("layer", RecursivePCell::TypeLayer, "Layer", :default => RBA::LayerInfo::new(0, 0))
|
||||
param("line", RecursivePCell::TypeShape, "Line", :default => RBA::Edge::new(0, 0, 10000, 0))
|
||||
param("level", RecursivePCell::TypeInt, "Level", :default => 1)
|
||||
|
||||
end
|
||||
|
||||
def display_text_impl
|
||||
# provide a descriptive text for the cell
|
||||
return "RecursivePCell(L=" + self.layer.to_s + ",E=" + (RBA::CplxTrans::new(self.layout.dbu) * self.line).to_s + ",LVL=" + self.level.to_s
|
||||
end
|
||||
|
||||
def produce_impl
|
||||
|
||||
# fetch the parameters
|
||||
l = self.layer_layer
|
||||
e = self.line
|
||||
|
||||
if self.level <= 0
|
||||
self.cell.shapes(l).insert(e)
|
||||
return
|
||||
end
|
||||
|
||||
d3 = e.d * (1.0 / 3.0)
|
||||
d3n = RBA::Vector::new(-d3.y, d3.x)
|
||||
|
||||
e1 = RBA::Edge::new(e.p1, e.p1 + d3)
|
||||
e2 = RBA::Edge::new(e1.p2, e1.p2 + d3 * 0.5 + d3n * Math::cos(Math::PI / 6))
|
||||
e3 = RBA::Edge::new(e2.p2, e.p1 + d3 * 2.0)
|
||||
e4 = RBA::Edge::new(e3.p2, e.p2)
|
||||
|
||||
[ e1, e2, e3, e4 ].each do |e|
|
||||
t = RBA::Trans::new(e.p1 - RBA::Point::new)
|
||||
cc = self.layout.create_cell("RecursivePCell", { "layer" => self.layer, "line" => t.inverted * e, "level" => self.level - 1 })
|
||||
self.cell.insert(RBA::CellInstArray::new(cc, t))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class PCellTestLib3 < RBA::Library
|
||||
|
||||
def initialize
|
||||
|
||||
# set the description
|
||||
self.description = "PCell test lib3"
|
||||
|
||||
# create the PCell declarations
|
||||
self.layout().register_pcell("RecursivePCell", RecursivePCell::new)
|
||||
|
||||
# register us with the name "PCellTestLib3"
|
||||
self.register("PCellTestLib3")
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# A helper for testing: provide an inspect method
|
||||
@@ -809,6 +874,30 @@ class DBPCell_TestClass < TestBase
|
||||
|
||||
end
|
||||
|
||||
def test_12
|
||||
|
||||
if !RBA.constants.member?(:PCellDeclarationHelper)
|
||||
return
|
||||
end
|
||||
|
||||
# instantiate and register the library
|
||||
tl = PCellTestLib3::new
|
||||
|
||||
ly = RBA::Layout::new
|
||||
|
||||
li1 = ly.find_layer("1/0")
|
||||
assert_equal(li1 == nil, true)
|
||||
|
||||
c1 = ly.create_cell("c1")
|
||||
|
||||
c2 = ly.create_cell("RecursivePCell", "PCellTestLib3", { "layer" => RBA::LayerInfo::new(1, 0), "level" => 4, "line" => RBA::Edge::new(0, 0, 20000, 0) })
|
||||
c1.insert(RBA::CellInstArray::new(c2.cell_index(), RBA::Trans::new))
|
||||
|
||||
assert_equal(c2.display_title, "PCellTestLib3.RecursivePCell(L=1/0,E=(0,0;20,0),LVL=4")
|
||||
assert_equal(c1.dbbox.to_s, "(0,0;20,5.774)")
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
load("test_epilogue.rb")
|
||||
|
||||
Reference in New Issue
Block a user