mirror of https://github.com/KLayout/klayout.git
Fixed #198 (DXF contour stitching renders fuzzy polygons)
This commit is contained in:
parent
9539e36bc9
commit
f4b2a015dc
|
|
@ -110,40 +110,93 @@ EdgesToContours::contour (size_t i) const
|
|||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
template <class C>
|
||||
class point_matcher
|
||||
{
|
||||
public:
|
||||
|
||||
point_matcher () : m_vp_min (0.0), m_d_min (0.0), m_any (false), m_any_coincident (false)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A search criterion for fitting next edges for a point (with attached edge)
|
||||
* This search will select the edge whose starting point is closest to the
|
||||
* end point of the reference edge and - if both points are coincident - forms
|
||||
* the smallest angle with the reference edge.
|
||||
*/
|
||||
bool more (const db::point<C> &p, const db::edge<C> &e, const db::edge<C> &other, bool swapped)
|
||||
{
|
||||
typedef db::coord_traits<C> coord_traits;
|
||||
|
||||
double d = p.double_distance (swapped ? other.p2 () : other.p1 ());
|
||||
bool coincident = d < coord_traits::prec ();
|
||||
|
||||
if (coincident) {
|
||||
|
||||
double vp = db::vprod (other.d (), e.d ()) * (1.0 / other.d ().double_length ());
|
||||
if (! m_any_coincident || vp < m_vp_min) {
|
||||
m_any_coincident = true;
|
||||
m_vp_min = vp;
|
||||
m_d_min = 0.0;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (! m_any_coincident) {
|
||||
|
||||
if (! m_any || d < m_d_min) {
|
||||
m_any = true;
|
||||
m_d_min = d;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
double m_vp_min;
|
||||
double m_d_min;
|
||||
bool m_any, m_any_coincident;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <class Iter, class C> static
|
||||
EdgeRef<Iter> *search_follower (const db::point<C> &p, const EdgeRef<Iter> *e, C distance, const db::box_tree<db::box<C>, EdgeRef<Iter> *, EdgeRefToBox<Iter, false> > &t1, const db::box_tree<db::box<C>, EdgeRef<Iter> *, EdgeRefToBox<Iter, true> > &t2)
|
||||
{
|
||||
typedef db::box<C> box_type;
|
||||
|
||||
double vp_min = 0.0;
|
||||
EdgeRef<Iter> *cand = 0;
|
||||
bool fwd = true;
|
||||
point_matcher<C> pm;
|
||||
|
||||
// try in forward tree
|
||||
|
||||
typename db::box_tree<box_type, EdgeRef<Iter> *, EdgeRefToBox<Iter, false> >::touching_iterator f = t1.begin_touching (box_type (p, p), EdgeRefToBox <Iter, false> (distance));
|
||||
while (! f.at_end ()) {
|
||||
if (*f != e && ! (*f)->connected && (*f)->swapped != 1) {
|
||||
double vp = db::vprod ((*f)->iter->d (), e->iter->d ()) * (1.0 / (*f)->iter->d ().double_length ());
|
||||
if (! cand || vp < vp_min) {
|
||||
vp_min = vp;
|
||||
if (*f != e && ! (*f)->connected && (*f)->swapped != 1 && pm.more (p, *e->iter, *(*f)->iter, false)) {
|
||||
cand = *f;
|
||||
}
|
||||
}
|
||||
++f;
|
||||
}
|
||||
|
||||
if (! t2.empty ()) {
|
||||
typename db::box_tree<box_type, EdgeRef<Iter> *, EdgeRefToBox<Iter, true> >::touching_iterator f = t2.begin_touching (box_type (p, p), EdgeRefToBox <Iter, true> (distance));
|
||||
while (! f.at_end ()) {
|
||||
if (*f != e && ! (*f)->connected && (*f)->swapped != -1) {
|
||||
double vp = db::vprod ((*f)->iter->d (), e->iter->d ()) * (1.0 / (*f)->iter->d ().double_length ());
|
||||
if (! cand || vp < vp_min) {
|
||||
vp_min = vp;
|
||||
if (*f != e && ! (*f)->connected && (*f)->swapped != -1 && pm.more (p, *e->iter, *(*f)->iter, true)) {
|
||||
cand = *f;
|
||||
fwd = false;
|
||||
}
|
||||
}
|
||||
++f;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -461,3 +461,26 @@ TEST(31)
|
|||
run_test (_this, "t31.dxf.gz", "t31d_au.gds.gz", opt);
|
||||
}
|
||||
|
||||
// issue #198
|
||||
TEST(32)
|
||||
{
|
||||
db::DXFReaderOptions opt;
|
||||
opt.layer_map = string2lm ("L11D0:1,L12D0:2");
|
||||
opt.create_other_layers = false;
|
||||
opt.polyline_mode = 3;
|
||||
|
||||
opt.contour_accuracy = 0.0;
|
||||
run_test_public (_this, "round_path.dxf.gz", "t32a_au.gds.gz", opt);
|
||||
|
||||
opt.contour_accuracy = 0.1;
|
||||
run_test_public (_this, "round_path.dxf.gz", "t32b_au.gds.gz", opt);
|
||||
|
||||
opt.contour_accuracy = 1.0;
|
||||
run_test_public (_this, "round_path.dxf.gz", "t32c_au.gds.gz", opt);
|
||||
|
||||
opt.polyline_mode = 4;
|
||||
run_test_public (_this, "round_path.dxf.gz", "t32d_au.gds.gz", opt);
|
||||
|
||||
opt.polyline_mode = 2;
|
||||
run_test_public (_this, "round_path.dxf.gz", "t32e_au.gds.gz", opt);
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue