mirror of https://github.com/KLayout/klayout.git
Fixed a number of issues with edge booleans in deep mode
- andnot was falling back to flat - "intersections" with second argument empty was delivering wrong results - output of "intersections" is raw now to preserve dots - enhanced tests for these cases
This commit is contained in:
parent
03b04daa61
commit
91e68cef02
|
|
@ -916,10 +916,19 @@ EdgesDelegate *DeepEdges::merged () const
|
|||
return res.release ();
|
||||
}
|
||||
|
||||
DeepLayer
|
||||
std::pair<DeepLayer, DeepLayer>
|
||||
DeepEdges::and_or_not_with (const DeepEdges *other, EdgeBoolOp op) const
|
||||
{
|
||||
std::vector<unsigned int> output_layers;
|
||||
|
||||
DeepLayer dl_out (deep_layer ().derived ());
|
||||
output_layers.push_back (dl_out.layer ());
|
||||
|
||||
DeepLayer dl_out2;
|
||||
if (op == EdgeAndNot) {
|
||||
dl_out2 = DeepLayer (deep_layer ().derived ());
|
||||
output_layers.push_back (dl_out2.layer ());
|
||||
}
|
||||
|
||||
db::EdgeBoolAndOrNotLocalOperation local_op (op);
|
||||
|
||||
|
|
@ -929,9 +938,9 @@ DeepEdges::and_or_not_with (const DeepEdges *other, EdgeBoolOp op) const
|
|||
proc.set_area_ratio (deep_layer ().store ()->max_area_ratio ());
|
||||
proc.set_max_vertex_count (deep_layer ().store ()->max_vertex_count ());
|
||||
|
||||
proc.run (&local_op, deep_layer ().layer (), other->deep_layer ().layer (), dl_out.layer ());
|
||||
proc.run (&local_op, deep_layer ().layer (), other->deep_layer ().layer (), output_layers);
|
||||
|
||||
return dl_out;
|
||||
return std::make_pair (dl_out, dl_out2);
|
||||
}
|
||||
|
||||
std::pair<DeepLayer, DeepLayer>
|
||||
|
|
@ -965,17 +974,25 @@ EdgesDelegate *DeepEdges::intersections (const Edges &other) const
|
|||
{
|
||||
const DeepEdges *other_deep = dynamic_cast <const DeepEdges *> (other.delegate ());
|
||||
|
||||
if (empty () || other.empty ()) {
|
||||
if (empty ()) {
|
||||
|
||||
return clone ();
|
||||
|
||||
} else if (other.empty ()) {
|
||||
|
||||
// NOTE: we do not use "EmptyEdges" as we want to maintain
|
||||
return new DeepEdges (deep_layer ().derived ());
|
||||
|
||||
} else if (! other_deep) {
|
||||
|
||||
return AsIfFlatEdges::intersections (other);
|
||||
|
||||
} else {
|
||||
|
||||
return new DeepEdges (and_or_not_with (other_deep, EdgeIntersections));
|
||||
db::DeepEdges *res = new DeepEdges (and_or_not_with (other_deep, EdgeIntersections).first);
|
||||
// this is to preserve dots in later steps
|
||||
res->set_merged_semantics (false);
|
||||
return res;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -999,7 +1016,7 @@ EdgesDelegate *DeepEdges::and_with (const Edges &other) const
|
|||
|
||||
} else {
|
||||
|
||||
return new DeepEdges (and_or_not_with (other_deep, EdgeAnd));
|
||||
return new DeepEdges (and_or_not_with (other_deep, EdgeAnd).first);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1018,7 +1035,7 @@ EdgesDelegate *DeepEdges::not_with (const Edges &other) const
|
|||
|
||||
} else {
|
||||
|
||||
return new DeepEdges (and_or_not_with (other_deep, EdgeNot));
|
||||
return new DeepEdges (and_or_not_with (other_deep, EdgeNot).first);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1094,7 +1111,7 @@ EdgesDelegate *DeepEdges::not_with (const Region &other) const
|
|||
std::pair<EdgesDelegate *, EdgesDelegate *>
|
||||
DeepEdges::andnot_with (const Edges &other) const
|
||||
{
|
||||
const DeepRegion *other_deep = dynamic_cast <const DeepRegion *> (other.delegate ());
|
||||
const DeepEdges *other_deep = dynamic_cast <const DeepEdges *> (other.delegate ());
|
||||
|
||||
if (empty ()) {
|
||||
|
||||
|
|
@ -1111,7 +1128,7 @@ DeepEdges::andnot_with (const Edges &other) const
|
|||
|
||||
} else {
|
||||
|
||||
auto res = edge_region_op (other_deep, EdgePolygonOp::Both, true /*include borders*/);
|
||||
auto res = and_or_not_with (other_deep, EdgeAndNot);
|
||||
return std::make_pair (new DeepEdges (res.first), new DeepEdges (res.second));
|
||||
|
||||
}
|
||||
|
|
@ -1137,8 +1154,8 @@ EdgesDelegate *DeepEdges::xor_with (const Edges &other) const
|
|||
|
||||
// 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, EdgeNot));
|
||||
DeepLayer n2 (other_deep->and_or_not_with (this, EdgeNot));
|
||||
DeepLayer n1 (and_or_not_with (other_deep, EdgeNot).first);
|
||||
DeepLayer n2 (other_deep->and_or_not_with (this, EdgeNot).first);
|
||||
|
||||
n1.add_from (n2);
|
||||
return new DeepEdges (n1);
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ private:
|
|||
|
||||
void init ();
|
||||
void ensure_merged_edges_valid () const;
|
||||
DeepLayer and_or_not_with(const DeepEdges *other, EdgeBoolOp op) const;
|
||||
std::pair<DeepLayer, DeepLayer> and_or_not_with (const DeepEdges *other, EdgeBoolOp op) const;
|
||||
std::pair<DeepLayer, DeepLayer> edge_region_op (const DeepRegion *other, EdgePolygonOp::mode_t op, bool include_borders) const;
|
||||
EdgePairsDelegate *run_check (db::edge_relation_type rel, const Edges *other, db::Coord d, const db::EdgesCheckOptions &options) const;
|
||||
virtual EdgesDelegate *pull_generic (const Edges &edges) const;
|
||||
|
|
|
|||
|
|
@ -94,6 +94,9 @@ EdgeBoolAndOrNotLocalOperation::do_compute_local (db::Layout * /*layout*/, db::C
|
|||
if (! is_and) {
|
||||
result.insert (subject);
|
||||
}
|
||||
if (result2) {
|
||||
result2->insert (subject);
|
||||
}
|
||||
} else {
|
||||
scanner.insert (&subject, 0);
|
||||
any_subject = true;
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ TEST(3_Edge2EdgeBooleans)
|
|||
|
||||
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
|
||||
unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0));
|
||||
unsigned int lempty = ly.insert_layer ();
|
||||
|
||||
db::Region r2 (db::RecursiveShapeIterator (ly, top_cell, l2), dss);
|
||||
db::Region r3 (db::RecursiveShapeIterator (ly, top_cell, l3), dss);
|
||||
|
|
@ -153,7 +154,11 @@ TEST(3_Edge2EdgeBooleans)
|
|||
|
||||
db::Edges e2 = r2.edges ();
|
||||
db::Edges e3 = r3.edges ();
|
||||
db::Edges e3copy = r3.edges ();
|
||||
db::Edges e2and3 = r2and3.edges ();
|
||||
db::Edges eempty (db::RecursiveShapeIterator (ly, top_cell, lempty), dss);
|
||||
db::Edges edots = e2and3.processed (db::EdgeSegmentSelector (-1, 0, 0));
|
||||
db::Edges edotscopy = e2and3.processed (db::EdgeSegmentSelector (-1, 0, 0));
|
||||
|
||||
db::Layout target;
|
||||
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
|
||||
|
|
@ -162,11 +167,58 @@ TEST(3_Edge2EdgeBooleans)
|
|||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (3, 0)), r3);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), e3);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), e2and3);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (12, 0)), edots);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (13, 0)), edots.merged ());
|
||||
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (20, 0)), e3 & e2and3);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (21, 0)), e3 - e2and3);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (22, 0)), e3 ^ e2and3);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (23, 0)), e3.intersections(e2and3));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (24, 0)), e3.intersections(e2));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (21, 0)), e3 & edots);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (22, 0)), e3 & eempty);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (23, 0)), e3 & e3copy);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (24, 0)), eempty & e2and3);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (25, 0)), edots & edotscopy);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (26, 0)), edots & e2);
|
||||
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (30, 0)), e3 - e2and3);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (31, 0)), e3 - edots);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (32, 0)), e3 - eempty);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (33, 0)), e3 - e3copy);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (34, 0)), eempty - e2and3);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (35, 0)), edots - edotscopy);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (36, 0)), edots - e2);
|
||||
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (40, 0)), e3 ^ e2and3);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (41, 0)), e3 ^ edots);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (42, 0)), e3 ^ eempty);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (43, 0)), e3 ^ e3copy);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (44, 0)), eempty ^ e2and3);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (45, 0)), edots ^ edotscopy);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (46, 0)), edots ^ e2);
|
||||
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (50, 0)), e3.andnot(e2and3).first);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (51, 0)), e3.andnot(edots).first);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (52, 0)), e3.andnot(eempty).first);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (53, 0)), e3.andnot(e3copy).first);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (54, 0)), eempty.andnot(e2and3).first);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (55, 0)), edots.andnot(edotscopy).first);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (56, 0)), edots.andnot(e2).first);
|
||||
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (60, 0)), e3.andnot(e2and3).second);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (61, 0)), e3.andnot(edots).second);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (62, 0)), e3.andnot(eempty).second);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (63, 0)), e3.andnot(e3copy).second);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (64, 0)), eempty.andnot(e2and3).second);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (65, 0)), edots.andnot(edotscopy).second);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (66, 0)), edots.andnot(e2).second);
|
||||
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (70, 0)), e3.intersections(e2and3));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (71, 0)), e3.intersections(edots));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (72, 0)), e3.intersections(eempty));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (73, 0)), e3.intersections(e3copy));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (74, 0)), eempty.intersections(e2and3));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (75, 0)), edots.intersections(edotscopy));
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (76, 0)), edots.intersections(e2));
|
||||
// test, whether dots are not merged
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (77, 0)), edots.intersections(e2).select_interacting(e2));
|
||||
|
||||
CHECKPOINT();
|
||||
db::compare_layouts (_this, target, tl::testdata () + "/algo/deep_edges_au3.gds");
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue