WIP: Deep region XOR implemented.

This commit is contained in:
Matthias Koefferlein 2018-11-21 00:32:14 +01:00
parent 712a390f52
commit 06c11d0096
4 changed files with 118 additions and 29 deletions

View File

@ -325,7 +325,7 @@ DeepRegion::not_with (const Region &other) const
// Nothing to do
return new EmptyRegion ();
} else if (other.empty () && ! strict_handling ()) {
} else if (other.empty ()) {
// Nothing to do
return clone ();
@ -356,6 +356,73 @@ DeepRegion::and_or_not_with (const DeepRegion *other, bool and_op) const
return dl_out;
}
RegionDelegate *
DeepRegion::xor_with (const Region &other) const
{
const DeepRegion *other_deep = dynamic_cast <const DeepRegion *> (other.delegate ());
if (empty ()) {
// Nothing to do
return other.delegate ()->clone ();
} else if (other.empty ()) {
// Nothing to do
return clone ();
} else if (! other_deep) {
return AsIfFlatRegion::xor_with (other);
} else {
// Implement XOR as (A-B)+(B-A) - only this implementation
// is compatible with the local processor scheme
DeepLayer n1 (and_or_not_with (other_deep, false));
DeepLayer n2 (other_deep->and_or_not_with (this, false));
std::auto_ptr<DeepRegion> r (new DeepRegion (n1));
r->add_from (n2);
return r.release ();
}
}
void
DeepRegion::add_from (const DeepLayer &dl)
{
if (dl.layout () == deep_layer ().layout ()) {
// intra-layout merge
deep_layer ().layout ()->copy_layer (dl.layer (), deep_layer ().layer ());
} else {
// inter-layout merge
db::cell_index_type into_cell = deep_layer ().initial_cell ()->cell_index ();
db::Layout *into_layout = deep_layer ().layout ();
db::cell_index_type source_cell = dl.initial_cell ()->cell_index ();
const db::Layout *source_layout = dl.layout ();
db::CellMapping cm;
cm.create_from_geometry_full (*into_layout, into_cell, *source_layout, source_cell);
// Actually copy the shapes
std::map<unsigned int, unsigned int> lm;
lm.insert (std::make_pair (dl.layer (), deep_layer ().layer ()));
std::vector <db::cell_index_type> source_cells;
source_cells.push_back (source_cell);
db::copy_shapes (*into_layout, *source_layout, db::ICplxTrans (), source_cells, cm.table (), lm);
}
}
RegionDelegate *
DeepRegion::add_in_place (const Region &other)
{
@ -366,34 +433,7 @@ DeepRegion::add_in_place (const Region &other)
const DeepRegion *other_deep = dynamic_cast <const DeepRegion *> (other.delegate ());
if (other_deep) {
if (other_deep->deep_layer ().layout () == deep_layer ().layout ()) {
// intra-layout merge
deep_layer ().layout ()->copy_layer (other_deep->deep_layer ().layer (), deep_layer ().layer ());
} else {
// inter-layout merge
db::cell_index_type into_cell = deep_layer ().initial_cell ()->cell_index ();
db::Layout *into_layout = deep_layer ().layout ();
db::cell_index_type source_cell = other_deep->deep_layer ().initial_cell ()->cell_index ();
const db::Layout *source_layout = other_deep->deep_layer ().layout ();
db::CellMapping cm;
cm.create_from_geometry_full (*into_layout, into_cell, *source_layout, source_cell);
// Actually copy the shapes
std::map<unsigned int, unsigned int> lm;
lm.insert (std::make_pair (other_deep->deep_layer ().layer (), deep_layer ().layer ()));
std::vector <db::cell_index_type> source_cells;
source_cells.push_back (source_cell);
db::copy_shapes (*into_layout, *source_layout, db::ICplxTrans (), source_cells, cm.table (), lm);
}
add_from (other_deep->deep_layer ());
} else {

View File

@ -72,6 +72,7 @@ public:
virtual RegionDelegate *and_with (const Region &other) const;
virtual RegionDelegate *not_with (const Region &other) const;
virtual RegionDelegate *xor_with (const Region &other) const;
virtual RegionDelegate *add_in_place (const Region &other);
virtual RegionDelegate *add (const Region &other) const;
@ -103,6 +104,7 @@ private:
void init ();
void ensure_merged_polygons_valid () const;
DeepLayer and_or_not_with(const DeepRegion *other, bool and_op) const;
void add_from (const DeepLayer &dl);
};
}

View File

@ -241,3 +241,50 @@ TEST(4_Add)
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au4b.gds");
}
}
TEST(5_BoolXOR)
{
db::Layout ly;
{
std::string fn (tl::testsrc ());
fn += "/testdata/algo/deep_region_l1.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 l2 = ly.get_layer (db::LayerProperties (2, 0));
unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0));
unsigned int l42 = ly.get_layer (db::LayerProperties (42, 0));
db::Region r2 (db::RecursiveShapeIterator (ly, top_cell, l2), dss);
db::Region r3 (db::RecursiveShapeIterator (ly, top_cell, l3), dss);
db::Region r42 (db::RecursiveShapeIterator (ly, top_cell, l42), dss);
db::Region box (db::Box (2000, -1000, 6000, 4000));
db::Region r2xor3 = r2 ^ r3;
db::Region r2xorbox = r2 ^ box;
db::Region r2xor42 = r2 ^ r42;
db::Region rboxxor3 = box ^ r3;
db::Region r42xor3 = r42 ^ r3;
db::Region r42xor42 = r42 ^ r42;
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 (10, 0)), r2xor3);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), r2xorbox);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (12, 0)), r2xor42);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (13, 0)), rboxxor3);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (14, 0)), r42xor3);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (15, 0)), r42xor42);
CHECKPOINT();
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au5.gds");
}

BIN
testdata/algo/deep_region_au5.gds vendored Normal file

Binary file not shown.