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!
|
// NOTE: edges are not copied!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vertex::~Vertex ()
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
Vertex &Vertex::operator= (const Vertex &v)
|
Vertex &Vertex::operator= (const Vertex &v)
|
||||||
{
|
{
|
||||||
if (this != &v) {
|
if (this != &v) {
|
||||||
|
|
@ -176,6 +181,11 @@ Edge::Edge (Graph *graph, Vertex *v1, Vertex *v2)
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Edge::~Edge ()
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Edge::set_left (Polygon *t)
|
Edge::set_left (Polygon *t)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -161,10 +161,12 @@ protected:
|
||||||
Vertex (Graph *graph, const DPoint &p);
|
Vertex (Graph *graph, const DPoint &p);
|
||||||
Vertex (Graph *graph, const Vertex &v);
|
Vertex (Graph *graph, const Vertex &v);
|
||||||
Vertex (Graph *graph, db::DCoord x, db::DCoord y);
|
Vertex (Graph *graph, db::DCoord x, db::DCoord y);
|
||||||
|
~Vertex ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Edge;
|
friend class Edge;
|
||||||
friend class Graph;
|
friend class Graph;
|
||||||
|
friend class tl::stable_vector<Vertex>;
|
||||||
|
|
||||||
void remove_edge (const edges_iterator_non_const &ec)
|
void remove_edge (const edges_iterator_non_const &ec)
|
||||||
{
|
{
|
||||||
|
|
@ -499,12 +501,14 @@ protected:
|
||||||
|
|
||||||
Edge (Graph *graph);
|
Edge (Graph *graph);
|
||||||
Edge (Graph *graph, Vertex *v1, Vertex *v2);
|
Edge (Graph *graph, Vertex *v1, Vertex *v2);
|
||||||
|
~Edge ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Polygon;
|
friend class Polygon;
|
||||||
friend class Graph;
|
friend class Graph;
|
||||||
friend class Triangulation;
|
friend class Triangulation;
|
||||||
friend class ConvexDecomposition;
|
friend class ConvexDecomposition;
|
||||||
|
friend class tl::stable_vector<Edge>;
|
||||||
|
|
||||||
Graph *mp_graph;
|
Graph *mp_graph;
|
||||||
Vertex *mp_v1, *mp_v2;
|
Vertex *mp_v1, *mp_v2;
|
||||||
|
|
@ -538,23 +542,34 @@ class DB_PUBLIC Polygon
|
||||||
: public tl::list_node<Polygon>, public tl::Object
|
: public tl::list_node<Polygon>, public tl::Object
|
||||||
{
|
{
|
||||||
public:
|
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 ();
|
~Polygon ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Detaches a polygon object from the edges
|
||||||
|
*/
|
||||||
void unlink ();
|
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; }
|
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; }
|
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;
|
std::string to_string (bool with_id = false) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -727,8 +742,19 @@ protected:
|
||||||
Polygon (Graph *graph);
|
Polygon (Graph *graph);
|
||||||
Polygon (Graph *graph, Edge *e1, Edge *e2, Edge *e3);
|
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:
|
private:
|
||||||
friend class Graph;
|
friend class Graph;
|
||||||
|
friend class Triangulation;
|
||||||
|
|
||||||
Graph *mp_graph;
|
Graph *mp_graph;
|
||||||
bool m_is_outside;
|
bool m_is_outside;
|
||||||
|
|
@ -764,6 +790,7 @@ struct PolygonLessFunc
|
||||||
* hold triangles (polygons with 3 vertexes).
|
* hold triangles (polygons with 3 vertexes).
|
||||||
*/
|
*/
|
||||||
class DB_PUBLIC Graph
|
class DB_PUBLIC Graph
|
||||||
|
: public tl::Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef tl::list<Polygon> polygons_type;
|
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)
|
Edge *find_outgoing_segment (Vertex *vertex, Edge *incoming, int &vp_max_sign)
|
||||||
{
|
{
|
||||||
Vertex *vfrom = incoming->other (vertex);
|
Vertex *vfrom = incoming->other (vertex);
|
||||||
|
|
@ -141,20 +123,16 @@ Edge *find_outgoing_segment (Vertex *vertex, Edge *incoming, int &vp_max_sign)
|
||||||
return outgoing;
|
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 ();
|
concave_vertexes.clear ();
|
||||||
|
|
||||||
// @@@ use edge "level"
|
|
||||||
// @@@ use edges from heap
|
|
||||||
std::unordered_set<Edge *> left;
|
std::unordered_set<Edge *> left;
|
||||||
|
|
||||||
for (auto it = tris.begin (); it != tris.end (); ++it) {
|
for (auto e = mp_graph->edges ().begin (); e != mp_graph->edges ().end (); ++e) {
|
||||||
for (unsigned int i = 0; i < 3; ++i) {
|
if (e->is_segment () && (e->left () != 0 || e->right () != 0)) {
|
||||||
Edge *e = it->edge (i);
|
left.insert (e.operator-> ());
|
||||||
if (e->is_segment ()) {
|
|
||||||
left.insert (e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,7 +169,7 @@ void collect_concave_vertexes (Graph &tris, std::vector<ConcaveCorner> &concave_
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, db::DPoint>
|
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?
|
auto vtri = v0->polygons (); // TODO: slow?
|
||||||
std::vector<const Vertex *> nvv, nvv_next;
|
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;
|
bool split_edges = param.split_edges;
|
||||||
|
|
||||||
std::vector<ConcaveCorner> concave_vertexes;
|
std::vector<ConcaveCorner> concave_vertexes;
|
||||||
collect_concave_vertexes (*mp_graph, concave_vertexes);
|
collect_concave_vertexes (concave_vertexes);
|
||||||
|
|
||||||
// @@@ return if no concave corners
|
// @@@ 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
|
// 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:
|
private:
|
||||||
Graph *mp_graph;
|
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 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
|
} // namespace plc
|
||||||
|
|
|
||||||
|
|
@ -1133,12 +1133,10 @@ Triangulation::ensure_edge_inner (Vertex *from, Vertex *to)
|
||||||
}
|
}
|
||||||
|
|
||||||
Vertex *split_vertex;
|
Vertex *split_vertex;
|
||||||
if (dedge.side_of (split_point) == 0) {
|
if (dedge.side_of (*split_edge->v1 ()) == 0) {
|
||||||
if (dedge.side_of (*split_edge->v1 ()) == 0) {
|
split_vertex = split_edge->v1 ();
|
||||||
split_vertex = split_edge->v1 ();
|
} else if (dedge.side_of (*split_edge->v2 ()) == 0) {
|
||||||
} else {
|
split_vertex = split_edge->v2 ();
|
||||||
split_vertex = split_edge->v2 ();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
split_vertex = insert_point (split_point);
|
split_vertex = insert_point (split_point);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,15 +27,97 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
TEST(basic)
|
namespace
|
||||||
{
|
{
|
||||||
db::DBox box (0, 0, 100.0, 200.0);
|
|
||||||
|
|
||||||
db::plc::Graph plc;
|
class TestableGraph
|
||||||
// @@@ pg.insert_polygon (db::DSimplePolygon (box));
|
: 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)
|
TestablePolygon (db::plc::Edge *e1, db::plc::Edge *e2, db::plc::Edge *e3)
|
||||||
: db::plc::Polygon (0, e1, e2, e3)
|
: db::plc::Polygon (0, e1, e2, e3)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
using db::plc::Polygon::set_outside;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Tests for Vertex class
|
// Tests for Vertex class
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,9 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
class TestableTriangulation
|
class TestableTriangulation
|
||||||
: public db::plc::Triangulation
|
: public db::plc::Triangulation
|
||||||
{
|
{
|
||||||
|
|
@ -64,6 +67,8 @@ public:
|
||||||
using db::plc::Graph::create_triangle;
|
using db::plc::Graph::create_triangle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
TEST(basic)
|
TEST(basic)
|
||||||
{
|
{
|
||||||
db::plc::Graph plc;
|
db::plc::Graph plc;
|
||||||
|
|
@ -343,7 +348,7 @@ TEST(heavy_insert)
|
||||||
double y = round (flt_rand () * res) * (1.0 / res);
|
double y = round (flt_rand () * res) * (1.0 / res);
|
||||||
db::plc::Vertex *v = tris.insert_point (x, y);
|
db::plc::Vertex *v = tris.insert_point (x, y);
|
||||||
bbox += db::DPoint (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:
|
// not strictly true, but very likely with at least 10 vertexes:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue