WIP: hierarchical mode for Region#in and Region#not_in

This commit is contained in:
Matthias Koefferlein 2022-11-27 10:26:01 +01:00
parent 1f2e8b4012
commit 9008464268
7 changed files with 182 additions and 7 deletions

View File

@ -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
{

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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;

BIN
testdata/algo/deep_region_au31.gds vendored Normal file

Binary file not shown.

BIN
testdata/algo/deep_region_l31.gds vendored Normal file

Binary file not shown.