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 ();
|
||||
|
||||
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;
|
||||
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
|
||||
insert_point (trans * *v)->set_is_precious (true, id++);
|
||||
}
|
||||
|
||||
create_constrained_delaunay (region, trans);
|
||||
constrain (edge_contours);
|
||||
refine (parameters);
|
||||
}
|
||||
|
||||
|
|
@ -1495,12 +1500,15 @@ Triangulation::triangulate (const db::Polygon &poly, const std::vector<db::Point
|
|||
|
||||
clear ();
|
||||
|
||||
std::vector<std::vector<Vertex *> > edge_contours;
|
||||
make_contours (poly, trans, edge_contours);
|
||||
|
||||
unsigned int id = 0;
|
||||
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
|
||||
insert_point (trans * *v)->set_is_precious (true, id++);
|
||||
}
|
||||
|
||||
create_constrained_delaunay (poly, trans);
|
||||
constrain (edge_contours);
|
||||
refine (parameters);
|
||||
}
|
||||
|
||||
|
|
@ -1517,12 +1525,15 @@ Triangulation::triangulate (const db::Polygon &poly, const std::vector<db::Point
|
|||
|
||||
clear ();
|
||||
|
||||
std::vector<std::vector<Vertex *> > edge_contours;
|
||||
make_contours (poly, trans, edge_contours);
|
||||
|
||||
unsigned int id = 0;
|
||||
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
|
||||
insert_point (trans * *v)->set_is_precious (true, id++);
|
||||
}
|
||||
|
||||
create_constrained_delaunay (poly, trans);
|
||||
constrain (edge_contours);
|
||||
refine (parameters);
|
||||
}
|
||||
|
||||
|
|
@ -1539,12 +1550,15 @@ Triangulation::triangulate (const db::DPolygon &poly, const std::vector<db::DPoi
|
|||
|
||||
clear ();
|
||||
|
||||
std::vector<std::vector<Vertex *> > edge_contours;
|
||||
make_contours (poly, trans, edge_contours);
|
||||
|
||||
unsigned int id = 0;
|
||||
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
|
||||
insert_point (trans * *v)->set_is_precious (true, id++);
|
||||
}
|
||||
|
||||
create_constrained_delaunay (poly, trans);
|
||||
constrain (edge_contours);
|
||||
refine (parameters);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1118,11 +1118,29 @@ TEST(triangulate_with_vertexes)
|
|||
EXPECT_EQ (vp, 0);
|
||||
}
|
||||
|
||||
// normal triangulation
|
||||
vertexes.clear ();
|
||||
vertexes.push_back (db::Point (50, 50));
|
||||
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) {
|
||||
auto *vp = tri.find_vertex_for_point (trans * *v);
|
||||
|
|
@ -1139,7 +1157,7 @@ TEST(triangulate_with_vertexes)
|
|||
tri.triangulate (poly, vertexes, param, trans);
|
||||
|
||||
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) {
|
||||
EXPECT_LE (t->area (), param.max_area);
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ RNetExtractor::extract (const RExtractorTech &tech,
|
|||
vp_offset += p->second.size ();
|
||||
}
|
||||
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
|
||||
|
|
@ -377,6 +377,7 @@ private:
|
|||
|
||||
// for internal nodes always create a node in the target network
|
||||
global = mp_rnetwork->create_node (local->type, ++m_next_internal_port_index);
|
||||
global->location = local->location;
|
||||
|
||||
} else if (local->type == RNode::VertexPort) {
|
||||
|
||||
|
|
@ -409,7 +410,7 @@ private:
|
|||
if (i2n != m_id_to_node.end ()) {
|
||||
global = i2n->second;
|
||||
} 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;
|
||||
m_id_to_node.insert (std::make_pair (id, global));
|
||||
}
|
||||
|
|
@ -422,7 +423,7 @@ private:
|
|||
}
|
||||
|
||||
// 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-> ();
|
||||
|
||||
|
|
@ -431,7 +432,14 @@ private:
|
|||
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 ();
|
||||
|
||||
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 ();
|
||||
|
||||
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);
|
||||
if (n4p == nodes_for_ports.end ()) {
|
||||
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;
|
||||
}
|
||||
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"
|
||||
);
|
||||
}
|
||||
|
||||
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