WIP: Deep edge pairs

This commit is contained in:
Matthias Koefferlein 2019-02-12 00:08:47 +01:00
parent 82ad528dbe
commit 6404ca6b1d
20 changed files with 650 additions and 8 deletions

View File

@ -272,5 +272,17 @@ AsIfFlatEdgePairs::less (const EdgePairs &other) const
return false;
}
void
AsIfFlatEdgePairs::insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
{
// improves performance when inserting an original layout into the same layout
db::LayoutLocker locker (layout);
db::Shapes &shapes = layout->cell (into_cell).shapes (into_layer);
for (EdgePairsIterator e (begin ()); ! e.at_end (); ++e) {
shapes.insert (*e);
}
}
}

View File

@ -68,6 +68,8 @@ public:
virtual bool equals (const EdgePairs &other) const;
virtual bool less (const EdgePairs &other) const;
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const;
protected:
void update_bbox (const db::Box &box);
void invalidate_bbox ();

View File

@ -22,13 +22,343 @@
#include "dbDeepEdgePairs.h"
#include "dbCellGraphUtils.h"
#include "dbDeepEdges.h"
#include "dbDeepRegion.h"
#include "dbCellMapping.h"
#include "dbLayoutUtils.h"
#include <sstream>
namespace db
{
// @@@ TODO: implement
/**
* @brief An iterator delegate for the deep edge pair collection
* TODO: this is kind of redundant with OriginalLayerIterator ..
*/
class DB_PUBLIC DeepEdgePairsIterator
: public EdgePairsIteratorDelegate
{
public:
DeepEdgePairsIterator (const db::RecursiveShapeIterator &iter)
: m_iter (iter)
{
set ();
}
virtual ~DeepEdgePairsIterator () { }
virtual bool at_end () const
{
return m_iter.at_end ();
}
virtual void increment ()
{
++m_iter;
set ();
}
virtual const value_type *get () const
{
return &m_edge_pair;
}
virtual EdgePairsIteratorDelegate *clone () const
{
return new DeepEdgePairsIterator (*this);
}
private:
friend class EdgePairs;
db::RecursiveShapeIterator m_iter;
mutable value_type m_edge_pair;
void set () const
{
if (! m_iter.at_end ()) {
m_iter.shape ().edge_pair (m_edge_pair);
m_edge_pair.transform (m_iter.trans ());
}
}
};
DeepEdgePairs::DeepEdgePairs ()
: AsIfFlatEdgePairs (), m_deep_layer ()
{
// .. nothing yet ..
}
DeepEdgePairs::DeepEdgePairs (const RecursiveShapeIterator &si, DeepShapeStore &dss)
: AsIfFlatEdgePairs (), m_deep_layer (dss.create_edge_pair_layer (si))
{
// .. nothing yet ..
}
DeepEdgePairs::DeepEdgePairs (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans)
: AsIfFlatEdgePairs (), m_deep_layer (dss.create_edge_pair_layer (si))
{
tl_assert (trans.is_unity ()); // TODO: implement
}
DeepEdgePairs::DeepEdgePairs (const DeepEdgePairs &other)
: AsIfFlatEdgePairs (other),
m_deep_layer (other.m_deep_layer.copy ())
{
// .. nothing yet ..
}
DeepEdgePairs::DeepEdgePairs (const DeepLayer &dl)
: AsIfFlatEdgePairs (), m_deep_layer (dl)
{
// .. nothing yet ..
}
DeepEdgePairs::~DeepEdgePairs ()
{
// .. nothing yet ..
}
EdgePairsDelegate *DeepEdgePairs::clone () const
{
return new DeepEdgePairs (*this);
}
EdgePairsIteratorDelegate *DeepEdgePairs::begin () const
{
return new DeepEdgePairsIterator (begin_iter ().first);
}
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> DeepEdgePairs::begin_iter () const
{
const db::Layout &layout = m_deep_layer.layout ();
if (layout.cells () == 0) {
return std::make_pair (db::RecursiveShapeIterator (), db::ICplxTrans ());
} else {
const db::Cell &top_cell = layout.cell (*layout.begin_top_down ());
db::RecursiveShapeIterator iter (m_deep_layer.layout (), top_cell, m_deep_layer.layer ());
return std::make_pair (iter, db::ICplxTrans ());
}
}
size_t DeepEdgePairs::size () const
{
size_t n = 0;
const db::Layout &layout = m_deep_layer.layout ();
db::CellCounter cc (&layout);
for (db::Layout::top_down_const_iterator c = layout.begin_top_down (); c != layout.end_top_down (); ++c) {
n += cc.weight (*c) * layout.cell (*c).shapes (m_deep_layer.layer ()).size ();
}
return n;
}
std::string DeepEdgePairs::to_string (size_t nmax) const
{
return db::AsIfFlatEdgePairs::to_string (nmax);
}
Box DeepEdgePairs::bbox () const
{
return m_deep_layer.initial_cell ().bbox (m_deep_layer.layer ());
}
bool DeepEdgePairs::empty () const
{
return begin_iter ().first.at_end ();
}
const db::EdgePair *DeepEdgePairs::nth (size_t) const
{
throw tl::Exception (tl::to_string (tr ("Random access to edge pairs is available only for flat edge pair collections")));
}
bool DeepEdgePairs::has_valid_edge_pairs () const
{
return false;
}
const db::RecursiveShapeIterator *DeepEdgePairs::iter () const
{
return 0;
}
void
DeepEdgePairs::add_from (const DeepLayer &dl)
{
if (&dl.layout () == &deep_layer ().layout ()) {
// intra-layout merge
deep_layer ().layout ().copy_layer (dl.layer (), deep_layer ().layer ());
} else {
// inter-layout merge
db::cell_index_type into_cell = deep_layer ().initial_cell ().cell_index ();
db::Layout *into_layout = &deep_layer ().layout ();
db::cell_index_type source_cell = dl.initial_cell ().cell_index ();
const db::Layout *source_layout = &dl.layout ();
db::CellMapping cm;
cm.create_from_geometry_full (*into_layout, into_cell, *source_layout, source_cell);
// Actually copy the shapes
std::map<unsigned int, unsigned int> lm;
lm.insert (std::make_pair (dl.layer (), deep_layer ().layer ()));
std::vector <db::cell_index_type> source_cells;
source_cells.push_back (source_cell);
db::copy_shapes (*into_layout, *source_layout, db::ICplxTrans (), source_cells, cm.table (), lm);
}
}
EdgePairsDelegate *
DeepEdgePairs::add_in_place (const EdgePairs &other)
{
if (other.empty ()) {
return this;
}
const DeepEdgePairs *other_deep = dynamic_cast <const DeepEdgePairs *> (other.delegate ());
if (other_deep) {
add_from (other_deep->deep_layer ());
} else {
// non-deep to deep merge (flat)
db::Shapes &shapes = deep_layer ().initial_cell ().shapes (deep_layer ().layer ());
for (db::EdgePairs::const_iterator p = other.begin (); ! p.at_end (); ++p) {
shapes.insert (*p);
}
}
return this;
}
EdgePairsDelegate *DeepEdgePairs::add (const EdgePairs &other) const
{
if (other.empty ()) {
return clone ();
} else if (empty ()) {
return other.delegate ()->clone ();
} else {
DeepEdgePairs *new_edge_pairs = dynamic_cast<DeepEdgePairs *> (clone ());
new_edge_pairs->add_in_place (other);
return new_edge_pairs;
}
}
EdgePairsDelegate *DeepEdgePairs::filter_in_place (const EdgePairFilterBase &filter)
{
// TODO: implement
return AsIfFlatEdgePairs::filter_in_place (filter);
}
EdgePairsDelegate *DeepEdgePairs::filtered (const EdgePairFilterBase &filter) const
{
// TODO: implement
return AsIfFlatEdgePairs::filtered (filter);
}
RegionDelegate *DeepEdgePairs::polygons (db::Coord e) const
{
db::DeepLayer new_layer = m_deep_layer.new_layer ();
db::Layout &layout = const_cast<db::Layout &> (m_deep_layer.layout ());
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
db::Shapes &output = c->shapes (new_layer.layer ());
for (db::Shapes::shape_iterator s = c->shapes (m_deep_layer.layer ()).begin (db::ShapeIterator::EdgePairs); ! s.at_end (); ++s) {
db::Polygon poly = s->edge_pair ().normalized ().to_polygon (e);
if (poly.vertices () >= 3) {
output.insert (poly);
}
}
}
return new db::DeepRegion (new_layer);
}
EdgesDelegate *DeepEdgePairs::generic_edges (bool first, bool second) const
{
db::DeepLayer new_layer = m_deep_layer.new_layer ();
db::Layout &layout = const_cast<db::Layout &> (m_deep_layer.layout ());
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
db::Shapes &output = c->shapes (new_layer.layer ());
for (db::Shapes::shape_iterator s = c->shapes (m_deep_layer.layer ()).begin (db::ShapeIterator::EdgePairs); ! s.at_end (); ++s) {
db::EdgePair ep = s->edge_pair ();
if (first) {
output.insert (ep.first ());
}
if (second) {
output.insert (ep.second ());
}
}
}
return new db::DeepEdges (new_layer);
}
EdgesDelegate *DeepEdgePairs::edges () const
{
return generic_edges (true, true);
}
EdgesDelegate *DeepEdgePairs::first_edges () const
{
return generic_edges (true, false);
}
EdgesDelegate *DeepEdgePairs::second_edges () const
{
return generic_edges (false, true);
}
EdgePairsDelegate *DeepEdgePairs::in (const EdgePairs &other, bool invert) const
{
// TODO: implement
return AsIfFlatEdgePairs::in (other, invert);
}
bool DeepEdgePairs::equals (const EdgePairs &other) const
{
const DeepEdgePairs *other_delegate = dynamic_cast<const DeepEdgePairs *> (other.delegate ());
if (other_delegate && &other_delegate->m_deep_layer.layout () == &m_deep_layer.layout ()
&& other_delegate->m_deep_layer.layer () == m_deep_layer.layer ()) {
return true;
} else {
return AsIfFlatEdgePairs::equals (other);
}
}
bool DeepEdgePairs::less (const EdgePairs &other) const
{
const DeepEdgePairs *other_delegate = dynamic_cast<const DeepEdgePairs *> (other.delegate ());
if (other_delegate && &other_delegate->m_deep_layer.layout () == &m_deep_layer.layout ()) {
return other_delegate->m_deep_layer.layer () < m_deep_layer.layer ();
} else {
return AsIfFlatEdgePairs::less (other);
}
}
void DeepEdgePairs::insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
{
m_deep_layer.insert_into (layout, into_cell, into_layer);
}
}

View File

@ -27,10 +27,77 @@
#include "dbCommon.h"
#include "dbAsIfFlatEdgePairs.h"
#include "dbDeepShapeStore.h"
#include "dbEdgePairs.h"
namespace db {
// @@@ TODO: implement
/**
* @brief Provides hierarchical edges implementation
*/
class DB_PUBLIC DeepEdgePairs
: public db::AsIfFlatEdgePairs
{
public:
DeepEdgePairs ();
DeepEdgePairs (const RecursiveShapeIterator &si, DeepShapeStore &dss);
DeepEdgePairs (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans);
DeepEdgePairs (const DeepEdgePairs &other);
DeepEdgePairs (const DeepLayer &dl);
virtual ~DeepEdgePairs ();
EdgePairsDelegate *clone () const;
virtual EdgePairsIteratorDelegate *begin () const;
virtual std::pair<db::RecursiveShapeIterator, db::ICplxTrans> begin_iter () const;
virtual size_t size () const;
virtual std::string to_string (size_t) const;
virtual Box bbox () const;
virtual bool empty () const;
virtual const db::EdgePair *nth (size_t n) const;
virtual bool has_valid_edge_pairs () const;
virtual const db::RecursiveShapeIterator *iter () const;
virtual EdgePairsDelegate *filter_in_place (const EdgePairFilterBase &filter);
virtual EdgePairsDelegate *filtered (const EdgePairFilterBase &) const;
virtual EdgePairsDelegate *add_in_place (const EdgePairs &other);
virtual EdgePairsDelegate *add (const EdgePairs &other) const;
virtual RegionDelegate *polygons (db::Coord e) const;
virtual EdgesDelegate *edges () const;
virtual EdgesDelegate *first_edges () const;
virtual EdgesDelegate *second_edges () const;
virtual EdgePairsDelegate *in (const EdgePairs &, bool) const;
virtual bool equals (const EdgePairs &other) const;
virtual bool less (const EdgePairs &other) const;
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const;
const DeepLayer &deep_layer () const
{
return m_deep_layer;
}
DeepLayer &deep_layer ()
{
return m_deep_layer;
}
private:
DeepEdgePairs &operator= (const DeepEdgePairs &other);
DeepLayer m_deep_layer;
void init ();
void add_from (const DeepLayer &dl);
EdgesDelegate *generic_edges (bool first, bool second) const;
};
}

View File

@ -423,6 +423,36 @@ DeepLayer DeepShapeStore::create_edge_layer (const db::RecursiveShapeIterator &s
return DeepLayer (this, layout_index, layer_index);
}
DeepLayer DeepShapeStore::create_edge_pair_layer (const db::RecursiveShapeIterator &si)
{
unsigned int layout_index = layout_for_iter (si);
db::Layout &layout = m_layouts[layout_index]->layout;
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;
unsigned int layer_index = layout.insert_layer ();
builder.set_target_layer (layer_index);
// The chain of operators for producing clipped and reduced polygon references
db::EdgePairBuildingHierarchyBuilderShapeReceiver refs;
// Build the working hierarchy from the recursive shape iterator
try {
tl::SelfTimer timer (tl::verbosity () >= 41, tl::to_string (tr ("Building working hierarchy")));
builder.set_shape_receiver (&refs);
db::RecursiveShapeIterator (si).push (& builder);
builder.set_shape_receiver (0);
} catch (...) {
builder.set_shape_receiver (0);
throw;
}
return DeepLayer (this, layout_index, layer_index);
}
void
DeepShapeStore::invalidate_hier ()
{

View File

@ -253,6 +253,15 @@ public:
*/
DeepLayer create_edge_layer (const db::RecursiveShapeIterator &si, bool as_edges);
/**
* @brief Inserts an edge pair layer into the deep shape store
*
* This method will create a new layer inside the deep shape store as a
* working copy of the original layer. This method creates a layer
* for edge pairs.
*/
DeepLayer create_edge_pair_layer (const db::RecursiveShapeIterator &si);
/**
* @brief Inserts the deep layer's shapes into some target layout
*/

View File

@ -26,6 +26,7 @@
#include "dbEdgePairs.h"
#include "dbEmptyEdgePairs.h"
#include "dbFlatEdgePairs.h"
#include "dbDeepEdgePairs.h"
#include "dbOriginalLayerEdgePairs.h"
#include "dbEdges.h"
#include "dbRegion.h"
@ -79,6 +80,16 @@ EdgePairs::EdgePairs (const RecursiveShapeIterator &si, const db::ICplxTrans &tr
mp_delegate = new OriginalLayerEdgePairs (si, trans);
}
EdgePairs::EdgePairs (const RecursiveShapeIterator &si, DeepShapeStore &dss)
{
mp_delegate = new DeepEdgePairs (si, dss);
}
EdgePairs::EdgePairs (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans)
{
mp_delegate = new DeepEdgePairs (si, dss, trans);
}
template <class Sh>
void EdgePairs::insert (const Sh &shape)
{

View File

@ -40,6 +40,7 @@ class FlatEdgePairs;
class EmptyEdgePairs;
class Edges;
class Region;
class DeepShapeStore;
/**
* @brief An edge pair set iterator
@ -274,7 +275,7 @@ public:
* Creates an edge pair set representing a single instance of that object
*/
template <class Sh>
EdgePairs (const Sh &s)
explicit EdgePairs (const Sh &s)
: mp_delegate (0)
{
insert (s);
@ -287,7 +288,7 @@ public:
* This version accepts iterators of the begin ... end style.
*/
template <class Iter>
EdgePairs (const Iter &b, const Iter &e)
explicit EdgePairs (const Iter &b, const Iter &e)
: mp_delegate (0)
{
reserve (e - b);
@ -302,7 +303,7 @@ public:
* Creates an edge pair set from a recursive shape iterator. This allows to feed an edge pair set
* from a hierarchy of cells.
*/
EdgePairs (const RecursiveShapeIterator &si);
explicit EdgePairs (const RecursiveShapeIterator &si);
/**
* @brief Constructor from a RecursiveShapeIterator with a transformation
@ -311,7 +312,20 @@ public:
* from a hierarchy of cells. The transformation is useful to scale to a specific
* DBU for example.
*/
EdgePairs (const RecursiveShapeIterator &si, const db::ICplxTrans &trans);
explicit EdgePairs (const RecursiveShapeIterator &si, const db::ICplxTrans &trans);
/**
* @brief Constructor from a RecursiveShapeIterator providing a deep representation
*
* This version will create a hierarchical edge pair collection. The DeepShapeStore needs to be provided
* during the lifetime of the collection and acts as a heap for optimized data.
*/
explicit EdgePairs (const RecursiveShapeIterator &si, DeepShapeStore &dss);
/**
* @brief Constructor from a RecursiveShapeIterator providing a deep representation with transformation
*/
explicit EdgePairs (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans);
/**
* @brief Gets the underlying delegate object
@ -628,6 +642,16 @@ public:
mp_delegate->disable_progress ();
}
/**
* @brief Inserts the edge pair collection into the given layout, cell and layer
* If the edge pair collection is a hierarchical region, the hierarchy is copied into the
* layout's hierarchy.
*/
void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
{
return mp_delegate->insert_into (layout, into_cell, into_layer);
}
private:
EdgePairsDelegate *mp_delegate;

View File

@ -35,6 +35,7 @@ class EdgePairs;
class EdgePairFilterBase;
class RegionDelegate;
class EdgesDelegate;
class Layout;
/**
* @brief The edge pair set iterator delegate
@ -108,6 +109,8 @@ public:
virtual bool equals (const EdgePairs &other) const = 0;
virtual bool less (const EdgePairs &other) const = 0;
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const = 0;
protected:
const std::string &progress_desc () const
{

View File

@ -74,6 +74,8 @@ public:
virtual bool equals (const EdgePairs &other) const;
virtual bool less (const EdgePairs &other) const;
virtual void insert_into (Layout *, db::cell_index_type, unsigned int) const { }
private:
EmptyEdgePairs &operator= (const EmptyEdgePairs &other);
};

View File

@ -180,6 +180,12 @@ const db::RecursiveShapeIterator *FlatEdgePairs::iter () const
return 0;
}
void
FlatEdgePairs::insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
{
layout->cell (into_cell).shapes (into_layer).insert (m_edge_pairs);
}
void
FlatEdgePairs::insert (const db::EdgePair &ep)
{

View File

@ -113,6 +113,8 @@ public:
virtual const db::RecursiveShapeIterator *iter () const;
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const;
void insert (const db::EdgePair &edge_pair);
void insert (const db::Shape &shape);

View File

@ -640,4 +640,16 @@ void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Polygon &poly, c
// ---------------------------------------------------------------------------------------------
EdgePairBuildingHierarchyBuilderShapeReceiver::EdgePairBuildingHierarchyBuilderShapeReceiver ()
{
// .. nothing yet ..
}
void EdgePairBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, const db::Box & /*region*/, const db::RecursiveShapeReceiver::box_tree_type * /*complex_region*/, db::Shapes *target)
{
if (shape.is_edge_pair ()) {
target->insert (shape.edge_pair ());
}
}
}

View File

@ -165,6 +165,20 @@ private:
bool m_as_edges;
};
/**
* @brief An edge pair-generating shape receiver that feeds a shapes array after turning the shapes into edges
*/
class DB_PUBLIC EdgePairBuildingHierarchyBuilderShapeReceiver
: public HierarchyBuilderShapeReceiver
{
public:
EdgePairBuildingHierarchyBuilderShapeReceiver ();
virtual void push (const db::Shape &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Box &, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *) { }
virtual void push (const db::Polygon &, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *) { }
};
/**
* @brief A class building a hierarchy from a recursive shape iterator in push mode
*

View File

@ -653,6 +653,12 @@ Layout::insert (db::cell_index_type cell, int layer, const db::Edges &edges)
edges.insert_into (this, cell, layer);
}
void
Layout::insert (db::cell_index_type cell, int layer, const db::EdgePairs &edge_pairs)
{
edge_pairs.insert_into (this, cell, layer);
}
void
Layout::flatten (const db::Cell &source_cell, db::Cell &target_cell, const db::ICplxTrans &t, int levels)
{

View File

@ -64,6 +64,7 @@ class CellMapping;
class LayerMapping;
class Region;
class Edges;
class EdgePairs;
template <class Coord> class generic_repository;
typedef generic_repository<db::Coord> GenericRepository;
@ -1112,6 +1113,15 @@ public:
*/
void insert (db::cell_index_type cell, int layer, const db::Edges &edges);
/**
* @brief Inserts a edge pair collection (potentially hierarchical) into the given cell and layer
*
* If the edge pair collection is flat (conceptionally), it will be put into the cell.
* If the edge pair collection is hierarchical, a cell hierarchy will be built below the
* given cell.
*/
void insert (db::cell_index_type cell, int layer, const db::EdgePairs &edge_pairs);
/**
* @brief Delete a cell plus all subcells
*

View File

@ -0,0 +1,101 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2019 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dbHierarchyBuilder.h"
#include "dbReader.h"
#include "dbTestSupport.h"
#include "dbEdgePairs.h"
#include "dbDeepShapeStore.h"
#include "dbRegion.h"
#include "dbEdges.h"
#include "tlUnitTest.h"
#include "tlStream.h"
TEST(1_Basics)
{
db::Layout ly;
{
std::string fn (tl::testsrc ());
fn += "/testdata/algo/deep_region_l1.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
}
// turn boxes into edge pairs to produce a test case
for (db::Layout::layer_iterator l = ly.begin_layers (); l != ly.end_layers (); ++l) {
for (db::Layout::iterator c = ly.begin (); c != ly.end (); ++c) {
db::Shapes out (ly.is_editable ());
db::Shapes &in = c->shapes ((*l).first);
for (db::Shapes::shape_iterator s = in.begin (db::ShapeIterator::All); !s.at_end (); ++s) {
if (s->is_box ()) {
db::Box b = s->box ();
db::EdgePair ep (db::Edge (b.p1 (), b.upper_left ()), db::Edge (b.p2 (), b.lower_right ()));
out.insert (ep);
}
}
in.swap (out);
}
}
db::cell_index_type top_cell_index = *ly.begin_top_down ();
db::Cell &top_cell = ly.cell (top_cell_index);
db::DeepShapeStore dss;
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0));
unsigned int l100 = ly.get_layer (db::LayerProperties (100, 0));
db::EdgePairs ep2 (db::RecursiveShapeIterator (ly, top_cell, l2), dss);
db::EdgePairs ep3 (db::RecursiveShapeIterator (ly, top_cell, l3), dss);
db::EdgePairs ep100 (db::RecursiveShapeIterator (ly, top_cell, l100), dss);
EXPECT_EQ (ep100.empty (), true);
EXPECT_EQ (ep2.empty (), false);
EXPECT_EQ (ep2.bbox ().to_string (), "(-1050,-475;24810,3275)");
EXPECT_EQ (ep2.size (), size_t (40));
EXPECT_EQ (ep2.to_string ().substr (0, 42), "(-1050,-475;-1050,475)/(250,475;250,-475);");
db::Layout target;
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
db::Region polygons;
ep2.polygons (polygons);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), polygons);
polygons.clear ();
ep3.polygons (polygons);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (20, 0)), polygons);
db::Edges edges, first_edges, second_edges;
ep2.edges (edges);
ep2.first_edges (first_edges);
ep2.second_edges (second_edges);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), edges);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (12, 0)), first_edges);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (13, 0)), second_edges);
CHECKPOINT();
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_edge_pairs_au1.gds");
}

View File

@ -68,7 +68,8 @@ SOURCES = \
dbLayoutToNetlistReaderTests.cc \
dbNetlistWriterTests.cc \
dbCellVariantsTests.cc \
dbDeepEdgesTests.cc
dbDeepEdgesTests.cc \
dbDeepEdgePairsTests.cc
INCLUDEPATH += $$TL_INC $$DB_INC $$GSI_INC
DEPENDPATH += $$TL_INC $$DB_INC $$GSI_INC

View File

@ -286,7 +286,7 @@ static void scan_edges (rdb::Category *cat, rdb::Cell *cell, const db::CplxTrans
static void scan_edge_pairs (rdb::Category *cat, rdb::Cell *cell, const db::CplxTrans &trans, const db::EdgePairs &edge_pairs, bool flat)
{
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> it; /* @@@ = edges.begin_iter (); */
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> it = edge_pairs.begin_iter ();
rdb::scan_layer (cat, cell, trans * it.second, it.first, flat);
}

BIN
testdata/algo/deep_edge_pairs_au1.gds vendored Normal file

Binary file not shown.