Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Changelog
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
0.30.10 (2026-08-22):
0.30.11 (2026-08-22):
* Bugfix: %GITHUB%/issues/2429 Internal error on triangulation
* Enhancement: %GITHUB%/issues/2374 LEF/DEF Import - skip duplicate Macros feature
* Enhancement: %GITHUB%/issues/2407 Visualize "Select" and "Partial" via selection box style
* Bugfix: %GITHUB%/issues/2416 Two-layer DRC check without merged first input produces separation violations that 0.30.9 does not reportbug
Expand Down
18 changes: 9 additions & 9 deletions src/db/db/dbPLC.cc
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ Edge::point_on (const db::DEdge &edge, const db::DPoint &point)
if (edge.side_of (point) != 0) {
return false;
} else {
return db::sprod_sign (point - edge.p1 (), edge.d ()) * db::sprod_sign(point - edge.p2 (), edge.d ()) < 0;
return db::sprod_sign (point - edge.p1 (), edge.d ()) * db::sprod_sign (point - edge.p2 (), edge.d ()) < 0;
}
}

Expand Down Expand Up @@ -918,24 +918,24 @@ Graph::to_layout (bool decompose_by_id) const
unsigned int l21 = layout->insert_layer (db::LayerProperties (21, 0));
unsigned int l22 = layout->insert_layer (db::LayerProperties (22, 0));

std::vector<db::DPoint> pts;
std::vector<db::Point> pts;
for (auto t = mp_polygons.begin (); t != mp_polygons.end (); ++t) {
pts.clear ();
for (int i = 0; i < int (t->size ()); ++i) {
pts.push_back (*t->vertex (i));
pts.push_back (dbu_trans * *t->vertex (i));
}
db::DPolygon poly;
poly.assign_hull (pts.begin (), pts.end ());
top.shapes (t->is_outside () ? l2 : l1).insert (dbu_trans * poly);
db::Polygon poly;
poly.assign_hull (pts.begin (), pts.end (), false, false);
top.shapes (t->is_outside () ? l2 : l1).insert (poly);
if (decompose_by_id) {
if ((t->id () & 1) != 0) {
top.shapes (l20).insert (dbu_trans * poly);
top.shapes (l20).insert (poly);
}
if ((t->id () & 2) != 0) {
top.shapes (l21).insert (dbu_trans * poly);
top.shapes (l21).insert (poly);
}
if ((t->id () & 4) != 0) {
top.shapes (l22).insert (dbu_trans * poly);
top.shapes (l22).insert (poly);
}
}
}
Expand Down
16 changes: 16 additions & 0 deletions src/db/db/dbPLC.h
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,22 @@ class DB_PUBLIC Edge
return *mp_v2 - *mp_v1;
}

/**
* @brief Gets the length of the edge
*/
double length () const
{
return mp_v1->double_distance (*mp_v2);
}

/**
* @brief Gets the squared length of the edge
*/
double sq_length () const
{
return mp_v1->sq_double_distance (*mp_v2);
}

/**
* @brief Gets the other triangle for the given one
*/
Expand Down
39 changes: 24 additions & 15 deletions src/db/db/dbPLCTriangulation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ static inline bool is_equal (const db::DPoint &a, const db::DPoint &b)
std::abs (a.y () - b.y ()) < std::max (1.0, (std::abs (a.y ()) + std::abs (b.y ()))) * db::epsilon;
}

// distance of point to vertex to be considered "on edge vertex" relative to edge length involved
const double snap_to_edge_vertex = 1e-5;

// distance of point to edge center to be considered "on edge center" relative to edge length involved
double snap_to_edge_center = 1e-3;


Triangulation::Triangulation (Graph *graph)
{
mp_graph = graph;
Expand Down Expand Up @@ -241,29 +248,33 @@ Triangulation::insert (Vertex *vertex, std::list<tl::weak_ptr<Polygon> > *new_tr
}

// check, if the new vertex is on an edge (may be edge between triangles or edge on outside)
std::vector<Edge *> on_edges;
Edge *on_edge = 0;
std::vector<Edge *> on_vertex;
for (int i = 0; i < 3; ++i) {

Edge *e = tris.front ()->edge (i);
if (e->side_of (*vertex) == 0) {
if (is_equal (*vertex, *e->v1 ()) || is_equal (*vertex, *e->v2 ())) {

double snap_range = snap_to_edge_vertex * e->length ();

if (std::abs (e->edge ().distance (*vertex)) < snap_range - db::epsilon) {
if (vertex->distance (*e->v1 ()) < snap_range + db::epsilon || vertex->distance (*e->v2 ()) < snap_range + db::epsilon) {
on_vertex.push_back (e);
} else {
on_edges.push_back (e);
} else if (! on_edge) {
on_edge = e;
}
}

}

if (! on_vertex.empty ()) {
if (on_edge) {

tl_assert (on_vertex.size () == size_t (2));
return on_vertex.front ()->common_vertex (on_vertex [1]);
split_triangles_on_edge (vertex, on_edge, new_triangles);
return vertex;

} else if (! on_edges.empty ()) {
} else if (! on_vertex.empty ()) {

tl_assert (on_edges.size () == size_t (1));
split_triangles_on_edge (vertex, on_edges.front (), new_triangles);
return vertex;
tl_assert (on_vertex.size () == size_t (2));
return on_vertex.front ()->common_vertex (on_vertex [1]);

} else if (tris.size () == size_t (1)) {

Expand Down Expand Up @@ -1624,16 +1635,14 @@ Triangulation::refine (const TriangulationParameters &parameters)

if (s > 0) {

double snap = 1e-3;

// Snap the center to a segment center if "close" to it.
// This avoids generating very skinny triangles that can't be fixed as the
// segment cannot be flipped. This a part of the issue #1996 problem.
for (unsigned int i = 0; i < 3; ++i) {
if ((*t)->edge (i)->is_segment ()) {
auto e = (*t)->edge (i)->edge ();
auto c = e.p1 () + e.d () * 0.5;
if (c.distance (center) < e.length () * 0.5 * snap - db::epsilon) {
if (c.distance (center) < e.length () * 0.5 * snap_to_edge_center - db::epsilon) {
center = c;
break;
}
Expand Down
60 changes: 60 additions & 0 deletions src/db/unit_tests/dbPLCTriangulationTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,65 @@ TEST(triangulate_issue1996)
EXPECT_LT (plc.num_polygons (), size_t (132000));
}

TEST(triangulate_discussion_2883)
{
db::DPoint contour[] = {
db::DPoint (-13025.428, -33338.541),
db::DPoint (-13127.959, -33236.01),
db::DPoint (-13132.732, -33240.783),
db::DPoint (-13135.914, -33237.601),
db::DPoint (-13026.136, -33127.823),
db::DPoint (-12923.605, -33230.354),
db::DPoint (-12920.423, -33227.172),
db::DPoint (-13022.954, -33124.641),
db::DPoint (-13014.999, -33116.686),
db::DPoint (-13011.817, -33119.868),
db::DPoint (-13016.59, -33124.641),
db::DPoint (-12914.059, -33227.172),
db::DPoint (-12923.605, -33236.718),
db::DPoint (-13026.136, -33134.187),
db::DPoint (-13029.317, -33137.369),
db::DPoint (-12926.787, -33239.899),
db::DPoint (-12936.333, -33249.445),
db::DPoint (-13038.863, -33146.915),
db::DPoint (-13042.045, -33150.097),
db::DPoint (-12939.515, -33252.627),
db::DPoint (-12949.061, -33262.173),
db::DPoint (-13051.591, -33159.643),
db::DPoint (-13054.773, -33162.825),
db::DPoint (-12952.243, -33265.355),
db::DPoint (-13012.701, -33325.813),
db::DPoint (-13115.231, -33223.283),
db::DPoint (-13118.413, -33226.464),
db::DPoint (-13015.882, -33328.995)
};

db::DPolygon poly;
poly.assign_hull (contour + 0, contour + sizeof (contour) / sizeof (contour[0]));

double dbu = 0.001;

db::plc::TriangulationParameters param;
param.min_b = 0.3;

db::plc::Graph plc;
TestableTriangulation tri (&plc);
db::DCplxTrans trans = db::DCplxTrans (dbu) * db::DCplxTrans (db::DTrans (db::DPoint () - poly.box ().center ()));
tri.triangulate (trans * poly, param);

EXPECT_EQ (tri.check (false), true);

// for debugging:
// tri.dump ("debug.gds");

for (auto t = plc.begin (); t != plc.end (); ++t) {
EXPECT_GE (t->b (), param.min_b);
}

EXPECT_GE (plc.num_polygons (), size_t (70));
EXPECT_LE (plc.num_polygons (), size_t (72));
}

TEST(triangulate_with_vertexes)
{
db::Point contour[] = {
Expand Down Expand Up @@ -1172,3 +1231,4 @@ TEST(triangulate_with_vertexes)
}
}
}

Binary file modified testdata/algo/hm_decomposition_au2.gds
Binary file not shown.
Binary file modified testdata/algo/hm_decomposition_au3.gds
Binary file not shown.
Binary file modified testdata/algo/hm_decomposition_au4.gds
Binary file not shown.
Binary file modified testdata/algo/hm_decomposition_au5.gds
Binary file not shown.
Binary file modified testdata/algo/hm_decomposition_au7.gds
Binary file not shown.
Loading