mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
745eb9b625
commit
88fd5ad8ca
|
|
@ -312,6 +312,12 @@ Triangles::insert_point (const db::DPoint &point, std::vector<db::Triangle *> *n
|
|||
return insert (create_vertex (point), new_triangles);
|
||||
}
|
||||
|
||||
db::Vertex *
|
||||
Triangles::insert_point (db::DCoord x, db::DCoord y, std::vector<db::Triangle *> *new_triangles)
|
||||
{
|
||||
return insert (create_vertex (x, y), new_triangles);
|
||||
}
|
||||
|
||||
db::Vertex *
|
||||
Triangles::insert (db::Vertex *vertex, std::vector<db::Triangle *> *new_triangles)
|
||||
{
|
||||
|
|
@ -443,6 +449,8 @@ Triangles::insert_new_vertex (db::Vertex *vertex, std::vector<db::Triangle *> *n
|
|||
{
|
||||
if (mp_triangles.empty ()) {
|
||||
|
||||
tl_assert (m_vertex_heap.size () <= size_t (3)); // fails if vertexes were created but not inserted.
|
||||
|
||||
if (m_vertex_heap.size () == 3) {
|
||||
|
||||
std::vector<db::Vertex *> vv;
|
||||
|
|
@ -1043,6 +1051,94 @@ Triangles::fill_concave_corners (const std::vector<db::TriangleEdge *> &edges)
|
|||
return res;
|
||||
}
|
||||
|
||||
std::vector<db::TriangleEdge *>
|
||||
Triangles::search_edges_crossing (Vertex *from, Vertex *to)
|
||||
{
|
||||
db::Vertex *v = from;
|
||||
db::Vertex *vv = to;
|
||||
db::DEdge edge (*from, *to);
|
||||
|
||||
db::Triangle *current_triangle = 0;
|
||||
db::TriangleEdge *next_edge = 0;
|
||||
|
||||
std::vector<db::TriangleEdge *> result;
|
||||
|
||||
for (auto e = v->begin_edges (); e != v->end_edges () && ! next_edge; ++e) {
|
||||
for (auto t = e->begin_triangles (); t != e->end_triangles (); ++t) {
|
||||
db::TriangleEdge *os = t->opposite (v);
|
||||
if (os->has_vertex (vv)) {
|
||||
return result;
|
||||
}
|
||||
if (os->crosses (edge)) {
|
||||
result.push_back (os);
|
||||
current_triangle = t.operator-> ();
|
||||
next_edge = os;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tl_assert (current_triangle != 0);
|
||||
|
||||
while (true) {
|
||||
|
||||
current_triangle = next_edge->other (current_triangle);
|
||||
|
||||
// Note that we're convex, so there has to be a path across triangles
|
||||
tl_assert (current_triangle != 0);
|
||||
|
||||
db::TriangleEdge *cs = next_edge;
|
||||
next_edge = 0;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
db::TriangleEdge *e = current_triangle->edge (i);
|
||||
if (e != cs) {
|
||||
if (e->has_vertex (vv)) {
|
||||
return result;
|
||||
}
|
||||
if (e->crosses (edge)) {
|
||||
result.push_back (e);
|
||||
next_edge = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tl_assert (next_edge != 0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
db::Vertex *
|
||||
Triangles::find_vertex_for_point (const db::DPoint &pt)
|
||||
{
|
||||
db::TriangleEdge *edge = find_closest_edge (pt);
|
||||
if (!edge) {
|
||||
return 0;
|
||||
}
|
||||
db::Vertex *v = 0;
|
||||
if (edge->v1 ()->equal (pt)) {
|
||||
v = edge->v1 ();
|
||||
} else if (edge->v2 ()->equal (pt)) {
|
||||
v = edge->v2 ();
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
db::TriangleEdge *
|
||||
Triangles::find_edge_for_points (const db::DPoint &p1, const db::DPoint &p2)
|
||||
{
|
||||
db::Vertex *v = find_vertex_for_point (p1);
|
||||
if (!v) {
|
||||
return 0;
|
||||
}
|
||||
for (auto e = v->begin_edges (); e != v->end_edges (); ++e) {
|
||||
if (e->other (v)->equal (p2)) {
|
||||
return const_cast <db::TriangleEdge *>(e.operator-> ());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
@ -1052,69 +1148,6 @@ from .triangle import *
|
|||
|
||||
class Triangles(object):
|
||||
|
||||
def find_edge_for_points(self, p1: Point, p2: Point) -> TriangleEdge:
|
||||
|
||||
v = self.find_vertex_for_point(p1)
|
||||
if v is None:
|
||||
return None
|
||||
for s in v.edges:
|
||||
if equals(s.other_vertex(v), p2):
|
||||
return s
|
||||
return None
|
||||
|
||||
def search_edges_crossing(self, edge: TriangleEdge) -> set:
|
||||
"""
|
||||
Finds all edges that cross the given one for a convex triangulation
|
||||
|
||||
Requirements:
|
||||
* self must be a convex triangulation
|
||||
* edge must not contain another vertex from the triangulation except p1 and p2
|
||||
"""
|
||||
|
||||
v = edge.p1
|
||||
vv = edge.p2
|
||||
|
||||
current_triangle = None
|
||||
next_edge = None
|
||||
|
||||
result = []
|
||||
|
||||
for s in v.edges:
|
||||
for t in [s.left, s.right]:
|
||||
if t is not None:
|
||||
os = t.opposite_edge(v)
|
||||
if os.has_vertex(vv):
|
||||
return result
|
||||
if os.crosses(edge):
|
||||
result.append(os)
|
||||
current_triangle = t
|
||||
next_edge = os
|
||||
break
|
||||
if next_edge is not None:
|
||||
break
|
||||
|
||||
assert (current_triangle is not None)
|
||||
|
||||
while True:
|
||||
|
||||
current_triangle = next_edge.other(current_triangle)
|
||||
|
||||
# Note that we're convex, so there has to be a path across triangles
|
||||
assert (current_triangle is not None)
|
||||
|
||||
cs = next_edge
|
||||
next_edge = None
|
||||
for s in current_triangle.edges():
|
||||
if s != cs:
|
||||
if s.has_vertex(vv):
|
||||
return result
|
||||
if s.crosses(edge):
|
||||
result.append(s)
|
||||
next_edge = s
|
||||
break
|
||||
|
||||
assert (next_edge is not None)
|
||||
|
||||
def _ensure_edge_inner(self, edge: Edge) -> [TriangleEdge]:
|
||||
|
||||
crossed_edges = self.search_edges_crossing(edge)
|
||||
|
|
|
|||
|
|
@ -94,24 +94,6 @@ public:
|
|||
*/
|
||||
db::Layout *to_layout () const;
|
||||
|
||||
/**
|
||||
* @brief Creates a new vertex object
|
||||
*
|
||||
* In order to insert the new vertex into the graph, use "insert".
|
||||
* Normally, "insert_point" should be used which creates a vertex and
|
||||
* inserts it.
|
||||
*/
|
||||
db::Vertex *create_vertex (double x, double y);
|
||||
|
||||
/**
|
||||
* @brief Creates a new vertex object
|
||||
*
|
||||
* In order to insert the new vertex into the graph, use "insert".
|
||||
* Normally, "insert_point" should be used which creates a vertex and
|
||||
* inserts it.
|
||||
*/
|
||||
db::Vertex *create_vertex (const db::DPoint &pt);
|
||||
|
||||
/**
|
||||
* @brief Finds the points within (not "on") a circle of radius "radius" around the given vertex.
|
||||
*/
|
||||
|
|
@ -126,15 +108,12 @@ public:
|
|||
db::Vertex *insert_point (const db::DPoint &point, std::vector<db::Triangle *> *new_triangles = 0);
|
||||
|
||||
/**
|
||||
* @brief Inserts the given vertex
|
||||
* @brief Inserts a new vertex as the given point
|
||||
*
|
||||
* If "new_triangles" is not null, it will receive the list of new triangles created during
|
||||
* the remove step.
|
||||
* The return value is the actual vertex created. It is no necessarily the one passed. When
|
||||
* a vertex already exists at the given location, the input vertex is ignored and the present
|
||||
* vertex is returned.
|
||||
*/
|
||||
db::Vertex *insert (db::Vertex *vertex, std::vector<db::Triangle *> *new_triangles = 0);
|
||||
db::Vertex *insert_point (db::DCoord x, db::DCoord y, std::vector<db::Triangle *> *new_triangles = 0);
|
||||
|
||||
/**
|
||||
* @brief Removes the given vertex
|
||||
|
|
@ -146,8 +125,31 @@ public:
|
|||
|
||||
|
||||
// exposed for testing purposes:
|
||||
|
||||
/**
|
||||
* @brief Flips the given edge
|
||||
*/
|
||||
std::pair<std::pair<db::Triangle *, db::Triangle *>, db::TriangleEdge *> flip (TriangleEdge *edge);
|
||||
|
||||
/**
|
||||
* @brief Finds all edges that cross the given one for a convex triangulation
|
||||
*
|
||||
* Requirements:
|
||||
* * self must be a convex triangulation
|
||||
* * edge must not contain another vertex from the triangulation except p1 and p2
|
||||
*/
|
||||
std::vector<db::TriangleEdge *> search_edges_crossing (db::Vertex *from, db::Vertex *to);
|
||||
|
||||
/**
|
||||
* @brief Finds the edge for two given points
|
||||
*/
|
||||
db::TriangleEdge *find_edge_for_points (const db::DPoint &p1, const db::DPoint &p2);
|
||||
|
||||
/**
|
||||
* @brief Finds the vertex for a point
|
||||
*/
|
||||
db::Vertex *find_vertex_for_point (const db::DPoint &pt);
|
||||
|
||||
private:
|
||||
tl::shared_collection<db::Triangle> mp_triangles;
|
||||
tl::weak_collection<db::TriangleEdge> mp_edges;
|
||||
|
|
@ -155,6 +157,8 @@ private:
|
|||
bool m_is_constrained;
|
||||
size_t m_level;
|
||||
|
||||
db::Vertex *create_vertex (double x, double y);
|
||||
db::Vertex *create_vertex (const db::DPoint &pt);
|
||||
db::TriangleEdge *create_edge (db::Vertex *v1, db::Vertex *v2);
|
||||
db::Triangle *create_triangle (db::TriangleEdge *e1, db::TriangleEdge *e2, db::TriangleEdge *e3);
|
||||
void remove (db::Triangle *tri);
|
||||
|
|
@ -170,6 +174,7 @@ private:
|
|||
static bool is_illegal_edge (db::TriangleEdge *edge);
|
||||
std::vector<db::Triangle *> find_triangle_for_point (const db::DPoint &point);
|
||||
db::TriangleEdge *find_closest_edge (const db::DPoint &p, db::Vertex *vstart = 0, bool inside_only = false);
|
||||
db::Vertex *insert (db::Vertex *vertex, std::vector<db::Triangle *> *new_triangles = 0);
|
||||
void split_triangle (db::Triangle *t, db::Vertex *vertex, std::vector<db::Triangle *> *new_triangles_out);
|
||||
void split_triangles_on_edge (const std::vector<db::Triangle *> &tris, db::Vertex *vertex, db::TriangleEdge *split_edge, std::vector<db::Triangle *> *new_triangles_out);
|
||||
void add_more_triangles (std::vector<Triangle *> &new_triangles,
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ TEST(Triangle_insert)
|
|||
db::Triangles tris;
|
||||
tris.init_box (db::DBox (0, 0, 1, 1));
|
||||
|
||||
tris.insert (tris.create_vertex (0.2, 0.2));
|
||||
tris.insert_point (0.2, 0.2);
|
||||
EXPECT_EQ (tris.to_string (), "((0, 0), (0, 1), (0.2, 0.2)), ((1, 0), (0, 0), (0.2, 0.2)), ((1, 1), (0.2, 0.2), (0, 1)), ((1, 1), (1, 0), (0.2, 0.2))");
|
||||
EXPECT_EQ (tris.check (), true);
|
||||
}
|
||||
|
|
@ -71,7 +71,7 @@ TEST(Triangle_split_segment)
|
|||
db::Triangles tris;
|
||||
tris.init_box (db::DBox (0, 0, 1, 1));
|
||||
|
||||
tris.insert (tris.create_vertex (0.5, 0.5));
|
||||
tris.insert_point (0.5, 0.5);
|
||||
EXPECT_EQ (tris.to_string (), "((1, 1), (1, 0), (0.5, 0.5)), ((1, 1), (0.5, 0.5), (0, 1)), ((0, 0), (0, 1), (0.5, 0.5)), ((0, 0), (0.5, 0.5), (1, 0))");
|
||||
EXPECT_EQ (tris.check(), true);
|
||||
}
|
||||
|
|
@ -81,9 +81,9 @@ TEST(Triangle_insert_vertex_twice)
|
|||
db::Triangles tris;
|
||||
tris.init_box (db::DBox (0, 0, 1, 1));
|
||||
|
||||
tris.insert (tris.create_vertex (0.5, 0.5));
|
||||
tris.insert_point (0.5, 0.5);
|
||||
// inserted a vertex twice does not change anything
|
||||
tris.insert (tris.create_vertex (0.5, 0.5));
|
||||
tris.insert_point (0.5, 0.5);
|
||||
EXPECT_EQ (tris.to_string (), "((1, 1), (1, 0), (0.5, 0.5)), ((1, 1), (0.5, 0.5), (0, 1)), ((0, 0), (0, 1), (0.5, 0.5)), ((0, 0), (0.5, 0.5), (1, 0))");
|
||||
EXPECT_EQ (tris.check(), true);
|
||||
}
|
||||
|
|
@ -91,11 +91,11 @@ TEST(Triangle_insert_vertex_twice)
|
|||
TEST(Triangle_insert_vertex_convex)
|
||||
{
|
||||
db::Triangles tris;
|
||||
tris.insert (tris.create_vertex (0.2, 0.2));
|
||||
tris.insert (tris.create_vertex (0.2, 0.8));
|
||||
tris.insert (tris.create_vertex (0.6, 0.5));
|
||||
tris.insert (tris.create_vertex (0.7, 0.5));
|
||||
tris.insert (tris.create_vertex (0.6, 0.4));
|
||||
tris.insert_point (0.2, 0.2);
|
||||
tris.insert_point (0.2, 0.8);
|
||||
tris.insert_point (0.6, 0.5);
|
||||
tris.insert_point (0.7, 0.5);
|
||||
tris.insert_point (0.6, 0.4);
|
||||
EXPECT_EQ (tris.to_string (), "((0.2, 0.2), (0.2, 0.8), (0.6, 0.5)), ((0.7, 0.5), (0.6, 0.5), (0.2, 0.8)), ((0.6, 0.5), (0.6, 0.4), (0.2, 0.2)), ((0.6, 0.5), (0.7, 0.5), (0.6, 0.4))");
|
||||
EXPECT_EQ (tris.check(), true);
|
||||
}
|
||||
|
|
@ -103,10 +103,10 @@ TEST(Triangle_insert_vertex_convex)
|
|||
TEST(Triangle_insert_vertex_convex2)
|
||||
{
|
||||
db::Triangles tris;
|
||||
tris.insert (tris.create_vertex (0.25, 0.1));
|
||||
tris.insert (tris.create_vertex (0.1, 0.4));
|
||||
tris.insert (tris.create_vertex (0.4, 0.15));
|
||||
tris.insert (tris.create_vertex (1, 0.7));
|
||||
tris.insert_point (0.25, 0.1);
|
||||
tris.insert_point (0.1, 0.4);
|
||||
tris.insert_point (0.4, 0.15);
|
||||
tris.insert_point (1, 0.7);
|
||||
EXPECT_EQ (tris.to_string (), "((0.25, 0.1), (0.1, 0.4), (0.4, 0.15)), ((1, 0.7), (0.4, 0.15), (0.1, 0.4))");
|
||||
EXPECT_EQ (tris.check(), true);
|
||||
}
|
||||
|
|
@ -114,38 +114,30 @@ TEST(Triangle_insert_vertex_convex2)
|
|||
TEST(Triangle_insert_vertex_convex3)
|
||||
{
|
||||
db::Triangles tris;
|
||||
tris.insert (tris.create_vertex (0.25, 0.5));
|
||||
tris.insert (tris.create_vertex (0.25, 0.55));
|
||||
tris.insert (tris.create_vertex (0.15, 0.8));
|
||||
tris.insert (tris.create_vertex (1, 0.4));
|
||||
tris.insert_point (0.25, 0.5);
|
||||
tris.insert_point (0.25, 0.55);
|
||||
tris.insert_point (0.15, 0.8);
|
||||
tris.insert_point (1, 0.4);
|
||||
EXPECT_EQ (tris.to_string (), "((0.25, 0.5), (0.15, 0.8), (0.25, 0.55)), ((1, 0.4), (0.25, 0.5), (0.25, 0.55)), ((0.15, 0.8), (1, 0.4), (0.25, 0.55))");
|
||||
EXPECT_EQ (tris.check(), true);
|
||||
}
|
||||
|
||||
#if 0
|
||||
TEST(Triangle_find_crossing_segments)
|
||||
TEST(Triangle_search_edges_crossing)
|
||||
{
|
||||
db::Triangles tris;
|
||||
v1 = tris.create_vertex (0.2, 0.2);
|
||||
v2 = tris.create_vertex (0.2, 0.8);
|
||||
v3 = tris.create_vertex (0.6, 0.5);
|
||||
v4 = tris.create_vertex (0.7, 0.5);
|
||||
v5 = tris.create_vertex (0.6, 0.4);
|
||||
v6 = tris.create_vertex (0.7, 0.2);
|
||||
tris.insert (v1);
|
||||
tris.insert (v2);
|
||||
tris.insert (v3);
|
||||
tris.insert (v4);
|
||||
tris.insert (v5);
|
||||
tris.insert (v6);
|
||||
db::Vertex *v1 = tris.insert_point (0.2, 0.2);
|
||||
db::Vertex *v2 = tris.insert_point (0.2, 0.8);
|
||||
db::Vertex *v3 = tris.insert_point (0.6, 0.5);
|
||||
/*db::Vertex *v4 =*/ tris.insert_point (0.7, 0.5);
|
||||
db::Vertex *v5 = tris.insert_point (0.6, 0.4);
|
||||
db::Vertex *v6 = tris.insert_point (0.7, 0.2);
|
||||
EXPECT_EQ (tris.check(), true);
|
||||
|
||||
auto xedges = tris.search_edges_crossing (db::DEdge (*v2, *v6));
|
||||
auto xedges = tris.search_edges_crossing (v2, v6);
|
||||
|
||||
EXPECT_EQ (xedges.size (), size_t (2));
|
||||
auto s1 = tris.find_edge_for_points (v1, v3);
|
||||
auto s2 = tris.find_edge_for_points (v1, v5);
|
||||
EXPECT_EQ (s1 in xedges, true);
|
||||
EXPECT_EQ (s2 in xedges, true);
|
||||
auto s1 = tris.find_edge_for_points (*v1, *v3);
|
||||
auto s2 = tris.find_edge_for_points (*v1, *v5);
|
||||
EXPECT_EQ (std::find (xedges.begin (), xedges.end (), s1) != xedges.end (), true);
|
||||
EXPECT_EQ (std::find (xedges.begin (), xedges.end (), s2) != xedges.end (), true);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue