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
8 changes: 4 additions & 4 deletions src/db/db/dbPLC.cc
Original file line number Diff line number Diff line change
Expand Up @@ -903,10 +903,10 @@ Graph::bbox () const
}

db::Layout *
Graph::to_layout (bool decompose_by_id) const
Graph::to_layout (bool decompose_by_id, double dbu) const
{
db::Layout *layout = new db::Layout ();
layout->dbu (0.001);
layout->dbu (dbu);

auto dbu_trans = db::CplxTrans (layout->dbu ()).inverted ();

Expand Down Expand Up @@ -950,9 +950,9 @@ Graph::to_layout (bool decompose_by_id) const
}

void
Graph::dump (const std::string &path, bool decompose_by_id) const
Graph::dump (const std::string &path, bool decompose_by_id, double dbu) const
{
std::unique_ptr<db::Layout> ly (to_layout (decompose_by_id));
std::unique_ptr<db::Layout> ly (to_layout (decompose_by_id, dbu));

tl::OutputStream stream (path);

Expand Down
4 changes: 2 additions & 2 deletions src/db/db/dbPLC.h
Original file line number Diff line number Diff line change
Expand Up @@ -879,13 +879,13 @@ class DB_PUBLIC Graph
* according to bit 0, 1 and 2 of the ID (useful with the 'mark_polygons'
* flat in TriangulateParameters).
*/
void dump (const std::string &path, bool decompose_by_id = false) const;
void dump (const std::string &path, bool decompose_by_id = false, double dbu = 0.001) const;

/**
* @brief Creates a new layout object representing the polygon graph
* This method is for testing purposes mainly.
*/
db::Layout *to_layout (bool decompose_by_id = false) const;
db::Layout *to_layout (bool decompose_by_id = false, double dbu = 0.001) const;

protected:
Vertex *create_vertex (double x, double y);
Expand Down
117 changes: 69 additions & 48 deletions src/db/db/dbPLCTriangulation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,8 @@ 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;
const double snap_to_edge_center = 1e-3;


Triangulation::Triangulation (Graph *graph)
Expand Down Expand Up @@ -238,70 +235,67 @@ Triangulation::insert_point (db::DCoord x, db::DCoord y, std::list<tl::weak_ptr<
Vertex *
Triangulation::insert (Vertex *vertex, std::list<tl::weak_ptr<Polygon> > *new_triangles)
{
std::vector<Polygon *> tris = find_triangle_for_point (*vertex);
Polygon *in_triangle = 0;
Edge *on_edge = 0;

if (! find_triangle_for_point (*vertex, in_triangle, on_edge)) {

// the new vertex is outside the domain
if (tris.empty ()) {
// the new vertex is outside the domain
tl_assert (! m_is_constrained);
insert_new_vertex (vertex, new_triangles);
return vertex;
}

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

Edge *e = tris.front ()->edge (i);

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 if (! on_edge) {
on_edge = e;
}
}

}

if (on_edge) {

split_triangles_on_edge (vertex, on_edge, new_triangles);
return vertex;
if (is_equal (*vertex, *on_edge->v1 ())) {
return on_edge->v1 ();
} else if (is_equal (*vertex, *on_edge->v2 ())) {
return on_edge->v2 ();
} else {
split_triangles_on_edge (vertex, on_edge, new_triangles);
return vertex;
}

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

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

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

// the new vertex is inside one triangle
split_triangle (tris.front (), vertex, new_triangles);
return vertex;
tl_assert (false);
return 0;

}

tl_assert (false);
}

std::vector<Polygon *>
Triangulation::find_triangle_for_point (const db::DPoint &point)
bool Triangulation::find_triangle_for_point (const db::DPoint &point, Polygon *&in_triangle, Edge *&on_edge)
{
Edge *edge = find_closest_edge (point);

std::vector<Polygon *> res;
if (edge) {
for (auto t = edge->begin_polygons (); t != edge->end_polygons (); ++t) {
if (t->contains (point) >= 0) {
res.push_back (t.operator-> ());

if (edge->side_of (point) == 0) {

on_edge = edge;
return true;

} else {

for (auto t = edge->begin_polygons (); t != edge->end_polygons (); ++t) {
if (t->contains (point) >= 0) {
in_triangle = t.operator-> ();
return true;
}
}

}

}

return res;
return false;
}

Edge *
Expand Down Expand Up @@ -1140,17 +1134,23 @@ static bool is_touching (const db::DEdge &a, const db::DEdge &b)
std::vector<Edge *>
Triangulation::ensure_edge_inner (Vertex *from, Vertex *to)
{
auto crossed_edges = search_edges_crossing (from, to);
std::vector<Edge *> result;

// check if there is an edge already
Edge *already_there = find_edge_for_points (*from, *to);
if (already_there) {
result.push_back (already_there);
return result;
}

auto crossed_edges = search_edges_crossing (from, to);

db::DEdge dedge (*from , *to);

if (crossed_edges.empty ()) {

// no crossing edge - there should be a edge already
Edge *res = find_edge_for_points (*from, *to);
tl_assert (res != 0);
result.push_back (res);
tl_assert (false);

} else if (crossed_edges.size () == 1 && ! is_touching (dedge, crossed_edges.front ()->edge ())) {

Expand All @@ -1171,7 +1171,7 @@ Triangulation::ensure_edge_inner (Vertex *from, Vertex *to)
db::DPoint p = (*e)->intersection_point (dedge);
double dp = fabs ((p - *from).sq_length () - l_half);
if (d < 0.0 || dp < d) {
dp = d;
d = dp;
split_point = p;
split_edge = *e;
}
Expand Down Expand Up @@ -1396,6 +1396,9 @@ template DB_PUBLIC void Triangulation::make_contours (const db::DPolygon &, cons
void
Triangulation::create_constrained_delaunay (const db::Region &region, const CplxTrans &trans)
{
std::vector<std::vector<Vertex *> > box_contours;
make_contours (db::Polygon (region.bbox ()), trans, box_contours);

std::vector<std::vector<Vertex *> > edge_contours;

for (auto p = region.begin_merged (); ! p.at_end (); ++p) {
Expand All @@ -1408,6 +1411,9 @@ Triangulation::create_constrained_delaunay (const db::Region &region, const Cplx
void
Triangulation::create_constrained_delaunay (const db::Polygon &p, const CplxTrans &trans)
{
std::vector<std::vector<Vertex *> > box_contours;
make_contours (db::Polygon (p.box ()), trans, box_contours);

std::vector<std::vector<Vertex *> > edge_contours;
make_contours (p, trans, edge_contours);

Expand All @@ -1417,6 +1423,9 @@ Triangulation::create_constrained_delaunay (const db::Polygon &p, const CplxTran
void
Triangulation::create_constrained_delaunay (const db::DPolygon &p, const DCplxTrans &trans)
{
std::vector<std::vector<Vertex *> > box_contours;
make_contours (db::DPolygon (p.box ()), trans, box_contours);

std::vector<std::vector<Vertex *> > edge_contours;
make_contours (p, trans, edge_contours);

Expand Down Expand Up @@ -1485,6 +1494,9 @@ Triangulation::triangulate (const db::Region &region, const std::vector<db::Poin

clear ();

std::vector<std::vector<Vertex *> > box_contours;
make_contours (db::Polygon (region.bbox ()), trans, box_contours);

std::vector<std::vector<Vertex *> > edge_contours;
for (auto p = region.begin_merged (); ! p.at_end (); ++p) {
make_contours (*p, trans, edge_contours);
Expand Down Expand Up @@ -1514,6 +1526,9 @@ Triangulation::triangulate (const db::Polygon &poly, const std::vector<db::Point

clear ();

std::vector<std::vector<Vertex *> > box_contours;
make_contours (db::Polygon (poly.box ()), trans, box_contours);

std::vector<std::vector<Vertex *> > edge_contours;
make_contours (poly, trans, edge_contours);

Expand All @@ -1539,6 +1554,9 @@ Triangulation::triangulate (const db::Polygon &poly, const std::vector<db::Point

clear ();

std::vector<std::vector<Vertex *> > box_contours;
make_contours (db::Polygon (poly.box ()), trans, box_contours);

std::vector<std::vector<Vertex *> > edge_contours;
make_contours (poly, trans, edge_contours);

Expand All @@ -1564,6 +1582,9 @@ Triangulation::triangulate (const db::DPolygon &poly, const std::vector<db::DPoi

clear ();

std::vector<std::vector<Vertex *> > box_contours;
make_contours (db::DPolygon (poly.box ()), trans, box_contours);

std::vector<std::vector<Vertex *> > edge_contours;
make_contours (poly, trans, edge_contours);

Expand Down
2 changes: 1 addition & 1 deletion src/db/db/dbPLCTriangulation.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ class DB_PUBLIC Triangulation
void remove_inside_vertex (Vertex *vertex, std::list<tl::weak_ptr<Polygon> > *new_triangles_out = 0);
std::vector<Polygon *> fill_concave_corners (const std::vector<Edge *> &edges);
void fix_triangles (const std::vector<Polygon *> &tris, const std::vector<Edge *> &fixed_edges, std::list<tl::weak_ptr<Polygon> > *new_triangles);
std::vector<Polygon *> find_triangle_for_point (const db::DPoint &point);
bool find_triangle_for_point (const db::DPoint &point, Polygon *&in_triangle, Edge *&on_edge);
Edge *find_closest_edge (const db::DPoint &p, Vertex *vstart = 0, bool inside_only = false) const;
Vertex *insert (Vertex *vertex, std::list<tl::weak_ptr<Polygon> > *new_triangles = 0);
void split_triangle (Polygon *t, Vertex *vertex, std::list<tl::weak_ptr<Polygon> > *new_triangles_out);
Expand Down
87 changes: 68 additions & 19 deletions src/db/unit_tests/dbPLCTriangulationTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -896,8 +896,8 @@ TEST(triangulate_geo)
}

EXPECT_LT (n_skinny, size_t (20));
EXPECT_GT (plc.num_polygons (), size_t (29000));
EXPECT_LT (plc.num_polygons (), size_t (30000));
EXPECT_GT (plc.num_polygons (), size_t (30000));
EXPECT_LT (plc.num_polygons (), size_t (30200));
}

TEST(triangulate_analytic)
Expand Down Expand Up @@ -951,8 +951,8 @@ TEST(triangulate_analytic)
EXPECT_GE (t->b (), param.min_b);
}

EXPECT_GT (plc.num_polygons (), size_t (1250));
EXPECT_LT (plc.num_polygons (), size_t (1300));
EXPECT_GT (plc.num_polygons (), size_t (1300));
EXPECT_LT (plc.num_polygons (), size_t (1340));
}

TEST(triangulate_problematic)
Expand Down Expand Up @@ -1078,7 +1078,7 @@ TEST(triangulate_issue1996)
EXPECT_LT (plc.num_polygons (), size_t (132000));
}

TEST(triangulate_discussion_2883)
TEST(triangulate_issue_2429)
{
db::DPoint contour[] = {
db::DPoint (-13025.428, -33338.541),
Expand Down Expand Up @@ -1114,27 +1114,76 @@ TEST(triangulate_discussion_2883)
db::DPolygon poly;
poly.assign_hull (contour + 0, contour + sizeof (contour) / sizeof (contour[0]));

double dbu = 0.001;
double dbu = 1.0;

db::plc::TriangulationParameters param;
param.min_b = 0.3;
{
db::plc::TriangulationParameters param;
param.min_b = 0.3;
param.max_area = 0.0;

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);
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);
EXPECT_EQ (tri.check (false), true);

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

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

EXPECT_GE (plc.num_polygons (), size_t (65));
EXPECT_LE (plc.num_polygons (), size_t (67));
}

EXPECT_GE (plc.num_polygons (), size_t (70));
EXPECT_LE (plc.num_polygons (), size_t (72));
{
db::plc::TriangulationParameters param;
param.min_b = 0.3;
param.max_area = 500.0;

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 (94));
EXPECT_LE (plc.num_polygons (), size_t (96));
}

{
db::plc::TriangulationParameters param;
param.min_b = 0.9;
param.max_area = 50.0;

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 (670));
EXPECT_LE (plc.num_polygons (), size_t (676));
}
}

TEST(triangulate_with_vertexes)
Expand Down
Loading
Loading