mirror of https://github.com/KLayout/klayout.git
WIP: bug fixes, one more test
This commit is contained in:
parent
71620445ee
commit
8a122c8a7d
|
|
@ -57,6 +57,9 @@ $python $inst/stubgen.py tl >$pyi_srcdir/tlcore.pyi
|
|||
echo "Generating stubs for db .."
|
||||
$python $inst/stubgen.py db tl,lay,rdb >$pyi_srcdir/dbcore.pyi
|
||||
|
||||
echo "Generating stubs for pex .."
|
||||
$python $inst/stubgen.py pex tl,db >$pyi_srcdir/pexcore.pyi
|
||||
|
||||
echo "Generating stubs for rdb .."
|
||||
$python $inst/stubgen.py rdb tl,db >$pyi_srcdir/rdbcore.pyi
|
||||
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ ConvexDecomposition::collect_concave_vertexes (std::vector<ConcaveCorner> &conca
|
|||
// and outgoing edge.
|
||||
|
||||
Edge *start_segment = segment;
|
||||
Vertex *vto = segment->right () ? segment->v2 () : segment->v1 ();
|
||||
Vertex *vto = (segment->right () && ! segment->right ()->is_outside ()) ? segment->v2 () : segment->v1 ();
|
||||
|
||||
do {
|
||||
|
||||
|
|
@ -338,7 +338,9 @@ ConvexDecomposition::hertel_mehlhorn_decomposition (Triangulation &tris, const C
|
|||
}
|
||||
|
||||
for (auto i = angles_and_edges.begin (); i != angles_and_edges.end (); ++i) {
|
||||
essential_edges.insert (i->second);
|
||||
if (i->second) {
|
||||
essential_edges.insert (i->second);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -347,7 +349,9 @@ ConvexDecomposition::hertel_mehlhorn_decomposition (Triangulation &tris, const C
|
|||
|
||||
std::unordered_set<const Polygon *> left_triangles;
|
||||
for (auto it = mp_graph->begin (); it != mp_graph->end (); ++it) {
|
||||
left_triangles.insert (it.operator-> ());
|
||||
if (! it->is_outside ()) {
|
||||
left_triangles.insert (it.operator-> ());
|
||||
}
|
||||
}
|
||||
|
||||
std::list<std::unordered_set<Edge *> > polygons;
|
||||
|
|
@ -385,7 +389,7 @@ ConvexDecomposition::hertel_mehlhorn_decomposition (Triangulation &tris, const C
|
|||
ivs.insert (e->v2 ());
|
||||
}
|
||||
|
||||
if (! qq || essential_edges.find (e) != essential_edges.end ()) {
|
||||
if (! qq || qq->is_outside () || essential_edges.find (e) != essential_edges.end ()) {
|
||||
edges.insert (const_cast<Edge *> (e)); // TODO: ugly const_cast
|
||||
} else if (left_triangles.find (qq) != left_triangles.end ()) {
|
||||
next_queue.push_back (qq);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@ struct DB_PUBLIC ConvexDecompositionParameters
|
|||
{
|
||||
tri_param.max_area = 0.0;
|
||||
tri_param.min_b = 0.0;
|
||||
|
||||
// Needed for the algorithm - don't change this
|
||||
tri_param.remove_outside_triangles = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1522,7 +1522,9 @@ Triangulation::refine (const TriangulationParameters ¶meters)
|
|||
if (parameters.min_b < db::epsilon && parameters.max_area < db::epsilon && parameters.max_area_border < db::epsilon) {
|
||||
|
||||
// no refinement requested - we're done.
|
||||
remove_outside_triangles ();
|
||||
if (parameters.remove_outside_triangles) {
|
||||
remove_outside_triangles ();
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
|
@ -1690,7 +1692,9 @@ Triangulation::refine (const TriangulationParameters ¶meters)
|
|||
|
||||
}
|
||||
|
||||
remove_outside_triangles ();
|
||||
if (parameters.remove_outside_triangles) {
|
||||
remove_outside_triangles ();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace plc
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@ struct DB_PUBLIC TriangulationParameters
|
|||
max_area_border (0.0),
|
||||
max_iterations (std::numeric_limits<size_t>::max ()),
|
||||
base_verbosity (30),
|
||||
mark_triangles (false)
|
||||
mark_triangles (false),
|
||||
remove_outside_triangles (true)
|
||||
{ }
|
||||
|
||||
/**
|
||||
|
|
@ -93,6 +94,11 @@ struct DB_PUBLIC TriangulationParameters
|
|||
* Bit 2: non-Delaunay (in the strict sense)
|
||||
*/
|
||||
bool mark_triangles;
|
||||
|
||||
/**
|
||||
* @brief If false, the outside triangles are not removed after triangulation
|
||||
*/
|
||||
bool remove_outside_triangles;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -153,3 +153,37 @@ TEST(internal_vertex)
|
|||
EXPECT_EQ (++p == plc.end (), true);
|
||||
}
|
||||
|
||||
TEST(problematic_polygon)
|
||||
{
|
||||
db::Point contour[] = {
|
||||
db::Point (14590, 990),
|
||||
db::Point (6100, 990),
|
||||
db::Point (7360, 4450),
|
||||
db::Point (2280, 4450),
|
||||
db::Point (2280, 6120),
|
||||
db::Point (7360, 6120),
|
||||
db::Point (8760, 7490),
|
||||
db::Point (13590, 17100),
|
||||
db::Point (10280, 6120),
|
||||
db::Point (26790, 13060),
|
||||
db::Point (41270, 970)
|
||||
};
|
||||
|
||||
db::Polygon poly;
|
||||
poly.assign_hull (contour + 0, contour + sizeof (contour) / sizeof (contour[0]));
|
||||
|
||||
double dbu = 0.001;
|
||||
|
||||
db::plc::ConvexDecompositionParameters param;
|
||||
param.with_segments = true;
|
||||
param.split_edges = false;
|
||||
|
||||
db::plc::Graph plc;
|
||||
TestableConvexDecomposition decomp (&plc);
|
||||
|
||||
decomp.decompose (poly, param, dbu);
|
||||
|
||||
std::unique_ptr<db::Layout> ly (plc.to_layout ());
|
||||
db::compare_layouts (_this, *ly, tl::testdata () + "/algo/hm_decomposition_au5.gds");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@ namespace gsi
|
|||
{
|
||||
|
||||
// @@@
|
||||
static pex::RExtractor *new_sqc_rextractor ()
|
||||
static pex::RExtractor *new_sqc_rextractor (double dbu)
|
||||
{
|
||||
return new pex::RExtractor ();
|
||||
return new pex::SquareCountingRExtractor (dbu);
|
||||
}
|
||||
|
||||
Class<pex::RExtractor> decl_RExtractor ("pex", "RExtractor",
|
||||
gsi::constructor ("square_counting", &new_sqc_rextractor,
|
||||
gsi::constructor ("square_counting", &new_sqc_rextractor, gsi::arg ("dbu"),
|
||||
"@brief Creates a square counting R extractor\n"
|
||||
),
|
||||
"@brief A base class for the R extractor\n"
|
||||
|
|
|
|||
|
|
@ -26,11 +26,146 @@
|
|||
namespace pex
|
||||
{
|
||||
|
||||
RNetwork::RNetwork ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
RNetwork::~RNetwork ()
|
||||
{
|
||||
clear ();
|
||||
}
|
||||
|
||||
void
|
||||
RNetwork::clear ()
|
||||
{
|
||||
m_elements.clear (); // must come before m_nodes
|
||||
m_nodes.clear ();
|
||||
m_elements_by_nodes.clear ();
|
||||
m_nodes_by_type.clear ();
|
||||
}
|
||||
|
||||
std::map<std::pair<RNode *, RNode *>, RElement *> m_elements_by_nodes;
|
||||
std::map<std::pair<RNode::node_type, unsigned int>, RNode *> m_nodes;
|
||||
|
||||
RNode *
|
||||
RNetwork::create_node (RNode::node_type type, unsigned int port_index)
|
||||
{
|
||||
if (type != RNode::INTERNAL) {
|
||||
|
||||
auto i = m_nodes_by_type.find (std::make_pair (type, port_index));
|
||||
if (i != m_nodes_by_type.end ()) {
|
||||
|
||||
return i->second;
|
||||
|
||||
} else {
|
||||
|
||||
RNode *new_node = new RNode (type, db::DBox (), port_index);
|
||||
m_nodes.push_back (new_node);
|
||||
m_nodes_by_type.insert (std::make_pair (std::make_pair (type, port_index), new_node));
|
||||
|
||||
return new_node;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
RNode *new_node = new RNode (type, db::DBox (), port_index);
|
||||
m_nodes.push_back (new_node);
|
||||
return new_node;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
RElement *
|
||||
RNetwork::create_element (double conductivity, RNode *a, RNode *b)
|
||||
{
|
||||
auto i = m_elements_by_nodes.find (std::make_pair (a, b));
|
||||
if (i != m_elements_by_nodes.end ()) {
|
||||
|
||||
i->second->conductivity += conductivity;
|
||||
return i->second;
|
||||
|
||||
} else {
|
||||
|
||||
RElement *element = new RElement (conductivity, a, b);
|
||||
a->elements.push_back (element);
|
||||
element->m_ia = --a->elements.end ();
|
||||
b->elements.push_back (element);
|
||||
element->m_ia = --b->elements.end ();
|
||||
|
||||
m_elements_by_nodes.insert (std::make_pair (std::make_pair (a, b), element));
|
||||
return element;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RNetwork::remove_node (RNode *node)
|
||||
{
|
||||
tl_assert (node->type == RNode::INTERNAL);
|
||||
while (! node->elements.empty ()) {
|
||||
remove_element (const_cast<RElement *> (node->elements.front ()));
|
||||
}
|
||||
delete node;
|
||||
}
|
||||
|
||||
void
|
||||
RNetwork::remove_element (RElement *element)
|
||||
{
|
||||
RNode *a = const_cast<RNode *> (element->a);
|
||||
RNode *b = const_cast<RNode *> (element->b);
|
||||
|
||||
delete element;
|
||||
|
||||
if (a && a->type == RNode::INTERNAL && a->elements.empty ()) {
|
||||
delete a;
|
||||
}
|
||||
if (b && b->type == RNode::INTERNAL && b->elements.empty ()) {
|
||||
delete b;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RExtractor::RExtractor ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
RExtractor::~RExtractor ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
|
||||
SquareCountingRExtractor::SquareCountingRExtractor (double dbu)
|
||||
{
|
||||
m_dbu = dbu;
|
||||
|
||||
m_decomp_param.split_edges = true;
|
||||
m_decomp_param.with_segments = false;
|
||||
}
|
||||
|
||||
void
|
||||
SquareCountingRExtractor::extract (const db::Polygon &polygon, const std::vector<db::Point> &vertex_ports, const std::vector<db::Polygon> &polygon_ports, RNetwork &rnetwork)
|
||||
{
|
||||
db::CplxTrans trans = db::CplxTrans (m_dbu) * db::ICplxTrans (db::Trans (db::Point () - polygon.box ().center ()));
|
||||
auto inv_trans = trans.inverted ();
|
||||
|
||||
db::plc::Graph plc;
|
||||
|
||||
db::plc::ConvexDecomposition decomp (&plc);
|
||||
decomp.decompose (polygon, vertex_ports, m_decomp_param, trans);
|
||||
|
||||
std::vector<std::pair<db::Polygon, db::plc::Polygon *> > decomp_polygons;
|
||||
for (auto p = plc.begin (); p != plc.end (); ++p) {
|
||||
// @@@decomp_polygons.push_back (db::Polygon ());
|
||||
// @@@decomp_polygons.back ().first = inv_trans * p->polygon ();
|
||||
}
|
||||
|
||||
// @@@ use box_scanner to find interactions between polygon_ports and decomp_polygons
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -24,11 +24,112 @@
|
|||
#define HDR_pexRExtractor
|
||||
|
||||
#include "pexCommon.h"
|
||||
|
||||
#include "dbPolygon.h"
|
||||
#include "dbPLC.h"
|
||||
#include "dbPLCConvexDecomposition.h" // @@@
|
||||
#include "dbPLCTriangulation.h" // @@@
|
||||
#include "tlList.h"
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
namespace pex
|
||||
{
|
||||
|
||||
class RElement;
|
||||
class RNode;
|
||||
|
||||
struct PEX_PUBLIC RNode
|
||||
: public tl::list_node<RNode>
|
||||
{
|
||||
public:
|
||||
enum node_type {
|
||||
INTERNAL,
|
||||
VERTEX_PORT,
|
||||
POLYGON_PORT
|
||||
};
|
||||
|
||||
node_type type;
|
||||
db::DBox location;
|
||||
unsigned int port_index;
|
||||
mutable std::list<const RElement *> elements;
|
||||
|
||||
protected:
|
||||
friend class RNetwork;
|
||||
friend class tl::list_impl<RNode, false>;
|
||||
|
||||
RNode (node_type _type, const db::DBox &_location, unsigned int _port_index)
|
||||
: type (_type), location (_location), port_index (_port_index)
|
||||
{ }
|
||||
|
||||
~RNode () { }
|
||||
|
||||
private:
|
||||
RNode (const RNode &other);
|
||||
RNode &operator= (const RNode &other);
|
||||
};
|
||||
|
||||
struct PEX_PUBLIC RElement
|
||||
: public tl::list_node<RElement>
|
||||
{
|
||||
double conductivity;
|
||||
const RNode *a, *b;
|
||||
|
||||
double resistance () const
|
||||
{
|
||||
return 1.0 / conductivity;
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class RNetwork;
|
||||
friend class tl::list_impl<RElement, false>;
|
||||
|
||||
RElement (double _conductivity, const RNode *_a, const RNode *_b)
|
||||
: conductivity (_conductivity), a (_a), b (_b)
|
||||
{ }
|
||||
|
||||
~RElement ()
|
||||
{
|
||||
if (a) {
|
||||
a->elements.erase (m_ia);
|
||||
}
|
||||
if (b) {
|
||||
b->elements.erase (m_ib);
|
||||
}
|
||||
a = b = 0;
|
||||
}
|
||||
|
||||
std::list<const RElement *>::iterator m_ia, m_ib;
|
||||
|
||||
private:
|
||||
RElement (const RElement &other);
|
||||
RElement &operator= (const RElement &other);
|
||||
};
|
||||
|
||||
class PEX_PUBLIC RNetwork
|
||||
{
|
||||
public:
|
||||
RNetwork ();
|
||||
~RNetwork ();
|
||||
|
||||
RNode *create_node (RNode::node_type type, unsigned int port_index);
|
||||
RElement *create_element (double conductivity, RNode *a, RNode *b);
|
||||
void remove_element (RElement *element);
|
||||
void remove_node (RNode *node);
|
||||
void clear ();
|
||||
|
||||
private:
|
||||
tl::list<RNode, false> m_nodes;
|
||||
tl::list<RElement, false> m_elements;
|
||||
std::map<std::pair<RNode *, RNode *>, RElement *> m_elements_by_nodes;
|
||||
std::map<std::pair<RNode::node_type, unsigned int>, RNode *> m_nodes_by_type;
|
||||
|
||||
RNetwork (const RNetwork &);
|
||||
RNetwork &operator= (const RNetwork &);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief A base class for an resistance extractor
|
||||
*
|
||||
|
|
@ -38,9 +139,42 @@ namespace pex
|
|||
* Ports are points or polygons that define the connection
|
||||
* points to the network.
|
||||
*/
|
||||
struct PEX_PUBLIC RExtractor
|
||||
class PEX_PUBLIC RExtractor
|
||||
{
|
||||
public:
|
||||
RExtractor ();
|
||||
virtual ~RExtractor ();
|
||||
|
||||
virtual void extract (const db::Polygon &polygon, const std::vector<db::Point> &vertex_ports, const std::vector<db::Polygon> &polygon_ports, RNetwork &rnetwork) = 0;
|
||||
};
|
||||
|
||||
// @@@
|
||||
class PEX_PUBLIC SquareCountingRExtractor
|
||||
: public RExtractor
|
||||
{
|
||||
public:
|
||||
SquareCountingRExtractor (double dbu);
|
||||
|
||||
db::plc::ConvexDecompositionParameters &decomposition_parameters ()
|
||||
{
|
||||
return m_decomp_param;
|
||||
}
|
||||
|
||||
void set_dbu (double dbu)
|
||||
{
|
||||
m_dbu = dbu;
|
||||
}
|
||||
|
||||
double dbu () const
|
||||
{
|
||||
return m_dbu;
|
||||
}
|
||||
|
||||
virtual void extract (const db::Polygon &polygon, const std::vector<db::Point> &vertex_ports, const std::vector<db::Polygon> &polygon_ports, RNetwork &rnetwork);
|
||||
|
||||
private:
|
||||
db::plc::ConvexDecompositionParameters m_decomp_param;
|
||||
double m_dbu;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13813,7 +13813,7 @@ class DPolygon:
|
|||
|
||||
The minimum angle of the resulting triangles relates to the 'b' parameter as: @t min_angle = arcsin(B/2) @/t.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
This method has been introduced in version 0.30.
|
||||
"""
|
||||
|
|
@ -13912,6 +13912,24 @@ class DPolygon:
|
|||
This method has been introduced in version 0.25.
|
||||
"""
|
||||
...
|
||||
def hm_decomposition(self, with_segments: Optional[bool] = ..., split_edges: Optional[bool] = ..., max_area: Optional[float] = ..., min_b: Optional[float] = ...) -> List[DPolygon]:
|
||||
r"""
|
||||
@brief Performs a Hertel-Mehlhorn convex decomposition.
|
||||
|
||||
@return An array holding the polygons of the decomposition.
|
||||
|
||||
The Hertel-Mehlhorn decomposition starts with a Delaunay triangulation of the polygons and recombines the triangles into convex polygons.
|
||||
|
||||
The decomposition is controlled by two parameters: 'with_segments' and 'split_edges'.
|
||||
|
||||
If 'with_segments' is true (the default), new segments are introduced perpendicular to the edges forming a concave corner. If false, only diagonals (edges connecting original vertexes) are used.
|
||||
|
||||
If 'split_edges' is true, the algorithm is allowed to create collinear edges in the output. In this case, the resulting polygons may contain edges that are split into collinear partial edges. Such edges usually recombine into longer edges when processing the polygon further. When such a recombination happens, the edges no longer correspond to original edges or diagonals. When 'split_edges' is false (the default), the resulting polygons will not contain collinear edges, but the decomposition will be constrained to fewer cut lines.
|
||||
'max_area' and 'min_b' are the corresponding parameters used for the triangulation (see \delaunay).
|
||||
|
||||
This method has been introduced in version 0.30.1.
|
||||
"""
|
||||
...
|
||||
def holes(self) -> int:
|
||||
r"""
|
||||
@brief Returns the number of holes
|
||||
|
|
@ -14926,7 +14944,7 @@ class DSimplePolygon:
|
|||
|
||||
The minimum angle of the resulting triangles relates to the 'b' parameter as: @t min_angle = arcsin(B/2) @/t.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
This method has been introduced in version 0.30.
|
||||
"""
|
||||
|
|
@ -15003,6 +15021,24 @@ class DSimplePolygon:
|
|||
This method has been introduced in version 0.25.
|
||||
"""
|
||||
...
|
||||
def hm_decomposition(self, with_segments: Optional[bool] = ..., split_edges: Optional[bool] = ..., max_area: Optional[float] = ..., min_b: Optional[float] = ...) -> List[DSimplePolygon]:
|
||||
r"""
|
||||
@brief Performs a Hertel-Mehlhorn convex decomposition.
|
||||
|
||||
@return An array holding the polygons of the decomposition.
|
||||
|
||||
The Hertel-Mehlhorn decomposition starts with a Delaunay triangulation of the polygons and recombines the triangles into convex polygons.
|
||||
|
||||
The decomposition is controlled by two parameters: 'with_segments' and 'split_edges'.
|
||||
|
||||
If 'with_segments' is true (the default), new segments are introduced perpendicular to the edges forming a concave corner. If false, only diagonals (edges connecting original vertexes) are used.
|
||||
|
||||
If 'split_edges' is true, the algorithm is allowed to create collinear edges in the output. In this case, the resulting polygons may contain edges that are split into collinear partial edges. Such edges usually recombine into longer edges when processing the polygon further. When such a recombination happens, the edges no longer correspond to original edges or diagonals. When 'split_edges' is false (the default), the resulting polygons will not contain collinear edges, but the decomposition will be constrained to fewer cut lines.
|
||||
'max_area' and 'min_b' are the corresponding parameters used for the triangulation (see \delaunay).
|
||||
|
||||
This method has been introduced in version 0.30.1.
|
||||
"""
|
||||
...
|
||||
def inside(self, p: DPoint) -> bool:
|
||||
r"""
|
||||
@brief Gets a value indicating whether the given point is inside the polygon
|
||||
|
|
@ -34920,11 +34956,11 @@ class Instance:
|
|||
|
||||
Starting with version 0.25 the displacement is of vector type.
|
||||
Setter:
|
||||
@brief Sets the displacement vector for the 'b' axis in micrometer units
|
||||
@brief Sets the displacement vector for the 'b' axis
|
||||
|
||||
Like \b= with an integer displacement, this method will set the displacement vector but it accepts a vector in micrometer units that is of \DVector type. The vector will be translated to database units internally.
|
||||
If the instance was not an array instance before it is made one.
|
||||
|
||||
This method has been introduced in version 0.25.
|
||||
This method has been introduced in version 0.23. Starting with version 0.25 the displacement is of vector type.
|
||||
"""
|
||||
cell: Cell
|
||||
r"""
|
||||
|
|
@ -34956,10 +34992,10 @@ class Instance:
|
|||
Getter:
|
||||
@brief Gets the basic \CellInstArray object associated with this instance reference.
|
||||
Setter:
|
||||
@brief Changes the \CellInstArray object to the given one.
|
||||
This method replaces the instance by the given CellInstArray object.
|
||||
@brief Returns the basic cell instance array object by giving a micrometer unit object.
|
||||
This method replaces the instance by the given CellInstArray object and it internally transformed into database units.
|
||||
|
||||
This method has been introduced in version 0.22
|
||||
This method has been introduced in version 0.25
|
||||
"""
|
||||
cplx_trans: ICplxTrans
|
||||
r"""
|
||||
|
|
@ -34967,10 +35003,9 @@ class Instance:
|
|||
@brief Gets the complex transformation of the instance or the first instance in the array
|
||||
This method is always valid compared to \trans, since simple transformations can be expressed as complex transformations as well.
|
||||
Setter:
|
||||
@brief Sets the complex transformation of the instance or the first instance in the array (in micrometer units)
|
||||
This method sets the transformation the same way as \cplx_trans=, but the displacement of this transformation is given in micrometer units. It is internally translated into database units.
|
||||
@brief Sets the complex transformation of the instance or the first instance in the array
|
||||
|
||||
This method has been introduced in version 0.25.
|
||||
This method has been introduced in version 0.23.
|
||||
"""
|
||||
da: DVector
|
||||
r"""
|
||||
|
|
@ -46700,17 +46735,17 @@ class NetTerminalRef:
|
|||
@overload
|
||||
def device(self) -> Device:
|
||||
r"""
|
||||
@brief Gets the device reference (non-const version).
|
||||
@brief Gets the device reference.
|
||||
Gets the device object that this connection is made to.
|
||||
|
||||
This constness variant has been introduced in version 0.26.8
|
||||
"""
|
||||
...
|
||||
@overload
|
||||
def device(self) -> Device:
|
||||
r"""
|
||||
@brief Gets the device reference.
|
||||
@brief Gets the device reference (non-const version).
|
||||
Gets the device object that this connection is made to.
|
||||
|
||||
This constness variant has been introduced in version 0.26.8
|
||||
"""
|
||||
...
|
||||
def device_class(self) -> DeviceClass:
|
||||
|
|
@ -47722,17 +47757,26 @@ class Netlist:
|
|||
@overload
|
||||
def circuit_by_name(self, name: str) -> Circuit:
|
||||
r"""
|
||||
@brief Gets the circuit object for a given name.
|
||||
@brief Gets the circuit object for a given name (const version).
|
||||
If the name is not a valid circuit name, nil is returned.
|
||||
|
||||
This constness variant has been introduced in version 0.26.8.
|
||||
"""
|
||||
...
|
||||
@overload
|
||||
def circuit_by_name(self, name: str) -> Circuit:
|
||||
r"""
|
||||
@brief Gets the circuit object for a given name (const version).
|
||||
@brief Gets the circuit object for a given name.
|
||||
If the name is not a valid circuit name, nil is returned.
|
||||
"""
|
||||
...
|
||||
@overload
|
||||
def circuits_by_name(self, name_pattern: str) -> List[Circuit]:
|
||||
r"""
|
||||
@brief Gets the circuit objects for a given name filter.
|
||||
The name filter is a glob pattern. This method will return all \Circuit objects matching the glob pattern.
|
||||
|
||||
This constness variant has been introduced in version 0.26.8.
|
||||
This method has been introduced in version 0.26.4.
|
||||
"""
|
||||
...
|
||||
@overload
|
||||
|
|
@ -47745,15 +47789,6 @@ class Netlist:
|
|||
This constness variant has been introduced in version 0.26.8.
|
||||
"""
|
||||
...
|
||||
@overload
|
||||
def circuits_by_name(self, name_pattern: str) -> List[Circuit]:
|
||||
r"""
|
||||
@brief Gets the circuit objects for a given name filter.
|
||||
The name filter is a glob pattern. This method will return all \Circuit objects matching the glob pattern.
|
||||
|
||||
This method has been introduced in version 0.26.4.
|
||||
"""
|
||||
...
|
||||
def combine_devices(self) -> None:
|
||||
r"""
|
||||
@brief Combines devices where possible
|
||||
|
|
@ -47996,7 +48031,7 @@ class Netlist:
|
|||
@overload
|
||||
def top_circuit(self) -> Circuit:
|
||||
r"""
|
||||
@brief Gets the top circuit.
|
||||
@brief Gets the top circuit (const version).
|
||||
This method will return nil, if there is no top circuit. It will raise an error, if there is more than a single top circuit.
|
||||
|
||||
This convenience method has been added in version 0.29.5.
|
||||
|
|
@ -48005,7 +48040,7 @@ class Netlist:
|
|||
@overload
|
||||
def top_circuit(self) -> Circuit:
|
||||
r"""
|
||||
@brief Gets the top circuit (const version).
|
||||
@brief Gets the top circuit.
|
||||
This method will return nil, if there is no top circuit. It will raise an error, if there is more than a single top circuit.
|
||||
|
||||
This convenience method has been added in version 0.29.5.
|
||||
|
|
@ -53581,11 +53616,13 @@ class Polygon:
|
|||
|
||||
The minimum angle of the resulting triangles relates to the 'b' parameter as: @t min_angle = arcsin(B/2) @/t.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
The area value is given in terms of DBU units.
|
||||
|
||||
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.
|
||||
|
||||
This method has been introduced in version 0.30.
|
||||
This method has been introduced in version 0.30. Since version 0.30.1, the resulting region is in 'no merged semantics' mode, to avoid re-merging of the triangles during following operations.
|
||||
"""
|
||||
...
|
||||
@overload
|
||||
|
|
@ -53595,7 +53632,7 @@ class Polygon:
|
|||
|
||||
This variant of the triangulation function accepts an array of additional vertexes for the triangulation.
|
||||
|
||||
This method has been introduced in version 0.30.
|
||||
This method has been introduced in version 0.30. Since version 0.30.1, the resulting region is in 'no merged semantics' mode, to avoid re-merging of the triangles during following operations.
|
||||
"""
|
||||
...
|
||||
def destroy(self) -> None:
|
||||
|
|
@ -53682,6 +53719,28 @@ class Polygon:
|
|||
This method has been introduced in version 0.25.
|
||||
"""
|
||||
...
|
||||
def hm_decomposition(self, with_segments: Optional[bool] = ..., split_edges: Optional[bool] = ..., max_area: Optional[float] = ..., min_b: Optional[float] = ..., dbu: Optional[float] = ...) -> Region:
|
||||
r"""
|
||||
@brief Performs a Hertel-Mehlhorn convex decomposition.
|
||||
|
||||
@return A \Region holding the polygons of the decomposition.
|
||||
|
||||
The resulting region is in 'no merged semantics' mode, to avoid re-merging of the polygons during following operations.
|
||||
|
||||
The Hertel-Mehlhorn decomposition starts with a Delaunay triangulation of the polygons and recombines the triangles into convex polygons.
|
||||
|
||||
The decomposition is controlled by two parameters: 'with_segments' and 'split_edges'.
|
||||
|
||||
If 'with_segments' is true (the default), new segments are introduced perpendicular to the edges forming a concave corner. If false, only diagonals (edges connecting original vertexes) are used.
|
||||
|
||||
If 'split_edges' is true, the algorithm is allowed to create collinear edges in the output. In this case, the resulting polygons may contain edges that are split into collinear partial edges. Such edges usually recombine into longer edges when processing the polygon further. When such a recombination happens, the edges no longer correspond to original edges or diagonals. When 'split_edges' is false (the default), the resulting polygons will not contain collinear edges, but the decomposition will be constrained to fewer cut lines.
|
||||
'max_area' and 'min_b' are the corresponding parameters used for the triangulation (see \delaunay).
|
||||
|
||||
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.
|
||||
|
||||
This method has been introduced in version 0.30.1.
|
||||
"""
|
||||
...
|
||||
def holes(self) -> int:
|
||||
r"""
|
||||
@brief Returns the number of holes
|
||||
|
|
@ -62995,11 +63054,12 @@ class Shape:
|
|||
This method has been introduced in version 0.23.
|
||||
|
||||
Setter:
|
||||
@brief Sets the lower left point of the box
|
||||
@brief Sets the lower left corner of the box with the point being given in micrometer units
|
||||
|
||||
Applies to boxes only. Changes the lower left point of the box and throws an exception if the shape is not a box.
|
||||
Translation from micrometer units to database units is done internally.
|
||||
|
||||
This method has been introduced in version 0.23.
|
||||
This method has been introduced in version 0.25.
|
||||
"""
|
||||
box_p2: Point
|
||||
r"""
|
||||
|
|
@ -63377,10 +63437,11 @@ class Shape:
|
|||
Starting with version 0.23, this method returns nil, if the shape does not represent a geometrical primitive that can be converted to a simple polygon.
|
||||
|
||||
Setter:
|
||||
@brief Replaces the shape by the given simple polygon (in micrometer units)
|
||||
This method replaces the shape by the given text, like \simple_polygon= with a \SimplePolygon argument does. This version translates the polygon from micrometer units to database units internally.
|
||||
@brief Replaces the shape by the given simple polygon object
|
||||
This method replaces the shape by the given simple polygon object. This method can only be called for editable layouts. It does not change the user properties of the shape.
|
||||
Calling this method will invalidate any iterators. It should not be called inside a loop iterating over shapes.
|
||||
|
||||
This method has been introduced in version 0.25.
|
||||
This method has been introduced in version 0.22.
|
||||
"""
|
||||
text: Any
|
||||
r"""
|
||||
|
|
@ -66718,11 +66779,13 @@ class SimplePolygon:
|
|||
|
||||
The minimum angle of the resulting triangles relates to the 'b' parameter as: @t min_angle = arcsin(B/2) @/t.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
The area value is given in terms of DBU units.
|
||||
|
||||
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.
|
||||
|
||||
This method has been introduced in version 0.30.
|
||||
This method has been introduced in version 0.30. Since version 0.30.1, the resulting region is in 'no merged semantics' mode, to avoid re-merging of the triangles during following operations.
|
||||
"""
|
||||
...
|
||||
@overload
|
||||
|
|
@ -66732,7 +66795,7 @@ class SimplePolygon:
|
|||
|
||||
This variant of the triangulation function accepts an array of additional vertexes for the triangulation.
|
||||
|
||||
This method has been introduced in version 0.30.
|
||||
This method has been introduced in version 0.30. Since version 0.30.1, the resulting region is in 'no merged semantics' mode, to avoid re-merging of the triangles during following operations.
|
||||
"""
|
||||
...
|
||||
def destroy(self) -> None:
|
||||
|
|
@ -66797,6 +66860,27 @@ class SimplePolygon:
|
|||
This method has been introduced in version 0.25.
|
||||
"""
|
||||
...
|
||||
def hm_decomposition(self, with_segments: Optional[bool] = ..., split_edges: Optional[bool] = ..., max_area: Optional[float] = ..., min_b: Optional[float] = ..., dbu: Optional[float] = ...) -> Region:
|
||||
r"""
|
||||
@brief Performs a Hertel-Mehlhorn convex decomposition.
|
||||
|
||||
@return A \Region holding the polygons of the decomposition.
|
||||
The resulting region is in 'no merged semantics' mode, to avoid re-merging of the polygons during following operations.
|
||||
|
||||
The Hertel-Mehlhorn decomposition starts with a Delaunay triangulation of the polygons and recombines the triangles into convex polygons.
|
||||
|
||||
The decomposition is controlled by two parameters: 'with_segments' and 'split_edges'.
|
||||
|
||||
If 'with_segments' is true (the default), new segments are introduced perpendicular to the edges forming a concave corner. If false, only diagonals (edges connecting original vertexes) are used.
|
||||
|
||||
If 'split_edges' is true, the algorithm is allowed to create collinear edges in the output. In this case, the resulting polygons may contain edges that are split into collinear partial edges. Such edges usually recombine into longer edges when processing the polygon further. When such a recombination happens, the edges no longer correspond to original edges or diagonals. When 'split_edges' is false (the default), the resulting polygons will not contain collinear edges, but the decomposition will be constrained to fewer cut lines.
|
||||
'max_area' and 'min_b' are the corresponding parameters used for the triangulation (see \delaunay).
|
||||
|
||||
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.
|
||||
|
||||
This method has been introduced in version 0.30.1.
|
||||
"""
|
||||
...
|
||||
def inside(self, p: Point) -> bool:
|
||||
r"""
|
||||
@brief Gets a value indicating whether the given point is inside the polygon
|
||||
|
|
@ -67552,17 +67636,23 @@ class SubCircuit(NetlistObject):
|
|||
@overload
|
||||
def circuit(self) -> Circuit:
|
||||
r"""
|
||||
@brief Gets the circuit the subcircuit lives in.
|
||||
@brief Gets the circuit the subcircuit lives in (non-const version).
|
||||
This is NOT the circuit which is referenced. For getting the circuit that the subcircuit references, use \circuit_ref.
|
||||
|
||||
This constness variant has been introduced in version 0.26.8
|
||||
"""
|
||||
...
|
||||
@overload
|
||||
def circuit(self) -> Circuit:
|
||||
r"""
|
||||
@brief Gets the circuit the subcircuit lives in (non-const version).
|
||||
@brief Gets the circuit the subcircuit lives in.
|
||||
This is NOT the circuit which is referenced. For getting the circuit that the subcircuit references, use \circuit_ref.
|
||||
|
||||
This constness variant has been introduced in version 0.26.8
|
||||
"""
|
||||
...
|
||||
@overload
|
||||
def circuit_ref(self) -> Circuit:
|
||||
r"""
|
||||
@brief Gets the circuit referenced by the subcircuit.
|
||||
"""
|
||||
...
|
||||
@overload
|
||||
|
|
@ -67575,12 +67665,6 @@ class SubCircuit(NetlistObject):
|
|||
"""
|
||||
...
|
||||
@overload
|
||||
def circuit_ref(self) -> Circuit:
|
||||
r"""
|
||||
@brief Gets the circuit referenced by the subcircuit.
|
||||
"""
|
||||
...
|
||||
@overload
|
||||
def connect_pin(self, pin: Pin, net: Net) -> None:
|
||||
r"""
|
||||
@brief Connects the given pin to the specified net.
|
||||
|
|
@ -68247,8 +68331,7 @@ class Text:
|
|||
Setter:
|
||||
@brief Sets the horizontal alignment
|
||||
|
||||
This property specifies how the text is aligned relative to the anchor point.
|
||||
This property has been introduced in version 0.22 and extended to enums in 0.28.
|
||||
This is the version accepting integer values. It's provided for backward compatibility.
|
||||
"""
|
||||
size: int
|
||||
r"""
|
||||
|
|
@ -68284,7 +68367,8 @@ class Text:
|
|||
Setter:
|
||||
@brief Sets the vertical alignment
|
||||
|
||||
This is the version accepting integer values. It's provided for backward compatibility.
|
||||
This property specifies how the text is aligned relative to the anchor point.
|
||||
This property has been introduced in version 0.22 and extended to enums in 0.28.
|
||||
"""
|
||||
x: int
|
||||
r"""
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
from typing import Any, ClassVar, Dict, Sequence, List, Iterator, Optional
|
||||
from typing import overload
|
||||
from __future__ import annotations
|
||||
import klayout.tl as tl
|
||||
import klayout.db as db
|
||||
|
|
@ -2908,7 +2908,9 @@ class Timer:
|
|||
r"""
|
||||
@brief Gets the current memory usage of the process in Bytes
|
||||
|
||||
This method has been introduced in version 0.27.
|
||||
The returned value is the resident memory size on Linux and MacOS and the working set size on Windows.
|
||||
|
||||
This method has been introduced in version 0.27. The value has been changed to be resident size (instead of virtual size) on Linux in version 0.30.
|
||||
"""
|
||||
...
|
||||
@classmethod
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue