mirror of https://github.com/KLayout/klayout.git
WIP: debugging, tests. Triangulation should be safer now against linear chains of vertexes.
This commit is contained in:
parent
f83cd61843
commit
80ad38f81b
|
|
@ -1471,12 +1471,17 @@ Triangulation::triangulate (const db::Region ®ion, const std::vector<db::Poin
|
||||||
|
|
||||||
clear ();
|
clear ();
|
||||||
|
|
||||||
|
std::vector<std::vector<Vertex *> > edge_contours;
|
||||||
|
for (auto p = region.begin_merged (); ! p.at_end (); ++p) {
|
||||||
|
make_contours (*p, trans, edge_contours);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int id = 0;
|
unsigned int id = 0;
|
||||||
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
|
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
|
||||||
insert_point (trans * *v)->set_is_precious (true, id++);
|
insert_point (trans * *v)->set_is_precious (true, id++);
|
||||||
}
|
}
|
||||||
|
|
||||||
create_constrained_delaunay (region, trans);
|
constrain (edge_contours);
|
||||||
refine (parameters);
|
refine (parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1495,12 +1500,15 @@ Triangulation::triangulate (const db::Polygon &poly, const std::vector<db::Point
|
||||||
|
|
||||||
clear ();
|
clear ();
|
||||||
|
|
||||||
|
std::vector<std::vector<Vertex *> > edge_contours;
|
||||||
|
make_contours (poly, trans, edge_contours);
|
||||||
|
|
||||||
unsigned int id = 0;
|
unsigned int id = 0;
|
||||||
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
|
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
|
||||||
insert_point (trans * *v)->set_is_precious (true, id++);
|
insert_point (trans * *v)->set_is_precious (true, id++);
|
||||||
}
|
}
|
||||||
|
|
||||||
create_constrained_delaunay (poly, trans);
|
constrain (edge_contours);
|
||||||
refine (parameters);
|
refine (parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1517,12 +1525,15 @@ Triangulation::triangulate (const db::Polygon &poly, const std::vector<db::Point
|
||||||
|
|
||||||
clear ();
|
clear ();
|
||||||
|
|
||||||
|
std::vector<std::vector<Vertex *> > edge_contours;
|
||||||
|
make_contours (poly, trans, edge_contours);
|
||||||
|
|
||||||
unsigned int id = 0;
|
unsigned int id = 0;
|
||||||
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
|
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
|
||||||
insert_point (trans * *v)->set_is_precious (true, id++);
|
insert_point (trans * *v)->set_is_precious (true, id++);
|
||||||
}
|
}
|
||||||
|
|
||||||
create_constrained_delaunay (poly, trans);
|
constrain (edge_contours);
|
||||||
refine (parameters);
|
refine (parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1539,12 +1550,15 @@ Triangulation::triangulate (const db::DPolygon &poly, const std::vector<db::DPoi
|
||||||
|
|
||||||
clear ();
|
clear ();
|
||||||
|
|
||||||
|
std::vector<std::vector<Vertex *> > edge_contours;
|
||||||
|
make_contours (poly, trans, edge_contours);
|
||||||
|
|
||||||
unsigned int id = 0;
|
unsigned int id = 0;
|
||||||
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
|
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
|
||||||
insert_point (trans * *v)->set_is_precious (true, id++);
|
insert_point (trans * *v)->set_is_precious (true, id++);
|
||||||
}
|
}
|
||||||
|
|
||||||
create_constrained_delaunay (poly, trans);
|
constrain (edge_contours);
|
||||||
refine (parameters);
|
refine (parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1118,11 +1118,29 @@ TEST(triangulate_with_vertexes)
|
||||||
EXPECT_EQ (vp, 0);
|
EXPECT_EQ (vp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// normal triangulation
|
||||||
vertexes.clear ();
|
vertexes.clear ();
|
||||||
vertexes.push_back (db::Point (50, 50));
|
vertexes.push_back (db::Point (50, 50));
|
||||||
tri.triangulate (poly, vertexes, param, trans);
|
tri.triangulate (poly, vertexes, param, trans);
|
||||||
|
|
||||||
EXPECT_EQ (plc.to_string (), "((-0.45, 0), (-0.5, -0.05), (-0.5, 0.05)), ((0.5, 0.05), (-0.45, 0), (-0.5, 0.05)), ((-0.45, 0), (0.5, -0.05), (-0.5, -0.05)), ((-0.45, 0), (0.5, 0.05), (0.5, -0.05))");
|
EXPECT_EQ (plc.to_string (), "((-0.5, -0.05), (-0.5, 0.05), (-0.45, 0)), ((-0.5, 0.05), (0.5, 0.05), (-0.45, 0)), ((0.5, -0.05), (-0.45, 0), (0.5, 0.05)), ((0.5, -0.05), (-0.5, -0.05), (-0.45, 0))");
|
||||||
|
|
||||||
|
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
|
||||||
|
auto *vp = tri.find_vertex_for_point (trans * *v);
|
||||||
|
if (! vp) {
|
||||||
|
tl::warn << "Vertex not present in output: " << v->to_string ();
|
||||||
|
EXPECT_EQ (1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// linear chain of vertexes must not break triangulation
|
||||||
|
vertexes.clear ();
|
||||||
|
vertexes.push_back (db::Point (50, 50));
|
||||||
|
vertexes.push_back (db::Point (100, 50));
|
||||||
|
vertexes.push_back (db::Point (150, 50));
|
||||||
|
tri.triangulate (poly, vertexes, param, trans);
|
||||||
|
|
||||||
|
EXPECT_EQ (plc.to_string (), "((-0.5, -0.05), (-0.5, 0.05), (-0.45, 0)), ((-0.4, 0), (-0.45, 0), (-0.5, 0.05)), ((-0.5, -0.05), (-0.45, 0), (-0.4, 0)), ((0.5, -0.05), (-0.35, 0), (0.5, 0.05)), ((-0.5, -0.05), (-0.35, 0), (0.5, -0.05)), ((-0.5, -0.05), (-0.4, 0), (-0.35, 0)), ((-0.35, 0), (-0.5, 0.05), (0.5, 0.05)), ((-0.35, 0), (-0.4, 0), (-0.5, 0.05))");
|
||||||
|
|
||||||
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
|
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
|
||||||
auto *vp = tri.find_vertex_for_point (trans * *v);
|
auto *vp = tri.find_vertex_for_point (trans * *v);
|
||||||
|
|
@ -1139,7 +1157,7 @@ TEST(triangulate_with_vertexes)
|
||||||
tri.triangulate (poly, vertexes, param, trans);
|
tri.triangulate (poly, vertexes, param, trans);
|
||||||
|
|
||||||
EXPECT_GT (plc.num_polygons (), size_t (380));
|
EXPECT_GT (plc.num_polygons (), size_t (380));
|
||||||
EXPECT_LT (plc.num_polygons (), size_t (400));
|
EXPECT_LT (plc.num_polygons (), size_t (420));
|
||||||
|
|
||||||
for (auto t = plc.begin (); t != plc.end (); ++t) {
|
for (auto t = plc.begin (); t != plc.end (); ++t) {
|
||||||
EXPECT_LE (t->area (), param.max_area);
|
EXPECT_LE (t->area (), param.max_area);
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ RNetExtractor::extract (const RExtractorTech &tech,
|
||||||
vp_offset += p->second.size ();
|
vp_offset += p->second.size ();
|
||||||
}
|
}
|
||||||
for (auto p = polygon_ports.begin (); p != polygon_ports.end () && p->first < g->first; ++p) {
|
for (auto p = polygon_ports.begin (); p != polygon_ports.end () && p->first < g->first; ++p) {
|
||||||
vp_offset += p->second.size ();
|
pp_offset += p->second.size ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch the port list for vertex ports
|
// fetch the port list for vertex ports
|
||||||
|
|
@ -377,6 +377,7 @@ private:
|
||||||
|
|
||||||
// for internal nodes always create a node in the target network
|
// for internal nodes always create a node in the target network
|
||||||
global = mp_rnetwork->create_node (local->type, ++m_next_internal_port_index);
|
global = mp_rnetwork->create_node (local->type, ++m_next_internal_port_index);
|
||||||
|
global->location = local->location;
|
||||||
|
|
||||||
} else if (local->type == RNode::VertexPort) {
|
} else if (local->type == RNode::VertexPort) {
|
||||||
|
|
||||||
|
|
@ -409,7 +410,7 @@ private:
|
||||||
if (i2n != m_id_to_node.end ()) {
|
if (i2n != m_id_to_node.end ()) {
|
||||||
global = i2n->second;
|
global = i2n->second;
|
||||||
} else {
|
} else {
|
||||||
global = mp_rnetwork->create_node (RNode::VertexPort, index_from_id (id) + m_polygon_port_index_offset);
|
global = mp_rnetwork->create_node (RNode::PolygonPort, index_from_id (id) + m_polygon_port_index_offset);
|
||||||
global->location = local->location;
|
global->location = local->location;
|
||||||
m_id_to_node.insert (std::make_pair (id, global));
|
m_id_to_node.insert (std::make_pair (id, global));
|
||||||
}
|
}
|
||||||
|
|
@ -422,7 +423,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the R elements in the target network
|
// create the R elements in the target network
|
||||||
for (auto e = local_network.begin_elements (); e != local_network.begin_elements (); ++e) {
|
for (auto e = local_network.begin_elements (); e != local_network.end_elements (); ++e) {
|
||||||
|
|
||||||
const RElement *local = e.operator-> ();
|
const RElement *local = e.operator-> ();
|
||||||
|
|
||||||
|
|
@ -431,7 +432,14 @@ private:
|
||||||
tl_assert (ia != n2n.end ());
|
tl_assert (ia != n2n.end ());
|
||||||
tl_assert (ia != n2n.end ());
|
tl_assert (ia != n2n.end ());
|
||||||
|
|
||||||
mp_rnetwork->create_element (local->conductance, ia->second, ib->second);
|
double c;
|
||||||
|
if (mp_cond->resistance < 1e-10) {
|
||||||
|
c = RElement::short_value ();
|
||||||
|
} else {
|
||||||
|
c = local->conductance / mp_cond->resistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_rnetwork->create_element (c, ia->second, ib->second);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,8 @@ SquareCountingRExtractor::extract (const db::Polygon &polygon, const std::vector
|
||||||
{
|
{
|
||||||
rnetwork.clear ();
|
rnetwork.clear ();
|
||||||
|
|
||||||
db::CplxTrans trans = db::CplxTrans (m_dbu) * db::ICplxTrans (db::Trans (db::Point () - polygon.box ().center ()));
|
db::CplxTrans to_um (m_dbu);
|
||||||
|
db::CplxTrans trans = to_um * db::ICplxTrans (db::Trans (db::Point () - polygon.box ().center ()));
|
||||||
auto inv_trans = trans.inverted ();
|
auto inv_trans = trans.inverted ();
|
||||||
|
|
||||||
db::plc::Graph plc;
|
db::plc::Graph plc;
|
||||||
|
|
@ -285,7 +286,7 @@ SquareCountingRExtractor::extract (const db::Polygon &polygon, const std::vector
|
||||||
auto n4p = nodes_for_ports.find (p->first);
|
auto n4p = nodes_for_ports.find (p->first);
|
||||||
if (n4p == nodes_for_ports.end ()) {
|
if (n4p == nodes_for_ports.end ()) {
|
||||||
pex::RNode *node = rnetwork.create_node (p->first.type, p->first.port_index);
|
pex::RNode *node = rnetwork.create_node (p->first.type, p->first.port_index);
|
||||||
node->location = trans * p->first.location;
|
node->location = to_um * p->first.location;
|
||||||
n4p = nodes_for_ports.insert (std::make_pair (p->first, node)).first;
|
n4p = nodes_for_ports.insert (std::make_pair (p->first, node)).first;
|
||||||
}
|
}
|
||||||
p->second = n4p->second;
|
p->second = n4p->second;
|
||||||
|
|
|
||||||
|
|
@ -137,3 +137,84 @@ TEST(netex_viagen2)
|
||||||
"R $10(0.6,4.9;1.2,5.1) $11(0.6,4.9;1.2,5.1) 25"
|
"R $10(0.6,4.9;1.2,5.1) $11(0.6,4.9;1.2,5.1) 25"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(netex_2layer)
|
||||||
|
{
|
||||||
|
db::Layout ly;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::string fn = tl::testdata () + "/pex/netex_test1.gds";
|
||||||
|
tl::InputStream is (fn);
|
||||||
|
db::Reader reader (is);
|
||||||
|
reader.read (ly);
|
||||||
|
}
|
||||||
|
|
||||||
|
TestableRNetExtractor rex (ly.dbu ());
|
||||||
|
|
||||||
|
auto tc = ly.cell_by_name ("TOP");
|
||||||
|
tl_assert (tc.first);
|
||||||
|
|
||||||
|
unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0));
|
||||||
|
unsigned int l1p = ly.get_layer (db::LayerProperties (1, 1));
|
||||||
|
unsigned int l1v = ly.get_layer (db::LayerProperties (1, 2));
|
||||||
|
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
|
||||||
|
unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0));
|
||||||
|
unsigned int l3p = ly.get_layer (db::LayerProperties (3, 1));
|
||||||
|
unsigned int l3v = ly.get_layer (db::LayerProperties (3, 2));
|
||||||
|
|
||||||
|
std::map<unsigned int, db::Region> geo;
|
||||||
|
geo.insert (std::make_pair (l1, db::Region (db::RecursiveShapeIterator (ly, ly.cell (tc.second), l1))));
|
||||||
|
geo.insert (std::make_pair (l2, db::Region (db::RecursiveShapeIterator (ly, ly.cell (tc.second), l2))));
|
||||||
|
geo.insert (std::make_pair (l3, db::Region (db::RecursiveShapeIterator (ly, ly.cell (tc.second), l3))));
|
||||||
|
|
||||||
|
pex::RNetwork network;
|
||||||
|
|
||||||
|
pex::RExtractorTech tech;
|
||||||
|
|
||||||
|
pex::RExtractorTechVia via1;
|
||||||
|
via1.bottom_conductor = l1;
|
||||||
|
via1.cut_layer = l2;
|
||||||
|
via1.top_conductor = l3;
|
||||||
|
via1.resistance = 2.0;
|
||||||
|
via1.merge_distance = 0.2;
|
||||||
|
tech.vias.push_back (via1);
|
||||||
|
|
||||||
|
pex::RExtractorTechConductor cond1;
|
||||||
|
cond1.layer = l1;
|
||||||
|
cond1.resistance = 0.5;
|
||||||
|
tech.conductors.push_back (cond1);
|
||||||
|
|
||||||
|
pex::RExtractorTechConductor cond2;
|
||||||
|
cond2.layer = l3;
|
||||||
|
cond2.resistance = 0.25;
|
||||||
|
tech.conductors.push_back (cond2);
|
||||||
|
|
||||||
|
std::map<unsigned int, std::vector<db::Point> > vertex_ports;
|
||||||
|
std::map<unsigned int, std::vector<db::Polygon> > polygon_ports;
|
||||||
|
|
||||||
|
db::Region l1p_region (db::RecursiveShapeIterator (ly, ly.cell (tc.second), l1p));
|
||||||
|
for (auto p = l1p_region.begin_merged (); ! p.at_end (); ++p) {
|
||||||
|
polygon_ports[l1].push_back (*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
db::Region l3p_region (db::RecursiveShapeIterator (ly, ly.cell (tc.second), l3p));
|
||||||
|
for (auto p = l3p_region.begin_merged (); ! p.at_end (); ++p) {
|
||||||
|
polygon_ports[l3].push_back (*p);
|
||||||
|
}
|
||||||
|
|
||||||
|
db::Region l1v_region (db::RecursiveShapeIterator (ly, ly.cell (tc.second), l1v));
|
||||||
|
for (auto p = l1v_region.begin_merged (); ! p.at_end (); ++p) {
|
||||||
|
vertex_ports[l1].push_back (p->box ().center ());
|
||||||
|
}
|
||||||
|
|
||||||
|
db::Region l3v_region (db::RecursiveShapeIterator (ly, ly.cell (tc.second), l3v));
|
||||||
|
for (auto p = l3v_region.begin_merged (); ! p.at_end (); ++p) {
|
||||||
|
vertex_ports[l3].push_back (p->box ().center ());
|
||||||
|
}
|
||||||
|
|
||||||
|
rex.extract (tech, geo, vertex_ports, polygon_ports, network);
|
||||||
|
|
||||||
|
EXPECT_EQ (network.to_string (true),
|
||||||
|
""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Reference in New Issue