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.
This commit is contained in:
Matthias Koefferlein 2023-12-03 21:50:03 +01:00
parent 7b4a5c3878
commit b701390e6a
8 changed files with 324 additions and 30 deletions

View File

@ -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<db::Edge, db::Edge, db::Edge> proc (const_cast<db::Layout *> (&deep_layer ().layout ()), const_cast<db::Cell *> (&deep_layer ().initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell ());
db::local_processor<db::Edge, db::Edge, db::Edge> proc (const_cast<db::Layout *> (&deep_layer ().layout ()), const_cast<db::Cell *> (&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<db::Edge, db::PolygonRef, db::Edge> proc (const_cast<db::Layout *> (&deep_layer ().layout ()), const_cast<db::Cell *> (&deep_layer ().initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell ());
db::local_processor<db::Edge, db::PolygonRef, db::Edge> proc (const_cast<db::Layout *> (&deep_layer ().layout ()), const_cast<db::Cell *> (&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<db::DeepRegion> res (new db::DeepRegion (edges.derived ()));
db::Layout &layout = const_cast<db::Layout &> (edges.layout ());
db::Cell &top_cell = const_cast<db::Cell &> (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<db::Edge, db::PolygonRef, db::Edge> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ());
db::local_processor<db::Edge, db::PolygonRef, db::Edge> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&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<db::Edge, db::PolygonRef, db::Edge> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ());
db::local_processor<db::Edge, db::PolygonRef, db::Edge> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&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<db::Edge, db::Edge, db::Edge> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ());
db::local_processor<db::Edge, db::Edge, db::Edge> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&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<db::Edge, db::Edge, db::Edge> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ());
db::local_processor<db::Edge, db::Edge, db::Edge> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&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<db::Edge, db::PolygonRef, db::PolygonRef> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&edges.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell ());
db::local_processor<db::Edge, db::PolygonRef, db::PolygonRef> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&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<db::Edge, db::Edge, db::Edge> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&edges.initial_cell ()), &other_edges.layout (), &other_edges.initial_cell ());
db::local_processor<db::Edge, db::Edge, db::Edge> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&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<db::Edge, db::Edge, db::Edge> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ());
db::local_processor<db::Edge, db::Edge, db::Edge> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&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<EdgesDelegate *, EdgesDelegate *> DeepEdges::in_and_out (const Edges &
db::ContainedEdgesLocalOperation op (PositiveAndNegative);
db::local_processor<db::Edge, db::Edge, db::Edge> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ());
db::local_processor<db::Edge, db::Edge, db::Edge> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&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<db::Edge, db::Edge, db::EdgePair> proc (const_cast<db::Layout *> (&edges.layout ()),
const_cast<db::Cell *> (&edges.initial_cell ()),
other_deep ? &other_deep->deep_layer ().layout () : const_cast<db::Layout *> (&edges.layout ()),
other_deep ? &other_deep->deep_layer ().initial_cell () : const_cast<db::Cell *> (&edges.initial_cell ()));
other_deep ? &other_deep->deep_layer ().initial_cell () : const_cast<db::Cell *> (&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 ());

View File

@ -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<DeepLayer, DeepLayer> 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;

View File

@ -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 ();
}

View File

@ -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 ();

View File

@ -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<db::cell_index_type> *
DeepShapeStoreState::breakout_cells (unsigned int layout_index) const
{
const std::set<db::cell_index_type> &boc = (const_cast<DeepShapeStoreState *> (this))->ensure_breakout_cells (layout_index);
if (boc.empty ()) {
const std::pair<std::set<db::cell_index_type>, size_t> &boc = (const_cast<DeepShapeStoreState *> (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<std::set<db::cell_index_type>, size_t> &boc = (const_cast<DeepShapeStoreState *> (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<std::set<db::cell_index_type>, size_t> &boc = ensure_breakout_cells (layout_index);
boc.first.clear ();
boc.second = std::hash<std::set<db::cell_index_type> >() (boc.first);
}
void
DeepShapeStoreState::set_breakout_cells (unsigned int layout_index, const std::set<db::cell_index_type> &boc)
DeepShapeStoreState::set_breakout_cells (unsigned int layout_index, const std::set<db::cell_index_type> &boc_in)
{
ensure_breakout_cells (layout_index) = boc;
std::pair<std::set<db::cell_index_type>, size_t> &boc = ensure_breakout_cells (layout_index);
boc.first = boc_in;
boc.second = std::hash<std::set<db::cell_index_type> >() (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<std::set<db::cell_index_type>, size_t> &boc = ensure_breakout_cells (layout_index);
boc.first.insert (ci);
boc.second = std::hash<std::set<db::cell_index_type> >() (boc.first);
}
void
DeepShapeStoreState::add_breakout_cells (unsigned int layout_index, const std::set<db::cell_index_type> &cc)
{
ensure_breakout_cells (layout_index).insert (cc.begin (), cc.end ());
std::pair<std::set<db::cell_index_type>, size_t> &boc = ensure_breakout_cells (layout_index);
boc.first.insert (cc.begin (), cc.end ());
boc.second = std::hash<std::set<db::cell_index_type> >() (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)
{

View File

@ -165,6 +165,11 @@ public:
*/
const std::set<db::cell_index_type> *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<db::cell_index_type> *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<db::cell_index_type> &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<std::set<db::cell_index_type> > m_breakout_cells;
std::vector<std::pair<std::set<db::cell_index_type>, size_t> > m_breakout_cells;
int m_text_enlargement;
bool m_subcircuit_hierarchy_for_nets;
std::set<db::cell_index_type> &ensure_breakout_cells (unsigned int layout_index)
std::pair<std::set<db::cell_index_type>, 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<db::cell_index_type> ());
m_breakout_cells.resize (layout_index + 1, std::pair<std::set<db::cell_index_type>, size_t> ());
}
return m_breakout_cells [layout_index];
}
@ -782,6 +788,11 @@ public:
*/
const std::set<db::cell_index_type> *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
*/

View File

@ -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<const db::DeepEdges *> (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<const db::DeepEdges *> (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<const db::DeepEdges *> (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<const db::DeepEdges *> (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<const db::DeepEdges *> (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<const db::DeepEdges *> (e1.delegate ())->merged_edges_available (), true);
CHECKPOINT();
db::compare_layouts (_this, ly, tl::testdata () + "/algo/cheats_edges_au.gds");
}

View File

@ -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<const db::DeepRegion *> (r1.delegate ())->merged_polygons_available (), false);
r1.sized (-1000).insert_into (&ly, top_cell_index, l20);
EXPECT_EQ (dynamic_cast<const db::DeepRegion *> (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<const db::DeepRegion *> (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<const db::DeepRegion *> (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<const db::DeepRegion *> (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<const db::DeepRegion *> (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<const db::DeepRegion *> (r1.delegate ())->merged_polygons_available (), true);
CHECKPOINT();
db::compare_layouts (_this, ly, tl::testdata () + "/algo/cheats_au.gds");
}