mirror of https://github.com/KLayout/klayout.git
Merge branch 'master' into pull_feature
This commit is contained in:
commit
5ed41cc345
|
|
@ -571,7 +571,12 @@ void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Shape &shape
|
||||||
if (! trans.is_unity ()) {
|
if (! trans.is_unity ()) {
|
||||||
poly.transform (trans);
|
poly.transform (trans);
|
||||||
}
|
}
|
||||||
target->insert (db::PolygonRef (poly, mp_layout->shape_repository ()));
|
|
||||||
|
// NOTE: as this is a specialized receiver for the purpose of building region
|
||||||
|
// representations we don't need empty polygons here
|
||||||
|
if (poly.area2 () > 0) {
|
||||||
|
target->insert (db::PolygonRef (poly, mp_layout->shape_repository ()));
|
||||||
|
}
|
||||||
|
|
||||||
} else if (shape.is_text () && m_text_enlargement >= 0) {
|
} else if (shape.is_text () && m_text_enlargement >= 0) {
|
||||||
|
|
||||||
|
|
@ -598,12 +603,16 @@ void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Shape &shape
|
||||||
|
|
||||||
void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Box &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
|
void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Box &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
|
||||||
{
|
{
|
||||||
target->insert (db::PolygonRef (db::Polygon (shape.transformed (trans)), mp_layout->shape_repository ()));
|
if (shape.area () > 0) {
|
||||||
|
target->insert (db::PolygonRef (db::Polygon (shape.transformed (trans)), mp_layout->shape_repository ()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Polygon &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
|
void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Polygon &shape, const db::ICplxTrans &trans, const db::Box &, const db::RecursiveShapeReceiver::box_tree_type *, db::Shapes *target)
|
||||||
{
|
{
|
||||||
target->insert (db::PolygonRef (shape.transformed (trans), mp_layout->shape_repository ()));
|
if (shape.area2 () > 0) {
|
||||||
|
target->insert (db::PolygonRef (shape.transformed (trans), mp_layout->shape_repository ()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -758,6 +758,16 @@ public:
|
||||||
* @brief The area of the contour
|
* @brief The area of the contour
|
||||||
*/
|
*/
|
||||||
area_type area () const
|
area_type area () const
|
||||||
|
{
|
||||||
|
return area2 () / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The area of the contour times 2
|
||||||
|
* For integer area types, this is the more precise value as the division
|
||||||
|
* by 2 might round off.
|
||||||
|
*/
|
||||||
|
area_type area2 () const
|
||||||
{
|
{
|
||||||
size_type n = size ();
|
size_type n = size ();
|
||||||
if (n < 3) {
|
if (n < 3) {
|
||||||
|
|
@ -771,10 +781,10 @@ public:
|
||||||
a += db::vprod (pp - point_type (), pl - point_type ());
|
a += db::vprod (pp - point_type (), pl - point_type ());
|
||||||
pl = pp;
|
pl = pp;
|
||||||
}
|
}
|
||||||
return a / 2;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The perimeter of the contour
|
* @brief The perimeter of the contour
|
||||||
*/
|
*/
|
||||||
perimeter_type perimeter () const
|
perimeter_type perimeter () const
|
||||||
|
|
@ -1682,7 +1692,13 @@ public:
|
||||||
*/
|
*/
|
||||||
double area_ratio () const
|
double area_ratio () const
|
||||||
{
|
{
|
||||||
return double (box ().area ()) / double (area ());
|
area_type a = area2 ();
|
||||||
|
if (a == 0) {
|
||||||
|
// By our definition, an empty polygon has an area ratio of 0
|
||||||
|
return 0.0;
|
||||||
|
} else {
|
||||||
|
return double (box ().area ()) / (0.5 * a);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2135,7 +2151,21 @@ public:
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @brief The area of the polygon times 2
|
||||||
|
* For integer area types, this is the more precise value as the division
|
||||||
|
* by 2 might round off.
|
||||||
|
*/
|
||||||
|
area_type area2 () const
|
||||||
|
{
|
||||||
|
area_type a = 0;
|
||||||
|
for (typename contour_list_type::const_iterator h = m_ctrs.begin (); h != m_ctrs.end (); ++h) {
|
||||||
|
a += h->area2 ();
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* @brief The perimeter of the polygon
|
* @brief The perimeter of the polygon
|
||||||
*/
|
*/
|
||||||
perimeter_type perimeter () const
|
perimeter_type perimeter () const
|
||||||
|
|
@ -2861,7 +2891,17 @@ public:
|
||||||
return m_hull.area ();
|
return m_hull.area ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @brief The area of the polygon times 2
|
||||||
|
* For integer area types, this is the more precise value as the division
|
||||||
|
* by 2 might round off.
|
||||||
|
*/
|
||||||
|
area_type area2 () const
|
||||||
|
{
|
||||||
|
return m_hull.area2 ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* @brief The perimeter of the polygon
|
* @brief The perimeter of the polygon
|
||||||
*/
|
*/
|
||||||
perimeter_type perimeter () const
|
perimeter_type perimeter () const
|
||||||
|
|
@ -2977,7 +3017,13 @@ public:
|
||||||
*/
|
*/
|
||||||
double area_ratio () const
|
double area_ratio () const
|
||||||
{
|
{
|
||||||
return double (box ().area ()) / double (area ());
|
area_type a = area2 ();
|
||||||
|
if (a == 0) {
|
||||||
|
// By our definition, an empty polygon has an area ratio of 0
|
||||||
|
return 0.0;
|
||||||
|
} else {
|
||||||
|
return double (box ().area ()) / (0.5 * a);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const
|
void mem_stat (MemStatistics *stat, MemStatistics::purpose_t purpose, int cat, bool no_self = false, void *parent = 0) const
|
||||||
|
|
@ -3154,7 +3200,17 @@ public:
|
||||||
return this->obj ().area ();
|
return this->obj ().area ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @brief The area of the polygon times 2
|
||||||
|
* For integer area types, this is the more precise value as the division
|
||||||
|
* by 2 might round off.
|
||||||
|
*/
|
||||||
|
area_type area2 () const
|
||||||
|
{
|
||||||
|
return this->obj ().area2 ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* @brief The perimeter of the polygon
|
* @brief The perimeter of the polygon
|
||||||
*/
|
*/
|
||||||
perimeter_type perimeter () const
|
perimeter_type perimeter () const
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,16 @@ struct simple_polygon_defs
|
||||||
return poly->area ();
|
return poly->area ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_64BIT_COORD)
|
||||||
|
// workaround for missing 128bit binding of GSI
|
||||||
|
static double area2 (const C *poly)
|
||||||
|
#else
|
||||||
|
static area_type area2 (const C *poly)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
return poly->area2 ();
|
||||||
|
}
|
||||||
|
|
||||||
static std::vector<tl::Variant> extract_rad (const C *sp)
|
static std::vector<tl::Variant> extract_rad (const C *sp)
|
||||||
{
|
{
|
||||||
db::polygon<coord_type> p, pnew;
|
db::polygon<coord_type> p, pnew;
|
||||||
|
|
@ -513,6 +523,13 @@ struct simple_polygon_defs
|
||||||
"@brief Gets the area of the polygon\n"
|
"@brief Gets the area of the polygon\n"
|
||||||
"The area is correct only if the polygon is not self-overlapping and the polygon is oriented clockwise."
|
"The area is correct only if the polygon is not self-overlapping and the polygon is oriented clockwise."
|
||||||
) +
|
) +
|
||||||
|
method_ext ("area2", &area2,
|
||||||
|
"@brief Gets the double area of the polygon\n"
|
||||||
|
"This method is provided because the area for an integer-type polygon is a multiple of 1/2. "
|
||||||
|
"Hence the double area can be expresses precisely as an integer for these types.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.26.1\n"
|
||||||
|
) +
|
||||||
method ("perimeter", &C::perimeter,
|
method ("perimeter", &C::perimeter,
|
||||||
"@brief Gets the perimeter of the polygon\n"
|
"@brief Gets the perimeter of the polygon\n"
|
||||||
"The perimeter is sum of the lengths of all edges making up the polygon."
|
"The perimeter is sum of the lengths of all edges making up the polygon."
|
||||||
|
|
@ -1022,6 +1039,16 @@ struct polygon_defs
|
||||||
return poly->area ();
|
return poly->area ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_64BIT_COORD)
|
||||||
|
// workaround for missing 128bit binding of GSI
|
||||||
|
static double area2 (const C *poly)
|
||||||
|
#else
|
||||||
|
static area_type area2 (const C *poly)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
return poly->area2 ();
|
||||||
|
}
|
||||||
|
|
||||||
static std::vector<tl::Variant> extract_rad (const C *p)
|
static std::vector<tl::Variant> extract_rad (const C *p)
|
||||||
{
|
{
|
||||||
C pnew;
|
C pnew;
|
||||||
|
|
@ -1492,6 +1519,13 @@ struct polygon_defs
|
||||||
"The area is correct only if the polygon is not self-overlapping and the polygon is oriented clockwise."
|
"The area is correct only if the polygon is not self-overlapping and the polygon is oriented clockwise."
|
||||||
"Orientation is ensured automatically in most cases.\n"
|
"Orientation is ensured automatically in most cases.\n"
|
||||||
) +
|
) +
|
||||||
|
method_ext ("area2", &area2,
|
||||||
|
"@brief Gets the double area of the polygon\n"
|
||||||
|
"This method is provided because the area for an integer-type polygon is a multiple of 1/2. "
|
||||||
|
"Hence the double area can be expresses precisely as an integer for these types.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.26.1\n"
|
||||||
|
) +
|
||||||
method ("perimeter", &C::perimeter,
|
method ("perimeter", &C::perimeter,
|
||||||
"@brief Gets the perimeter of the polygon\n"
|
"@brief Gets the perimeter of the polygon\n"
|
||||||
"The perimeter is sum of the lengths of all edges making up the polygon.\n"
|
"The perimeter is sum of the lengths of all edges making up the polygon.\n"
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,8 @@ TEST(1)
|
||||||
b = p.box ();
|
b = p.box ();
|
||||||
EXPECT_EQ (p.holes (), size_t (0));
|
EXPECT_EQ (p.holes (), size_t (0));
|
||||||
EXPECT_EQ (p.area (), 1000*100);
|
EXPECT_EQ (p.area (), 1000*100);
|
||||||
|
EXPECT_EQ (p.area2 (), 2*1000*100);
|
||||||
|
EXPECT_EQ (tl::to_string (p.area_ratio ()), "1");
|
||||||
EXPECT_EQ (p.perimeter (), db::Polygon::perimeter_type (2200));
|
EXPECT_EQ (p.perimeter (), db::Polygon::perimeter_type (2200));
|
||||||
EXPECT_EQ (p.is_box (), true);
|
EXPECT_EQ (p.is_box (), true);
|
||||||
|
|
||||||
|
|
@ -103,6 +105,8 @@ TEST(1)
|
||||||
EXPECT_EQ (ip.vertices (), size_t (12));
|
EXPECT_EQ (ip.vertices (), size_t (12));
|
||||||
|
|
||||||
EXPECT_EQ (p.area (), 1000*100-2*380*80);
|
EXPECT_EQ (p.area (), 1000*100-2*380*80);
|
||||||
|
EXPECT_EQ (p.area2 (), 2*(1000*100-2*380*80));
|
||||||
|
EXPECT_EQ (tl::to_string (p.area_ratio (), 6), "2.55102");
|
||||||
EXPECT_EQ (p.perimeter (), db::Polygon::perimeter_type (2000+200+4*(380+80)));
|
EXPECT_EQ (p.perimeter (), db::Polygon::perimeter_type (2000+200+4*(380+80)));
|
||||||
EXPECT_EQ (p.is_box (), false);
|
EXPECT_EQ (p.is_box (), false);
|
||||||
EXPECT_EQ (p.box (), b);
|
EXPECT_EQ (p.box (), b);
|
||||||
|
|
@ -121,6 +125,7 @@ TEST(1)
|
||||||
pp.insert_hole (c2.begin (), c2.end ());
|
pp.insert_hole (c2.begin (), c2.end ());
|
||||||
pp.assign_hull (c1.begin (), c1.end ());
|
pp.assign_hull (c1.begin (), c1.end ());
|
||||||
EXPECT_EQ (pp.area (), 1000*100-2*380*80);
|
EXPECT_EQ (pp.area (), 1000*100-2*380*80);
|
||||||
|
EXPECT_EQ (pp.area2 (), 2*(1000*100-2*380*80));
|
||||||
EXPECT_EQ (pp.box (), b);
|
EXPECT_EQ (pp.box (), b);
|
||||||
|
|
||||||
EXPECT_EQ (p, pp);
|
EXPECT_EQ (p, pp);
|
||||||
|
|
@ -163,6 +168,8 @@ TEST(2)
|
||||||
b = p.box ();
|
b = p.box ();
|
||||||
EXPECT_EQ (p.holes (), size_t (0));
|
EXPECT_EQ (p.holes (), size_t (0));
|
||||||
EXPECT_EQ (p.area (), 1000*100);
|
EXPECT_EQ (p.area (), 1000*100);
|
||||||
|
EXPECT_EQ (p.area2 (), 2*1000*100);
|
||||||
|
EXPECT_EQ (tl::to_string (p.area_ratio ()), "1");
|
||||||
EXPECT_EQ (p.perimeter (), db::SimplePolygon::perimeter_type (2000+200));
|
EXPECT_EQ (p.perimeter (), db::SimplePolygon::perimeter_type (2000+200));
|
||||||
EXPECT_EQ (p.is_box (), true);
|
EXPECT_EQ (p.is_box (), true);
|
||||||
|
|
||||||
|
|
@ -460,8 +467,11 @@ TEST(5)
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPECT_EQ (p.area (), 100*1000-10*100);
|
EXPECT_EQ (p.area (), 100*1000-10*100);
|
||||||
|
EXPECT_EQ (p.area2 (), 2*(100*1000-10*100));
|
||||||
|
EXPECT_EQ (tl::to_string (p.area_ratio (), 6), "1.0101");
|
||||||
EXPECT_EQ (p.perimeter (), db::Polygon::perimeter_type (200+2000+20+200));
|
EXPECT_EQ (p.perimeter (), db::Polygon::perimeter_type (200+2000+20+200));
|
||||||
EXPECT_EQ (pref.area (), 100*1000-10*100);
|
EXPECT_EQ (pref.area (), 100*1000-10*100);
|
||||||
|
EXPECT_EQ (pref.area2 (), 2*(100*1000-10*100));
|
||||||
EXPECT_EQ (pref.perimeter (), db::Polygon::perimeter_type (200+2000+20+200));
|
EXPECT_EQ (pref.perimeter (), db::Polygon::perimeter_type (200+2000+20+200));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue