From 4a212e8db6b57ee7a217acdf55f23d22c543b56e Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Thu, 7 Nov 2019 23:33:54 +0100 Subject: [PATCH] Added tests for Region#scale_and_snap and Region#snap --- src/db/unit_tests/dbDeepRegionTests.cc | 147 +++++++++++++++++-------- src/db/unit_tests/dbRegion.cc | 104 +++++++++++++++++ testdata/algo/deep_region_au28.gds | Bin 0 -> 65750 bytes testdata/algo/region_au32.gds | Bin 0 -> 65750 bytes testdata/algo/region_au33.gds | Bin 0 -> 65750 bytes 5 files changed, 204 insertions(+), 47 deletions(-) create mode 100644 testdata/algo/deep_region_au28.gds create mode 100644 testdata/algo/region_au32.gds create mode 100644 testdata/algo/region_au33.gds diff --git a/src/db/unit_tests/dbDeepRegionTests.cc b/src/db/unit_tests/dbDeepRegionTests.cc index e8e012b42..cbe9a558c 100644 --- a/src/db/unit_tests/dbDeepRegionTests.cc +++ b/src/db/unit_tests/dbDeepRegionTests.cc @@ -1490,59 +1490,112 @@ TEST(26_BreakoutCells) db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/deep_region_au26.gds"); } -TEST(27_snap) +TEST(27a_snap) { + db::Layout ly; { - db::Layout ly; - { - std::string fn (tl::testsrc ()); - fn += "/testdata/algo/scale_and_snap.gds"; - tl::InputStream stream (fn); - db::Reader reader (stream); - reader.read (ly); - } - - db::cell_index_type top_cell_index = *ly.begin_top_down (); - db::Cell &top_cell = ly.cell (top_cell_index); - - db::DeepShapeStore dss; - - unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); - db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1), dss); - r1.set_merged_semantics (false); - db::Region r2 = r1.snapped (19, 19); - - r2.insert_into (&ly, top_cell_index, ly.get_layer (db::LayerProperties (100, 0))); - - CHECKPOINT(); - db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/deep_region_au27.gds"); + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/scale_and_snap.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); } + db::cell_index_type top_cell_index = *ly.begin_top_down (); + db::Cell &top_cell = ly.cell (top_cell_index); + + db::DeepShapeStore dss; + + unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); + db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1), dss); + r1.set_merged_semantics (false); + db::Region r2 = r1.snapped (19, 19); + + r2.insert_into (&ly, top_cell_index, ly.get_layer (db::LayerProperties (100, 0))); + + CHECKPOINT(); + db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/deep_region_au27.gds"); +} + +TEST(27b_snap) +{ + db::Layout ly; { - db::Layout ly; - { - std::string fn (tl::testsrc ()); - fn += "/testdata/algo/scale_and_snap.gds"; - tl::InputStream stream (fn); - db::Reader reader (stream); - reader.read (ly); - } - - db::cell_index_type top_cell_index = *ly.begin_top_down (); - db::Cell &top_cell = ly.cell (top_cell_index); - - db::DeepShapeStore dss; - - unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); - db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1), dss); - r1.set_merged_semantics (false); - r1.snap (19, 19); - - r1.insert_into (&ly, top_cell_index, ly.get_layer (db::LayerProperties (100, 0))); - - CHECKPOINT(); - db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/deep_region_au27.gds"); + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/scale_and_snap.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); } + + db::cell_index_type top_cell_index = *ly.begin_top_down (); + db::Cell &top_cell = ly.cell (top_cell_index); + + db::DeepShapeStore dss; + + unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); + db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1), dss); + r1.set_merged_semantics (false); + r1.snap (19, 19); + + r1.insert_into (&ly, top_cell_index, ly.get_layer (db::LayerProperties (100, 0))); + + CHECKPOINT(); + db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/deep_region_au27.gds"); +} + +TEST(28a_snap) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/scale_and_snap.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::cell_index_type top_cell_index = *ly.begin_top_down (); + db::Cell &top_cell = ly.cell (top_cell_index); + + db::DeepShapeStore dss; + + unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); + db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1), dss); + r1.set_merged_semantics (false); + db::Region r2 = r1.scaled_and_snapped (19, 2, 10, 19, 2, 10); + + r2.insert_into (&ly, top_cell_index, ly.get_layer (db::LayerProperties (100, 0))); + + CHECKPOINT(); + db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/deep_region_au28.gds"); +} + +TEST(28b_snap) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/scale_and_snap.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::cell_index_type top_cell_index = *ly.begin_top_down (); + db::Cell &top_cell = ly.cell (top_cell_index); + + db::DeepShapeStore dss; + + unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); + db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1), dss); + r1.set_merged_semantics (false); + r1.scale_and_snap (19, 2, 10, 19, 2, 10); + + r1.insert_into (&ly, top_cell_index, ly.get_layer (db::LayerProperties (100, 0))); + + CHECKPOINT(); + db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/deep_region_au28.gds"); } TEST(100_Integration) diff --git a/src/db/unit_tests/dbRegion.cc b/src/db/unit_tests/dbRegion.cc index 9f1a4b40f..21ba05b60 100644 --- a/src/db/unit_tests/dbRegion.cc +++ b/src/db/unit_tests/dbRegion.cc @@ -28,6 +28,10 @@ #include "dbRegionProcessors.h" #include "dbEdgesUtils.h" #include "dbBoxScanner.h" +#include "dbReader.h" +#include "dbTestSupport.h" + +#include "tlStream.h" #include @@ -1391,6 +1395,106 @@ TEST(31) EXPECT_EQ (db::Region (db::Box (db::Point (0, 3999), db::Point (1001, 6000))).pull_overlapping (r).to_string (), "(1000,0;1000,4000;6000,4000;6000,0)"); } +TEST(32a_snap) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/scale_and_snap.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::cell_index_type top_cell_index = *ly.begin_top_down (); + db::Cell &top_cell = ly.cell (top_cell_index); + + unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); + db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1)); + r1.set_merged_semantics (false); + db::Region r2 = r1.snapped (19, 19); + + r2.insert_into (&ly, top_cell_index, ly.get_layer (db::LayerProperties (100, 0))); + + CHECKPOINT(); + db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/region_au32.gds"); +} + +TEST(32b_snap) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/scale_and_snap.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::cell_index_type top_cell_index = *ly.begin_top_down (); + db::Cell &top_cell = ly.cell (top_cell_index); + + unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); + db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1)); + r1.set_merged_semantics (false); + r1.snap (19, 19); + + r1.insert_into (&ly, top_cell_index, ly.get_layer (db::LayerProperties (100, 0))); + + CHECKPOINT(); + db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/region_au32.gds"); +} + +TEST(33a_snap) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/scale_and_snap.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::cell_index_type top_cell_index = *ly.begin_top_down (); + db::Cell &top_cell = ly.cell (top_cell_index); + + unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); + db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1)); + r1.set_merged_semantics (false); + db::Region r2 = r1.scaled_and_snapped (19, 2, 10, 19, 2, 10); + + r2.insert_into (&ly, top_cell_index, ly.get_layer (db::LayerProperties (100, 0))); + + CHECKPOINT(); + db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/region_au33.gds"); +} + +TEST(33b_snap) +{ + db::Layout ly; + { + std::string fn (tl::testsrc ()); + fn += "/testdata/algo/scale_and_snap.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::cell_index_type top_cell_index = *ly.begin_top_down (); + db::Cell &top_cell = ly.cell (top_cell_index); + + unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); + db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1)); + r1.set_merged_semantics (false); + r1.scale_and_snap (19, 2, 10, 19, 2, 10); + + r1.insert_into (&ly, top_cell_index, ly.get_layer (db::LayerProperties (100, 0))); + + CHECKPOINT(); + db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/region_au33.gds"); +} + TEST(100_Processors) { db::Region r; diff --git a/testdata/algo/deep_region_au28.gds b/testdata/algo/deep_region_au28.gds new file mode 100644 index 0000000000000000000000000000000000000000..b7d0b6ef15e1ac33261a3303dc78f0097e275e09 GIT binary patch literal 65750 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 literal 0 HcmV?d00001 diff --git a/testdata/algo/region_au32.gds b/testdata/algo/region_au32.gds new file mode 100644 index 0000000000000000000000000000000000000000..f510c8dca2d52646f562c3e093c94d1cae76de13 GIT binary patch literal 65750 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 F^1srhbjkn# literal 0 HcmV?d00001 diff --git a/testdata/algo/region_au33.gds b/testdata/algo/region_au33.gds new file mode 100644 index 0000000000000000000000000000000000000000..bae4cd78ea91e63fbf59fe337f8e9ce922de9fee GIT binary patch literal 65750 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 literal 0 HcmV?d00001