WIP: more on deep edge collections.

This commit is contained in:
Matthias Koefferlein 2019-02-10 15:33:14 +01:00
parent f22217b6c4
commit a14ca01bac
22 changed files with 384 additions and 205 deletions

View File

@ -926,5 +926,17 @@ AsIfFlatEdges::less (const Edges &other) const
return false;
}
void
AsIfFlatEdges::insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
{
// improves performance when inserting an original layout into the same layout
db::LayoutLocker locker (layout);
db::Shapes &shapes = layout->cell (into_cell).shapes (into_layer);
for (EdgesIterator e (begin ()); ! e.at_end (); ++e) {
shapes.insert (*e);
}
}
}

View File

@ -154,6 +154,8 @@ public:
virtual bool equals (const Edges &other) const;
virtual bool less (const Edges &other) const;
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const;
protected:
void update_bbox (const db::Box &box);
void invalidate_bbox ();

View File

@ -87,14 +87,14 @@ private:
// -------------------------------------------------------------------------------------------------------------
// DeepEdges implementation
DeepEdges::DeepEdges (const RecursiveShapeIterator &si, DeepShapeStore &dss)
: AsIfFlatEdges (), m_deep_layer (dss.create_edge_layer (si)), m_merged_edges ()
DeepEdges::DeepEdges (const RecursiveShapeIterator &si, DeepShapeStore &dss, bool as_edges)
: AsIfFlatEdges (), m_deep_layer (dss.create_edge_layer (si, as_edges)), m_merged_edges ()
{
init ();
}
DeepEdges::DeepEdges (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans, bool merged_semantics)
: AsIfFlatEdges (), m_deep_layer (dss.create_edge_layer (si)), m_merged_edges ()
DeepEdges::DeepEdges (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans, bool as_edges, bool merged_semantics)
: AsIfFlatEdges (), m_deep_layer (dss.create_edge_layer (si, as_edges)), m_merged_edges ()
{
init ();

View File

@ -42,8 +42,8 @@ class DB_PUBLIC DeepEdges
{
public:
DeepEdges ();
DeepEdges (const RecursiveShapeIterator &si, DeepShapeStore &dss);
DeepEdges (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans, bool merged_semantics = true);
DeepEdges (const RecursiveShapeIterator &si, DeepShapeStore &dss, bool as_edges = true);
DeepEdges (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans, bool as_edges = true, bool merged_semantics = true);
DeepEdges (const DeepEdges &other);
DeepEdges (const DeepLayer &dl);

View File

@ -393,7 +393,7 @@ DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator
return DeepLayer (this, layout_index, layer_index);
}
DeepLayer DeepShapeStore::create_edge_layer (const db::RecursiveShapeIterator &si)
DeepLayer DeepShapeStore::create_edge_layer (const db::RecursiveShapeIterator &si, bool as_edges)
{
unsigned int layout_index = layout_for_iter (si);
@ -404,7 +404,7 @@ DeepLayer DeepShapeStore::create_edge_layer (const db::RecursiveShapeIterator &s
builder.set_target_layer (layer_index);
// The chain of operators for producing clipped and reduced polygon references
db::EdgeBuildingHierarchyBuilderShapeReceiver refs;
db::EdgeBuildingHierarchyBuilderShapeReceiver refs (as_edges);
// Build the working hierarchy from the recursive shape iterator
try {

View File

@ -246,8 +246,12 @@ public:
* This method will create a new layer inside the deep shape store as a
* working copy of the original layer. This method creates a layer
* for edges.
*
* If "as_edges" is true, polygons and boxes will be converted into edges. Otherwise
* only edge objects are taken from the shape iterator. Note that the shape iterator
* must be configured to deliver all shape types if "as_edges" is true.
*/
DeepLayer create_edge_layer (const db::RecursiveShapeIterator &si);
DeepLayer create_edge_layer (const db::RecursiveShapeIterator &si, bool as_edges);
/**
* @brief Inserts the deep layer's shapes into some target layout

View File

@ -21,6 +21,7 @@
*/
#include "dbEdges.h"
#include "dbDeepEdges.h"
#include "dbOriginalLayerEdges.h"
#include "dbEmptyEdges.h"
#include "dbFlatEdges.h"
@ -91,6 +92,16 @@ Edges::Edges (const RecursiveShapeIterator &si, const db::ICplxTrans &trans, boo
}
}
Edges::Edges (const RecursiveShapeIterator &si, DeepShapeStore &dss, bool as_edges)
{
mp_delegate = new DeepEdges (si, dss, as_edges);
}
Edges::Edges (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans, bool as_edges, bool merged_semantics)
{
mp_delegate = new DeepEdges (si, dss, trans, as_edges, merged_semantics);
}
const db::RecursiveShapeIterator &
Edges::iter () const
{

View File

@ -36,6 +36,7 @@ namespace db {
class EdgeFilterBase;
class FlatEdges;
class EmptyEdges;
class DeepShapeStore;
/**
* @brief An edge set iterator
@ -391,7 +392,7 @@ public:
* Creates an edge set representing a single instance of that object
*/
template <class Sh>
Edges (const Sh &s)
explicit Edges (const Sh &s)
: mp_delegate (0)
{
insert (s);
@ -405,7 +406,7 @@ public:
* style.
*/
template <class Iter>
Edges (const Iter &b, const Iter &e)
explicit Edges (const Iter &b, const Iter &e)
: mp_delegate (0)
{
reserve (e - b);
@ -420,7 +421,7 @@ public:
* Creates an edge set from a recursive shape iterator. This allows to feed an edge set
* from a hierarchy of cells.
*/
Edges (const RecursiveShapeIterator &si, bool as_edges = true);
explicit Edges (const RecursiveShapeIterator &si, bool as_edges = true);
/**
* @brief Constructor from a RecursiveShapeIterator with a transformation
@ -429,7 +430,20 @@ public:
* from a hierarchy of cells. The transformation is useful to scale to a specific
* DBU for example.
*/
Edges (const RecursiveShapeIterator &si, const db::ICplxTrans &trans, bool as_edges = true, bool merged_semantics = true);
explicit Edges (const RecursiveShapeIterator &si, const db::ICplxTrans &trans, bool as_edges = true, bool merged_semantics = true);
/**
* @brief Constructor from a RecursiveShapeIterator providing a deep representation
*
* This version will create a hierarchical edge collection. The DeepShapeStore needs to be provided
* during the lifetime of the collection and acts as a heap for optimized data.
*/
explicit Edges (const RecursiveShapeIterator &si, DeepShapeStore &dss, bool as_edges = true);
/**
* @brief Constructor from a RecursiveShapeIterator providing a deep representation with transformation
*/
explicit Edges (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans, bool as_edges = true, bool merged_semantics = true);
/**
* @brief Gets the underlying delegate object
@ -1283,6 +1297,16 @@ public:
return mp_delegate->less (other);
}
/**
* @brief Inserts the edge collection into the given layout, cell and layer
* If the edge collection is a hierarchical region, the hierarchy is copied into the
* layout's hierarchy.
*/
void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
{
return mp_delegate->insert_into (layout, into_cell, into_layer);
}
private:
friend class EdgePairs;

View File

@ -164,6 +164,8 @@ public:
virtual bool equals (const Edges &other) const = 0;
virtual bool less (const Edges &other) const = 0;
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const = 0;
protected:
const std::string &progress_desc () const
{

View File

@ -101,6 +101,8 @@ public:
virtual bool equals (const Edges &other) const;
virtual bool less (const Edges &other) const;
virtual void insert_into (Layout *, db::cell_index_type, unsigned int) const { }
private:
EmptyEdges &operator= (const EmptyEdges &other);
};

View File

@ -88,6 +88,11 @@ void FlatEdges::init ()
m_merged_edges_valid = false;
}
void FlatEdges::insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
{
layout->cell (into_cell).shapes (into_layer).insert (m_edges);
}
void FlatEdges::merged_semantics_changed ()
{
m_merged_edges.clear ();

View File

@ -109,6 +109,8 @@ public:
virtual size_t size () const;
virtual bool is_merged () const;
virtual void insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const;
virtual EdgesDelegate *filter_in_place (const EdgeFilterBase &filter);
virtual EdgesDelegate *add_in_place (const Edges &other);

View File

@ -202,14 +202,14 @@ template <class Trans>
static bool
interaction_test (const db::Edge &a, const db::Edge &b, const Trans &trans)
{
return a.intersect (b.transformed (trans));
return a.coincident (b.transformed (trans));
}
template <class C>
static bool
interaction_test (const db::Edge &a, const db::Edge &b, const db::unit_trans<C> &)
{
return a.intersect (b);
return a.coincident (b);
}
template <class T, class Trans>

View File

@ -600,13 +600,19 @@ void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Polygon &sha
// ---------------------------------------------------------------------------------------------
EdgeBuildingHierarchyBuilderShapeReceiver::EdgeBuildingHierarchyBuilderShapeReceiver (bool as_edges)
: m_as_edges (as_edges)
{
// .. nothing yet ..
}
void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, const db::Box &region, const db::RecursiveShapeReceiver::box_tree_type *complex_region, db::Shapes *target)
{
if (shape.is_polygon () || shape.is_simple_polygon () || shape.is_path ()) {
if (m_as_edges && (shape.is_polygon () || shape.is_simple_polygon () || shape.is_path ())) {
db::Polygon poly;
shape.polygon (poly);
push (poly, region, complex_region, target);
} else if (shape.is_box ()) {
} else if (m_as_edges && shape.is_box ()) {
push (shape.box (), region, complex_region, target);
} else if (shape.is_edge ()) {
target->insert (shape.edge ());
@ -615,7 +621,7 @@ void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Shape &shape, co
void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Box &box, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
{
if (! box.empty ()) {
if (m_as_edges && ! box.empty ()) {
target->insert (db::Edge (box.p1 (), box.upper_left ()));
target->insert (db::Edge (box.upper_left (), box.p2 ()));
target->insert (db::Edge (box.p2 (), box.lower_right ()));
@ -625,8 +631,10 @@ void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Box &box, const
void EdgeBuildingHierarchyBuilderShapeReceiver::push (const db::Polygon &poly, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
{
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
target->insert (*e);
if (m_as_edges) {
for (db::Polygon::polygon_edge_iterator e = poly.begin_edge (); ! e.at_end (); ++e) {
target->insert (*e);
}
}
}

View File

@ -155,9 +155,14 @@ class DB_PUBLIC EdgeBuildingHierarchyBuilderShapeReceiver
: public HierarchyBuilderShapeReceiver
{
public:
EdgeBuildingHierarchyBuilderShapeReceiver (bool as_edges);
virtual void push (const db::Shape &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Box &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
virtual void push (const db::Polygon &shape, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target);
private:
bool m_as_edges;
};
/**

View File

@ -647,7 +647,13 @@ Layout::insert (db::cell_index_type cell, int layer, const db::Region &region)
region.insert_into (this, cell, layer);
}
void
void
Layout::insert (db::cell_index_type cell, int layer, const db::Edges &edges)
{
edges.insert_into (this, cell, layer);
}
void
Layout::flatten (const db::Cell &source_cell, db::Cell &target_cell, const db::ICplxTrans &t, int levels)
{
db::ICplxTrans tt = t;

View File

@ -63,6 +63,7 @@ class LibraryProxy;
class CellMapping;
class LayerMapping;
class Region;
class Edges;
template <class Coord> class generic_repository;
typedef generic_repository<db::Coord> GenericRepository;
@ -1102,6 +1103,15 @@ public:
*/
void insert (db::cell_index_type cell, int layer, const db::Region &region);
/**
* @brief Inserts a edge collection (potentially hierarchical) into the given cell and layer
*
* If the edge collection is flat (conceptionally), it will be put into the cell.
* If the edge collection is hierarchical, a cell hierarchy will be built below the
* given cell.
*/
void insert (db::cell_index_type cell, int layer, const db::Edges &edges);
/**
* @brief Delete a cell plus all subcells
*

View File

@ -23,6 +23,7 @@
#include "gsiDecl.h"
#include "dbDeepShapeStore.h"
#include "dbEdges.h"
#include "dbRegion.h"
#include "dbLayoutUtils.h"
@ -92,6 +93,16 @@ static db::Edges *new_si2 (const db::RecursiveShapeIterator &si, const db::ICplx
return new db::Edges (si, trans, as_edges);
}
static db::Edges *new_sid (const db::RecursiveShapeIterator &si, db::DeepShapeStore &dss, bool as_edges)
{
return new db::Edges (si, dss, as_edges);
}
static db::Edges *new_si2d (const db::RecursiveShapeIterator &si, db::DeepShapeStore &dss, const db::ICplxTrans &trans, bool as_edges)
{
return new db::Edges (si, dss, trans, as_edges);
}
static db::Edges::distance_type length1 (const db::Edges *edges)
{
return edges->length ();
@ -368,59 +379,51 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"This constructor creates an empty edge collection.\n"
) +
constructor ("new", &new_e,
constructor ("new", &new_e, gsi::arg ("edge"),
"@brief Constructor from a single edge\n"
"@args edge\n"
"\n"
"This constructor creates an edge collection with a single edge.\n"
) +
constructor ("new", &new_a1,
constructor ("new", &new_a1, gsi::arg ("array"),
"@brief Constructor from a polygon array\n"
"@args array\n"
"\n"
"This constructor creates a region from an array of polygons.\n"
"The edges form the contours of the polygons.\n"
) +
constructor ("new", &new_a2,
constructor ("new", &new_a2, gsi::arg ("array"),
"@brief Constructor from an egde array\n"
"@args array\n"
"\n"
"This constructor creates a region from an array of edges.\n"
) +
constructor ("new", &new_b,
constructor ("new", &new_b, gsi::arg ("box"),
"@brief Box constructor\n"
"@args box\n"
"\n"
"This constructor creates an edge collection from a box.\n"
"The edges form the contour of the box.\n"
) +
constructor ("new", &new_p,
constructor ("new", &new_p, gsi::arg ("polygon"),
"@brief Polygon constructor\n"
"@args polygon\n"
"\n"
"This constructor creates an edge collection from a polygon.\n"
"The edges form the contour of the polygon.\n"
) +
constructor ("new", &new_ps,
constructor ("new", &new_ps, gsi::arg ("polygon"),
"@brief Simple polygon constructor\n"
"@args polygon\n"
"\n"
"This constructor creates an edge collection from a simple polygon.\n"
"The edges form the contour of the polygon.\n"
) +
constructor ("new", &new_path,
constructor ("new", &new_path, gsi::arg ("path"),
"@brief Path constructor\n"
"@args path\n"
"\n"
"This constructor creates an edge collection from a path.\n"
"The edges form the contour of the path.\n"
) +
constructor ("new", &new_si,
"@brief Constructor from a hierarchical shape set\n"
"@args shape_iterator, as_edges\n"
constructor ("new", &new_si, gsi::arg ("shape_iterator"), gsi::arg ("as_edges", true),
"@brief Constructor of a flat edge collection from a hierarchical shape set\n"
"\n"
"This constructor creates an edge collection from the shapes delivered by the given recursive shape iterator.\n"
"It feeds the shapes from a hierarchy of cells into the edge set.\n"
"It feeds the shapes from a hierarchy of cells into a flat edge set.\n"
"\n"
"Text objects are not inserted, because they cannot be converted to edges.\n"
"Edge objects are inserted as such. If \"as_edges\" is true, \"solid\" objects (boxes, polygons, paths) are converted to edges which "
@ -433,12 +436,11 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"r = RBA::Edges::new(layout.begin_shapes(cell, layer), false)\n"
"@/code\n"
) +
constructor ("new", &new_si2,
"@brief Constructor from a hierarchical shape set with a transformation\n"
"@args shape_iterator, trans, as_edges\n"
constructor ("new", &new_si2, gsi::arg ("shape_iterator"), gsi::arg ("trans"), gsi::arg ("as_edges", true),
"@brief Constructor of a flat edge collection from a hierarchical shape set with a transformation\n"
"\n"
"This constructor creates an edge collection from the shapes delivered by the given recursive shape iterator.\n"
"It feeds the shapes from a hierarchy of cells into the edge set.\n"
"It feeds the shapes from a hierarchy of cells into a flat edge set.\n"
"The transformation is useful to scale to a specific database unit for example.\n"
"\n"
"Text objects are not inserted, because they cannot be converted to edges.\n"
@ -453,16 +455,54 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"r = RBA::Edges::new(layout.begin_shapes(cell, layer), RBA::ICplxTrans::new(layout.dbu / dbu))\n"
"@/code\n"
) +
method_ext ("with_length", with_length1,
constructor ("new", &new_sid, gsi::arg ("shape_iterator"), gsi::arg ("dss"), gsi::arg ("as_edges", true),
"@brief Constructor of a hierarchical edge collection\n"
"\n"
"This constructor creates an edge collection from the shapes delivered by the given recursive shape iterator.\n"
"It feeds the shapes from a hierarchy of cells into the hierarchical edge set.\n"
"The edges remain within their original hierachy unless other operations require the edges to be moved in the hierarchy.\n"
"\n"
"Text objects are not inserted, because they cannot be converted to edges.\n"
"Edge objects are inserted as such. If \"as_edges\" is true, \"solid\" objects (boxes, polygons, paths) are converted to edges which "
"form the hull of these objects. If \"as_edges\" is false, solid objects are ignored.\n"
"\n"
"@code\n"
"dss = RBA::DeepShapeStore::new\n"
"layout = ... # a layout\n"
"cell = ... # the index of the initial cell\n"
"layer = ... # the index of the layer from where to take the shapes from\n"
"r = RBA::Edges::new(layout.begin_shapes(cell, layer), dss, false)\n"
"@/code\n"
) +
constructor ("new", &new_si2d, gsi::arg ("shape_iterator"), gsi::arg ("dss"), gsi::arg ("trans"), gsi::arg ("as_edges", true),
"@brief Constructor of a hierarchical edge collection with a transformation\n"
"\n"
"This constructor creates an edge collection from the shapes delivered by the given recursive shape iterator.\n"
"It feeds the shapes from a hierarchy of cells into the hierarchical edge set.\n"
"The edges remain within their original hierachy unless other operations require the edges to be moved in the hierarchy.\n"
"The transformation is useful to scale to a specific database unit for example.\n"
"\n"
"Text objects are not inserted, because they cannot be converted to edges.\n"
"Edge objects are inserted as such. If \"as_edges\" is true, \"solid\" objects (boxes, polygons, paths) are converted to edges which "
"form the hull of these objects. If \"as_edges\" is false, solid objects are ignored.\n"
"\n"
"@code\n"
"dss = RBA::DeepShapeStore::new\n"
"layout = ... # a layout\n"
"cell = ... # the index of the initial cell\n"
"layer = ... # the index of the layer from where to take the shapes from\n"
"dbu = 0.1 # the target database unit\n"
"r = RBA::Edges::new(layout.begin_shapes(cell, layer), dss, RBA::ICplxTrans::new(layout.dbu / dbu), false)\n"
"@/code\n"
) +
method_ext ("with_length", with_length1, gsi::arg ("length"), gsi::arg ("inverse"),
"@brief Filter the edges by length\n"
"@args length, inverse\n"
"Filters the edges in the edge collection by length. If \"inverse\" is false, only "
"edges which have the given length are returned. If \"inverse\" is true, "
"edges not having the given length are returned.\n"
) +
method_ext ("with_length", with_length2,
method_ext ("with_length", with_length2, gsi::arg ("min_length"), gsi::arg ("max_length"), gsi::arg ("inverse"),
"@brief Filter the edges by length\n"
"@args min_length, max_length, inverse\n"
"Filters the edges in the edge collection by length. If \"inverse\" is false, only "
"edges which have a length larger or equal to \"min_length\" and less than \"max_length\" are "
"returned. If \"inverse\" is true, "
@ -471,9 +511,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"If you don't want to specify a lower or upper limit, pass nil to that parameter.\n"
) +
method_ext ("with_angle", with_angle1,
method_ext ("with_angle", with_angle1, gsi::arg ("angle"), gsi::arg ("inverse"),
"@brief Filter the edges by orientation\n"
"@args length, inverse\n"
"Filters the edges in the edge collection by orientation. If \"inverse\" is false, only "
"edges which have the given angle to the x-axis are returned. If \"inverse\" is true, "
"edges not having the given angle are returned.\n"
@ -484,92 +523,79 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"horizontal = edges.with_orientation(0, true)\n"
"@/code\n"
) +
method_ext ("with_angle", with_angle2,
method_ext ("with_angle", with_angle2, gsi::arg ("min_angle"), gsi::arg ("max_angle"), gsi::arg ("inverse"),
"@brief Filter the edges by orientation\n"
"@args min_angle, max_angle, inverse\n"
"Filters the edges in the edge collection by orientation. If \"inverse\" is false, only "
"edges which have an angle to the x-axis larger or equal to \"min_angle\" and less than \"max_angle\" are "
"returned. If \"inverse\" is true, "
"edges which do not conform to this criterion are returned."
) +
method ("insert", (void (db::Edges::*)(const db::Edge &)) &db::Edges::insert,
method ("insert", (void (db::Edges::*)(const db::Edge &)) &db::Edges::insert, gsi::arg ("edge"),
"@brief Inserts an edge\n"
"@args edge\n"
"\n"
"Inserts the edge into the edge collection.\n"
) +
method ("insert", (void (db::Edges::*)(const db::Box &)) &db::Edges::insert,
method ("insert", (void (db::Edges::*)(const db::Box &)) &db::Edges::insert, gsi::arg ("box"),
"@brief Inserts a box\n"
"@args box\n"
"\n"
"Inserts the edges that form the contour of the box into the edge collection.\n"
) +
method ("insert", (void (db::Edges::*)(const db::Polygon &)) &db::Edges::insert,
method ("insert", (void (db::Edges::*)(const db::Polygon &)) &db::Edges::insert, gsi::arg ("polygon"),
"@brief Inserts a polygon\n"
"@args polygon\n"
"\n"
"Inserts the edges that form the contour of the polygon into the edge collection.\n"
) +
method ("insert", (void (db::Edges::*)(const db::SimplePolygon &)) &db::Edges::insert,
method ("insert", (void (db::Edges::*)(const db::SimplePolygon &)) &db::Edges::insert, gsi::arg ("polygon"),
"@brief Inserts a simple polygon\n"
"@args polygon\n"
"\n"
"Inserts the edges that form the contour of the simple polygon into the edge collection.\n"
) +
method ("insert", (void (db::Edges::*)(const db::Path &)) &db::Edges::insert,
method ("insert", (void (db::Edges::*)(const db::Path &)) &db::Edges::insert, gsi::arg ("path"),
"@brief Inserts a path\n"
"@args path\n"
"\n"
"Inserts the edges that form the contour of the path into the edge collection.\n"
) +
method_ext ("insert", &insert_e,
method_ext ("insert", &insert_e, gsi::arg ("edges"),
"@brief Inserts all edges from the other edge collection into this one\n"
"@args edges\n"
"This method has been introduced in version 0.25."
) +
method_ext ("insert", &insert_r,
method_ext ("insert", &insert_r, gsi::arg ("region"),
"@brief Inserts a region\n"
"@args region\n"
"Inserts the edges that form the contours of the polygons from the region into the edge collection.\n"
"\n"
"This method has been introduced in version 0.25."
) +
method_ext ("insert", &insert_s,
method_ext ("insert", &insert_s, gsi::arg ("shapes"),
"@brief Inserts all edges from the shape collection into this edge collection\n"
"@args shapes\n"
"This method takes each edge from the shape collection and "
"insertes it into the region. \"Polygon-like\" objects are inserted as edges forming the contours of the polygons.\n"
"Text objects are ignored.\n"
"\n"
"This method has been introduced in version 0.25."
) +
method_ext ("insert", &insert_st<db::Trans>,
method_ext ("insert", &insert_st<db::Trans>, gsi::arg ("shapes"), gsi::arg ("trans"),
"@brief Inserts all edges from the shape collection into this edge collection (with transformation)\n"
"@args shapes\n"
"This method acts as the version without transformation, but will apply the given "
"transformation before inserting the edges.\n"
"\n"
"This method has been introduced in version 0.25."
) +
method_ext ("insert", &insert_st<db::ICplxTrans>,
method_ext ("insert", &insert_st<db::ICplxTrans>, gsi::arg ("shapes"), gsi::arg ("trans"),
"@brief Inserts all edges from the shape collection into this edge collection with complex transformation\n"
"@args shapes\n"
"This method acts as the version without transformation, but will apply the given "
"complex transformation before inserting the edges.\n"
"\n"
"This method has been introduced in version 0.25."
) +
method_ext ("insert", &insert_si,
method_ext ("insert", &insert_si, gsi::arg ("shape_iterator"),
"@brief Inserts all shapes delivered by the recursive shape iterator into this edge collection\n"
"@args shape_iterator\n"
"\n"
"For \"solid\" shapes (boxes, polygons, paths), this method inserts the edges that form the contour of the shape into the edge collection.\n"
"Edge shapes are inserted as such.\n"
"Text objects are not inserted, because they cannot be converted to polygons.\n"
) +
method_ext ("insert", &insert_si2,
method_ext ("insert", &insert_si2, gsi::arg ("shape_iterator"), gsi::arg ("trans"),
"@brief Inserts all shapes delivered by the recursive shape iterator into this edge collection with a transformation\n"
"@args shape_iterator, trans\n"
"\n"
"For \"solid\" shapes (boxes, polygons, paths), this method inserts the edges that form the contour of the shape into the edge collection.\n"
"Edge shapes are inserted as such.\n"
@ -577,13 +603,11 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"This variant will apply the given transformation to the shapes. This is useful to scale the "
"shapes to a specific database unit for example.\n"
) +
method_ext ("insert", &insert_a1,
method_ext ("insert", &insert_a1, gsi::arg ("polygons"),
"@brief Inserts all polygons from the array into this edge collection\n"
"@args array\n"
) +
method_ext ("insert", &insert_a2,
method_ext ("insert", &insert_a2, gsi::arg ("edges"),
"@brief Inserts all edges from the array into this edge collection\n"
"@args array\n"
) +
method ("merge", (db::Edges &(db::Edges::*) ()) &db::Edges::merge,
"@brief Merge the edges\n"
@ -603,30 +627,27 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"Crossing edges are not merged.\n"
"In contrast to \\merge, this method does not modify the edge collection but returns a merged copy.\n"
) +
method ("&", (db::Edges (db::Edges::*)(const db::Edges &) const) &db::Edges::operator&,
method ("&", (db::Edges (db::Edges::*)(const db::Edges &) const) &db::Edges::operator&, gsi::arg ("other"),
"@brief Returns the boolean AND between self and the other edge collection\n"
"\n"
"@args other\n"
"@return The result of the boolean AND operation\n"
"\n"
"The boolean AND operation will return all parts of the edges in this collection which "
"are coincident with parts of the edges in the other collection."
"The result will be a merged edge collection.\n"
) +
method ("&=", (db::Edges &(db::Edges::*)(const db::Edges &)) &db::Edges::operator&=,
method ("&=", (db::Edges &(db::Edges::*)(const db::Edges &)) &db::Edges::operator&=, gsi::arg ("other"),
"@brief Performs the boolean AND between self and the other edge collection\n"
"\n"
"@args other\n"
"@return The edge collection after modification (self)\n"
"\n"
"The boolean AND operation will return all parts of the edges in this collection which "
"are coincident with parts of the edges in the other collection."
"The result will be a merged edge collection.\n"
) +
method ("&", (db::Edges (db::Edges::*)(const db::Region &) const) &db::Edges::operator&,
method ("&", (db::Edges (db::Edges::*)(const db::Region &) const) &db::Edges::operator&, gsi::arg ("other"),
"@brief Returns the parts of the edges inside the given region\n"
"\n"
"@args other\n"
"@return The edges inside the given region\n"
"\n"
"This operation returns the parts of the edges which are inside the given region.\n"
@ -636,10 +657,9 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"This method has been introduced in version 0.24."
) +
method ("&=", (db::Edges &(db::Edges::*)(const db::Region &)) &db::Edges::operator&=,
method ("&=", (db::Edges &(db::Edges::*)(const db::Region &)) &db::Edges::operator&=, gsi::arg ("other"),
"@brief Selects the parts of the edges inside the given region\n"
"\n"
"@args other\n"
"@return The edge collection after modification (self)\n"
"\n"
"This operation selects the parts of the edges which are inside the given region.\n"
@ -649,30 +669,27 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"This method has been introduced in version 0.24."
) +
method ("-", (db::Edges (db::Edges::*)(const db::Edges &) const) &db::Edges::operator-,
method ("-", (db::Edges (db::Edges::*)(const db::Edges &) const) &db::Edges::operator-, gsi::arg ("other"),
"@brief Returns the boolean NOT between self and the other edge collection\n"
"\n"
"@args other\n"
"@return The result of the boolean NOT operation\n"
"\n"
"The boolean NOT operation will return all parts of the edges in this collection which "
"are not coincident with parts of the edges in the other collection."
"The result will be a merged edge collection.\n"
) +
method ("-=", (db::Edges &(db::Edges::*)(const db::Edges &)) &db::Edges::operator-=,
method ("-=", (db::Edges &(db::Edges::*)(const db::Edges &)) &db::Edges::operator-=, gsi::arg ("other"),
"@brief Performs the boolean NOT between self and the other edge collection\n"
"\n"
"@args other\n"
"@return The edge collection after modification (self)\n"
"\n"
"The boolean NOT operation will return all parts of the edges in this collection which "
"are not coincident with parts of the edges in the other collection."
"The result will be a merged edge collection.\n"
) +
method ("-", (db::Edges (db::Edges::*)(const db::Region &) const) &db::Edges::operator-,
method ("-", (db::Edges (db::Edges::*)(const db::Region &) const) &db::Edges::operator-, gsi::arg ("other"),
"@brief Returns the parts of the edges outside the given region\n"
"\n"
"@args other\n"
"@return The edges outside the given region\n"
"\n"
"This operation returns the parts of the edges which are outside the given region.\n"
@ -682,10 +699,9 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"This method has been introduced in version 0.24."
) +
method ("-=", (db::Edges &(db::Edges::*)(const db::Region &)) &db::Edges::operator-=,
method ("-=", (db::Edges &(db::Edges::*)(const db::Region &)) &db::Edges::operator-=, gsi::arg ("other"),
"@brief Selects the parts of the edges outside the given region\n"
"\n"
"@args other\n"
"@return The edge collection after modification (self)\n"
"\n"
"This operation selects the parts of the edges which are outside the given region.\n"
@ -695,138 +711,123 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"This method has been introduced in version 0.24."
) +
method ("^", &db::Edges::operator^,
method ("^", &db::Edges::operator^, gsi::arg ("other"),
"@brief Returns the boolean XOR between self and the other edge collection\n"
"\n"
"@args other\n"
"@return The result of the boolean XOR operation\n"
"\n"
"The boolean XOR operation will return all parts of the edges in this and the other collection except "
"the parts where both are coincident.\n"
"The result will be a merged edge collection.\n"
) +
method ("^=", &db::Edges::operator^=,
method ("^=", &db::Edges::operator^=, gsi::arg ("other"),
"@brief Performs the boolean XOR between self and the other edge collection\n"
"\n"
"@args other\n"
"@return The edge collection after modification (self)\n"
"\n"
"The boolean XOR operation will return all parts of the edges in this and the other collection except "
"the parts where both are coincident.\n"
"The result will be a merged edge collection.\n"
) +
method ("\\|", &db::Edges::operator|,
method ("\\|", &db::Edges::operator|, gsi::arg ("other"),
"@brief Returns the boolean OR between self and the other edge set\n"
"\n"
"@args other\n"
"@return The resulting edge collection\n"
"\n"
"The boolean OR is implemented by merging the edges of both edge sets. To simply join the edge collections "
"without merging, the + operator is more efficient."
) +
method ("\\|=", &db::Edges::operator|=,
method ("\\|=", &db::Edges::operator|=, gsi::arg ("other"),
"@brief Performs the boolean OR between self and the other redge set\n"
"\n"
"@args other\n"
"@return The edge collection after modification (self)\n"
"\n"
"The boolean OR is implemented by merging the edges of both edge sets. To simply join the edge collections "
"without merging, the + operator is more efficient."
) +
method ("+", &db::Edges::operator+,
method ("+", &db::Edges::operator+, gsi::arg ("other"),
"@brief Returns the combined edge set of self and the other one\n"
"\n"
"@args other\n"
"@return The resulting edge set\n"
"\n"
"This operator adds the edges of the other edge set to self and returns a new combined edge set. "
"This usually creates unmerged edge sets and edges may overlap. Use \\merge if you want to ensure the result edge set is merged.\n"
) +
method ("+=", &db::Edges::operator+=,
method ("+=", &db::Edges::operator+=, gsi::arg ("other"),
"@brief Adds the edges of the other edge collection to self\n"
"\n"
"@args other\n"
"@return The edge set after modification (self)\n"
"\n"
"This operator adds the edges of the other edge set to self. "
"This usually creates unmerged edge sets and edges may overlap. Use \\merge if you want to ensure the result edge set is merged.\n"
) +
method ("interacting", (db::Edges (db::Edges::*) (const db::Edges &) const) &db::Edges::selected_interacting,
method ("interacting", (db::Edges (db::Edges::*) (const db::Edges &) const) &db::Edges::selected_interacting, gsi::arg ("other"),
"@brief Returns the edges of this edge collection which overlap or touch edges from the other edge collection\n"
"\n"
"@args other\n"
"@return A new edge collection containing the edges overlapping or touching edges from the other region\n"
"\n"
"This method does not merge the edges before they are selected. If you want to select coherent "
"edges, make sure the edge collection is merged before this method is used.\n"
) +
method ("not_interacting", (db::Edges (db::Edges::*) (const db::Edges &) const) &db::Edges::selected_not_interacting,
method ("not_interacting", (db::Edges (db::Edges::*) (const db::Edges &) const) &db::Edges::selected_not_interacting, gsi::arg ("other"),
"@brief Returns the edges of this edge collection which do not overlap or touch edges from the other edge collection\n"
"\n"
"@args other\n"
"@return A new edge collection containing the edges not overlapping or touching edges from the other region\n"
"\n"
"This method does not merge the edges before they are selected. If you want to select coherent "
"edges, make sure the edge collection is merged before this method is used.\n"
) +
method ("select_interacting", (db::Edges &(db::Edges::*) (const db::Edges &)) &db::Edges::select_interacting,
method ("select_interacting", (db::Edges &(db::Edges::*) (const db::Edges &)) &db::Edges::select_interacting, gsi::arg ("other"),
"@brief Selects the edges from this edge collection which overlap or touch edges from the other edge collection\n"
"\n"
"@args other\n"
"@return The edge collection after the edges have been selected (self)\n"
"\n"
"This method does not merge the edges before they are selected. If you want to select coherent "
"edges, make sure the edge collection is merged before this method is used.\n"
) +
method ("select_not_interacting", (db::Edges &(db::Edges::*) (const db::Edges &)) &db::Edges::select_not_interacting,
method ("select_not_interacting", (db::Edges &(db::Edges::*) (const db::Edges &)) &db::Edges::select_not_interacting, gsi::arg ("other"),
"@brief Selects the edges from this edge collection which do not overlap or touch edges from the other edge collection\n"
"\n"
"@args other\n"
"@return The edge collection after the edges have been selected (self)\n"
"\n"
"This method does not merge the edges before they are selected. If you want to select coherent "
"edges, make sure the edge collection is merged before this method is used.\n"
) +
method ("interacting", (db::Edges (db::Edges::*) (const db::Region &) const) &db::Edges::selected_interacting,
method ("interacting", (db::Edges (db::Edges::*) (const db::Region &) const) &db::Edges::selected_interacting, gsi::arg ("other"),
"@brief Returns the edges from this region which overlap or touch polygons from the region\n"
"\n"
"@args other\n"
"@return A new edge collection containing the edges overlapping or touching polygons from the region\n"
"\n"
"This method does not merge the edges before they are selected. If you want to select coherent "
"edges, make sure the edge collection is merged before this method is used.\n"
) +
method ("not_interacting", (db::Edges (db::Edges::*) (const db::Region &) const) &db::Edges::selected_not_interacting,
method ("not_interacting", (db::Edges (db::Edges::*) (const db::Region &) const) &db::Edges::selected_not_interacting, gsi::arg ("other"),
"@brief Returns the edges from this region which do not overlap or touch polygons from the region\n"
"\n"
"@args other\n"
"@return A new edge collection containing the edges not overlapping or touching polygons from the region\n"
"\n"
"This method does not merge the edges before they are selected. If you want to select coherent "
"edges, make sure the edge collection is merged before this method is used.\n"
) +
method ("select_interacting", (db::Edges &(db::Edges::*) (const db::Region &)) &db::Edges::select_interacting,
method ("select_interacting", (db::Edges &(db::Edges::*) (const db::Region &)) &db::Edges::select_interacting, gsi::arg ("other"),
"@brief Selects the edges from this region which overlap or touch polygons from the region\n"
"\n"
"@args other\n"
"@return The edge collection after the edges have been selected (self)\n"
"\n"
"This method does not merge the edges before they are selected. If you want to select coherent "
"edges, make sure the edge collection is merged before this method is used.\n"
) +
method ("select_not_interacting", (db::Edges &(db::Edges::*) (const db::Region &)) &db::Edges::select_not_interacting,
method ("select_not_interacting", (db::Edges &(db::Edges::*) (const db::Region &)) &db::Edges::select_not_interacting, gsi::arg ("other"),
"@brief Selects the edges from this region which do not overlap or touch polygons from the region\n"
"\n"
"@args other\n"
"@return The edge collection after the edges have been selected (self)\n"
"\n"
"This method does not merge the edges before they are selected. If you want to select coherent "
"edges, make sure the edge collection is merged before this method is used.\n"
) +
method ("inside_part", &db::Edges::inside_part,
method ("inside_part", &db::Edges::inside_part, gsi::arg ("other"),
"@brief Returns the parts of the edges of this edge collection which are inside the polygons of the region\n"
"\n"
"@args other\n"
"@return A new edge collection containing the edge parts inside the region\n"
"\n"
"This operation returns the parts of the edges which are inside the given region.\n"
@ -836,10 +837,9 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"This method has been introduced in version 0.24."
) +
method ("outside_part", &db::Edges::outside_part,
method ("outside_part", &db::Edges::outside_part, gsi::arg ("other"),
"@brief Returns the parts of the edges of this edge collection which are outside the polygons of the region\n"
"\n"
"@args other\n"
"@return A new edge collection containing the edge parts outside the region\n"
"\n"
"This operation returns the parts of the edges which are not inside the given region.\n"
@ -849,10 +849,9 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"This method has been introduced in version 0.24."
) +
method ("select_inside_part", &db::Edges::select_inside_part,
method ("select_inside_part", &db::Edges::select_inside_part, gsi::arg ("other"),
"@brief Selects the parts of the edges from this edge collection which are inside the polygons of the given region\n"
"\n"
"@args other\n"
"@return The edge collection after the edges have been selected (self)\n"
"\n"
"This operation selects the parts of the edges which are inside the given region.\n"
@ -862,10 +861,9 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"This method has been introduced in version 0.24."
) +
method ("select_outside_part", &db::Edges::select_outside_part,
method ("select_outside_part", &db::Edges::select_outside_part, gsi::arg ("other"),
"@brief Selects the parts of the edges from this edge collection which are outside the polygons of the given region\n"
"\n"
"@args other\n"
"@return The edge collection after the edges have been selected (self)\n"
"\n"
"This operation selects the parts of the edges which are not inside the given region.\n"
@ -878,15 +876,13 @@ Class<db::Edges> dec_Edges ("db", "Edges",
method ("clear", &db::Edges::clear,
"@brief Clears the edge collection\n"
) +
method ("swap", &db::Edges::swap,
method ("swap", &db::Edges::swap, gsi::arg ("other"),
"@brief Swap the contents of this edge collection with the contents of another one\n"
"@args other\n"
"This method is useful to avoid excessive memory allocation in some cases. "
"For managed memory languages such as Ruby, those cases will be rare. "
) +
method_ext ("move", &move_p,
method_ext ("move", &move_p, gsi::arg ("v"),
"@brief Moves the edge collection\n"
"@args v\n"
"\n"
"Moves the polygon by the given offset and returns the \n"
"moved edge collection. The edge collection is overwritten.\n"
@ -897,9 +893,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"Starting with version 0.25 the displacement type is a vector."
) +
method_ext ("move", &move_xy,
method_ext ("move", &move_xy, gsi::arg ("x"), gsi::arg ("y"),
"@brief Moves the edge collection\n"
"@args x,y\n"
"\n"
"Moves the edge collection by the given offset and returns the \n"
"moved edge collection. The edge collection is overwritten.\n"
@ -909,9 +904,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"@return The moved edge collection (self).\n"
) +
method_ext ("moved", &moved_p,
method_ext ("moved", &moved_p, gsi::arg ("v"),
"@brief Returns the moved edge collection (does not modify self)\n"
"@args v\n"
"\n"
"Moves the edge collection by the given offset and returns the \n"
"moved edge collection. The edge collection is not modified.\n"
@ -922,9 +916,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"Starting with version 0.25 the displacement type is a vector."
) +
method_ext ("moved", &moved_xy,
method_ext ("moved", &moved_xy, gsi::arg ("x"), gsi::arg ("v"),
"@brief Returns the moved edge collection (does not modify self)\n"
"@args x,y\n"
"\n"
"Moves the edge collection by the given offset and returns the \n"
"moved edge collection. The edge collection is not modified.\n"
@ -934,9 +927,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"@return The moved edge collection.\n"
) +
method ("transformed", (db::Edges (db::Edges::*)(const db::Trans &) const) &db::Edges::transformed,
method ("transformed", (db::Edges (db::Edges::*)(const db::Trans &) const) &db::Edges::transformed, gsi::arg ("t"),
"@brief Transform the edge collection\n"
"@args t\n"
"\n"
"Transforms the edge collection with the given transformation.\n"
"Does not modify the edge collection but returns the transformed edge collection.\n"
@ -945,9 +937,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"@return The transformed edge collection.\n"
) +
method ("transformed|#transformed_icplx", (db::Edges (db::Edges::*)(const db::ICplxTrans &) const) &db::Edges::transformed,
method ("transformed|#transformed_icplx", (db::Edges (db::Edges::*)(const db::ICplxTrans &) const) &db::Edges::transformed, gsi::arg ("t"),
"@brief Transform the edge collection with a complex transformation\n"
"@args t\n"
"\n"
"Transforms the edge collection with the given complex transformation.\n"
"Does not modify the edge collection but returns the transformed edge collection.\n"
@ -956,9 +947,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"@return The transformed edge collection.\n"
) +
method ("transform", (db::Edges &(db::Edges::*)(const db::Trans &)) &db::Edges::transform,
method ("transform", (db::Edges &(db::Edges::*)(const db::Trans &)) &db::Edges::transform, gsi::arg ("t"),
"@brief Transform the edge collection (modifies self)\n"
"@args t\n"
"\n"
"Transforms the edge collection with the given transformation.\n"
"This version modifies the edge collection and returns a reference to self.\n"
@ -967,9 +957,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"@return The transformed edge collection.\n"
) +
method ("transform|#transform_icplx", (db::Edges &(db::Edges::*)(const db::ICplxTrans &)) &db::Edges::transform,
method ("transform|#transform_icplx", (db::Edges &(db::Edges::*)(const db::ICplxTrans &)) &db::Edges::transform, gsi::arg ("t"),
"@brief Transform the edge collection with a complex transformation (modifies self)\n"
"@args t\n"
"\n"
"Transforms the edge collection with the given transformation.\n"
"This version modifies the edge collection and returns a reference to self.\n"
@ -978,9 +967,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"@return The transformed edge collection.\n"
) +
method_ext ("width_check", &width1,
method_ext ("width_check", &width1, gsi::arg ("d"),
"@brief Performs a width check between edges\n"
"@args other, d\n"
"@param d The minimum width for which the edges are checked\n"
"@param other The other edge collection against which to check\n"
"To understand the overlap check for edges, one has to be familiar with the concept of the inside and outside "
@ -996,9 +984,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"A version of this method is available with more options (i.e. the option the deliver whole edges). "
"Other checks with different edge relations are \\space_check, \\inside_check, \\overlap_check, \\separation_check and \\enclosing_check.\n"
) +
method_ext ("width_check", &width2,
method_ext ("width_check", &width2, gsi::arg ("d"), gsi::arg ("whole_edges"), gsi::arg ("metrics"), gsi::arg ("ignore_angle"), gsi::arg ("min_projection"), gsi::arg ("max_projection"),
"@brief Performs a width check with options\n"
"@args d, whole_edges, metrics, ignore_angle, min_projection, max_projection\n"
"@param d The minimum width for which the edges are checked\n"
"@param whole_edges If true, deliver the whole edges\n"
"@param metrics Specify the metrics type\n"
@ -1026,9 +1013,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"The projected length must be larger or equal to \"min_projection\" and less than \"max_projection\". "
"If you don't want to specify one threshold, pass nil to the respective value.\n"
) +
method_ext ("space_check", &space1,
method_ext ("space_check", &space1, gsi::arg ("d"),
"@brief Performs a space check between edges\n"
"@args d\n"
"@param d The minimum distance for which the edges are checked\n"
"To understand the space check for edges, one has to be familiar with the concept of the inside and outside "
"interpretation of an edge. An edge is considered a boundary between \"inside\" and \"outside\" where \"inside\" "
@ -1043,9 +1029,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"A version of this method is available with more options (i.e. the option the deliver whole edges). "
"Other checks with different edge relations are \\width_check, \\inside_check, \\overlap_check, \\separation_check and \\enclosing_check.\n"
) +
method_ext ("space_check", &space2,
method_ext ("space_check", &space2, gsi::arg ("d"), gsi::arg ("whole_edges"), gsi::arg ("metrics"), gsi::arg ("ignore_angle"), gsi::arg ("min_projection"), gsi::arg ("max_projection"),
"@brief Performs a space check with options\n"
"@args d, whole_edges, metrics, ignore_angle, min_projection, max_projection\n"
"@param d The minimum distance for which the edges are checked\n"
"@param whole_edges If true, deliver the whole edges\n"
"@param metrics Specify the metrics type\n"
@ -1073,9 +1058,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"The projected length must be larger or equal to \"min_projection\" and less than \"max_projection\". "
"If you don't want to specify one threshold, pass nil to the respective value.\n"
) +
method_ext ("inside_check", &inside1,
method_ext ("inside_check", &inside1, gsi::arg ("other"), gsi::arg ("d"),
"@brief Performs an inside check between edges\n"
"@args other, d\n"
"@param d The minimum distance for which the edges are checked\n"
"@param other The other edge collection against which to check\n"
"To understand the inside check for edges, one has to be familiar with the concept of the inside and outside "
@ -1091,9 +1075,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"A version of this method is available with more options (i.e. the option the deliver whole edges). "
"Other checks with different edge relations are \\width_check, \\space_check, \\overlap_check, \\separation_check and \\enclosing_check.\n"
) +
method_ext ("inside_check", &inside2,
method_ext ("inside_check", &inside2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges"), gsi::arg ("metrics"), gsi::arg ("ignore_angle"), gsi::arg ("min_projection"), gsi::arg ("max_projection"),
"@brief Performs an inside check with options\n"
"@args other, d, whole_edges, metrics, ignore_angle, min_projection, max_projection\n"
"@param d The minimum distance for which the edges are checked\n"
"@param other The other edge collection against which to check\n"
"@param whole_edges If true, deliver the whole edges\n"
@ -1122,9 +1105,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"The projected length must be larger or equal to \"min_projection\" and less than \"max_projection\". "
"If you don't want to specify one threshold, pass nil to the respective value.\n"
) +
method_ext ("enclosing_check", &enclosing1,
method_ext ("enclosing_check", &enclosing1, gsi::arg ("other"), gsi::arg ("d"),
"@brief Performs an enclosing check between edges\n"
"@args other, d\n"
"@param d The minimum distance for which the edges are checked\n"
"@param other The other edge collection against which to check\n"
"To understand the enclosing check for edges, one has to be familiar with the concept of the inside and outside "
@ -1140,9 +1122,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"A version of this method is available with more options (i.e. the option the deliver whole edges). "
"Other checks with different edge relations are \\width_check, \\space_check, \\overlap_check, \\separation_check and \\inside_check.\n"
) +
method_ext ("enclosing_check", &enclosing2,
method_ext ("enclosing_check", &enclosing2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges"), gsi::arg ("metrics"), gsi::arg ("ignore_angle"), gsi::arg ("min_projection"), gsi::arg ("max_projection"),
"@brief Performs an enclosing check with options\n"
"@args other, d, whole_edges, metrics, ignore_angle, min_projection, max_projection\n"
"@param d The minimum distance for which the edges are checked\n"
"@param other The other edge collection against which to check\n"
"@param whole_edges If true, deliver the whole edges\n"
@ -1171,9 +1152,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"The projected length must be larger or equal to \"min_projection\" and less than \"max_projection\". "
"If you don't want to specify one threshold, pass nil to the respective value.\n"
) +
method_ext ("overlap_check", &overlap1,
method_ext ("overlap_check", &overlap1, gsi::arg ("other"), gsi::arg ("d"),
"@brief Performs an overlap check between edges\n"
"@args other, d\n"
"@param d The minimum distance for which the edges are checked\n"
"@param other The other edge collection against which to check\n"
"Technically, the overlap check is a width check between edges from different collections. "
@ -1187,9 +1167,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"A version of this method is available with more options (i.e. the option the deliver whole edges). "
"Other checks with different edge relations are \\width_check, \\space_check, \\enclosing_check, \\separation_check and \\inside_check.\n"
) +
method_ext ("overlap_check", &overlap2,
method_ext ("overlap_check", &overlap2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges"), gsi::arg ("metrics"), gsi::arg ("ignore_angle"), gsi::arg ("min_projection"), gsi::arg ("max_projection"),
"@brief Performs an overlap check with options\n"
"@args other, d, whole_edges, metrics, ignore_angle, min_projection, max_projection\n"
"@param d The minimum distance for which the edges are checked\n"
"@param other The other edge collection against which to check\n"
"@param whole_edges If true, deliver the whole edges\n"
@ -1218,9 +1197,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"The projected length must be larger or equal to \"min_projection\" and less than \"max_projection\". "
"If you don't want to specify one threshold, pass nil to the respective value.\n"
) +
method_ext ("separation_check", &separation1,
method_ext ("separation_check", &separation1, gsi::arg ("other"), gsi::arg ("d"),
"@brief Performs an separation check between edges\n"
"@args other, d\n"
"@param d The minimum distance for which the edges are checked\n"
"@param other The other edge collection against which to check\n"
"Technically, the separation check is a space check between edges from different collections. "
@ -1234,9 +1212,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"A version of this method is available with more options (i.e. the option the deliver whole edges). "
"Other checks with different edge relations are \\width_check, \\space_check, \\enclosing_check, \\overlap_check and \\inside_check.\n"
) +
method_ext ("separation_check", &separation2,
method_ext ("separation_check", &separation2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges"), gsi::arg ("metrics"), gsi::arg ("ignore_angle"), gsi::arg ("min_projection"), gsi::arg ("max_projection"),
"@brief Performs an overlap check with options\n"
"@args other, d, whole_edges, metrics, ignore_angle, min_projection, max_projection\n"
"@param d The minimum distance for which the edges are checked\n"
"@param other The other edge collection against which to check\n"
"@param whole_edges If true, deliver the whole edges\n"
@ -1271,25 +1248,22 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"The boxes will not be merged, so it is possible to determine overlaps "
"of these boxes for example.\n"
) +
method_ext ("extents", &extents1,
method_ext ("extents", &extents1, gsi::arg ("d"),
"@brief Returns a region with the enlarged bounding boxes of the edges\n"
"@args d\n"
"This method will return a region consisting of the bounding boxes of the edges enlarged by the given distance d.\n"
"The enlargement is specified per edge, i.e the width and height will be increased by 2*d.\n"
"The boxes will not be merged, so it is possible to determine overlaps "
"of these boxes for example.\n"
) +
method_ext ("extents", &extents2,
method_ext ("extents", &extents2, gsi::arg ("dx"), gsi::arg ("dy"),
"@brief Returns a region with the enlarged bounding boxes of the edges\n"
"@args dx, dy\n"
"This method will return a region consisting of the bounding boxes of the edges enlarged by the given distance dx in x direction and dy in y direction.\n"
"The enlargement is specified per edge, i.e the width will be increased by 2*dx.\n"
"The boxes will not be merged, so it is possible to determine overlaps "
"of these boxes for example.\n"
) +
method_ext ("extended_in", &extended_in,
method_ext ("extended_in", &extended_in, gsi::arg ("e"),
"@brief Returns a region with shapes representing the edges with the given width\n"
"@args e\n"
"@param e The extension width\n"
"@return A region containing the polygons representing these extended edges\n"
"The edges are extended to the \"inside\" by the given distance \"e\". The distance will be applied to the right side "
@ -1298,9 +1272,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"Other versions of this feature are \\extended_out and \\extended.\n"
) +
method_ext ("extended_out", &extended_out,
method_ext ("extended_out", &extended_out, gsi::arg ("e"),
"@brief Returns a region with shapes representing the edges with the given width\n"
"@args e\n"
"@param e The extension width\n"
"@return A region containing the polygons representing these extended edges\n"
"The edges are extended to the \"outside\" by the given distance \"e\". The distance will be applied to the left side "
@ -1309,9 +1282,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"Other versions of this feature are \\extended_in and \\extended.\n"
) +
method_ext ("extended", &extended,
method_ext ("extended", &extended, gsi::arg ("b"), gsi::arg ("e"), gsi::arg ("o"), gsi::arg ("i"), gsi::arg ("join"),
"@brief Returns a region with shapes representing the edges with the specified extensions\n"
"@args b, e, o, i, join\n"
"@param b the parallel extension at the start point of the edge\n"
"@param e the parallel extension at the end point of the edge\n"
"@param o the perpendicular extension to the \"outside\" (left side as seen in the direction of the edge)\n"
@ -1327,9 +1299,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"If join is true and edges form a closed loop, the b and e parameters are ignored and a rim polygon is created "
"that forms the loop with the outside and inside extension given by o and i.\n"
) +
method ("start_segments", &db::Edges::start_segments,
method ("start_segments", &db::Edges::start_segments, gsi::arg ("length"), gsi::arg ("fraction"),
"@brief Returns edges representing a part of the edge after the start point\n"
"@args length, fraction\n"
"@return A new collection of edges representing the start part\n"
"This method allows to specify the length of these segments in a twofold way: either as a fixed length or "
"by specifying a fraction of the original length:\n"
@ -1345,9 +1316,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"It is possible to specify 0 for both values. In this case, degenerated edges (points) are delivered which specify the "
"start positions of the edges but can't participate in some functions.\n"
) +
method ("end_segments", &db::Edges::end_segments,
method ("end_segments", &db::Edges::end_segments, gsi::arg ("length"), gsi::arg ("fraction"),
"@brief Returns edges representing a part of the edge before the end point\n"
"@args length, fraction\n"
"@return A new collection of edges representing the end part\n"
"This method allows to specify the length of these segments in a twofold way: either as a fixed length or "
"by specifying a fraction of the original length:\n"
@ -1363,9 +1333,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"It is possible to specify 0 for both values. In this case, degenerated edges (points) are delivered which specify the "
"end positions of the edges but can't participate in some functions.\n"
) +
method ("centers", &db::Edges::centers,
method ("centers", &db::Edges::centers, gsi::arg ("length"), gsi::arg ("fraction"),
"@brief Returns edges representing the center part of the edges\n"
"@args length, fraction\n"
"@return A new collection of edges representing the part around the center\n"
"This method allows to specify the length of these segments in a twofold way: either as a fixed length or "
"by specifying a fraction of the original length:\n"
@ -1390,24 +1359,21 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"Merged semantics applies for this method (see \\merged_semantics= of merged semantics)\n"
) +
method_ext ("length", &length2,
method_ext ("length", &length2, gsi::arg ("rect"),
"@brief Returns the total length of all edges in the edge collection (restricted to a rectangle)\n"
"@args rect\n"
"This version will compute the total length of all edges in the collection, restricting the computation to the given rectangle.\n"
"Edges along the border are handled in a special way: they are counted when they are oriented with their inside "
"side toward the rectangle (in other words: outside edges must coincide with the rectangle's border in order to be counted).\n"
"\n"
"Merged semantics applies for this method (see \\merged_semantics= of merged semantics)\n"
) +
method_ext ("members_of|#in", &in,
method_ext ("members_of|#in", &in, gsi::arg ("other"),
"@brief Returns all edges which are members of the other edge collection\n"
"@args other\n"
"This method returns all edges in self which can be found in the other edge collection as well with exactly the same "
"geometry."
) +
method_ext ("not_members_of|#not_in", &not_in,
method_ext ("not_members_of|#not_in", &not_in, gsi::arg ("other"),
"@brief Returns all edges which are not members of the other edge collection\n"
"@args other\n"
"This method returns all edges in self which can not be found in the other edge collection with exactly the same "
"geometry."
) +
@ -1432,9 +1398,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"\n"
"This method has been introduced in version 0.25."
) +
method ("[]", &db::Edges::nth,
method ("[]", &db::Edges::nth, gsi::arg ("n"),
"@brief Returns the nth edge of the collection\n"
"@args n\n"
"\n"
"This method returns nil if the index is out of range. It is available for flat edge collections only - i.e. "
"those for which \\has_valid_edges? is true. Use \\flatten to explicitly flatten an edge collection.\n"
@ -1460,14 +1425,12 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"The length of the output is limited to 20 edges to avoid giant strings on large regions. "
"For full output use \"to_s\" with a maximum count parameter.\n"
) +
method_ext ("to_s", &to_string1,
method_ext ("to_s", &to_string1, gsi::arg ("max_count"),
"@brief Converts the edge collection to a string\n"
"@args max_count\n"
"This version allows specification of the maximum number of edges contained in the string."
) +
method ("merged_semantics=", &db::Edges::set_merged_semantics,
method ("merged_semantics=", &db::Edges::set_merged_semantics, gsi::arg ("f"),
"@brief Enable or disable merged semantics\n"
"@args f\n"
"If merged semantics is enabled (the default), colinear, connected or overlapping edges will be considered\n"
"as single edges.\n"
) +
@ -1475,9 +1438,8 @@ Class<db::Edges> dec_Edges ("db", "Edges",
"@brief Gets a flag indicating whether merged semantics is enabled\n"
"See \\merged_semantics= for a description of this attribute.\n"
) +
method ("enable_progress", &db::Edges::enable_progress,
method ("enable_progress", &db::Edges::enable_progress, gsi::arg ("label"),
"@brief Enable progress reporting\n"
"@args label\n"
"After calling this method, the edge collection will report the progress through a progress bar while "
"expensive operations are running.\n"
"The label is a text which is put in front of the progress bar.\n"

View File

@ -1180,7 +1180,7 @@ Class<db::Layout> decl_Layout ("db", "Layout",
"\n"
"This method has been introduced in version 0.20.\n"
) +
gsi::method ("insert", (void (db::Layout::*) (db::cell_index_type, unsigned int, const db::Region &)) &db::Layout::insert,
gsi::method ("insert", (void (db::Layout::*) (db::cell_index_type, int, const db::Region &)) &db::Layout::insert,
gsi::arg ("cell_index"), gsi::arg ("layer"), gsi::arg ("region"),
"@brief Inserts a region into the given cell and layer\n"
"If the region is (conceptionally) a flat region, it will be inserted into the cell's shapes "
@ -1192,6 +1192,18 @@ Class<db::Layout> decl_Layout ("db", "Layout",
"\n"
"This method has been introduced in version 0.26.\n"
) +
gsi::method ("insert", (void (db::Layout::*) (db::cell_index_type, int, const db::Edges &)) &db::Layout::insert,
gsi::arg ("cell_index"), gsi::arg ("layer"), gsi::arg ("edges"),
"@brief Inserts an edge collection into the given cell and layer\n"
"If the edge collection is (conceptionally) flat, it will be inserted into the cell's shapes "
"list as a flat sequence of edges.\n"
"If the edge collection is deep (hierarchical), it will create a subhierarchy below the given "
"cell and it's edges will be put into the respective cells. Suitable subcells will be picked "
"for inserting the edges. If a hierarchy already exists below the given cell, the algorithm will "
"try to reuse this hierarchy.\n"
"\n"
"This method has been introduced in version 0.26.\n"
) +
gsi::method_ext ("flatten", &flatten,
"@brief Flattens the given cell\n"
"@args cell_index, levels, prune\n"

View File

@ -0,0 +1,108 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2019 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dbHierarchyBuilder.h"
#include "dbReader.h"
#include "dbTestSupport.h"
#include "dbEdges.h"
#include "dbDeepShapeStore.h"
#include "tlUnitTest.h"
#include "tlStream.h"
TEST(1)
{
db::Layout ly;
{
std::string fn (tl::testsrc ());
fn += "/testdata/algo/deep_region_l1.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
}
db::cell_index_type top_cell_index = *ly.begin_top_down ();
db::DeepShapeStore dss;
db::Layout target;
// deliberately using vector to force reallocation ...
std::vector<db::Edges> edges;
std::vector<unsigned int> target_layers;
for (db::Layout::layer_iterator li = ly.begin_layers (); li != ly.end_layers (); ++li) {
unsigned int li1 = (*li).first;
db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), li1);
target_layers.push_back (target.insert_layer (*(*li).second));
edges.push_back (db::Edges (iter, dss));
EXPECT_EQ (edges.back ().size (), db::Edges (iter).size ());
EXPECT_EQ (edges.back ().bbox (), db::Edges (iter).bbox ());
}
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
for (std::vector<db::Edges>::const_iterator r = edges.begin (); r != edges.end (); ++r) {
target.insert (target_top_cell_index, target_layers [r - edges.begin ()], *r);
}
CHECKPOINT();
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_edges_au1.gds");
}
TEST(2_MergeEdges)
{
db::Layout ly;
{
std::string fn (tl::testsrc ());
fn += "/testdata/algo/deep_region_l1.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
}
db::cell_index_type top_cell_index = *ly.begin_top_down ();
db::Cell &top_cell = ly.cell (top_cell_index);
db::DeepShapeStore dss;
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
unsigned int l3 = ly.get_layer (db::LayerProperties (3, 0));
db::Edges r2 (db::RecursiveShapeIterator (ly, top_cell, l2), dss);
r2.merge ();
db::Edges r3 (db::RecursiveShapeIterator (ly, top_cell, l3), dss);
db::Edges r3_merged (r3.merged ());
db::Layout target;
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), r2);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), r3_merged);
CHECKPOINT();
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_edges_au2.gds");
}

View File

@ -57,6 +57,9 @@ TEST(1)
regions.push_back (db::Region (iter, dss));
EXPECT_EQ (regions.back ().size (), db::Region (iter).size ());
EXPECT_EQ (regions.back ().bbox (), db::Region (iter).bbox ());
}
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));

View File

@ -67,7 +67,8 @@ SOURCES = \
dbLayoutToNetlistWriterTests.cc \
dbLayoutToNetlistReaderTests.cc \
dbNetlistWriterTests.cc \
dbCellVariantsTests.cc
dbCellVariantsTests.cc \
dbDeepEdgesTests.cc
INCLUDEPATH += $$TL_INC $$DB_INC $$GSI_INC
DEPENDPATH += $$TL_INC $$DB_INC $$GSI_INC