From 9c92a9c72e94bddc3e83b53731ef15dc971fea3b Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Wed, 7 Nov 2018 00:45:29 +0100 Subject: [PATCH] Region refactoring: many unit tests are passing again. --- src/db/db/dbRegion.cc | 104 +++++++++++++++++++++++++++------- src/db/db/dbRegion.h | 33 ++++------- src/db/unit_tests/dbRegion.cc | 11 +++- 3 files changed, 106 insertions(+), 42 deletions(-) diff --git a/src/db/db/dbRegion.cc b/src/db/db/dbRegion.cc index 4ab3ab950..c63ae42a5 100644 --- a/src/db/db/dbRegion.cc +++ b/src/db/db/dbRegion.cc @@ -50,6 +50,23 @@ RegionDelegate::RegionDelegate () m_merge_min_coherence = false; } +RegionDelegate::RegionDelegate (const RegionDelegate &other) +{ + operator= (other); +} + +RegionDelegate & +RegionDelegate::operator= (const RegionDelegate &other) +{ + if (this != &other) { + m_report_progress = other.m_report_progress; + m_merged_semantics = other.m_merged_semantics; + m_strict_handling = other.m_strict_handling; + m_merge_min_coherence = other.m_merge_min_coherence; + } + return *this; +} + RegionDelegate::~RegionDelegate () { // .. nothing yet .. @@ -109,18 +126,6 @@ EmptyRegion::clone () const return new EmptyRegion (*this); } -RegionDelegate * -EmptyRegion::xor_with (const Region &other) const -{ - return other.delegate ()->clone (); -} - -RegionDelegate * -EmptyRegion::or_with (const Region &other) const -{ - return other.delegate ()->clone (); -} - RegionDelegate * EmptyRegion::add_in_place (const Region &other) { @@ -133,6 +138,24 @@ EmptyRegion::add (const Region &other) const return other.delegate ()->clone (); } +RegionDelegate * +EmptyRegion::xor_with (const Region &other) const +{ + return or_with (other); +} + +RegionDelegate * +EmptyRegion::or_with (const Region &other) const +{ + if (other.empty ()) { + return new EmptyRegion (); + } else if (! other.strict_handling ()) { + return other.delegate ()->clone (); + } else { + return other.delegate ()->merged (); + } +} + bool EmptyRegion::equals (const Region &other) const { @@ -1267,7 +1290,7 @@ AsIfFlatRegion::and_with (const Region &other) const // map AND with box to clip .. db::Box b = bbox (); - std::auto_ptr new_region (new FlatRegion ()); + std::auto_ptr new_region (new FlatRegion (false)); std::vector clipped; for (RegionIterator p (other.begin ()); ! p.at_end (); ++p) { @@ -1282,7 +1305,7 @@ AsIfFlatRegion::and_with (const Region &other) const // map AND with box to clip .. db::Box b = other.bbox (); - std::auto_ptr new_region (new FlatRegion ()); + std::auto_ptr new_region (new FlatRegion (false)); std::vector clipped; for (RegionIterator p (begin ()); ! p.at_end (); ++p) { @@ -1500,6 +1523,8 @@ AsIfFlatRegion::add (const Region &other) const if (other_flat) { std::auto_ptr new_region (new FlatRegion (*other_flat)); + new_region->set_is_merged (false); + new_region->invalidate_cache (); size_t n = new_region->raw_polygons ().size () + size (); @@ -1659,6 +1684,11 @@ FlatRegion::FlatRegion (bool is_merged) m_is_merged = is_merged; } +void FlatRegion::set_is_merged (bool m) +{ + m_is_merged = m; +} + void FlatRegion::invalidate_cache () { invalidate_bbox (); @@ -1872,6 +1902,8 @@ RegionDelegate *FlatRegion::merged () const RegionDelegate *FlatRegion::add (const Region &other) const { std::auto_ptr new_region (new FlatRegion (*this)); + new_region->invalidate_cache (); + new_region->set_is_merged (false); FlatRegion *other_flat = dynamic_cast (other.delegate ()); if (other_flat) { @@ -1899,6 +1931,7 @@ RegionDelegate *FlatRegion::add (const Region &other) const RegionDelegate *FlatRegion::add_in_place (const Region &other) { invalidate_cache (); + m_is_merged = false; FlatRegion *other_flat = dynamic_cast (other.delegate ()); if (other_flat) { @@ -1920,8 +1953,6 @@ RegionDelegate *FlatRegion::add_in_place (const Region &other) } - m_is_merged = false; - return this; } @@ -1944,9 +1975,21 @@ void FlatRegion::insert (const db::Box &box) { if (! box.empty () && box.width () > 0 && box.height () > 0) { - m_polygons.insert (db::Polygon (box)); - m_is_merged = false; - invalidate_cache (); + + if (empty ()) { + + m_polygons.insert (db::Polygon (box)); + m_is_merged = true; + update_bbox (box); + + } else { + + m_polygons.insert (db::Polygon (box)); + m_is_merged = false; + invalidate_cache (); + + } + } } @@ -2283,6 +2326,29 @@ Region::iter () const return *(i ? i : &def_iter); } +void +Region::set_delegate (RegionDelegate *delegate) +{ + if (delegate != mp_delegate) { + delete mp_delegate; + mp_delegate = delegate; + } +} + +FlatRegion * +Region::flat_region () +{ + FlatRegion *region = dynamic_cast (mp_delegate); + if (! region) { + region = new FlatRegion (); + region->RegionDelegate::operator= (*mp_delegate); + region->insert_seq (begin ()); + set_delegate (region); + } + + return region; +} + // ------------------------------------------------------------------------------------------------------------- #if 0 diff --git a/src/db/db/dbRegion.h b/src/db/db/dbRegion.h index 269532762..c93b943de 100644 --- a/src/db/db/dbRegion.h +++ b/src/db/db/dbRegion.h @@ -429,6 +429,9 @@ public: RegionDelegate (); virtual ~RegionDelegate (); + RegionDelegate (const RegionDelegate &other); + RegionDelegate &operator= (const RegionDelegate &other); + virtual RegionDelegate *clone () const = 0; void enable_progress (const std::string &progress_desc); @@ -632,7 +635,7 @@ public: virtual RegionDelegate *rounded_corners (double, double, unsigned int) const { return new EmptyRegion (); } virtual RegionDelegate *smoothed (coord_type) const { return new EmptyRegion (); } - virtual bool has_valid_polygons () const { return false; } + virtual bool has_valid_polygons () const { return true; } virtual const db::Polygon *nth (size_t) const { tl_assert (false); } virtual const db::RecursiveShapeIterator *iter () const { return 0; } @@ -928,14 +931,17 @@ public: } } - db::Shapes &raw_polygons () { return m_polygons; } - protected: virtual void merged_semantics_changed (); virtual Box compute_bbox () const; void invalidate_cache (); + void set_is_merged (bool m); private: + friend class AsIfFlatRegion; + + db::Shapes &raw_polygons () { return m_polygons; } + FlatRegion &operator= (const FlatRegion &other); bool m_is_merged; @@ -2195,25 +2201,8 @@ public: private: RegionDelegate *mp_delegate; - void set_delegate (RegionDelegate *delegate) - { - if (delegate != mp_delegate) { - delete mp_delegate; - mp_delegate = delegate; - } - } - - FlatRegion *flat_region () - { - FlatRegion *region = dynamic_cast (mp_delegate); - if (! region) { - region = new FlatRegion (); - region->insert_seq (begin ()); - set_delegate (region); - } - - return region; - } + void set_delegate (RegionDelegate *delegate); + FlatRegion *flat_region (); }; diff --git a/src/db/unit_tests/dbRegion.cc b/src/db/unit_tests/dbRegion.cc index c1eb0271b..aca7b2640 100644 --- a/src/db/unit_tests/dbRegion.cc +++ b/src/db/unit_tests/dbRegion.cc @@ -52,10 +52,19 @@ TEST(1) EXPECT_EQ (r.transformed (db::Trans (db::Vector (1, 2))).to_string (), "(1,2;1,202;101,202;101,2)"); EXPECT_EQ (r.bbox ().to_string (), "(0,0;100,200)"); EXPECT_EQ (r.empty (), false); - EXPECT_EQ (r.is_merged (), false); + EXPECT_EQ (r.is_merged (), true); EXPECT_EQ (r.is_box (), true); EXPECT_EQ (r.begin ().at_end (), false); + db::Region rr = r; + rr.insert (db::Box (db::Point (10, 10), db::Point (110, 30))); + EXPECT_EQ (rr.bbox ().to_string (), "(0,0;110,200)"); + EXPECT_EQ (rr.to_string (), "(0,0;0,200;100,200;100,0);(10,10;10,30;110,30;110,10)"); + EXPECT_EQ (rr.empty (), false); + EXPECT_EQ (rr.is_merged (), false); + EXPECT_EQ (rr.is_box (), false); + EXPECT_EQ (rr.begin ().at_end (), false); + db::Region r1 = r; db::Region r2; EXPECT_EQ (r1.to_string (), "(0,0;0,200;100,200;100,0)");