Enabled net tracing for heavily decomposed polygons

This commit is contained in:
Matthias Koefferlein 2019-09-19 00:13:14 +02:00
parent 6c52daa3a3
commit d69c60a5c5
4 changed files with 119 additions and 10 deletions

View File

@ -571,7 +571,12 @@ void PolygonReferenceHierarchyBuilderShapeReceiver::push (const db::Shape &shape
if (! trans.is_unity ()) {
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) {
@ -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)
{
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)
{
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 ()));
}
}
// ---------------------------------------------------------------------------------------------

View File

@ -758,6 +758,16 @@ public:
* @brief The area of the contour
*/
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 ();
if (n < 3) {
@ -771,10 +781,10 @@ public:
a += db::vprod (pp - point_type (), pl - point_type ());
pl = pp;
}
return a / 2;
return a;
}
/**
/**
* @brief The perimeter of the contour
*/
perimeter_type perimeter () const
@ -1682,7 +1692,13 @@ public:
*/
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;
}
/**
/**
* @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
*/
perimeter_type perimeter () const
@ -2861,7 +2891,17 @@ public:
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
*/
perimeter_type perimeter () const
@ -2977,7 +3017,13 @@ public:
*/
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
@ -3154,7 +3200,17 @@ public:
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
*/
perimeter_type perimeter () const

View File

@ -184,6 +184,16 @@ struct simple_polygon_defs
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)
{
db::polygon<coord_type> p, pnew;
@ -513,6 +523,13 @@ struct simple_polygon_defs
"@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."
) +
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,
"@brief Gets the perimeter of the polygon\n"
"The perimeter is sum of the lengths of all edges making up the polygon."
@ -1022,6 +1039,16 @@ struct polygon_defs
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)
{
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."
"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,
"@brief Gets the perimeter of the polygon\n"
"The perimeter is sum of the lengths of all edges making up the polygon.\n"

View File

@ -79,6 +79,8 @@ TEST(1)
b = p.box ();
EXPECT_EQ (p.holes (), size_t (0));
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.is_box (), true);
@ -103,6 +105,8 @@ TEST(1)
EXPECT_EQ (ip.vertices (), size_t (12));
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.is_box (), false);
EXPECT_EQ (p.box (), b);
@ -121,6 +125,7 @@ TEST(1)
pp.insert_hole (c2.begin (), c2.end ());
pp.assign_hull (c1.begin (), c1.end ());
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 (p, pp);
@ -163,6 +168,8 @@ TEST(2)
b = p.box ();
EXPECT_EQ (p.holes (), size_t (0));
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.is_box (), true);
@ -460,8 +467,11 @@ TEST(5)
}
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 (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));
}