EdgePairs refactoring

- Uses a db::Shapes container
- Aligned with db::Edges and db::Region
- With original layer delegate
This commit is contained in:
Matthias Koefferlein 2018-11-10 00:07:53 +01:00
parent 8e19474095
commit 7a37da91e0
20 changed files with 1992 additions and 255 deletions

View File

@ -130,7 +130,12 @@ SOURCES = \
dbAsIfFlatEdges.cc \
dbFlatEdges.cc \
dbEdgeBoolean.cc \
dbOriginalLayerEdges.cc
dbOriginalLayerEdges.cc \
dbAsIfFlatEdgePairs.cc \
dbEmptyEdgePairs.cc \
dbFlatEdgePairs.cc \
dbOriginalLayerEdgePairs.cc \
dbEdgePairsDelegate.cc
HEADERS = \
dbArray.h \
@ -230,7 +235,12 @@ HEADERS = \
dbAsIfFlatEdges.h \
dbFlatEdges.h \
dbEdgeBoolean.h \
dbOriginalLayerEdges.h
dbOriginalLayerEdges.h \
dbAsIfFlatEdgePairs.h \
dbEmptyEdgePairs.h \
dbFlatEdgePairs.h \
dbOriginalLayerEdgePairs.h \
dbEdgePairsDelegate.h
!equals(HAVE_QT, "0") {

View File

@ -0,0 +1,276 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2018 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 "dbAsIfFlatEdgePairs.h"
#include "dbFlatEdgePairs.h"
#include "dbFlatRegion.h"
#include "dbFlatEdges.h"
#include "dbEmptyEdgePairs.h"
#include "dbEdgePairs.h"
#include "dbBoxConvert.h"
#include <sstream>
namespace db
{
// -------------------------------------------------------------------------------------------------------------
// AsIfFlagEdgePairs implementation
AsIfFlatEdgePairs::AsIfFlatEdgePairs ()
: EdgePairsDelegate (), m_bbox_valid (false)
{
// .. nothing yet ..
}
AsIfFlatEdgePairs::~AsIfFlatEdgePairs ()
{
// .. nothing yet ..
}
std::string
AsIfFlatEdgePairs::to_string (size_t nmax) const
{
std::ostringstream os;
EdgePairsIterator p (begin ());
bool first = true;
for ( ; ! p.at_end () && nmax != 0; ++p, --nmax) {
if (! first) {
os << ";";
}
first = false;
os << p->to_string ();
}
if (! p.at_end ()) {
os << "...";
}
return os.str ();
}
EdgePairsDelegate *
AsIfFlatEdgePairs::in (const EdgePairs &other, bool invert) const
{
std::set <db::EdgePair> op;
for (EdgePairsIterator o (other.begin ()); ! o.at_end (); ++o) {
op.insert (*o);
}
std::auto_ptr<FlatEdgePairs> new_edge_pairs (new FlatEdgePairs (false));
for (EdgePairsIterator o (begin ()); ! o.at_end (); ++o) {
if ((op.find (*o) == op.end ()) == invert) {
new_edge_pairs->insert (*o);
}
}
return new_edge_pairs.release ();
}
size_t
AsIfFlatEdgePairs::size () const
{
size_t n = 0;
for (EdgePairsIterator p (begin ()); ! p.at_end (); ++p) {
++n;
}
return n;
}
Box AsIfFlatEdgePairs::bbox () const
{
if (! m_bbox_valid) {
m_bbox = compute_bbox ();
m_bbox_valid = true;
}
return m_bbox;
}
Box AsIfFlatEdgePairs::compute_bbox () const
{
db::Box b;
for (EdgePairsIterator e (begin ()); ! e.at_end (); ++e) {
b += e->bbox ();
}
return b;
}
void AsIfFlatEdgePairs::update_bbox (const db::Box &b)
{
m_bbox = b;
m_bbox_valid = true;
}
void AsIfFlatEdgePairs::invalidate_bbox ()
{
m_bbox_valid = false;
}
EdgePairsDelegate *
AsIfFlatEdgePairs::filtered (const EdgePairFilterBase &filter) const
{
std::auto_ptr<FlatEdgePairs> new_edge_pairs (new FlatEdgePairs ());
for (EdgePairsIterator p (begin ()); ! p.at_end (); ++p) {
if (filter.selected (*p)) {
new_edge_pairs->insert (*p);
}
}
return new_edge_pairs.release ();
}
RegionDelegate *
AsIfFlatEdgePairs::polygons (db::Coord e) const
{
std::auto_ptr<FlatRegion> output (new FlatRegion ());
for (EdgePairsIterator ep (begin ()); ! ep.at_end (); ++ep) {
db::Polygon poly = ep->normalized ().to_polygon (e);
if (poly.vertices () >= 3) {
output->insert (poly);
}
}
return output.release ();
}
EdgesDelegate *
AsIfFlatEdgePairs::edges () const
{
std::auto_ptr<FlatEdges> output (new FlatEdges ());
for (EdgePairsIterator ep (begin ()); ! ep.at_end (); ++ep) {
output->insert (ep->first ());
output->insert (ep->second ());
}
return output.release ();
}
EdgesDelegate *
AsIfFlatEdgePairs::first_edges () const
{
std::auto_ptr<FlatEdges> output (new FlatEdges ());
for (EdgePairsIterator ep (begin ()); ! ep.at_end (); ++ep) {
output->insert (ep->first ());
}
return output.release ();
}
EdgesDelegate *
AsIfFlatEdgePairs::second_edges () const
{
std::auto_ptr<FlatEdges> output (new FlatEdges ());
for (EdgePairsIterator ep (begin ()); ! ep.at_end (); ++ep) {
output->insert (ep->second ());
}
return output.release ();
}
EdgePairsDelegate *
AsIfFlatEdgePairs::add (const EdgePairs &other) const
{
FlatEdgePairs *other_flat = dynamic_cast<FlatEdgePairs *> (other.delegate ());
if (other_flat) {
std::auto_ptr<FlatEdgePairs> new_edge_pairs (new FlatEdgePairs (*other_flat));
new_edge_pairs->invalidate_cache ();
size_t n = new_edge_pairs->raw_edge_pairs ().size () + size ();
new_edge_pairs->reserve (n);
for (EdgePairsIterator p (begin ()); ! p.at_end (); ++p) {
new_edge_pairs->raw_edge_pairs ().insert (*p);
}
return new_edge_pairs.release ();
} else {
std::auto_ptr<FlatEdgePairs> new_edge_pairs (new FlatEdgePairs ());
size_t n = size () + other.size ();
new_edge_pairs->reserve (n);
for (EdgePairsIterator p (begin ()); ! p.at_end (); ++p) {
new_edge_pairs->raw_edge_pairs ().insert (*p);
}
for (EdgePairsIterator p (other.begin ()); ! p.at_end (); ++p) {
new_edge_pairs->raw_edge_pairs ().insert (*p);
}
return new_edge_pairs.release ();
}
}
bool
AsIfFlatEdgePairs::equals (const EdgePairs &other) const
{
if (empty () != other.empty ()) {
return false;
}
if (size () != other.size ()) {
return false;
}
EdgePairsIterator o1 (begin ());
EdgePairsIterator o2 (other.begin ());
while (! o1.at_end () && ! o2.at_end ()) {
if (*o1 != *o2) {
return false;
}
++o1;
++o2;
}
return true;
}
bool
AsIfFlatEdgePairs::less (const EdgePairs &other) const
{
if (empty () != other.empty ()) {
return empty () < other.empty ();
}
if (size () != other.size ()) {
return (size () < other.size ());
}
EdgePairsIterator o1 (begin ());
EdgePairsIterator o2 (other.begin ());
while (! o1.at_end () && ! o2.at_end ()) {
if (*o1 != *o2) {
return *o1 < *o2;
}
++o1;
++o2;
}
return false;
}
}

View File

@ -0,0 +1,87 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2018 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
*/
#ifndef HDR_dbAsIfFlatEdgePairs
#define HDR_dbAsIfFlatEdgePairs
#include "dbCommon.h"
#include "dbEdgePairsDelegate.h"
namespace db {
/**
* @brief Provides default flat implementations
*/
class DB_PUBLIC AsIfFlatEdgePairs
: public EdgePairsDelegate
{
public:
AsIfFlatEdgePairs ();
virtual ~AsIfFlatEdgePairs ();
virtual size_t size () const;
virtual std::string to_string (size_t) const;
virtual Box bbox () const;
virtual EdgePairsDelegate *filter_in_place (const EdgePairFilterBase &filter)
{
return filtered (filter);
}
virtual EdgePairsDelegate *filtered (const EdgePairFilterBase &) const;
virtual EdgePairsDelegate *add_in_place (const EdgePairs &other)
{
return add (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;
protected:
void update_bbox (const db::Box &box);
void invalidate_bbox ();
private:
AsIfFlatEdgePairs &operator= (const AsIfFlatEdgePairs &other);
mutable bool m_bbox_valid;
mutable db::Box m_bbox;
virtual db::Box compute_bbox () const;
};
}
#endif

View File

@ -24,6 +24,9 @@
#include "dbCommon.h"
#include "dbEdgePairs.h"
#include "dbEmptyEdgePairs.h"
#include "dbFlatEdgePairs.h"
#include "dbOriginalLayerEdgePairs.h"
#include "dbEdges.h"
#include "dbRegion.h"
@ -34,164 +37,140 @@
namespace db
{
void
EdgePairs::insert (const db::Edge &e1, const db::Edge &e2)
EdgePairs::EdgePairs ()
: mp_delegate (new EmptyEdgePairs ())
{
m_edge_pairs.push_back (db::EdgePair (e1, e2));
m_bbox_valid = false;
// .. nothing yet ..
}
void
EdgePairs::insert (const edge_pair_type &ep)
EdgePairs::~EdgePairs ()
{
m_edge_pairs.push_back (ep);
m_bbox_valid = false;
delete mp_delegate;
mp_delegate = 0;
}
bool
EdgePairs::operator== (const db::EdgePairs &other) const
EdgePairs::EdgePairs (EdgePairsDelegate *delegate)
: mp_delegate (delegate)
{
if (empty () != other.empty ()) {
return false;
}
if (size () != other.size ()) {
return false;
}
db::EdgePairs::const_iterator o1 = begin ();
db::EdgePairs::const_iterator o2 = other.begin ();
while (o1 != end () && o2 != other.end ()) {
if (*o1 != *o2) {
return false;
}
++o1;
++o2;
}
return true;
// .. nothing yet ..
}
bool
EdgePairs::operator< (const db::EdgePairs &other) const
EdgePairs::EdgePairs (const EdgePairs &other)
: mp_delegate (other.mp_delegate->clone ())
{
if (empty () != other.empty ()) {
return empty () < other.empty ();
}
if (size () != other.size ()) {
return (size () < other.size ());
}
db::EdgePairs::const_iterator o1 = begin ();
db::EdgePairs::const_iterator o2 = other.begin ();
while (o1 != end () && o2 != other.end ()) {
if (*o1 != *o2) {
return *o1 < *o2;
}
++o1;
++o2;
}
return false;
// .. nothing yet ..
}
db::EdgePairs &
EdgePairs::operator+= (const db::EdgePairs &other)
EdgePairs &EdgePairs::operator= (const EdgePairs &other)
{
if (! other.empty ()) {
m_edge_pairs.insert (m_edge_pairs.end (), other.begin (), other.end ());
m_bbox_valid = false;
if (this != &other) {
set_delegate (other.mp_delegate->clone ());
}
return *this;
}
std::string
EdgePairs::to_string (size_t nmax) const
EdgePairs::EdgePairs (const RecursiveShapeIterator &si)
{
std::ostringstream os;
const_iterator ep;
for (ep = begin (); ep != end () && nmax != 0; ++ep, --nmax) {
if (ep != begin ()) {
os << ";";
mp_delegate = new OriginalLayerEdgePairs (si);
}
EdgePairs::EdgePairs (const RecursiveShapeIterator &si, const db::ICplxTrans &trans)
{
mp_delegate = new OriginalLayerEdgePairs (si, trans);
}
template <class Sh>
void EdgePairs::insert (const Sh &shape)
{
flat_edge_pairs ()->insert (shape);
}
template void EdgePairs::insert (const db::EdgePair &);
void EdgePairs::insert (const db::Shape &shape)
{
flat_edge_pairs ()->insert (shape);
}
template <class T>
void EdgePairs::insert (const db::Shape &shape, const T &trans)
{
flat_edge_pairs ()->insert (shape, trans);
}
template void EdgePairs::insert (const db::Shape &, const db::ICplxTrans &);
template void EdgePairs::insert (const db::Shape &, const db::Trans &);
void EdgePairs::clear ()
{
set_delegate (new EmptyEdgePairs ());
}
void EdgePairs::reserve (size_t n)
{
flat_edge_pairs ()->reserve (n);
}
template <class T>
EdgePairs &EdgePairs::transform (const T &trans)
{
flat_edge_pairs ()->transform (trans);
return *this;
}
// explicit instantiations
template EdgePairs &EdgePairs::transform (const db::ICplxTrans &);
template EdgePairs &EdgePairs::transform (const db::Trans &);
const db::RecursiveShapeIterator &
EdgePairs::iter () const
{
static db::RecursiveShapeIterator def_iter;
const db::RecursiveShapeIterator *i = mp_delegate->iter ();
return *(i ? i : &def_iter);
}
void EdgePairs::polygons (Region &output, db::Coord e) const
{
output.set_delegate (mp_delegate->polygons (e));
}
void EdgePairs::edges (Edges &output) const
{
output.set_delegate (mp_delegate->edges ());
}
void EdgePairs::first_edges (Edges &output) const
{
output.set_delegate (mp_delegate->first_edges ());
}
void EdgePairs::second_edges (Edges &output) const
{
output.set_delegate (mp_delegate->second_edges ());
}
void EdgePairs::set_delegate (EdgePairsDelegate *delegate)
{
if (delegate != mp_delegate) {
delete mp_delegate;
mp_delegate = delegate;
}
}
FlatEdgePairs *EdgePairs::flat_edge_pairs ()
{
FlatEdgePairs *edge_pairs = dynamic_cast<FlatEdgePairs *> (mp_delegate);
if (! edge_pairs) {
edge_pairs = new FlatEdgePairs ();
if (mp_delegate) {
edge_pairs->EdgePairsDelegate::operator= (*mp_delegate);
edge_pairs->insert_seq (begin ());
}
os << ep->to_string ();
set_delegate (edge_pairs);
}
if (ep != end ()) {
os << "...";
}
return os.str ();
}
void
EdgePairs::clear ()
{
m_edge_pairs.clear ();
m_bbox = db::Box ();
m_bbox_valid = true;
}
void
EdgePairs::polygons (Region &output, db::Coord e) const
{
for (const_iterator ep = begin (); ep != end (); ++ep) {
db::Polygon poly = ep->normalized ().to_polygon (e);
if (poly.vertices () >= 3) {
output.insert (poly);
}
}
}
void
EdgePairs::edges (Edges &output) const
{
for (const_iterator ep = begin (); ep != end (); ++ep) {
output.insert (ep->first ());
output.insert (ep->second ());
}
}
void
EdgePairs::first_edges (Edges &output) const
{
for (const_iterator ep = begin (); ep != end (); ++ep) {
output.insert (ep->first ());
}
}
void
EdgePairs::second_edges (Edges &output) const
{
for (const_iterator ep = begin (); ep != end (); ++ep) {
output.insert (ep->second ());
}
}
void
EdgePairs::init ()
{
m_bbox_valid = false;
m_report_progress = false;
}
void
EdgePairs::ensure_bbox_valid () const
{
if (! m_bbox_valid) {
m_bbox = db::Box ();
for (const_iterator ep = begin (); ep != end (); ++ep) {
m_bbox += db::Box (ep->first ().p1 (), ep->first ().p2 ());
m_bbox += db::Box (ep->second ().p1 (), ep->second ().p2 ());
}
m_bbox_valid = true;
}
}
void
EdgePairs::disable_progress ()
{
m_report_progress = false;
}
void
EdgePairs::enable_progress (const std::string &progress_desc)
{
m_report_progress = true;
m_progress_desc = progress_desc;
return edge_pairs;
}
}

View File

@ -24,14 +24,195 @@
#ifndef HDR_dbEdgePairs
#define HDR_dbEdgePairs
#include "dbEdge.h"
#include "dbEdgePair.h"
#include "dbEdgePairsDelegate.h"
#include "dbShape.h"
#include "dbRecursiveShapeIterator.h"
#include "gsiObject.h"
#include <list>
namespace db
{
class Region;
class EdgePairFilterBase;
class FlatEdgePairs;
class EmptyEdgePairs;
class Edges;
class Region;
/**
* @brief An edge pair set iterator
*
* The iterator delivers the edge pairs of the edge pair set
*/
class DB_PUBLIC EdgePairsIterator
{
public:
typedef EdgePairsIteratorDelegate::value_type value_type;
typedef const value_type &reference;
typedef const value_type *pointer;
typedef std::forward_iterator_tag iterator_category;
typedef void difference_type;
/**
* @brief Default constructor
*/
EdgePairsIterator ()
: mp_delegate (0)
{
// .. nothing yet ..
}
/**
* @brief Constructor from a delegate
* The iterator will take ownership over the delegate
*/
EdgePairsIterator (EdgePairsIteratorDelegate *delegate)
: mp_delegate (delegate)
{
// .. nothing yet ..
}
/**
* @brief Destructor
*/
~EdgePairsIterator ()
{
delete mp_delegate;
mp_delegate = 0;
}
/**
* @brief Copy constructor and assignment
*/
EdgePairsIterator (const EdgePairsIterator &other)
: mp_delegate (0)
{
operator= (other);
}
/**
* @brief Assignment
*/
EdgePairsIterator &operator= (const EdgePairsIterator &other)
{
if (this != &other) {
delete mp_delegate;
mp_delegate = other.mp_delegate ? other.mp_delegate->clone () : 0;
}
return *this;
}
/**
* @Returns true, if the iterator is at the end
*/
bool at_end () const
{
return mp_delegate == 0 || mp_delegate->at_end ();
}
/**
* @brief Increment
*/
EdgePairsIterator &operator++ ()
{
if (mp_delegate) {
mp_delegate->increment ();
}
return *this;
}
/**
* @brief Access
*/
reference operator* () const
{
const value_type *value = operator-> ();
tl_assert (value != 0);
return *value;
}
/**
* @brief Access
*/
pointer operator-> () const
{
return mp_delegate ? mp_delegate->get () : 0;
}
private:
EdgePairsIteratorDelegate *mp_delegate;
};
/**
* @brief A helper class allowing delivery of addressable edges
*
* In some applications (i.e. box scanner), edges need to be taken
* by address. The edge set cannot always deliver adressable edges.
* This class help providing this ability by keeping a temporary copy
* if required.
*/
class DB_PUBLIC AddressableEdgePairDelivery
{
public:
AddressableEdgePairDelivery ()
: m_iter (), m_valid (false)
{
// .. nothing yet ..
}
AddressableEdgePairDelivery (const EdgePairsIterator &iter, bool valid)
: m_iter (iter), m_valid (valid)
{
if (! m_valid && ! m_iter.at_end ()) {
m_heap.push_back (*m_iter);
}
}
bool at_end () const
{
return m_iter.at_end ();
}
AddressableEdgePairDelivery &operator++ ()
{
++m_iter;
if (! m_valid && ! m_iter.at_end ()) {
m_heap.push_back (*m_iter);
}
return *this;
}
const db::EdgePair *operator-> () const
{
if (m_valid) {
return m_iter.operator-> ();
} else {
return &m_heap.back ();
}
}
private:
EdgePairsIterator m_iter;
bool m_valid;
std::list<db::EdgePair> m_heap;
};
class EdgePairs;
/**
* @brief A base class for edge pair filters
*/
class DB_PUBLIC EdgePairFilterBase
{
public:
EdgePairFilterBase () { }
virtual ~EdgePairFilterBase () { }
virtual bool selected (const db::EdgePair &edge) const = 0;
};
/**
* @brief A set of edge pairs
@ -46,92 +227,150 @@ class Edges;
* can be converted to polygons or to individual edges.
*/
class DB_PUBLIC EdgePairs
: public gsi::ObjectBase
{
public:
typedef db::Coord coord_type;
typedef db::coord_traits<db::Coord> coord_traits;
typedef db::EdgePair edge_pair_type;
typedef std::vector<edge_pair_type>::const_iterator const_iterator;
typedef db::Vector vector_type;
typedef db::Point point_type;
typedef db::Box box_type;
typedef coord_traits::distance_type distance_type;
typedef EdgePairsIterator const_iterator;
/**
* @brief Default constructor
*
* This constructor creates an empty edge pair set.
*/
EdgePairs ()
{
init ();
}
EdgePairs ();
/**
* @brief Equality
* @brief Destructor
*/
bool operator== (const db::EdgePairs &other) const;
~EdgePairs ();
/**
* @brief Inequality
* @brief Constructor from a delegate
*
* The region will take ownership of the delegate.
*/
bool operator!= (const db::EdgePairs &other) const
EdgePairs (EdgePairsDelegate *delegate);
/**
* @brief Copy constructor
*/
EdgePairs (const EdgePairs &other);
/**
* @brief Assignment
*/
EdgePairs &operator= (const EdgePairs &other);
/**
* @brief Constructor from an object
*
* Creates an edge pair set representing a single instance of that object
*/
template <class Sh>
EdgePairs (const Sh &s)
: mp_delegate (0)
{
return !operator== (other);
insert (s);
}
/**
* @brief Less operator
*/
bool operator< (const db::EdgePairs &other) const;
/**
* @brief Joining of edge pair sets
* @brief Sequence constructor
*
* This method will combine the edge pairs from "other" with the egdes of "this".
* Creates an edge set from a sequence of objects. The objects need to be edge pairs.
* This version accepts iterators of the begin ... end style.
*/
db::EdgePairs operator+ (const db::EdgePairs &other) const
template <class Iter>
EdgePairs (const Iter &b, const Iter &e)
: mp_delegate (0)
{
db::EdgePairs d (*this);
d += other;
return d;
reserve (e - b);
for (Iter i = b; i != e; ++i) {
insert (*i);
}
}
/**
* @brief In-place joining of edge pair sets
* @brief Constructor from a RecursiveShapeIterator
*
* Creates an edge pair set from a recursive shape iterator. This allows to feed an edge pair set
* from a hierarchy of cells.
*/
db::EdgePairs &operator+= (const db::EdgePairs &other);
EdgePairs (const RecursiveShapeIterator &si);
/**
* @brief Begin iterator of the edge pair set
* @brief Constructor from a RecursiveShapeIterator with a transformation
*
* The iterator delivers the edge pairs of the edge pair set.
* Creates an edge pair set from a recursive shape iterator. This allows to feed an edge pair set
* 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);
/**
* @brief Gets the underlying delegate object
*/
EdgePairsDelegate *delegate () const
{
return mp_delegate;
}
/**
* @brief Iterator of the edge pair set
*
* The iterator delivers the edges of the edge pair set.
* It follows the at_end semantics.
*/
const_iterator begin () const
{
return m_edge_pairs.begin ();
return EdgePairsIterator (mp_delegate->begin ());
}
/**
* @brief End iterator of the edge pair set
*
* The iterator delivers the edge pairs of the edge pair set.
* @brief Delivers a RecursiveShapeIterator pointing to the edge pairs plus the necessary transformation
*/
const_iterator end () const
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> begin_iter () const
{
return m_edge_pairs.end ();
return mp_delegate->begin_iter ();
}
/**
* @brief Insert an edge pair into the edge pair set
* @brief Inserts the given shape (working object) into the edge pair set
*/
void insert (const db::Edge &e1, const db::Edge &e2);
template <class Sh>
void insert (const Sh &shape);
/**
* @brief Insert an edge pair into the edge pair set
* @brief Inserts an edge pair made from two edges
*/
void insert (const edge_pair_type &ep);
void insert (const db::Edge &e1, const db::Edge &e2)
{
insert (db::EdgePair (e1, e2));
}
/**
* @brief Insert a shape reference into the edge pair set
*/
void insert (const db::Shape &shape);
/**
* @brief Insert a transformed shape into the edge pair set
*/
template <class T>
void insert (const db::Shape &shape, const T &trans);
/**
* @brief Returns true if the edge pair set is empty
*/
bool empty () const
{
return m_edge_pairs.empty ();
return mp_delegate->empty ();
}
/**
@ -139,84 +378,65 @@ public:
*/
size_t size () const
{
return m_edge_pairs.size ();
return mp_delegate->size ();
}
/**
* @brief Returns a string representing the edge pair set
*
* nmax specifies how many edge pairs are included (set to std::numeric_limits<size_t>::max() for "all".
*/
std::string to_string (size_t nmax = 10) const;
std::string to_string (size_t nmax = 10) const
{
return mp_delegate->to_string (nmax);
}
/**
* @brief Clear the edge pair set
* @brief Clears the edge set
*/
void clear ();
/**
* @brief Reserve memory for the given number of polygons
* @brief Reserve memory for the given number of edges
*/
void reserve (size_t n)
{
m_edge_pairs.reserve (n);
}
void reserve (size_t n);
/**
* @brief Returns the bounding box of the edge pair set
*/
Box bbox () const
{
ensure_bbox_valid ();
return m_bbox;
return mp_delegate->bbox ();
}
/**
* @brief Filters the edge pair set
* @brief Filters the edge pairs
*
* This method will keep all edge pairs for which the filter returns true.
* Merged semantics applies.
*/
template <class F>
EdgePairs &filter (F &filter)
EdgePairs &filter (const EdgePairFilterBase &filter)
{
std::vector <edge_pair_type>::iterator ew = m_edge_pairs.begin ();
for (const_iterator e = begin (); e != end (); ++e) {
if (filter (*e)) {
*ew++ = *e;
}
}
m_edge_pairs.erase (ew, m_edge_pairs.end ());
set_delegate (mp_delegate->filter_in_place (filter));
return *this;
}
/**
* @brief Returns the filtered edge pairs
*
* This method will return a new region with only those edge pairs which
* This method will return a new region with only those edge pairs which
* conform to the filter criterion.
*/
template <class F>
EdgePairs filtered (F &filter) const
EdgePairs filtered (const EdgePairFilterBase &filter) const
{
EdgePairs d;
for (const_iterator e = begin (); e != end (); ++e) {
if (filter (*e)) {
d.insert (*e);
}
}
return d;
return EdgePairs (mp_delegate->filtered (filter));
}
/**
* @brief Transform the edge pair set
* @brief Transforms the edge pair set
*/
template <class T>
EdgePairs &transform (const T &trans)
{
for (std::vector <edge_pair_type>::iterator e = m_edge_pairs.begin (); e != m_edge_pairs.end (); ++e) {
e->transform (trans);
}
m_bbox_valid = false;
return *this;
}
EdgePairs &transform (const T &trans);
/**
* @brief Returns the transformed edge pair set
@ -230,13 +450,110 @@ public:
}
/**
* @brief Swaps with the other edge pair set
* @brief Swaps with the other edge set
*/
void swap (db::EdgePairs &other)
{
std::swap (m_edge_pairs, other.m_edge_pairs);
std::swap (m_bbox, other.m_bbox);
std::swap (m_bbox_valid, other.m_bbox_valid);
std::swap (other.mp_delegate, mp_delegate);
}
/**
* @brief Joining of edge pair set
*
* This method joins the edge pair sets.
*/
EdgePairs operator+ (const EdgePairs &other) const
{
return EdgePairs (mp_delegate->add (other));
}
/**
* @brief In-place edge pair set joining
*/
EdgePairs &operator+= (const EdgePairs &other)
{
set_delegate (mp_delegate->add_in_place (other));
return *this;
}
/**
* @brief Returns all edge pairs which are in the other edge pair set
*
* This method will return all edge pairs which are part of another edge pair set.
* The match is done exactly.
* The "invert" flag can be used to invert the sense, i.e. with
* "invert" set to true, this method will return all edge pairs not
* in the other edge pair set.
*/
EdgePairs in (const EdgePairs &other, bool invert = false) const
{
return EdgePairs (mp_delegate->in (other, invert));
}
/**
* @brief Returns the nth edge pair
*
* This operation is only cheap if "has_valid_edge_pairs" is true. Otherwise, the
* complexity is O(n).
*/
const db::EdgePair *nth (size_t n) const
{
return mp_delegate->nth (n);
}
/**
* @brief Returns true, if the edge pair set has valid edges stored within itself
*
* If the region has valid edges, it is permissable to use the edge pair's addresses
* from the iterator. Furthermore, the random access operator nth() is available.
*/
bool has_valid_edge_pairs () const
{
return mp_delegate->has_valid_edge_pairs ();
}
/**
* @brief Returns an addressable delivery for edge pairs
*
* This object allows accessing the edge pairs by address, even if they
* are not delivered from a container. The magic is a heap object
* inside the delivery object. Hence, the deliver object must persist
* as long as the addresses are required.
*/
AddressableEdgePairDelivery addressable_edge_pairs () const
{
return AddressableEdgePairDelivery (begin (), has_valid_edge_pairs ());
}
/**
* @brief Gets the internal iterator
*
* This method is intended for users who know what they are doing
*/
const db::RecursiveShapeIterator &iter () const;
/**
* @brief Equality
*/
bool operator== (const db::EdgePairs &other) const
{
return mp_delegate->equals (other);
}
/**
* @brief Inequality
*/
bool operator!= (const db::EdgePairs &other) const
{
return ! mp_delegate->equals (other);
}
/**
* @brief Less operator
*/
bool operator< (const db::EdgePairs &other) const
{
return mp_delegate->less (other);
}
/**
@ -288,22 +605,24 @@ public:
*
* @param progress_text The description text of the progress object
*/
void enable_progress (const std::string &progress_desc = std::string ());
void enable_progress (const std::string &progress_desc = std::string ())
{
mp_delegate->enable_progress (progress_desc);
}
/**
* @brief Disable progress reporting
*/
void disable_progress ();
void disable_progress ()
{
mp_delegate->disable_progress ();
}
private:
std::vector<edge_pair_type> m_edge_pairs;
mutable db::Box m_bbox;
mutable bool m_bbox_valid;
bool m_report_progress;
std::string m_progress_desc;
EdgePairsDelegate *mp_delegate;
void init ();
void ensure_bbox_valid () const;
void set_delegate (EdgePairsDelegate *delegate);
FlatEdgePairs *flat_edge_pairs ();
};
}

View File

@ -0,0 +1,67 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2018 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 "dbEdgePairsDelegate.h"
namespace db
{
// -------------------------------------------------------------------------------------------------------------
EdgePairsDelegate::EdgePairsDelegate ()
{
m_report_progress = false;
}
EdgePairsDelegate::EdgePairsDelegate (const EdgePairsDelegate &other)
{
operator= (other);
}
EdgePairsDelegate &
EdgePairsDelegate::operator= (const EdgePairsDelegate &other)
{
if (this != &other) {
m_report_progress = other.m_report_progress;
}
return *this;
}
EdgePairsDelegate::~EdgePairsDelegate ()
{
// .. nothing yet ..
}
void EdgePairsDelegate::enable_progress (const std::string &progress_desc)
{
m_report_progress = true;
m_progress_desc = progress_desc;
}
void EdgePairsDelegate::disable_progress ()
{
m_report_progress = false;
}
}

View File

@ -0,0 +1,130 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2018 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
*/
#ifndef HDR_dbEdgePairsDelegate
#define HDR_dbEdgePairsDelegate
#include "dbCommon.h"
#include "dbEdgePair.h"
namespace db {
class RecursiveShapeIterator;
class EdgePairs;
class EdgePairFilterBase;
class RegionDelegate;
class EdgesDelegate;
/**
* @brief The edge pair set iterator delegate
*/
class DB_PUBLIC EdgePairsIteratorDelegate
{
public:
EdgePairsIteratorDelegate () { }
virtual ~EdgePairsIteratorDelegate () { }
typedef db::EdgePair value_type;
virtual bool at_end () const = 0;
virtual void increment () = 0;
virtual const value_type *get () const = 0;
virtual EdgePairsIteratorDelegate *clone () const = 0;
};
/**
* @brief The delegate for the actual edge set implementation
*/
class DB_PUBLIC EdgePairsDelegate
{
public:
typedef db::Coord coord_type;
typedef db::coord_traits<db::Coord> coord_traits;
typedef db::EdgePair edge_pair_type;
typedef db::Vector vector_type;
typedef db::Point point_type;
typedef db::Box box_type;
EdgePairsDelegate ();
virtual ~EdgePairsDelegate ();
EdgePairsDelegate (const EdgePairsDelegate &other);
EdgePairsDelegate &operator= (const EdgePairsDelegate &other);
virtual EdgePairsDelegate *clone () const = 0;
void enable_progress (const std::string &progress_desc);
void disable_progress ();
virtual std::string to_string (size_t nmax) const = 0;
virtual EdgePairsIteratorDelegate *begin () const = 0;
virtual std::pair<db::RecursiveShapeIterator, db::ICplxTrans> begin_iter () const = 0;
virtual bool empty () const = 0;
virtual size_t size () const = 0;
virtual Box bbox () const = 0;
virtual EdgePairsDelegate *filter_in_place (const EdgePairFilterBase &filter) = 0;
virtual EdgePairsDelegate *filtered (const EdgePairFilterBase &filter) const = 0;
virtual RegionDelegate *polygons (db::Coord e) const = 0;
virtual EdgesDelegate *edges () const = 0;
virtual EdgesDelegate *first_edges () const = 0;
virtual EdgesDelegate *second_edges () const = 0;
virtual EdgePairsDelegate *add_in_place (const EdgePairs &other) = 0;
virtual EdgePairsDelegate *add (const EdgePairs &other) const = 0;
virtual EdgePairsDelegate *in (const EdgePairs &other, bool invert) const = 0;
virtual const db::EdgePair *nth (size_t n) const = 0;
virtual bool has_valid_edge_pairs () const = 0;
virtual const db::RecursiveShapeIterator *iter () const = 0;
virtual bool equals (const EdgePairs &other) const = 0;
virtual bool less (const EdgePairs &other) const = 0;
protected:
const std::string &progress_desc () const
{
return m_progress_desc;
}
bool report_progress () const
{
return m_report_progress;
}
private:
bool m_report_progress;
std::string m_progress_desc;
};
}
#endif

View File

@ -37,7 +37,6 @@ class EdgeFilterBase;
class FlatEdges;
class EmptyEdges;
/**
* @brief An edge set iterator
*
@ -200,7 +199,7 @@ private:
class Edges;
/**
* @brief A base class for polygon filters
* @brief A base class for edge filters
*/
class DB_PUBLIC EdgeFilterBase
{
@ -1256,6 +1255,8 @@ public:
}
private:
friend class EdgePairs;
EdgesDelegate *mp_delegate;
void set_delegate (EdgesDelegate *delegate);

View File

@ -0,0 +1,99 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2018 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 "dbEmptyEdgePairs.h"
#include "dbEmptyRegion.h"
#include "dbEmptyEdges.h"
namespace db
{
// -------------------------------------------------------------------------------------------------------------
EmptyEdgePairs::EmptyEdgePairs ()
{
// .. nothing yet ..
}
EmptyEdgePairs::EmptyEdgePairs (const EmptyEdgePairs &other)
: EdgePairsDelegate (other)
{
// .. nothing yet ..
}
EdgePairsDelegate *
EmptyEdgePairs::clone () const
{
return new EmptyEdgePairs (*this);
}
RegionDelegate *
EmptyEdgePairs::polygons (db::Coord) const
{
return new EmptyRegion ();
}
EdgesDelegate *
EmptyEdgePairs::edges () const
{
return new EmptyEdges ();
}
EdgesDelegate *
EmptyEdgePairs::first_edges () const
{
return new EmptyEdges ();
}
EdgesDelegate *
EmptyEdgePairs::second_edges () const
{
return new EmptyEdges ();
}
EdgePairsDelegate *
EmptyEdgePairs::add_in_place (const EdgePairs &other)
{
return add (other);
}
EdgePairsDelegate *
EmptyEdgePairs::add (const EdgePairs &other) const
{
return other.delegate ()->clone ();
}
bool
EmptyEdgePairs::equals (const EdgePairs &other) const
{
return other.empty ();
}
bool
EmptyEdgePairs::less (const EdgePairs &other) const
{
return other.empty () ? false : true;
}
}

View File

@ -0,0 +1,84 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2018 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
*/
#ifndef HDR_dbEmptyEdgePairs
#define HDR_dbEmptyEdgePairs
#include "dbCommon.h"
#include "dbEdgePairsDelegate.h"
#include "dbRecursiveShapeIterator.h"
namespace db {
/**
* @brief The delegate for the actual edge set implementation
*/
class DB_PUBLIC EmptyEdgePairs
: public EdgePairsDelegate
{
public:
EmptyEdgePairs ();
EmptyEdgePairs (const EmptyEdgePairs &other);
virtual EdgePairsDelegate *clone () const;
virtual std::string to_string (size_t) const { return std::string (); }
virtual EdgePairsIteratorDelegate *begin () const { return 0; }
virtual std::pair<db::RecursiveShapeIterator, db::ICplxTrans> begin_iter () const { return std::make_pair (db::RecursiveShapeIterator (), db::ICplxTrans ()); }
virtual bool empty () const { return true; }
virtual size_t size () const { return 0; }
virtual Box bbox () const { return Box (); }
virtual EdgePairsDelegate *filter_in_place (const EdgePairFilterBase &) { return this; }
virtual EdgePairsDelegate *filtered (const EdgePairFilterBase &) const { return new EmptyEdgePairs (); }
virtual RegionDelegate *polygons (db::Coord e) const;
virtual EdgesDelegate *edges () const;
virtual EdgesDelegate *first_edges () const;
virtual EdgesDelegate *second_edges () const;
virtual EdgePairsDelegate *add_in_place (const EdgePairs &other);
virtual EdgePairsDelegate *add (const EdgePairs &other) const;
virtual EdgePairsDelegate *in (const EdgePairs &, bool) const { return new EmptyEdgePairs (); }
virtual const db::EdgePair *nth (size_t) const { tl_assert (false); }
virtual bool has_valid_edge_pairs () const { return true; }
virtual const db::RecursiveShapeIterator *iter () const { return 0; }
virtual bool equals (const EdgePairs &other) const;
virtual bool less (const EdgePairs &other) const;
private:
EmptyEdgePairs &operator= (const EmptyEdgePairs &other);
};
}
#endif

View File

@ -0,0 +1,202 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2018 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 "dbFlatEdgePairs.h"
#include "dbEmptyEdgePairs.h"
#include "dbEdgePairs.h"
namespace db
{
// -------------------------------------------------------------------------------------------------------------
// FlatEdgePairs implementation
FlatEdgePairs::FlatEdgePairs ()
: AsIfFlatEdgePairs (), m_edge_pairs (false)
{
// .. nothing yet ..
}
FlatEdgePairs::~FlatEdgePairs ()
{
// .. nothing yet ..
}
FlatEdgePairs::FlatEdgePairs (const FlatEdgePairs &other)
: AsIfFlatEdgePairs (other), m_edge_pairs (false)
{
m_edge_pairs = other.m_edge_pairs;
}
FlatEdgePairs::FlatEdgePairs (const db::Shapes &edge_pairs)
: AsIfFlatEdgePairs (), m_edge_pairs (edge_pairs)
{
// .. nothing yet ..
}
void FlatEdgePairs::invalidate_cache ()
{
invalidate_bbox ();
}
void FlatEdgePairs::reserve (size_t n)
{
m_edge_pairs.reserve (db::EdgePair::tag (), n);
}
EdgePairsIteratorDelegate *FlatEdgePairs::begin () const
{
return new FlatEdgePairsIterator (m_edge_pairs.get_layer<db::EdgePair, db::unstable_layer_tag> ().begin (), m_edge_pairs.get_layer<db::EdgePair, db::unstable_layer_tag> ().end ());
}
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> FlatEdgePairs::begin_iter () const
{
return std::make_pair (db::RecursiveShapeIterator (m_edge_pairs), db::ICplxTrans ());
}
bool FlatEdgePairs::empty () const
{
return m_edge_pairs.empty ();
}
size_t FlatEdgePairs::size () const
{
return m_edge_pairs.size ();
}
Box FlatEdgePairs::compute_bbox () const
{
m_edge_pairs.update_bbox ();
return m_edge_pairs.bbox ();
}
EdgePairsDelegate *
FlatEdgePairs::filter_in_place (const EdgePairFilterBase &filter)
{
edge_pair_iterator_type pw = m_edge_pairs.get_layer<db::EdgePair, db::unstable_layer_tag> ().begin ();
for (EdgePairsIterator p (begin ()); ! p.at_end (); ++p) {
if (filter.selected (*p)) {
if (pw == m_edge_pairs.get_layer<db::EdgePair, db::unstable_layer_tag> ().end ()) {
m_edge_pairs.get_layer<db::EdgePair, db::unstable_layer_tag> ().insert (*p);
pw = m_edge_pairs.get_layer<db::EdgePair, db::unstable_layer_tag> ().end ();
} else {
m_edge_pairs.get_layer<db::EdgePair, db::unstable_layer_tag> ().replace (pw++, *p);
}
}
}
m_edge_pairs.get_layer<db::EdgePair, db::unstable_layer_tag> ().erase (pw, m_edge_pairs.get_layer<db::EdgePair, db::unstable_layer_tag> ().end ());
return this;
}
EdgePairsDelegate *FlatEdgePairs::add (const EdgePairs &other) const
{
std::auto_ptr<FlatEdgePairs> new_edge_pairs (new FlatEdgePairs (*this));
new_edge_pairs->invalidate_cache ();
FlatEdgePairs *other_flat = dynamic_cast<FlatEdgePairs *> (other.delegate ());
if (other_flat) {
new_edge_pairs->raw_edge_pairs ().insert (other_flat->raw_edge_pairs ().get_layer<db::EdgePair, db::unstable_layer_tag> ().begin (), other_flat->raw_edge_pairs ().get_layer<db::EdgePair, db::unstable_layer_tag> ().end ());
} else {
size_t n = new_edge_pairs->raw_edge_pairs ().size ();
for (EdgePairsIterator p (other.begin ()); ! p.at_end (); ++p) {
++n;
}
new_edge_pairs->raw_edge_pairs ().reserve (db::EdgePair::tag (), n);
for (EdgePairsIterator p (other.begin ()); ! p.at_end (); ++p) {
new_edge_pairs->raw_edge_pairs ().insert (*p);
}
}
return new_edge_pairs.release ();
}
EdgePairsDelegate *FlatEdgePairs::add_in_place (const EdgePairs &other)
{
invalidate_cache ();
FlatEdgePairs *other_flat = dynamic_cast<FlatEdgePairs *> (other.delegate ());
if (other_flat) {
m_edge_pairs.insert (other_flat->raw_edge_pairs ().get_layer<db::EdgePair, db::unstable_layer_tag> ().begin (), other_flat->raw_edge_pairs ().get_layer<db::EdgePair, db::unstable_layer_tag> ().end ());
} else {
size_t n = m_edge_pairs.size ();
for (EdgePairsIterator p (other.begin ()); ! p.at_end (); ++p) {
++n;
}
m_edge_pairs.reserve (db::EdgePair::tag (), n);
for (EdgePairsIterator p (other.begin ()); ! p.at_end (); ++p) {
m_edge_pairs.insert (*p);
}
}
return this;
}
const db::EdgePair *FlatEdgePairs::nth (size_t n) const
{
return n < m_edge_pairs.size () ? &m_edge_pairs.get_layer<db::EdgePair, db::unstable_layer_tag> ().begin () [n] : 0;
}
bool FlatEdgePairs::has_valid_edge_pairs () const
{
return true;
}
const db::RecursiveShapeIterator *FlatEdgePairs::iter () const
{
return 0;
}
void
FlatEdgePairs::insert (const db::EdgePair &ep)
{
m_edge_pairs.insert (ep);
}
void
FlatEdgePairs::insert (const db::Shape &shape)
{
if (shape.is_edge_pair ()) {
db::EdgePair ep;
shape.edge_pair (ep);
insert (ep);
}
}
}

168
src/db/db/dbFlatEdgePairs.h Normal file
View File

@ -0,0 +1,168 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2018 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
*/
#ifndef HDR_dbFlatEdgePairs
#define HDR_dbFlatEdgePairs
#include "dbCommon.h"
#include "dbAsIfFlatEdgePairs.h"
#include "dbShapes.h"
namespace db {
/**
* @brief An iterator delegate for the flat edge pair set
*/
class DB_PUBLIC FlatEdgePairsIterator
: public EdgePairsIteratorDelegate
{
public:
typedef db::layer<db::EdgePair, db::unstable_layer_tag> edge_pair_layer_type;
typedef edge_pair_layer_type::iterator iterator_type;
FlatEdgePairsIterator (iterator_type from, iterator_type to)
: m_from (from), m_to (to)
{
// .. nothing yet ..
}
virtual bool at_end () const
{
return m_from == m_to;
}
virtual void increment ()
{
++m_from;
}
virtual const value_type *get () const
{
return m_from.operator-> ();
}
virtual EdgePairsIteratorDelegate *clone () const
{
return new FlatEdgePairsIterator (*this);
}
private:
friend class EdgePairs;
iterator_type m_from, m_to;
};
/**
* @brief The delegate for the actual edge pair set implementation
*/
class DB_PUBLIC FlatEdgePairs
: public AsIfFlatEdgePairs
{
public:
typedef db::layer<db::EdgePair, db::unstable_layer_tag> edge_pair_layer_type;
typedef edge_pair_layer_type::iterator edge_pair_iterator_type;
FlatEdgePairs ();
FlatEdgePairs (const db::Shapes &edges);
FlatEdgePairs (const FlatEdgePairs &other);
virtual ~FlatEdgePairs ();
EdgePairsDelegate *clone () const
{
return new FlatEdgePairs (*this);
}
void reserve (size_t);
virtual EdgePairsIteratorDelegate *begin () const;
virtual std::pair<db::RecursiveShapeIterator, db::ICplxTrans> begin_iter () const;
virtual bool empty () const;
virtual size_t size () const;
virtual EdgePairsDelegate *filter_in_place (const EdgePairFilterBase &filter);
virtual EdgePairsDelegate *add_in_place (const EdgePairs &other);
virtual EdgePairsDelegate *add (const EdgePairs &other) const;
virtual const db::EdgePair *nth (size_t n) const;
virtual bool has_valid_edge_pairs () const;
virtual const db::RecursiveShapeIterator *iter () const;
void insert (const db::EdgePair &edge_pair);
void insert (const db::Shape &shape);
template <class T>
void insert (const db::Shape &shape, const T &trans)
{
if (shape.is_edge_pair ()) {
db::EdgePair ep;
shape.edge_pair (ep);
ep.transform (trans);
insert (ep);
}
}
template <class Iter>
void insert_seq (const Iter &seq)
{
for (Iter i = seq; ! i.at_end (); ++i) {
insert (*i);
}
}
template <class Trans>
void transform (const Trans &trans)
{
if (! trans.is_unity ()) {
for (edge_pair_iterator_type p = m_edge_pairs.template get_layer<db::EdgePair, db::unstable_layer_tag> ().begin (); p != m_edge_pairs.template get_layer<db::EdgePair, db::unstable_layer_tag> ().end (); ++p) {
m_edge_pairs.get_layer<db::EdgePair, db::unstable_layer_tag> ().replace (p, p->transformed (trans));
}
invalidate_cache ();
}
}
protected:
virtual Box compute_bbox () const;
void invalidate_cache ();
private:
friend class AsIfFlatEdgePairs;
db::Shapes &raw_edge_pairs () { return m_edge_pairs; }
FlatEdgePairs &operator= (const FlatEdgePairs &other);
mutable db::Shapes m_edge_pairs;
};
}
#endif

View File

@ -0,0 +1,196 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2018 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 "dbOriginalLayerEdgePairs.h"
#include "dbEdgePairs.h"
namespace db
{
// -------------------------------------------------------------------------------------------------------------
// OriginalLayerEdgePairs implementation
namespace
{
class OriginalLayerEdgePairsIterator
: public EdgePairsIteratorDelegate
{
public:
OriginalLayerEdgePairsIterator (const db::RecursiveShapeIterator &iter, const db::ICplxTrans &trans)
: m_rec_iter (iter), m_iter_trans (trans)
{
set ();
}
virtual bool at_end () const
{
return m_rec_iter.at_end ();
}
virtual void increment ()
{
inc ();
set ();
}
virtual const value_type *get () const
{
return &m_edge_pair;
}
virtual EdgePairsIteratorDelegate *clone () const
{
return new OriginalLayerEdgePairsIterator (*this);
}
private:
friend class EdgePairs;
db::RecursiveShapeIterator m_rec_iter;
db::ICplxTrans m_iter_trans;
db::EdgePair m_edge_pair;
void set ()
{
while (! m_rec_iter.at_end () && ! m_rec_iter.shape ().is_edge_pair ()) {
++m_rec_iter;
}
if (! m_rec_iter.at_end ()) {
m_rec_iter.shape ().edge_pair (m_edge_pair);
m_edge_pair.transform (m_iter_trans * m_rec_iter.trans ());
}
}
void inc ()
{
if (! m_rec_iter.at_end ()) {
++m_rec_iter;
}
}
};
}
OriginalLayerEdgePairs::OriginalLayerEdgePairs ()
: AsIfFlatEdgePairs ()
{
init ();
}
OriginalLayerEdgePairs::OriginalLayerEdgePairs (const OriginalLayerEdgePairs &other)
: AsIfFlatEdgePairs (other),
m_iter (other.m_iter),
m_iter_trans (other.m_iter_trans)
{
// .. nothing yet ..
}
OriginalLayerEdgePairs::OriginalLayerEdgePairs (const RecursiveShapeIterator &si)
: AsIfFlatEdgePairs (), m_iter (si)
{
init ();
}
OriginalLayerEdgePairs::OriginalLayerEdgePairs (const RecursiveShapeIterator &si, const db::ICplxTrans &trans)
: AsIfFlatEdgePairs (), m_iter (si), m_iter_trans (trans)
{
init ();
}
OriginalLayerEdgePairs::~OriginalLayerEdgePairs ()
{
// .. nothing yet ..
}
EdgePairsDelegate *
OriginalLayerEdgePairs::clone () const
{
return new OriginalLayerEdgePairs (*this);
}
EdgePairsIteratorDelegate *
OriginalLayerEdgePairs::begin () const
{
return new OriginalLayerEdgePairsIterator (m_iter, m_iter_trans);
}
std::pair<db::RecursiveShapeIterator, db::ICplxTrans>
OriginalLayerEdgePairs::begin_iter () const
{
return std::make_pair (m_iter, m_iter_trans);
}
bool
OriginalLayerEdgePairs::empty () const
{
return m_iter.at_end ();
}
const db::EdgePair *
OriginalLayerEdgePairs::nth (size_t) const
{
tl_assert (false);
}
bool
OriginalLayerEdgePairs::has_valid_edge_pairs () const
{
return false;
}
const db::RecursiveShapeIterator *
OriginalLayerEdgePairs::iter () const
{
return &m_iter;
}
bool
OriginalLayerEdgePairs::equals (const EdgePairs &other) const
{
const OriginalLayerEdgePairs *other_delegate = dynamic_cast<const OriginalLayerEdgePairs *> (other.delegate ());
if (other_delegate && other_delegate->m_iter == m_iter && other_delegate->m_iter_trans == m_iter_trans) {
return true;
} else {
return AsIfFlatEdgePairs::equals (other);
}
}
bool
OriginalLayerEdgePairs::less (const EdgePairs &other) const
{
const OriginalLayerEdgePairs *other_delegate = dynamic_cast<const OriginalLayerEdgePairs *> (other.delegate ());
if (other_delegate && other_delegate->m_iter == m_iter && other_delegate->m_iter_trans == m_iter_trans) {
return false;
} else {
return AsIfFlatEdgePairs::less (other);
}
}
void
OriginalLayerEdgePairs::init ()
{
// .. nothing yet ..
}
}

View File

@ -0,0 +1,75 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2018 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
*/
#ifndef HDR_dbOriginalLayerEdgePairs
#define HDR_dbOriginalLayerEdgePairs
#include "dbCommon.h"
#include "dbAsIfFlatEdgePairs.h"
#include "dbShapes.h"
#include "dbRecursiveShapeIterator.h"
namespace db {
/**
* @brief An original layerregion based on a RecursiveShapeIterator
*/
class DB_PUBLIC OriginalLayerEdgePairs
: public AsIfFlatEdgePairs
{
public:
OriginalLayerEdgePairs ();
OriginalLayerEdgePairs (const OriginalLayerEdgePairs &other);
OriginalLayerEdgePairs (const RecursiveShapeIterator &si);
OriginalLayerEdgePairs (const RecursiveShapeIterator &si, const db::ICplxTrans &trans);
virtual ~OriginalLayerEdgePairs ();
EdgePairsDelegate *clone () const;
virtual EdgePairsIteratorDelegate *begin () const;
virtual std::pair<db::RecursiveShapeIterator, db::ICplxTrans> begin_iter () 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 bool equals (const EdgePairs &other) const;
virtual bool less (const EdgePairs &other) const;
private:
OriginalLayerEdgePairs &operator= (const OriginalLayerEdgePairs &other);
mutable db::RecursiveShapeIterator m_iter;
db::ICplxTrans m_iter_trans;
void init ();
};
}
#endif

View File

@ -1660,6 +1660,7 @@ public:
private:
friend class Edges;
friend class EdgePairs;
RegionDelegate *mp_delegate;

View File

@ -341,7 +341,7 @@ void insert (X &inserter, const db::Edges &data, const db::Box &tile, bool clip)
template <class X>
void insert (X &inserter, const db::EdgePairs &data, const db::Box &tile, bool clip)
{
for (db::EdgePairs::const_iterator o = data.begin (); o != data.end (); ++o) {
for (db::EdgePairs::const_iterator o = data.begin (); ! o.at_end (); ++o) {
insert (inserter, *o, tile, clip);
}
}

View File

@ -45,15 +45,6 @@ static std::string to_string1 (const db::EdgePairs *r, size_t n)
return r->to_string (n);
}
static const db::EdgePair *nth (const db::EdgePairs *r, size_t n)
{
if (n >= r->size ()) {
return 0;
} else {
return &r->begin ()[n];
}
}
static db::EdgePairs &move_p (db::EdgePairs *r, const db::Vector &p)
{
r->transform (db::Disp (p));
@ -94,7 +85,7 @@ static db::Region extents2 (const db::EdgePairs *r, db::Coord dx, db::Coord dy)
{
db::Region e;
e.reserve (r->size ());
for (db::EdgePairs::const_iterator i = r->begin (); i != r->end (); ++i) {
for (db::EdgePairs::const_iterator i = r->begin (); ! i.at_end (); ++i) {
e.insert (i->bbox ().enlarged (db::Vector (dx, dy)));
}
return e;
@ -133,7 +124,7 @@ static db::Edges second_edges (const db::EdgePairs *ep)
static void insert_e (db::EdgePairs *e, const db::EdgePairs &a)
{
for (db::EdgePairs::const_iterator p = a.begin (); p != a.end (); ++p) {
for (db::EdgePairs::const_iterator p = a.begin (); ! p.at_end (); ++p) {
e->insert (*p);
}
}
@ -339,10 +330,10 @@ Class<db::EdgePairs> decl_EdgePairs ("db", "EdgePairs",
method ("size", &db::EdgePairs::size,
"@brief Returns the number of edge pairs in this collection\n"
) +
gsi::iterator ("each", &db::EdgePairs::begin, &db::EdgePairs::end,
gsi::iterator ("each", &db::EdgePairs::begin,
"@brief Returns each edge pair of the edge pair collection\n"
) +
method_ext ("[]", &nth,
method ("[]", &db::EdgePairs::nth,
"@brief Returns the nth edge pair\n"
"@args n\n"
"\n"

View File

@ -338,7 +338,7 @@ static void insert_edges_with_dtrans (db::Shapes *sh, const db::Edges &r, const
static void insert_edge_pairs_as_polygons (db::Shapes *sh, const db::EdgePairs &r, db::Coord e)
{
for (db::EdgePairs::const_iterator s = r.begin (); s != r.end (); ++s) {
for (db::EdgePairs::const_iterator s = r.begin (); ! s.at_end (); ++s) {
sh->insert (s->normalized ().to_simple_polygon (e));
}
}
@ -346,14 +346,14 @@ static void insert_edge_pairs_as_polygons (db::Shapes *sh, const db::EdgePairs &
static void insert_edge_pairs_as_polygons_d (db::Shapes *sh, const db::EdgePairs &r, db::DCoord de)
{
db::Coord e = db::coord_traits<db::Coord>::rounded (de / shapes_dbu (sh));
for (db::EdgePairs::const_iterator s = r.begin (); s != r.end (); ++s) {
for (db::EdgePairs::const_iterator s = r.begin (); ! s.at_end (); ++s) {
sh->insert (s->normalized ().to_simple_polygon (e));
}
}
static void insert_edge_pairs_as_polygons_with_trans (db::Shapes *sh, const db::EdgePairs &r, const db::ICplxTrans &trans, db::Coord e)
{
for (db::EdgePairs::const_iterator s = r.begin (); s != r.end (); ++s) {
for (db::EdgePairs::const_iterator s = r.begin (); ! s.at_end (); ++s) {
sh->insert (s->normalized ().to_simple_polygon (e).transformed (trans));
}
}
@ -363,14 +363,14 @@ static void insert_edge_pairs_as_polygons_with_dtrans (db::Shapes *sh, const db:
db::Coord e = db::coord_traits<db::Coord>::rounded (de / shapes_dbu (sh));
db::CplxTrans dbu_trans (shapes_dbu (sh));
db::ICplxTrans itrans = dbu_trans.inverted () * trans * dbu_trans;
for (db::EdgePairs::const_iterator s = r.begin (); s != r.end (); ++s) {
for (db::EdgePairs::const_iterator s = r.begin (); ! s.at_end (); ++s) {
sh->insert (s->normalized ().to_simple_polygon (e).transformed (itrans));
}
}
static void insert_edge_pairs_as_edges (db::Shapes *sh, const db::EdgePairs &r)
{
for (db::EdgePairs::const_iterator s = r.begin (); s != r.end (); ++s) {
for (db::EdgePairs::const_iterator s = r.begin (); ! s.at_end (); ++s) {
sh->insert (s->first ());
sh->insert (s->second ());
}
@ -378,7 +378,7 @@ static void insert_edge_pairs_as_edges (db::Shapes *sh, const db::EdgePairs &r)
static void insert_edge_pairs_as_edges_with_trans (db::Shapes *sh, const db::EdgePairs &r, const db::ICplxTrans &trans)
{
for (db::EdgePairs::const_iterator s = r.begin (); s != r.end (); ++s) {
for (db::EdgePairs::const_iterator s = r.begin (); ! s.at_end (); ++s) {
sh->insert (s->first ().transformed (trans));
sh->insert (s->second ().transformed (trans));
}
@ -388,12 +388,35 @@ static void insert_edge_pairs_as_edges_with_dtrans (db::Shapes *sh, const db::Ed
{
db::CplxTrans dbu_trans (shapes_dbu (sh));
db::ICplxTrans itrans = dbu_trans.inverted () * trans * dbu_trans;
for (db::EdgePairs::const_iterator s = r.begin (); s != r.end (); ++s) {
for (db::EdgePairs::const_iterator s = r.begin (); ! s.at_end (); ++s) {
sh->insert (s->first ().transformed (itrans));
sh->insert (s->second ().transformed (itrans));
}
}
static void insert_edge_pairs (db::Shapes *sh, const db::EdgePairs &r)
{
for (db::EdgePairs::const_iterator s = r.begin (); ! s.at_end (); ++s) {
sh->insert (*s);
}
}
static void insert_edge_pairs_with_trans (db::Shapes *sh, const db::EdgePairs &r, const db::ICplxTrans &trans)
{
for (db::EdgePairs::const_iterator s = r.begin (); ! s.at_end (); ++s) {
sh->insert (s->transformed (trans));
}
}
static void insert_edge_pairs_with_dtrans (db::Shapes *sh, const db::EdgePairs &r, const db::DCplxTrans &trans)
{
db::CplxTrans dbu_trans (shapes_dbu (sh));
db::ICplxTrans itrans = dbu_trans.inverted () * trans * dbu_trans;
for (db::EdgePairs::const_iterator s = r.begin (); ! s.at_end (); ++s) {
sh->insert (s->transformed (itrans));
}
}
static unsigned int s_all () { return db::ShapeIterator::All; }
static unsigned int s_all_with_properties () { return db::ShapeIterator::AllWithProperties; }
static unsigned int s_properties () { return db::ShapeIterator::Properties; }
@ -551,6 +574,34 @@ Class<db::Shapes> decl_Shapes ("db", "Shapes",
"\n"
"This method has been introduced in version 0.25.\n"
) +
gsi::method_ext ("insert", &insert_edge_pairs, gsi::arg ("edge_pairs"),
"@brief Inserts the edges from the edge pair collection into this shape container\n"
"@param edges The edge pairs to insert\n"
"\n"
"This method inserts all edge pairs from the edge pair collection into this shape container.\n"
"\n"
"This method has been introduced in version 0.26.\n"
) +
gsi::method_ext ("insert", &insert_edge_pairs_with_trans, gsi::arg ("edge_pairs"), gsi::arg ("trans"),
"@brief Inserts the edge pairs from the edge pair collection into this shape container with a transformation\n"
"@param edges The edge pairs to insert\n"
"@param trans The transformation to apply\n"
"\n"
"This method inserts all edge pairs from the edge pair collection into this shape container.\n"
"Before an edge pair is inserted, the given transformation is applied.\n"
"\n"
"This method has been introduced in version 0.26.\n"
) +
gsi::method_ext ("insert", &insert_edge_pairs_with_dtrans, gsi::arg ("edge_pairs"), gsi::arg ("trans"),
"@brief Inserts the edge pairs from the edge pair collection into this shape container with a transformation (given in micrometer units)\n"
"@param edges The edge pairs to insert\n"
"@param trans The transformation to apply (displacement in micrometer units)\n"
"\n"
"This method inserts all edge pairs from the edge collection into this shape container.\n"
"Before an edge pair is inserted, the given transformation is applied.\n"
"\n"
"This method has been introduced in version 0.26.\n"
) +
gsi::method_ext ("insert_as_polygons", &insert_edge_pairs_as_polygons, gsi::arg ("edge_pairs"), gsi::arg ("e"),
"@brief Inserts the edge pairs from the edge pair collection as polygons into this shape container\n"
"@param edge_pairs The edge pairs to insert\n"

View File

@ -106,8 +106,9 @@ TEST(2)
}
struct EPTestFilter
: public db::EdgePairFilterBase
{
bool operator() (const db::EdgePair &ep)
bool selected (const db::EdgePair &ep) const
{
return ep.first ().double_length () < 50;
}

View File

@ -1024,7 +1024,7 @@ void create_items_from_edge_pairs (rdb::Database *db, rdb::id_type cell_id, rdb:
{
typedef db::EdgePairs::const_iterator iter;
for (iter o = collection.begin (); o != collection.end (); ++o) {
for (iter o = collection.begin (); ! o.at_end (); ++o) {
rdb::Item *item = db->create_item (cell_id, cat_id);
item->values ().add (new rdb::Value <db::DEdgePair> (o->transformed (trans)));
}