mirror of https://github.com/KLayout/klayout.git
Adding support for min_coherence toggling in OriginalLayerRegion
This commit is contained in:
parent
51f39d71e2
commit
9382e259ce
|
|
@ -142,28 +142,34 @@ OriginalLayerRegion::OriginalLayerRegion ()
|
|||
OriginalLayerRegion::OriginalLayerRegion (const OriginalLayerRegion &other)
|
||||
: AsIfFlatRegion (other),
|
||||
m_is_merged (other.m_is_merged),
|
||||
m_is_merged_min_coherence (other.m_is_merged_min_coherence),
|
||||
m_merged_polygons (other.m_merged_polygons),
|
||||
m_merged_polygons_valid (other.m_merged_polygons_valid),
|
||||
m_merged_polygons_min_coherence (other.m_merged_polygons_min_coherence),
|
||||
m_iter (other.m_iter),
|
||||
m_iter_trans (other.m_iter_trans)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
OriginalLayerRegion::OriginalLayerRegion (const RecursiveShapeIterator &si, bool is_merged)
|
||||
OriginalLayerRegion::OriginalLayerRegion (const RecursiveShapeIterator &si, bool is_merged, bool min_coh)
|
||||
: AsIfFlatRegion (), m_merged_polygons (false), m_iter (si)
|
||||
{
|
||||
init ();
|
||||
set_min_coherence (min_coh);
|
||||
|
||||
m_is_merged = is_merged;
|
||||
m_is_merged_min_coherence = min_coh;
|
||||
}
|
||||
|
||||
OriginalLayerRegion::OriginalLayerRegion (const RecursiveShapeIterator &si, const db::ICplxTrans &trans, bool merged_semantics, bool is_merged)
|
||||
OriginalLayerRegion::OriginalLayerRegion (const RecursiveShapeIterator &si, const db::ICplxTrans &trans, bool merged_semantics, bool is_merged, bool min_coh)
|
||||
: AsIfFlatRegion (), m_merged_polygons (false), m_iter (si), m_iter_trans (trans)
|
||||
{
|
||||
init ();
|
||||
set_min_coherence (min_coh);
|
||||
|
||||
m_is_merged = is_merged;
|
||||
m_is_merged_min_coherence = min_coh;
|
||||
set_merged_semantics (merged_semantics);
|
||||
}
|
||||
|
||||
|
|
@ -183,6 +189,7 @@ OriginalLayerRegion::merged_semantics_changed ()
|
|||
{
|
||||
m_merged_polygons.clear ();
|
||||
m_merged_polygons_valid = false;
|
||||
m_merged_polygons_min_coherence = false;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -190,14 +197,13 @@ OriginalLayerRegion::join_properties_on_merge_changed ()
|
|||
{
|
||||
m_merged_polygons.clear ();
|
||||
m_merged_polygons_valid = false;
|
||||
m_merged_polygons_min_coherence = false;
|
||||
}
|
||||
|
||||
void
|
||||
OriginalLayerRegion::min_coherence_changed ()
|
||||
{
|
||||
m_is_merged = false;
|
||||
m_merged_polygons.clear ();
|
||||
m_merged_polygons_valid = false;
|
||||
// merged status is tracked in separate variables and is validated on inquiry
|
||||
}
|
||||
|
||||
size_t
|
||||
|
|
@ -309,7 +315,7 @@ OriginalLayerRegion::begin () const
|
|||
RegionIteratorDelegate *
|
||||
OriginalLayerRegion::begin_merged () const
|
||||
{
|
||||
if (! merged_semantics () || m_is_merged) {
|
||||
if (! merged_semantics () || is_merged ()) {
|
||||
return begin ();
|
||||
} else {
|
||||
ensure_merged_polygons_valid ();
|
||||
|
|
@ -332,7 +338,7 @@ OriginalLayerRegion::begin_iter () const
|
|||
std::pair<db::RecursiveShapeIterator, db::ICplxTrans>
|
||||
OriginalLayerRegion::begin_merged_iter () const
|
||||
{
|
||||
if (! merged_semantics () || m_is_merged) {
|
||||
if (! merged_semantics () || is_merged ()) {
|
||||
return begin_iter ();
|
||||
} else {
|
||||
ensure_merged_polygons_valid ();
|
||||
|
|
@ -346,6 +352,33 @@ OriginalLayerRegion::begin_unmerged_iter () const
|
|||
return std::make_pair (m_iter, m_iter_trans);
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
OriginalLayerRegion::merged () const
|
||||
{
|
||||
if (! is_merged ()) {
|
||||
|
||||
if (! merged_polygons_valid ()) {
|
||||
ensure_merged_polygons_valid ();
|
||||
}
|
||||
|
||||
std::unique_ptr<FlatRegion> new_region (new FlatRegion (m_merged_polygons, true, 0, 0, min_coherence ()));
|
||||
|
||||
return new_region.release ();
|
||||
|
||||
} else {
|
||||
return clone ();
|
||||
}
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
OriginalLayerRegion::merged (bool min_coh, unsigned int min_wc, bool jp) const
|
||||
{
|
||||
std::unique_ptr<FlatRegion> new_region (new FlatRegion (true, 0, 0, min_coh));
|
||||
merge_polygons_to (new_region->raw_polygons (), min_coh, min_wc, jp);
|
||||
|
||||
return new_region.release ();
|
||||
}
|
||||
|
||||
bool
|
||||
OriginalLayerRegion::empty () const
|
||||
{
|
||||
|
|
@ -355,7 +388,13 @@ OriginalLayerRegion::empty () const
|
|||
bool
|
||||
OriginalLayerRegion::is_merged () const
|
||||
{
|
||||
return m_is_merged;
|
||||
return m_is_merged && m_is_merged_min_coherence == min_coherence ();
|
||||
}
|
||||
|
||||
bool
|
||||
OriginalLayerRegion::merged_polygons_valid () const
|
||||
{
|
||||
return m_merged_polygons_valid && m_merged_polygons_min_coherence == min_coherence ();
|
||||
}
|
||||
|
||||
const db::Polygon *
|
||||
|
|
@ -379,7 +418,7 @@ OriginalLayerRegion::has_valid_polygons () const
|
|||
bool
|
||||
OriginalLayerRegion::has_valid_merged_polygons () const
|
||||
{
|
||||
return merged_semantics () && ! m_is_merged;
|
||||
return merged_semantics () && ! is_merged ();
|
||||
}
|
||||
|
||||
const db::RecursiveShapeIterator *
|
||||
|
|
@ -394,6 +433,7 @@ OriginalLayerRegion::apply_property_translator (const db::PropertiesTranslator &
|
|||
m_iter.apply_property_translator (pt);
|
||||
|
||||
m_merged_polygons_valid = false;
|
||||
m_merged_polygons_min_coherence = false;
|
||||
m_merged_polygons.clear ();
|
||||
}
|
||||
|
||||
|
|
@ -423,7 +463,9 @@ void
|
|||
OriginalLayerRegion::init ()
|
||||
{
|
||||
m_is_merged = false;
|
||||
m_is_merged_min_coherence = false;
|
||||
m_merged_polygons_valid = false;
|
||||
m_merged_polygons_min_coherence = false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
@ -459,15 +501,22 @@ OriginalLayerRegion::insert_into (Layout *layout, db::cell_index_type into_cell,
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
OriginalLayerRegion::merged_polygons_available () const
|
||||
{
|
||||
return is_merged () || merged_polygons_valid ();
|
||||
}
|
||||
|
||||
void
|
||||
OriginalLayerRegion::ensure_merged_polygons_valid () const
|
||||
{
|
||||
if (! m_merged_polygons_valid) {
|
||||
if (! merged_polygons_valid ()) {
|
||||
|
||||
m_merged_polygons.clear ();
|
||||
merge_polygons_to (m_merged_polygons, min_coherence (), 0, join_properties_on_merge ());
|
||||
|
||||
m_merged_polygons_valid = true;
|
||||
m_merged_polygons_min_coherence = min_coherence ();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ class DB_PUBLIC OriginalLayerRegion
|
|||
public:
|
||||
OriginalLayerRegion ();
|
||||
OriginalLayerRegion (const OriginalLayerRegion &other);
|
||||
OriginalLayerRegion (const RecursiveShapeIterator &si, bool is_merged = false);
|
||||
OriginalLayerRegion (const RecursiveShapeIterator &si, const db::ICplxTrans &trans, bool merged_semantics, bool is_merged = false);
|
||||
OriginalLayerRegion (const RecursiveShapeIterator &si, bool is_merged = false, bool min_coh = false);
|
||||
OriginalLayerRegion (const RecursiveShapeIterator &si, const db::ICplxTrans &trans, bool merged_semantics, bool is_merged = false, bool min_coh = false);
|
||||
virtual ~OriginalLayerRegion ();
|
||||
|
||||
RegionDelegate *clone () const;
|
||||
|
|
@ -57,6 +57,11 @@ public:
|
|||
virtual std::pair<db::RecursiveShapeIterator, db::ICplxTrans> begin_merged_iter () const;
|
||||
virtual std::pair<db::RecursiveShapeIterator, db::ICplxTrans> begin_unmerged_iter () const;
|
||||
|
||||
virtual RegionDelegate *merged () const;
|
||||
virtual RegionDelegate *merged (bool min_coherence, unsigned int min_wc, bool join_properties_on_merge) const;
|
||||
|
||||
bool merged_polygons_available () const;
|
||||
|
||||
virtual bool empty () const;
|
||||
|
||||
virtual bool is_merged () const;
|
||||
|
|
@ -85,13 +90,16 @@ private:
|
|||
OriginalLayerRegion &operator= (const OriginalLayerRegion &other);
|
||||
|
||||
bool m_is_merged;
|
||||
mutable bool m_is_merged_min_coherence;
|
||||
mutable db::Shapes m_merged_polygons;
|
||||
mutable bool m_merged_polygons_valid;
|
||||
mutable bool m_merged_polygons_min_coherence;
|
||||
mutable db::RecursiveShapeIterator m_iter;
|
||||
db::ICplxTrans m_iter_trans;
|
||||
|
||||
void init ();
|
||||
void ensure_merged_polygons_valid () const;
|
||||
bool merged_polygons_valid () const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2158,6 +2158,118 @@ TEST(45_min_coherence_and_merge)
|
|||
EXPECT_EQ (r2.to_string (), "(0,0;0,2000;1000,2000;1000,3000;9000,3000;9000,10000;10000,10000;10000,2000;1000,2000;1000,0)");
|
||||
}
|
||||
|
||||
TEST(46_min_coherence_and_merge_from_original)
|
||||
{
|
||||
db::Layout ly;
|
||||
|
||||
auto &top = ly.cell (ly.add_cell ("TOP"));
|
||||
unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0));
|
||||
|
||||
top.shapes (l1).insert (db::Box (0, 0, 1000, 2000));
|
||||
top.shapes (l1).insert (db::Box (1000, 2000, 10000, 3000));
|
||||
top.shapes (l1).insert (db::Box (9000, 3000, 10000, 10000));
|
||||
|
||||
db::Region r1 (db::RecursiveShapeIterator (ly, top, l1));
|
||||
|
||||
EXPECT_EQ (r1.min_coherence (), false);
|
||||
EXPECT_EQ (r1.is_merged (), false);
|
||||
EXPECT_EQ (dynamic_cast<const db::OriginalLayerRegion *> (r1.delegate ())->merged_polygons_available (), false);
|
||||
EXPECT_EQ (r1.to_string (), "(0,0;0,2000;1000,2000;1000,0);(1000,2000;1000,3000;10000,3000;10000,2000);(9000,3000;9000,10000;10000,10000;10000,3000)");
|
||||
|
||||
// forces merged status
|
||||
r1.sized (1);
|
||||
|
||||
EXPECT_EQ (r1.min_coherence (), false);
|
||||
EXPECT_EQ (r1.is_merged (), false);
|
||||
EXPECT_EQ (dynamic_cast<const db::OriginalLayerRegion *> (r1.delegate ())->merged_polygons_available (), true);
|
||||
|
||||
db::Region r2 = r1.merged ();
|
||||
EXPECT_EQ (r2.to_string (), "(0,0;0,2000;1000,2000;1000,3000;9000,3000;9000,10000;10000,10000;10000,2000;1000,2000;1000,0)");
|
||||
|
||||
EXPECT_EQ (r2.min_coherence (), false);
|
||||
|
||||
EXPECT_EQ (r1.min_coherence (), false);
|
||||
EXPECT_EQ (r1.is_merged (), false);
|
||||
EXPECT_EQ (dynamic_cast<const db::OriginalLayerRegion *> (r1.delegate ())->merged_polygons_available (), true);
|
||||
|
||||
r1.set_min_coherence (true);
|
||||
|
||||
// valid_merged_polygons is invalidated
|
||||
EXPECT_EQ (r1.min_coherence (), true);
|
||||
EXPECT_EQ (r1.is_merged (), false);
|
||||
EXPECT_EQ (dynamic_cast<const db::OriginalLayerRegion *> (r1.delegate ())->merged_polygons_available (), false);
|
||||
|
||||
r1.set_min_coherence (false);
|
||||
|
||||
// setting min_coherence to false will bring the validation back
|
||||
EXPECT_EQ (r1.min_coherence (), false);
|
||||
EXPECT_EQ (r1.is_merged (), false);
|
||||
EXPECT_EQ (dynamic_cast<const db::OriginalLayerRegion *> (r1.delegate ())->merged_polygons_available (), true);
|
||||
|
||||
r1.set_min_coherence (true);
|
||||
|
||||
// valid_merged_polygons is invalidated again by setting min_coherence to true
|
||||
EXPECT_EQ (r1.min_coherence (), true);
|
||||
EXPECT_EQ (r1.is_merged (), false);
|
||||
EXPECT_EQ (dynamic_cast<const db::OriginalLayerRegion *> (r1.delegate ())->merged_polygons_available (), false);
|
||||
|
||||
// inserting a box into the region will reset the merged valid flag and not bring it back by resetting min_coherence
|
||||
db::Region r3 = r1;
|
||||
r3.insert (db::Box (0, 0, 100, 100));
|
||||
EXPECT_EQ (r3.min_coherence (), true);
|
||||
r3.set_min_coherence (false);
|
||||
EXPECT_EQ (r3.is_merged (), false);
|
||||
EXPECT_EQ (dynamic_cast<const db::FlatRegion *> (r3.delegate ())->merged_polygons_available (), false);
|
||||
|
||||
// creates a intrinsically merged copy and tests if the min_coherence
|
||||
// flag is inherited
|
||||
r3 = r1.merged ();
|
||||
EXPECT_EQ (r3.to_string (), "(0,0;0,2000;1000,2000;1000,0);(1000,2000;1000,3000;9000,3000;9000,10000;10000,10000;10000,2000)");
|
||||
EXPECT_EQ (r3.is_merged (), true);
|
||||
EXPECT_EQ (r3.min_coherence (), true);
|
||||
|
||||
// merged polygons are validated against min_coherence = true during r1.merged() before, so
|
||||
// resetting min_coherence to false will invalidat them
|
||||
r1.set_min_coherence (false);
|
||||
EXPECT_EQ (r1.min_coherence (), false);
|
||||
EXPECT_EQ (r1.is_merged (), false);
|
||||
EXPECT_EQ (dynamic_cast<const db::OriginalLayerRegion *> (r1.delegate ())->merged_polygons_available (), false);
|
||||
|
||||
// creates a intrinsically merged copy and tests if the min_coherence
|
||||
// flag is inherited
|
||||
r3 = r1.merged ();
|
||||
EXPECT_EQ (r3.to_string (), "(0,0;0,2000;1000,2000;1000,3000;9000,3000;9000,10000;10000,10000;10000,2000;1000,2000;1000,0)");
|
||||
EXPECT_EQ (r3.is_merged (), true);
|
||||
EXPECT_EQ (r3.min_coherence (), false);
|
||||
|
||||
// r2 is an intrinsically merged region (with min coherence false)
|
||||
EXPECT_EQ (r2.min_coherence (), false);
|
||||
EXPECT_EQ (r2.is_merged (), true);
|
||||
EXPECT_EQ (r2.to_string (), "(0,0;0,2000;1000,2000;1000,3000;9000,3000;9000,10000;10000,10000;10000,2000;1000,2000;1000,0)");
|
||||
|
||||
// after changing min_coherence, the merged status is no longer true
|
||||
r2.set_min_coherence (true);
|
||||
EXPECT_EQ (r2.min_coherence (), true);
|
||||
EXPECT_EQ (r2.is_merged (), false);
|
||||
EXPECT_EQ (r2.to_string (), "(0,0;0,2000;1000,2000;1000,3000;9000,3000;9000,10000;10000,10000;10000,2000;1000,2000;1000,0)");
|
||||
|
||||
// read-only experiments with r2
|
||||
|
||||
// inserting a box into the region will reset the merged state
|
||||
// and not bring it back by resetting min_coherence
|
||||
r3 = r2;
|
||||
r3.insert (db::Box (0, 0, 100, 100));
|
||||
r3.set_min_coherence (false);
|
||||
EXPECT_EQ (r3.is_merged (), false);
|
||||
EXPECT_EQ (r3.to_string (), "(0,0;0,2000;1000,2000;1000,3000;9000,3000;9000,10000;10000,10000;10000,2000;1000,2000;1000,0);(0,0;0,100;100,100;100,0)");
|
||||
|
||||
// r2 merged state it can be restored by resetting min_coherence to false
|
||||
r2.set_min_coherence (false);
|
||||
EXPECT_EQ (r2.min_coherence (), false);
|
||||
EXPECT_EQ (r2.is_merged (), true);
|
||||
EXPECT_EQ (r2.to_string (), "(0,0;0,2000;1000,2000;1000,3000;9000,3000;9000,10000;10000,10000;10000,2000;1000,2000;1000,0)");
|
||||
}
|
||||
|
||||
TEST(100_Issue1275)
|
||||
{
|
||||
db::Point pts[] = {
|
||||
|
|
|
|||
Loading…
Reference in New Issue