diff --git a/src/db/db/dbPolygonTools.cc b/src/db/db/dbPolygonTools.cc index 77f7c9dcd..e44ecfa8b 100644 --- a/src/db/db/dbPolygonTools.cc +++ b/src/db/db/dbPolygonTools.cc @@ -112,7 +112,7 @@ struct cut_polygon_edge { typedef typename PointType::coord_type coord_type; typedef typename db::edge edge_type; - typedef typename db::coord_traits::area_type projection_type; + typedef double projection_type; cut_polygon_edge () : contour (-1), index (0), projected (0), point (), last_point () @@ -179,7 +179,7 @@ public: bool operator< (const loose_end_struct &other) const { - if (proj () != other.proj ()) { + if (! db::coord_traits::equal (proj (), other.proj ())) { return proj () < other.proj (); } else { return db::vprod_sign (edge (), other.edge ()) > 0; @@ -196,13 +196,13 @@ static bool _cut_polygon_internal (const PolygonType &input, const Edge &line, C typedef db::edge edge_type; typedef cut_polygon_edge cut_polygon_edge_type; typedef cut_polygon_segment cutting_segment_type; - typedef typename db::coord_traits::area_type projection_type; bool do_hole_assignment = (input.holes () > 0); std::vector hull_polygons; std::vector hole_polygons; std::vector cutting_segments; + double line_length = line.double_length (); for (unsigned int nc = 0; nc < input.holes () + 1; ++nc) { @@ -229,7 +229,7 @@ static bool _cut_polygon_internal (const PolygonType &input, const Edge &line, C int s1 = line.side_of (e.p1 ()); int s2 = line.side_of (e.p2 ()); - projection_type p = db::sprod (ip.second - line.p1 (), line.p2 () - line.p1 ()); + double p = line_length * double (db::vprod (e.p1 () - line.p1 (), e.d ())) / double (db::vprod (line.d (), e.d ())); if (s1 < 0 && s2 >= 0) { // right -> left or on edge diff --git a/src/db/unit_tests/dbPolygonTools.cc b/src/db/unit_tests/dbPolygonTools.cc index 06224c533..6229f89f4 100644 --- a/src/db/unit_tests/dbPolygonTools.cc +++ b/src/db/unit_tests/dbPolygonTools.cc @@ -2241,3 +2241,20 @@ TEST(403) EXPECT_EQ (right_of.size (), size_t (0)); } } + +// issue 166 +TEST(404) +{ + db::Polygon poly; + std::string s ("(390,0;438,936;176,874;0,832;438,937;541,961;821,102)"); + tl::Extractor ex (s.c_str ()); + ex.read (poly); + + std::vector sp; + db::split_polygon (poly, sp); + EXPECT_EQ (sp.size (), size_t (2)); + if (sp.size () >= 2) { + EXPECT_EQ (sp[0].to_string (), "(390,0;438,936;390,925;438,937;541,961;821,102)"); + EXPECT_EQ (sp[1].to_string (), "(0,832;176,874;390,925)"); + } +} diff --git a/src/plugins/streamers/gds2/unit_tests/dbGDS2Writer.cc b/src/plugins/streamers/gds2/unit_tests/dbGDS2Writer.cc index 7481dec1c..b48066aad 100644 --- a/src/plugins/streamers/gds2/unit_tests/dbGDS2Writer.cc +++ b/src/plugins/streamers/gds2/unit_tests/dbGDS2Writer.cc @@ -1145,3 +1145,11 @@ TEST(121) opt.max_vertex_count = 4; run_test (_this, "t121.oas.gz", "t121_au.gds.gz", true, opt); } + +// Extreme fracturing by max. points +TEST(166) +{ + db::GDS2WriterOptions opt; + opt.max_vertex_count = 4; + run_test (_this, "t166.oas.gz", "t166_au.gds.gz", false, opt); +} diff --git a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc index c16d732ed..15638f065 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbDEFImporter.cc @@ -70,17 +70,6 @@ DEFImporter::get_orient (bool optional) } } -/** - * @brief A structure describing a via - */ -struct ViaDesc -{ - ViaDesc () : cell (0) { } - - db::Cell *cell; - std::string m1, m2; -}; - void DEFImporter::read_polygon (db::Polygon &poly, double scale) { @@ -153,7 +142,7 @@ DEFImporter::do_read (db::Layout &layout) double dbu_mic = 1000.0; double scale = 1.0 / (dbu_mic * layout.dbu ()); std::map styles; - std::map via_desc; + std::map via_desc = m_lef_importer.vias (); std::map > regions; std::list groups; std::list > instances; diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h index 1b716023e..7188fcfae 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.h @@ -533,6 +533,24 @@ private: const LEFDEFReaderOptions *mp_tech_comp; }; +/** + * @brief A structure describing a via + */ +struct EXT_PUBLIC ViaDesc +{ + ViaDesc () : cell (0) { } + + /** + * @brief The cell representing the via + */ + db::Cell *cell; + + /** + * @brief The names of bottom and top metal respectively + */ + std::string m1, m2; +}; + /** * @brief The LEF importer object */ diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc index 105ddcc32..639d52549 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.cc @@ -458,6 +458,9 @@ LEFImporter::do_read (db::Layout &layout) std::string cellname = "VIA_" + n; db::Cell &cell = layout.cell (layout.add_cell (cellname.c_str ())); + ViaDesc &via_desc = m_vias[n]; + via_desc.cell = &cell; + while (test ("DEFAULT") || test ("TOPOFSTACKONLY")) ; test (";"); @@ -543,9 +546,9 @@ LEFImporter::do_read (db::Layout &layout) } else if (test ("LAYERS")) { - geometry[0].first = get (); + via_desc.m1 = geometry[0].first = get (); geometry[1].first = get (); - geometry[2].first = get (); + via_desc.m2 = geometry[2].first = get (); test (";"); diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h index 2d47040ac..c1467cb5c 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFImporter.h @@ -86,6 +86,16 @@ public: */ double layer_ext (const std::string &layer, double def_ext = 0.0) const; + /** + * @brief Gets a map of the vias defined in this LEF file + * + * The map maps the via name to the via description. + */ + const std::map &vias () const + { + return m_vias; + } + protected: void do_read (db::Layout &layout); @@ -95,6 +105,7 @@ private: std::map m_default_ext; std::map m_macros_by_name; std::map m_macro_bboxes_by_name; + std::map m_vias; std::vector get_iteration (db::Layout &layout); void read_geometries (db::Layout &layout, db::Cell &cell, LayerPurpose purpose, std::map *collect_bboxes = 0); diff --git a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImport.cc b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImport.cc index 6fe739373..3da2eec81 100644 --- a/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImport.cc +++ b/src/plugins/streamers/lefdef/unit_tests/dbLEFDEFImport.cc @@ -30,7 +30,7 @@ #include -static void run_test (tl::TestBase *_this, const char *lef_dir, const char *filename, const char *au) +static void run_test (tl::TestBase *_this, const char *lef_dir, const char *filename, const char *au, bool priv = true) { db::LEFDEFReaderOptions tc; tc.set_via_geometry_datatype (0); @@ -60,7 +60,7 @@ static void run_test (tl::TestBase *_this, const char *lef_dir, const char *file if (ex.test ("def:")) { - std::string fn (tl::testsrc_private ()); + std::string fn (priv ? tl::testsrc_private () : tl::testsrc ()); fn += "/testdata/lefdef/"; fn += lef_dir; fn += "/"; @@ -73,7 +73,7 @@ static void run_test (tl::TestBase *_this, const char *lef_dir, const char *file } else if (ex.test ("lef:")) { - std::string fn (tl::testsrc_private ()); + std::string fn (priv ? tl::testsrc_private () : tl::testsrc ()); fn += "/testdata/lefdef/"; fn += lef_dir; fn += "/"; @@ -118,7 +118,7 @@ static void run_test (tl::TestBase *_this, const char *lef_dir, const char *file if (au) { - std::string fn (tl::testsrc_private ()); + std::string fn (priv ? tl::testsrc_private () : tl::testsrc ()); fn += "/testdata/lefdef/"; fn += lef_dir; fn += "/"; @@ -233,3 +233,8 @@ TEST(19) run_test (_this, "def10", "def:in.def", "au.oas.gz"); } +TEST(20) +{ + run_test (_this, "issue-172", "lef:in.lef+def:in.def", "au.oas.gz", false); +} + diff --git a/testdata/gds/t166.oas.gz b/testdata/gds/t166.oas.gz new file mode 100644 index 000000000..3a209870a Binary files /dev/null and b/testdata/gds/t166.oas.gz differ diff --git a/testdata/gds/t166_au.gds.gz b/testdata/gds/t166_au.gds.gz new file mode 100644 index 000000000..7766ef28e Binary files /dev/null and b/testdata/gds/t166_au.gds.gz differ diff --git a/testdata/lefdef/issue-172/au.oas.gz b/testdata/lefdef/issue-172/au.oas.gz new file mode 100644 index 000000000..ce4faf592 Binary files /dev/null and b/testdata/lefdef/issue-172/au.oas.gz differ diff --git a/testdata/lefdef/issue-172/in.def b/testdata/lefdef/issue-172/in.def new file mode 100644 index 000000000..a4311b4ae --- /dev/null +++ b/testdata/lefdef/issue-172/in.def @@ -0,0 +1,16 @@ +VERSION 5.6 ; +NAMESCASESENSITIVE ON ; +DIVIDERCHAR "/" ; +BUSBITCHARS "<>" ; +DESIGN SMALL ; +UNITS DISTANCE MICRONS 100 ; + +DIEAREA ( -30 -30 ) ( 1030 1030 ) ; + +NETS 1 ; +- TOP ++ ROUTED M1 ( 0 0 ) ( 1000 * ) M2_M1 + NEW M2 ( 1000 0 ) ( 1000 1000 ) ; +END NETS + +END DESIGN diff --git a/testdata/lefdef/issue-172/in.lef b/testdata/lefdef/issue-172/in.lef new file mode 100644 index 000000000..a0359f764 --- /dev/null +++ b/testdata/lefdef/issue-172/in.lef @@ -0,0 +1,40 @@ +VERSION 5.7 ; +NAMESCASESENSITIVE ON ; +BUSBITCHARS "[]" ; +DIVIDERCHAR "/" ; +UNITS + DATABASE MICRONS 1000 ; +END UNITS + +USEMINSPACING OBS ON ; +USEMINSPACING PIN OFF ; +CLEARANCEMEASURE EUCLIDEAN ; + +MANUFACTURINGGRID 0.05 ; + +LAYER M1 + TYPE ROUTING ; + DIRECTION HORIZONTAL ; + WIDTH 0.2 ; +END M1 + +LAYER V2 + TYPE CUT ; +END V2 + +LAYER M2 + TYPE ROUTING ; + DIRECTION VERTICAL ; + WIDTH 0.2 ; +END M2 + +VIA M2_M1 DEFAULT + LAYER M1 ; + RECT -0.300 -0.300 0.300 0.300 ; + LAYER V2 ; + RECT -0.200 -0.200 0.200 0.200 ; + LAYER M2 ; + RECT -0.300 -0.300 0.300 0.300 ; +END M2_M1 + +END LIBRARY diff --git a/testdata/python/dbTransTest.py b/testdata/python/dbTransTest.py index c08d638e0..8f7643f45 100644 --- a/testdata/python/dbTransTest.py +++ b/testdata/python/dbTransTest.py @@ -150,7 +150,7 @@ class DBTransTests(unittest.TestCase): self.assertEqual( c.is_mirror(), True ) self.assertEqual( c.rot(), pya.DCplxTrans.M135.rot() ) self.assertEqual( str(c.s_trans()), "m135 0,0" ) - self.assertEqual( c.angle, 270 ) + self.assertAlmostEqual( c.angle, 270 ) self.assertEqual( str(c.trans( pya.Edge(0, 1, 2, 3) )), "(-1,0;-3,-2)" ) self.assertEqual( str(( c * pya.Edge(0, 1, 2, 3) )), "(-1,0;-3,-2)" ) @@ -174,7 +174,7 @@ class DBTransTests(unittest.TestCase): self.assertEqual( c.is_mirror(), False ) self.assertEqual( c.rot(), pya.DCplxTrans.R0.rot() ) self.assertEqual( str(c.s_trans()), "r0 0,0" ) - self.assertEqual( c.angle, 0 ) + self.assertAlmostEqual( c.angle, 0 ) c = pya.DCplxTrans( 0.75, 45, True, 2.5, -12.5 ) self.assertEqual( str(c), "m22.5 *0.75 2.5,-12.5" ) @@ -185,7 +185,7 @@ class DBTransTests(unittest.TestCase): self.assertEqual( c.is_mag(), True ) self.assertEqual( c.rot(), pya.DCplxTrans.M0.rot() ) self.assertEqual( str(c.s_trans()), "m0 2.5,-12.5" ) - self.assertEqual( c.angle, 45 ) + self.assertAlmostEqual( c.angle, 45 ) self.assertEqual( str(c.ctrans( 5 )), "3.75" ) self.assertEqual( str(c.trans( pya.DPoint( 12, 16 ) )), "17.3492424049,-14.6213203436" ) @@ -335,7 +335,7 @@ class DBTransTests(unittest.TestCase): self.assertEqual( c.is_mirror(), True ) self.assertEqual( c.rot(), pya.CplxTrans.M135.rot() ) self.assertEqual( str(c.s_trans()), "m135 0,0" ) - self.assertEqual( c.angle, 270 ) + self.assertAlmostEqual( c.angle, 270 ) c = pya.CplxTrans.from_dtrans( pya.DCplxTrans.M135 ) self.assertEqual( str(c), "m135 *1 0,0" ) @@ -348,7 +348,7 @@ class DBTransTests(unittest.TestCase): self.assertEqual( c.is_mirror(), False ) self.assertEqual( c.rot(), pya.CplxTrans.R0.rot() ) self.assertEqual( str(c.s_trans()), "r0 0,0" ) - self.assertEqual( c.angle, 0 ) + self.assertAlmostEqual( c.angle, 0 ) c = pya.CplxTrans( 0.75, 45, True, 2.5, -12.5 ) self.assertEqual( str(c), "m22.5 *0.75 2.5,-12.5" ) @@ -360,7 +360,7 @@ class DBTransTests(unittest.TestCase): self.assertEqual( c.is_mag(), True ) self.assertEqual( c.rot(), pya.CplxTrans.M0.rot() ) self.assertEqual( str(c.s_trans()), "m0 3,-13" ) - self.assertEqual( c.angle, 45 ) + self.assertAlmostEqual( c.angle, 45 ) self.assertEqual( str(c.ctrans( 5 )), "3.75" ) self.assertEqual( str(c.trans( pya.Point( 12, 16 ) )), "17.3492424049,-14.6213203436" ) @@ -517,7 +517,7 @@ class DBTransTests(unittest.TestCase): self.assertEqual(t1 < t4, True) self.assertEqual(t4 < t1, False) - # Hash values + # Hash values def test_5_Trans_Hash(self): t1 = pya.DTrans( pya.DTrans.M135, pya.DPoint( 17, 5 )) diff --git a/testdata/python/qtbinding.py b/testdata/python/qtbinding.py index 77ec69173..a077656e4 100644 --- a/testdata/python/qtbinding.py +++ b/testdata/python/qtbinding.py @@ -471,9 +471,11 @@ class QtBindingTest(unittest.TestCase): pya.QApplication.processEvents() - s1 = "QKeyEvent: ShortcutOverride (51)\nQKeyEvent: KeyPress (6)\nQKeyEvent: ShortcutOverride (51)\nQKeyEvent: KeyPress (6)\nQKeyEvent: ShortcutOverride (51)\nQKeyEvent: KeyPress (6)" - s2 = "QKeyEvent: KeyPress (6)\nQKeyEvent: KeyPress (6)\nQKeyEvent: KeyPress (6)" - self.assertEqual("\n".join(ef.log()) == s1 or "\n".join(ef.log()) == s2, True) + s1 = "QKeyEvent: ShortcutOverride (51)\nQKeyEvent: KeyPress (6)\nQKeyEvent: ShortcutOverride (51)\nQKeyEvent: KeyPress (6)\nQKeyEvent: ShortcutOverride (51)\nQKeyEvent: KeyPress (6)" + s2 = "QKeyEvent: KeyPress (6)\nQKeyEvent: KeyPress (6)\nQKeyEvent: KeyPress (6)" + s3 = "QKeyEvent_Native: ShortcutOverride (51)\nQKeyEvent: KeyPress (6)\nQKeyEvent_Native: ShortcutOverride (51)\nQKeyEvent: KeyPress (6)\nQKeyEvent_Native: ShortcutOverride (51)\nQKeyEvent: KeyPress (6)" + self.assertIn("\n".join(ef.log()), (s1, s2, s3)) + ef = None self.assertEqual(widget.text, "ABCpO") diff --git a/testdata/ruby/qtbinding.rb b/testdata/ruby/qtbinding.rb index 884f05e7b..e8d044dee 100644 --- a/testdata/ruby/qtbinding.rb +++ b/testdata/ruby/qtbinding.rb @@ -534,7 +534,10 @@ class QtBinding_TestClass < TestBase GC.start - assert_equal(ef.log.select { |s| s !~ /RBA::QKeyEvent: ShortcutOverride/ }.join("\n"), "RBA::QKeyEvent: KeyPress (6)\nRBA::QKeyEvent: KeyPress (6)\nRBA::QKeyEvent: KeyPress (6)") + assert_equal(ef.log.select { |s| s !~ /RBA::QKeyEvent: ShortcutOverride/ }.join("\n"), "RBA::QKeyEvent: KeyPress (6)\nRBA::QKeyEvent: KeyPress (6)\nRBA::QKeyEvent: KeyPress (6)") + + # TODO: on macOS 10.13, ef.log yields "RBA::QKeyEvent_Native: ShortcutOverride (51)\nRBA::QKeyEvent: KeyPress (6)\nRBA::QKeyEvent_Native: ShortcutOverride (51)\nRBA::QKeyEvent: KeyPress (6)\nRBA::QKeyEvent_Native: ShortcutOverride (51)\nRBA::QKeyEvent: KeyPress (6)", causing this test to fail. + ef = nil ef = EventFilter::new GC.start