mirror of https://github.com/KLayout/klayout.git
Added test for edge-based clusters, edge connectivity modes
This commit is contained in:
parent
98864b1eda
commit
10f9de8b66
|
|
@ -45,6 +45,13 @@ namespace db
|
||||||
// Connectivity implementation
|
// Connectivity implementation
|
||||||
|
|
||||||
Connectivity::Connectivity ()
|
Connectivity::Connectivity ()
|
||||||
|
: m_ec (Connectivity::EdgesConnectCollinear)
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
|
Connectivity::Connectivity (edge_connectivity_type ec)
|
||||||
|
: m_ec (ec)
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
@ -176,7 +183,7 @@ Connectivity::end_connected (unsigned int layer) const
|
||||||
|
|
||||||
template <class Trans>
|
template <class Trans>
|
||||||
static bool
|
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)
|
// TODO: this could be part of db::interact (including transformation)
|
||||||
if (a.obj ().is_box () && b.obj ().is_box ()) {
|
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>
|
template <class C>
|
||||||
static bool
|
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)
|
// TODO: this could be part of db::interact (including transformation)
|
||||||
if (a.obj ().is_box () && b.obj ().is_box ()) {
|
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>
|
template <class Trans>
|
||||||
static bool
|
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>
|
template <class C>
|
||||||
static bool
|
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>
|
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 ()) {
|
if (i == m_connected.end () || i->second.find (lb) == i->second.end ()) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return interaction_test (a, b, trans);
|
return interaction_test (a, b, trans, m_ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,11 +60,32 @@ public:
|
||||||
typedef std::set<size_t> global_nets_type;
|
typedef std::set<size_t> global_nets_type;
|
||||||
typedef global_nets_type::const_iterator global_nets_iterator;
|
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
|
* @brief Creates a connectivity object without any connections
|
||||||
*/
|
*/
|
||||||
Connectivity ();
|
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
|
* @brief Adds intra-layer connectivity for layer l
|
||||||
*/
|
*/
|
||||||
|
|
@ -162,6 +183,7 @@ private:
|
||||||
std::map<unsigned int, layers_type> m_connected;
|
std::map<unsigned int, layers_type> m_connected;
|
||||||
std::vector<std::string> m_global_net_names;
|
std::vector<std::string> m_global_net_names;
|
||||||
std::map<unsigned int, global_nets_type> m_global_connections;
|
std::map<unsigned int, global_nets_type> m_global_connections;
|
||||||
|
edge_connectivity_type m_ec;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -277,6 +277,11 @@ static std::string obj2string (const db::PolygonRef &ref)
|
||||||
return ref.obj ().transformed (ref.trans ()).to_string ();
|
return ref.obj ().transformed (ref.trans ()).to_string ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string obj2string (const db::Edge &ref)
|
||||||
|
{
|
||||||
|
return ref.to_string ();
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
static std::string local_cluster_to_string (const db::local_cluster<T> &cluster, const db::Connectivity &conn)
|
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)
|
TEST(30_LocalConnectedClusters)
|
||||||
{
|
{
|
||||||
db::Layout layout;
|
db::Layout layout;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue