Skip to content

Commit

Permalink
Merge pull request #367 from KLayout/pcb-l2n
Browse files Browse the repository at this point in the history
Enabled net tracing for heavily decomposed polygons
  • Loading branch information
klayoutmatthias committed Oct 3, 2019
2 parents 1c16cea + d69c60a commit a072822
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 10 deletions.
15 changes: 12 additions & 3 deletions src/db/db/dbHierarchyBuilder.cc
Expand Up @@ -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) {

Expand All @@ -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 ()));
}
}

// ---------------------------------------------------------------------------------------------
Expand Down
70 changes: 63 additions & 7 deletions src/db/db/dbPolygon.h
Expand Up @@ -758,6 +758,16 @@ class DB_PUBLIC polygon_contour
* @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) {
Expand All @@ -771,10 +781,10 @@ class DB_PUBLIC polygon_contour
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
Expand Down Expand Up @@ -1682,7 +1692,13 @@ class DB_PUBLIC_TEMPLATE polygon
*/
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);
}
}

/**
Expand Down Expand Up @@ -2135,7 +2151,21 @@ class DB_PUBLIC_TEMPLATE polygon
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
Expand Down Expand Up @@ -2861,7 +2891,17 @@ class DB_PUBLIC_TEMPLATE simple_polygon
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
Expand Down Expand Up @@ -2977,7 +3017,13 @@ class DB_PUBLIC_TEMPLATE simple_polygon
*/
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
Expand Down Expand Up @@ -3154,7 +3200,17 @@ class polygon_ref
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
Expand Down
34 changes: 34 additions & 0 deletions src/db/db/gsiDeclDbPolygon.cc
Expand Up @@ -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;
Expand Down Expand Up @@ -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."
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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"
Expand Down
10 changes: 10 additions & 0 deletions src/db/unit_tests/dbPolygon.cc
Expand Up @@ -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);

Expand All @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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));

}
Expand Down

0 comments on commit a072822

Please sign in to comment.