Edge vs. dot booleans for edge collections

This commit is contained in:
Matthias Koefferlein 2024-03-06 21:46:33 +01:00
parent e70cb7e3ee
commit 4ecf6a9ce1
10 changed files with 168 additions and 101 deletions

View File

@ -872,8 +872,6 @@ AsIfFlatEdges::intersections (const Edges &other) const
EdgesDelegate *
AsIfFlatEdges::boolean (const Edges *other, EdgeBoolOp op) const
{
std::set<db::Edge> dots, other_dots;
std::unique_ptr<FlatEdges> output (new FlatEdges (true));
EdgeBooleanClusterCollectorToShapes cluster_collector (&output->raw_edges (), op);
@ -883,11 +881,7 @@ AsIfFlatEdges::boolean (const Edges *other, EdgeBoolOp op) const
AddressableEdgeDelivery e (begin ());
for ( ; ! e.at_end (); ++e) {
if (op == EdgeIntersections || ! e->is_degenerate ()) {
scanner.insert (e.operator-> (), 0);
} else if (op != EdgeOr) {
dots.insert (*e);
}
scanner.insert (e.operator-> (), 0);
}
AddressableEdgeDelivery ee;
@ -895,58 +889,18 @@ AsIfFlatEdges::boolean (const Edges *other, EdgeBoolOp op) const
if (other) {
ee = other->addressable_edges ();
for ( ; ! ee.at_end (); ++ee) {
if (op == EdgeIntersections || ! ee->is_degenerate ()) {
scanner.insert (ee.operator-> (), 1);
} else if (op != EdgeOr) {
other_dots.insert (*ee);
}
scanner.insert (ee.operator-> (), 1);
}
}
scanner.process (cluster_collector, 1, db::box_convert<db::Edge> ());
// process dots
// NOTE: currently, dots vs. dots is supported, but not dots vs. edges
if (op == EdgeOr) {
for (auto i = dots.begin (); i != dots.end (); ++i) {
output->insert (*i);
}
for (auto i = other_dots.begin (); i != other_dots.end (); ++i) {
output->insert (*i);
}
} else if (op == EdgeNot) {
for (auto i = dots.begin (); i != dots.end (); ++i) {
if (other_dots.find (*i) == other_dots.end ()) {
output->insert (*i);
}
}
} else if (op == EdgeXor) {
for (auto i = dots.begin (); i != dots.end (); ++i) {
if (other_dots.find (*i) == other_dots.end ()) {
output->insert (*i);
}
}
for (auto i = other_dots.begin (); i != other_dots.end (); ++i) {
if (dots.find (*i) == dots.end ()) {
output->insert (*i);
}
}
} else if (op == EdgeAnd) {
for (auto i = dots.begin (); i != dots.end (); ++i) {
if (other_dots.find (*i) != other_dots.end ()) {
output->insert (*i);
}
}
}
return output.release ();
}
std::pair<EdgesDelegate *, EdgesDelegate *>
AsIfFlatEdges::boolean_andnot (const Edges *other) const
{
std::set<db::Edge> dots, other_dots;
std::unique_ptr<FlatEdges> output (new FlatEdges (true));
std::unique_ptr<FlatEdges> output2 (new FlatEdges (true));
EdgeBooleanClusterCollectorToShapes cluster_collector (&output->raw_edges (), EdgeAndNot, &output2->raw_edges ());
@ -957,11 +911,7 @@ AsIfFlatEdges::boolean_andnot (const Edges *other) const
AddressableEdgeDelivery e (begin ());
for ( ; ! e.at_end (); ++e) {
if (! e->is_degenerate ()) {
scanner.insert (e.operator-> (), 0);
} else {
dots.insert (*e);
}
scanner.insert (e.operator-> (), 0);
}
AddressableEdgeDelivery ee;
@ -969,26 +919,12 @@ AsIfFlatEdges::boolean_andnot (const Edges *other) const
if (other) {
ee = other->addressable_edges ();
for ( ; ! ee.at_end (); ++ee) {
if (! ee->is_degenerate ()) {
scanner.insert (ee.operator-> (), 1);
} else {
other_dots.insert (*ee);
}
scanner.insert (ee.operator-> (), 1);
}
}
scanner.process (cluster_collector, 1, db::box_convert<db::Edge> ());
// process dots
// NOTE: currently, dots vs. dots is supported, but not dots vs. edges
for (auto i = dots.begin (); i != dots.end (); ++i) {
if (other_dots.find (*i) == other_dots.end ()) {
output2->insert (*i);
} else {
output->insert (*i);
}
}
return std::make_pair (output.release (), output2.release ());
}

View File

@ -1079,7 +1079,7 @@ public:
m_cl.erase (cli);
}
} else if (m_report_single) {
} else if (m_report_single && m_ignore_single.find (obj) == m_ignore_single.end ()) {
// single-object entry: create a cluster and feed it a single-object signature
Cluster cl (m_cl_template);
@ -1089,6 +1089,13 @@ public:
}
}
void ignore_single (const Obj *o)
{
if (m_report_single) {
m_ignore_single.insert (o);
}
}
void add_asymm (const Obj *o1, const Prop &p1, const Obj *o2, const Prop &p2)
{
om_iterator_type om1 = m_om.find (om_key_type (o1, p1));
@ -1166,6 +1173,7 @@ private:
bool m_report_single;
cl_type m_cl;
om_type m_om;
std::set<const Obj *> m_ignore_single;
};
}

View File

@ -86,14 +86,14 @@ struct EdgeBooleanCluster
{
typedef db::Edge::coord_type coord_type;
EdgeBooleanCluster (OutputContainer *output, EdgeBoolOp op)
: mp_output (output), mp_output2 (0), m_op (op)
EdgeBooleanCluster (OutputContainer *output, std::set<db::Point> *dots, EdgeBoolOp op)
: mp_output (output), mp_output2 (0), mp_dots (dots), mp_dots2 (0), m_op (op)
{
// .. nothing yet ..
}
EdgeBooleanCluster (OutputContainer *output, OutputContainer *output2, EdgeBoolOp op)
: mp_output (output), mp_output2 (output2), m_op (op)
EdgeBooleanCluster (OutputContainer *output, OutputContainer *output2, std::set<db::Point> *dots, std::set<db::Point> *dots2, EdgeBoolOp op)
: mp_output (output), mp_output2 (output2), mp_dots (dots), mp_dots2 (dots2), m_op (op)
{
// .. nothing yet ..
}
@ -106,13 +106,31 @@ struct EdgeBooleanCluster
if (begin () + 1 == end ()) {
if (begin ()->second == 0) {
if (m_op == EdgeAndNot) {
mp_output2->insert (*(begin ()->first));
if (begin ()->first->is_degenerate ()) {
if (mp_dots) {
mp_dots2->insert (begin ()->first->p1 ());
}
} else if (mp_output2) {
mp_output2->insert (*(begin ()->first));
}
} else if (m_op != EdgeAnd) {
mp_output->insert (*(begin ()->first));
if (begin ()->first->is_degenerate ()) {
if (mp_dots) {
mp_dots->insert (begin ()->first->p1 ());
}
} else if (mp_output) {
mp_output->insert (*(begin ()->first));
}
}
} else {
if (m_op != EdgeAnd && m_op != EdgeNot && m_op != EdgeAndNot) {
mp_output->insert (*(begin ()->first));
if (begin ()->first->is_degenerate ()) {
if (mp_dots) {
mp_dots->insert (begin ()->first->p1 ());
}
} else if (mp_output) {
mp_output->insert (*(begin ()->first));
}
}
}
return;
@ -258,6 +276,7 @@ struct EdgeBooleanCluster
private:
OutputContainer *mp_output, *mp_output2;
std::set<db::Point> *mp_dots, *mp_dots2;
db::EdgeBoolOp m_op;
};
@ -266,8 +285,8 @@ struct EdgeBooleanClusterCollector
: public db::cluster_collector<db::Edge, size_t, EdgeBooleanCluster<OutputContainer> >
{
EdgeBooleanClusterCollector (OutputContainer *output, EdgeBoolOp op, OutputContainer *output2 = 0)
: db::cluster_collector<db::Edge, size_t, EdgeBooleanCluster<OutputContainer> > (EdgeBooleanCluster<OutputContainer> (output, output2, op == EdgeIntersections ? EdgeAnd : op), op != EdgeAnd && op != EdgeIntersections /*report single*/),
mp_output (output), mp_intersections (op == EdgeIntersections ? output : 0)
: db::cluster_collector<db::Edge, size_t, EdgeBooleanCluster<OutputContainer> > (EdgeBooleanCluster<OutputContainer> (output, output2, &m_dots, &m_dots2, op == EdgeIntersections ? EdgeAnd : op), op != EdgeAnd && op != EdgeIntersections /*report single*/),
mp_output (output), mp_output2 (output2), m_op (op)
{
// .. nothing yet ..
}
@ -289,11 +308,76 @@ struct EdgeBooleanClusterCollector
} else {
if (mp_intersections && p1 != p2) {
std::pair<bool, db::Point> ip = o1->intersect_point (*o2);
if (ip.first) {
m_intersections.insert (ip.second);
// dots vs. edge or dot is handled here, no need to copy dots
if (o1->is_degenerate ()) {
this->ignore_single (o1);
}
if (o2->is_degenerate ()) {
this->ignore_single (o2);
}
if (m_op == EdgeIntersections) {
if (p1 != p2) {
std::pair<bool, db::Point> ip = o1->intersect_point (*o2);
if (ip.first) {
m_dots.insert (ip.second);
}
}
} else if (m_op == EdgeAndNot) {
// handle case of dot vs. edge or dot
if (p1 != p2 && (o1->is_degenerate () || o2->is_degenerate ())) {
std::pair<bool, db::Point> ip = o1->intersect_point (*o2);
if (ip.first) {
m_dots.insert (ip.second);
}
if (o1->is_degenerate () && ! ip.first) {
m_dots2.insert (o1->p1 ());
}
}
} else if (m_op == EdgeAnd) {
// handle case of dot vs. edge or dot
if (p1 != p2 && (o1->is_degenerate () || o2->is_degenerate ())) {
std::pair<bool, db::Point> ip = o1->intersect_point (*o2);
if (ip.first) {
m_dots.insert (ip.second);
}
}
} else if (m_op == EdgeNot) {
// handle case of dot vs. edge or dot
if (p1 != p2 && o1->is_degenerate ()) {
std::pair<bool, db::Point> ip = o1->intersect_point (*o2);
if (! ip.first) {
m_dots.insert (o1->p1 ());
}
}
} else if (m_op == EdgeOr) {
// forward dots
if (o1->is_degenerate ()) {
m_dots.insert (o1->p1 ());
}
if (o2->is_degenerate ()) {
m_dots.insert (o2->p1 ());
}
} else if (m_op == EdgeXor) {
// handle case of dot vs. edge or dot
if (p1 != p2 && o1->is_degenerate () && o2->is_degenerate ()) {
if (o1->p1 () != o2->p1 ()) {
m_dots.insert (o1->p1 ());
m_dots.insert (o2->p1 ());
}
}
}
}
@ -348,35 +432,44 @@ struct EdgeBooleanClusterCollector
};
/**
* @brief Finalizes the implementation for "EdgeIntersections"
* @brief Finalizes the implementation for "sections"
* This method pushes those points which don't interact with the edges to the output container
* as degenerate edges. It needs to be called after the pass has been made.
*/
void finalize (bool)
{
if (m_intersections.empty ()) {
add_orphan_dots (m_dots, mp_output);
if (mp_output2) {
add_orphan_dots (m_dots2, mp_output2);
}
}
private:
OutputContainer *mp_output, *mp_output2;
EdgeBoolOp m_op;
std::set<db::Point> m_dots, m_dots2;
static void add_orphan_dots (const std::set<db::Point> &dots, OutputContainer *output)
{
if (dots.empty ()) {
return;
}
db::box_scanner2<db::Edge, size_t, db::Point, size_t> intersections_to_edge_scanner;
for (typename OutputContainer::const_iterator e = mp_output->begin (); e != mp_output->end (); ++e) {
intersections_to_edge_scanner.insert1 (e.operator-> (), 0);
db::box_scanner2<db::Edge, size_t, db::Point, size_t> dots_to_edge_scanner;
for (typename OutputContainer::const_iterator e = output->begin (); e != output->end (); ++e) {
dots_to_edge_scanner.insert1 (e.operator-> (), 0);
}
for (std::set<db::Point>::const_iterator p = m_intersections.begin (); p != m_intersections.end (); ++p) {
intersections_to_edge_scanner.insert2 (p.operator-> (), 0);
for (std::set<db::Point>::const_iterator p = dots.begin (); p != dots.end (); ++p) {
dots_to_edge_scanner.insert2 (p.operator-> (), 0);
}
std::set<db::Point> points_to_remove;
RemovePointsOnEdges rpoe (points_to_remove);
intersections_to_edge_scanner.process (rpoe, 1, db::box_convert<db::Edge> (), db::box_convert<db::Point> ());
dots_to_edge_scanner.process (rpoe, 1, db::box_convert<db::Edge> (), db::box_convert<db::Point> ());
std::set_difference (dots.begin (), dots.end (), points_to_remove.begin (), points_to_remove.end (), PointInserter (output));
std::set_difference (m_intersections.begin (), m_intersections.end (), points_to_remove.begin (), points_to_remove.end (), PointInserter (mp_intersections));
}
private:
OutputContainer *mp_output;
OutputContainer *mp_intersections;
std::set<db::Point> m_intersections;
};
/**

View File

@ -133,7 +133,7 @@ Edge2EdgeCheckBase::finish (const Edge *o, size_t p)
std::set<db::Edge> partial_edges;
db::EdgeBooleanCluster<std::set<db::Edge> > ec (&partial_edges, db::EdgeNot);
db::EdgeBooleanCluster<std::set<db::Edge> > ec (&partial_edges, 0, db::EdgeNot);
ec.add (o, 0);
for (std::multimap<std::pair<db::Edge, size_t>, size_t>::const_iterator i = i0; i != m_e2ep.end () && i->first == k; ++i) {

View File

@ -133,7 +133,7 @@ TEST(3_Edge2EdgeBooleans)
db::Layout ly;
{
std::string fn (tl::testdata ());
fn += "/algo/deep_region_l1.gds";
fn += "/algo/deep_edges_l1.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
@ -145,14 +145,17 @@ TEST(3_Edge2EdgeBooleans)
db::DeepShapeStore dss;
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
unsigned int l21 = ly.get_layer (db::LayerProperties (2, 1));
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 r21 (db::RecursiveShapeIterator (ly, top_cell, l21), dss);
db::Region r3 (db::RecursiveShapeIterator (ly, top_cell, l3), dss);
db::Region r2and3 = r2 & r3;
db::Edges e2 = r2.edges ();
db::Edges e21 = r21.edges ();
db::Edges e3 = r3.edges ();
db::Edges e3copy = r3.edges ();
db::Edges e2and3 = r2and3.edges ();
@ -177,6 +180,8 @@ TEST(3_Edge2EdgeBooleans)
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 (27, 0)), e21 & edots);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (28, 0)), edots & e21);
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);
@ -185,6 +190,8 @@ TEST(3_Edge2EdgeBooleans)
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 (37, 0)), e21 - edots);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (38, 0)), edots - e21);
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);
@ -193,6 +200,8 @@ TEST(3_Edge2EdgeBooleans)
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 (47, 0)), e21 ^ edots);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (48, 0)), edots ^ e21);
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);
@ -201,6 +210,8 @@ TEST(3_Edge2EdgeBooleans)
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 (57, 0)), e21.andnot(edots).first);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (58, 0)), edots.andnot(e21).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);
@ -209,6 +220,8 @@ TEST(3_Edge2EdgeBooleans)
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 (67, 0)), e21.andnot(edots).second);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (68, 0)), edots.andnot(e21).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));
@ -219,6 +232,8 @@ TEST(3_Edge2EdgeBooleans)
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));
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (78, 0)), e21.intersections(edots));
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (79, 0)), edots.intersections(e21));
CHECKPOINT();
db::compare_layouts (_this, target, tl::testdata () + "/algo/deep_edges_au3.gds");

View File

@ -1165,7 +1165,7 @@ TEST(29)
db::Edges e;
e.insert (db::Edge (db::Point(0, 0), db::Point (100, 0)));
e.insert (db::Edge (db::Point(110, 0), db::Point (110, 0)));
EXPECT_EQ (e.merged ().to_string (), "(0,0;100,0)");
EXPECT_EQ (e.merged ().to_string (), "(0,0;100,0);(110,0;110,0)");
e.insert (db::Edge (db::Point(100, 0), db::Point (110, 0)));
// dots do not participate in merge
@ -1175,7 +1175,7 @@ TEST(29)
e.insert (db::Edge (db::Point(110, 0), db::Point (110, 0)));
e.insert (db::Edge (db::Point(110, 0), db::Point (110, 0)));
// dots do not participate in merge
EXPECT_EQ (e.merged ().to_string (), "");
EXPECT_EQ (e.merged ().to_string (), "(110,0;110,0)");
}
// interacting with count
@ -1263,7 +1263,7 @@ TEST(31)
db::Layout ly;
{
std::string fn (tl::testdata ());
fn += "/algo/deep_region_l1.gds";
fn += "/algo/deep_edges_l1.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
@ -1273,14 +1273,17 @@ TEST(31)
db::Cell &top_cell = ly.cell (top_cell_index);
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
unsigned int l21 = ly.get_layer (db::LayerProperties (2, 1));
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));
db::Region r21 (db::RecursiveShapeIterator (ly, top_cell, l21));
db::Region r3 (db::RecursiveShapeIterator (ly, top_cell, l3));
db::Region r2and3 = r2 & r3;
db::Edges e2 = r2.edges ();
db::Edges e21 = r21.edges ();
db::Edges e3 = r3.edges ();
db::Edges e3copy = r3.edges ();
db::Edges e2and3 = r2and3.edges ();
@ -1305,6 +1308,8 @@ TEST(31)
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 (27, 0)), e21 & edots);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (28, 0)), edots & e21);
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);
@ -1313,6 +1318,8 @@ TEST(31)
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 (37, 0)), e21 - edots);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (38, 0)), edots - e21);
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);
@ -1321,6 +1328,8 @@ TEST(31)
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 (47, 0)), e21 ^ edots);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (48, 0)), edots ^ e21);
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);
@ -1329,6 +1338,8 @@ TEST(31)
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 (57, 0)), e21.andnot(edots).first);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (58, 0)), edots.andnot(e21).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);
@ -1337,6 +1348,8 @@ TEST(31)
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 (67, 0)), e21.andnot(edots).second);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (68, 0)), edots.andnot(e21).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));
@ -1347,6 +1360,8 @@ TEST(31)
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));
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (78, 0)), e21.intersections(edots));
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (79, 0)), edots.intersections(e21));
CHECKPOINT();
db::compare_layouts (_this, target, tl::testdata () + "/algo/deep_edges_au3_flat.gds");

Binary file not shown.

Binary file not shown.

BIN
testdata/algo/deep_edges_l1.gds vendored Normal file

Binary file not shown.

Binary file not shown.