diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index a13e49823..e6cd117c1 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -764,7 +764,7 @@ AsIfFlatRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const db::Box b = bbox ().enlarged (db::Vector (dx, dy)); return region_from_box (b); - } else if (! merged_semantics ()) { + } else if (! merged_semantics () || is_merged ()) { // Generic case std::auto_ptr new_region (new FlatRegion (false /*output isn't merged*/)); @@ -801,7 +801,7 @@ AsIfFlatRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const db::ShapeGenerator pc (new_region->raw_polygons (), true /*clear*/); db::PolygonGenerator pg2 (pc, false /*don't resolve holes*/, true /*min. coherence*/); db::SizingPolygonFilter siz (pg2, dx, dy, mode); - db::PolygonGenerator pg (siz, false /*don't resolve holes*/, false /*min. coherence*/); + db::PolygonGenerator pg (siz, false /*don't resolve holes*/, min_coherence () /*min. coherence*/); db::BooleanOp op (db::BooleanOp::Or); ep.process (pg, op); diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 0ee8b7195..572e7a6ba 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -160,6 +160,11 @@ void DeepRegion::merged_semantics_changed () // .. nothing yet .. } +void DeepRegion::min_coherence_changed () +{ + set_is_merged (false); +} + RegionIteratorDelegate * DeepRegion::begin () const { diff --git a/src/db/db/dbDeepRegion.h b/src/db/db/dbDeepRegion.h index 6ede2cee0..ce554ffb9 100644 --- a/src/db/db/dbDeepRegion.h +++ b/src/db/db/dbDeepRegion.h @@ -220,6 +220,7 @@ public: protected: virtual void merged_semantics_changed (); + virtual void min_coherence_changed (); void set_is_merged (bool f); private: diff --git a/src/db/db/dbFlatRegion.cc b/src/db/db/dbFlatRegion.cc index 1ab7ebaa9..3df87bf77 100644 --- a/src/db/db/dbFlatRegion.cc +++ b/src/db/db/dbFlatRegion.cc @@ -94,6 +94,13 @@ void FlatRegion::merged_semantics_changed () m_merged_polygons_valid = false; } +void FlatRegion::min_coherence_changed () +{ + m_is_merged = false; + m_merged_polygons.clear (); + m_merged_polygons_valid = false; +} + void FlatRegion::reserve (size_t n) { m_polygons.reserve (db::Polygon::tag (), n); diff --git a/src/db/db/dbFlatRegion.h b/src/db/db/dbFlatRegion.h index 5fe5e50ec..5f7d2d2cd 100644 --- a/src/db/db/dbFlatRegion.h +++ b/src/db/db/dbFlatRegion.h @@ -180,6 +180,7 @@ public: protected: virtual void merged_semantics_changed (); + virtual void min_coherence_changed (); virtual Box compute_bbox () const; void invalidate_cache (); void set_is_merged (bool m); diff --git a/src/db/db/dbOriginalLayerRegion.cc b/src/db/db/dbOriginalLayerRegion.cc index 73f9aa83f..28a79033f 100644 --- a/src/db/db/dbOriginalLayerRegion.cc +++ b/src/db/db/dbOriginalLayerRegion.cc @@ -151,6 +151,14 @@ OriginalLayerRegion::merged_semantics_changed () m_merged_polygons_valid = false; } +void +OriginalLayerRegion::min_coherence_changed () +{ + m_is_merged = false; + m_merged_polygons.clear (); + m_merged_polygons_valid = false; +} + RegionIteratorDelegate * OriginalLayerRegion::begin () const { diff --git a/src/db/db/dbOriginalLayerRegion.h b/src/db/db/dbOriginalLayerRegion.h index b99a651ec..23ce7004b 100644 --- a/src/db/db/dbOriginalLayerRegion.h +++ b/src/db/db/dbOriginalLayerRegion.h @@ -72,6 +72,7 @@ public: protected: virtual void merged_semantics_changed (); + virtual void min_coherence_changed (); private: OriginalLayerRegion &operator= (const OriginalLayerRegion &other); diff --git a/src/db/db/dbRegionDelegate.cc b/src/db/db/dbRegionDelegate.cc index 0e6328ce7..2ce675465 100644 --- a/src/db/db/dbRegionDelegate.cc +++ b/src/db/db/dbRegionDelegate.cc @@ -78,7 +78,10 @@ void RegionDelegate::set_base_verbosity (int vb) void RegionDelegate::set_min_coherence (bool f) { - m_merge_min_coherence = f; + if (f != m_merge_min_coherence) { + m_merge_min_coherence = f; + min_coherence_changed (); + } } void RegionDelegate::set_merged_semantics (bool f) diff --git a/src/db/db/dbRegionDelegate.h b/src/db/db/dbRegionDelegate.h index f5eb945d7..8fe79edb9 100644 --- a/src/db/db/dbRegionDelegate.h +++ b/src/db/db/dbRegionDelegate.h @@ -319,6 +319,7 @@ protected: } virtual void merged_semantics_changed () { } + virtual void min_coherence_changed () { } private: bool m_merged_semantics; diff --git a/src/db/unit_tests/dbDeepRegionTests.cc b/src/db/unit_tests/dbDeepRegionTests.cc index a23807ecb..5bdb28766 100644 --- a/src/db/unit_tests/dbDeepRegionTests.cc +++ b/src/db/unit_tests/dbDeepRegionTests.cc @@ -1406,3 +1406,30 @@ TEST(101_DeepFlatCollaboration) db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au101.gds"); } +TEST(issue_277) +{ + db::Layout ly; + db::cell_index_type top_cell_index = ly.add_cell ("TOP"); + db::Cell &top_cell = ly.cell (top_cell_index); + unsigned int l1 = ly.insert_layer (); + + db::Shapes &s = top_cell.shapes (l1); + s.insert (db::Box (0, 0, 400, 400)); + s.insert (db::Box (400, 400, 800, 800)); + + + db::DeepShapeStore dss; + + db::Region r (db::RecursiveShapeIterator (ly, top_cell, l1), dss); + + EXPECT_EQ (r.sized (1).merged (false, 1).to_string (), ""); + + r.set_min_coherence (true); + EXPECT_EQ (r.sized (1).merged (false, 1).to_string (), "(399,399;399,401;401,401;401,399)"); + + r.merge (); + EXPECT_EQ (r.sized (1).merged (false, 1).to_string (), "(399,399;399,401;401,401;401,399)"); + + r.set_min_coherence (false); // needs to merge again + EXPECT_EQ (r.sized (1).merged (false, 1).to_string (), ""); +} diff --git a/src/db/unit_tests/dbRegion.cc b/src/db/unit_tests/dbRegion.cc index 6fb883ae1..31d939d4a 100644 --- a/src/db/unit_tests/dbRegion.cc +++ b/src/db/unit_tests/dbRegion.cc @@ -1397,3 +1397,21 @@ TEST(issue_228) EXPECT_EQ (r.selected_interacting (rr).to_string (), r.to_string ()); EXPECT_EQ (rr.selected_interacting (r).to_string (), rr.to_string ()); } + +TEST(issue_277) +{ + db::Region r; + r.insert (db::Box (0, 0, 400, 400)); + r.insert (db::Box (400, 400, 800, 800)); + + EXPECT_EQ (r.sized (1).merged (false, 1).to_string (), ""); + + r.set_min_coherence (true); + EXPECT_EQ (r.sized (1).merged (false, 1).to_string (), "(399,399;399,401;401,401;401,399)"); + + r.merge (); + EXPECT_EQ (r.sized (1).merged (false, 1).to_string (), "(399,399;399,401;401,401;401,399)"); + + r.set_min_coherence (false); // needs to merge again + EXPECT_EQ (r.sized (1).merged (false, 1).to_string (), ""); +}