Merge pull request #229 from KLayout/issue_228

Fixed issue #228
This commit is contained in:
Matthias Köfferlein 2019-01-27 00:40:52 +01:00 committed by GitHub
commit 44f9d1540d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 10 deletions

View File

@ -639,7 +639,8 @@ InteractionDetector::reset ()
{ {
m_wcv_n.clear (); m_wcv_n.clear ();
m_wcv_s.clear (); m_wcv_s.clear ();
m_inside.clear (); m_inside_n.clear ();
m_inside_s.clear ();
} }
void void
@ -649,7 +650,8 @@ InteractionDetector::reserve (size_t n)
m_wcv_s.clear (); m_wcv_s.clear ();
m_wcv_n.resize (n, 0); m_wcv_n.resize (n, 0);
m_wcv_s.resize (n, 0); m_wcv_s.resize (n, 0);
m_inside.clear (); m_inside_n.clear ();
m_inside_s.clear ();
} }
int int
@ -667,9 +669,11 @@ InteractionDetector::edge (bool north, bool enter, property_type p)
// we have to catch interactions between objects north and south to the scanline // we have to catch interactions between objects north and south to the scanline
if (north || (m_mode == 0 && m_include_touching)) { if (north || (m_mode == 0 && m_include_touching)) {
std::set <property_type> *inside = north ? &m_inside_n : &m_inside_s;
if (inside_after < inside_before) { if (inside_after < inside_before) {
m_inside.erase (p); inside->erase (p);
if (m_mode != 0) { if (m_mode != 0) {
@ -677,7 +681,7 @@ InteractionDetector::edge (bool north, bool enter, property_type p)
// (due to prefer_touch == true and the sorting of coincident edges by property id) // (due to prefer_touch == true and the sorting of coincident edges by property id)
// hence every remaining parts count as non-interacting (outside) // hence every remaining parts count as non-interacting (outside)
if (p == m_container_id) { if (p == m_container_id) {
for (std::set <property_type>::const_iterator i = m_inside.begin (); i != m_inside.end (); ++i) { for (std::set <property_type>::const_iterator i = inside->begin (); i != inside->end (); ++i) {
if (*i != m_container_id) { if (*i != m_container_id) {
m_non_interactions.insert (*i); m_non_interactions.insert (*i);
} }
@ -695,13 +699,13 @@ InteractionDetector::edge (bool north, bool enter, property_type p)
// note that the container parts will be delivered first of all coincident // note that the container parts will be delivered first of all coincident
// edges hence we can check whether the container is present even for coincident // edges hence we can check whether the container is present even for coincident
// edges // edges
if (m_inside.find (m_container_id) != m_inside.end ()) { if (inside->find (m_container_id) != inside->end ()) {
m_interactions.insert (std::make_pair (m_container_id, p)); m_interactions.insert (std::make_pair (m_container_id, p));
} else { } else {
m_non_interactions.insert (p); m_non_interactions.insert (p);
} }
} else { } else {
for (std::set <property_type>::const_iterator i = m_inside.begin (); i != m_inside.end (); ++i) { for (std::set <property_type>::const_iterator i = inside->begin (); i != inside->end (); ++i) {
if (*i != m_container_id) { if (*i != m_container_id) {
m_interactions.insert (std::make_pair (m_container_id, *i)); m_interactions.insert (std::make_pair (m_container_id, *i));
} }
@ -710,7 +714,15 @@ InteractionDetector::edge (bool north, bool enter, property_type p)
} else { } else {
for (std::set <property_type>::const_iterator i = m_inside.begin (); i != m_inside.end (); ++i) { for (std::set <property_type>::const_iterator i = m_inside_n.begin (); i != m_inside_n.end (); ++i) {
if (*i < p) {
m_interactions.insert (std::make_pair (*i, p));
} else if (*i > p) {
m_interactions.insert (std::make_pair (p, *i));
}
}
for (std::set <property_type>::const_iterator i = m_inside_s.begin (); i != m_inside_s.end (); ++i) {
if (*i < p) { if (*i < p) {
m_interactions.insert (std::make_pair (*i, p)); m_interactions.insert (std::make_pair (*i, p));
} else if (*i > p) { } else if (*i > p) {
@ -720,7 +732,7 @@ InteractionDetector::edge (bool north, bool enter, property_type p)
} }
m_inside.insert (p); inside->insert (p);
} }

View File

@ -299,7 +299,7 @@ public:
virtual void reserve (size_t n); virtual void reserve (size_t n);
virtual int edge (bool north, bool enter, property_type p); virtual int edge (bool north, bool enter, property_type p);
virtual int compare_ns () const; virtual int compare_ns () const;
virtual bool is_reset () const { return m_inside.empty (); } virtual bool is_reset () const { return m_inside_s.empty () && m_inside_n.empty (); }
virtual bool prefer_touch () const { return m_include_touching; } virtual bool prefer_touch () const { return m_include_touching; }
private: private:
@ -307,7 +307,7 @@ private:
bool m_include_touching; bool m_include_touching;
property_type m_container_id; property_type m_container_id;
std::vector <int> m_wcv_n, m_wcv_s; std::vector <int> m_wcv_n, m_wcv_s;
std::set <property_type> m_inside; std::set <property_type> m_inside_n, m_inside_s;
std::set<std::pair<property_type, property_type> > m_interactions; std::set<std::pair<property_type, property_type> > m_interactions;
std::set<property_type> m_non_interactions; std::set<property_type> m_non_interactions;
}; };

View File

@ -1329,3 +1329,27 @@ TEST(30c)
EXPECT_EQ (r.to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)"); EXPECT_EQ (r.to_string (), "(-100,-100;-100,0;0,0;0,200;100,200;100,0;0,0;0,-100)");
} }
TEST(issue_228)
{
db::Region r;
db::Point pts[] = {
db::Point (0, 10),
db::Point (0, 290),
db::Point (280, 290),
db::Point (280, 230),
db::Point (360, 230),
db::Point (360, 70),
db::Point (280,70),
db::Point (280,10)
};
db::Polygon poly;
poly.assign_hull (pts, pts + sizeof (pts) / sizeof (pts [0]));
r.insert (poly);
db::Region rr;
rr.insert (db::Box (360, 70, 480, 230));
EXPECT_EQ (r.selected_interacting (rr).to_string (), r.to_string ());
EXPECT_EQ (rr.selected_interacting (r).to_string (), rr.to_string ());
}