mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
94396da117
commit
a2ef7a28f8
|
|
@ -72,6 +72,11 @@ Vertex::Vertex (const Vertex &v)
|
|||
// NOTE: edges are not copied!
|
||||
}
|
||||
|
||||
Vertex::~Vertex ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Vertex &Vertex::operator= (const Vertex &v)
|
||||
{
|
||||
if (this != &v) {
|
||||
|
|
@ -176,6 +181,11 @@ Edge::Edge (Graph *graph, Vertex *v1, Vertex *v2)
|
|||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Edge::~Edge ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void
|
||||
Edge::set_left (Polygon *t)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -161,10 +161,12 @@ protected:
|
|||
Vertex (Graph *graph, const DPoint &p);
|
||||
Vertex (Graph *graph, const Vertex &v);
|
||||
Vertex (Graph *graph, db::DCoord x, db::DCoord y);
|
||||
~Vertex ();
|
||||
|
||||
private:
|
||||
friend class Edge;
|
||||
friend class Graph;
|
||||
friend class tl::stable_vector<Vertex>;
|
||||
|
||||
void remove_edge (const edges_iterator_non_const &ec)
|
||||
{
|
||||
|
|
@ -499,12 +501,14 @@ protected:
|
|||
|
||||
Edge (Graph *graph);
|
||||
Edge (Graph *graph, Vertex *v1, Vertex *v2);
|
||||
~Edge ();
|
||||
|
||||
private:
|
||||
friend class Polygon;
|
||||
friend class Graph;
|
||||
friend class Triangulation;
|
||||
friend class ConvexDecomposition;
|
||||
friend class tl::stable_vector<Edge>;
|
||||
|
||||
Graph *mp_graph;
|
||||
Vertex *mp_v1, *mp_v2;
|
||||
|
|
@ -538,23 +542,34 @@ class DB_PUBLIC Polygon
|
|||
: public tl::list_node<Polygon>, public tl::Object
|
||||
{
|
||||
public:
|
||||
template<class Iter>
|
||||
Polygon (Graph *graph, Iter from, Iter to)
|
||||
: mp_graph (graph), mp_e (from, to)
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*
|
||||
* It is legal to delete a polygon object to remove it.
|
||||
*/
|
||||
~Polygon ();
|
||||
|
||||
/**
|
||||
* @brief Detaches a polygon object from the edges
|
||||
*/
|
||||
void unlink ();
|
||||
|
||||
void set_id (size_t id) { m_id = id; }
|
||||
/**
|
||||
* @brief Gets the polygon's unique ID
|
||||
*/
|
||||
size_t id () const { return m_id; }
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether the polygon is an outside polygon
|
||||
*
|
||||
* Outside polygons are polygons that fill concave parts in a triangulation for example.
|
||||
*/
|
||||
bool is_outside () const { return m_is_outside; }
|
||||
void set_outside (bool o) { m_is_outside = o; }
|
||||
|
||||
/**
|
||||
* @brief Returns a string representation
|
||||
*/
|
||||
std::string to_string (bool with_id = false) const;
|
||||
|
||||
/**
|
||||
|
|
@ -727,8 +742,19 @@ protected:
|
|||
Polygon (Graph *graph);
|
||||
Polygon (Graph *graph, Edge *e1, Edge *e2, Edge *e3);
|
||||
|
||||
template<class Iter>
|
||||
Polygon (Graph *graph, Iter from, Iter to)
|
||||
: mp_graph (graph), mp_e (from, to)
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
||||
void set_outside (bool o) { m_is_outside = o; }
|
||||
void set_id (size_t id) { m_id = id; }
|
||||
|
||||
private:
|
||||
friend class Graph;
|
||||
friend class Triangulation;
|
||||
|
||||
Graph *mp_graph;
|
||||
bool m_is_outside;
|
||||
|
|
@ -764,6 +790,7 @@ struct PolygonLessFunc
|
|||
* hold triangles (polygons with 3 vertexes).
|
||||
*/
|
||||
class DB_PUBLIC Graph
|
||||
: public tl::Object
|
||||
{
|
||||
public:
|
||||
typedef tl::list<Polygon> polygons_type;
|
||||
|
|
|
|||
|
|
@ -85,24 +85,6 @@ struct equal_compare_func
|
|||
}
|
||||
};
|
||||
|
||||
struct ConcaveCorner
|
||||
{
|
||||
ConcaveCorner ()
|
||||
: corner (0), incoming (0), outgoing (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
ConcaveCorner (Vertex *_corner, Edge *_incoming, Edge *_outgoing)
|
||||
: corner (_corner), incoming (_incoming), outgoing (_outgoing)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Vertex *corner;
|
||||
Edge *incoming, *outgoing;
|
||||
};
|
||||
|
||||
Edge *find_outgoing_segment (Vertex *vertex, Edge *incoming, int &vp_max_sign)
|
||||
{
|
||||
Vertex *vfrom = incoming->other (vertex);
|
||||
|
|
@ -141,20 +123,16 @@ Edge *find_outgoing_segment (Vertex *vertex, Edge *incoming, int &vp_max_sign)
|
|||
return outgoing;
|
||||
}
|
||||
|
||||
void collect_concave_vertexes (Graph &tris, std::vector<ConcaveCorner> &concave_vertexes)
|
||||
void
|
||||
ConvexDecomposition::collect_concave_vertexes (std::vector<ConcaveCorner> &concave_vertexes)
|
||||
{
|
||||
concave_vertexes.clear ();
|
||||
|
||||
// @@@ use edge "level"
|
||||
// @@@ use edges from heap
|
||||
std::unordered_set<Edge *> left;
|
||||
|
||||
for (auto it = tris.begin (); it != tris.end (); ++it) {
|
||||
for (unsigned int i = 0; i < 3; ++i) {
|
||||
Edge *e = it->edge (i);
|
||||
if (e->is_segment ()) {
|
||||
left.insert (e);
|
||||
}
|
||||
for (auto e = mp_graph->edges ().begin (); e != mp_graph->edges ().end (); ++e) {
|
||||
if (e->is_segment () && (e->left () != 0 || e->right () != 0)) {
|
||||
left.insert (e.operator-> ());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -191,7 +169,7 @@ void collect_concave_vertexes (Graph &tris, std::vector<ConcaveCorner> &concave_
|
|||
}
|
||||
|
||||
std::pair<bool, db::DPoint>
|
||||
search_crossing_with_next_segment (const Vertex *v0, const db::DVector &direction)
|
||||
ConvexDecomposition::search_crossing_with_next_segment (const Vertex *v0, const db::DVector &direction)
|
||||
{
|
||||
auto vtri = v0->polygons (); // TODO: slow?
|
||||
std::vector<const Vertex *> nvv, nvv_next;
|
||||
|
|
@ -253,7 +231,7 @@ ConvexDecomposition::hertel_mehlhorn_decomposition (Triangulation &tris, const C
|
|||
bool split_edges = param.split_edges;
|
||||
|
||||
std::vector<ConcaveCorner> concave_vertexes;
|
||||
collect_concave_vertexes (*mp_graph, concave_vertexes);
|
||||
collect_concave_vertexes (concave_vertexes);
|
||||
|
||||
// @@@ return if no concave corners
|
||||
|
||||
|
|
@ -302,7 +280,7 @@ ConvexDecomposition::hertel_mehlhorn_decomposition (Triangulation &tris, const C
|
|||
}
|
||||
|
||||
// As the insertion invalidates the edges, we need to collect the concave vertexes again
|
||||
collect_concave_vertexes (*mp_graph, concave_vertexes);
|
||||
collect_concave_vertexes (concave_vertexes);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,7 +121,27 @@ public:
|
|||
private:
|
||||
Graph *mp_graph;
|
||||
|
||||
struct ConcaveCorner
|
||||
{
|
||||
ConcaveCorner ()
|
||||
: corner (0), incoming (0), outgoing (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
ConcaveCorner (Vertex *_corner, Edge *_incoming, Edge *_outgoing)
|
||||
: corner (_corner), incoming (_incoming), outgoing (_outgoing)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Vertex *corner;
|
||||
Edge *incoming, *outgoing;
|
||||
};
|
||||
|
||||
void hertel_mehlhorn_decomposition (Triangulation &tris, const ConvexDecompositionParameters ¶m);
|
||||
void collect_concave_vertexes (std::vector<ConcaveCorner> &concave_vertexes);
|
||||
std::pair<bool, db::DPoint> search_crossing_with_next_segment (const Vertex *v0, const db::DVector &direction);
|
||||
};
|
||||
|
||||
} // namespace plc
|
||||
|
|
|
|||
|
|
@ -1133,12 +1133,10 @@ Triangulation::ensure_edge_inner (Vertex *from, Vertex *to)
|
|||
}
|
||||
|
||||
Vertex *split_vertex;
|
||||
if (dedge.side_of (split_point) == 0) {
|
||||
if (dedge.side_of (*split_edge->v1 ()) == 0) {
|
||||
split_vertex = split_edge->v1 ();
|
||||
} else {
|
||||
split_vertex = split_edge->v2 ();
|
||||
}
|
||||
if (dedge.side_of (*split_edge->v1 ()) == 0) {
|
||||
split_vertex = split_edge->v1 ();
|
||||
} else if (dedge.side_of (*split_edge->v2 ()) == 0) {
|
||||
split_vertex = split_edge->v2 ();
|
||||
} else {
|
||||
split_vertex = insert_point (split_point);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,15 +27,97 @@
|
|||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
TEST(basic)
|
||||
namespace
|
||||
{
|
||||
db::DBox box (0, 0, 100.0, 200.0);
|
||||
|
||||
db::plc::Graph plc;
|
||||
// @@@ pg.insert_polygon (db::DSimplePolygon (box));
|
||||
class TestableGraph
|
||||
: public db::plc::Graph
|
||||
{
|
||||
public:
|
||||
using db::plc::Graph::Graph;
|
||||
using db::plc::Graph::create_vertex;
|
||||
using db::plc::Graph::create_edge;
|
||||
using db::plc::Graph::create_triangle;
|
||||
using db::plc::Graph::create_polygon;
|
||||
};
|
||||
|
||||
// @@@
|
||||
tl::info << plc.to_string ();
|
||||
plc.dump ("debug.gds"); // @@@
|
||||
}
|
||||
|
||||
TEST(basic)
|
||||
{
|
||||
TestableGraph plc;
|
||||
|
||||
db::plc::Vertex *v1 = plc.create_vertex (db::DPoint (1, 2));
|
||||
EXPECT_EQ (v1->to_string (), "(1, 2)");
|
||||
|
||||
v1 = plc.create_vertex (db::DPoint (2, 1));
|
||||
EXPECT_EQ (v1->to_string (), "(2, 1)");
|
||||
|
||||
EXPECT_EQ (v1->is_precious (), false);
|
||||
v1->set_is_precious (true);
|
||||
EXPECT_EQ (v1->is_precious (), true);
|
||||
}
|
||||
|
||||
TEST(edge)
|
||||
{
|
||||
TestableGraph plc;
|
||||
|
||||
db::plc::Vertex *v1 = plc.create_vertex (db::DPoint (1, 2));
|
||||
db::plc::Vertex *v2 = plc.create_vertex (db::DPoint (3, 4));
|
||||
|
||||
db::plc::Edge *e = plc.create_edge (v1, v2);
|
||||
EXPECT_EQ (e->to_string (), "((1, 2), (3, 4))");
|
||||
|
||||
EXPECT_EQ (v1->num_edges (), size_t (1));
|
||||
EXPECT_EQ (v2->num_edges (), size_t (1));
|
||||
|
||||
EXPECT_EQ ((*v1->begin_edges ())->edge ().to_string (), "(1,2;3,4)");
|
||||
EXPECT_EQ ((*v2->begin_edges ())->edge ().to_string (), "(1,2;3,4)");
|
||||
}
|
||||
|
||||
TEST(polygon)
|
||||
{
|
||||
TestableGraph plc;
|
||||
EXPECT_EQ (plc.num_polygons (), size_t (0));
|
||||
EXPECT_EQ (plc.bbox ().to_string (), "()");
|
||||
|
||||
db::plc::Vertex *v1 = plc.create_vertex (db::DPoint (1, 2));
|
||||
db::plc::Vertex *v2 = plc.create_vertex (db::DPoint (3, 4));
|
||||
db::plc::Vertex *v3 = plc.create_vertex (db::DPoint (3, 2));
|
||||
|
||||
db::plc::Edge *e1 = plc.create_edge (v1, v2);
|
||||
db::plc::Edge *e2 = plc.create_edge (v1, v3);
|
||||
db::plc::Edge *e3 = plc.create_edge (v2, v3);
|
||||
|
||||
db::plc::Polygon *tri = plc.create_triangle (e1, e2, e3);
|
||||
EXPECT_EQ (tri->to_string (), "((1, 2), (3, 4), (3, 2))");
|
||||
EXPECT_EQ (tri->polygon ().to_string (), "(1,2;3,4;3,2)");
|
||||
EXPECT_EQ (plc.bbox ().to_string (), "(1,2;3,4)");
|
||||
EXPECT_EQ (plc.num_polygons (), size_t (1));
|
||||
|
||||
EXPECT_EQ (v1->num_edges (), size_t (2));
|
||||
EXPECT_EQ (v2->num_edges (), size_t (2));
|
||||
EXPECT_EQ (v3->num_edges (), size_t (2));
|
||||
|
||||
EXPECT_EQ (tri->edge (0) == e1, true);
|
||||
EXPECT_EQ (tri->edge (3) == e1, true);
|
||||
EXPECT_EQ (tri->edge (1) == e3, true);
|
||||
EXPECT_EQ (tri->edge (2) == e2, true);
|
||||
EXPECT_EQ (tri->edge (-1) == e2, true);
|
||||
|
||||
EXPECT_EQ (e1->left () == 0, true);
|
||||
EXPECT_EQ (e1->right () == tri, true);
|
||||
EXPECT_EQ (e2->left () == tri, true);
|
||||
EXPECT_EQ (e2->right () == 0, true);
|
||||
EXPECT_EQ (e3->left () == 0, true);
|
||||
EXPECT_EQ (e3->right () == tri, true);
|
||||
|
||||
delete tri;
|
||||
|
||||
EXPECT_EQ (e1->left () == 0, true);
|
||||
EXPECT_EQ (e1->right () == 0, true);
|
||||
EXPECT_EQ (e2->left () == 0, true);
|
||||
EXPECT_EQ (e2->right () == 0, true);
|
||||
EXPECT_EQ (e3->left () == 0, true);
|
||||
EXPECT_EQ (e3->right () == 0, true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@ public:
|
|||
TestablePolygon (db::plc::Edge *e1, db::plc::Edge *e2, db::plc::Edge *e3)
|
||||
: db::plc::Polygon (0, e1, e2, e3)
|
||||
{ }
|
||||
|
||||
using db::plc::Polygon::set_outside;
|
||||
};
|
||||
|
||||
// Tests for Vertex class
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@
|
|||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class TestableTriangulation
|
||||
: public db::plc::Triangulation
|
||||
{
|
||||
|
|
@ -64,6 +67,8 @@ public:
|
|||
using db::plc::Graph::create_triangle;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
TEST(basic)
|
||||
{
|
||||
db::plc::Graph plc;
|
||||
|
|
@ -343,7 +348,7 @@ TEST(heavy_insert)
|
|||
double y = round (flt_rand () * res) * (1.0 / res);
|
||||
db::plc::Vertex *v = tris.insert_point (x, y);
|
||||
bbox += db::DPoint (x, y);
|
||||
vmap.insert (std::make_pair (*v, false));
|
||||
vmap.insert (std::pair<db::DPoint, bool> (*v, false));
|
||||
}
|
||||
|
||||
// not strictly true, but very likely with at least 10 vertexes:
|
||||
|
|
|
|||
Loading…
Reference in New Issue