mirror of https://github.com/KLayout/klayout.git
WIP: Shapes#break_polygons, Layout#break_polygons, Region#break_polygons (as alias)
This commit is contained in:
parent
7146db4762
commit
a89e295349
|
|
@ -683,5 +683,88 @@ scale_and_snap (db::Layout &layout, db::Cell &cell, db::Coord g, db::Coord m, db
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// break_polygons implementation
|
||||
|
||||
void
|
||||
break_polygons (db::Shapes &shapes, size_t max_vertex_count, double max_area_ratio)
|
||||
{
|
||||
std::vector<db::Polygon> new_polygons;
|
||||
std::vector<db::Shape> to_delete;
|
||||
|
||||
for (auto s = shapes.begin (db::ShapeIterator::Polygons | db::ShapeIterator::Paths); ! s.at_end (); ++s) {
|
||||
|
||||
std::vector<db::Polygon> polygons;
|
||||
polygons.push_back (db::Polygon ());
|
||||
s->instantiate (polygons.back ());
|
||||
|
||||
bool first = true;
|
||||
while (! polygons.empty ()) {
|
||||
|
||||
std::vector<db::Polygon> split_polygons;
|
||||
|
||||
for (auto p = polygons.begin (); p != polygons.end (); ++p) {
|
||||
if ((max_vertex_count > 0 && p->vertices () > max_vertex_count) ||
|
||||
(max_area_ratio > 0 && p->area_ratio () > max_area_ratio)) {
|
||||
if (first) {
|
||||
to_delete.push_back (*s);
|
||||
}
|
||||
db::split_polygon (*p, split_polygons);
|
||||
} else if (! first) {
|
||||
new_polygons.push_back (db::Polygon ());
|
||||
new_polygons.back ().swap (*p);
|
||||
}
|
||||
}
|
||||
|
||||
first = false;
|
||||
polygons.swap (split_polygons);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
shapes.erase_shapes (to_delete);
|
||||
|
||||
for (auto p = new_polygons.begin (); p != new_polygons.end (); ++p) {
|
||||
shapes.insert (*p);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
break_polygons (db::Layout &layout, db::cell_index_type cell_index, unsigned int layer, size_t max_vertex_count, double max_area_ratio)
|
||||
{
|
||||
if (layout.is_valid_cell_index (cell_index) && layout.is_valid_layer (layer)) {
|
||||
db::Cell &cell = layout.cell (cell_index);
|
||||
break_polygons (cell.shapes (layer), max_vertex_count, max_area_ratio);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
break_polygons (db::Layout &layout, unsigned int layer, size_t max_vertex_count, double max_area_ratio)
|
||||
{
|
||||
for (db::cell_index_type ci = 0; ci < layout.cells (); ++ci) {
|
||||
if (layout.is_valid_cell_index (ci)) {
|
||||
db::Cell &cell = layout.cell (ci);
|
||||
break_polygons (cell.shapes (layer), max_vertex_count, max_area_ratio);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
break_polygons (db::Layout &layout, size_t max_vertex_count, double max_area_ratio)
|
||||
{
|
||||
for (db::cell_index_type ci = 0; ci < layout.cells (); ++ci) {
|
||||
if (layout.is_valid_cell_index (ci)) {
|
||||
db::Cell &cell = layout.cell (ci);
|
||||
for (unsigned int li = 0; li < layout.layers (); ++li) {
|
||||
if (layout.is_valid_layer (li)) {
|
||||
break_polygons (cell.shapes (li), max_vertex_count, max_area_ratio);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -249,6 +249,33 @@ private:
|
|||
*/
|
||||
DB_PUBLIC void scale_and_snap (db::Layout &layout, db::Cell &cell, db::Coord g, db::Coord m, db::Coord d);
|
||||
|
||||
/**
|
||||
* @brief Breaks polygons according to max_vertex_count and max_area_ratio
|
||||
*
|
||||
* This method will investigate all polygons on the given layer and cell and split them in case they
|
||||
* have more than the specified vertices and an bounding-box area to polygon area ratio larget
|
||||
* than the specified max_area_ratio. This serves optimization for algorithms needing a good
|
||||
* bounding box approximation.
|
||||
*
|
||||
* Setting max_vertex_count or max_area_ratio to 0 disables the respective check.
|
||||
*/
|
||||
DB_PUBLIC void break_polygons (db::Layout &layout, db::cell_index_type cell_index, unsigned int layer, size_t max_vertex_count, double max_area_ratio);
|
||||
|
||||
/**
|
||||
* @brief Like "break_polygons" before, but applies it to all cells.
|
||||
*/
|
||||
DB_PUBLIC void break_polygons (db::Layout &layout, unsigned int layer, size_t max_vertex_count, double max_area_ratio);
|
||||
|
||||
/**
|
||||
* @brief Like "break_polygons" before, but applies it to all cells and all layers.
|
||||
*/
|
||||
DB_PUBLIC void break_polygons (db::Layout &layout, size_t max_vertex_count, double max_area_ratio);
|
||||
|
||||
/**
|
||||
* @brief Like "break_polygons" before, but applies it to the given Shapes container.
|
||||
*/
|
||||
DB_PUBLIC void break_polygons (db::Shapes &shapes, size_t max_vertex_count, double max_area_ratio);
|
||||
|
||||
} // namespace db
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ namespace db
|
|||
// Recursive shape iterator implementation
|
||||
|
||||
RecursiveShapeIterator::RecursiveShapeIterator (const RecursiveShapeIterator &d)
|
||||
: gsi::ObjectBase (d)
|
||||
{
|
||||
operator= (d);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#include "dbLayerMapping.h"
|
||||
#include "dbCellMapping.h"
|
||||
#include "dbTechnology.h"
|
||||
#include "dbLayoutUtils.h"
|
||||
#include "tlStream.h"
|
||||
#include "tlGlobPattern.h"
|
||||
|
||||
|
|
@ -1050,6 +1051,16 @@ static void set_properties (db::Layout *layout, unsigned int index, const db::La
|
|||
}
|
||||
}
|
||||
|
||||
void break_polygons2 (db::Layout *layout, unsigned int layer, size_t max_vertex_count, double max_area_ratio)
|
||||
{
|
||||
db::break_polygons (*layout, layer, max_vertex_count, max_area_ratio);
|
||||
}
|
||||
|
||||
void break_polygons1 (db::Layout *layout, size_t max_vertex_count, double max_area_ratio)
|
||||
{
|
||||
db::break_polygons (*layout, max_vertex_count, max_area_ratio);
|
||||
}
|
||||
|
||||
Class<db::Layout> decl_Layout ("db", "Layout",
|
||||
gsi::constructor ("new", &layout_ctor_with_manager, gsi::arg ("manager"),
|
||||
"@brief Creates a layout object attached to a manager\n"
|
||||
|
|
@ -1956,6 +1967,33 @@ Class<db::Layout> decl_Layout ("db", "Layout",
|
|||
"\n"
|
||||
"This method has been introduced in version 0.26.1.\n"
|
||||
) +
|
||||
gsi::method_ext ("break_polygons", &break_polygons1, gsi::arg ("max_vertex_count"), gsi::arg ("max_area_ratio", 0.0),
|
||||
"@brief Breaks the polygons of the layout into smaller ones\n"
|
||||
"\n"
|
||||
"There are two criteria for splitting a polygon: a polygon is split into parts with less then "
|
||||
"'max_vertex_count' points and an bounding box-to-polygon area ratio less than 'max_area_ratio'. "
|
||||
"The area ratio is supposed to render polygons whose bounding box is a better approximation. "
|
||||
"This applies for example to 'L' shape polygons.\n"
|
||||
"\n"
|
||||
"Using a value of 0 for either limit means that the respective limit isn't checked. "
|
||||
"Breaking happens by cutting the polygons into parts at 'good' locations. The "
|
||||
"algorithm does not have a specific goal to minimize the number of parts for example. "
|
||||
"The only goal is to achieve parts within the given limits.\n"
|
||||
"\n"
|
||||
"Breaking also applies to paths if their polygon representation satisfies the breaking criterion. "
|
||||
"In that case, paths are converted to polygons and broken into smaller parts.\n"
|
||||
"\n"
|
||||
"This variant applies breaking to all cells and layers.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.29.5."
|
||||
) +
|
||||
gsi::method_ext ("break_polygons", &break_polygons2, gsi::arg ("layer"), gsi::arg ("max_vertex_count"), gsi::arg ("max_area_ratio", 0.0),
|
||||
"@brief Breaks the polygons of the layer into smaller ones\n"
|
||||
"\n"
|
||||
"This variant applies breaking to all cells and the given layer.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.29.5."
|
||||
) +
|
||||
gsi::method ("transform", (void (db::Layout::*) (const db::Trans &t)) &db::Layout::transform, gsi::arg ("trans"),
|
||||
"@brief Transforms the layout with the given transformation\n"
|
||||
"\n"
|
||||
|
|
|
|||
|
|
@ -2895,7 +2895,7 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"This method returns all polygons in self which are not rectilinear."
|
||||
"Merged semantics applies for this method (see \\merged_semantics= for a description of this concept)\n"
|
||||
) +
|
||||
method_ext ("break", &break_polygons, gsi::arg ("max_vertex_count"), gsi::arg ("max_area_ratio", 0.0),
|
||||
method_ext ("break_polygons|#break", &break_polygons, gsi::arg ("max_vertex_count"), gsi::arg ("max_area_ratio", 0.0),
|
||||
"@brief Breaks the polygons of the region into smaller ones\n"
|
||||
"\n"
|
||||
"There are two criteria for splitting a polygon: a polygon is split into parts with less then "
|
||||
|
|
@ -2908,7 +2908,8 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"algorithm does not have a specific goal to minimize the number of parts for example. "
|
||||
"The only goal is to achieve parts within the given limits.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.26."
|
||||
"This method has been introduced in version 0.26. The 'break_polygons' alias has been introduced "
|
||||
"in version 0.29.5 to avoid issues with reserved keywords."
|
||||
) +
|
||||
method_ext ("delaunay", &delaunay,
|
||||
"@brief Computes a constrained Delaunay triangulation from the given region\n"
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "dbRegion.h"
|
||||
#include "dbEdgePairs.h"
|
||||
#include "dbEdges.h"
|
||||
#include "dbLayoutUtils.h"
|
||||
|
||||
namespace gsi
|
||||
{
|
||||
|
|
@ -441,6 +442,11 @@ static db::Layout *layout (db::Shapes *sh)
|
|||
}
|
||||
}
|
||||
|
||||
static void break_polygons (db::Shapes *sh, size_t max_vertex_count, double max_area_ratio)
|
||||
{
|
||||
db::break_polygons (*sh, max_vertex_count, max_area_ratio);
|
||||
}
|
||||
|
||||
static unsigned int s_all () { return db::ShapeIterator::All; }
|
||||
static unsigned int s_all_with_properties () { return db::ShapeIterator::AllWithProperties; }
|
||||
static unsigned int s_properties () { return db::ShapeIterator::Properties; }
|
||||
|
|
@ -791,6 +797,24 @@ Class<db::Shapes> decl_Shapes ("db", "Shapes",
|
|||
"\n"
|
||||
"This method has been introduced in version 0.25.\n"
|
||||
) +
|
||||
gsi::method_ext ("break_polygons", &break_polygons, gsi::arg ("max_vertex_count"), gsi::arg ("max_area_ratio", 0.0),
|
||||
"@brief Breaks the polygons of the shape container into smaller ones\n"
|
||||
"\n"
|
||||
"There are two criteria for splitting a polygon: a polygon is split into parts with less then "
|
||||
"'max_vertex_count' points and an bounding box-to-polygon area ratio less than 'max_area_ratio'. "
|
||||
"The area ratio is supposed to render polygons whose bounding box is a better approximation. "
|
||||
"This applies for example to 'L' shape polygons.\n"
|
||||
"\n"
|
||||
"Using a value of 0 for either limit means that the respective limit isn't checked. "
|
||||
"Breaking happens by cutting the polygons into parts at 'good' locations. The "
|
||||
"algorithm does not have a specific goal to minimize the number of parts for example. "
|
||||
"The only goal is to achieve parts within the given limits.\n"
|
||||
"\n"
|
||||
"Breaking also applies to paths if their polygon representation satisfies the breaking criterion. "
|
||||
"In that case, paths are converted to polygons and broken into smaller parts.\n"
|
||||
"\n"
|
||||
"This method has been introduced in version 0.29.5."
|
||||
) +
|
||||
gsi::method_ext ("replace", &replace<db::Box>, gsi::arg ("shape"), gsi::arg ("box"),
|
||||
"@brief Replaces the given shape with a box\n"
|
||||
"@return A reference to the new shape (a \\Shape object)\n"
|
||||
|
|
|
|||
Loading…
Reference in New Issue