mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
0941bc214c
commit
1756ddfafa
|
|
@ -33,7 +33,7 @@ namespace db
|
||||||
{
|
{
|
||||||
|
|
||||||
Triangles::Triangles ()
|
Triangles::Triangles ()
|
||||||
: m_is_constrained (false)
|
: m_is_constrained (false), m_level (0)
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
@ -488,15 +488,114 @@ Triangles::remove_inside_vertex (db::Vertex *vertex, std::vector<db::Triangle *>
|
||||||
fix_triangles (triangles_to_fix, std::vector<db::TriangleEdge *> (), new_triangles_out);
|
fix_triangles (triangles_to_fix, std::vector<db::TriangleEdge *> (), new_triangles_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
Triangles::fix_triangles (const std::vector<db::Triangle *> &tris, const std::vector<db::TriangleEdge *> &fixed_edges, std::vector<db::Triangle *> *new_triangles)
|
Triangles::fix_triangles (const std::vector<db::Triangle *> &tris, const std::vector<db::TriangleEdge *> &fixed_edges, std::vector<db::Triangle *> *new_triangles)
|
||||||
{
|
{
|
||||||
|
int flips = 0;
|
||||||
|
|
||||||
// @@@
|
m_level += 1;
|
||||||
|
for (auto e = fixed_edges.begin (); e != fixed_edges.end (); ++e) {
|
||||||
|
(*e)->set_level (m_level);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<db::TriangleEdge *> queue, todo;
|
||||||
|
|
||||||
|
for (auto t = tris.begin (); t != tris.end (); ++t) {
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
db::TriangleEdge *e = (*t)->edge (i);
|
||||||
|
if (e->level () < m_level && ! e->is_segment ()) {
|
||||||
|
queue.push_back (e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (! queue.empty ()) {
|
||||||
|
|
||||||
|
todo.clear ();
|
||||||
|
todo.swap (queue);
|
||||||
|
std::set<db::TriangleEdge *> queued;
|
||||||
|
|
||||||
|
// NOTE: we cannot be sure that already treated edges will not become
|
||||||
|
// illegal by neighbor edges flipping ..
|
||||||
|
// for s in todo:
|
||||||
|
// s.level = self.level
|
||||||
|
|
||||||
|
for (auto e = todo.begin (); e != todo.end (); ++e) {
|
||||||
|
|
||||||
|
if (is_illegal_edge (*e)) {
|
||||||
|
|
||||||
|
queued.erase (*e);
|
||||||
|
|
||||||
|
auto pp = flip (*e);
|
||||||
|
auto t1 = pp.first.first;
|
||||||
|
auto t2 = pp.first.second;
|
||||||
|
auto s12 = pp.second;
|
||||||
|
|
||||||
|
if (new_triangles) {
|
||||||
|
new_triangles->push_back (t1);
|
||||||
|
new_triangles->push_back (t2);
|
||||||
|
}
|
||||||
|
|
||||||
|
++flips;
|
||||||
|
tl_assert (! is_illegal_edge (s12)); // @@@ remove later!
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
db::TriangleEdge *s1 = t1->edge (i);
|
||||||
|
if (s1->level () < m_level && ! s1->is_segment () && queued.find (s1) == queued.end ()) {
|
||||||
|
queue.push_back (s1);
|
||||||
|
queued.insert (s1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
db::TriangleEdge *s2 = t2->edge (i);
|
||||||
|
if (s2->level () < m_level && ! s2->is_segment () && queued.find (s2) == queued.end ()) {
|
||||||
|
queue.push_back (s2);
|
||||||
|
queued.insert (s2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::pair<Triangle *, Triangle *>, TriangleEdge *> Triangles::flip (TriangleEdge *edge)
|
}
|
||||||
|
|
||||||
|
std::vector<db::TriangleEdge *>::iterator wp = queue.begin ();
|
||||||
|
for (auto e = queue.begin (); e != queue.end (); ++e) {
|
||||||
|
if (queued.find (*e) != queued.end ()) {
|
||||||
|
*wp++ = *e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
queue.erase (wp, queue.end ());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return flips;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Triangles::is_illegal_edge (db::TriangleEdge *edge)
|
||||||
|
{
|
||||||
|
db::Triangle *left = edge->left ();
|
||||||
|
db::Triangle *right = edge->right ();
|
||||||
|
if (!left || !right) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto lr = left->circumcircle ();
|
||||||
|
if (right->opposite (edge)->in_circle (lr.first, lr.second) > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto rr = right->circumcircle();
|
||||||
|
if (left->opposite (edge)->in_circle (rr.first, rr.second) > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<std::pair<Triangle *, Triangle *>, TriangleEdge *>
|
||||||
|
Triangles::flip (TriangleEdge *edge)
|
||||||
{
|
{
|
||||||
db::Triangle *t1 = edge->left ();
|
db::Triangle *t1 = edge->left ();
|
||||||
db::Triangle *t2 = edge->right ();
|
db::Triangle *t2 = edge->right ();
|
||||||
|
|
@ -973,51 +1072,6 @@ class Triangles(object):
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _fix_triangles(self, tris: [Triangle], fixed_edges: [TriangleEdge], new_triangles: [Triangle] = None):
|
|
||||||
|
|
||||||
flips = 0
|
|
||||||
|
|
||||||
self.level += 1
|
|
||||||
for s in fixed_edges:
|
|
||||||
s.level = self.level
|
|
||||||
|
|
||||||
queue = []
|
|
||||||
|
|
||||||
for t in tris:
|
|
||||||
for s in t.edges():
|
|
||||||
if s.level < self.level and not s.is_segment:
|
|
||||||
if s not in queue:
|
|
||||||
queue.append(s)
|
|
||||||
|
|
||||||
while not len(queue) == 0:
|
|
||||||
|
|
||||||
todo = queue
|
|
||||||
queue = []
|
|
||||||
|
|
||||||
# NOTE: we cannot be sure that already treated edges will not become
|
|
||||||
# illegal by neighbor edges flipping ..
|
|
||||||
# for s in todo:
|
|
||||||
# s.level = self.level
|
|
||||||
|
|
||||||
for s in todo:
|
|
||||||
if self._is_illegal_edge(s):
|
|
||||||
if s in queue:
|
|
||||||
queue.remove(s)
|
|
||||||
t1, t2, s12 = self.flip(s)
|
|
||||||
if new_triangles is not None:
|
|
||||||
new_triangles.append(t1)
|
|
||||||
new_triangles.append(t2)
|
|
||||||
flips += 1
|
|
||||||
assert(not self._is_illegal_edge(s12)) # @@@ TODO: remove later
|
|
||||||
for s1 in t1.edges():
|
|
||||||
if s1.level < self.level and not s1.is_segment and s1 not in queue:
|
|
||||||
queue.append(s1)
|
|
||||||
for s2 in t2.edges():
|
|
||||||
if s2.level < self.level and not s2.is_segment and s2 not in queue:
|
|
||||||
queue.append(s2)
|
|
||||||
|
|
||||||
return flips
|
|
||||||
|
|
||||||
def flipped_edge(self, s: TriangleEdge) -> Edge:
|
def flipped_edge(self, s: TriangleEdge) -> Edge:
|
||||||
|
|
||||||
return Edge(s.left.ext_vertex(s), s.right.ext_vertex(s))
|
return Edge(s.left.ext_vertex(s), s.right.ext_vertex(s))
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ private:
|
||||||
tl::weak_collection<db::TriangleEdge> mp_edges;
|
tl::weak_collection<db::TriangleEdge> mp_edges;
|
||||||
std::list<db::Vertex> m_vertex_heap;
|
std::list<db::Vertex> m_vertex_heap;
|
||||||
bool m_is_constrained;
|
bool m_is_constrained;
|
||||||
|
size_t m_level;
|
||||||
|
|
||||||
db::Vertex *create_vertex (double x, double y);
|
db::Vertex *create_vertex (double x, double y);
|
||||||
db::Vertex *create_vertex (const db::DPoint &pt);
|
db::Vertex *create_vertex (const db::DPoint &pt);
|
||||||
|
|
@ -79,8 +80,9 @@ private:
|
||||||
void remove_outside_vertex (db::Vertex *vertex, std::vector<db::Triangle *> *new_triangles = 0);
|
void remove_outside_vertex (db::Vertex *vertex, std::vector<db::Triangle *> *new_triangles = 0);
|
||||||
void remove_inside_vertex (db::Vertex *vertex, std::vector<db::Triangle *> *new_triangles_out = 0);
|
void remove_inside_vertex (db::Vertex *vertex, std::vector<db::Triangle *> *new_triangles_out = 0);
|
||||||
std::vector<db::Triangle *> fill_concave_corners (const std::vector<TriangleEdge *> &edges);
|
std::vector<db::Triangle *> fill_concave_corners (const std::vector<TriangleEdge *> &edges);
|
||||||
void fix_triangles (const std::vector<db::Triangle *> &tris, const std::vector<db::TriangleEdge *> &fixed_edges, std::vector<db::Triangle *> *new_triangles);
|
int fix_triangles(const std::vector<db::Triangle *> &tris, const std::vector<db::TriangleEdge *> &fixed_edges, std::vector<db::Triangle *> *new_triangles);
|
||||||
std::pair<std::pair<db::Triangle *, db::Triangle *>, db::TriangleEdge *> flip (TriangleEdge *edge);
|
std::pair<std::pair<db::Triangle *, db::Triangle *>, db::TriangleEdge *> flip (TriangleEdge *edge);
|
||||||
|
static bool is_illegal_edge (db::TriangleEdge *edge);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue