mirror of https://github.com/KLayout/klayout.git
WIP: Polygon#delaunay and variants
This commit is contained in:
parent
21bfe7a632
commit
593678e228
|
|
@ -1455,10 +1455,14 @@ Triangles::create_constrained_delaunay (const db::Region ®ion, const CplxTran
|
|||
}
|
||||
|
||||
void
|
||||
Triangles::create_constrained_delaunay (const db::Polygon &p, const CplxTrans &trans)
|
||||
Triangles::create_constrained_delaunay (const db::Polygon &p, const std::vector<Point> &vertexes, const CplxTrans &trans)
|
||||
{
|
||||
clear ();
|
||||
|
||||
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
|
||||
insert_point (trans * *v);
|
||||
}
|
||||
|
||||
std::vector<std::vector<db::Vertex *> > edge_contours;
|
||||
make_contours (p, trans, edge_contours);
|
||||
|
||||
|
|
@ -1466,12 +1470,16 @@ Triangles::create_constrained_delaunay (const db::Polygon &p, const CplxTrans &t
|
|||
}
|
||||
|
||||
void
|
||||
Triangles::create_constrained_delaunay (const db::DPolygon &p)
|
||||
Triangles::create_constrained_delaunay (const db::DPolygon &p, const std::vector<DPoint> &vertexes, const DCplxTrans &trans)
|
||||
{
|
||||
clear ();
|
||||
|
||||
for (auto v = vertexes.begin (); v != vertexes.end (); ++v) {
|
||||
insert_point (trans * *v);
|
||||
}
|
||||
|
||||
std::vector<std::vector<db::Vertex *> > edge_contours;
|
||||
make_contours (p, db::DUnitTrans (), edge_contours);
|
||||
make_contours (p, trans, edge_contours);
|
||||
|
||||
constrain (edge_contours);
|
||||
}
|
||||
|
|
@ -1529,28 +1537,46 @@ Triangles::triangulate (const db::Region ®ion, const TriangulateParameters &p
|
|||
|
||||
void
|
||||
Triangles::triangulate (const db::Polygon &poly, const TriangulateParameters ¶meters, double dbu)
|
||||
{
|
||||
triangulate (poly, std::vector<db::Point> (), parameters, dbu);
|
||||
}
|
||||
|
||||
void
|
||||
Triangles::triangulate (const db::Polygon &poly, const std::vector<db::Point> &vertexes, const TriangulateParameters ¶meters, double dbu)
|
||||
{
|
||||
tl::SelfTimer timer (tl::verbosity () > parameters.base_verbosity, "Triangles::triangulate");
|
||||
|
||||
create_constrained_delaunay (poly, db::CplxTrans (dbu));
|
||||
create_constrained_delaunay (poly, vertexes, db::CplxTrans (dbu));
|
||||
refine (parameters);
|
||||
}
|
||||
|
||||
void
|
||||
Triangles::triangulate (const db::Polygon &poly, const TriangulateParameters ¶meters, const db::CplxTrans &trans)
|
||||
{
|
||||
triangulate (poly, std::vector<db::Point> (), parameters, trans);
|
||||
}
|
||||
|
||||
void
|
||||
Triangles::triangulate (const db::Polygon &poly, const std::vector<db::Point> &vertexes, const TriangulateParameters ¶meters, const db::CplxTrans &trans)
|
||||
{
|
||||
tl::SelfTimer timer (tl::verbosity () > parameters.base_verbosity, "Triangles::triangulate");
|
||||
|
||||
create_constrained_delaunay (poly, trans);
|
||||
create_constrained_delaunay (poly, vertexes, trans);
|
||||
refine (parameters);
|
||||
}
|
||||
|
||||
void
|
||||
Triangles::triangulate (const db::DPolygon &poly, const TriangulateParameters ¶meters)
|
||||
Triangles::triangulate (const db::DPolygon &poly, const TriangulateParameters ¶meters, const DCplxTrans &trans)
|
||||
{
|
||||
triangulate (poly, std::vector<db::DPoint> (), parameters, trans);
|
||||
}
|
||||
|
||||
void
|
||||
Triangles::triangulate (const db::DPolygon &poly, const std::vector<db::DPoint> &vertexes, const TriangulateParameters ¶meters, const DCplxTrans &trans)
|
||||
{
|
||||
tl::SelfTimer timer (tl::verbosity () > parameters.base_verbosity, "Triangles::triangulate");
|
||||
|
||||
create_constrained_delaunay (poly);
|
||||
create_constrained_delaunay (poly, vertexes, trans);
|
||||
refine (parameters);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -160,14 +160,17 @@ public:
|
|||
void triangulate (const db::Region ®ion, const TriangulateParameters ¶meters, double dbu = 1.0);
|
||||
|
||||
// more versions
|
||||
void triangulate (const db::Polygon &poly, const TriangulateParameters ¶meters, double dbu = 1.0);
|
||||
void triangulate (const db::Region ®ion, const TriangulateParameters ¶meters, const db::CplxTrans &trans = db::CplxTrans ());
|
||||
void triangulate (const db::Polygon &poly, const TriangulateParameters ¶meters, double dbu = 1.0);
|
||||
void triangulate (const db::Polygon &poly, const std::vector<db::Point> &vertexes, const TriangulateParameters ¶meters, double dbu = 1.0);
|
||||
void triangulate (const db::Polygon &poly, const TriangulateParameters ¶meters, const db::CplxTrans &trans = db::CplxTrans ());
|
||||
void triangulate (const db::Polygon &poly, const std::vector<db::Point> &vertexes, const TriangulateParameters ¶meters, const db::CplxTrans &trans = db::CplxTrans ());
|
||||
|
||||
/**
|
||||
* @brief Triangulates a floating-point polygon
|
||||
*/
|
||||
void triangulate (const db::DPolygon &poly, const TriangulateParameters ¶meters);
|
||||
void triangulate (const db::DPolygon &poly, const TriangulateParameters ¶meters, const db::DCplxTrans &trans = db::DCplxTrans ());
|
||||
void triangulate (const db::DPolygon &poly, const std::vector<db::DPoint> &vertexes, const TriangulateParameters ¶meters, const db::DCplxTrans &trans = db::DCplxTrans ());
|
||||
|
||||
/**
|
||||
* @brief Statistics: number of flips (fixing)
|
||||
|
|
@ -289,12 +292,12 @@ protected:
|
|||
/**
|
||||
* @brief Creates a constrained Delaunay triangulation from the given Polygon
|
||||
*/
|
||||
void create_constrained_delaunay (const db::Polygon &poly, const db::CplxTrans &trans = db::CplxTrans ());
|
||||
void create_constrained_delaunay (const db::Polygon &poly, const std::vector<db::Point> &vertexes, const db::CplxTrans &trans = db::CplxTrans ());
|
||||
|
||||
/**
|
||||
* @brief Creates a constrained Delaunay triangulation from the given DPolygon
|
||||
*/
|
||||
void create_constrained_delaunay (const db::DPolygon &poly);
|
||||
void create_constrained_delaunay (const db::DPolygon &poly, const std::vector<DPoint> &vertexes, const DCplxTrans &trans);
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether the edge is "illegal" (violates the Delaunay criterion)
|
||||
|
|
|
|||
|
|
@ -28,10 +28,124 @@
|
|||
#include "dbPolygonTools.h"
|
||||
#include "dbPolygonGenerators.h"
|
||||
#include "dbHash.h"
|
||||
#include "dbTriangles.h"
|
||||
|
||||
namespace gsi
|
||||
{
|
||||
|
||||
template <class T>
|
||||
static db::Region region_from_triangles (const db::Triangles &tri, const T &trans)
|
||||
{
|
||||
db::Region result;
|
||||
|
||||
db::Point pts [3];
|
||||
|
||||
for (auto t = tri.begin (); t != tri.end (); ++t) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
pts [i] = trans * *t->vertex (i);
|
||||
}
|
||||
db::SimplePolygon poly;
|
||||
poly.assign_hull (pts + 0, pts + 3);
|
||||
result.insert (poly);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class P, class T>
|
||||
static std::vector<P> polygons_from_triangles (const db::Triangles &tri, const T &trans)
|
||||
{
|
||||
std::vector<P> result;
|
||||
result.reserve (tri.num_triangles ());
|
||||
|
||||
typename P::point_type pts [3];
|
||||
|
||||
for (auto t = tri.begin (); t != tri.end (); ++t) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
pts [i] = trans * *t->vertex (i);
|
||||
}
|
||||
P poly;
|
||||
poly.assign_hull (pts + 0, pts + 3);
|
||||
result.push_back (poly);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class C>
|
||||
static db::polygon<C> to_polygon (const db::simple_polygon<C> &sp)
|
||||
{
|
||||
db::polygon<C> p;
|
||||
p.assign_hull (sp.begin_hull (), sp.end_hull ());
|
||||
return p;
|
||||
}
|
||||
|
||||
template <class C>
|
||||
static db::polygon<C> to_polygon (const db::polygon<C> &p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
template <class P>
|
||||
static db::Region triangulate_ipolygon (const P *p, double max_area = 0.0, double min_b = 0.0, double dbu = 0.001)
|
||||
{
|
||||
db::Triangles tris;
|
||||
db::Triangles::TriangulateParameters param;
|
||||
param.min_b = min_b;
|
||||
param.max_area = max_area * dbu * dbu;
|
||||
|
||||
db::CplxTrans trans = db::CplxTrans (dbu) * db::ICplxTrans (db::Trans (db::Point () - p->box ().center ()));
|
||||
|
||||
tris.triangulate (to_polygon (*p), param, trans);
|
||||
|
||||
return region_from_triangles (tris, trans.inverted ());
|
||||
}
|
||||
|
||||
template <class P>
|
||||
static db::Region triangulate_ipolygon_v (const P *p, const std::vector<db::Point> &vertexes, double max_area = 0.0, double min_b = 0.0, double dbu = 0.001)
|
||||
{
|
||||
db::Triangles tris;
|
||||
db::Triangles::TriangulateParameters param;
|
||||
param.min_b = min_b;
|
||||
param.max_area = max_area * dbu * dbu;
|
||||
|
||||
db::CplxTrans trans = db::CplxTrans (dbu) * db::ICplxTrans (db::Trans (db::Point () - p->box ().center ()));
|
||||
|
||||
tris.triangulate (to_polygon (*p), vertexes, param, trans);
|
||||
|
||||
return region_from_triangles (tris, trans.inverted ());
|
||||
}
|
||||
|
||||
template <class P>
|
||||
static std::vector<P> triangulate_dpolygon (const P *p, double max_area = 0.0, double min_b = 0.0)
|
||||
{
|
||||
db::Triangles tris;
|
||||
db::Triangles::TriangulateParameters param;
|
||||
param.min_b = min_b;
|
||||
param.max_area = max_area;
|
||||
|
||||
db::DCplxTrans trans = db::DCplxTrans (db::DTrans (db::DPoint () - p->box ().center ()));
|
||||
|
||||
tris.triangulate (to_polygon (*p), param, trans);
|
||||
|
||||
return polygons_from_triangles<P, db::DCplxTrans> (tris, trans.inverted ());
|
||||
}
|
||||
|
||||
template <class P>
|
||||
static std::vector<P> triangulate_dpolygon_v (const P *p, const std::vector<db::DPoint> &vertexes, double max_area = 0.0, double min_b = 0.0)
|
||||
{
|
||||
db::Triangles tris;
|
||||
db::Triangles::TriangulateParameters param;
|
||||
param.min_b = min_b;
|
||||
param.max_area = max_area;
|
||||
|
||||
db::DCplxTrans trans = db::DCplxTrans (db::DTrans (db::DPoint () - p->box ().center ()));
|
||||
|
||||
tris.triangulate (to_polygon (*p), vertexes, param, trans);
|
||||
|
||||
return polygons_from_triangles<P, db::DCplxTrans> (tris, trans.inverted ());
|
||||
}
|
||||
|
||||
template <class C>
|
||||
static std::vector<C> split_poly (const C *p)
|
||||
{
|
||||
|
|
@ -766,6 +880,37 @@ Class<db::SimplePolygon> decl_SimplePolygon ("db", "SimplePolygon",
|
|||
"\n"
|
||||
"This method has been introduced in version 0.18.\n"
|
||||
) +
|
||||
method_ext ("delaunay", &triangulate_ipolygon<db::SimplePolygon>, gsi::arg ("max_area", 0.0), gsi::arg ("min_b", 0.0), gsi::arg ("dbu", 0.001),
|
||||
"@brief Performs a Delaunay triangulation of the polygon.\n"
|
||||
"\n"
|
||||
"@return A \\Region holding the triangles of the refined, constrained Delaunay triangulation.\n"
|
||||
"\n"
|
||||
"Refinement is implemented by Chew's second algorithm. A maximum area can be given. Triangles "
|
||||
"larger than this area will be split. In addition 'skinny' triangles will be resolved where "
|
||||
"possible. 'skinny' is defined in terms of shortest edge to circumcircle radius ratio (b). "
|
||||
"A minimum number for b can be given. A value of 1.0 corresponds to a minimum angle of 30 degree "
|
||||
"and is usually a good choice. The algorithm is stable up to roughly 1.2 which corresponds to "
|
||||
"a minimum angle of abouth 37 degree.\n"
|
||||
"\n"
|
||||
"The minimum angle of the resulting triangles relates to the 'b' parameter as: @t min_angle = arcsin(B/2) @/t.\n"
|
||||
"\n"
|
||||
"The area value is given in terms of DBU units. Picking a value of 0.0 for area and min b will "
|
||||
"make the implementation skip the refinement step. In that case, the results are identical to "
|
||||
"the standard constrained Delaunay triangulation.\n"
|
||||
"\n"
|
||||
"The 'dbu' parameter a numerical scaling parameter. It should be choosen in a way that the polygon dimensions "
|
||||
"are \"in the order of 1\" (very roughly) after multiplication with the dbu parameter. A value of 0.001 is suitable "
|
||||
"for polygons with typical dimensions in the order to 1000 DBU. Usually the default value is good enough.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.30."
|
||||
) +
|
||||
method_ext ("delaunay", &triangulate_ipolygon_v<db::SimplePolygon>, gsi::arg ("vertexes"), gsi::arg ("max_area", 0.0), gsi::arg ("min_b", 0.0), gsi::arg ("dbu", 0.001),
|
||||
"@brief Performs a Delaunay triangulation of the polygon.\n"
|
||||
"\n"
|
||||
"This variant of the triangulation function accepts an array of additional vertexes for the triangulation.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.30."
|
||||
) +
|
||||
simple_polygon_defs<db::SimplePolygon>::methods (),
|
||||
"@brief A simple polygon class\n"
|
||||
"\n"
|
||||
|
|
@ -861,6 +1006,33 @@ Class<db::DSimplePolygon> decl_DSimplePolygon ("db", "DSimplePolygon",
|
|||
"\n"
|
||||
"This method has been introduced in version 0.25.\n"
|
||||
) +
|
||||
method_ext ("delaunay", &triangulate_dpolygon<db::DSimplePolygon>, gsi::arg ("max_area", 0.0), gsi::arg ("min_b", 0.0),
|
||||
"@brief Performs a Delaunay triangulation of the polygon.\n"
|
||||
"\n"
|
||||
"@return An array of triangular polygons of the refined, constrained Delaunay triangulation.\n"
|
||||
"\n"
|
||||
"Refinement is implemented by Chew's second algorithm. A maximum area can be given. Triangles "
|
||||
"larger than this area will be split. In addition 'skinny' triangles will be resolved where "
|
||||
"possible. 'skinny' is defined in terms of shortest edge to circumcircle radius ratio (b). "
|
||||
"A minimum number for b can be given. A value of 1.0 corresponds to a minimum angle of 30 degree "
|
||||
"and is usually a good choice. The algorithm is stable up to roughly 1.2 which corresponds to "
|
||||
"a minimum angle of abouth 37 degree.\n"
|
||||
"\n"
|
||||
"The minimum angle of the resulting triangles relates to the 'b' parameter as: @t min_angle = arcsin(B/2) @/t.\n"
|
||||
"\n"
|
||||
"Picking a value of 0.0 for max area and min b will "
|
||||
"make the implementation skip the refinement step. In that case, the results are identical to "
|
||||
"the standard constrained Delaunay triangulation.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.30."
|
||||
) +
|
||||
method_ext ("delaunay", &triangulate_dpolygon_v<db::DSimplePolygon>, gsi::arg ("vertexes"), gsi::arg ("max_area", 0.0), gsi::arg ("min_b", 0.0),
|
||||
"@brief Performs a Delaunay triangulation of the polygon.\n"
|
||||
"\n"
|
||||
"This variant of the triangulation function accepts an array of additional vertexes for the triangulation.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.30."
|
||||
) +
|
||||
simple_polygon_defs<db::DSimplePolygon>::methods (),
|
||||
"@brief A simple polygon class\n"
|
||||
"\n"
|
||||
|
|
@ -2035,6 +2207,37 @@ Class<db::Polygon> decl_Polygon ("db", "Polygon",
|
|||
"\n"
|
||||
"This method was introduced in version 0.18.\n"
|
||||
) +
|
||||
method_ext ("delaunay", &triangulate_ipolygon<db::Polygon>, gsi::arg ("max_area", 0.0), gsi::arg ("min_b", 0.0), gsi::arg ("dbu", 0.001),
|
||||
"@brief Performs a Delaunay triangulation of the polygon.\n"
|
||||
"\n"
|
||||
"@return A \\Region holding the triangles of the refined, constrained Delaunay triangulation.\n"
|
||||
"\n"
|
||||
"Refinement is implemented by Chew's second algorithm. A maximum area can be given. Triangles "
|
||||
"larger than this area will be split. In addition 'skinny' triangles will be resolved where "
|
||||
"possible. 'skinny' is defined in terms of shortest edge to circumcircle radius ratio (b). "
|
||||
"A minimum number for b can be given. A value of 1.0 corresponds to a minimum angle of 30 degree "
|
||||
"and is usually a good choice. The algorithm is stable up to roughly 1.2 which corresponds to "
|
||||
"a minimum angle of abouth 37 degree.\n"
|
||||
"\n"
|
||||
"The minimum angle of the resulting triangles relates to the 'b' parameter as: @t min_angle = arcsin(B/2) @/t.\n"
|
||||
"\n"
|
||||
"The area value is given in terms of DBU units. Picking a value of 0.0 for area and min b will "
|
||||
"make the implementation skip the refinement step. In that case, the results are identical to "
|
||||
"the standard constrained Delaunay triangulation.\n"
|
||||
"\n"
|
||||
"The 'dbu' parameter a numerical scaling parameter. It should be choosen in a way that the polygon dimensions "
|
||||
"are \"in the order of 1\" (very roughly) after multiplication with the dbu parameter. A value of 0.001 is suitable "
|
||||
"for polygons with typical dimensions in the order to 1000 DBU. Usually the default value is good enough.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.30."
|
||||
) +
|
||||
method_ext ("delaunay", &triangulate_ipolygon_v<db::Polygon>, gsi::arg ("vertexes"), gsi::arg ("max_area", 0.0), gsi::arg ("min_b", 0.0), gsi::arg ("dbu", 0.001),
|
||||
"@brief Performs a Delaunay triangulation of the polygon.\n"
|
||||
"\n"
|
||||
"This variant of the triangulation function accepts an array of additional vertexes for the triangulation.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.30."
|
||||
) +
|
||||
polygon_defs<db::Polygon>::methods (),
|
||||
"@brief A polygon class\n"
|
||||
"\n"
|
||||
|
|
@ -2157,6 +2360,33 @@ Class<db::DPolygon> decl_DPolygon ("db", "DPolygon",
|
|||
"\n"
|
||||
"This method has been introduced in version 0.25.\n"
|
||||
) +
|
||||
method_ext ("delaunay", &triangulate_dpolygon<db::DPolygon>, gsi::arg ("max_area", 0.0), gsi::arg ("min_b", 0.0),
|
||||
"@brief Performs a Delaunay triangulation of the polygon.\n"
|
||||
"\n"
|
||||
"@return An array of triangular polygons of the refined, constrained Delaunay triangulation.\n"
|
||||
"\n"
|
||||
"Refinement is implemented by Chew's second algorithm. A maximum area can be given. Triangles "
|
||||
"larger than this area will be split. In addition 'skinny' triangles will be resolved where "
|
||||
"possible. 'skinny' is defined in terms of shortest edge to circumcircle radius ratio (b). "
|
||||
"A minimum number for b can be given. A value of 1.0 corresponds to a minimum angle of 30 degree "
|
||||
"and is usually a good choice. The algorithm is stable up to roughly 1.2 which corresponds to "
|
||||
"a minimum angle of abouth 37 degree.\n"
|
||||
"\n"
|
||||
"The minimum angle of the resulting triangles relates to the 'b' parameter as: @t min_angle = arcsin(B/2) @/t.\n"
|
||||
"\n"
|
||||
"Picking a value of 0.0 for max area and min b will "
|
||||
"make the implementation skip the refinement step. In that case, the results are identical to "
|
||||
"the standard constrained Delaunay triangulation.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.30."
|
||||
) +
|
||||
method_ext ("delaunay", &triangulate_dpolygon_v<db::DPolygon>, gsi::arg ("vertexes"), gsi::arg ("max_area", 0.0), gsi::arg ("min_b", 0.0),
|
||||
"@brief Performs a Delaunay triangulation of the polygon.\n"
|
||||
"\n"
|
||||
"This variant of the triangulation function accepts an array of additional vertexes for the triangulation.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.30."
|
||||
) +
|
||||
polygon_defs<db::DPolygon>::methods (),
|
||||
"@brief A polygon class\n"
|
||||
"\n"
|
||||
|
|
|
|||
Loading…
Reference in New Issue