From 9ec6b44c931d77a9107e9aa3b44847af1cd30f95 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 18 Feb 2019 00:15:26 +0100 Subject: [PATCH] Added some tests for the previous commit. --- src/db/db/gsiDeclDbEdgePairs.cc | 52 ++++++++++++++++++ src/db/db/gsiDeclDbEdges.cc | 17 ++++++ src/db/unit_tests/dbDeepEdgePairsTests.cc | 1 + src/db/unit_tests/dbEdgePairs.cc | 15 ++++++ testdata/algo/deep_edge_pairs_au1.gds | Bin 1138 -> 1202 bytes testdata/ruby/dbEdgePairsTest.rb | 63 ++++++++++++++++++++++ testdata/ruby/dbEdgesTest.rb | 40 ++++++++++++++ testdata/ruby/dbRegionTest.rb | 16 ++++++ 8 files changed, 204 insertions(+) diff --git a/src/db/db/gsiDeclDbEdgePairs.cc b/src/db/db/gsiDeclDbEdgePairs.cc index c3ef30cf7..62e20011e 100644 --- a/src/db/db/gsiDeclDbEdgePairs.cc +++ b/src/db/db/gsiDeclDbEdgePairs.cc @@ -65,6 +65,16 @@ static db::EdgePairs *new_si2 (const db::RecursiveShapeIterator &si, const db::I return new db::EdgePairs (si, trans); } +static db::EdgePairs *new_sid (const db::RecursiveShapeIterator &si, db::DeepShapeStore &dss) +{ + return new db::EdgePairs (si, dss); +} + +static db::EdgePairs *new_si2d (const db::RecursiveShapeIterator &si, db::DeepShapeStore &dss, const db::ICplxTrans &trans) +{ + return new db::EdgePairs (si, dss, trans); +} + static std::string to_string0 (const db::EdgePairs *r) { return r->to_string (); @@ -201,6 +211,8 @@ Class decl_EdgePairs ("db", "EdgePairs", "This constructor creates an edge pair collection from the shapes delivered by the given recursive shape iterator.\n" "Only edge pairs are taken from the shape set and other shapes are ignored.\n" "This method allows feeding the edge pair collection from a hierarchy of cells.\n" + "Edge pairs in layout objects are somewhat special as most formats don't support reading " + "or writing of edge pairs. Still they are useful objects and can be created and manipulated inside layouts.\n" "\n" "@code\n" "layout = ... # a layout\n" @@ -220,6 +232,8 @@ Class decl_EdgePairs ("db", "EdgePairs", "The given transformation is applied to each edge pair taken.\n" "This method allows feeding the edge pair collection from a hierarchy of cells.\n" "The transformation is useful to scale to a specific database unit for example.\n" + "Edge pairs in layout objects are somewhat special as most formats don't support reading " + "or writing of edge pairs. Still they are useful objects and can be created and manipulated inside layouts.\n" "\n" "@code\n" "layout = ... # a layout\n" @@ -231,6 +245,44 @@ Class decl_EdgePairs ("db", "EdgePairs", "\n" "This constructor has been introduced in version 0.26." ) + + constructor ("new", &new_sid, gsi::arg ("shape_iterator"), gsi::arg ("dss"), + "@brief Creates a hierarchical edge pair collection from an original layer\n" + "\n" + "This constructor creates an edge pair collection from the shapes delivered by the given recursive shape iterator.\n" + "This version will create a hierarchical edge pair collection which supports hierarchical operations.\n" + "Edge pairs in layout objects are somewhat special as most formats don't support reading " + "or writing of edge pairs. Still they are useful objects and can be created and manipulated inside layouts.\n" + "\n" + "@code\n" + "dss = RBA::DeepShapeStore::new\n" + "layout = ... # a layout\n" + "cell = ... # the index of the initial cell\n" + "layer = ... # the index of the layer from where to take the shapes from\n" + "r = RBA::EdgePairs::new(layout.begin_shapes(cell, layer))\n" + "@/code\n" + "\n" + "This constructor has been introduced in version 0.26." + ) + + constructor ("new", &new_si2d, gsi::arg ("shape_iterator"), gsi::arg ("dss"), gsi::arg ("trans"), + "@brief Creates a hierarchical edge pair collection from an original layer with a transformation\n" + "\n" + "This constructor creates an edge pair collection from the shapes delivered by the given recursive shape iterator.\n" + "This version will create a hierarchical edge pair collection which supports hierarchical operations.\n" + "The transformation is useful to scale to a specific database unit for example.\n" + "Edge pairs in layout objects are somewhat special as most formats don't support reading " + "or writing of edge pairs. Still they are useful objects and can be created and manipulated inside layouts.\n" + "\n" + "@code\n" + "dss = RBA::DeepShapeStore::new\n" + "layout = ... # a layout\n" + "cell = ... # the index of the initial cell\n" + "layer = ... # the index of the layer from where to take the shapes from\n" + "dbu = 0.1 # the target database unit\n" + "r = RBA::EdgePairs::new(layout.begin_shapes(cell, layer), RBA::ICplxTrans::new(layout.dbu / dbu))\n" + "@/code\n" + "\n" + "This constructor has been introduced in version 0.26." + ) + method ("insert_into", &db::EdgePairs::insert_into, gsi::arg ("layout"), gsi::arg ("cell_index"), gsi::arg ("layer"), "@brief Inserts this edge pairs into the given layout, below the given cell and into the given layer.\n" "If the edge pair collection is a hierarchical one, a suitable hierarchy will be built below the top cell or " diff --git a/src/db/db/gsiDeclDbEdges.cc b/src/db/db/gsiDeclDbEdges.cc index d6e6ea66f..720dccbc8 100644 --- a/src/db/db/gsiDeclDbEdges.cc +++ b/src/db/db/gsiDeclDbEdges.cc @@ -84,6 +84,15 @@ static db::Edges *new_path (const db::Path &o) return new db::Edges (o); } +static db::Edges *new_shapes (const db::Shapes &s, bool as_edges) +{ + db::Edges *r = new db::Edges (); + for (db::Shapes::shape_iterator i = s.begin (as_edges ? db::ShapeIterator::All : db::ShapeIterator::Edges); !i.at_end (); ++i) { + r->insert (*i); + } + return r; +} + static db::Edges *new_si (const db::RecursiveShapeIterator &si, bool as_edges) { return new db::Edges (si, as_edges); @@ -425,6 +434,14 @@ Class dec_Edges ("db", "Edges", "This constructor creates an edge collection from a path.\n" "The edges form the contour of the path.\n" ) + + constructor ("new", &new_shapes, gsi::arg ("shapes"), gsi::arg ("as_edges", true), + "@brief Constructor of a flat edge collection from a \\Shapes container\n" + "\n" + "If 'as_edges' is true, the shapes from the container will be converted to edges (i.e. polygon contours to edges). " + "Otherwise, only edges will be taken from the container.\n" + "\n" + "This method has been introduced in version 0.26.\n" + ) + constructor ("new", &new_si, gsi::arg ("shape_iterator"), gsi::arg ("as_edges", true), "@brief Constructor of a flat edge collection from a hierarchical shape set\n" "\n" diff --git a/src/db/unit_tests/dbDeepEdgePairsTests.cc b/src/db/unit_tests/dbDeepEdgePairsTests.cc index c48af3b9b..374d25891 100644 --- a/src/db/unit_tests/dbDeepEdgePairsTests.cc +++ b/src/db/unit_tests/dbDeepEdgePairsTests.cc @@ -95,6 +95,7 @@ TEST(1_Basics) target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), edges); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (12, 0)), first_edges); target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (13, 0)), second_edges); + db::EdgePairs (ep2).insert_into_as_polygons (&target, target_top_cell_index, target.get_layer (db::LayerProperties (14, 0)), 1); CHECKPOINT(); db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_edge_pairs_au1.gds"); diff --git a/src/db/unit_tests/dbEdgePairs.cc b/src/db/unit_tests/dbEdgePairs.cc index 6ac6e5f77..7b889d4a1 100644 --- a/src/db/unit_tests/dbEdgePairs.cc +++ b/src/db/unit_tests/dbEdgePairs.cc @@ -126,3 +126,18 @@ TEST(3) EXPECT_EQ (ep.to_string (), ""); } +TEST(4) +{ + db::EdgePairs ep; + ep.insert (db::EdgePair (db::Edge (db::Point (10, 20), db::Point (50, 50)), db::Edge (db::Point (-10, -20), db::Point (90, 80)))); + ep.insert (db::EdgePair (db::Edge (db::Point (10, 20), db::Point (110, 120)), db::Edge (db::Point (90, 80), db::Point (-10, -20)))); + + db::Layout ly; + unsigned int l1 = ly.insert_layer (db::LayerProperties (1, 0)); + db::cell_index_type top_cell = ly.add_cell ("TOP"); + + ep.insert_into_as_polygons (&ly, top_cell, l1, 1); + + db::Region r (db::RecursiveShapeIterator (ly, ly.cell (top_cell), l1)); + EXPECT_EQ (r.to_string (), "(-11,-20;50,51;9,20;90,81);(-10,-21;9,20;110,121;91,80)"); +} diff --git a/testdata/algo/deep_edge_pairs_au1.gds b/testdata/algo/deep_edge_pairs_au1.gds index 59e006caffc3ff59b995438406af69b9b0b89853..c1c697e282219d04e4f72cf299f67c6a7e76ae44 100644 GIT binary patch delta 191 zcmeywv58ZOfsKKQDS|V!YE&c!hp9+X(U|_t%z`)cEqhaD8nt?@-fq{jcfkB29r_Gz^FwSJe LX7^?fW-UelT+%1U delta 127 zcmdnQ`H4e`fsKKQDS|o8HYG%vy{9=W7qT diff --git a/testdata/ruby/dbEdgePairsTest.rb b/testdata/ruby/dbEdgePairsTest.rb index b3a3efd6d..ba029ec51 100644 --- a/testdata/ruby/dbEdgePairsTest.rb +++ b/testdata/ruby/dbEdgePairsTest.rb @@ -112,6 +112,7 @@ class DBEdgePairs_TestClass < TestBase ep1 = RBA::EdgePair::new(RBA::Edge::new(0, 1, 2, 3), RBA::Edge::new(10, 11, 12, 13)) ep2 = RBA::EdgePair::new(RBA::Edge::new(20, 21, 22, 23), RBA::Edge::new(30, 31, 32, 33)) + ep3 = RBA::EdgePair::new(RBA::Edge::new(0, 0, 0, 10), RBA::Edge::new(10, 10, 10, 0)) r1 = RBA::EdgePairs::new([ ep1, ep2 ]) assert_equal(r1.to_s, "(0,1;2,3)/(10,11;12,13);(20,21;22,23)/(30,31;32,33)") @@ -128,6 +129,7 @@ class DBEdgePairs_TestClass < TestBase ly = RBA::Layout::new l1 = ly.layer("l1") l2 = ly.layer("l2") + l3 = ly.layer("l3") c1 = ly.create_cell("C1") c2 = ly.create_cell("C2") c1.insert(RBA::CellInstArray::new(c2.cell_index, RBA::Trans::new(0, 0))) @@ -135,6 +137,7 @@ class DBEdgePairs_TestClass < TestBase c1.insert(RBA::CellInstArray::new(c2.cell_index, RBA::Trans::new(200, 100))) c2.shapes(l1).insert(ep1) c2.shapes(l2).insert(ep2) + c2.shapes(l3).insert(ep3) r = RBA::EdgePairs::new(ly.begin_shapes(c1.cell_index, l1)) assert_equal(r.to_s(30), "(0,1;2,3)/(10,11;12,13);(0,101;2,103)/(10,111;12,113);(200,101;202,103)/(210,111;212,113)") @@ -145,12 +148,72 @@ class DBEdgePairs_TestClass < TestBase assert_equal(r.has_valid_edge_pairs?, false) assert_equal(r.bbox.to_s, "(0,1;212,113)") + assert_equal(r.is_deep?, false) + r.flatten assert_equal(r.has_valid_edge_pairs?, true) assert_equal(r[1].to_s, "(0,101;2,103)/(10,111;12,113)") assert_equal(r[100].inspect, "nil") assert_equal(r.bbox.to_s, "(0,1;212,113)") + dss = RBA::DeepShapeStore::new + r = RBA::EdgePairs::new(ly.begin_shapes(c1.cell_index, l1), dss) + assert_equal(r.to_s(30), "(0,1;2,3)/(10,11;12,13);(0,101;2,103)/(10,111;12,113);(200,101;202,103)/(210,111;212,113)") + assert_equal(r.to_s(2), "(0,1;2,3)/(10,11;12,13);(0,101;2,103)/(10,111;12,113)...") + assert_equal(r.is_empty?, false) + assert_equal(r.size, 3) + + assert_equal(r.has_valid_edge_pairs?, false) + assert_equal(r.bbox.to_s, "(0,1;212,113)") + + assert_equal(r.is_deep?, true) + + r.flatten + assert_equal(r.has_valid_edge_pairs?, true) + assert_equal(r[1].to_s, "(0,101;2,103)/(10,111;12,113)") + assert_equal(r[100].inspect, "nil") + assert_equal(r.bbox.to_s, "(0,1;212,113)") + + assert_equal(r.is_deep?, false) + + end + + def test_4 + + # insert_into and insert_into_as_polygons + + ep1 = RBA::EdgePair::new(RBA::Edge::new(0, 0, 0, 10), RBA::Edge::new(10, 10, 10, 0)) + + ly = RBA::Layout::new + l1 = ly.layer("l1") + c1 = ly.create_cell("C1") + c2 = ly.create_cell("C2") + c1.insert(RBA::CellInstArray::new(c2.cell_index, RBA::Trans::new(0, 0))) + c1.insert(RBA::CellInstArray::new(c2.cell_index, RBA::Trans::new(0, 100))) + c1.insert(RBA::CellInstArray::new(c2.cell_index, RBA::Trans::new(200, 100))) + c2.shapes(l1).insert(ep1) + + dss = RBA::DeepShapeStore::new + r = RBA::EdgePairs::new(ly.begin_shapes(c1.cell_index, l1), dss) + + target = RBA::Layout::new + target_top = target.add_cell("TOP") + target_li = target.layer + r.insert_into(target, target_top, target_li) + cells = [] + target.each_cell { |c| cells << c.name } + assert_equal(cells.join(","), "TOP,C2") + assert_equal(RBA::EdgePairs::new(target.cell("TOP").shapes(target_li)).to_s, "") + assert_equal(RBA::EdgePairs::new(target.cell("C2").shapes(target_li)).to_s, "(0,0;0,10)/(10,10;10,0)") + + target_li = target.layer + r.insert_into_as_polygons(target, target_top, target_li, 1) + cells = [] + target.each_cell { |c| cells << c.name } + assert_equal(cells.join(","), "TOP,C2") + assert_equal(RBA::Region::new(target.cell("TOP").shapes(target_li)).to_s, "") + assert_equal(RBA::Region::new(target.cell("C2").shapes(target_li)).to_s, "(-1,-1;-1,11;11,11;11,-1)") + end end diff --git a/testdata/ruby/dbEdgesTest.rb b/testdata/ruby/dbEdgesTest.rb index 872d24dc7..52e3c9062 100644 --- a/testdata/ruby/dbEdgesTest.rb +++ b/testdata/ruby/dbEdgesTest.rb @@ -559,6 +559,46 @@ class DBEdges_TestClass < TestBase end + # deep edges + def test_9 + + ly = RBA::Layout::new + l1 = ly.layer("l1") + c1 = ly.create_cell("C1") + c2 = ly.create_cell("C2") + c1.insert(RBA::CellInstArray::new(c2.cell_index, RBA::Trans::new(0, 0))) + c1.insert(RBA::CellInstArray::new(c2.cell_index, RBA::Trans::new(0, 100))) + c1.insert(RBA::CellInstArray::new(c2.cell_index, RBA::Trans::new(200, 100))) + c2.shapes(l1).insert(RBA::Box::new(-10, -20, 10, 20)) + + dss = RBA::DeepShapeStore::new + r = RBA::Edges::new(ly.begin_shapes(c1.cell_index, l1), dss, true) + assert_equal(r.to_s(30), "(-10,-20;-10,20);(-10,20;10,20);(10,20;10,-20);(10,-20;-10,-20);(-10,80;-10,120);(-10,120;10,120);(10,120;10,80);(10,80;-10,80);(190,80;190,120);(190,120;210,120);(210,120;210,80);(210,80;190,80)") + assert_equal(r.to_s(2), "(-10,-20;-10,20);(-10,20;10,20)...") + assert_equal(r.is_empty?, false) + assert_equal(r.bbox.to_s, "(-10,-20;210,120)") + assert_equal(r.is_deep?, true) + + target = RBA::Layout::new + target_top = target.add_cell("TOP") + target_li = target.layer + r.insert_into(target, target_top, target_li) + cells = [] + target.each_cell { |c| cells << c.name } + assert_equal(cells.join(","), "TOP,C2") + assert_equal(RBA::Edges::new(target.cell("TOP").shapes(target_li)).to_s, "") + assert_equal(RBA::Edges::new(target.cell("C2").shapes(target_li)).to_s, "(-10,-20;-10,20);(-10,20;10,20);(10,20;10,-20);(10,-20;-10,-20)") + + r.flatten + + assert_equal(r.is_deep?, false) + + assert_equal(r.size, 12) + assert_equal(r[1].to_s, "(-10,20;10,20)") + assert_equal(r[100].to_s, "") + + end + end load("test_epilogue.rb") diff --git a/testdata/ruby/dbRegionTest.rb b/testdata/ruby/dbRegionTest.rb index 37519e7dd..2a641b517 100644 --- a/testdata/ruby/dbRegionTest.rb +++ b/testdata/ruby/dbRegionTest.rb @@ -796,6 +796,7 @@ class DBRegion_TestClass < TestBase r = RBA::Region::new(ly.top_cell.begin_shapes_rec(l1), dss) rf = RBA::Region::new(ly.top_cell.begin_shapes_rec(l1)) + assert_equal(r.is_deep?, true) assert_equal(r.area, 53120000) assert_equal(rf.area, 53120000) @@ -815,6 +816,21 @@ class DBRegion_TestClass < TestBase assert_equal(s1, {"INV2"=>1, "TOP"=>0, "TRANS"=>0}) assert_equal(s2, {"INV2"=>0, "TOP"=>10, "TRANS"=>0}) + target = RBA::Layout::new + target_top = target.add_cell("TOP") + target_li = target.layer + r.insert_into(target, target_top, target_li) + cells = [] + target.each_cell { |c| cells << c.name } + assert_equal(cells.join(","), "TOP,INV2,TRANS") + assert_equal(RBA::Region::new(target.cell("TOP").shapes(target_li)).to_s, "") + assert_equal(RBA::Region::new(target.cell("INV2").shapes(target_li)).to_s, "(-1400,1800;-1400,3800;1400,3800;1400,1800)") + assert_equal(RBA::Region::new(target.cell("TRANS").shapes(target_li)).to_s, "") + + r.flatten + assert_equal(r.is_deep?, false) + assert_equal(r.area, 53120000) + # force destroy, so the unit tests pass on the next iteration dss._destroy assert_equal(RBA::DeepShapeStore::instance_count, 0)