mirror of https://github.com/KLayout/klayout.git
WIP: some refactoring of the flat local processor mode for generalization
This commit is contained in:
parent
ec01c9b72b
commit
f05fd28a94
|
|
@ -259,8 +259,8 @@ protected:
|
||||||
void update_bbox (const db::Box &box);
|
void update_bbox (const db::Box &box);
|
||||||
void invalidate_bbox ();
|
void invalidate_bbox ();
|
||||||
|
|
||||||
EdgePairsDelegate *run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const;
|
virtual EdgePairsDelegate *run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const;
|
||||||
EdgePairsDelegate *run_single_polygon_check (db::edge_relation_type rel, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const;
|
virtual EdgePairsDelegate *run_single_polygon_check (db::edge_relation_type rel, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const;
|
||||||
virtual RegionDelegate *selected_interacting_generic (const Region &other, int mode, bool touching, bool inverse, size_t min_count = 1, size_t max_count = std::numeric_limits<size_t>::max ()) const;
|
virtual RegionDelegate *selected_interacting_generic (const Region &other, int mode, bool touching, bool inverse, size_t min_count = 1, size_t max_count = std::numeric_limits<size_t>::max ()) const;
|
||||||
virtual RegionDelegate *selected_interacting_generic (const Edges &other, bool inverse, size_t min_count = 1, size_t max_count = std::numeric_limits<size_t>::max ()) const;
|
virtual RegionDelegate *selected_interacting_generic (const Edges &other, bool inverse, size_t min_count = 1, size_t max_count = std::numeric_limits<size_t>::max ()) const;
|
||||||
virtual RegionDelegate *selected_interacting_generic (const Texts &other, bool inverse, size_t min_count = 1, size_t max_count = std::numeric_limits<size_t>::max ()) const;
|
virtual RegionDelegate *selected_interacting_generic (const Texts &other, bool inverse, size_t min_count = 1, size_t max_count = std::numeric_limits<size_t>::max ()) const;
|
||||||
|
|
|
||||||
|
|
@ -88,46 +88,6 @@ public:
|
||||||
virtual RegionDelegate *add_in_place (const Region &other);
|
virtual RegionDelegate *add_in_place (const Region &other);
|
||||||
virtual RegionDelegate *add (const Region &other) const;
|
virtual RegionDelegate *add (const Region &other) const;
|
||||||
|
|
||||||
EdgePairsDelegate *width_check (db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const
|
|
||||||
{
|
|
||||||
return run_single_polygon_check (db::WidthRelation, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded);
|
|
||||||
}
|
|
||||||
|
|
||||||
EdgePairsDelegate *space_check (db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const
|
|
||||||
{
|
|
||||||
return run_check (db::SpaceRelation, false, 0, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded);
|
|
||||||
}
|
|
||||||
|
|
||||||
EdgePairsDelegate *isolated_check (db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const
|
|
||||||
{
|
|
||||||
return run_check (db::SpaceRelation, true, 0, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded);
|
|
||||||
}
|
|
||||||
|
|
||||||
EdgePairsDelegate *notch_check (db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const
|
|
||||||
{
|
|
||||||
return run_single_polygon_check (db::SpaceRelation, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded);
|
|
||||||
}
|
|
||||||
|
|
||||||
EdgePairsDelegate *enclosing_check (const Region &other, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const
|
|
||||||
{
|
|
||||||
return run_check (db::OverlapRelation, true, &other, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded);
|
|
||||||
}
|
|
||||||
|
|
||||||
EdgePairsDelegate *overlap_check (const Region &other, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const
|
|
||||||
{
|
|
||||||
return run_check (db::WidthRelation, true, &other, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded);
|
|
||||||
}
|
|
||||||
|
|
||||||
EdgePairsDelegate *separation_check (const Region &other, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const
|
|
||||||
{
|
|
||||||
return run_check (db::SpaceRelation, true, &other, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded);
|
|
||||||
}
|
|
||||||
|
|
||||||
EdgePairsDelegate *inside_check (const Region &other, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection, bool shielded) const
|
|
||||||
{
|
|
||||||
return run_check (db::InsideRelation, true, &other, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual EdgePairsDelegate *grid_check (db::Coord gx, db::Coord gy) const;
|
virtual EdgePairsDelegate *grid_check (db::Coord gx, db::Coord gy) const;
|
||||||
virtual EdgePairsDelegate *angle_check (double min, double max, bool inverse) const;
|
virtual EdgePairsDelegate *angle_check (double min, double max, bool inverse) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -670,26 +670,6 @@ template class DB_PUBLIC shape_interactions<db::TextRef, db::PolygonRef>;
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
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 TS, class TI>
|
template <class TS, class TI>
|
||||||
struct interaction_registration_shape2shape
|
struct interaction_registration_shape2shape
|
||||||
: db::box_scanner_receiver2<TS, unsigned int, TI, unsigned int>
|
: db::box_scanner_receiver2<TS, unsigned int, TI, unsigned int>
|
||||||
|
|
@ -1657,7 +1637,7 @@ struct scan_shape2shape_same_layer
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
operator () (const db::Shapes *, unsigned int, unsigned int, shape_interactions<TS, TI> &, db::Coord) const
|
operator () (const shapes_iterator<TS> &, unsigned int, unsigned int, shape_interactions<TS, TI> &, db::Coord) const
|
||||||
{
|
{
|
||||||
// cannot have different types on the same layer
|
// cannot have different types on the same layer
|
||||||
tl_assert (false);
|
tl_assert (false);
|
||||||
|
|
@ -1688,15 +1668,14 @@ struct scan_shape2shape_same_layer<T, T>
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
operator () (const db::Shapes *shapes, unsigned int subject_id0, unsigned int intruder_layer, shape_interactions<T, T> &interactions, db::Coord dist) const
|
operator () (const shapes_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;
|
db::box_scanner<T, int> scanner;
|
||||||
interaction_registration_shape1<T, T> rec (&interactions, intruder_layer);
|
interaction_registration_shape1<T, T> rec (&interactions, intruder_layer);
|
||||||
|
|
||||||
unsigned int id = subject_id0;
|
unsigned int id = subject_id0;
|
||||||
for (db::Shapes::shape_iterator i = shapes->begin (shape_flags<T> ()); !i.at_end (); ++i) {
|
for (shapes_iterator<T> i = subjects; !i.at_end (); ++i) {
|
||||||
const T *ref = i->basic_ptr (typename T::tag ());
|
scanner.insert (i.operator-> (), id++);
|
||||||
scanner.insert (ref, id++);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scanner.process (rec, dist, db::box_convert<T> ());
|
scanner.process (rec, dist, db::box_convert<T> ());
|
||||||
|
|
@ -1734,6 +1713,44 @@ struct scan_shape2shape_different_layers
|
||||||
|
|
||||||
scanner.process (rec, dist, db::box_convert<TS> (), db::box_convert<TI> ());
|
scanner.process (rec, dist, db::box_convert<TS> (), db::box_convert<TI> ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
db::box_scanner2<TS, int, TI, int> scanner;
|
||||||
|
interaction_registration_shape2shape<TS, TI> rec (layout, &interactions, intruder_layer);
|
||||||
|
|
||||||
|
db::Box subjects_box = subjects.bbox ();
|
||||||
|
if (subjects_box != db::Box::world ()) {
|
||||||
|
subjects_box.enlarge (db::Vector (dist, dist));
|
||||||
|
}
|
||||||
|
|
||||||
|
db::Box intruders_box = intruders.bbox ();
|
||||||
|
if (intruders_box != db::Box::world ()) {
|
||||||
|
intruders_box.enlarge (db::Vector (dist, dist));
|
||||||
|
}
|
||||||
|
|
||||||
|
db::Box common_box = intruders_box & subjects_box;
|
||||||
|
if (common_box.empty ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int id = subject_id0;
|
||||||
|
|
||||||
|
shapes_iterator<TS> is = subjects;
|
||||||
|
is.reset (common_box, true);
|
||||||
|
for ( ; !is.at_end (); ++is) {
|
||||||
|
scanner.insert1 (is.operator-> (), id++);
|
||||||
|
}
|
||||||
|
|
||||||
|
shapes_iterator<TI> ii = intruders;
|
||||||
|
ii.reset (common_box, true);
|
||||||
|
for (; !ii.at_end (); ++ii) {
|
||||||
|
scanner.insert2 (ii.operator-> (), interactions.next_id ());
|
||||||
|
}
|
||||||
|
|
||||||
|
scanner.process (rec, dist, db::box_convert<TS> (), db::box_convert<TI> ());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class TS, class TI, class TR>
|
template <class TS, class TI, class TR>
|
||||||
|
|
@ -1853,32 +1870,43 @@ template <class TS, class TI, class TR>
|
||||||
void
|
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
|
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<const db::Shapes *> is;
|
std::vector<shapes_iterator<TI> > is;
|
||||||
is.push_back (intruders);
|
is.push_back (shapes_iterator<TI> (intruders));
|
||||||
|
|
||||||
std::vector<db::Shapes *> os;
|
std::vector<db::Shapes *> os;
|
||||||
os.push_back (result_shapes);
|
os.push_back (result_shapes);
|
||||||
|
|
||||||
run_flat (subject_shapes, is, op, os);
|
run_flat (shapes_iterator<TS> (subject_shapes), is, op, os);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class TS, class TI, class TR>
|
template <class TS, class TI, class TR>
|
||||||
void
|
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
|
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;
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
run_flat (shapes_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
|
||||||
{
|
{
|
||||||
tl_assert (mp_subject_top == 0);
|
tl_assert (mp_subject_top == 0);
|
||||||
tl_assert (mp_intruder_top == 0);
|
tl_assert (mp_intruder_top == 0);
|
||||||
|
|
||||||
shape_interactions<TS, TI> interactions;
|
shape_interactions<TS, TI> interactions;
|
||||||
|
|
||||||
for (std::vector<const db::Shapes *>::const_iterator il = intruders.begin (); il != intruders.end (); ++il) {
|
for (typename std::vector<shapes_iterator<TI> >::const_iterator il = intruders.begin (); il != intruders.end (); ++il) {
|
||||||
|
|
||||||
const db::Shapes *intruder_shapes = *il;
|
|
||||||
|
|
||||||
// insert dummy interactions to accommodate subject vs. nothing and assign an ID
|
// insert dummy interactions to accommodate subject vs. nothing and assign an ID
|
||||||
// range for the subject shapes.
|
// range for the subject shapes.
|
||||||
unsigned int subject_id0 = 0;
|
unsigned int subject_id0 = 0;
|
||||||
for (db::Shapes::shape_iterator i = subject_shapes->begin (shape_flags<TS> ()); !i.at_end (); ++i) {
|
for (shapes_iterator<TS> i = subjects; !i.at_end (); ++i) {
|
||||||
|
|
||||||
unsigned int id = interactions.next_id ();
|
unsigned int id = interactions.next_id ();
|
||||||
if (subject_id0 == 0) {
|
if (subject_id0 == 0) {
|
||||||
|
|
@ -1886,20 +1914,19 @@ local_processor<TS, TI, TR>::run_flat (const db::Shapes *subject_shapes, const s
|
||||||
}
|
}
|
||||||
|
|
||||||
if (op->on_empty_intruder_hint () != local_operation<TS, TI, TR>::Drop) {
|
if (op->on_empty_intruder_hint () != local_operation<TS, TI, TR>::Drop) {
|
||||||
const TS *ref = i->basic_ptr (typename TS::tag ());
|
interactions.add_subject (id, *i);
|
||||||
interactions.add_subject (id, *ref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::set<TI> empty_intruders;
|
static std::set<TI> empty_intruders;
|
||||||
|
|
||||||
if (! subject_shapes->empty () && intruder_shapes) {
|
if (! subjects.at_end ()) {
|
||||||
|
|
||||||
if (intruder_shapes == subject_shapes) {
|
if (*il == subjects) {
|
||||||
scan_shape2shape_same_layer<TS, TI> () (subject_shapes, subject_id0, (unsigned int) (il - intruders.begin ()), interactions, op->dist ());
|
scan_shape2shape_same_layer<TS, TI> () (subjects, subject_id0, (unsigned int) (il - intruders.begin ()), interactions, op->dist ());
|
||||||
} else {
|
} else {
|
||||||
scan_shape2shape_different_layers<TS, TI> () (0 /*layout*/, subject_shapes, intruder_shapes, subject_id0, 0 /*ext. intruders*/, (unsigned int) (il - intruders.begin ()), interactions, op->dist ());
|
scan_shape2shape_different_layers<TS, TI> () (0 /*layout*/, subjects, *il, subject_id0, (unsigned int) (il - intruders.begin ()), interactions, op->dist ());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -371,6 +371,290 @@ 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>
|
template <class TS, class TI, class TR>
|
||||||
class DB_PUBLIC local_processor
|
class DB_PUBLIC local_processor
|
||||||
{
|
{
|
||||||
|
|
@ -385,6 +669,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 *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 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 set_description (const std::string &d)
|
void set_description (const std::string &d)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue