mirror of https://github.com/KLayout/klayout.git
WIP: allowing multiple vertex ports on the same location
This commit is contained in:
parent
80ad38f81b
commit
aca3095efa
|
|
@ -43,47 +43,58 @@ namespace plc
|
|||
// Vertex implementation
|
||||
|
||||
Vertex::Vertex (Graph *graph)
|
||||
: DPoint (), mp_graph (graph), m_is_precious (false)
|
||||
: DPoint (), mp_graph (graph), mp_ids (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Vertex::Vertex (Graph *graph, const db::DPoint &p)
|
||||
: DPoint (p), mp_graph (graph), m_is_precious (false)
|
||||
: DPoint (p), mp_graph (graph), mp_ids (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Vertex::Vertex (Graph *graph, const Vertex &v)
|
||||
: DPoint (), mp_graph (graph), m_is_precious (false), m_id (0)
|
||||
: DPoint (), mp_graph (graph), mp_ids (0)
|
||||
{
|
||||
operator= (v);
|
||||
}
|
||||
|
||||
Vertex::Vertex (Graph *graph, db::DCoord x, db::DCoord y)
|
||||
: DPoint (x, y), mp_graph (graph), m_is_precious (false), m_id (0)
|
||||
: DPoint (x, y), mp_graph (graph), mp_ids (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
Vertex::Vertex (const Vertex &v)
|
||||
: DPoint (v), mp_graph (v.mp_graph), m_is_precious (v.m_is_precious), m_id (v.m_id)
|
||||
: DPoint (), mp_graph (v.mp_graph), mp_ids (0)
|
||||
{
|
||||
// NOTE: edges are not copied!
|
||||
operator= (v);
|
||||
}
|
||||
|
||||
Vertex::~Vertex ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
if (mp_ids) {
|
||||
delete mp_ids;
|
||||
mp_ids = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Vertex &Vertex::operator= (const Vertex &v)
|
||||
{
|
||||
if (this != &v) {
|
||||
|
||||
// NOTE: edges are not copied!
|
||||
db::DPoint::operator= (v);
|
||||
m_is_precious = v.m_is_precious;
|
||||
m_id = v.m_id;
|
||||
|
||||
if (mp_ids) {
|
||||
delete mp_ids;
|
||||
mp_ids = 0;
|
||||
}
|
||||
if (v.mp_ids) {
|
||||
mp_ids = new std::set<unsigned int> (*v.mp_ids);
|
||||
}
|
||||
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -99,6 +110,39 @@ Vertex::is_outside () const
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Vertex::set_is_precious (bool f, unsigned int id)
|
||||
{
|
||||
if (f) {
|
||||
if (! mp_ids) {
|
||||
mp_ids = new std::set<unsigned int> ();
|
||||
}
|
||||
mp_ids->insert (id);
|
||||
} else {
|
||||
if (mp_ids) {
|
||||
delete mp_ids;
|
||||
mp_ids = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Vertex::is_precious () const
|
||||
{
|
||||
return mp_ids != 0;
|
||||
}
|
||||
|
||||
const std::set<unsigned int> &
|
||||
Vertex::ids () const
|
||||
{
|
||||
if (mp_ids != 0) {
|
||||
return *mp_ids;
|
||||
} else {
|
||||
static std::set<unsigned int> empty;
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Polygon *>
|
||||
Vertex::polygons () const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -131,16 +131,12 @@ public:
|
|||
*
|
||||
* "precious" vertexes are not removed during triangulation for example.
|
||||
*/
|
||||
void set_is_precious (bool f, unsigned int id)
|
||||
{
|
||||
m_is_precious = f;
|
||||
m_id = id;
|
||||
}
|
||||
void set_is_precious (bool f, unsigned int id);
|
||||
|
||||
/**
|
||||
* @brief Gets a value indicating whether the vertex is precious
|
||||
*/
|
||||
bool is_precious () const { return m_is_precious; }
|
||||
bool is_precious () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the ID passed to "set_is_precious"
|
||||
|
|
@ -148,7 +144,7 @@ public:
|
|||
* This ID can be used to identify the vertex in the context it came from (e.g.
|
||||
* index in point vector).
|
||||
*/
|
||||
unsigned int id () const { return m_id; }
|
||||
const std::set<unsigned int> &ids () const;
|
||||
|
||||
/**
|
||||
* @brief Returns a string representation of the vertex
|
||||
|
|
@ -187,8 +183,7 @@ private:
|
|||
|
||||
Graph *mp_graph;
|
||||
edges_type mp_edges;
|
||||
bool m_is_precious : 1;
|
||||
unsigned int m_id : 31;
|
||||
std::set<unsigned int> *mp_ids;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -236,10 +236,38 @@ public:
|
|||
/**
|
||||
* @brief Refines the triangulation using the given parameters
|
||||
*
|
||||
* This method is used internally by the "triangulation" method after creating the basic triangulation.
|
||||
* This method is used internally by the "triangulate" method after creating the basic triangulation.
|
||||
*
|
||||
* This method is provided as a partial solution of a triangulation for special cases.
|
||||
*/
|
||||
void refine (const TriangulationParameters ¶m);
|
||||
|
||||
/**
|
||||
* @brief Given a set of contours with edges, mark outer triangles
|
||||
*
|
||||
* The edges must be made from existing vertexes. Edge orientation is
|
||||
* clockwise.
|
||||
*
|
||||
* This will also mark triangles as outside ones.
|
||||
* This method is used internally by the "triangulate" method after creating the basic triangulation.
|
||||
*
|
||||
* This method is provided as a partial solution of a triangulation for special cases.
|
||||
*/
|
||||
void constrain (const std::vector<std::vector<Vertex *> > &contours);
|
||||
|
||||
/**
|
||||
* @brief Inserts a contours of a polygon
|
||||
*
|
||||
* This method fills the contours of the given polygon by doint an "insert_point"
|
||||
* on all points and logging the outer edges ("segments") into the "contours"
|
||||
* array. The latter can be passed to "constrain" to create a constrained
|
||||
* triangulation.
|
||||
*
|
||||
* This method is used internally by the "triangulate" method to create the basic triangulation.
|
||||
* This method is provided as a partial solution of a triangulation for special cases.
|
||||
*/
|
||||
template<class Poly, class Trans> void make_contours (const Poly &poly, const Trans &trans, std::vector<std::vector<Vertex *> > &contours);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Checks the polygon graph for consistency
|
||||
|
|
@ -287,16 +315,6 @@ protected:
|
|||
*/
|
||||
std::vector<Edge *> ensure_edge (Vertex *from, Vertex *to);
|
||||
|
||||
/**
|
||||
* @brief Given a set of contours with edges, mark outer triangles
|
||||
*
|
||||
* The edges must be made from existing vertexes. Edge orientation is
|
||||
* clockwise.
|
||||
*
|
||||
* This will also mark triangles as outside ones.
|
||||
*/
|
||||
void constrain (const std::vector<std::vector<Vertex *> > &contours);
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether the edge is "illegal" (violates the Delaunay criterion)
|
||||
*/
|
||||
|
|
@ -313,8 +331,6 @@ private:
|
|||
size_t m_id;
|
||||
mutable size_t m_flips, m_hops;
|
||||
|
||||
template<class Poly, class Trans> void make_contours (const Poly &poly, const Trans &trans, std::vector<std::vector<Vertex *> > &contours);
|
||||
|
||||
void remove_outside_vertex (Vertex *vertex, std::list<tl::weak_ptr<Polygon> > *new_triangles = 0);
|
||||
void remove_inside_vertex (Vertex *vertex, std::list<tl::weak_ptr<Polygon> > *new_triangles_out = 0);
|
||||
std::vector<Polygon *> fill_concave_corners (const std::vector<Edge *> &edges);
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ TEST(internal_vertex)
|
|||
|
||||
std::vector<std::string> ip;
|
||||
for (size_t i = 0; i < p->internal_vertexes (); ++i) {
|
||||
ip.push_back (p->internal_vertex (i)->to_string () + "#" + tl::to_string (p->internal_vertex (i)->id ()));
|
||||
ip.push_back (p->internal_vertex (i)->to_string () + "#" + tl::to_string (p->internal_vertex (i)->ids ()));
|
||||
}
|
||||
std::sort (ip.begin (), ip.end ());
|
||||
EXPECT_EQ (tl::join (ip, "/"), "(0, 0)#2/(0, 0.05)#0/(0.2, 0.07)#1");
|
||||
|
|
|
|||
|
|
@ -56,7 +56,12 @@ TEST(basic)
|
|||
EXPECT_EQ (v1->is_precious (), false);
|
||||
v1->set_is_precious (true, 17);
|
||||
EXPECT_EQ (v1->is_precious (), true);
|
||||
EXPECT_EQ (v1->id (), 17u);
|
||||
EXPECT_EQ (v1->ids ().size (), 1u);
|
||||
EXPECT_EQ (*v1->ids ().begin (), 17u);
|
||||
v1->set_is_precious (true, 1);
|
||||
EXPECT_EQ (v1->is_precious (), true);
|
||||
EXPECT_EQ (v1->ids ().size (), 2u);
|
||||
EXPECT_EQ (*v1->ids ().begin (), 2u);
|
||||
}
|
||||
|
||||
TEST(edge)
|
||||
|
|
|
|||
|
|
@ -468,14 +468,14 @@ RNetExtractor::extract_conductor (const RExtractorTechConductor &cond,
|
|||
|
||||
// type 0 objects (vertex ports)
|
||||
for (auto i = vertex_ports.begin (); i != vertex_ports.end (); ++i) {
|
||||
// @@@ could be without enlarge?
|
||||
// TODO: could be without enlarge?
|
||||
box_heap.push_back (db::Box (*i, *i).enlarged (db::Vector (1, 1)));
|
||||
scanner.insert2 (&box_heap.back (), make_id (i - vertex_ports.begin (), 0));
|
||||
}
|
||||
|
||||
// type 1 objects (via ports)
|
||||
for (auto i = via_ports.begin (); i != via_ports.end (); ++i) {
|
||||
// @@@ could be without enlarge?
|
||||
// TODO: could be without enlarge?
|
||||
box_heap.push_back (db::Box (i->position, i->position).enlarged (db::Vector (1, 1)));
|
||||
scanner.insert2 (&box_heap.back (), make_id (i - via_ports.begin (), 1));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -269,7 +269,9 @@ SquareCountingRExtractor::extract (const db::Polygon &polygon, const std::vector
|
|||
for (size_t i = 0; i < plc_poly->internal_vertexes (); ++i) {
|
||||
auto v = plc_poly->internal_vertex (i);
|
||||
db::Point loc = inv_trans * *v;
|
||||
ports.push_back (std::make_pair (PortDefinition (pex::RNode::VertexPort, loc, v->id ()), (pex::RNode *) 0));
|
||||
for (auto pi = v->ids ().begin (); pi != v->ids ().end (); ++pi) {
|
||||
ports.push_back (std::make_pair (PortDefinition (pex::RNode::VertexPort, loc, *pi), (pex::RNode *) 0));
|
||||
}
|
||||
}
|
||||
|
||||
// 3. polygon ports
|
||||
|
|
|
|||
|
|
@ -77,6 +77,14 @@ TriangulationRExtractor::extract (const db::Polygon &polygon, const std::vector<
|
|||
|
||||
tri.clear ();
|
||||
|
||||
std::vector<std::vector<db::plc::Vertex *> > edge_contours;
|
||||
|
||||
// first step of the triangulation
|
||||
|
||||
for (auto p = residual_poly.begin_merged (); ! p.at_end (); ++p) {
|
||||
tri.make_contours (*p, trans, edge_contours);
|
||||
}
|
||||
|
||||
unsigned int id = 0;
|
||||
for (auto v = vertex_ports.begin (); v != vertex_ports.end (); ++v) {
|
||||
tri.insert_point (trans * *v)->set_is_precious (true, id++);
|
||||
|
|
@ -91,9 +99,9 @@ TriangulationRExtractor::extract (const db::Polygon &polygon, const std::vector<
|
|||
}
|
||||
}
|
||||
|
||||
// perform the triangulation
|
||||
// constrain and refine the triangulation
|
||||
|
||||
tri.create_constrained_delaunay (residual_poly, trans);
|
||||
tri.constrain (edge_contours);
|
||||
tri.refine (param);
|
||||
|
||||
// identify the vertexes present for the polygon port -> store them inside pp_vertexes
|
||||
|
|
@ -147,11 +155,19 @@ TriangulationRExtractor::extract (const db::Polygon &polygon, const std::vector<
|
|||
|
||||
} else if (vertex->is_precious ()) {
|
||||
|
||||
size_t port_index = size_t (vertex->id ());
|
||||
if (port_index < vertex_ports.size ()) {
|
||||
n = rnetwork.create_node (pex::RNode::VertexPort, port_index);
|
||||
n->location = db::DBox (*vertex, *vertex);
|
||||
vports_present.insert (port_index);
|
||||
for (auto pi = vertex->ids ().begin (); pi != vertex->ids ().end (); ++pi) {
|
||||
size_t port_index = size_t (*pi);
|
||||
if (port_index < vertex_ports.size ()) {
|
||||
RNode *nn = rnetwork.create_node (pex::RNode::VertexPort, port_index);
|
||||
nn->location = db::DBox (*vertex, *vertex);
|
||||
if (n) {
|
||||
// in case of multiple vertexes on the same spot, short them
|
||||
rnetwork.create_element (RElement::short_value (), n, nn);
|
||||
} else {
|
||||
n = nn;
|
||||
}
|
||||
vports_present.insert (port_index);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -215,6 +215,18 @@ TEST(netex_2layer)
|
|||
rex.extract (tech, geo, vertex_ports, polygon_ports, network);
|
||||
|
||||
EXPECT_EQ (network.to_string (true),
|
||||
""
|
||||
"R $0(0.3,-5.7;0.5,-5.5) $1(0.3,-5.7;0.5,-5.5) 50\n"
|
||||
"R $2(9.3,-5.9;9.9,-5.3) $3(9.3,-5.9;9.9,-5.3) 12.5\n"
|
||||
"R $4(9.3,0.1;9.9,0.3) $5(9.3,0.1;9.9,0.3) 25\n"
|
||||
"R $6(0.1,0.1;0.7,0.7) $7(0.1,0.1;0.7,0.7) 12.5\n"
|
||||
"R $0(0.3,-5.7;0.5,-5.5) $2(9.3,-5.9;9.9,-5.3) 5.75\n"
|
||||
"R $2(9.3,-5.9;9.9,-5.3) P0(12.9,-5.9;13.5,-5.3) 2.25\n"
|
||||
"R $6(0.1,0.1;0.7,0.7) V0(5.2,0.4;5.2,0.4) 3\n"
|
||||
"R $4(9.3,0.1;9.9,0.3) V0(5.2,0.4;5.2,0.4) 2.75\n"
|
||||
"R $5(9.3,0.1;9.9,0.3) $8(10,-3.5;10,-2.7) 1.03125\n"
|
||||
"R $3(9.3,-5.9;9.9,-5.3) $8(10,-3.5;10,-2.7) 0.78125\n"
|
||||
"R $8(10,-3.5;10,-2.7) P1(12.9,-3.4;13.5,-2.8) 1\n"
|
||||
"R $7(0.1,0.1;0.7,0.7) V1(0.4,-5.6;0.4,-5.6) 1.875\n"
|
||||
"R $1(0.3,-5.7;0.5,-5.5) V1(0.4,-5.6;0.4,-5.6) 0"
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ TEST(extraction_analytic_disc)
|
|||
rex.extract (disc, vertex_ports, polygon_ports, rn);
|
||||
|
||||
EXPECT_EQ (rn.to_string (),
|
||||
"R P0 P1 0.245379" // theoretical: 1/(2*PI)*log(r2/r1) = 0.25615 with r2=10000, r1=2000
|
||||
"R P0 P1 0.245558" // theoretical: 1/(2*PI)*log(r2/r1) = 0.25615 with r2=10000, r1=2000
|
||||
)
|
||||
|
||||
rex.triangulation_parameters ().max_area = 100000 * dbu * dbu;
|
||||
|
|
@ -309,7 +309,7 @@ TEST(extraction_analytic_disc)
|
|||
rex.extract (disc, vertex_ports, polygon_ports, rn);
|
||||
|
||||
EXPECT_EQ (rn.to_string (),
|
||||
"R P0 P1 0.255614" // theoretical: 1/(2*PI)*log(r2/r1) = 0.25615 with r2=10000, r1=2000
|
||||
"R P0 P1 0.255609" // theoretical: 1/(2*PI)*log(r2/r1) = 0.25615 with r2=10000, r1=2000
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -357,7 +357,7 @@ TEST(extraction_meander)
|
|||
rex.extract (poly, vertex_ports, polygon_ports, rn);
|
||||
|
||||
EXPECT_EQ (rn.to_string (),
|
||||
"R V0 V1 8.75751" // what is the "real" value?
|
||||
"R V0 V1 8.61417" // what is the "real" value?
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue