mirror of https://github.com/KLayout/klayout.git
WIP: hierarchical mode for Region#in and Region#not_in
This commit is contained in:
parent
1f2e8b4012
commit
9008464268
|
|
@ -1550,13 +1550,6 @@ DeepRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const
|
|||
return res.release ();
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
DeepRegion::in (const Region &other, bool invert) const
|
||||
{
|
||||
// TODO: this can be optimized maybe ...
|
||||
return db::AsIfFlatRegion::in (other, invert);
|
||||
}
|
||||
|
||||
template <class TR, class Output>
|
||||
static
|
||||
Output *region_cop_impl (DeepRegion *region, db::CompoundRegionOperationNode &node)
|
||||
|
|
@ -1796,6 +1789,43 @@ private:
|
|||
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
DeepRegion::in (const Region &other, bool invert) const
|
||||
{
|
||||
// TODO: we could offer in_and_not_it (both at once)
|
||||
InteractingOutputMode output_mode = invert ? Negative : Positive;
|
||||
return in_and_out (other, output_mode).first;
|
||||
}
|
||||
|
||||
std::pair<RegionDelegate *, RegionDelegate *>
|
||||
DeepRegion::in_and_out (const Region &other, InteractingOutputMode output_mode) const
|
||||
{
|
||||
std::unique_ptr<db::DeepRegion> dr_holder;
|
||||
const db::DeepRegion *other_deep = dynamic_cast<const db::DeepRegion *> (other.delegate ());
|
||||
if (! other_deep) {
|
||||
// if the other region isn't deep, turn into a top-level only deep region to facilitate re-hierarchization
|
||||
dr_holder.reset (new db::DeepRegion (other, const_cast<db::DeepShapeStore &> (*deep_layer ().store ())));
|
||||
other_deep = dr_holder.get ();
|
||||
}
|
||||
|
||||
const db::DeepLayer &polygons = merged_deep_layer ();
|
||||
const db::DeepLayer &other_polygons = other_deep->merged_deep_layer ();
|
||||
|
||||
db::ContainedLocalOperation op (output_mode);
|
||||
|
||||
db::local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef> proc (const_cast<db::Layout *> (&polygons.layout ()), const_cast<db::Cell *> (&polygons.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell (), polygons.breakout_cells (), other_polygons.breakout_cells ());
|
||||
proc.set_description (progress_desc ());
|
||||
proc.set_report_progress (report_progress ());
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
proc.set_threads (polygons.store ()->threads ());
|
||||
|
||||
InteractingResultHolder orh (output_mode, merged_semantics (), polygons);
|
||||
|
||||
proc.run (&op, polygons.layer (), other_polygons.layer (), orh.layers ());
|
||||
|
||||
return orh.result_pair ();
|
||||
}
|
||||
|
||||
std::pair<RegionDelegate *, RegionDelegate *>
|
||||
DeepRegion::selected_interacting_generic (const Region &other, int mode, bool touching, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -155,6 +155,7 @@ protected:
|
|||
virtual std::pair<RegionDelegate *, RegionDelegate *> selected_interacting_generic (const Region &other, int mode, bool touching, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const;
|
||||
virtual std::pair<RegionDelegate *, RegionDelegate *> selected_interacting_generic (const Edges &other, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const;
|
||||
virtual std::pair<RegionDelegate *, RegionDelegate *> selected_interacting_generic (const Texts &other, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const;
|
||||
virtual std::pair<RegionDelegate *, RegionDelegate *> in_and_out (const Region &other, InteractingOutputMode output_mode) const;
|
||||
virtual RegionDelegate *pull_generic (const Region &other, int mode, bool touching) const;
|
||||
virtual EdgesDelegate *pull_generic (const Edges &other) const;
|
||||
virtual TextsDelegate *pull_generic (const Texts &other) const;
|
||||
|
|
|
|||
|
|
@ -915,6 +915,83 @@ template class DB_PUBLIC interacting_local_operation<db::Polygon, db::Polygon, d
|
|||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
contained_local_operation<TS, TI, TR>::contained_local_operation (InteractingOutputMode output_mode)
|
||||
: m_output_mode (output_mode)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
db::Coord contained_local_operation<TS, TI, TR>::dist () const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
void contained_local_operation<TS, TI, TR>::do_compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
|
||||
{
|
||||
if (m_output_mode == None) {
|
||||
return;
|
||||
} else if (m_output_mode == Positive || m_output_mode == Negative) {
|
||||
tl_assert (results.size () == 1);
|
||||
} else {
|
||||
tl_assert (results.size () == 2);
|
||||
}
|
||||
|
||||
db::EdgeProcessor ep;
|
||||
ep.set_base_verbosity (50);
|
||||
|
||||
std::set<TI> others;
|
||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (typename shape_interactions<TS, TI>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
others.insert (interactions.intruder_shape (*j).second);
|
||||
}
|
||||
}
|
||||
|
||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const TS &subject = interactions.subject_shape (i->first);
|
||||
if (others.find (subject) != others.end ()) {
|
||||
if (m_output_mode == Positive || m_output_mode == PositiveAndNegative) {
|
||||
results [0].insert (subject);
|
||||
}
|
||||
} else {
|
||||
if (m_output_mode == Negative) {
|
||||
results [0].insert (subject);
|
||||
} else if (m_output_mode == PositiveAndNegative) {
|
||||
results [1].insert (subject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
OnEmptyIntruderHint
|
||||
contained_local_operation<TS, TI, TR>::on_empty_intruder_hint () const
|
||||
{
|
||||
if (m_output_mode == Positive) {
|
||||
return OnEmptyIntruderHint::Drop;
|
||||
} else if (m_output_mode == Negative) {
|
||||
return OnEmptyIntruderHint::Copy;
|
||||
} else if (m_output_mode == PositiveAndNegative) {
|
||||
return OnEmptyIntruderHint::CopyToSecond;
|
||||
} else {
|
||||
return OnEmptyIntruderHint::Ignore;
|
||||
}
|
||||
}
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
std::string contained_local_operation<TS, TI, TR>::description () const
|
||||
{
|
||||
return tl::to_string (tr ("Select polygons contained in other region"));
|
||||
}
|
||||
|
||||
// explicit instantiations
|
||||
template class DB_PUBLIC contained_local_operation<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
|
||||
template class DB_PUBLIC contained_local_operation<db::Polygon, db::Polygon, db::Polygon>;
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
pull_local_operation<TS, TI, TR>::pull_local_operation (int mode, bool touching)
|
||||
: m_mode (mode), m_touching (touching)
|
||||
|
|
|
|||
|
|
@ -351,6 +351,24 @@ public:
|
|||
|
||||
typedef pull_with_text_local_operation<db::PolygonRef, db::TextRef, db::TextRef> PullWithTextLocalOperation;
|
||||
|
||||
template <class TS, class TI, class TR>
|
||||
class contained_local_operation
|
||||
: public local_operation<TS, TI, TR>
|
||||
{
|
||||
public:
|
||||
contained_local_operation (InteractingOutputMode output_mode);
|
||||
|
||||
virtual db::Coord dist () const;
|
||||
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
|
||||
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
|
||||
virtual std::string description () const;
|
||||
|
||||
private:
|
||||
InteractingOutputMode m_output_mode;
|
||||
};
|
||||
|
||||
typedef contained_local_operation<db::PolygonRef, db::PolygonRef, db::PolygonRef> ContainedLocalOperation;
|
||||
|
||||
} // namespace db
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2018,6 +2018,55 @@ TEST(30c_interact_with_count_text)
|
|||
EXPECT_EQ (r.selected_not_interacting (rr, 3, 4).to_string (), "(0,0;0,200;100,200;100,0)");
|
||||
}
|
||||
|
||||
TEST(31_in)
|
||||
{
|
||||
db::Layout ly;
|
||||
{
|
||||
std::string fn (tl::testdata ());
|
||||
fn += "/algo/deep_region_l31.gds";
|
||||
tl::InputStream stream (fn);
|
||||
db::Reader reader (stream);
|
||||
reader.read (ly);
|
||||
}
|
||||
|
||||
db::cell_index_type top_cell_index = *ly.begin_top_down ();
|
||||
db::Cell &top_cell = ly.cell (top_cell_index);
|
||||
|
||||
db::DeepShapeStore dss;
|
||||
|
||||
unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0));
|
||||
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
|
||||
unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0));
|
||||
|
||||
db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1), dss);
|
||||
db::Region r2 (db::RecursiveShapeIterator (ly, top_cell, l2), dss);
|
||||
db::Region r1r = r1;
|
||||
r1r.set_merged_semantics (false);
|
||||
db::Region r2r = r2;
|
||||
r2r.set_merged_semantics (false);
|
||||
|
||||
db::Layout target;
|
||||
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
|
||||
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (1, 0)), r1);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (2, 0)), r2);
|
||||
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), r2.in (r1));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), r2.in (r1, true));
|
||||
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (20, 0)), r2r.in (r1));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (21, 0)), r2r.in (r1, true));
|
||||
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (30, 0)), r2.in (r1r));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (31, 0)), r2.in (r1r, true));
|
||||
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (40, 0)), r2r.in (r1r));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (41, 0)), r2r.in (r1r, true));
|
||||
|
||||
CHECKPOINT();
|
||||
db::compare_layouts (_this, target, tl::testdata () + "/algo/deep_region_au31.gds");
|
||||
}
|
||||
|
||||
TEST(100_Integration)
|
||||
{
|
||||
db::Layout ly;
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue