mirror of https://github.com/KLayout/klayout.git
WIP: Some optimization of check functions
This commit is contained in:
parent
3f8113e404
commit
1026d197cb
|
|
@ -46,32 +46,6 @@ static inline const db::PolygonRef *push_polygon_to_heap (db::Layout *layout, co
|
|||
return &heap.back ();
|
||||
}
|
||||
|
||||
static inline bool needs_merge (const std::unordered_set<db::PolygonRef> &polygons)
|
||||
{
|
||||
if (polygons.empty ()) {
|
||||
return false;
|
||||
} else if (polygons.size () > 1) {
|
||||
return true;
|
||||
} else if (polygons.begin ()->obj ().is_box ()) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool needs_merge (const std::unordered_set<db::Polygon> &polygons)
|
||||
{
|
||||
if (polygons.empty ()) {
|
||||
return false;
|
||||
} else if (polygons.size () > 1) {
|
||||
return true;
|
||||
} else if (polygons.begin ()->is_box ()) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
struct ResultInserter
|
||||
{
|
||||
typedef db::Polygon value_type;
|
||||
|
|
@ -167,7 +141,6 @@ static bool shields_interaction (const db::EdgePair &ep, const P &poly)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
template <class TS, class TI>
|
||||
check_local_operation<TS, TI>::check_local_operation (const EdgeRelationFilter &check, bool different_polygons, bool has_other, bool other_is_merged, bool shielded, db::OppositeFilter opposite_filter, db::RectFilter rect_filter)
|
||||
: m_check (check), m_different_polygons (different_polygons), m_has_other (has_other), m_other_is_merged (other_is_merged), m_shielded (shielded), m_opposite_filter (opposite_filter), m_rect_filter (rect_filter)
|
||||
|
|
@ -175,6 +148,23 @@ check_local_operation<TS, TI>::check_local_operation (const EdgeRelationFilter &
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
template <class T, class S>
|
||||
void insert_into_hash (std::unordered_set<T> &, const S &)
|
||||
{
|
||||
tl_assert (false);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void insert_into_hash (std::unordered_set<T> &hash, const T &shape)
|
||||
{
|
||||
hash.insert (shape);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <class TS, class TI>
|
||||
void
|
||||
check_local_operation<TS, TI>::compute_local (db::Layout *layout, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
|
||||
|
|
@ -190,13 +180,14 @@ check_local_operation<TS, TI>::compute_local (db::Layout *layout, const shape_in
|
|||
db::box_scanner<TS, size_t> scanner;
|
||||
std::unordered_set<TI> polygons;
|
||||
|
||||
if (m_has_other) {
|
||||
|
||||
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) {
|
||||
polygons.insert (interactions.intruder_shape (*j).second);
|
||||
}
|
||||
std::set<unsigned int> ids;
|
||||
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) {
|
||||
ids.insert (*j);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_has_other) {
|
||||
|
||||
size_t n = 0;
|
||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
|
|
@ -207,14 +198,20 @@ check_local_operation<TS, TI>::compute_local (db::Layout *layout, const shape_in
|
|||
|
||||
// merge the intruders to remove inner edges
|
||||
|
||||
if (! m_other_is_merged && needs_merge (polygons)) {
|
||||
if (ids.empty ()) {
|
||||
|
||||
// empty intruders
|
||||
|
||||
} else if (! m_other_is_merged && (ids.size () > 1 || ! interactions.intruder_shape (*ids.begin ()).second.is_box ())) {
|
||||
|
||||
db::EdgeProcessor ep;
|
||||
|
||||
ep.clear ();
|
||||
size_t i = 0;
|
||||
for (typename std::unordered_set<TI>::const_iterator o = polygons.begin (); o != polygons.end (); ++o) {
|
||||
for (typename TI::polygon_edge_iterator e = o->begin_edge (); ! e.at_end(); ++e) {
|
||||
|
||||
for (std::set<unsigned int>::const_iterator id = ids.begin (); id != ids.end (); ++id) {
|
||||
const TI &is = interactions.intruder_shape (*id).second;
|
||||
for (typename TI::polygon_edge_iterator e = is.begin_edge (); ! e.at_end (); ++e) {
|
||||
ep.insert (*e, i);
|
||||
}
|
||||
++i;
|
||||
|
|
@ -227,29 +224,44 @@ check_local_operation<TS, TI>::compute_local (db::Layout *layout, const shape_in
|
|||
db::SimpleMerge op (1 /*wc>0*/);
|
||||
ep.process (pg, op);
|
||||
|
||||
}
|
||||
n = 1;
|
||||
for (typename std::unordered_set<TI>::const_iterator o = polygons.begin (); o != polygons.end (); ++o) {
|
||||
scanner.insert (push_polygon_to_heap (layout, *o, heap), n);
|
||||
n += 2;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
n = 1;
|
||||
for (std::set<unsigned int>::const_iterator id = ids.begin (); id != ids.end (); ++id) {
|
||||
scanner.insert (push_polygon_to_heap (layout, interactions.intruder_shape (*id).second, heap), n);
|
||||
n += 2;
|
||||
}
|
||||
|
||||
n = 1;
|
||||
for (typename std::unordered_set<TI>::const_iterator o = polygons.begin (); o != polygons.end (); ++o) {
|
||||
scanner.insert (push_polygon_to_heap (layout, *o, heap), n);
|
||||
n += 2;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
polygons.insert (interactions.subject_shape (i->first));
|
||||
for (typename shape_interactions<TS, TI>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
polygons.insert (interactions.intruder_shape (*j).second);
|
||||
}
|
||||
}
|
||||
// NOTE: we need to eliminate identical shapes from intruders and subjects because those will shield
|
||||
|
||||
size_t n = 0;
|
||||
for (typename std::unordered_set<TI>::const_iterator o = polygons.begin (); o != polygons.end (); ++o) {
|
||||
scanner.insert (push_polygon_to_heap (layout, *o, heap), n);
|
||||
|
||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
// we can't directly insert because TS may be != TI
|
||||
const TS &ts = interactions.subject_shape (i->first);
|
||||
insert_into_hash (polygons, ts);
|
||||
scanner.insert (push_polygon_to_heap (layout, ts, heap), n);
|
||||
n += 2;
|
||||
}
|
||||
|
||||
for (std::set<unsigned int>::const_iterator id = ids.begin (); id != ids.end (); ++id) {
|
||||
const TI &ti = interactions.intruder_shape (*id).second;
|
||||
if (polygons.find (ti) == polygons.end ()) {
|
||||
scanner.insert (push_polygon_to_heap (layout, ti, heap), n);
|
||||
n += 2;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
do {
|
||||
|
|
|
|||
|
|
@ -508,11 +508,11 @@ TEST(15a)
|
|||
EXPECT_EQ (r.width_check (15).to_string (), "(0,0;0,10)/(10,10;10,0);(0,10;10,10)/(10,0;0,0)");
|
||||
EXPECT_EQ (r.width_check (5).to_string (), "");
|
||||
EXPECT_EQ (r.width_check (5, db::RegionCheckOptions (false, db::Euclidian, 91)).to_string (), "(0,5;0,10)/(0,10;5,10);(0,0;0,5)/(5,0;0,0);(5,10;10,10)/(10,10;10,5);(10,5;10,0)/(10,0;5,0);(20,45;20,50)/(20,50;25,50);(20,20;20,25)/(25,20;20,20);(35,50;40,50)/(40,50;40,45);(40,25;40,20)/(40,20;35,20)");
|
||||
EXPECT_EQ (r.space_check (15, db::RegionCheckOptions (false, db::Euclidian, 91)).to_string (), "(10,10;10,9)/(21,20;20,20);(10,10;10,9)/(20,20;20,21);(9,10;10,10)/(21,20;20,20);(9,10;10,10)/(20,20;20,21)");
|
||||
EXPECT_EQ (r.space_check (15, db::RegionCheckOptions (false, db::Square, 91)).to_string (), "(10,10;10,5)/(25,20;20,20);(10,10;10,5)/(20,20;20,25);(5,10;10,10)/(25,20;20,20);(5,10;10,10)/(20,20;20,25)");
|
||||
EXPECT_EQ (r.space_check (15).to_string (), "(10,10;10,9)/(20,20;20,21);(9,10;10,10)/(21,20;20,20)");
|
||||
EXPECT_EQ (r.space_check (15, db::RegionCheckOptions (true)).to_string (), "(10,10;10,0)/(20,20;20,50);(0,10;10,10)/(40,20;20,20)");
|
||||
EXPECT_EQ (r.space_check (15, db::RegionCheckOptions (false, db::Square)).to_string (), "(10,10;10,5)/(20,20;20,25);(5,10;10,10)/(25,20;20,20)");
|
||||
EXPECT_EQ (r.space_check (15, db::RegionCheckOptions (false, db::Euclidian, 91)).to_string (), "(21,20;20,20)/(10,10;10,9);(21,20;20,20)/(9,10;10,10);(20,20;20,21)/(10,10;10,9);(20,20;20,21)/(9,10;10,10)");
|
||||
EXPECT_EQ (r.space_check (15, db::RegionCheckOptions (false, db::Square, 91)).to_string (), "(25,20;20,20)/(10,10;10,5);(25,20;20,20)/(5,10;10,10);(20,20;20,25)/(10,10;10,5);(20,20;20,25)/(5,10;10,10)");
|
||||
EXPECT_EQ (r.space_check (15).to_string (), "(21,20;20,20)/(9,10;10,10);(20,20;20,21)/(10,10;10,9)");
|
||||
EXPECT_EQ (r.space_check (15, db::RegionCheckOptions (true)).to_string (), "(40,20;20,20)/(0,10;10,10);(20,20;20,50)/(10,10;10,0)");
|
||||
EXPECT_EQ (r.space_check (15, db::RegionCheckOptions (false, db::Square)).to_string (), "(25,20;20,20)/(5,10;10,10);(20,20;20,25)/(10,10;10,5)");
|
||||
|
||||
r.clear ();
|
||||
db::Point pts[] = {
|
||||
|
|
@ -545,9 +545,9 @@ TEST(15b)
|
|||
r.insert (db::Box (db::Point (400, 200), db::Point (500, 300)));
|
||||
|
||||
EXPECT_EQ (r.width_check (120, db::RegionCheckOptions (false, db::Projection)).to_string (), "(400,200;400,300)/(500,300;500,200)");
|
||||
EXPECT_EQ (r.space_check (120, db::RegionCheckOptions (false, db::Projection)).to_string (), "(200,500;200,300)/(300,300;300,500);(300,200;400,200)/(400,300;300,300);(200,200;200,0)/(300,0;300,200)");
|
||||
EXPECT_EQ (r.space_check (120, db::RegionCheckOptions (false, db::Projection)).to_string (), "(300,200;400,200)/(400,300;300,300);(300,300;300,500)/(200,500;200,300);(300,0;300,200)/(200,200;200,0)");
|
||||
EXPECT_EQ (r.notch_check (120, db::RegionCheckOptions (false, db::Projection)).to_string (), "(300,200;400,200)/(400,300;300,300)");
|
||||
EXPECT_EQ (r.isolated_check (120, db::RegionCheckOptions (false, db::Projection)).to_string (), "(300,300;300,500)/(200,500;200,300);(300,0;300,200)/(200,200;200,0)");
|
||||
EXPECT_EQ (r.isolated_check (120, db::RegionCheckOptions (false, db::Projection)).to_string (), "(200,500;200,300)/(300,300;300,500);(200,200;200,0)/(300,0;300,200)");
|
||||
}
|
||||
|
||||
TEST(15c)
|
||||
|
|
@ -563,9 +563,9 @@ TEST(15c)
|
|||
r.insert (db::Box (db::Point (400, 250), db::Point (500, 300)));
|
||||
|
||||
EXPECT_EQ (r.width_check (120, db::RegionCheckOptions (false, db::Projection)).to_string (), "(400,200;400,300)/(500,300;500,200)");
|
||||
EXPECT_EQ (r.space_check (120, db::RegionCheckOptions (false, db::Projection)).to_string (), "(200,500;200,300)/(300,300;300,500);(300,200;400,200)/(400,300;300,300);(200,200;200,0)/(300,0;300,200)");
|
||||
EXPECT_EQ (r.space_check (120, db::RegionCheckOptions (false, db::Projection)).to_string (), "(300,200;400,200)/(400,300;300,300);(300,300;300,500)/(200,500;200,300);(300,0;300,200)/(200,200;200,0)");
|
||||
EXPECT_EQ (r.notch_check (120, db::RegionCheckOptions (false, db::Projection)).to_string (), "(300,200;400,200)/(400,300;300,300)");
|
||||
EXPECT_EQ (r.isolated_check (120, db::RegionCheckOptions (false, db::Projection)).to_string (), "(300,300;300,500)/(200,500;200,300);(300,0;300,200)/(200,200;200,0)");
|
||||
EXPECT_EQ (r.isolated_check (120, db::RegionCheckOptions (false, db::Projection)).to_string (), "(200,500;200,300)/(300,300;300,500);(200,200;200,0)/(300,0;300,200)");
|
||||
}
|
||||
|
||||
TEST(15d)
|
||||
|
|
@ -581,12 +581,12 @@ TEST(15d)
|
|||
r.insert (db::Box (db::Point (0, 140), db::Point (350, 160)));
|
||||
|
||||
EXPECT_EQ (r.space_check (120, db::RegionCheckOptions (false, db::Projection)).to_string (),
|
||||
"(600,100;700,100)/(700,200;600,200);"
|
||||
"(300,160;350,160)/(350,200;300,200);"
|
||||
"(0,100;100,100)/(100,140;0,140);"
|
||||
"(300,100;350,100)/(350,140;300,140);"
|
||||
"(300,100;400,100)/(400,200;300,200);"
|
||||
"(100,200;0,200)/(0,160;100,160)"
|
||||
"(100,140;0,140)/(0,100;100,100);"
|
||||
"(350,140;300,140)/(300,100;350,100);"
|
||||
"(100,200;0,200)/(0,160;100,160);"
|
||||
"(400,200;300,200)/(300,100;400,100);"
|
||||
"(350,200;300,200)/(300,160;350,160);"
|
||||
"(700,200;600,200)/(600,100;700,100)"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -1242,7 +1242,7 @@ TEST(20)
|
|||
{
|
||||
db::Region r1 (db::RecursiveShapeIterator (ly, ly.cell (top), l2));
|
||||
EXPECT_EQ (r1.has_valid_polygons (), false);
|
||||
EXPECT_EQ (r1.space_check (30).to_string (), "(70,20;70,12)/(80,40;80,48);(60,20;70,20)/(92,40;80,40);(40,40;40,10)/(60,10;60,20)");
|
||||
EXPECT_EQ (r1.space_check (30).to_string (), "(40,40;40,10)/(60,10;60,20);(92,40;80,40)/(60,20;70,20);(80,40;80,48)/(70,20;70,12)");
|
||||
EXPECT_EQ (r1.space_check (2).to_string (), "");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue