mirror of https://github.com/KLayout/klayout.git
Compare commits
4 Commits
f80c51bfd2
...
42230de353
| Author | SHA1 | Date |
|---|---|---|
|
|
42230de353 | |
|
|
4ee73b5f86 | |
|
|
853a7d7a13 | |
|
|
eb06679c44 |
|
|
@ -110,6 +110,17 @@ Vertex::is_outside () const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Vertex::is_on_outline () const
|
||||
{
|
||||
for (auto e = mp_edges.begin (); e != mp_edges.end (); ++e) {
|
||||
if ((*e)->is_segment ()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Vertex::set_is_precious (bool f, unsigned int id)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -96,6 +96,11 @@ public:
|
|||
*/
|
||||
bool is_outside () const;
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether is on the outline - i.e. one edge is a segment
|
||||
*/
|
||||
bool is_on_outline () const;
|
||||
|
||||
/**
|
||||
* @brief Gets a list of polygons that are attached to this vertex
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
// #define DEBUG_DUMP_ESSENTIAL_EDGES
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
|
|
@ -286,16 +288,23 @@ ConvexDecomposition::hertel_mehlhorn_decomposition (Triangulation &tris, const C
|
|||
// them one-by-one, but using them in length order, from the
|
||||
|
||||
std::unordered_set<const Edge *> essential_edges;
|
||||
std::unordered_set<const Vertex *> concave_vertexes_seen;
|
||||
|
||||
while (! concave_vertexes.empty ()) {
|
||||
|
||||
typedef std::list<std::pair<double, const Edge *> > angles_and_edges_list;
|
||||
angles_and_edges_list angles_and_edges;
|
||||
std::vector<angles_and_edges_list::iterator> sorted_edges;
|
||||
|
||||
std::unordered_set<const Vertex *> new_inner_vertexes;
|
||||
|
||||
for (auto cc = concave_vertexes.begin (); cc != concave_vertexes.end (); ++cc) {
|
||||
|
||||
angles_and_edges.clear ();
|
||||
const Vertex *v0 = cc->corner;
|
||||
|
||||
concave_vertexes_seen.insert (v0);
|
||||
|
||||
const Edge *e = cc->incoming;
|
||||
while (e) {
|
||||
|
||||
|
|
@ -340,11 +349,73 @@ ConvexDecomposition::hertel_mehlhorn_decomposition (Triangulation &tris, const C
|
|||
for (auto i = angles_and_edges.begin (); i != angles_and_edges.end (); ++i) {
|
||||
if (i->second) {
|
||||
essential_edges.insert (i->second);
|
||||
// record new endpoints of essential edges which are inside the polygon - i.e. they
|
||||
// have a segment attached. Below we will turn them into new concave "corners" and
|
||||
// continue deriving essential edges from there.
|
||||
if (! i->second->v1 ()->is_on_outline () && concave_vertexes_seen.find (i->second->v1 ()) == concave_vertexes_seen.end ()) {
|
||||
new_inner_vertexes.insert (i->second->v1 ());
|
||||
}
|
||||
if (! i->second->v2 ()->is_on_outline () && concave_vertexes_seen.find (i->second->v2 ()) == concave_vertexes_seen.end ()) {
|
||||
new_inner_vertexes.insert (i->second->v2 ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// new inner vertexes (i.e. endpoints of essential edges inside the polygon) are treated as new convex vertexes
|
||||
|
||||
concave_vertexes.clear ();
|
||||
|
||||
for (auto i = new_inner_vertexes.begin (); i != new_inner_vertexes.end (); ++i) {
|
||||
|
||||
const Vertex *v0 = *i;
|
||||
auto ie = v0->begin_edges ();
|
||||
for ( ; ie != v0->end_edges () && essential_edges.find (*ie) == essential_edges.end (); ++ie)
|
||||
;
|
||||
tl_assert (ie != v0->end_edges ());
|
||||
const Edge *e = *ie;
|
||||
|
||||
const Edge *en = e;
|
||||
|
||||
do {
|
||||
|
||||
const Edge *enn = en;
|
||||
|
||||
// look for the next edge (clockwise) which is an essential edge
|
||||
do {
|
||||
const Polygon *t = enn->v2 () == v0 ? enn->right () : enn->left ();
|
||||
tl_assert (t != 0);
|
||||
enn = t->next_edge (enn, v0);
|
||||
tl_assert (enn != 0);
|
||||
} while (enn != en && essential_edges.find (enn) == essential_edges.end ());
|
||||
|
||||
db::DEdge e1 (*en->other (v0), *v0);
|
||||
db::DEdge e2 (*v0, *enn->other (v0));
|
||||
|
||||
// vp > 0: concave, vp < 0: convex
|
||||
int vp_sign = db::vprod_sign (e1, e2);
|
||||
if (vp_sign > 0 || en == enn /*folding back*/) {
|
||||
concave_vertexes.push_back (ConcaveCorner (v0, en, enn));
|
||||
}
|
||||
|
||||
en = enn;
|
||||
|
||||
} while (en != e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if defined(DEBUG_DUMP_ESSENTIAL_EDGES)
|
||||
// dump the essential edges for debugging
|
||||
db::Edges edges;
|
||||
for (auto e = essential_edges.begin (); e != essential_edges.end (); ++e) {
|
||||
db::DEdge de = (*e)->edge ();
|
||||
edges.insert (db::VCplxTrans (1000.0) * de);
|
||||
}
|
||||
edges.write ("debug_dump_essential_edges.gds");
|
||||
#endif
|
||||
|
||||
// Combine triangles, but don't cross essential edges
|
||||
|
||||
std::unordered_set<const Polygon *> left_triangles;
|
||||
|
|
|
|||
|
|
@ -136,14 +136,14 @@ private:
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
ConcaveCorner (Vertex *_corner, Edge *_incoming, Edge *_outgoing)
|
||||
ConcaveCorner (const Vertex *_corner, const Edge *_incoming, const Edge *_outgoing)
|
||||
: corner (_corner), incoming (_incoming), outgoing (_outgoing)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Vertex *corner;
|
||||
Edge *incoming, *outgoing;
|
||||
const Vertex *corner;
|
||||
const Edge *incoming, *outgoing;
|
||||
};
|
||||
|
||||
void hertel_mehlhorn_decomposition (Triangulation &tris, const ConvexDecompositionParameters ¶m);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include "dbPLCConvexDecomposition.h"
|
||||
#include "dbWriter.h"
|
||||
#include "dbReader.h"
|
||||
#include "dbLayout.h"
|
||||
#include "dbRegionProcessors.h"
|
||||
#include "dbTestSupport.h"
|
||||
#include "tlUnitTest.h"
|
||||
|
|
@ -144,3 +146,80 @@ TEST(problematic_polygon)
|
|||
db::compare_layouts (_this, *ly, tl::testdata () + "/algo/hm_decomposition_au5.gds");
|
||||
}
|
||||
|
||||
TEST(problematic_polygon2)
|
||||
{
|
||||
db::Point contour[] = {
|
||||
db::Point (-2100, 200),
|
||||
db::Point (-2100, 2000),
|
||||
db::Point (-500, 2000),
|
||||
db::Point (-500, 1700),
|
||||
db::Point (-849, 1700),
|
||||
db::Point (-947, 1690),
|
||||
db::Point (-1043, 1671),
|
||||
db::Point (-1137, 1643),
|
||||
db::Point (-1228, 1605),
|
||||
db::Point (-1315, 1559),
|
||||
db::Point (-1396, 1504),
|
||||
db::Point (-1472, 1442),
|
||||
db::Point (-1542, 1372),
|
||||
db::Point (-1604, 1296),
|
||||
db::Point (-1659, 1215),
|
||||
db::Point (-1705, 1128),
|
||||
db::Point (-1743, 1037),
|
||||
db::Point (-1771, 943),
|
||||
db::Point (-1790, 847),
|
||||
db::Point (-1800, 749),
|
||||
db::Point (-1800, 200)
|
||||
};
|
||||
|
||||
db::Polygon poly;
|
||||
poly.assign_hull (contour + 0, contour + sizeof (contour) / sizeof (contour[0]));
|
||||
|
||||
double dbu = 0.001;
|
||||
|
||||
db::plc::ConvexDecompositionParameters param;
|
||||
param.with_segments = false;
|
||||
param.split_edges = false;
|
||||
param.tri_param.max_area = 1000000;
|
||||
param.tri_param.min_b = 0.5;
|
||||
|
||||
db::plc::Graph plc;
|
||||
TestableConvexDecomposition decomp (&plc);
|
||||
|
||||
decomp.decompose (poly, param, dbu);
|
||||
|
||||
std::unique_ptr<db::Layout> ly (plc.to_layout ());
|
||||
db::compare_layouts (_this, *ly, tl::testdata () + "/algo/hm_decomposition_au6.gds");
|
||||
}
|
||||
|
||||
TEST(polygon_with_holes)
|
||||
{
|
||||
db::Layout ly;
|
||||
tl::InputStream s (tl::testdata () + "/algo/hm_decomposition_7.gds");
|
||||
db::Reader reader (s);
|
||||
reader.read (ly);
|
||||
|
||||
unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0));
|
||||
const db::Cell &top = ly.cell (*ly.begin_top_down ());
|
||||
|
||||
db::Region r (db::RecursiveShapeIterator (ly, top, l1));
|
||||
r.merge ();
|
||||
db::Polygon poly = *r.begin ();
|
||||
|
||||
double dbu = 0.001;
|
||||
|
||||
db::plc::ConvexDecompositionParameters param;
|
||||
param.with_segments = false;
|
||||
param.split_edges = false;
|
||||
param.tri_param.max_area = 1000000;
|
||||
param.tri_param.min_b = 0.5;
|
||||
|
||||
db::plc::Graph plc;
|
||||
TestableConvexDecomposition decomp (&plc);
|
||||
|
||||
decomp.decompose (poly, param, dbu);
|
||||
|
||||
std::unique_ptr<db::Layout> ly_out (plc.to_layout ());
|
||||
db::compare_layouts (_this, *ly_out, tl::testdata () + "/algo/hm_decomposition_au7.gds");
|
||||
}
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue