mirror of https://github.com/KLayout/klayout.git
277 lines
10 KiB
Ruby
277 lines
10 KiB
Ruby
# encoding: UTF-8
|
|
|
|
# KLayout Layout Viewer
|
|
# Copyright (C) 2006-2025 Matthias Koefferlein
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
if !$:.member?(File::dirname($0))
|
|
$:.push(File::dirname($0))
|
|
end
|
|
|
|
load("test_prologue.rb")
|
|
|
|
class DBLayout_TestClass < TestBase
|
|
|
|
def collect(s, l)
|
|
|
|
# check native iteration here too ..
|
|
res2 = []
|
|
s.each do |s|
|
|
r = "[#{s.inst_cell.name}]"
|
|
r += (s.trans * s.inst_trans).to_s
|
|
res2.push(r)
|
|
end
|
|
|
|
res = []
|
|
s.reset
|
|
while !s.at_end?
|
|
r = "[#{s.inst_cell.name}]"
|
|
r += (s.trans * s.inst_trans).to_s
|
|
res.push(r)
|
|
s.next
|
|
end
|
|
|
|
assert_equal(res, res2)
|
|
|
|
return res.join("/")
|
|
|
|
end
|
|
|
|
def dcollect(s, l)
|
|
|
|
res = []
|
|
while !s.at_end?
|
|
r = "[#{s.inst_cell.name}]"
|
|
r += (s.dtrans * s.inst_dtrans).to_s
|
|
res.push(r)
|
|
s.next
|
|
end
|
|
|
|
return res.join("/")
|
|
|
|
end
|
|
|
|
def test_1
|
|
|
|
# Recursive instance iterator tests
|
|
|
|
l = RBA::Layout.new
|
|
l.insert_layer_at(0, RBA::LayerInfo.new(1, 0))
|
|
l.insert_layer_at(1, RBA::LayerInfo.new(2, 0))
|
|
c0 = l.cell(l.add_cell("c0"))
|
|
c1 = l.cell(l.add_cell("c1"))
|
|
c2 = l.cell(l.add_cell("c2"))
|
|
c3 = l.cell(l.add_cell("c3"))
|
|
|
|
b = RBA::Box.new(0, 100, 1000, 1200)
|
|
c0.shapes(0).insert(b)
|
|
c1.shapes(0).insert(b)
|
|
c2.shapes(0).insert(b)
|
|
c3.shapes(0).insert(b)
|
|
|
|
bb = RBA::Box.new(1, 101, 1001, 1201)
|
|
c3.shapes(1).insert(bb)
|
|
|
|
tt = RBA::Trans.new
|
|
c0.insert(RBA::CellInstArray.new(c1.cell_index, tt))
|
|
c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100))))
|
|
c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1)))
|
|
c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0))))
|
|
|
|
i1 = c0.begin_instances_rec_touching(RBA::Box.new(0, 0, 100, 100))
|
|
i1copy = i1.dup
|
|
assert_equal(i1copy.overlapping?, false)
|
|
assert_equal(collect(i1, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100")
|
|
i1.reset
|
|
assert_equal(dcollect(i1, l), "[c1]r0 *1 0,0/[c2]r0 *1 0.1,-0.1")
|
|
assert_equal(collect(i1copy, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100")
|
|
|
|
i1 = c0.begin_instances_rec_touching(RBA::DBox.new(0, 0, 0.100, 0.100))
|
|
assert_equal(collect(i1, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100")
|
|
|
|
i1o = c0.begin_instances_rec_overlapping(RBA::Box.new(0, 0, 100, 100));
|
|
assert_equal(collect(i1o, l), "");
|
|
i1o = c0.begin_instances_rec_overlapping(RBA::DBox.new(0, 0, 0.100, 0.100));
|
|
assert_equal(collect(i1o, l), "");
|
|
i1copy.overlapping = true
|
|
assert_equal(i1copy.overlapping?, true)
|
|
assert_equal(collect(i1copy, l), "");
|
|
i1o = c0.begin_instances_rec_overlapping(RBA::Box.new(0, 0, 100, 101));
|
|
assert_equal(collect(i1o, l), "[c1]r0 *1 0,0");
|
|
i1o = c0.begin_instances_rec_overlapping(RBA::DBox.new(0, 0, 0.100, 0.101));
|
|
assert_equal(collect(i1o, l), "[c1]r0 *1 0,0");
|
|
i1copy.region = RBA::Box.new(0, 0, 100, 101)
|
|
assert_equal(i1copy.region.to_s, "(0,0;100,101)")
|
|
assert_equal(collect(i1copy, l), "[c1]r0 *1 0,0");
|
|
i1copy.region = RBA::Region::new(RBA::Box.new(0, 0, 100, 101))
|
|
assert_equal(i1copy.region.to_s, "(0,0;100,101)")
|
|
assert_equal(collect(i1copy, l), "[c1]r0 *1 0,0");
|
|
i1copy.region = RBA::Box.new(-1000, -1000, 1100, 1101)
|
|
i1copy.confine_region(RBA::Box.new(0, 0, 100, 101))
|
|
assert_equal(i1copy.region.to_s, "(0,0;100,101)")
|
|
assert_equal(collect(i1copy, l), "[c1]r0 *1 0,0");
|
|
i1copy.region = RBA::Box.new(-1000, -1000, 1100, 1101)
|
|
i1copy.confine_region(RBA::Region::new(RBA::Box.new(0, 0, 100, 101)))
|
|
assert_equal(i1copy.region.to_s, "(0,0;100,101)")
|
|
assert_equal(collect(i1copy, l), "[c1]r0 *1 0,0");
|
|
i1o = c0.begin_instances_rec_overlapping(RBA::Box.new(0, 0, 101, 101));
|
|
assert_equal(collect(i1o, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100");
|
|
i1o = c0.begin_instances_rec_overlapping(RBA::Box.new(0, 0, 101, 101));
|
|
assert_equal(collect(i1o, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100");
|
|
|
|
i2 = c0.begin_instances_rec_touching(RBA::Box.new(-100, 0, 100, 100));
|
|
assert_equal(collect(i2, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100/[c3]r90 *1 0,0");
|
|
i2o = c0.begin_instances_rec_overlapping(RBA::Box.new(-100, 0, 100, 100));
|
|
assert_equal(collect(i2o, l), "");
|
|
i2o = c0.begin_instances_rec_overlapping(RBA::Box.new(-101, 0, 101, 101));
|
|
assert_equal(collect(i2o, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100/[c3]r90 *1 0,0");
|
|
|
|
i4 = c0.begin_instances_rec_touching(RBA::Box.new(-100, 0, 2000, 100));
|
|
i4_copy = c0.begin_instances_rec_touching(RBA::Box.new(-100, 0, 2000, 100));
|
|
i4.max_depth = 0;
|
|
assert_equal(collect(i4, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100/[c3]r90 *1 0,0");
|
|
|
|
assert_equal(i4 == i4, true);
|
|
assert_equal(i4 != i4, false);
|
|
assert_equal(i4 == i4_copy, false);
|
|
assert_equal(i4 != i4_copy, true);
|
|
i4 = i4_copy.dup
|
|
assert_equal(i4 == i4_copy, true);
|
|
assert_equal(i4 != i4_copy, false);
|
|
i4.max_depth = 1;
|
|
assert_equal(i4.max_depth, 1)
|
|
assert_equal(collect(i4, l), "[c1]r0 *1 0,0/[c3]r0 *1 1200,-100/[c2]r0 *1 100,-100/[c3]r90 *1 0,0");
|
|
i4.min_depth = 1;
|
|
assert_equal(i4.min_depth, 1)
|
|
assert_equal(collect(i4, l), "[c3]r0 *1 1200,-100");
|
|
|
|
i4.assign(i4_copy);
|
|
assert_equal(collect(i4, l), "[c1]r0 *1 0,0/[c3]r0 *1 1200,-100/[c2]r0 *1 100,-100/[c3]r90 *1 0,0");
|
|
|
|
i5 = c0.begin_instances_rec
|
|
assert_equal(collect(i5, l), "[c1]r0 *1 0,0/[c3]r0 *1 1200,-100/[c2]r0 *1 100,-100/[c3]r90 *1 0,0");
|
|
|
|
ii = RBA::RecursiveInstanceIterator::new
|
|
assert_equal(collect(ii, l), "")
|
|
|
|
ii = RBA::RecursiveInstanceIterator::new(l, c2)
|
|
assert_equal(collect(ii, l), "[c3]r0 *1 1100,0")
|
|
assert_equal(ii.top_cell.name, "c2")
|
|
assert_equal(ii.layout == l, true)
|
|
|
|
ii = RBA::RecursiveInstanceIterator::new(l, c0, RBA::Box.new(-100, 0, 2000, 100), false)
|
|
assert_equal(collect(ii, l), "[c1]r0 *1 0,0/[c3]r0 *1 1200,-100/[c2]r0 *1 100,-100/[c3]r90 *1 0,0")
|
|
|
|
ii = RBA::RecursiveInstanceIterator::new(l, c0, RBA::Box.new(-100, 0, 2000, 100), true)
|
|
assert_equal(collect(ii, l), "[c3]r0 *1 1200,-100/[c2]r0 *1 100,-100")
|
|
|
|
ii = RBA::RecursiveInstanceIterator::new(l, c0, RBA::Box.new(-100, 0, 2000, 101), true)
|
|
assert_equal(collect(ii, l), "[c1]r0 *1 0,0/[c3]r0 *1 1200,-100/[c2]r0 *1 100,-100")
|
|
|
|
ii = RBA::RecursiveInstanceIterator::new(l, c0, RBA::Region::new(RBA::Box.new(-100, 0, 2000, 101)), true)
|
|
assert_equal(collect(ii, l), "[c1]r0 *1 0,0/[c3]r0 *1 1200,-100/[c2]r0 *1 100,-100")
|
|
|
|
ii = RBA::RecursiveInstanceIterator::new(l, c0)
|
|
assert_equal(collect(ii, l), "[c1]r0 *1 0,0/[c3]r0 *1 1200,-100/[c2]r0 *1 100,-100/[c3]r90 *1 0,0")
|
|
|
|
ii.reset
|
|
ii.unselect_cells("c0")
|
|
ii.select_cells("c2")
|
|
assert_equal(collect(ii, l), "[c3]r0 *1 1200,-100")
|
|
|
|
ii.reset_selection
|
|
ii.unselect_cells("c*")
|
|
ii.select_cells([ c2.cell_index ])
|
|
assert_equal(collect(ii, l), "[c3]r0 *1 1200,-100")
|
|
|
|
ii.reset_selection
|
|
ii.unselect_all_cells
|
|
ii.select_cells("c2")
|
|
assert_equal(collect(ii, l), "[c3]r0 *1 1200,-100")
|
|
|
|
ii.reset_selection
|
|
ii.select_all_cells
|
|
ii.unselect_cells("c2")
|
|
assert_equal(collect(ii, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100/[c3]r90 *1 0,0")
|
|
|
|
ii.reset_selection
|
|
ii.select_cells("c*")
|
|
ii.unselect_cells([ c1.cell_index, c2.cell_index ])
|
|
assert_equal(collect(ii, l), "[c1]r0 *1 0,0/[c2]r0 *1 100,-100/[c3]r90 *1 0,0")
|
|
|
|
ii = RBA::RecursiveInstanceIterator::new(l, c0)
|
|
assert_equal(ii.all_targets_enabled?, true)
|
|
ii.targets = "c3"
|
|
assert_equal(ii.all_targets_enabled?, false)
|
|
assert_equal(collect(ii, l), "[c3]r0 *1 1200,-100/[c3]r90 *1 0,0")
|
|
ii.enable_all_targets
|
|
assert_equal(ii.all_targets_enabled?, true)
|
|
assert_equal(collect(ii, l), "[c1]r0 *1 0,0/[c3]r0 *1 1200,-100/[c2]r0 *1 100,-100/[c3]r90 *1 0,0")
|
|
ii.targets = [ c3.cell_index, c1.cell_index ]
|
|
assert_equal(ii.all_targets_enabled?, false)
|
|
assert_equal(collect(ii, l), "[c1]r0 *1 0,0/[c3]r0 *1 1200,-100/[c3]r90 *1 0,0")
|
|
|
|
end
|
|
|
|
def test_2
|
|
|
|
# Recursive instance iterator tests
|
|
|
|
l = RBA::Layout.new
|
|
l.insert_layer_at(0, RBA::LayerInfo.new(1, 0))
|
|
l.insert_layer_at(1, RBA::LayerInfo.new(2, 0))
|
|
c0 = l.cell(l.add_cell("c0"))
|
|
c1 = l.cell(l.add_cell("c1"))
|
|
c2 = l.cell(l.add_cell("c2"))
|
|
c3 = l.cell(l.add_cell("c3"))
|
|
|
|
b = RBA::Box.new(0, 100, 1000, 1200)
|
|
c3.shapes(0).insert(b)
|
|
|
|
bb = RBA::Box.new(1, 101, 1001, 1201)
|
|
c3.shapes(1).insert(bb)
|
|
|
|
tt = RBA::Trans.new
|
|
c0.insert(RBA::CellInstArray.new(c1.cell_index, tt))
|
|
c0.insert(RBA::CellInstArray.new(c2.cell_index, RBA::Trans.new(RBA::Point.new(100, -100))))
|
|
c0.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(1), RBA::Vector::new(10, 20), RBA::Vector::new(11, 21), 2, 3))
|
|
c2.insert(RBA::CellInstArray.new(c3.cell_index, RBA::Trans.new(RBA::Point.new(1100, 0))))
|
|
|
|
res = []
|
|
i = c0.begin_instances_rec
|
|
while !i.at_end?
|
|
res << i.inst_cell.bbox.transformed(i.trans * i.inst_trans).to_s + " " + (i.path + [ i.current_inst_element ]).collect { |e| "[" + l.cell(e.cell_inst.cell_index).name + " #" + e.ia.to_s + "," + e.ib.to_s + " -> " + e.specific_trans.to_s + "]" }.join("")
|
|
i.next
|
|
end
|
|
|
|
assert_equal(res.join("\n") + "\n", <<"END")
|
|
() [c1 #-1,-1 -> r0 0,0]
|
|
(1200,0;2201,1101) [c2 #-1,-1 -> r0 100,-100][c3 #-1,-1 -> r0 1100,0]
|
|
(1200,0;2201,1101) [c2 #-1,-1 -> r0 100,-100]
|
|
(-1201,0;-100,1001) [c3 #0,0 -> r90 0,0]
|
|
(-1191,20;-90,1021) [c3 #1,0 -> r90 10,20]
|
|
(-1190,21;-89,1022) [c3 #0,1 -> r90 11,21]
|
|
(-1180,41;-79,1042) [c3 #1,1 -> r90 21,41]
|
|
(-1179,42;-78,1043) [c3 #0,2 -> r90 22,42]
|
|
(-1169,62;-68,1063) [c3 #1,2 -> r90 32,62]
|
|
END
|
|
|
|
end
|
|
|
|
end
|
|
|
|
load("test_epilogue.rb")
|