diff --git a/src/plugins/streamers/gds2/db_plugin/dbGDS2.cc b/src/plugins/streamers/gds2/db_plugin/dbGDS2.cc index cb1db602d..21f25c7e1 100644 --- a/src/plugins/streamers/gds2/db_plugin/dbGDS2.cc +++ b/src/plugins/streamers/gds2/db_plugin/dbGDS2.cc @@ -74,6 +74,7 @@ class GDS2FormatDeclaration tl::make_member (&db::GDS2WriterOptions::write_file_properties, "write-file-properties") + tl::make_member (&db::GDS2WriterOptions::no_zero_length_paths, "no-zero-length-paths") + tl::make_member (&db::GDS2WriterOptions::multi_xy_records, "multi-xy-records") + + tl::make_member (&db::GDS2WriterOptions::resolve_skew_arrays, "resolve-skew-arrays") + tl::make_member (&db::GDS2WriterOptions::max_vertex_count, "max-vertex-count") + tl::make_member (&db::GDS2WriterOptions::max_cellname_length, "max-cellname-length") + tl::make_member (&db::GDS2WriterOptions::libname, "libname") diff --git a/src/plugins/streamers/gds2/db_plugin/dbGDS2Format.h b/src/plugins/streamers/gds2/db_plugin/dbGDS2Format.h index 79592d62a..30941c142 100644 --- a/src/plugins/streamers/gds2/db_plugin/dbGDS2Format.h +++ b/src/plugins/streamers/gds2/db_plugin/dbGDS2Format.h @@ -109,6 +109,7 @@ public: : max_vertex_count (8000), no_zero_length_paths (false), multi_xy_records (false), + resolve_skew_arrays (false), max_cellname_length (32000), libname ("LIB"), user_units (1.0), @@ -146,6 +147,13 @@ public: */ bool multi_xy_records; + /** + * @brief Resolve skew arrays into single instances + * + * Setting this property to true will resolve skew (non-orthogonal) arrays into single instances. + */ + bool resolve_skew_arrays; + /** * @brief Maximum length of cell names * diff --git a/src/plugins/streamers/gds2/db_plugin/dbGDS2WriterBase.cc b/src/plugins/streamers/gds2/db_plugin/dbGDS2WriterBase.cc index fad889519..0ed5d14ae 100644 --- a/src/plugins/streamers/gds2/db_plugin/dbGDS2WriterBase.cc +++ b/src/plugins/streamers/gds2/db_plugin/dbGDS2WriterBase.cc @@ -130,6 +130,7 @@ GDS2WriterBase::write (db::Layout &layout, tl::OutputStream &stream, const db::S size_t max_cellname_length = std::max (gds2_options.max_cellname_length, (unsigned int)8); size_t max_vertex_count = std::max (gds2_options.max_vertex_count, (unsigned int)4); bool no_zero_length_paths = gds2_options.no_zero_length_paths; + bool resolve_skew_arrays = gds2_options.resolve_skew_arrays; m_cell_name_map = db::WriterCellNameMap (max_cellname_length); m_cell_name_map.replacement ('$'); @@ -281,7 +282,7 @@ GDS2WriterBase::write (db::Layout &layout, tl::OutputStream &stream, const db::S if (options.keep_instances () || cell_set.find (inst->cell_index ()) != cell_set.end ()) { progress_checkpoint (); - write_inst (sf, *inst, true /*normalize*/, layout, inst->prop_id ()); + write_inst (sf, *inst, true /*normalize*/, resolve_skew_arrays, layout, inst->prop_id ()); } @@ -346,14 +347,24 @@ GDS2WriterBase::write (db::Layout &layout, tl::OutputStream &stream, const db::S progress_checkpoint (); } +static bool is_orthogonal (const db::Vector &rv, const db::Vector &cv) +{ + return (rv.x () == 0 && cv.y () == 0) || (rv.y () == 0 && cv.x () == 0); +} + void -GDS2WriterBase::write_inst (double sf, const db::Instance &instance, bool normalize, const db::Layout &layout, db::properties_id_type prop_id) +GDS2WriterBase::write_inst (double sf, const db::Instance &instance, bool normalize, bool resolve_skew_arrays, const db::Layout &layout, db::properties_id_type prop_id) { db::Vector a, b; unsigned long amax, bmax; bool is_reg = instance.is_regular_array (a, b, amax, bmax); + // skew arrays are resolved if required + if (is_reg && ! is_orthogonal (a, b) != 0 && resolve_skew_arrays) { + is_reg = false; + } + for (db::CellInstArray::iterator ii = instance.begin (); ! ii.at_end (); ++ii) { db::Trans t = *ii; diff --git a/src/plugins/streamers/gds2/db_plugin/dbGDS2WriterBase.h b/src/plugins/streamers/gds2/db_plugin/dbGDS2WriterBase.h index cc15680e6..3dada7332 100644 --- a/src/plugins/streamers/gds2/db_plugin/dbGDS2WriterBase.h +++ b/src/plugins/streamers/gds2/db_plugin/dbGDS2WriterBase.h @@ -122,7 +122,7 @@ protected: /** * @brief Write an instance */ - void write_inst (double sf, const db::Instance &instance, bool normalize, const db::Layout &layout, db::properties_id_type prop_id); + void write_inst (double sf, const db::Instance &instance, bool normalize, bool resolve_skew_arrays, const db::Layout &layout, db::properties_id_type prop_id); /** * @brief Write a shape as box diff --git a/src/plugins/streamers/gds2/db_plugin/gsiDeclDbGDS2.cc b/src/plugins/streamers/gds2/db_plugin/gsiDeclDbGDS2.cc index 8b732eba1..c8e62120e 100644 --- a/src/plugins/streamers/gds2/db_plugin/gsiDeclDbGDS2.cc +++ b/src/plugins/streamers/gds2/db_plugin/gsiDeclDbGDS2.cc @@ -65,6 +65,16 @@ static bool get_gds2_multi_xy_records (const db::SaveLayoutOptions *options) return options->get_options ().multi_xy_records; } +static void set_gds2_resolve_skew_arrays (db::SaveLayoutOptions *options, bool n) +{ + options->get_options ().resolve_skew_arrays = n; +} + +static bool get_gds2_resolve_skew_arrays (const db::SaveLayoutOptions *options) +{ + return options->get_options ().resolve_skew_arrays; +} + static void set_gds2_write_file_properties (db::SaveLayoutOptions *options, bool n) { options->get_options ().write_file_properties = n; @@ -129,7 +139,7 @@ static double get_gds2_user_units (const db::SaveLayoutOptions *options) static gsi::ClassExt gds2_writer_options ( gsi::method_ext ("gds2_max_vertex_count=", &set_gds2_max_vertex_count, gsi::arg ("count"), - "@brief Set the maximum number of vertices for polygons to write\n" + "@brief Sets the maximum number of vertices for polygons to write\n" "This property describes the maximum number of point for polygons in GDS2 files.\n" "Polygons with more points will be split.\n" "The minimum value for this property is 4. The maximum allowed value is about 4000 or 8000, depending on the\n" @@ -138,24 +148,37 @@ gsi::ClassExt gds2_writer_options ( "\nThis property has been added in version 0.18.\n" ) + gsi::method_ext ("gds2_max_vertex_count", &get_gds2_max_vertex_count, - "@brief Get the maximum number of vertices for polygons to write\n" + "@brief Gets the maximum number of vertices for polygons to write\n" "See \\gds2_max_vertex_count= method for a description of the maximum vertex count." "\nThis property has been added in version 0.18.\n" ) + gsi::method_ext ("gds2_multi_xy_records=", &set_gds2_multi_xy_records, gsi::arg ("flag"), - "@brief Use multiple XY records in BOUNDARY elements for unlimited large polygons\n" + "@brief Uses multiple XY records in BOUNDARY elements for unlimited large polygons\n" "\n" "Setting this property to true allows producing polygons with an unlimited number of points \n" "at the cost of incompatible formats. Setting it to true disables the \\gds2_max_vertex_count setting.\n" "\nThis property has been added in version 0.18.\n" ) + gsi::method_ext ("gds2_multi_xy_records?", &get_gds2_multi_xy_records, - "@brief Get the property enabling multiple XY records for BOUNDARY elements\n" + "@brief Gets the property enabling multiple XY records for BOUNDARY elements\n" "See \\gds2_multi_xy_records= method for a description of this property." "\nThis property has been added in version 0.18.\n" ) + + gsi::method_ext ("gds2_resolve_skew_arrays=", &set_gds2_resolve_skew_arrays, gsi::arg ("flag"), + "@brief Resolves skew arrays into single instances\n" + "\n" + "Setting this property to true will make skew (non-orthongonal) arrays being resolved into single instances.\n" + "Skew arrays happen if either the row or column vector isn't paralell to x or y axis. Such arrays can cause problems with " + "some legacy software and can be disabled with this option.\n" + "\nThis property has been added in version 0.27.1.\n" + ) + + gsi::method_ext ("gds2_resolve_skew_arrays?", &get_gds2_resolve_skew_arrays, + "@brief Gets a value indicating whether to resolve skew arrays into single instances\n" + "See \\gds2_resolve_skew_arrays= method for a description of this property." + "\nThis property has been added in version 0.27.1.\n" + ) + gsi::method_ext ("gds2_write_timestamps=", &set_gds2_write_timestamps, gsi::arg ("flag"), - "@brief Write the current time into the GDS2 timestamps if set to true\n" + "@brief Writes the current time into the GDS2 timestamps if set to true\n" "\n" "If this property is set to false, the time fields will all be zero. This somewhat simplifies compare and diff " "applications.\n" diff --git a/src/plugins/streamers/gds2/lay_plugin/GDS2WriterOptionPage.ui b/src/plugins/streamers/gds2/lay_plugin/GDS2WriterOptionPage.ui index 4cc503688..72c6020f4 100644 --- a/src/plugins/streamers/gds2/lay_plugin/GDS2WriterOptionPage.ui +++ b/src/plugins/streamers/gds2/lay_plugin/GDS2WriterOptionPage.ui @@ -50,58 +50,13 @@ 6 - - - - Max. vertices - - - - + Write current time to time stamps (BGNLIB, BGNSTR) - - - - - - - (<4000 recommended, absolute limit 8191) - - - - - - - - - - (keep empty for unspecified limit) - - - - - - - Multi-XY record mode for boundaries -(enables infinitely large polygons/paths at the cost of compatibility) - - - - - - - - - - Library name - - - @@ -109,13 +64,16 @@ - - + + - Eliminate zero-length paths (convert to BOUNDARY) + (<4000 recommended, absolute limit 8191) + + + @@ -181,6 +139,55 @@ + + + + + + + (keep empty for unspecified limit) + + + + + + + Multi-XY record mode for boundaries +(enables infinitely large polygons/paths at the cost of compatibility) + + + + + + + Library name + + + + + + + Max. vertices + + + + + + + + + + Eliminate zero-length paths (convert to BOUNDARY) + + + + + + + Resolve skew (non-orthogonal) arrays into single instances + + + diff --git a/src/plugins/streamers/gds2/lay_plugin/layGDS2WriterPlugin.cc b/src/plugins/streamers/gds2/lay_plugin/layGDS2WriterPlugin.cc index c24eda9b8..948b211a7 100644 --- a/src/plugins/streamers/gds2/lay_plugin/layGDS2WriterPlugin.cc +++ b/src/plugins/streamers/gds2/lay_plugin/layGDS2WriterPlugin.cc @@ -61,6 +61,7 @@ GDS2WriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const db: mp_ui->write_file_properties->setChecked (options->write_file_properties); mp_ui->no_zero_length_paths->setChecked (options->no_zero_length_paths); mp_ui->multi_xy_cbx->setChecked (options->multi_xy_records); + mp_ui->resolve_skew_arrays_cbx->setChecked (options->resolve_skew_arrays); mp_ui->max_vertex_le->setEnabled (! options->multi_xy_records); mp_ui->max_vertex_le->setText (tl::to_qstring (tl::to_string (options->max_vertex_count))); mp_ui->cell_name_length_le->setText (tl::to_qstring (tl::to_string (options->max_cellname_length))); @@ -76,6 +77,7 @@ GDS2WriterOptionPage::commit (db::FormatSpecificWriterOptions *o, const db::Tech unsigned int n; options->multi_xy_records = mp_ui->multi_xy_cbx->isChecked (); + options->resolve_skew_arrays = mp_ui->resolve_skew_arrays_cbx->isChecked (); options->write_timestamps = mp_ui->write_timestamps->isChecked (); options->write_cell_properties = mp_ui->write_cell_properties->isChecked (); options->write_file_properties = mp_ui->write_file_properties->isChecked (); diff --git a/src/plugins/streamers/gds2/unit_tests/dbGDS2Writer.cc b/src/plugins/streamers/gds2/unit_tests/dbGDS2Writer.cc index 77c902223..35e25883c 100644 --- a/src/plugins/streamers/gds2/unit_tests/dbGDS2Writer.cc +++ b/src/plugins/streamers/gds2/unit_tests/dbGDS2Writer.cc @@ -83,6 +83,19 @@ TEST(1) run_test (_this, "arefs.gds", "arefs_ref.gds"); } +TEST(1a) +{ + db::GDS2WriterOptions opt; + run_test (_this, "arefs_skew.gds", "arefs_skew1.gds", false, opt); +} + +TEST(1b) +{ + db::GDS2WriterOptions opt; + opt.resolve_skew_arrays = true; + run_test (_this, "arefs_skew.gds", "arefs_skew2.gds", false, opt); +} + TEST(2) { db::Manager m (false); diff --git a/testdata/gds/arefs_skew.gds b/testdata/gds/arefs_skew.gds new file mode 100644 index 000000000..e478b422d Binary files /dev/null and b/testdata/gds/arefs_skew.gds differ diff --git a/testdata/gds/arefs_skew1.gds b/testdata/gds/arefs_skew1.gds new file mode 100644 index 000000000..a7738e3c7 Binary files /dev/null and b/testdata/gds/arefs_skew1.gds differ diff --git a/testdata/gds/arefs_skew2.gds b/testdata/gds/arefs_skew2.gds new file mode 100644 index 000000000..6183fcbd8 Binary files /dev/null and b/testdata/gds/arefs_skew2.gds differ diff --git a/testdata/python/dbReaders.py b/testdata/python/dbReaders.py index 426b6f17f..d7f2d5c44 100644 --- a/testdata/python/dbReaders.py +++ b/testdata/python/dbReaders.py @@ -64,6 +64,11 @@ class DBReadersTests(unittest.TestCase): opt.gds2_allow_multi_xy_records = False self.assertEqual(opt.gds2_allow_multi_xy_records, False) + opt.gds2_resolve_skew_arrays = True + self.assertEqual(opt.gds2_resolve_skew_arrays, True) + opt.gds2_resolve_skew_arrays = False + self.assertEqual(opt.gds2_resolve_skew_arrays, False) + opt.gds2_allow_big_records = True self.assertEqual(opt.gds2_allow_big_records, True) opt.gds2_allow_big_records = False