From b701390e6afc38fdfbf47ba89ba7e27714ffcc2c Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 3 Dec 2023 21:50:03 +0100 Subject: [PATCH] Enabling cheats for edges and (implicit) polygon merges DRC "cheats" have not been effective on "size" for example. Also they have not been effective at all for edges. --- src/db/db/dbDeepEdges.cc | 43 +++++--- src/db/db/dbDeepEdges.h | 5 +- src/db/db/dbDeepRegion.cc | 12 ++- src/db/db/dbDeepRegion.h | 1 + src/db/db/dbDeepShapeStore.cc | 43 ++++++-- src/db/db/dbDeepShapeStore.h | 17 ++- src/db/unit_tests/dbDeepEdgesTests.cc | 138 +++++++++++++++++++++++++ src/db/unit_tests/dbDeepRegionTests.cc | 95 +++++++++++++++++ 8 files changed, 324 insertions(+), 30 deletions(-) diff --git a/src/db/db/dbDeepEdges.cc b/src/db/db/dbDeepEdges.cc index 12b9a1774..d81032b0b 100644 --- a/src/db/db/dbDeepEdges.cc +++ b/src/db/db/dbDeepEdges.cc @@ -176,6 +176,7 @@ DeepEdges::~DeepEdges () DeepEdges::DeepEdges (const DeepEdges &other) : MutableEdges (other), DeepShapeCollectionDelegateBase (other), m_merged_edges_valid (other.m_merged_edges_valid), + m_merged_edges_boc_hash (other.m_merged_edges_boc_hash), m_is_merged (other.m_is_merged) { if (m_merged_edges_valid) { @@ -192,6 +193,7 @@ DeepEdges::operator= (const DeepEdges &other) DeepShapeCollectionDelegateBase::operator= (other); m_merged_edges_valid = other.m_merged_edges_valid; + m_merged_edges_boc_hash = other.m_merged_edges_boc_hash; m_is_merged = other.m_is_merged; if (m_merged_edges_valid) { m_merged_edges = other.m_merged_edges.copy (); @@ -205,6 +207,7 @@ DeepEdges::operator= (const DeepEdges &other) void DeepEdges::init () { m_merged_edges_valid = false; + m_merged_edges_boc_hash = 0; m_merged_edges = db::DeepLayer (); m_is_merged = false; } @@ -458,6 +461,7 @@ void DeepEdges::apply_property_translator (const db::PropertiesTranslator &pt) DeepShapeCollectionDelegateBase::apply_property_translator (pt); m_merged_edges_valid = false; + m_merged_edges_boc_hash = 0; m_merged_edges = db::DeepLayer (); } @@ -637,10 +641,16 @@ DeepEdges::merged_deep_layer () const } } +bool +DeepEdges::merged_edges_available () const +{ + return m_is_merged || (m_merged_edges_valid && m_merged_edges_boc_hash == deep_layer ().breakout_cells_hash ()); +} + void DeepEdges::ensure_merged_edges_valid () const { - if (! m_merged_edges_valid) { + if (! m_merged_edges_valid || (! m_is_merged && m_merged_edges_boc_hash != deep_layer ().breakout_cells_hash ())) { if (m_is_merged) { @@ -659,7 +669,7 @@ DeepEdges::ensure_merged_edges_valid () const db::Connectivity conn; conn.connect (deep_layer ()); hc.set_base_verbosity (base_verbosity() + 10); - hc.build (layout, deep_layer ().initial_cell (), conn); + hc.build (layout, deep_layer ().initial_cell (), conn, 0, deep_layer ().breakout_cells ()); // collect the clusters and merge them into larger edges // NOTE: using the ClusterMerger we merge bottom-up forming bigger and bigger polygons. This is @@ -683,6 +693,7 @@ DeepEdges::ensure_merged_edges_valid () const } m_merged_edges_valid = true; + m_merged_edges_boc_hash = deep_layer ().breakout_cells_hash (); } } @@ -692,6 +703,7 @@ DeepEdges::set_is_merged (bool f) { m_is_merged = f; m_merged_edges_valid = false; + m_merged_edges_boc_hash = 0; m_merged_edges = db::DeepLayer (); } @@ -909,7 +921,7 @@ DeepEdges::and_or_not_with (const DeepEdges *other, EdgeBoolOp op) const db::EdgeBoolAndOrNotLocalOperation local_op (op); - db::local_processor proc (const_cast (&deep_layer ().layout ()), const_cast (&deep_layer ().initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell ()); + db::local_processor proc (const_cast (&deep_layer ().layout ()), const_cast (&deep_layer ().initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell (), deep_layer ().breakout_cells (), other->deep_layer ().breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (deep_layer ().store ()->threads ()); proc.set_area_ratio (deep_layer ().store ()->max_area_ratio ()); @@ -936,7 +948,7 @@ DeepEdges::edge_region_op (const DeepRegion *other, EdgePolygonOp::mode_t mode, db::EdgeToPolygonLocalOperation op (mode, include_borders); - db::local_processor proc (const_cast (&deep_layer ().layout ()), const_cast (&deep_layer ().initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell ()); + db::local_processor proc (const_cast (&deep_layer ().layout ()), const_cast (&deep_layer ().initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell (), deep_layer ().breakout_cells (), other->deep_layer ().breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (deep_layer ().store ()->threads ()); proc.set_area_ratio (deep_layer ().store ()->max_area_ratio ()); @@ -1253,7 +1265,6 @@ RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_t std::unique_ptr res (new db::DeepRegion (edges.derived ())); db::Layout &layout = const_cast (edges.layout ()); - db::Cell &top_cell = const_cast (edges.initial_cell ()); // TODO: there is a special case when we'd need a MagnificationAndOrientationReducer: // dots formally don't have an orientation, hence the interpretation is x and y. @@ -1271,7 +1282,7 @@ RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_t db::Connectivity conn (db::Connectivity::EdgesConnectByPoints); conn.connect (edges); hc.set_base_verbosity (base_verbosity () + 10); - hc.build (layout, edges.initial_cell (), conn); + hc.build (layout, edges.initial_cell (), conn, 0, edges.breakout_cells ()); // TODO: iterate only over the called cells? for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) { @@ -1714,7 +1725,7 @@ DeepEdges::selected_interacting_generic (const Region &other, EdgeInteractionMod db::Edge2PolygonInteractingLocalOperation op (mode, inverse ? db::Edge2PolygonInteractingLocalOperation::Inverse : db::Edge2PolygonInteractingLocalOperation::Normal); - db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ()); + db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), edges.breakout_cells (), other_deep->deep_layer ().breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (edges.store ()->threads ()); @@ -1746,7 +1757,7 @@ DeepEdges::selected_interacting_pair_generic (const Region &other, EdgeInteracti db::Edge2PolygonInteractingLocalOperation op (mode, db::Edge2PolygonInteractingLocalOperation::Both); - db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ()); + db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), edges.breakout_cells (), other_deep->deep_layer ().breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (edges.store ()->threads ()); @@ -1772,7 +1783,7 @@ DeepEdges::selected_interacting_generic (const Edges &other, EdgeInteractionMode db::Edge2EdgeInteractingLocalOperation op (mode, inverse ? db::Edge2EdgeInteractingLocalOperation::Inverse : db::Edge2EdgeInteractingLocalOperation::Normal); - db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ()); + db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), edges.breakout_cells (), other_deep->deep_layer ().breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (edges.store ()->threads ()); @@ -1804,7 +1815,7 @@ DeepEdges::selected_interacting_pair_generic (const Edges &other, EdgeInteractio db::Edge2EdgeInteractingLocalOperation op (mode, db::Edge2EdgeInteractingLocalOperation::Both); - db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ()); + db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), edges.breakout_cells (), other_deep->deep_layer ().breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (edges.store ()->threads ()); @@ -1830,7 +1841,7 @@ RegionDelegate *DeepEdges::pull_generic (const Region &other) const db::Edge2PolygonPullLocalOperation op; - db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell ()); + db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell (), edges.breakout_cells (), other_polygons.breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (edges.store ()->threads ()); @@ -1856,7 +1867,7 @@ EdgesDelegate *DeepEdges::pull_generic (const Edges &other) const db::Edge2EdgePullLocalOperation op; - db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_edges.layout (), &other_edges.initial_cell ()); + db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_edges.layout (), &other_edges.initial_cell (), edges.breakout_cells (), other_edges.breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (edges.store ()->threads ()); @@ -1885,7 +1896,7 @@ EdgesDelegate *DeepEdges::in (const Edges &other, bool invert) const db::ContainedEdgesLocalOperation op (invert ? Negative : Positive); - db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ()); + db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), edges.breakout_cells (), other_deep->deep_layer ().breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (edges.store ()->threads ()); @@ -1916,7 +1927,7 @@ std::pair DeepEdges::in_and_out (const Edges & db::ContainedEdgesLocalOperation op (PositiveAndNegative); - db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ()); + db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), edges.breakout_cells (), other_deep->deep_layer ().breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (edges.store ()->threads ()); @@ -2049,7 +2060,9 @@ DeepEdges::run_check (db::edge_relation_type rel, const Edges *other, db::Coord db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), other_deep ? &other_deep->deep_layer ().layout () : const_cast (&edges.layout ()), - other_deep ? &other_deep->deep_layer ().initial_cell () : const_cast (&edges.initial_cell ())); + other_deep ? &other_deep->deep_layer ().initial_cell () : const_cast (&edges.initial_cell ()), + edges.breakout_cells (), + other_deep ? other_deep->deep_layer ().breakout_cells () : 0); proc.set_base_verbosity (base_verbosity ()); proc.set_threads (edges.store ()->threads ()); diff --git a/src/db/db/dbDeepEdges.h b/src/db/db/dbDeepEdges.h index 78fb04935..bdd7ea947 100644 --- a/src/db/db/dbDeepEdges.h +++ b/src/db/db/dbDeepEdges.h @@ -170,6 +170,9 @@ public: void set_is_merged (bool f); + bool merged_edges_available () const; + const DeepLayer &merged_deep_layer () const; + protected: virtual void merged_semantics_changed (); @@ -180,11 +183,11 @@ private: mutable DeepLayer m_merged_edges; mutable bool m_merged_edges_valid; + mutable size_t m_merged_edges_boc_hash; bool m_is_merged; void init (); void ensure_merged_edges_valid () const; - const DeepLayer &merged_deep_layer () const; DeepLayer and_or_not_with(const DeepEdges *other, EdgeBoolOp op) const; std::pair edge_region_op (const DeepRegion *other, EdgePolygonOp::mode_t op, bool include_borders) const; EdgePairsDelegate *run_check (db::edge_relation_type rel, const Edges *other, db::Coord d, const db::EdgesCheckOptions &options) const; diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index b6e04023a..11780bfd6 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -179,6 +179,7 @@ DeepRegion::~DeepRegion () DeepRegion::DeepRegion (const DeepRegion &other) : MutableRegion (other), DeepShapeCollectionDelegateBase (other), m_merged_polygons_valid (other.m_merged_polygons_valid), + m_merged_polygons_boc_hash (other.m_merged_polygons_boc_hash), m_is_merged (other.m_is_merged) { if (m_merged_polygons_valid) { @@ -195,6 +196,7 @@ DeepRegion::operator= (const DeepRegion &other) DeepShapeCollectionDelegateBase::operator= (other); m_merged_polygons_valid = other.m_merged_polygons_valid; + m_merged_polygons_boc_hash = other.m_merged_polygons_boc_hash; m_is_merged = other.m_is_merged; if (m_merged_polygons_valid) { m_merged_polygons = other.m_merged_polygons.copy (); @@ -208,6 +210,7 @@ DeepRegion::operator= (const DeepRegion &other) void DeepRegion::init () { m_merged_polygons_valid = false; + m_merged_polygons_boc_hash = 0; m_merged_polygons = db::DeepLayer (); m_is_merged = false; } @@ -484,6 +487,7 @@ void DeepRegion::apply_property_translator (const db::PropertiesTranslator &pt) DeepShapeCollectionDelegateBase::apply_property_translator (pt); m_merged_polygons_valid = false; + m_merged_polygons_boc_hash = 0; m_merged_polygons = db::DeepLayer (); } @@ -683,13 +687,13 @@ DeepRegion::merged_deep_layer () const bool DeepRegion::merged_polygons_available () const { - return m_is_merged || m_merged_polygons_valid; + return m_is_merged || (m_merged_polygons_valid && m_merged_polygons_boc_hash == deep_layer ().breakout_cells_hash ()); } void DeepRegion::ensure_merged_polygons_valid () const { - if (! m_merged_polygons_valid) { + if (! m_merged_polygons_valid || (! m_is_merged && m_merged_polygons_boc_hash != deep_layer ().breakout_cells_hash ())) { if (m_is_merged) { @@ -708,7 +712,7 @@ DeepRegion::ensure_merged_polygons_valid () const db::Connectivity conn; conn.connect (deep_layer ()); hc.set_base_verbosity (base_verbosity () + 10); - hc.build (layout, deep_layer ().initial_cell (), conn, 0, 0, true /*separate_attributes*/); + hc.build (layout, deep_layer ().initial_cell (), conn, 0, deep_layer ().breakout_cells (), true /*separate_attributes*/); // collect the clusters and merge them into big polygons // NOTE: using the ClusterMerger we merge bottom-up forming bigger and bigger polygons. This is @@ -732,6 +736,7 @@ DeepRegion::ensure_merged_polygons_valid () const } m_merged_polygons_valid = true; + m_merged_polygons_boc_hash = deep_layer ().breakout_cells_hash (); } } @@ -741,6 +746,7 @@ DeepRegion::set_is_merged (bool f) { m_is_merged = f; m_merged_polygons_valid = false; + m_merged_polygons_boc_hash = 0; m_merged_polygons = db::DeepLayer (); } diff --git a/src/db/db/dbDeepRegion.h b/src/db/db/dbDeepRegion.h index df40fec49..cc05259b7 100644 --- a/src/db/db/dbDeepRegion.h +++ b/src/db/db/dbDeepRegion.h @@ -173,6 +173,7 @@ private: mutable DeepLayer m_merged_polygons; mutable bool m_merged_polygons_valid; + mutable size_t m_merged_polygons_boc_hash; bool m_is_merged; void init (); diff --git a/src/db/db/dbDeepShapeStore.cc b/src/db/db/dbDeepShapeStore.cc index 81ff9c327..70005e136 100644 --- a/src/db/db/dbDeepShapeStore.cc +++ b/src/db/db/dbDeepShapeStore.cc @@ -184,6 +184,12 @@ DeepLayer::breakout_cells () const return store ()->breakout_cells (layout_index ()); } +size_t +DeepLayer::breakout_cells_hash () const +{ + return store ()->breakout_cells_hash (layout_index ()); +} + void DeepLayer::insert_into (db::Layout *into_layout, db::cell_index_type into_cell, unsigned int into_layer) const { @@ -409,36 +415,51 @@ DeepShapeStoreState::text_property_name () const const std::set * DeepShapeStoreState::breakout_cells (unsigned int layout_index) const { - const std::set &boc = (const_cast (this))->ensure_breakout_cells (layout_index); - if (boc.empty ()) { + const std::pair, size_t> &boc = (const_cast (this))->ensure_breakout_cells (layout_index); + if (boc.first.empty ()) { return 0; } else { - return &boc; + return &boc.first; } } +size_t +DeepShapeStoreState::breakout_cells_hash (unsigned int layout_index) const +{ + const std::pair, size_t> &boc = (const_cast (this))->ensure_breakout_cells (layout_index); + return boc.second; +} + void DeepShapeStoreState::clear_breakout_cells (unsigned int layout_index) { - ensure_breakout_cells (layout_index).clear (); + std::pair, size_t> &boc = ensure_breakout_cells (layout_index); + boc.first.clear (); + boc.second = std::hash >() (boc.first); } void -DeepShapeStoreState::set_breakout_cells (unsigned int layout_index, const std::set &boc) +DeepShapeStoreState::set_breakout_cells (unsigned int layout_index, const std::set &boc_in) { - ensure_breakout_cells (layout_index) = boc; + std::pair, size_t> &boc = ensure_breakout_cells (layout_index); + boc.first = boc_in; + boc.second = std::hash >() (boc.first); } void DeepShapeStoreState::add_breakout_cell (unsigned int layout_index, db::cell_index_type ci) { - ensure_breakout_cells (layout_index).insert (ci); + std::pair, size_t> &boc = ensure_breakout_cells (layout_index); + boc.first.insert (ci); + boc.second = std::hash >() (boc.first); } void DeepShapeStoreState::add_breakout_cells (unsigned int layout_index, const std::set &cc) { - ensure_breakout_cells (layout_index).insert (cc.begin (), cc.end ()); + std::pair, size_t> &boc = ensure_breakout_cells (layout_index); + boc.first.insert (cc.begin (), cc.end ()); + boc.second = std::hash >() (boc.first); } void @@ -726,6 +747,12 @@ DeepShapeStore::breakout_cells (unsigned int layout_index) const return m_state.breakout_cells (layout_index); } +size_t +DeepShapeStore::breakout_cells_hash (unsigned int layout_index) const +{ + return m_state.breakout_cells_hash (layout_index); +} + void DeepShapeStore::clear_breakout_cells (unsigned int layout_index) { diff --git a/src/db/db/dbDeepShapeStore.h b/src/db/db/dbDeepShapeStore.h index 1e6e0aaaa..ab2f2336b 100644 --- a/src/db/db/dbDeepShapeStore.h +++ b/src/db/db/dbDeepShapeStore.h @@ -165,6 +165,11 @@ public: */ const std::set *breakout_cells () const; + /** + * @brief Gets a hash value representing the breakout cells + */ + size_t breakout_cells_hash () const; + /** * @brief Inserts the layer into the given layout, starting from the given cell and into the given layer */ @@ -251,6 +256,7 @@ public: bool reject_odd_polygons () const; const std::set *breakout_cells (unsigned int layout_index) const; + size_t breakout_cells_hash (unsigned int layout_index) const; void clear_breakout_cells (unsigned int layout_index); void set_breakout_cells (unsigned int layout_index, const std::set &boc); void add_breakout_cell (unsigned int layout_index, db::cell_index_type ci); @@ -265,14 +271,14 @@ private: size_t m_max_vertex_count; bool m_reject_odd_polygons; tl::Variant m_text_property_name; - std::vector > m_breakout_cells; + std::vector, size_t> > m_breakout_cells; int m_text_enlargement; bool m_subcircuit_hierarchy_for_nets; - std::set &ensure_breakout_cells (unsigned int layout_index) + std::pair, size_t> &ensure_breakout_cells (unsigned int layout_index) { if (m_breakout_cells.size () <= size_t (layout_index)) { - m_breakout_cells.resize (layout_index + 1, std::set ()); + m_breakout_cells.resize (layout_index + 1, std::pair, size_t> ()); } return m_breakout_cells [layout_index]; } @@ -782,6 +788,11 @@ public: */ const std::set *breakout_cells (unsigned int layout_index) const; + /** + * @brief Gets a hash value representing the breakout cells + */ + size_t breakout_cells_hash (unsigned int layout_index) const; + /** * @brief Clears the breakout cell list for a given layout */ diff --git a/src/db/unit_tests/dbDeepEdgesTests.cc b/src/db/unit_tests/dbDeepEdgesTests.cc index fae54490e..783ceb326 100644 --- a/src/db/unit_tests/dbDeepEdgesTests.cc +++ b/src/db/unit_tests/dbDeepEdgesTests.cc @@ -29,6 +29,7 @@ #include "dbEdgesUtils.h" #include "dbDeepShapeStore.h" #include "dbCellGraphUtils.h" +#include "dbDeepEdges.h" #include "tlUnitTest.h" #include "tlStream.h" @@ -1292,3 +1293,140 @@ TEST(20_in_and_out) db::compare_layouts (_this, target, tl::testdata () + "/algo/deep_edges_au20.gds"); } +TEST(deep_edges_and_cheats) +{ + db::Layout ly; + { + std::string fn (tl::testdata ()); + fn += "/algo/cheats.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::cell_index_type top_cell_index = *ly.begin_top_down (); + db::Cell &top_cell = ly.cell (top_cell_index); + + unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); + unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); + unsigned int l10 = ly.get_layer (db::LayerProperties (10, 0)); + unsigned int l11 = ly.get_layer (db::LayerProperties (11, 0)); + unsigned int l12 = ly.get_layer (db::LayerProperties (12, 0)); + unsigned int l13 = ly.get_layer (db::LayerProperties (13, 0)); + unsigned int l14 = ly.get_layer (db::LayerProperties (14, 0)); + unsigned int l19 = ly.get_layer (db::LayerProperties (19, 0)); + unsigned int l20 = ly.get_layer (db::LayerProperties (20, 0)); + unsigned int l21 = ly.get_layer (db::LayerProperties (21, 0)); + unsigned int l22 = ly.get_layer (db::LayerProperties (22, 0)); + unsigned int l23 = ly.get_layer (db::LayerProperties (23, 0)); + unsigned int l24 = ly.get_layer (db::LayerProperties (24, 0)); + unsigned int l29 = ly.get_layer (db::LayerProperties (29, 0)); + unsigned int l30 = ly.get_layer (db::LayerProperties (30, 0)); + unsigned int l31 = ly.get_layer (db::LayerProperties (31, 0)); + unsigned int l32 = ly.get_layer (db::LayerProperties (32, 0)); + unsigned int l33 = ly.get_layer (db::LayerProperties (33, 0)); + unsigned int l34 = ly.get_layer (db::LayerProperties (34, 0)); + unsigned int l39 = ly.get_layer (db::LayerProperties (39, 0)); + + db::DeepShapeStore dss; + + db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1), dss); + db::Region r2 (db::RecursiveShapeIterator (ly, top_cell, l2), dss); + + (r1.edges () - r2).insert_into (&ly, top_cell_index, l10); + + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("A").second); + + (r1.edges () - r2).insert_into (&ly, top_cell_index, l11); + + dss.clear_breakout_cells (0); + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("B").second); + + (r1.edges () - r2).insert_into (&ly, top_cell_index, l12); + + dss.clear_breakout_cells (0); + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("C").second); + + (r1.edges () - r2).insert_into (&ly, top_cell_index, l13); + + dss.clear_breakout_cells (0); + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("D").second); + + (r1.edges () - r2).insert_into (&ly, top_cell_index, l14); + + dss.clear_breakout_cells (0); + (r1.edges () - r2).insert_into (&ly, top_cell_index, l19); + + (r1.edges () - r2.edges ()).insert_into (&ly, top_cell_index, l20); + + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("A").second); + + (r1.edges () - r2.edges ()).insert_into (&ly, top_cell_index, l21); + + dss.clear_breakout_cells (0); + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("B").second); + + (r1.edges () - r2.edges ()).insert_into (&ly, top_cell_index, l22); + + dss.clear_breakout_cells (0); + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("C").second); + + (r1.edges () - r2.edges ()).insert_into (&ly, top_cell_index, l23); + + dss.clear_breakout_cells (0); + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("D").second); + + (r1.edges () - r2.edges ()).insert_into (&ly, top_cell_index, l24); + + dss.clear_breakout_cells (0); + (r1.edges () - r2.edges ()).insert_into (&ly, top_cell_index, l29); + + db::Region eo; + db::Edges e1; + + e1 = r2.edges (); + e1.extended (eo, 0, 0, 500, 0); + eo.insert_into (&ly, top_cell_index, l30); + EXPECT_EQ (dynamic_cast (e1.delegate ())->merged_edges_available (), true); + + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("A").second); + + e1 = r2.edges (); + e1.extended (eo, 0, 0, 500, 0); + eo.insert_into (&ly, top_cell_index, l31); + EXPECT_EQ (dynamic_cast (e1.delegate ())->merged_edges_available (), true); + + dss.clear_breakout_cells (0); + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("B").second); + + e1 = r2.edges (); + e1.extended (eo, 0, 0, 500, 0); + eo.insert_into (&ly, top_cell_index, l32); + EXPECT_EQ (dynamic_cast (e1.delegate ())->merged_edges_available (), true); + + dss.clear_breakout_cells (0); + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("C").second); + + e1 = r2.edges (); + e1.extended (eo, 0, 0, 500, 0); + eo.insert_into (&ly, top_cell_index, l33); + EXPECT_EQ (dynamic_cast (e1.delegate ())->merged_edges_available (), true); + + dss.clear_breakout_cells (0); + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("D").second); + + e1 = r2.edges (); + e1.extended (eo, 0, 0, 500, 0); + eo.insert_into (&ly, top_cell_index, l34); + EXPECT_EQ (dynamic_cast (e1.delegate ())->merged_edges_available (), true); + + dss.clear_breakout_cells (0); + + e1 = r2.edges (); + e1.extended (eo, 0, 0, 500, 0); + eo.insert_into (&ly, top_cell_index, l39); + EXPECT_EQ (dynamic_cast (e1.delegate ())->merged_edges_available (), true); + + CHECKPOINT(); + db::compare_layouts (_this, ly, tl::testdata () + "/algo/cheats_edges_au.gds"); +} diff --git a/src/db/unit_tests/dbDeepRegionTests.cc b/src/db/unit_tests/dbDeepRegionTests.cc index 5bdeaadd3..3583dc279 100644 --- a/src/db/unit_tests/dbDeepRegionTests.cc +++ b/src/db/unit_tests/dbDeepRegionTests.cc @@ -30,6 +30,7 @@ #include "dbRegionProcessors.h" #include "dbEdgesUtils.h" #include "dbDeepShapeStore.h" +#include "dbDeepRegion.h" #include "dbOriginalLayerRegion.h" #include "dbCellGraphUtils.h" #include "dbTestSupport.h" @@ -2846,3 +2847,97 @@ TEST(issue_663_separation_from_inside) CHECKPOINT(); db::compare_layouts (_this, ly, tl::testdata () + "/algo/deep_region_au663.gds"); } + +TEST(deep_region_and_cheats) +{ + db::Layout ly; + { + std::string fn (tl::testdata ()); + fn += "/algo/cheats.gds"; + tl::InputStream stream (fn); + db::Reader reader (stream); + reader.read (ly); + } + + db::cell_index_type top_cell_index = *ly.begin_top_down (); + db::Cell &top_cell = ly.cell (top_cell_index); + + unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0)); + unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0)); + unsigned int l10 = ly.get_layer (db::LayerProperties (10, 0)); + unsigned int l11 = ly.get_layer (db::LayerProperties (11, 0)); + unsigned int l12 = ly.get_layer (db::LayerProperties (12, 0)); + unsigned int l13 = ly.get_layer (db::LayerProperties (13, 0)); + unsigned int l14 = ly.get_layer (db::LayerProperties (14, 0)); + unsigned int l19 = ly.get_layer (db::LayerProperties (19, 0)); + unsigned int l20 = ly.get_layer (db::LayerProperties (20, 0)); + unsigned int l21 = ly.get_layer (db::LayerProperties (21, 0)); + unsigned int l22 = ly.get_layer (db::LayerProperties (22, 0)); + unsigned int l23 = ly.get_layer (db::LayerProperties (23, 0)); + unsigned int l24 = ly.get_layer (db::LayerProperties (24, 0)); + unsigned int l29 = ly.get_layer (db::LayerProperties (29, 0)); + + db::DeepShapeStore dss; + + db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1), dss); + db::Region r2 (db::RecursiveShapeIterator (ly, top_cell, l2), dss); + + (r1 - r2).insert_into (&ly, top_cell_index, l10); + + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("A").second); + + (r1 - r2).insert_into (&ly, top_cell_index, l11); + + dss.clear_breakout_cells (0); + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("B").second); + + (r1 - r2).insert_into (&ly, top_cell_index, l12); + + dss.clear_breakout_cells (0); + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("C").second); + + (r1 - r2).insert_into (&ly, top_cell_index, l13); + + dss.clear_breakout_cells (0); + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("D").second); + + (r1 - r2).insert_into (&ly, top_cell_index, l14); + + dss.clear_breakout_cells (0); + (r1 - r2).insert_into (&ly, top_cell_index, l19); + + EXPECT_EQ (dynamic_cast (r1.delegate ())->merged_polygons_available (), false); + + r1.sized (-1000).insert_into (&ly, top_cell_index, l20); + EXPECT_EQ (dynamic_cast (r1.delegate ())->merged_polygons_available (), true); + + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("A").second); + + r1.sized (-1000).insert_into (&ly, top_cell_index, l21); + EXPECT_EQ (dynamic_cast (r1.delegate ())->merged_polygons_available (), true); + + dss.clear_breakout_cells (0); + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("B").second); + + r1.sized (-1000).insert_into (&ly, top_cell_index, l22); + EXPECT_EQ (dynamic_cast (r1.delegate ())->merged_polygons_available (), true); + + dss.clear_breakout_cells (0); + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("C").second); + + r1.sized (-1000).insert_into (&ly, top_cell_index, l23); + EXPECT_EQ (dynamic_cast (r1.delegate ())->merged_polygons_available (), true); + + dss.clear_breakout_cells (0); + dss.add_breakout_cell (0, dss.layout (0).cell_by_name ("D").second); + + r1.sized (-1000).insert_into (&ly, top_cell_index, l24); + EXPECT_EQ (dynamic_cast (r1.delegate ())->merged_polygons_available (), true); + + dss.clear_breakout_cells (0); + r1.sized (-1000).insert_into (&ly, top_cell_index, l29); + EXPECT_EQ (dynamic_cast (r1.delegate ())->merged_polygons_available (), true); + + CHECKPOINT(); + db::compare_layouts (_this, ly, tl::testdata () + "/algo/cheats_au.gds"); +}