mirror of https://github.com/KLayout/klayout.git
Basic implementation of 'resolve skew aref' feature
This commit is contained in:
parent
6496a71b5b
commit
eb26b6ed34
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -65,6 +65,16 @@ static bool get_gds2_multi_xy_records (const db::SaveLayoutOptions *options)
|
|||
return options->get_options<db::GDS2WriterOptions> ().multi_xy_records;
|
||||
}
|
||||
|
||||
static void set_gds2_resolve_skew_arrays (db::SaveLayoutOptions *options, bool n)
|
||||
{
|
||||
options->get_options<db::GDS2WriterOptions> ().resolve_skew_arrays = n;
|
||||
}
|
||||
|
||||
static bool get_gds2_resolve_skew_arrays (const db::SaveLayoutOptions *options)
|
||||
{
|
||||
return options->get_options<db::GDS2WriterOptions> ().resolve_skew_arrays;
|
||||
}
|
||||
|
||||
static void set_gds2_write_file_properties (db::SaveLayoutOptions *options, bool n)
|
||||
{
|
||||
options->get_options<db::GDS2WriterOptions> ().write_file_properties = n;
|
||||
|
|
@ -129,7 +139,7 @@ static double get_gds2_user_units (const db::SaveLayoutOptions *options)
|
|||
static
|
||||
gsi::ClassExt<db::SaveLayoutOptions> 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<db::SaveLayoutOptions> 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"
|
||||
|
|
|
|||
|
|
@ -50,58 +50,13 @@
|
|||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Max. vertices</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="3">
|
||||
<item row="7" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="write_timestamps">
|
||||
<property name="text">
|
||||
<string>Write current time to time stamps (BGNLIB, BGNSTR)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="max_vertex_le"/>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>(<4000 recommended, absolute limit 8191)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="libname_le"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>(keep empty for unspecified limit)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="3">
|
||||
<widget class="QCheckBox" name="multi_xy_cbx">
|
||||
<property name="text">
|
||||
<string>Multi-XY record mode for boundaries
|
||||
(enables infinitely large polygons/paths at the cost of compatibility)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="cell_name_length_le"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Library name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
|
|
@ -109,13 +64,16 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="no_zero_length_paths">
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Eliminate zero-length paths (convert to BOUNDARY)</string>
|
||||
<string>(<4000 recommended, absolute limit 8191)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="cell_name_length_le"/>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="3">
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
|
|
@ -181,6 +139,55 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="max_vertex_le"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>(keep empty for unspecified limit)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="3">
|
||||
<widget class="QCheckBox" name="multi_xy_cbx">
|
||||
<property name="text">
|
||||
<string>Multi-XY record mode for boundaries
|
||||
(enables infinitely large polygons/paths at the cost of compatibility)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Library name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Max. vertices</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="libname_le"/>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="no_zero_length_paths">
|
||||
<property name="text">
|
||||
<string>Eliminate zero-length paths (convert to BOUNDARY)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="resolve_skew_arrays_cbx">
|
||||
<property name="text">
|
||||
<string>Resolve skew (non-orthogonal) arrays into single instances</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue