Added test for edge-based clusters, edge connectivity modes

This commit is contained in:
Matthias Koefferlein 2019-02-12 22:14:50 +01:00
parent 98864b1eda
commit 10f9de8b66
3 changed files with 101 additions and 7 deletions

View File

@ -45,6 +45,13 @@ namespace db
// Connectivity implementation
Connectivity::Connectivity ()
: m_ec (Connectivity::EdgesConnectCollinear)
{
// .. nothing yet ..
}
Connectivity::Connectivity (edge_connectivity_type ec)
: m_ec (ec)
{
// .. nothing yet ..
}
@ -176,7 +183,7 @@ Connectivity::end_connected (unsigned int layer) const
template <class Trans>
static bool
interaction_test (const db::PolygonRef &a, const db::PolygonRef &b, const Trans &trans)
interaction_test (const db::PolygonRef &a, const db::PolygonRef &b, const Trans &trans, db::Connectivity::edge_connectivity_type)
{
// TODO: this could be part of db::interact (including transformation)
if (a.obj ().is_box () && b.obj ().is_box ()) {
@ -188,7 +195,7 @@ interaction_test (const db::PolygonRef &a, const db::PolygonRef &b, const Trans
template <class C>
static bool
interaction_test (const db::PolygonRef &a, const db::PolygonRef &b, const db::unit_trans<C> &)
interaction_test (const db::PolygonRef &a, const db::PolygonRef &b, const db::unit_trans<C> &, db::Connectivity::edge_connectivity_type)
{
// TODO: this could be part of db::interact (including transformation)
if (a.obj ().is_box () && b.obj ().is_box ()) {
@ -200,16 +207,25 @@ interaction_test (const db::PolygonRef &a, const db::PolygonRef &b, const db::un
template <class Trans>
static bool
interaction_test (const db::Edge &a, const db::Edge &b, const Trans &trans)
interaction_test (const db::Edge &a, const db::Edge &b, const Trans &trans, db::Connectivity::edge_connectivity_type ec)
{
return a.coincident (b.transformed (trans));
db::Edge bt = b.transformed (trans);
if (ec == db::Connectivity::EdgesConnectByPoints) {
return a.p2 () == bt.p1 () || a.p1 () == bt.p2 ();
} else {
return a.parallel (bt) && a.intersect (bt);
}
}
template <class C>
static bool
interaction_test (const db::Edge &a, const db::Edge &b, const db::unit_trans<C> &)
interaction_test (const db::Edge &a, const db::Edge &b, const db::unit_trans<C> &, db::Connectivity::edge_connectivity_type ec)
{
return a.coincident (b);
if (ec == db::Connectivity::EdgesConnectByPoints) {
return a.p2 () == b.p1 () || a.p1 () == b.p2 ();
} else {
return a.parallel (b) && a.intersect (b);
}
}
template <class T, class Trans>
@ -219,7 +235,7 @@ bool Connectivity::interacts (const T &a, unsigned int la, const T &b, unsigned
if (i == m_connected.end () || i->second.find (lb) == i->second.end ()) {
return false;
} else {
return interaction_test (a, b, trans);
return interaction_test (a, b, trans, m_ec);
}
}

View File

@ -60,11 +60,32 @@ public:
typedef std::set<size_t> global_nets_type;
typedef global_nets_type::const_iterator global_nets_iterator;
/**
* @brief Specifies the edge connectivity mode
*/
enum edge_connectivity_type
{
/**
* @brief Edges connect if they are collinear
*/
EdgesConnectCollinear,
/**
* @brief Edges connect if the end point of one edge is the start point of the other edge
*/
EdgesConnectByPoints
};
/**
* @brief Creates a connectivity object without any connections
*/
Connectivity ();
/**
* @brief Creates a connectivity object without connections and the given edge connectivity mode
*/
Connectivity (edge_connectivity_type ec);
/**
* @brief Adds intra-layer connectivity for layer l
*/
@ -162,6 +183,7 @@ private:
std::map<unsigned int, layers_type> m_connected;
std::vector<std::string> m_global_net_names;
std::map<unsigned int, global_nets_type> m_global_connections;
edge_connectivity_type m_ec;
};
/**

View File

@ -277,6 +277,11 @@ static std::string obj2string (const db::PolygonRef &ref)
return ref.obj ().transformed (ref.trans ()).to_string ();
}
static std::string obj2string (const db::Edge &ref)
{
return ref.to_string ();
}
template <class T>
static std::string local_cluster_to_string (const db::local_cluster<T> &cluster, const db::Connectivity &conn)
{
@ -534,6 +539,57 @@ TEST(22_LocalClustersWithGlobal)
);
}
TEST(23_LocalClustersWithEdges)
{
db::Layout layout;
db::Cell &cell = layout.cell (layout.add_cell ("TOP"));
db::Edge edge;
tl::from_string ("(0,0;0,500)", edge);
cell.shapes (0).insert (edge);
tl::from_string ("(0,500;0,1000)", edge);
cell.shapes (0).insert (edge);
tl::from_string ("(0,1000;2000,1000)", edge);
cell.shapes (0).insert (edge);
tl::from_string ("(2000,1000;2000,500)", edge);
cell.shapes (0).insert (edge);
tl::from_string ("(2000,500;1000,250)", edge);
cell.shapes (0).insert (edge);
tl::from_string ("(1500,375;0,0)", edge);
cell.shapes (0).insert (edge);
{
// edge clusters are for intra-layer mainly
db::Connectivity conn;
conn.connect (0);
db::local_clusters<db::Edge> clusters;
clusters.build_clusters (cell, db::ShapeIterator::Edges, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn),
"#1:[0](0,0;0,500);[0](0,500;0,1000)\n"
"#2:[0](2000,500;1000,250);[0](1500,375;0,0)\n"
"#3:[0](0,1000;2000,1000)\n"
"#4:[0](2000,1000;2000,500)"
);
}
{
// edge clusters are for intra-layer mainly
db::Connectivity conn (db::Connectivity::EdgesConnectByPoints);
conn.connect (0);
db::local_clusters<db::Edge> clusters;
clusters.build_clusters (cell, db::ShapeIterator::Edges, conn);
EXPECT_EQ (local_clusters_to_string (clusters, conn), "#1:[0](0,0;0,500);[0](0,500;0,1000);[0](1500,375;0,0);[0](0,1000;2000,1000);[0](2000,1000;2000,500);[0](2000,500;1000,250)");
}
}
TEST(30_LocalConnectedClusters)
{
db::Layout layout;