mirror of https://github.com/KLayout/klayout.git
WIP complex regions for RecursiveShapeIterator
* Refactoring: no more "box+exclude" regions - they can be emulated using a NOT with the same result * "confinement" of regions inside recursive shape iterators * setters and getters for complex regions in GSI, confinement * more unit tests, some bug fixes
This commit is contained in:
parent
fb6cf92b15
commit
320e96f6da
|
|
@ -31,6 +31,62 @@ namespace db
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// Recursive shape iterator implementation
|
// Recursive shape iterator implementation
|
||||||
|
|
||||||
|
RecursiveShapeIterator::RecursiveShapeIterator (const RecursiveShapeIterator &d)
|
||||||
|
{
|
||||||
|
operator= (d);
|
||||||
|
}
|
||||||
|
|
||||||
|
RecursiveShapeIterator &RecursiveShapeIterator::operator= (const RecursiveShapeIterator &d)
|
||||||
|
{
|
||||||
|
if (&d != this) {
|
||||||
|
|
||||||
|
m_layers = d.m_layers;
|
||||||
|
m_has_layers = d.m_has_layers;
|
||||||
|
m_max_depth = d.m_max_depth;
|
||||||
|
m_min_depth = d.m_min_depth;
|
||||||
|
m_shape_flags = d.m_shape_flags;
|
||||||
|
mp_shape_prop_sel = d.mp_shape_prop_sel;
|
||||||
|
m_shape_inv_prop_sel = d.m_shape_inv_prop_sel;
|
||||||
|
m_overlapping = d.m_overlapping;
|
||||||
|
m_start = d.m_start;
|
||||||
|
m_stop = d.m_stop;
|
||||||
|
|
||||||
|
mp_layout = d.mp_layout;
|
||||||
|
mp_top_cell = d.mp_top_cell;
|
||||||
|
mp_shapes = d.mp_shapes;
|
||||||
|
|
||||||
|
m_region = d.m_region;
|
||||||
|
if (d.mp_complex_region.get () != 0) {
|
||||||
|
mp_complex_region.reset (new region_type (*d.mp_complex_region.get ()));
|
||||||
|
} else {
|
||||||
|
mp_complex_region.reset (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_box_convert = d.m_box_convert;
|
||||||
|
|
||||||
|
m_inst = d.m_inst;
|
||||||
|
m_inst_array = d.m_inst_array;
|
||||||
|
m_empty_cells_cache = d.m_empty_cells_cache;
|
||||||
|
m_layer = d.m_layer;
|
||||||
|
mp_cell = d.mp_cell;
|
||||||
|
m_current_layer = d.m_current_layer;
|
||||||
|
m_shape = d.m_shape;
|
||||||
|
m_trans = d.m_trans;
|
||||||
|
m_trans_stack = d.m_trans_stack;
|
||||||
|
m_inst_iterators = d.m_inst_iterators;
|
||||||
|
m_inst_array_iterators = d.m_inst_array_iterators;
|
||||||
|
m_cells = d.m_cells;
|
||||||
|
m_local_complex_region_stack = d.m_local_complex_region_stack;
|
||||||
|
m_local_region_stack = d.m_local_region_stack;
|
||||||
|
m_needs_reinit = d.m_needs_reinit;
|
||||||
|
m_inst_quad_id = d.m_inst_quad_id;
|
||||||
|
m_inst_quad_id_stack = d.m_inst_quad_id_stack;
|
||||||
|
m_shape_quad_id = d.m_shape_quad_id;
|
||||||
|
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
RecursiveShapeIterator::RecursiveShapeIterator ()
|
RecursiveShapeIterator::RecursiveShapeIterator ()
|
||||||
{
|
{
|
||||||
// anything. Not necessary reasonable.
|
// anything. Not necessary reasonable.
|
||||||
|
|
@ -54,50 +110,36 @@ RecursiveShapeIterator::RecursiveShapeIterator (const shapes_type &shapes)
|
||||||
{
|
{
|
||||||
m_layer = 0;
|
m_layer = 0;
|
||||||
m_has_layers = false;
|
m_has_layers = false;
|
||||||
m_region = box_type::world ();
|
|
||||||
mp_layout = 0;
|
mp_layout = 0;
|
||||||
mp_shapes = &shapes;
|
mp_shapes = &shapes;
|
||||||
mp_top_cell = 0;
|
mp_top_cell = 0;
|
||||||
m_overlapping = false;
|
m_overlapping = false;
|
||||||
init ();
|
init ();
|
||||||
|
init_region (box_type::world ());
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursiveShapeIterator::RecursiveShapeIterator (const shapes_type &shapes, const box_type ®ion, bool overlapping)
|
RecursiveShapeIterator::RecursiveShapeIterator (const shapes_type &shapes, const box_type ®ion, bool overlapping)
|
||||||
{
|
{
|
||||||
m_layer = 0;
|
m_layer = 0;
|
||||||
m_has_layers = false;
|
m_has_layers = false;
|
||||||
m_region = region;
|
|
||||||
mp_layout = 0;
|
mp_layout = 0;
|
||||||
mp_shapes = &shapes;
|
mp_shapes = &shapes;
|
||||||
mp_top_cell = 0;
|
mp_top_cell = 0;
|
||||||
m_overlapping = overlapping;
|
m_overlapping = overlapping;
|
||||||
init ();
|
init ();
|
||||||
|
init_region (region);
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursiveShapeIterator::RecursiveShapeIterator (const shapes_type &shapes, const region_type ®ion, bool overlapping)
|
RecursiveShapeIterator::RecursiveShapeIterator (const shapes_type &shapes, const region_type ®ion, bool overlapping)
|
||||||
{
|
{
|
||||||
m_layer = 0;
|
m_layer = 0;
|
||||||
m_has_layers = false;
|
m_has_layers = false;
|
||||||
m_region = region.bbox ();
|
|
||||||
mp_layout = 0;
|
mp_layout = 0;
|
||||||
mp_shapes = &shapes;
|
mp_shapes = &shapes;
|
||||||
mp_top_cell = 0;
|
mp_top_cell = 0;
|
||||||
m_overlapping = overlapping;
|
m_overlapping = overlapping;
|
||||||
init ();
|
init ();
|
||||||
init_complex_region (region);
|
init_region (region);
|
||||||
}
|
|
||||||
|
|
||||||
RecursiveShapeIterator::RecursiveShapeIterator (const shapes_type &shapes, const box_type ®ion, const region_type &excl_region, bool overlapping)
|
|
||||||
{
|
|
||||||
m_layer = 0;
|
|
||||||
m_has_layers = false;
|
|
||||||
m_region = region;
|
|
||||||
mp_layout = 0;
|
|
||||||
mp_shapes = &shapes;
|
|
||||||
mp_top_cell = 0;
|
|
||||||
m_overlapping = overlapping;
|
|
||||||
init ();
|
|
||||||
init_complex_region (region, excl_region);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, unsigned int layer, const box_type ®ion, bool overlapping)
|
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, unsigned int layer, const box_type ®ion, bool overlapping)
|
||||||
|
|
@ -105,12 +147,12 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
|
||||||
{
|
{
|
||||||
m_layer = layer;
|
m_layer = layer;
|
||||||
m_has_layers = false;
|
m_has_layers = false;
|
||||||
m_region = region;
|
|
||||||
mp_layout = &layout;
|
mp_layout = &layout;
|
||||||
mp_shapes = 0;
|
mp_shapes = 0;
|
||||||
mp_top_cell = &cell;
|
mp_top_cell = &cell;
|
||||||
m_overlapping = overlapping;
|
m_overlapping = overlapping;
|
||||||
init ();
|
init ();
|
||||||
|
init_region (region);
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, unsigned int layer, const region_type ®ion, bool overlapping)
|
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, unsigned int layer, const region_type ®ion, bool overlapping)
|
||||||
|
|
@ -118,27 +160,12 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
|
||||||
{
|
{
|
||||||
m_layer = layer;
|
m_layer = layer;
|
||||||
m_has_layers = false;
|
m_has_layers = false;
|
||||||
m_region = region.bbox ();
|
|
||||||
mp_layout = &layout;
|
mp_layout = &layout;
|
||||||
mp_shapes = 0;
|
mp_shapes = 0;
|
||||||
mp_top_cell = &cell;
|
mp_top_cell = &cell;
|
||||||
m_overlapping = overlapping;
|
m_overlapping = overlapping;
|
||||||
init ();
|
init ();
|
||||||
init_complex_region (region);
|
init_region (region);
|
||||||
}
|
|
||||||
|
|
||||||
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, unsigned int layer, const box_type ®ion, const region_type &excl_region, bool overlapping)
|
|
||||||
: m_box_convert (layout, layer)
|
|
||||||
{
|
|
||||||
m_layer = layer;
|
|
||||||
m_has_layers = false;
|
|
||||||
m_region = region;
|
|
||||||
mp_layout = &layout;
|
|
||||||
mp_shapes = 0;
|
|
||||||
mp_top_cell = &cell;
|
|
||||||
m_overlapping = overlapping;
|
|
||||||
init ();
|
|
||||||
init_complex_region (region, excl_region);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, unsigned int layer)
|
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, unsigned int layer)
|
||||||
|
|
@ -146,12 +173,12 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
|
||||||
{
|
{
|
||||||
m_layer = layer;
|
m_layer = layer;
|
||||||
m_has_layers = false;
|
m_has_layers = false;
|
||||||
m_region = box_type::world ();
|
|
||||||
mp_layout = &layout;
|
mp_layout = &layout;
|
||||||
mp_shapes = 0;
|
mp_shapes = 0;
|
||||||
mp_top_cell = &cell;
|
mp_top_cell = &cell;
|
||||||
m_overlapping = false;
|
m_overlapping = false;
|
||||||
init ();
|
init ();
|
||||||
|
init_region (box_type::world ());
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::vector<unsigned int> &layers, const box_type ®ion, bool overlapping)
|
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::vector<unsigned int> &layers, const box_type ®ion, bool overlapping)
|
||||||
|
|
@ -160,12 +187,12 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
|
||||||
m_layer = 0;
|
m_layer = 0;
|
||||||
m_layers = layers;
|
m_layers = layers;
|
||||||
m_has_layers = true;
|
m_has_layers = true;
|
||||||
m_region = region;
|
|
||||||
mp_layout = &layout;
|
mp_layout = &layout;
|
||||||
mp_shapes = 0;
|
mp_shapes = 0;
|
||||||
mp_top_cell = &cell;
|
mp_top_cell = &cell;
|
||||||
m_overlapping = overlapping;
|
m_overlapping = overlapping;
|
||||||
init ();
|
init ();
|
||||||
|
init_region (region);
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::vector<unsigned int> &layers, const region_type ®ion, bool overlapping)
|
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::vector<unsigned int> &layers, const region_type ®ion, bool overlapping)
|
||||||
|
|
@ -174,28 +201,12 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
|
||||||
m_layer = 0;
|
m_layer = 0;
|
||||||
m_layers = layers;
|
m_layers = layers;
|
||||||
m_has_layers = true;
|
m_has_layers = true;
|
||||||
m_region = region.bbox ();
|
|
||||||
mp_layout = &layout;
|
mp_layout = &layout;
|
||||||
mp_shapes = 0;
|
mp_shapes = 0;
|
||||||
mp_top_cell = &cell;
|
mp_top_cell = &cell;
|
||||||
m_overlapping = overlapping;
|
m_overlapping = overlapping;
|
||||||
init ();
|
init ();
|
||||||
init_complex_region (region);
|
init_region (region);
|
||||||
}
|
|
||||||
|
|
||||||
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::vector<unsigned int> &layers, const box_type ®ion, const region_type &excl_region, bool overlapping)
|
|
||||||
: m_box_convert (layout)
|
|
||||||
{
|
|
||||||
m_layer = 0;
|
|
||||||
m_layers = layers;
|
|
||||||
m_has_layers = true;
|
|
||||||
m_region = region;
|
|
||||||
mp_layout = &layout;
|
|
||||||
mp_shapes = 0;
|
|
||||||
mp_top_cell = &cell;
|
|
||||||
m_overlapping = overlapping;
|
|
||||||
init ();
|
|
||||||
init_complex_region (region, excl_region);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::vector<unsigned int> &layers)
|
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::vector<unsigned int> &layers)
|
||||||
|
|
@ -204,12 +215,12 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
|
||||||
m_layer = 0;
|
m_layer = 0;
|
||||||
m_layers = layers;
|
m_layers = layers;
|
||||||
m_has_layers = true;
|
m_has_layers = true;
|
||||||
m_region = box_type::world ();
|
|
||||||
mp_layout = &layout;
|
mp_layout = &layout;
|
||||||
mp_shapes = 0;
|
mp_shapes = 0;
|
||||||
mp_top_cell = &cell;
|
mp_top_cell = &cell;
|
||||||
m_overlapping = false;
|
m_overlapping = false;
|
||||||
init ();
|
init ();
|
||||||
|
init_region (box_type::world ());
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::set<unsigned int> &layers, const box_type ®ion, bool overlapping)
|
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::set<unsigned int> &layers, const box_type ®ion, bool overlapping)
|
||||||
|
|
@ -218,12 +229,12 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
|
||||||
m_layer = 0;
|
m_layer = 0;
|
||||||
m_layers.insert (m_layers.end (), layers.begin (), layers.end ());
|
m_layers.insert (m_layers.end (), layers.begin (), layers.end ());
|
||||||
m_has_layers = true;
|
m_has_layers = true;
|
||||||
m_region = region;
|
|
||||||
mp_layout = &layout;
|
mp_layout = &layout;
|
||||||
mp_shapes = 0;
|
mp_shapes = 0;
|
||||||
mp_top_cell = &cell;
|
mp_top_cell = &cell;
|
||||||
m_overlapping = overlapping;
|
m_overlapping = overlapping;
|
||||||
init ();
|
init ();
|
||||||
|
init_region (region);
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::set<unsigned int> &layers, const region_type ®ion, bool overlapping)
|
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::set<unsigned int> &layers, const region_type ®ion, bool overlapping)
|
||||||
|
|
@ -232,28 +243,12 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
|
||||||
m_layer = 0;
|
m_layer = 0;
|
||||||
m_layers.insert (m_layers.end (), layers.begin (), layers.end ());
|
m_layers.insert (m_layers.end (), layers.begin (), layers.end ());
|
||||||
m_has_layers = true;
|
m_has_layers = true;
|
||||||
m_region = region.bbox ();
|
|
||||||
mp_layout = &layout;
|
mp_layout = &layout;
|
||||||
mp_shapes = 0;
|
mp_shapes = 0;
|
||||||
mp_top_cell = &cell;
|
mp_top_cell = &cell;
|
||||||
m_overlapping = overlapping;
|
m_overlapping = overlapping;
|
||||||
init ();
|
init ();
|
||||||
init_complex_region (region);
|
init_region (region);
|
||||||
}
|
|
||||||
|
|
||||||
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::set<unsigned int> &layers, const box_type ®ion, const region_type &excl_region, bool overlapping)
|
|
||||||
: m_box_convert (layout)
|
|
||||||
{
|
|
||||||
m_layer = 0;
|
|
||||||
m_layers.insert (m_layers.end (), layers.begin (), layers.end ());
|
|
||||||
m_has_layers = true;
|
|
||||||
m_region = region;
|
|
||||||
mp_layout = &layout;
|
|
||||||
mp_shapes = 0;
|
|
||||||
mp_top_cell = &cell;
|
|
||||||
m_overlapping = overlapping;
|
|
||||||
init ();
|
|
||||||
init_complex_region (region, excl_region);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::set<unsigned int> &layers)
|
RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::set<unsigned int> &layers)
|
||||||
|
|
@ -262,12 +257,12 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
|
||||||
m_layer = 0;
|
m_layer = 0;
|
||||||
m_layers.insert (m_layers.end (), layers.begin (), layers.end ());
|
m_layers.insert (m_layers.end (), layers.begin (), layers.end ());
|
||||||
m_has_layers = true;
|
m_has_layers = true;
|
||||||
m_region = box_type::world ();
|
|
||||||
mp_layout = &layout;
|
mp_layout = &layout;
|
||||||
mp_shapes = 0;
|
mp_shapes = 0;
|
||||||
mp_top_cell = &cell;
|
mp_top_cell = &cell;
|
||||||
m_overlapping = false;
|
m_overlapping = false;
|
||||||
init ();
|
init ();
|
||||||
|
init_region (box_type::world ());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -283,6 +278,78 @@ RecursiveShapeIterator::init ()
|
||||||
m_shape_quad_id = 0;
|
m_shape_quad_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RecursiveShapeIterator::init_region (const RecursiveShapeIterator::box_type ®ion)
|
||||||
|
{
|
||||||
|
m_region = region;
|
||||||
|
mp_complex_region.reset (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RecursiveShapeIterator::init_region (const RecursiveShapeIterator::region_type ®ion)
|
||||||
|
{
|
||||||
|
if (region.empty ()) {
|
||||||
|
|
||||||
|
m_region = box_type ();
|
||||||
|
mp_complex_region.reset (0);
|
||||||
|
|
||||||
|
} else if (region.is_box ()) {
|
||||||
|
|
||||||
|
m_region = region.bbox ();
|
||||||
|
mp_complex_region.reset (0);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
mp_complex_region.reset (new region_type (region));
|
||||||
|
m_region = region.bbox ();
|
||||||
|
// A small optimization. We can do this since we merge and translate to trapezoids anyway.
|
||||||
|
mp_complex_region->set_strict_handling (false);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RecursiveShapeIterator::set_region (const box_type ®ion)
|
||||||
|
{
|
||||||
|
if (m_region != region || mp_complex_region.get () != 0) {
|
||||||
|
init_region (region);
|
||||||
|
m_needs_reinit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RecursiveShapeIterator::set_region (const region_type ®ion)
|
||||||
|
{
|
||||||
|
init_region (region);
|
||||||
|
m_needs_reinit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RecursiveShapeIterator::confine_region (const box_type ®ion)
|
||||||
|
{
|
||||||
|
if (m_region.empty ()) {
|
||||||
|
// no more confinement
|
||||||
|
} else if (mp_complex_region.get ()) {
|
||||||
|
init_region (*mp_complex_region & region_type (region));
|
||||||
|
} else {
|
||||||
|
init_region (m_region & region);
|
||||||
|
}
|
||||||
|
m_needs_reinit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RecursiveShapeIterator::confine_region (const region_type ®ion)
|
||||||
|
{
|
||||||
|
if (m_region.empty ()) {
|
||||||
|
// no more confinement
|
||||||
|
} else if (mp_complex_region.get ()) {
|
||||||
|
init_region (*mp_complex_region & region);
|
||||||
|
} else {
|
||||||
|
init_region (region & region_type (m_region));
|
||||||
|
}
|
||||||
|
m_needs_reinit = true;
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct BoxTreePusher
|
struct BoxTreePusher
|
||||||
|
|
@ -305,48 +372,6 @@ private:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
RecursiveShapeIterator::init_complex_region (const RecursiveShapeIterator::box_type &box, const RecursiveShapeIterator::region_type &excl_region)
|
|
||||||
{
|
|
||||||
// Use a boolean NOT and the trapezoid generator to produce a decomposition that goes into the complex region
|
|
||||||
|
|
||||||
db::EdgeProcessor ep;
|
|
||||||
ep.insert (db::Polygon (box), 0);
|
|
||||||
size_t n = 1;
|
|
||||||
for (region_type::const_iterator p = excl_region.begin (); !p.at_end (); ++p) {
|
|
||||||
ep.insert (*p, n);
|
|
||||||
n += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
BoxTreePusher btp (&m_complex_region);
|
|
||||||
db::TrapezoidGenerator tg (btp);
|
|
||||||
|
|
||||||
db::BooleanOp op (BooleanOp::ANotB);
|
|
||||||
ep.process (tg, op);
|
|
||||||
|
|
||||||
m_complex_region.sort (db::box_convert <db::Box> ());
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RecursiveShapeIterator::init_complex_region (const RecursiveShapeIterator::region_type ®ion)
|
|
||||||
{
|
|
||||||
// Use a merge and the trapezoid generator to produce a decomposition that goes into the complex region
|
|
||||||
|
|
||||||
db::EdgeProcessor ep;
|
|
||||||
size_t n = 0;
|
|
||||||
for (region_type::const_iterator p = region.begin (); !p.at_end (); ++p, ++n) {
|
|
||||||
ep.insert (*p, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
BoxTreePusher btp (&m_complex_region);
|
|
||||||
db::TrapezoidGenerator tg (btp);
|
|
||||||
|
|
||||||
db::MergeOp op (0);
|
|
||||||
ep.process (tg, op);
|
|
||||||
|
|
||||||
m_complex_region.sort (db::box_convert <db::Box> ());
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RecursiveShapeIterator::validate () const
|
RecursiveShapeIterator::validate () const
|
||||||
{
|
{
|
||||||
|
|
@ -366,9 +391,33 @@ RecursiveShapeIterator::validate () const
|
||||||
m_trans = cplx_trans_type ();
|
m_trans = cplx_trans_type ();
|
||||||
m_current_layer = 0;
|
m_current_layer = 0;
|
||||||
m_shape = shape_iterator ();
|
m_shape = shape_iterator ();
|
||||||
|
m_shape_quad_id = 0;
|
||||||
|
|
||||||
|
m_local_region_stack.clear ();
|
||||||
m_local_region_stack.push_back (m_region);
|
m_local_region_stack.push_back (m_region);
|
||||||
if (!m_complex_region.empty ()) {
|
|
||||||
m_local_complex_region_stack.push_back (m_complex_region);
|
m_local_complex_region_stack.clear ();
|
||||||
|
if (mp_complex_region.get ()) {
|
||||||
|
|
||||||
|
// prepare a local complex region
|
||||||
|
m_local_complex_region_stack.push_back (box_tree_type ());
|
||||||
|
|
||||||
|
// Use a merge and the trapezoid generator to produce a decomposition that goes into the complex region
|
||||||
|
|
||||||
|
db::EdgeProcessor ep;
|
||||||
|
size_t n = 0;
|
||||||
|
for (region_type::const_iterator p = mp_complex_region->begin (); !p.at_end (); ++p, ++n) {
|
||||||
|
ep.insert (*p, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
BoxTreePusher btp (&m_local_complex_region_stack.back ());
|
||||||
|
db::TrapezoidGenerator tg (btp);
|
||||||
|
|
||||||
|
db::MergeOp op (0);
|
||||||
|
ep.process (tg, op);
|
||||||
|
|
||||||
|
m_local_complex_region_stack.back ().sort (db::box_convert <db::Box> ());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp_shapes) {
|
if (mp_shapes) {
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include "dbLayout.h"
|
#include "dbLayout.h"
|
||||||
#include "dbInstElement.h"
|
#include "dbInstElement.h"
|
||||||
|
#include "tlAssert.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
@ -67,6 +68,16 @@ public:
|
||||||
*/
|
*/
|
||||||
RecursiveShapeIterator ();
|
RecursiveShapeIterator ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Copy constructor
|
||||||
|
*/
|
||||||
|
RecursiveShapeIterator (const RecursiveShapeIterator &d);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Assignment
|
||||||
|
*/
|
||||||
|
RecursiveShapeIterator &operator= (const RecursiveShapeIterator &d);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Standard constructor iterating a single shape container
|
* @brief Standard constructor iterating a single shape container
|
||||||
*
|
*
|
||||||
|
|
@ -101,20 +112,6 @@ public:
|
||||||
*/
|
*/
|
||||||
RecursiveShapeIterator (const shapes_type &shapes, const region_type ®ion, bool overlapping = false);
|
RecursiveShapeIterator (const shapes_type &shapes, const region_type ®ion, bool overlapping = false);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Standard constructor iterating a single shape container
|
|
||||||
*
|
|
||||||
* @param shapes The shape container to iterate
|
|
||||||
* @param region The basic region from which to select the shapes
|
|
||||||
* @param excl_region A complex region that will be excluded from the rectangular region
|
|
||||||
* @param overlapping Specify overlapping mode
|
|
||||||
*
|
|
||||||
* This iterator will iterate the shapes from the given shapes container using
|
|
||||||
* the given search region in overlapping or touching mode. It allows specification of a complex
|
|
||||||
* search region using a basic region and a complex region that is excluded from the search.
|
|
||||||
*/
|
|
||||||
RecursiveShapeIterator (const shapes_type &shapes, const box_type ®ion, const region_type &excl_region, bool overlapping = false);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Standard constructor
|
* @brief Standard constructor
|
||||||
*
|
*
|
||||||
|
|
@ -146,23 +143,6 @@ public:
|
||||||
*/
|
*/
|
||||||
RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, unsigned int layer, const region_type ®ion, bool overlapping = false);
|
RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, unsigned int layer, const region_type ®ion, bool overlapping = false);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Standard constructor
|
|
||||||
*
|
|
||||||
* @param layout The layout from which to get the cell hierarchy
|
|
||||||
* @param cell The starting cell
|
|
||||||
* @param layer The layer from which to deliver the shapes
|
|
||||||
* @param region The region from which to select the shapes
|
|
||||||
* @param excl_region A complex region that will be excluded from the rectangular region
|
|
||||||
* @param overlapping Specify overlapping mode
|
|
||||||
*
|
|
||||||
* By default the iterator operates in touching mode - i.e. shapes that touch the given region
|
|
||||||
* are returned. By specifying the "overlapping" flag with a true value, the iterator delivers shapes that
|
|
||||||
* overlap the given region by at least one database unit. It allows specification of a complex
|
|
||||||
* search region using a basic region and a complex region that is excluded from the search.
|
|
||||||
*/
|
|
||||||
RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, unsigned int layer, const box_type ®ion, const region_type &excl_region, bool overlapping = false);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Standard constructor for "world" iteration
|
* @brief Standard constructor for "world" iteration
|
||||||
*
|
*
|
||||||
|
|
@ -205,23 +185,6 @@ public:
|
||||||
*/
|
*/
|
||||||
RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::vector<unsigned int> &layers, const region_type ®ion, bool overlapping = false);
|
RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::vector<unsigned int> &layers, const region_type ®ion, bool overlapping = false);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Standard constructor with a layer selection
|
|
||||||
*
|
|
||||||
* @param layout The layout from which to get the cell hierarchy
|
|
||||||
* @param cell The starting cell
|
|
||||||
* @param layers The layers from which to deliver the shapes
|
|
||||||
* @param region The region from which to select the shapes
|
|
||||||
* @param excl_region A complex region that will be excluded from the rectangular region
|
|
||||||
* @param overlapping Specify overlapping mode
|
|
||||||
*
|
|
||||||
* By default the iterator operates in touching mode - i.e. shapes that touch the given region
|
|
||||||
* are returned. By specifying the "overlapping" flag with a true value, the iterator delivers shapes that
|
|
||||||
* overlap the given region by at least one database unit. It allows specification of a complex
|
|
||||||
* search region using a basic region and a complex region that is excluded from the search.
|
|
||||||
*/
|
|
||||||
RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::vector<unsigned int> &layers, const box_type ®ion, const region_type &excl_region, bool overlapping = false);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Standard constructor with a layer selection
|
* @brief Standard constructor with a layer selection
|
||||||
*
|
*
|
||||||
|
|
@ -253,23 +216,6 @@ public:
|
||||||
*/
|
*/
|
||||||
RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::set<unsigned int> &layers, const region_type ®ion, bool overlapping = false);
|
RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::set<unsigned int> &layers, const region_type ®ion, bool overlapping = false);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Standard constructor with a layer selection
|
|
||||||
*
|
|
||||||
* @param layout The layout from which to get the cell hierarchy
|
|
||||||
* @param cell The starting cell
|
|
||||||
* @param layers The layers from which to deliver the shapes
|
|
||||||
* @param region The region from which to select the shapes
|
|
||||||
* @param excl_region A complex region that will be excluded from the rectangular region
|
|
||||||
* @param overlapping Specify overlapping mode
|
|
||||||
*
|
|
||||||
* By default the iterator operates in touching mode - i.e. shapes that touch the given region
|
|
||||||
* are returned. By specifying the "overlapping" flag with a true value, the iterator delivers shapes that
|
|
||||||
* overlap the given region by at least one database unit. It allows specification of a complex
|
|
||||||
* search region using a basic region and a complex region that is excluded from the search.
|
|
||||||
*/
|
|
||||||
RecursiveShapeIterator (const layout_type &layout, const cell_type &cell, const std::set<unsigned int> &layers, const box_type ®ion, const region_type &excl_region, bool overlapping = false);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Standard constructor for "world" iteration with a layer set
|
* @brief Standard constructor for "world" iteration with a layer set
|
||||||
*
|
*
|
||||||
|
|
@ -345,7 +291,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the region the iterator is using (will be world if none is set)
|
* @brief Gets the basic region the iterator is using (will be world if none is set)
|
||||||
|
* In addition to the basic region, a complex region may be defined that is further confining the
|
||||||
|
* search to a subregion of the basic region.
|
||||||
*/
|
*/
|
||||||
const box_type ®ion () const
|
const box_type ®ion () const
|
||||||
{
|
{
|
||||||
|
|
@ -353,16 +301,48 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the region
|
* @brief Returns true if a complex region is given
|
||||||
*/
|
*/
|
||||||
void set_region (const box_type ®ion)
|
bool has_complex_region () const
|
||||||
{
|
{
|
||||||
if (m_region != region) {
|
return mp_complex_region.get () != 0;
|
||||||
m_region = region;
|
|
||||||
m_needs_reinit = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the complex region the iterator is using
|
||||||
|
*/
|
||||||
|
const region_type &complex_region () const
|
||||||
|
{
|
||||||
|
tl_assert (mp_complex_region.get ());
|
||||||
|
return *mp_complex_region;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the region to a basic rectangle
|
||||||
|
* This will reset the iterator.
|
||||||
|
*/
|
||||||
|
void set_region (const box_type ®ion);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets a complex search region
|
||||||
|
* This will reset the iterator to the beginning.
|
||||||
|
*/
|
||||||
|
void set_region (const region_type ®ion);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Confines the search further to the given rectangle.
|
||||||
|
* This will reset the iterator and confine the search to the given rectangle
|
||||||
|
* in addition to any region or complex region already defined.
|
||||||
|
*/
|
||||||
|
void confine_region (const box_type ®ion);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Confines the search further to the given complex region.
|
||||||
|
* This will reset the iterator and confine the search to the given region
|
||||||
|
* in addition to any simple region or complex region already defined.
|
||||||
|
*/
|
||||||
|
void confine_region (const region_type ®ion);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets a flag indicating whether overlapping shapes are selected when a region is used
|
* @brief Gets a flag indicating whether overlapping shapes are selected when a region is used
|
||||||
*/
|
*/
|
||||||
|
|
@ -669,7 +649,7 @@ private:
|
||||||
const shapes_type *mp_shapes;
|
const shapes_type *mp_shapes;
|
||||||
|
|
||||||
box_type m_region;
|
box_type m_region;
|
||||||
box_tree_type m_complex_region;
|
std::auto_ptr<region_type> mp_complex_region;
|
||||||
db::box_convert<db::CellInst> m_box_convert;
|
db::box_convert<db::CellInst> m_box_convert;
|
||||||
|
|
||||||
mutable inst_iterator m_inst;
|
mutable inst_iterator m_inst;
|
||||||
|
|
@ -692,8 +672,8 @@ private:
|
||||||
mutable size_t m_shape_quad_id;
|
mutable size_t m_shape_quad_id;
|
||||||
|
|
||||||
void init ();
|
void init ();
|
||||||
void init_complex_region (const box_type &box, const region_type &excl_region);
|
void init_region (const region_type ®ion);
|
||||||
void init_complex_region (const region_type &excl_region);
|
void init_region (const box_type ®ion);
|
||||||
void skip_shape_iter_for_complex_region () const;
|
void skip_shape_iter_for_complex_region () const;
|
||||||
void skip_inst_iter_for_complex_region () const;
|
void skip_inst_iter_for_complex_region () const;
|
||||||
void validate () const;
|
void validate () const;
|
||||||
|
|
|
||||||
|
|
@ -509,7 +509,7 @@ TilingProcessorWorker::do_perform (const TilingProcessorTask *tile_task)
|
||||||
db::RecursiveShapeIterator iter;
|
db::RecursiveShapeIterator iter;
|
||||||
if (! region_dbu.empty ()) {
|
if (! region_dbu.empty ()) {
|
||||||
iter = i->iter;
|
iter = i->iter;
|
||||||
iter.set_region (region_dbu);
|
iter.confine_region (region_dbu);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i->region) {
|
if (i->region) {
|
||||||
|
|
|
||||||
|
|
@ -48,12 +48,7 @@ static db::RecursiveShapeIterator *new_si3 (const db::Layout &layout, const db::
|
||||||
return new db::RecursiveShapeIterator (layout, cell, layer, box, overlapping);
|
return new db::RecursiveShapeIterator (layout, cell, layer, box, overlapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
static db::RecursiveShapeIterator *new_si3a (const db::Layout &layout, const db::Cell &cell, unsigned int layer, const db::Box &box, const db::Region &excl_region, bool overlapping)
|
static db::RecursiveShapeIterator *new_si3a (const db::Layout &layout, const db::Cell &cell, unsigned int layer, const db::Region ®ion, bool overlapping)
|
||||||
{
|
|
||||||
return new db::RecursiveShapeIterator (layout, cell, layer, box, excl_region, overlapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
static db::RecursiveShapeIterator *new_si3b (const db::Layout &layout, const db::Cell &cell, unsigned int layer, const db::Region ®ion, bool overlapping)
|
|
||||||
{
|
{
|
||||||
return new db::RecursiveShapeIterator (layout, cell, layer, region, overlapping);
|
return new db::RecursiveShapeIterator (layout, cell, layer, region, overlapping);
|
||||||
}
|
}
|
||||||
|
|
@ -63,12 +58,7 @@ static db::RecursiveShapeIterator *new_si4 (const db::Layout &layout, const db::
|
||||||
return new db::RecursiveShapeIterator (layout, cell, layers, box, overlapping);
|
return new db::RecursiveShapeIterator (layout, cell, layers, box, overlapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
static db::RecursiveShapeIterator *new_si4a (const db::Layout &layout, const db::Cell &cell, const std::vector<unsigned int> &layers, const db::Box &box, const db::Region &excl_region, bool overlapping)
|
static db::RecursiveShapeIterator *new_si4a (const db::Layout &layout, const db::Cell &cell, const std::vector<unsigned int> &layers, const db::Region ®ion, bool overlapping)
|
||||||
{
|
|
||||||
return new db::RecursiveShapeIterator (layout, cell, layers, box, excl_region, overlapping);
|
|
||||||
}
|
|
||||||
|
|
||||||
static db::RecursiveShapeIterator *new_si4b (const db::Layout &layout, const db::Cell &cell, const std::vector<unsigned int> &layers, const db::Region ®ion, bool overlapping)
|
|
||||||
{
|
{
|
||||||
return new db::RecursiveShapeIterator (layout, cell, layers, region, overlapping);
|
return new db::RecursiveShapeIterator (layout, cell, layers, region, overlapping);
|
||||||
}
|
}
|
||||||
|
|
@ -113,6 +103,14 @@ static void unselect_cells2 (db::RecursiveShapeIterator *r, const std::string &p
|
||||||
r->unselect_cells (cc);
|
r->unselect_cells (cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static db::Region complex_region (const db::RecursiveShapeIterator *iter)
|
||||||
|
{
|
||||||
|
if (iter->has_complex_region ()) {
|
||||||
|
return iter->complex_region ();
|
||||||
|
} else {
|
||||||
|
return db::Region (iter->region ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Class<db::RecursiveShapeIterator> decl_RecursiveShapeIterator ("RecursiveShapeIterator",
|
Class<db::RecursiveShapeIterator> decl_RecursiveShapeIterator ("RecursiveShapeIterator",
|
||||||
gsi::constructor ("new", &new_si1,
|
gsi::constructor ("new", &new_si1,
|
||||||
|
|
@ -160,29 +158,6 @@ Class<db::RecursiveShapeIterator> decl_RecursiveShapeIterator ("RecursiveShapeIt
|
||||||
"This constructor has been introduced in version 0.23.\n"
|
"This constructor has been introduced in version 0.23.\n"
|
||||||
) +
|
) +
|
||||||
gsi::constructor ("new", &new_si3a,
|
gsi::constructor ("new", &new_si3a,
|
||||||
"@brief Creates a recursive, single-layer shape iterator with a region.\n"
|
|
||||||
"@args layout, cell, layer, box, excl_region, overlapping\n"
|
|
||||||
"@param layout The layout which shall be iterated\n"
|
|
||||||
"@param cell The initial cell which shall be iterated (including it's children)\n"
|
|
||||||
"@param layer The layer (index) from which the shapes are taken\n"
|
|
||||||
"@param box The basic search region\n"
|
|
||||||
"@param excl_region The region that is excluded from the basic search region\n"
|
|
||||||
"@param overlapping If set to true, shapes overlapping the search region are reported, otherwise touching is sufficient\n"
|
|
||||||
"\n"
|
|
||||||
"This constructor creates a new recursive shape iterator which delivers the shapes of "
|
|
||||||
"the given cell plus it's children from the layer given by the layer index in the \"layer\" parameter.\n"
|
|
||||||
"\n"
|
|
||||||
"The search is confined to the region given by the \"box\" and the \"excl_region\" parameter. "
|
|
||||||
"The box specifies the basic region. From that basic region the parts specified with \"excl_region\" "
|
|
||||||
"are excluded. The excluded region needs to be a rectilinear region.\n"
|
|
||||||
"\n"
|
|
||||||
"If \"overlapping\" is true, shapes whose "
|
|
||||||
"bounding box is overlapping the search region are reported. If \"overlapping\" is false, shapes whose "
|
|
||||||
"bounding box is touching the search region are reported.\n"
|
|
||||||
"\n"
|
|
||||||
"This constructor has been introduced in version 0.25.\n"
|
|
||||||
) +
|
|
||||||
gsi::constructor ("new", &new_si3b,
|
|
||||||
"@brief Creates a recursive, single-layer shape iterator with a region.\n"
|
"@brief Creates a recursive, single-layer shape iterator with a region.\n"
|
||||||
"@args layout, cell, layer, region, overlapping\n"
|
"@args layout, cell, layer, region, overlapping\n"
|
||||||
"@param layout The layout which shall be iterated\n"
|
"@param layout The layout which shall be iterated\n"
|
||||||
|
|
@ -221,30 +196,6 @@ Class<db::RecursiveShapeIterator> decl_RecursiveShapeIterator ("RecursiveShapeIt
|
||||||
"This constructor has been introduced in version 0.23.\n"
|
"This constructor has been introduced in version 0.23.\n"
|
||||||
) +
|
) +
|
||||||
gsi::constructor ("new", &new_si4a,
|
gsi::constructor ("new", &new_si4a,
|
||||||
"@brief Creates a recursive, multi-layer shape iterator with a region.\n"
|
|
||||||
"@args layout, cell, layers, box, excl_region, overlapping\n"
|
|
||||||
"@param layout The layout which shall be iterated\n"
|
|
||||||
"@param cell The initial cell which shall be iterated (including it's children)\n"
|
|
||||||
"@param layers The layer indexes from which the shapes are taken\n"
|
|
||||||
"@param box The basic search region\n"
|
|
||||||
"@param excl_region The region that is excluded from the basic search region\n"
|
|
||||||
"@param overlapping If set to true, shapes overlapping the search region are reported, otherwise touching is sufficient\n"
|
|
||||||
"\n"
|
|
||||||
"This constructor creates a new recursive shape iterator which delivers the shapes of "
|
|
||||||
"the given cell plus it's children from the layers given by the layer indexes in the \"layers\" parameter.\n"
|
|
||||||
"While iterating use the \\layer method to retrieve the layer of the current shape.\n"
|
|
||||||
"\n"
|
|
||||||
"The search is confined to the region given by the \"box\" and the \"excl_region\" parameter. "
|
|
||||||
"The box specifies the basic region. From that basic region the parts specified with \"excl_region\" "
|
|
||||||
"are excluded. The excluded region needs to be a rectilinear region.\n"
|
|
||||||
"\n"
|
|
||||||
"If \"overlapping\" is true, shapes whose "
|
|
||||||
"bounding box is overlapping the search region are reported. If \"overlapping\" is false, shapes whose "
|
|
||||||
"bounding box is touching the search region are reported.\n"
|
|
||||||
"\n"
|
|
||||||
"This constructor has been introduced in version 0.23.\n"
|
|
||||||
) +
|
|
||||||
gsi::constructor ("new", &new_si4b,
|
|
||||||
"@brief Creates a recursive, multi-layer shape iterator with a region.\n"
|
"@brief Creates a recursive, multi-layer shape iterator with a region.\n"
|
||||||
"@args layout, cell, layers, region, overlapping\n"
|
"@args layout, cell, layers, region, overlapping\n"
|
||||||
"@param layout The layout which shall be iterated\n"
|
"@param layout The layout which shall be iterated\n"
|
||||||
|
|
@ -305,17 +256,54 @@ Class<db::RecursiveShapeIterator> decl_RecursiveShapeIterator ("RecursiveShapeIt
|
||||||
"This method has been introduced in version 0.23.\n"
|
"This method has been introduced in version 0.23.\n"
|
||||||
) +
|
) +
|
||||||
gsi::method ("region", &db::RecursiveShapeIterator::region,
|
gsi::method ("region", &db::RecursiveShapeIterator::region,
|
||||||
"@brief Gets the region that is iterator is using\n"
|
"@brief Gets the basic region that is iterator is using\n"
|
||||||
|
"The basic region is the overall box the region iterator iterates over. "
|
||||||
|
"There may be an additional complex region that confines the region iterator. "
|
||||||
|
"See \\complex_region for this attribute.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.23.\n"
|
"This method has been introduced in version 0.23.\n"
|
||||||
) +
|
) +
|
||||||
gsi::method ("region=", &db::RecursiveShapeIterator::set_region,
|
gsi::method_ext ("complex_region", &complex_region,
|
||||||
"@brief Sets the region that is iterator is using\n"
|
"@brief Gets the complex region that is iterator is using\n"
|
||||||
|
"The complex region is the effective region (a \\Region object) that the "
|
||||||
|
"iterator is selecting from the layout layers. This region can be a single box "
|
||||||
|
"or a complex region.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.25.\n"
|
||||||
|
) +
|
||||||
|
gsi::method ("region=", (void (db::RecursiveShapeIterator::*)(const db::RecursiveShapeIterator::box_type &)) &db::RecursiveShapeIterator::set_region,
|
||||||
|
"@brief Sets the rectangular region that is iterator is iterating over\n"
|
||||||
"@args region\n"
|
"@args region\n"
|
||||||
|
"See \\region for a description of this attribute.\n"
|
||||||
|
"Setting a simple region will reset the complex region to a rectangle and reset the iterator to "
|
||||||
|
"the beginning of the sequence."
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.23.\n"
|
"This method has been introduced in version 0.23.\n"
|
||||||
) +
|
) +
|
||||||
gsi::method ("overlapping?", &db::RecursiveShapeIterator::overlapping,
|
gsi::method ("region=", (void (db::RecursiveShapeIterator::*)(const db::RecursiveShapeIterator::region_type &)) &db::RecursiveShapeIterator::set_region,
|
||||||
|
"@brief Sets the complex region that is iterator is using\n"
|
||||||
|
"@args complex_region\n"
|
||||||
|
"See \\complex_region for a description of this attribute. Setting the complex region will "
|
||||||
|
"reset the basic region (see \\region) to the bounding box of the complex region and "
|
||||||
|
"reset the iterator to the beginning of the sequence.\n"
|
||||||
|
"\n"
|
||||||
|
"This method overload has been introduced in version 0.25.\n"
|
||||||
|
) +
|
||||||
|
gsi::method ("confine_region", (void (db::RecursiveShapeIterator::*)(const db::RecursiveShapeIterator::box_type &)) &db::RecursiveShapeIterator::confine_region,
|
||||||
|
"@brief Confines the region that is iterator is iterating over\n"
|
||||||
|
"@args region\n"
|
||||||
|
"This method is similar to setting the region (see \\region=), but will add to any (complex or simple) region already set. "
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.25.\n"
|
||||||
|
) +
|
||||||
|
gsi::method ("region=", (void (db::RecursiveShapeIterator::*)(const db::RecursiveShapeIterator::region_type &)) &db::RecursiveShapeIterator::confine_region,
|
||||||
|
"@brief Confines the region that is iterator is iterating over\n"
|
||||||
|
"@args region\n"
|
||||||
|
"This method is similar to setting the complex region (see \\region=), but will add to any (complex or simple) region already set."
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.25.\n"
|
||||||
|
) +
|
||||||
|
gsi::method ("overlapping?", &db::RecursiveShapeIterator::overlapping,
|
||||||
"@brief Gets a flag indicating whether overlapping shapes are selected when a region is used\n"
|
"@brief Gets a flag indicating whether overlapping shapes are selected when a region is used\n"
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.23.\n"
|
"This method has been introduced in version 0.23.\n"
|
||||||
|
|
|
||||||
|
|
@ -474,7 +474,62 @@ TEST(3)
|
||||||
rro.insert (db::Box (3400, 3450, 5600, 6500));
|
rro.insert (db::Box (3400, 3450, 5600, 6500));
|
||||||
rro.insert (db::Box (6650, 5300, 10000, 7850));
|
rro.insert (db::Box (6650, 5300, 10000, 7850));
|
||||||
|
|
||||||
db::RecursiveShapeIterator i23o (g, c0, 0, rro);
|
db::RecursiveShapeIterator i23o (g, c0, 0, rro, true);
|
||||||
|
db::RecursiveShapeIterator i23ocopy = i23o;
|
||||||
|
|
||||||
|
x = collect(i23o, g);
|
||||||
|
EXPECT_EQ (x, "[$3](4000,2500;5000,3500)/[$3](7000,5500;8000,6500)/[$3](7000,7500;8000,8500)");
|
||||||
|
|
||||||
|
x = collect (i23ocopy, g);
|
||||||
|
EXPECT_EQ (x, "[$3](4000,2500;5000,3500)/[$3](7000,5500;8000,6500)/[$3](7000,7500;8000,8500)");
|
||||||
|
|
||||||
|
// reset
|
||||||
|
i23o.reset ();
|
||||||
|
x = collect (i23o, g);
|
||||||
|
EXPECT_EQ (x, "[$3](4000,2500;5000,3500)/[$3](7000,5500;8000,6500)/[$3](7000,7500;8000,8500)");
|
||||||
|
|
||||||
|
// copy constructor
|
||||||
|
i23ocopy = i23o;
|
||||||
|
i23ocopy.reset ();
|
||||||
|
x = collect (i23ocopy, g);
|
||||||
|
EXPECT_EQ (x, "[$3](4000,2500;5000,3500)/[$3](7000,5500;8000,6500)/[$3](7000,7500;8000,8500)");
|
||||||
|
|
||||||
|
// setting of region
|
||||||
|
|
||||||
|
db::Region rg;
|
||||||
|
i23o.set_region (rg);
|
||||||
|
x = collect(i23o, g);
|
||||||
|
EXPECT_EQ (x, "");
|
||||||
|
|
||||||
|
rg.insert (db::Box (3400, 3450, 5600, 6500));
|
||||||
|
rg.insert (db::Box (16650, 5300, 20000, 7850));
|
||||||
|
|
||||||
|
i23o.set_region (rg);
|
||||||
|
x = collect(i23o, g);
|
||||||
|
EXPECT_EQ (x, "[$3](4000,2500;5000,3500)");
|
||||||
|
|
||||||
|
i23o.set_region (db::Box (6650, 5300, 10000, 7850));
|
||||||
|
x = collect(i23o, g);
|
||||||
|
EXPECT_EQ (x, "[$3](7000,5500;8000,6500)/[$3](7000,7500;8000,8500)");
|
||||||
|
|
||||||
|
// region confinement
|
||||||
|
|
||||||
|
i23o.confine_region (db::Box (3400, 3450, 5600, 6500));
|
||||||
|
x = collect(i23o, g);
|
||||||
|
EXPECT_EQ (x, "");
|
||||||
|
|
||||||
|
i23o.set_region (rro);
|
||||||
|
i23o.confine_region (db::Box (3400, 3450, 5600, 6500));
|
||||||
|
x = collect(i23o, g);
|
||||||
|
EXPECT_EQ (x, "[$3](4000,2500;5000,3500)");
|
||||||
|
|
||||||
|
i23o.set_region (db::Box (3400, 3450, 5600, 6500));
|
||||||
|
i23o.confine_region (rro);
|
||||||
|
x = collect(i23o, g);
|
||||||
|
EXPECT_EQ (x, "[$3](4000,2500;5000,3500)");
|
||||||
|
|
||||||
|
i23o.set_region (rro);
|
||||||
|
i23o.confine_region (rro);
|
||||||
x = collect(i23o, g);
|
x = collect(i23o, g);
|
||||||
EXPECT_EQ (x, "[$3](4000,2500;5000,3500)/[$3](7000,5500;8000,6500)/[$3](7000,7500;8000,8500)");
|
EXPECT_EQ (x, "[$3](4000,2500;5000,3500)/[$3](7000,5500;8000,6500)/[$3](7000,7500;8000,8500)");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue