mirror of https://github.com/KLayout/klayout.git
WIP: refactoring, unify shape iterator
This commit is contained in:
parent
f05fd28a94
commit
26028cdeb9
|
|
@ -28,6 +28,7 @@ SOURCES = \
|
|||
dbEdges.cc \
|
||||
dbFillTool.cc \
|
||||
dbFuzzyCellMapping.cc \
|
||||
dbGenericShapeIterator.cc \
|
||||
dbGlyphs.cc \
|
||||
dbHershey.cc \
|
||||
dbInstances.cc \
|
||||
|
|
@ -63,6 +64,7 @@ SOURCES = \
|
|||
dbRegionLocalOperations.cc \
|
||||
dbSaveLayoutOptions.cc \
|
||||
dbShape.cc \
|
||||
dbShapeFlags.cc \
|
||||
dbShapes2.cc \
|
||||
dbShapes3.cc \
|
||||
dbShapes.cc \
|
||||
|
|
@ -224,6 +226,7 @@ HEADERS = \
|
|||
dbEdgesToContours.h \
|
||||
dbFillTool.h \
|
||||
dbFuzzyCellMapping.h \
|
||||
dbGenericShapeIterator.h \
|
||||
dbHash.h \
|
||||
dbHersheyFont.h \
|
||||
dbHershey.h \
|
||||
|
|
@ -263,6 +266,7 @@ HEADERS = \
|
|||
dbRegionLocalOperations.h \
|
||||
dbSaveLayoutOptions.h \
|
||||
dbShape.h \
|
||||
dbShapeFlags.h \
|
||||
dbShapeRepository.h \
|
||||
dbShapes2.h \
|
||||
dbShapeProcessor.h \
|
||||
|
|
|
|||
|
|
@ -79,11 +79,28 @@ public:
|
|||
return &m_polygon;
|
||||
}
|
||||
|
||||
virtual bool equals (const generic_shape_iterator_delegate_base<value_type> *other) const
|
||||
{
|
||||
const DeepRegionIterator *o = dynamic_cast<const DeepRegionIterator *> (other);
|
||||
return o && o->m_iter == m_iter;
|
||||
}
|
||||
|
||||
virtual RegionIteratorDelegate *clone () const
|
||||
{
|
||||
return new DeepRegionIterator (*this);
|
||||
}
|
||||
|
||||
virtual void do_reset (const db::Box ®ion, bool overlapping)
|
||||
{
|
||||
m_iter.set_region (region);
|
||||
m_iter.set_overlapping (overlapping);
|
||||
}
|
||||
|
||||
virtual db::Box bbox () const
|
||||
{
|
||||
return m_iter.bbox ();
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Region;
|
||||
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ FlatRegion::ensure_merged_polygons_valid () const
|
|||
|
||||
RegionIteratorDelegate *FlatRegion::begin () const
|
||||
{
|
||||
return new FlatRegionIterator (m_polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().begin (), m_polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().end ());
|
||||
return new FlatRegionIterator (&m_polygons);
|
||||
}
|
||||
|
||||
RegionIteratorDelegate *FlatRegion::begin_merged () const
|
||||
|
|
@ -151,7 +151,7 @@ RegionIteratorDelegate *FlatRegion::begin_merged () const
|
|||
return begin ();
|
||||
} else {
|
||||
ensure_merged_polygons_valid ();
|
||||
return new FlatRegionIterator (m_merged_polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().begin (), m_merged_polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().end ());
|
||||
return new FlatRegionIterator (&m_merged_polygons);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,44 +35,7 @@ namespace db {
|
|||
/**
|
||||
* @brief An iterator delegate for the flat region
|
||||
*/
|
||||
class DB_PUBLIC FlatRegionIterator
|
||||
: public RegionIteratorDelegate
|
||||
{
|
||||
public:
|
||||
typedef db::layer<db::Polygon, db::unstable_layer_tag> polygon_layer_type;
|
||||
typedef polygon_layer_type::iterator iterator_type;
|
||||
|
||||
FlatRegionIterator (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 RegionIteratorDelegate *clone () const
|
||||
{
|
||||
return new FlatRegionIterator (*this);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Region;
|
||||
|
||||
iterator_type m_from, m_to;
|
||||
};
|
||||
typedef generic_shapes_iterator_delegate<db::Polygon> FlatRegionIterator;
|
||||
|
||||
/**
|
||||
* @brief A flat, polygon-set delegate
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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 "dbGenericShapeIterator.h"
|
||||
|
|
@ -0,0 +1,322 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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_dbGenericShapeIterator
|
||||
#define HDR_dbGenericShapeIterator
|
||||
|
||||
#include "dbCommon.h"
|
||||
#include "dbShapes.h"
|
||||
#include "dbShapeFlags.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
template <class T>
|
||||
class DB_PUBLIC generic_shape_iterator_delegate_base
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
generic_shape_iterator_delegate_base () { }
|
||||
virtual ~generic_shape_iterator_delegate_base () { }
|
||||
|
||||
virtual void do_reset (const db::Box & /*region*/, bool /*overlapping*/) { }
|
||||
virtual db::Box bbox () const { return db::Box::world (); }
|
||||
virtual bool at_end () const = 0;
|
||||
virtual void increment () = 0;
|
||||
virtual const T *get () const = 0;
|
||||
virtual generic_shape_iterator_delegate_base<T> *clone () const = 0;
|
||||
virtual bool equals (const generic_shape_iterator_delegate_base<T> *other) const = 0;
|
||||
};
|
||||
|
||||
template <class Iter>
|
||||
class DB_PUBLIC generic_shape_iterator_delegate2
|
||||
: public generic_shape_iterator_delegate_base<typename Iter::value_type>
|
||||
{
|
||||
public:
|
||||
typedef typename Iter::value_type value_type;
|
||||
|
||||
generic_shape_iterator_delegate2 (const Iter &from, const Iter &to)
|
||||
: m_iter (from), m_from (from), m_to (to)
|
||||
{ }
|
||||
|
||||
virtual void do_reset (const db::Box &, bool)
|
||||
{
|
||||
m_iter = m_from;
|
||||
}
|
||||
|
||||
virtual bool at_end () const
|
||||
{
|
||||
return m_iter == m_to;
|
||||
}
|
||||
|
||||
virtual void increment ()
|
||||
{
|
||||
++m_iter;
|
||||
}
|
||||
|
||||
virtual const value_type *get () const
|
||||
{
|
||||
return m_iter.operator-> ();
|
||||
}
|
||||
|
||||
generic_shape_iterator_delegate_base<value_type> *clone () const
|
||||
{
|
||||
return new generic_shape_iterator_delegate2<Iter> (*this);
|
||||
}
|
||||
|
||||
virtual bool equals (const generic_shape_iterator_delegate_base<value_type> *other) const
|
||||
{
|
||||
const generic_shape_iterator_delegate2<Iter> *o = dynamic_cast<const generic_shape_iterator_delegate2<Iter> *> (other);
|
||||
return o && o->m_iter == m_iter;
|
||||
}
|
||||
|
||||
private:
|
||||
Iter m_iter, m_from, m_to;
|
||||
};
|
||||
|
||||
template <class Iter>
|
||||
class DB_PUBLIC generic_shape_iterator_delegate1
|
||||
: public generic_shape_iterator_delegate_base<typename Iter::value_type>
|
||||
{
|
||||
public:
|
||||
typedef typename Iter::value_type value_type;
|
||||
|
||||
generic_shape_iterator_delegate1 (const Iter &from)
|
||||
: m_iter (from), m_from (from)
|
||||
{ }
|
||||
|
||||
virtual void do_reset (const db::Box &, bool)
|
||||
{
|
||||
m_iter = m_from;
|
||||
}
|
||||
|
||||
virtual bool at_end () const
|
||||
{
|
||||
return m_iter.at_end ();
|
||||
}
|
||||
|
||||
virtual void increment ()
|
||||
{
|
||||
++m_iter;
|
||||
}
|
||||
|
||||
virtual const value_type *get () const
|
||||
{
|
||||
return m_iter.operator-> ();
|
||||
}
|
||||
|
||||
generic_shape_iterator_delegate_base<value_type> *clone () const
|
||||
{
|
||||
return new generic_shape_iterator_delegate1<Iter> (*this);
|
||||
}
|
||||
|
||||
virtual bool equals (const generic_shape_iterator_delegate_base<value_type> *other) const
|
||||
{
|
||||
const generic_shape_iterator_delegate1<Iter> *o = dynamic_cast<const generic_shape_iterator_delegate1<Iter> *> (other);
|
||||
return o && o->m_iter == m_iter;
|
||||
}
|
||||
|
||||
private:
|
||||
Iter m_iter, m_from;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class DB_PUBLIC generic_shapes_iterator_delegate
|
||||
: public generic_shape_iterator_delegate_base<T>
|
||||
{
|
||||
public:
|
||||
generic_shapes_iterator_delegate (const db::Shapes *shapes)
|
||||
: mp_shapes (shapes), m_iter (mp_shapes->begin (shape_flags<T> ()))
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual void do_reset (const db::Box &box, bool overlapping)
|
||||
{
|
||||
if (box == db::Box::world ()) {
|
||||
m_iter = mp_shapes->begin (shape_flags<T> ());
|
||||
} else {
|
||||
if (mp_shapes->is_bbox_dirty ()) {
|
||||
const_cast<db::Shapes *> (mp_shapes)->update ();
|
||||
}
|
||||
if (overlapping) {
|
||||
m_iter = mp_shapes->begin_overlapping (box, shape_flags<T> ());
|
||||
} else {
|
||||
m_iter = mp_shapes->begin_touching (box, shape_flags<T> ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool at_end () const
|
||||
{
|
||||
return m_iter.at_end ();
|
||||
}
|
||||
|
||||
virtual void increment ()
|
||||
{
|
||||
++m_iter;
|
||||
}
|
||||
|
||||
virtual const T *get () const
|
||||
{
|
||||
return m_iter->basic_ptr (typename T::tag ());
|
||||
}
|
||||
|
||||
generic_shape_iterator_delegate_base<T> *clone () const
|
||||
{
|
||||
return new generic_shapes_iterator_delegate<T> (*this);
|
||||
}
|
||||
|
||||
virtual db::Box bbox () const
|
||||
{
|
||||
if (mp_shapes->is_bbox_dirty ()) {
|
||||
const_cast<db::Shapes *> (mp_shapes)->update ();
|
||||
}
|
||||
return mp_shapes->bbox ();
|
||||
}
|
||||
|
||||
virtual bool equals (const generic_shape_iterator_delegate_base<T> *other) const
|
||||
{
|
||||
const generic_shapes_iterator_delegate<T> *o = dynamic_cast<const generic_shapes_iterator_delegate<T> *> (other);
|
||||
return o && o->mp_shapes == mp_shapes && o->m_iter.at_end () == m_iter.at_end () && (m_iter.at_end () || o->m_iter->basic_ptr (typename T::tag ()) == m_iter->basic_ptr (typename T::tag ()));
|
||||
}
|
||||
|
||||
private:
|
||||
const db::Shapes *mp_shapes;
|
||||
db::Shapes::shape_iterator m_iter;
|
||||
|
||||
generic_shapes_iterator_delegate (const generic_shapes_iterator_delegate &other)
|
||||
: mp_shapes (other.mp_shapes), m_iter (other.m_iter)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class DB_PUBLIC generic_shape_iterator
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef const value_type &reference;
|
||||
typedef const value_type *pointer;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
typedef void difference_type;
|
||||
|
||||
template <class Iter>
|
||||
generic_shape_iterator (const Iter &from, const Iter &to)
|
||||
: mp_delegate (new generic_shape_iterator_delegate2<Iter> (from, to))
|
||||
{ }
|
||||
|
||||
template <class Iter>
|
||||
generic_shape_iterator (const Iter &from)
|
||||
: mp_delegate (new generic_shape_iterator_delegate1<Iter> (from))
|
||||
{ }
|
||||
|
||||
generic_shape_iterator ()
|
||||
: mp_delegate (0)
|
||||
{ }
|
||||
|
||||
generic_shape_iterator (generic_shape_iterator_delegate_base<T> *delegate)
|
||||
: mp_delegate (delegate)
|
||||
{ }
|
||||
|
||||
generic_shape_iterator (const db::Shapes *shapes)
|
||||
: mp_delegate (new generic_shapes_iterator_delegate<T> (shapes))
|
||||
{ }
|
||||
|
||||
generic_shape_iterator (const generic_shape_iterator &other)
|
||||
: mp_delegate (other.mp_delegate ? other.mp_delegate->clone () : 0)
|
||||
{ }
|
||||
|
||||
~generic_shape_iterator ()
|
||||
{
|
||||
delete mp_delegate;
|
||||
}
|
||||
|
||||
generic_shape_iterator &operator= (const generic_shape_iterator &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
delete mp_delegate;
|
||||
mp_delegate = other.mp_delegate ? other.mp_delegate->clone () : 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator== (const generic_shape_iterator<T> &other) const
|
||||
{
|
||||
return mp_delegate && other.mp_delegate && mp_delegate->equals (other.mp_delegate);
|
||||
}
|
||||
|
||||
template <class TO>
|
||||
bool operator== (const generic_shape_iterator<TO> &) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
reference operator* () const
|
||||
{
|
||||
return *mp_delegate->get ();
|
||||
}
|
||||
|
||||
pointer operator-> () const
|
||||
{
|
||||
return mp_delegate->get ();
|
||||
}
|
||||
|
||||
generic_shape_iterator &operator++ ()
|
||||
{
|
||||
mp_delegate->increment ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool at_end () const
|
||||
{
|
||||
return !mp_delegate || mp_delegate->at_end ();
|
||||
}
|
||||
|
||||
void reset ()
|
||||
{
|
||||
if (mp_delegate) {
|
||||
mp_delegate->do_reset (db::Box::world (), false);
|
||||
}
|
||||
}
|
||||
|
||||
void reset (const db::Box &box, bool overlapping)
|
||||
{
|
||||
if (mp_delegate) {
|
||||
mp_delegate->do_reset (box, overlapping);
|
||||
}
|
||||
}
|
||||
|
||||
db::Box bbox () const
|
||||
{
|
||||
return mp_delegate ? mp_delegate->bbox () : db::Box ();
|
||||
}
|
||||
|
||||
public:
|
||||
generic_shape_iterator_delegate_base<T> *mp_delegate;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
#include "dbEdgeProcessor.h"
|
||||
#include "dbPolygonGenerators.h"
|
||||
#include "dbLocalOperationUtils.h"
|
||||
#include "dbShapeFlags.h"
|
||||
#include "tlLog.h"
|
||||
#include "tlTimer.h"
|
||||
#include "tlInternational.h"
|
||||
|
|
@ -1637,7 +1638,7 @@ struct scan_shape2shape_same_layer
|
|||
}
|
||||
|
||||
void
|
||||
operator () (const shapes_iterator<TS> &, unsigned int, unsigned int, shape_interactions<TS, TI> &, db::Coord) const
|
||||
operator () (const generic_shape_iterator<TS> &, unsigned int, unsigned int, shape_interactions<TS, TI> &, db::Coord) const
|
||||
{
|
||||
// cannot have different types on the same layer
|
||||
tl_assert (false);
|
||||
|
|
@ -1668,13 +1669,13 @@ struct scan_shape2shape_same_layer<T, T>
|
|||
}
|
||||
|
||||
void
|
||||
operator () (const shapes_iterator<T> &subjects, unsigned int subject_id0, unsigned int intruder_layer, shape_interactions<T, T> &interactions, db::Coord dist) const
|
||||
operator () (const generic_shape_iterator<T> &subjects, unsigned int subject_id0, unsigned int intruder_layer, shape_interactions<T, T> &interactions, db::Coord dist) const
|
||||
{
|
||||
db::box_scanner<T, int> scanner;
|
||||
interaction_registration_shape1<T, T> rec (&interactions, intruder_layer);
|
||||
|
||||
unsigned int id = subject_id0;
|
||||
for (shapes_iterator<T> i = subjects; !i.at_end (); ++i) {
|
||||
for (generic_shape_iterator<T> i = subjects; !i.at_end (); ++i) {
|
||||
scanner.insert (i.operator-> (), id++);
|
||||
}
|
||||
|
||||
|
|
@ -1715,7 +1716,7 @@ struct scan_shape2shape_different_layers
|
|||
}
|
||||
|
||||
void
|
||||
operator () (db::Layout *layout, const shapes_iterator<TS> &subjects, const shapes_iterator<TI> &intruders, unsigned int subject_id0, unsigned int intruder_layer, shape_interactions<TS, TI> &interactions, db::Coord dist) const
|
||||
operator () (db::Layout *layout, const generic_shape_iterator<TS> &subjects, const generic_shape_iterator<TI> &intruders, unsigned int subject_id0, unsigned int intruder_layer, shape_interactions<TS, TI> &interactions, db::Coord dist) const
|
||||
{
|
||||
db::box_scanner2<TS, int, TI, int> scanner;
|
||||
interaction_registration_shape2shape<TS, TI> rec (layout, &interactions, intruder_layer);
|
||||
|
|
@ -1737,13 +1738,13 @@ struct scan_shape2shape_different_layers
|
|||
|
||||
unsigned int id = subject_id0;
|
||||
|
||||
shapes_iterator<TS> is = subjects;
|
||||
generic_shape_iterator<TS> is = subjects;
|
||||
is.reset (common_box, true);
|
||||
for ( ; !is.at_end (); ++is) {
|
||||
scanner.insert1 (is.operator-> (), id++);
|
||||
}
|
||||
|
||||
shapes_iterator<TI> ii = intruders;
|
||||
generic_shape_iterator<TI> ii = intruders;
|
||||
ii.reset (common_box, true);
|
||||
for (; !ii.at_end (); ++ii) {
|
||||
scanner.insert2 (ii.operator-> (), interactions.next_id ());
|
||||
|
|
@ -1870,43 +1871,43 @@ template <class TS, class TI, class TR>
|
|||
void
|
||||
local_processor<TS, TI, TR>::run_flat (const db::Shapes *subject_shapes, const db::Shapes *intruders, const local_operation<TS, TI, TR> *op, db::Shapes *result_shapes) const
|
||||
{
|
||||
std::vector<shapes_iterator<TI> > is;
|
||||
is.push_back (shapes_iterator<TI> (intruders));
|
||||
std::vector<generic_shape_iterator<TI> > is;
|
||||
is.push_back (generic_shape_iterator<TI> (intruders));
|
||||
|
||||
std::vector<db::Shapes *> os;
|
||||
os.push_back (result_shapes);
|
||||
|
||||
run_flat (shapes_iterator<TS> (subject_shapes), is, op, os);
|
||||
run_flat (generic_shape_iterator<TS> (subject_shapes), is, op, os);
|
||||
}
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
void
|
||||
local_processor<TS, TI, TR>::run_flat (const db::Shapes *subject_shapes, const std::vector<const db::Shapes *> &intruders, const local_operation<TS, TI, TR> *op, const std::vector<db::Shapes *> &result_shapes) const
|
||||
{
|
||||
std::vector<shapes_iterator<TI> > is;
|
||||
std::vector<generic_shape_iterator<TI> > is;
|
||||
is.reserve (intruders.size ());
|
||||
for (std::vector<const db::Shapes *>::const_iterator i = intruders.begin (); i != intruders.end (); ++i) {
|
||||
is.push_back (shapes_iterator<TI> (*i));
|
||||
is.push_back (generic_shape_iterator<TI> (*i));
|
||||
}
|
||||
|
||||
run_flat (shapes_iterator<TS> (subject_shapes), is, op, result_shapes);
|
||||
run_flat (generic_shape_iterator<TS> (subject_shapes), is, op, result_shapes);
|
||||
}
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
void
|
||||
local_processor<TS, TI, TR>::run_flat (const shapes_iterator<TS> &subjects, const std::vector<shapes_iterator<TI> > &intruders, const local_operation<TS, TI, TR> *op, const std::vector<db::Shapes *> &result_shapes) const
|
||||
local_processor<TS, TI, TR>::run_flat (const generic_shape_iterator<TS> &subjects, const std::vector<generic_shape_iterator<TI> > &intruders, const local_operation<TS, TI, TR> *op, const std::vector<db::Shapes *> &result_shapes) const
|
||||
{
|
||||
tl_assert (mp_subject_top == 0);
|
||||
tl_assert (mp_intruder_top == 0);
|
||||
|
||||
shape_interactions<TS, TI> interactions;
|
||||
|
||||
for (typename std::vector<shapes_iterator<TI> >::const_iterator il = intruders.begin (); il != intruders.end (); ++il) {
|
||||
for (typename std::vector<generic_shape_iterator<TI> >::const_iterator il = intruders.begin (); il != intruders.end (); ++il) {
|
||||
|
||||
// insert dummy interactions to accommodate subject vs. nothing and assign an ID
|
||||
// range for the subject shapes.
|
||||
unsigned int subject_id0 = 0;
|
||||
for (shapes_iterator<TS> i = subjects; !i.at_end (); ++i) {
|
||||
for (generic_shape_iterator<TS> i = subjects; !i.at_end (); ++i) {
|
||||
|
||||
unsigned int id = interactions.next_id ();
|
||||
if (subject_id0 == 0) {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "dbLayout.h"
|
||||
#include "dbLocalOperation.h"
|
||||
#include "dbGenericShapeIterator.h"
|
||||
#include "tlThreadedWorkers.h"
|
||||
#include "tlProgress.h"
|
||||
|
||||
|
|
@ -371,290 +372,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
template <class T> unsigned int shape_flags ();
|
||||
|
||||
template <>
|
||||
inline unsigned int shape_flags<db::PolygonRef> ()
|
||||
{
|
||||
return 1 << db::ShapeIterator::PolygonRef;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned int shape_flags<db::Edge> ()
|
||||
{
|
||||
return db::ShapeIterator::Edges;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned int shape_flags<db::TextRef> ()
|
||||
{
|
||||
return db::ShapeIterator::Texts;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class DB_PUBLIC iterator_delegate_base
|
||||
{
|
||||
public:
|
||||
iterator_delegate_base () { }
|
||||
virtual ~iterator_delegate_base () { }
|
||||
|
||||
virtual void do_reset (const db::Box ®ion, bool overlapping) = 0;
|
||||
virtual db::Box bbox () const { return db::Box::world (); }
|
||||
virtual bool at_end () const = 0;
|
||||
virtual void inc () = 0;
|
||||
virtual const T *get () const = 0;
|
||||
virtual iterator_delegate_base<T> *clone () const = 0;
|
||||
virtual bool equals (const iterator_delegate_base<T> *other) const = 0;
|
||||
};
|
||||
|
||||
template <class Iter>
|
||||
class DB_PUBLIC iterator_delegate2
|
||||
: public iterator_delegate_base<typename Iter::value_type>
|
||||
{
|
||||
public:
|
||||
typedef typename Iter::value_type value_type;
|
||||
|
||||
iterator_delegate2 (const Iter &from, const Iter &to)
|
||||
: m_iter (from), m_from (from), m_to (to)
|
||||
{ }
|
||||
|
||||
virtual void do_reset (const db::Box &, bool)
|
||||
{
|
||||
m_iter = m_from;
|
||||
}
|
||||
|
||||
virtual bool at_end () const
|
||||
{
|
||||
return m_iter == m_to;
|
||||
}
|
||||
|
||||
virtual void inc ()
|
||||
{
|
||||
++m_iter;
|
||||
}
|
||||
|
||||
virtual const value_type *get () const
|
||||
{
|
||||
return m_iter.operator-> ();
|
||||
}
|
||||
|
||||
iterator_delegate_base<value_type> *clone () const
|
||||
{
|
||||
return new iterator_delegate2<Iter> (*this);
|
||||
}
|
||||
|
||||
virtual bool equals (const iterator_delegate_base<value_type> *other) const
|
||||
{
|
||||
const iterator_delegate2<Iter> *o = dynamic_cast<const iterator_delegate2<Iter> *> (other);
|
||||
return o && o->m_iter == m_iter;
|
||||
}
|
||||
|
||||
private:
|
||||
Iter m_iter, m_from, m_to;
|
||||
};
|
||||
|
||||
template <class Iter>
|
||||
class DB_PUBLIC iterator_delegate1
|
||||
: public iterator_delegate_base<typename Iter::value_type>
|
||||
{
|
||||
public:
|
||||
typedef typename Iter::value_type value_type;
|
||||
|
||||
iterator_delegate1 (const Iter &from)
|
||||
: m_iter (from), m_from (from)
|
||||
{ }
|
||||
|
||||
virtual void do_reset (const db::Box &, bool)
|
||||
{
|
||||
m_iter = m_from;
|
||||
}
|
||||
|
||||
virtual bool at_end () const
|
||||
{
|
||||
return m_iter.at_end ();
|
||||
}
|
||||
|
||||
virtual void inc ()
|
||||
{
|
||||
++m_iter;
|
||||
}
|
||||
|
||||
virtual const value_type &get () const
|
||||
{
|
||||
return *m_iter;
|
||||
}
|
||||
|
||||
iterator_delegate_base<value_type> *clone () const
|
||||
{
|
||||
return new iterator_delegate1<Iter> (*this);
|
||||
}
|
||||
|
||||
virtual bool equals (const iterator_delegate_base<value_type> *other) const
|
||||
{
|
||||
const iterator_delegate1<Iter> *o = dynamic_cast<const iterator_delegate1<Iter> *> (other);
|
||||
return o && o->m_iter == m_iter;
|
||||
}
|
||||
|
||||
private:
|
||||
Iter m_iter, m_from;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class DB_PUBLIC shapes_iterator_delegate
|
||||
: public iterator_delegate_base<T>
|
||||
{
|
||||
public:
|
||||
shapes_iterator_delegate (const db::Shapes *shapes)
|
||||
: mp_shapes (shapes), m_iter (mp_shapes->begin (shape_flags<T> ()))
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual void do_reset (const db::Box &box, bool overlapping)
|
||||
{
|
||||
if (box == db::Box::world ()) {
|
||||
m_iter = mp_shapes->begin (shape_flags<T> ());
|
||||
} else {
|
||||
if (mp_shapes->is_bbox_dirty ()) {
|
||||
const_cast<db::Shapes *> (mp_shapes)->update ();
|
||||
}
|
||||
if (overlapping) {
|
||||
m_iter = mp_shapes->begin_overlapping (box, shape_flags<T> ());
|
||||
} else {
|
||||
m_iter = mp_shapes->begin_touching (box, shape_flags<T> ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool at_end () const
|
||||
{
|
||||
return m_iter.at_end ();
|
||||
}
|
||||
|
||||
virtual void inc ()
|
||||
{
|
||||
++m_iter;
|
||||
}
|
||||
|
||||
virtual const T *get () const
|
||||
{
|
||||
return m_iter->basic_ptr (typename T::tag ());
|
||||
}
|
||||
|
||||
iterator_delegate_base<T> *clone () const
|
||||
{
|
||||
return new shapes_iterator_delegate<T> (*this);
|
||||
}
|
||||
|
||||
virtual db::Box bbox () const
|
||||
{
|
||||
if (mp_shapes->is_bbox_dirty ()) {
|
||||
const_cast<db::Shapes *> (mp_shapes)->update ();
|
||||
}
|
||||
return mp_shapes->bbox ();
|
||||
}
|
||||
|
||||
virtual bool equals (const iterator_delegate_base<T> *other) const
|
||||
{
|
||||
const shapes_iterator_delegate<T> *o = dynamic_cast<const shapes_iterator_delegate<T> *> (other);
|
||||
return o && o->mp_shapes == mp_shapes && o->m_iter.at_end () == m_iter.at_end () && (m_iter.at_end () || o->m_iter->basic_ptr (typename T::tag ()) == m_iter->basic_ptr (typename T::tag ()));
|
||||
}
|
||||
|
||||
private:
|
||||
const db::Shapes *mp_shapes;
|
||||
db::Shapes::shape_iterator m_iter;
|
||||
|
||||
shapes_iterator_delegate (const shapes_iterator_delegate &other)
|
||||
: mp_shapes (other.mp_shapes), m_iter (other.m_iter)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class DB_PUBLIC shapes_iterator
|
||||
{
|
||||
public:
|
||||
template <class Iter>
|
||||
shapes_iterator (const Iter &from, const Iter &to)
|
||||
: mp_delegate (new iterator_delegate2<Iter> (from, to))
|
||||
{ }
|
||||
|
||||
template <class Iter>
|
||||
shapes_iterator (const Iter &from)
|
||||
: mp_delegate (new iterator_delegate1<Iter> (from))
|
||||
{ }
|
||||
|
||||
shapes_iterator (const db::Shapes *shapes)
|
||||
: mp_delegate (new shapes_iterator_delegate<T> (shapes))
|
||||
{ }
|
||||
|
||||
shapes_iterator (const shapes_iterator<T> &other)
|
||||
: mp_delegate (other.mp_delegate->clone ())
|
||||
{ }
|
||||
|
||||
shapes_iterator &operator= (const shapes_iterator &other)
|
||||
{
|
||||
delete mp_delegate;
|
||||
mp_delegate = other.mp_delegate->clone ();
|
||||
}
|
||||
|
||||
bool operator== (const shapes_iterator<T> &other) const
|
||||
{
|
||||
return mp_delegate->equals (other.mp_delegate);
|
||||
}
|
||||
|
||||
template <class TO>
|
||||
bool operator== (const shapes_iterator<TO> &) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
~shapes_iterator ()
|
||||
{
|
||||
delete mp_delegate;
|
||||
}
|
||||
|
||||
const T &operator* () const
|
||||
{
|
||||
return *mp_delegate->get ();
|
||||
}
|
||||
|
||||
const T *operator-> () const
|
||||
{
|
||||
return mp_delegate->get ();
|
||||
}
|
||||
|
||||
shapes_iterator &operator++ ()
|
||||
{
|
||||
mp_delegate->inc ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool at_end () const
|
||||
{
|
||||
return mp_delegate->at_end ();
|
||||
}
|
||||
|
||||
void reset ()
|
||||
{
|
||||
mp_delegate->do_reset (db::Box::world (), false);
|
||||
}
|
||||
|
||||
void reset (const db::Box &box, bool overlapping)
|
||||
{
|
||||
mp_delegate->do_reset (box, overlapping);
|
||||
}
|
||||
|
||||
db::Box bbox () const
|
||||
{
|
||||
return mp_delegate->bbox ();
|
||||
}
|
||||
|
||||
public:
|
||||
iterator_delegate_base<T> *mp_delegate;
|
||||
};
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
class DB_PUBLIC local_processor
|
||||
{
|
||||
|
|
@ -669,7 +386,7 @@ public:
|
|||
|
||||
void run_flat (const db::Shapes *subject_shapes, const db::Shapes *intruders, const local_operation<TS, TI, TR> *op, db::Shapes *result_shapes) const;
|
||||
void run_flat (const db::Shapes *subjects, const std::vector<const db::Shapes *> &intruders, const local_operation<TS, TI, TR> *op, const std::vector<db::Shapes *> &result_shapes) const;
|
||||
void run_flat (const shapes_iterator<TS> &subjects, const std::vector<shapes_iterator<TI> > &intruders, const local_operation<TS, TI, TR> *op, const std::vector<db::Shapes *> &result_shapes) const;
|
||||
void run_flat (const generic_shape_iterator<TS> &subjects, const std::vector<generic_shape_iterator<TI> > &intruders, const local_operation<TS, TI, TR> *op, const std::vector<db::Shapes *> &result_shapes) const;
|
||||
|
||||
void set_description (const std::string &d)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ namespace
|
|||
|
||||
virtual void increment ()
|
||||
{
|
||||
inc ();
|
||||
do_increment ();
|
||||
set ();
|
||||
}
|
||||
|
||||
|
|
@ -71,6 +71,27 @@ namespace
|
|||
return new OriginalLayerRegionIterator (*this);
|
||||
}
|
||||
|
||||
virtual bool equals (const generic_shape_iterator_delegate_base<value_type> *other) const
|
||||
{
|
||||
const OriginalLayerRegionIterator *o = dynamic_cast<const OriginalLayerRegionIterator *> (other);
|
||||
return o && o->m_rec_iter == m_rec_iter && o->m_iter_trans.equal (m_iter_trans);
|
||||
}
|
||||
|
||||
virtual void do_reset (const db::Box ®ion, bool overlapping)
|
||||
{
|
||||
if (region == db::Box::world ()) {
|
||||
m_rec_iter.set_region (region);
|
||||
} else {
|
||||
m_rec_iter.set_region (m_iter_trans.inverted () * region);
|
||||
}
|
||||
m_rec_iter.set_overlapping (overlapping);
|
||||
}
|
||||
|
||||
virtual db::Box bbox () const
|
||||
{
|
||||
return m_iter_trans * m_rec_iter.bbox ();
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Region;
|
||||
|
||||
|
|
@ -89,7 +110,7 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
void inc ()
|
||||
void do_increment ()
|
||||
{
|
||||
if (! m_rec_iter.at_end ()) {
|
||||
++m_rec_iter;
|
||||
|
|
@ -172,7 +193,7 @@ OriginalLayerRegion::begin_merged () const
|
|||
return begin ();
|
||||
} else {
|
||||
ensure_merged_polygons_valid ();
|
||||
return new FlatRegionIterator (m_merged_polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().begin (), m_merged_polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().end ());
|
||||
return new FlatRegionIterator (& m_merged_polygons);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,19 +47,14 @@ class TransformationReducer;
|
|||
* The iterator delivers the polygons of the region
|
||||
*/
|
||||
class DB_PUBLIC RegionIterator
|
||||
: public generic_shape_iterator<db::Polygon>
|
||||
{
|
||||
public:
|
||||
typedef RegionIteratorDelegate::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
|
||||
*/
|
||||
RegionIterator ()
|
||||
: mp_delegate (0)
|
||||
: generic_shape_iterator<db::Polygon> ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -69,27 +64,18 @@ public:
|
|||
* The iterator will take ownership over the delegate
|
||||
*/
|
||||
RegionIterator (RegionIteratorDelegate *delegate)
|
||||
: mp_delegate (delegate)
|
||||
: generic_shape_iterator<db::Polygon> (delegate)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~RegionIterator ()
|
||||
{
|
||||
delete mp_delegate;
|
||||
mp_delegate = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy constructor and assignment
|
||||
*/
|
||||
RegionIterator (const RegionIterator &other)
|
||||
: mp_delegate (0)
|
||||
: generic_shape_iterator<db::Polygon> (static_cast<const generic_shape_iterator<db::Polygon> &> (other))
|
||||
{
|
||||
operator= (other);
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -97,52 +83,18 @@ public:
|
|||
*/
|
||||
RegionIterator &operator= (const RegionIterator &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
delete mp_delegate;
|
||||
mp_delegate = other.mp_delegate ? other.mp_delegate->clone () : 0;
|
||||
}
|
||||
generic_shape_iterator<db::Polygon>::operator= (other);
|
||||
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
|
||||
*/
|
||||
RegionIterator &operator++ ()
|
||||
{
|
||||
if (mp_delegate) {
|
||||
mp_delegate->increment ();
|
||||
}
|
||||
generic_shape_iterator<db::Polygon>::operator++ ();
|
||||
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:
|
||||
RegionIteratorDelegate *mp_delegate;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include "dbEdgePairs.h"
|
||||
#include "dbEdgePairRelations.h"
|
||||
#include "dbShapeCollection.h"
|
||||
#include "dbGenericShapeIterator.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
|
|
@ -142,19 +143,7 @@ typedef shape_collection_processor<db::Polygon, db::EdgePair> PolygonToEdgePairP
|
|||
/**
|
||||
* @brief The region iterator delegate
|
||||
*/
|
||||
class DB_PUBLIC RegionIteratorDelegate
|
||||
{
|
||||
public:
|
||||
RegionIteratorDelegate () { }
|
||||
virtual ~RegionIteratorDelegate () { }
|
||||
|
||||
typedef db::Polygon value_type;
|
||||
|
||||
virtual bool at_end () const = 0;
|
||||
virtual void increment () = 0;
|
||||
virtual const value_type *get () const = 0;
|
||||
virtual RegionIteratorDelegate *clone () const = 0;
|
||||
};
|
||||
typedef db::generic_shape_iterator_delegate_base <db::Polygon> RegionIteratorDelegate;
|
||||
|
||||
/**
|
||||
* @brief The delegate for the actual region implementation
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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 "dbShapeFlags.h"
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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_dbShapeFlags
|
||||
#define HDR_dbShapeFlags
|
||||
|
||||
#include "dbCommon.h"
|
||||
#include "dbShapes.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
template <class T> unsigned int shape_flags ();
|
||||
|
||||
template <>
|
||||
inline unsigned int shape_flags<db::PolygonRef> ()
|
||||
{
|
||||
return 1 << db::ShapeIterator::PolygonRef;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned int shape_flags<db::Box> ()
|
||||
{
|
||||
return 1 << db::ShapeIterator::Box;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned int shape_flags<db::Path> ()
|
||||
{
|
||||
return 1 << db::ShapeIterator::Path;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned int shape_flags<db::Polygon> ()
|
||||
{
|
||||
return 1 << db::ShapeIterator::Polygon;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned int shape_flags<db::Edge> ()
|
||||
{
|
||||
return 1 << db::ShapeIterator::Edge;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned int shape_flags<db::Text> ()
|
||||
{
|
||||
return 1 << db::ShapeIterator::Text;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned int shape_flags<db::TextRef> ()
|
||||
{
|
||||
return 1 << db::ShapeIterator::TextRef;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue