mirror of https://github.com/KLayout/klayout.git
WIP: Deep edge pairs
This commit is contained in:
parent
82ad528dbe
commit
6404ca6b1d
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue