mirror of https://github.com/KLayout/klayout.git
Adding 'merge_props' and 'merged_props' to DRC
This commit is contained in:
parent
f9ea9af466
commit
ffafebcaae
|
|
@ -33,7 +33,7 @@ RegionDelegate::RegionDelegate ()
|
|||
m_base_verbosity = 30;
|
||||
m_report_progress = false;
|
||||
m_merged_semantics = true;
|
||||
m_join_properties_on_merge = true;
|
||||
m_join_properties_on_merge = false;
|
||||
m_strict_handling = false;
|
||||
m_merge_min_coherence = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1059,9 +1059,9 @@ static void break_polygons (db::Region *r, size_t max_vertex_count, double max_a
|
|||
r->process (db::PolygonBreaker (max_vertex_count, max_area_ratio));
|
||||
}
|
||||
|
||||
static db::Region &merge_ext1 (db::Region *r, int min_wc, bool jpm)
|
||||
static db::Region &merge_ext1 (db::Region *r, int min_wc)
|
||||
{
|
||||
r->merge (false, std::max (0, min_wc - 1), jpm);
|
||||
r->merge (false, std::max (0, min_wc - 1));
|
||||
return *r;
|
||||
}
|
||||
|
||||
|
|
@ -1071,9 +1071,9 @@ static db::Region &merge_ext2 (db::Region *r, bool min_coherence, int min_wc, bo
|
|||
return *r;
|
||||
}
|
||||
|
||||
static db::Region merged_ext1 (db::Region *r, int min_wc, bool jpm)
|
||||
static db::Region merged_ext1 (db::Region *r, int min_wc)
|
||||
{
|
||||
return r->merged (false, std::max (0, min_wc - 1), jpm);
|
||||
return r->merged (false, std::max (0, min_wc - 1));
|
||||
}
|
||||
|
||||
static db::Region merged_ext2 (db::Region *r, bool min_coherence, int min_wc, bool jpm)
|
||||
|
|
@ -1747,14 +1747,13 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
method ("join_properties_on_merge=", &db::Region::set_join_properties_on_merge, gsi::arg ("f"),
|
||||
"@brief Sets a flag indication whether to join properties on merge\n"
|
||||
"\n"
|
||||
"When this flag is set to true (the default), properties are joined on 'merge'.\n"
|
||||
"When this flag is set to true, properties are joined on 'merge'.\n"
|
||||
"That is: shapes merging into bigger shapes will have their properties joined.\n"
|
||||
"With the flag set to false, 'merge' will not join properties and return merged\n"
|
||||
"With the flag set to false (the default), 'merge' will not join properties and return merged\n"
|
||||
"shapes only if the sub-shapes have the same properties - i.e. properties form\n"
|
||||
"different classes on merge.\n"
|
||||
"\n"
|
||||
"This attribute has been introduced in version 0.30.3. The default has changed from 'don't join properties' to "
|
||||
"'join properties' in that version."
|
||||
"This attribute has been introduced in version 0.30.3."
|
||||
) +
|
||||
method ("join_properties_on_merge?", &db::Region::join_properties_on_merge,
|
||||
"@brief Gets a flag indication whether to join properties on merge\n"
|
||||
|
|
@ -2398,13 +2397,13 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"@return The region after it has been merged (self).\n"
|
||||
"\n"
|
||||
"Merging removes overlaps and joins touching polygons.\n"
|
||||
"If the region is already merged, this method does nothing\n"
|
||||
"If the region is already merged, this method does nothing.\n"
|
||||
"This method will behave according to the settings of the \\min_coherence and \\join_properties_on_merge attributes."
|
||||
) +
|
||||
method_ext ("merge", &merge_ext1, gsi::arg ("min_wc"), gsi::arg ("join_properties_on_merge", true),
|
||||
method_ext ("merge", &merge_ext1, gsi::arg ("min_wc"),
|
||||
"@brief Merge the region with options\n"
|
||||
"\n"
|
||||
"@param min_wc Overlap selection\n"
|
||||
"@param join_properties_on_merge See below\n"
|
||||
"@return The region after it has been merged (self).\n"
|
||||
"\n"
|
||||
"Merging removes overlaps and joins touching polygons.\n"
|
||||
|
|
@ -2412,16 +2411,9 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"polygons overlap. The value specifies the number of polygons that need to overlap. A value of 2 "
|
||||
"means that output is only produced if two or more polygons overlap.\n"
|
||||
"\n"
|
||||
"The 'join_properties_on_merge' argument indicates how properties should be handled: if true, "
|
||||
"the properties of the constituents are joined and attached to the merged shape. If false, "
|
||||
"only shapes with the same properties are merged - i.e. different properties form shape classes "
|
||||
"that are merged individually.\n"
|
||||
"\n"
|
||||
"This method is equivalent to \"merge(false, min_wc, join_properties_on_merge).\n"
|
||||
"\n"
|
||||
"'join_properties_on_merge' has been added in version 0.30.3."
|
||||
"This method is equivalent to \"merge(false, min_wc, false).\n"
|
||||
) +
|
||||
method_ext ("merge", &merge_ext2, gsi::arg ("min_coherence"), gsi::arg ("min_wc"), gsi::arg ("join_properties_on_merge", true),
|
||||
method_ext ("merge", &merge_ext2, gsi::arg ("min_coherence"), gsi::arg ("min_wc"), gsi::arg ("join_properties_on_merge", false),
|
||||
"@brief Merge the region with options\n"
|
||||
"\n"
|
||||
"@param min_coherence A flag indicating whether the resulting polygons shall have minimum coherence\n"
|
||||
|
|
@ -2449,24 +2441,24 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"\n"
|
||||
"Merging removes overlaps and joins touching polygons.\n"
|
||||
"If the region is already merged, this method does nothing.\n"
|
||||
"This method will behave according to the settings of the \\min_coherence and \\join_properties_on_merge attributes.\n"
|
||||
"In contrast to \\merge, this method does not modify the region but returns a merged copy.\n"
|
||||
) +
|
||||
method_ext ("merged", &merged_ext1, gsi::arg ("min_wc"), gsi::arg ("join_properties_on_merge", true),
|
||||
method_ext ("merged", &merged_ext1, gsi::arg ("min_wc"),
|
||||
"@brief Returns the merged region (with options)\n"
|
||||
"\n"
|
||||
"@param min_wc Overlap selection\n"
|
||||
"@param join_properties_on_merge See below\n"
|
||||
"@return The region after it has been merged.\n"
|
||||
"\n"
|
||||
"This version provides one additional options: \"min_wc\" controls whether output is only produced if multiple "
|
||||
"polygons overlap. The value specifies the number of polygons that need to overlap. A value of 2 "
|
||||
"means that output is only produced if two or more polygons overlap.\n"
|
||||
"\n"
|
||||
"This method is equivalent to \"merged(false, min_wc, join_properties_on_merge)\".\n"
|
||||
"This method is equivalent to \"merged(false, min_wc, false)\".\n"
|
||||
"\n"
|
||||
"In contrast to \\merge, this method does not modify the region but returns a merged copy.\n"
|
||||
) +
|
||||
method_ext ("merged", &merged_ext2, gsi::arg ("min_coherence"), gsi::arg ("min_wc"), gsi::arg ("join_properties_on_merge", true),
|
||||
method_ext ("merged", &merged_ext2, gsi::arg ("min_coherence"), gsi::arg ("min_wc"), gsi::arg ("join_properties_on_merge", false),
|
||||
"@brief Returns the merged region (with options)\n"
|
||||
"\n"
|
||||
"@param min_coherence A flag indicating whether the resulting polygons shall have minimum coherence\n"
|
||||
|
|
|
|||
|
|
@ -2151,6 +2151,8 @@ TEST(40_BoolWithProperties)
|
|||
db::RecursiveShapeIterator si1 (ly, top_cell, l1);
|
||||
si1.apply_property_translator (db::PropertiesTranslator::make_pass_all ());
|
||||
db::Region r1 (si1, dss);
|
||||
EXPECT_EQ (r1.join_properties_on_merge (), false);
|
||||
r1.set_join_properties_on_merge (true);
|
||||
EXPECT_EQ (r1.join_properties_on_merge (), true);
|
||||
r1.set_join_properties_on_merge (false);
|
||||
EXPECT_EQ (r1.join_properties_on_merge (), false);
|
||||
|
|
|
|||
|
|
@ -5103,18 +5103,66 @@ CODE
|
|||
# Like \merged, but modifies the input and returns a reference to the
|
||||
# new layer.
|
||||
|
||||
def merged(*args)
|
||||
def merged(overlap_count = 1)
|
||||
@engine._context("merged") do
|
||||
requires_edges_or_region
|
||||
aa = args.collect { |a| @engine._prep_value(a) }
|
||||
aa = [ @engine._prep_value(overlap_count) ]
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, self.data.class, :merged, *aa))
|
||||
end
|
||||
end
|
||||
|
||||
def merge(*args)
|
||||
def merge(overlap_count = 1)
|
||||
@engine._context("merge") do
|
||||
requires_edges_or_region
|
||||
aa = args.collect { |a| @engine._prep_value(a) }
|
||||
aa = [ @engine._prep_value(overlap_count) ]
|
||||
if @engine.is_tiled?
|
||||
# in tiled mode, no modifying versions are available
|
||||
self.data = @engine._tcmd(self.data, 0, self.data.class, :merged, *aa)
|
||||
else
|
||||
@engine._tcmd(self.data, 0, self.data.class, :merge, *aa)
|
||||
end
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
# %DRC%
|
||||
# @name merged_props
|
||||
# @brief Merges and joins properties of the shapes
|
||||
# @synopsis layer.merged_props([overlap_count])
|
||||
#
|
||||
# Returns the merged input. Unlike the plain \merged method, this version
|
||||
# will join properties on merged shapes. Properties with the same name
|
||||
# will be merged by computing the maximum value of the parts.
|
||||
#
|
||||
# For example:
|
||||
# Properties @tt { "A" => 17, "C" => 2.5 } @/tt merged with @tt { "A" => 1, "B" => "a text" } @/tt will give
|
||||
# @tt { "A" => 17, "B" => "a text", "C" => 2.5 } @/tt.
|
||||
#
|
||||
# The plain \merged method will treat shapes with different properties as
|
||||
# separate entities and will not merge them.
|
||||
#
|
||||
# Currently, this method is available for polygon layers only.
|
||||
|
||||
# %DRC%
|
||||
# @name merge_props
|
||||
# @brief Merges the layer and joins the properties (modifies the layer)
|
||||
# @synopsis layer.merge_props([overlap_count])
|
||||
#
|
||||
# Like \merged_props, but modifies the input and returns a reference to the
|
||||
# new layer.
|
||||
|
||||
def merged_props(overlap_count = 1)
|
||||
@engine._context("merged") do
|
||||
requires_region
|
||||
aa = [ self.data.min_coherence, @engine._prep_value(overlap_count), true ]
|
||||
DRCLayer::new(@engine, @engine._tcmd(self.data, 0, self.data.class, :merged, *aa))
|
||||
end
|
||||
end
|
||||
|
||||
def merge_props(overlap_count = 1)
|
||||
@engine._context("merge") do
|
||||
requires_region
|
||||
aa = [ self.data.min_coherence, @engine._prep_value(overlap_count), true ]
|
||||
if @engine.is_tiled?
|
||||
# in tiled mode, no modifying versions are available
|
||||
self.data = @engine._tcmd(self.data, 0, self.data.class, :merged, *aa)
|
||||
|
|
|
|||
|
|
@ -2003,3 +2003,13 @@ TEST(140d_target_modification)
|
|||
{
|
||||
run_test (_this, "140", true);
|
||||
}
|
||||
|
||||
TEST(141_merge_properties)
|
||||
{
|
||||
run_test (_this, "141", false);
|
||||
}
|
||||
|
||||
TEST(141d_merge_properties)
|
||||
{
|
||||
run_test (_this, "141", true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
source $drc_test_source
|
||||
target $drc_test_target
|
||||
|
||||
if $drc_test_deep
|
||||
deep
|
||||
end
|
||||
|
||||
l1 = input(1, 0, enable_props)
|
||||
|
||||
l1.output(1, 0)
|
||||
|
||||
l1.merged_props.output(10, 0)
|
||||
|
||||
l1d = l1.dup
|
||||
l1d.merge_props
|
||||
l1d.output(11, 0)
|
||||
|
||||
l1.merged_props(2).output(20, 0)
|
||||
|
||||
l1d = l1.dup
|
||||
l1d.merge_props(2)
|
||||
l1d.output(21, 0)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1637,12 +1637,12 @@ class DBRegion_TestClass < TestBase
|
|||
s = r.each.collect(&:to_s).join(";")
|
||||
assert_equal(s, "(10,20;10,220;110,220;110,20) props={};(0,0;0,200;100,200;100,0) props={1=>one}")
|
||||
rr = r.dup
|
||||
rr.join_properties_on_merge = false
|
||||
assert_equal(rr.join_properties_on_merge, false)
|
||||
rr.join_properties_on_merge = true
|
||||
assert_equal(rr.join_properties_on_merge, true)
|
||||
s = rr.each_merged.collect(&:to_s).join(";")
|
||||
assert_equal(s, "(10,20;10,220;110,220;110,20) props={};(0,0;0,200;100,200;100,0) props={1=>one}")
|
||||
s = r.each_merged.collect(&:to_s).join(";")
|
||||
assert_equal(s, "(0,0;0,200;10,200;10,220;110,220;110,20;100,20;100,0) props={1=>one}")
|
||||
s = r.each_merged.collect(&:to_s).join(";")
|
||||
assert_equal(s, "(10,20;10,220;110,220;110,20) props={};(0,0;0,200;100,200;100,0) props={1=>one}")
|
||||
|
||||
r = RBA::Region::new
|
||||
r.insert(RBA::BoxWithProperties::new(RBA::Box::new(0, 0, 100, 200), { 1 => "one" }))
|
||||
|
|
|
|||
Loading…
Reference in New Issue