mirror of https://github.com/KLayout/klayout.git
Smooth bug (#740)
* Smoothing function: provide ability to keep horizontal/vertical lines (important for cut lines) * Introducting API compatibility macros for generic plugins.
This commit is contained in:
parent
9e3183250f
commit
184f2bee50
|
|
@ -725,7 +725,7 @@ template DB_PUBLIC void split_polygon<> (const db::DSimplePolygon &polygon, std:
|
|||
// Smoothing tools
|
||||
|
||||
void
|
||||
smooth_contour (db::Polygon::polygon_contour_iterator from, db::Polygon::polygon_contour_iterator to, std::vector <db::Point> &points, db::Coord d)
|
||||
smooth_contour (db::Polygon::polygon_contour_iterator from, db::Polygon::polygon_contour_iterator to, std::vector <db::Point> &points, db::Coord d, bool keep_hv)
|
||||
{
|
||||
points.clear ();
|
||||
points.reserve (std::distance (from, to));
|
||||
|
|
@ -781,7 +781,9 @@ smooth_contour (db::Polygon::polygon_contour_iterator from, db::Polygon::polygon
|
|||
|
||||
bool can_drop = false;
|
||||
|
||||
if (db::Coord (p1.distance(p0)) <= d && db::sprod_sign (p2 - p1, p0 - pm1) > 0 && std::abs (db::vprod (p2 - p1, p0 - pm1)) < 0.8 * p2.distance (p1) * p0.distance (pm1)) {
|
||||
if (keep_hv && (p1.x () == p0.x () || p1.y () == p0.y () || p2.x () == p1.x () || p2.y () == p1.y ())) {
|
||||
// keep points which participate in either a vertical or horizontal edge
|
||||
} else if (db::Coord (p1.distance(p0)) <= d && db::sprod_sign (p2 - p1, p0 - pm1) > 0 && std::abs (db::vprod (p2 - p1, p0 - pm1)) < 0.8 * p2.distance (p1) * p0.distance (pm1)) {
|
||||
// jog configurations with small edges are candidates
|
||||
can_drop = true;
|
||||
} else if (db::vprod_sign (p2 - p1, p1 - p0) < 0) {
|
||||
|
|
@ -839,19 +841,19 @@ smooth_contour (db::Polygon::polygon_contour_iterator from, db::Polygon::polygon
|
|||
}
|
||||
|
||||
db::Polygon
|
||||
smooth (const db::Polygon &polygon, db::Coord d)
|
||||
smooth (const db::Polygon &polygon, db::Coord d, bool keep_hv)
|
||||
{
|
||||
db::Polygon new_poly;
|
||||
std::vector <db::Point> new_pts;
|
||||
|
||||
smooth_contour (polygon.begin_hull (), polygon.end_hull (), new_pts, d);
|
||||
smooth_contour (polygon.begin_hull (), polygon.end_hull (), new_pts, d, keep_hv);
|
||||
if (new_pts.size () >= 3) {
|
||||
|
||||
new_poly.assign_hull (new_pts.begin (), new_pts.end (), false /*don't compress*/);
|
||||
|
||||
for (unsigned int h = 0; h < polygon.holes (); ++h) {
|
||||
new_pts.clear ();
|
||||
smooth_contour (polygon.begin_hole (h), polygon.end_hole (h), new_pts, d);
|
||||
smooth_contour (polygon.begin_hole (h), polygon.end_hole (h), new_pts, d, keep_hv);
|
||||
if (new_pts.size () >= 3) {
|
||||
new_poly.insert_hole (new_pts.begin (), new_pts.end (), false /*don't compress*/);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -449,6 +449,8 @@ db::Polygon DB_PUBLIC compute_rounded (const db::Polygon &poly, double rinner, d
|
|||
*/
|
||||
db::DPolygon DB_PUBLIC compute_rounded (const db::DPolygon &poly, double rinner, double router, unsigned int n);
|
||||
|
||||
#define KLAYOUT_SMOOTH_HAS_KEEP_HV 1
|
||||
|
||||
/**
|
||||
* @brief Smooth a contour
|
||||
*
|
||||
|
|
@ -458,13 +460,14 @@ db::DPolygon DB_PUBLIC compute_rounded (const db::DPolygon &poly, double rinner,
|
|||
* @param to The end of the contour
|
||||
* @param new_pts The points that make up the new contour
|
||||
* @param d The distance that determines the smoothing "roughness"
|
||||
* @param keep_hv If true, vertical and horizontal edges are maintained
|
||||
*/
|
||||
void DB_PUBLIC smooth_contour (db::Polygon::polygon_contour_iterator from, db::Polygon::polygon_contour_iterator to, std::vector <db::Point> &new_pts, db::Coord d);
|
||||
void DB_PUBLIC smooth_contour (db::Polygon::polygon_contour_iterator from, db::Polygon::polygon_contour_iterator to, std::vector <db::Point> &new_pts, db::Coord d, bool keep_hv);
|
||||
|
||||
/**
|
||||
* @brief Smooth a polygon (apply smoothing to the whole polygon)
|
||||
*/
|
||||
db::Polygon DB_PUBLIC smooth (const db::Polygon &poly, db::Coord d);
|
||||
db::Polygon DB_PUBLIC smooth (const db::Polygon &poly, db::Coord d, bool keep_hv);
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating whether the polygon is an "strange polygon"
|
||||
|
|
|
|||
|
|
@ -263,15 +263,15 @@ Region::rounded_corners (double rinner, double router, unsigned int n) const
|
|||
}
|
||||
|
||||
void
|
||||
Region::smooth (coord_type d)
|
||||
Region::smooth (coord_type d, bool keep_hv)
|
||||
{
|
||||
process (SmoothingProcessor (d));
|
||||
process (SmoothingProcessor (d, keep_hv));
|
||||
}
|
||||
|
||||
Region
|
||||
Region::smoothed (coord_type d) const
|
||||
Region::smoothed (coord_type d, bool keep_hv) const
|
||||
{
|
||||
return processed (SmoothingProcessor (d));
|
||||
return processed (SmoothingProcessor (d, keep_hv));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -1518,14 +1518,14 @@ public:
|
|||
/**
|
||||
* @brief Smoothes the region (in-place)
|
||||
*/
|
||||
void smooth (coord_type d);
|
||||
void smooth (coord_type d, bool keep_hv);
|
||||
|
||||
/**
|
||||
* @brief Returns the smoothed region
|
||||
*
|
||||
* @param d The smoothing accuracy
|
||||
*/
|
||||
Region smoothed (coord_type d) const;
|
||||
Region smoothed (coord_type d, bool keep_hv) const;
|
||||
|
||||
/**
|
||||
* @brief Returns the nth polygon
|
||||
|
|
|
|||
|
|
@ -868,14 +868,14 @@ StrangePolygonCheckProcessor::process (const db::Polygon &poly, std::vector<db::
|
|||
// -------------------------------------------------------------------------------------------------------------
|
||||
// Smoothing processor
|
||||
|
||||
SmoothingProcessor::SmoothingProcessor (db::Coord d) : m_d (d) { }
|
||||
SmoothingProcessor::SmoothingProcessor (db::Coord d, bool keep_hv) : m_d (d), m_keep_hv (keep_hv) { }
|
||||
|
||||
SmoothingProcessor::~SmoothingProcessor () { }
|
||||
|
||||
void
|
||||
SmoothingProcessor::process (const db::Polygon &poly, std::vector<db::Polygon> &res) const
|
||||
{
|
||||
res.push_back (db::smooth (poly, m_d));
|
||||
res.push_back (db::smooth (poly, m_d, m_keep_hv));
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -504,7 +504,7 @@ class DB_PUBLIC SmoothingProcessor
|
|||
: public PolygonProcessorBase
|
||||
{
|
||||
public:
|
||||
SmoothingProcessor (db::Coord d);
|
||||
SmoothingProcessor (db::Coord d, bool keep_hv);
|
||||
~SmoothingProcessor ();
|
||||
|
||||
virtual void process (const db::Polygon &poly, std::vector<db::Polygon> &res) const;
|
||||
|
|
@ -517,6 +517,7 @@ public:
|
|||
|
||||
private:
|
||||
db::Coord m_d;
|
||||
bool m_keep_hv;
|
||||
db::MagnificationReducer m_vars;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -185,10 +185,10 @@ static db::CompoundRegionOperationNode *new_strange_polygons_filter (db::Compoun
|
|||
return new db::CompoundRegionProcessingOperationNode (new db::StrangePolygonCheckProcessor (), input, true /*processor is owned*/);
|
||||
}
|
||||
|
||||
static db::CompoundRegionOperationNode *new_smoothed (db::CompoundRegionOperationNode *input, db::Coord d)
|
||||
static db::CompoundRegionOperationNode *new_smoothed (db::CompoundRegionOperationNode *input, db::Coord d, bool keep_hv)
|
||||
{
|
||||
check_non_null (input, "input");
|
||||
return new db::CompoundRegionProcessingOperationNode (new db::SmoothingProcessor (d), input, true /*processor is owned*/, d);
|
||||
return new db::CompoundRegionProcessingOperationNode (new db::SmoothingProcessor (d, keep_hv), input, true /*processor is owned*/, d);
|
||||
}
|
||||
|
||||
static db::CompoundRegionOperationNode *new_rounded_corners (db::CompoundRegionOperationNode *input, double rinner, double router, unsigned int n)
|
||||
|
|
@ -572,9 +572,10 @@ Class<db::CompoundRegionOperationNode> decl_CompoundRegionOperationNode ("db", "
|
|||
"@brief Creates a node extracting strange polygons.\n"
|
||||
"'strange polygons' are ones which cannot be oriented - e.g. '8' shape polygons."
|
||||
) +
|
||||
gsi::constructor ("new_smoothed", &new_smoothed, gsi::arg ("input"), gsi::arg ("d"),
|
||||
gsi::constructor ("new_smoothed", &new_smoothed, gsi::arg ("input"), gsi::arg ("d"), gsi::arg ("keep_hv", false),
|
||||
"@brief Creates a node smoothing the polygons.\n"
|
||||
"@param d The tolerance to be applied for the smoothing."
|
||||
"@param d The tolerance to be applied for the smoothing.\n"
|
||||
"@param keep_hv If true, horizontal and vertical edges are maintained.\n"
|
||||
) +
|
||||
gsi::constructor ("new_rounded_corners", &new_rounded_corners, gsi::arg ("input"), gsi::arg ("rinner"), gsi::arg ("router"), gsi::arg ("n"),
|
||||
"@brief Creates a node generating rounded corners.\n"
|
||||
|
|
|
|||
|
|
@ -1602,9 +1602,9 @@ static db::Polygon transformed_icplx_dp (const db::Polygon *p, const db::ICplxTr
|
|||
return p->transformed (t, false /*don't compress*/);
|
||||
}
|
||||
|
||||
static db::Polygon smooth (const db::Polygon *p, db::Coord d)
|
||||
static db::Polygon smooth (const db::Polygon *p, db::Coord d, bool keep_hv)
|
||||
{
|
||||
return db::smooth (*p, d);
|
||||
return db::smooth (*p, d, keep_hv);
|
||||
}
|
||||
|
||||
static db::Polygon minkowsky_sum_pe (const db::Polygon *p, const db::Edge &e, bool rh)
|
||||
|
|
@ -1787,17 +1787,18 @@ Class<db::Polygon> decl_Polygon ("db", "Polygon",
|
|||
"\n"
|
||||
"This method was introduced in version 0.22.\n"
|
||||
) +
|
||||
method_ext ("smooth", &smooth, gsi::arg ("d"),
|
||||
method_ext ("smooth", &smooth, gsi::arg ("d"), gsi::arg ("keep_hv", false),
|
||||
"@brief Smoothes a polygon\n"
|
||||
"\n"
|
||||
"Remove vertices that deviate by more than the distance d from the average contour.\n"
|
||||
"The value d is basically the roughness which is removed.\n"
|
||||
"\n"
|
||||
"@param d The smoothing \"roughness\".\n"
|
||||
"@param keep_hv If true, horizontal and vertical edges will be preserved always.\n"
|
||||
"\n"
|
||||
"@return The smoothed polygon.\n"
|
||||
"\n"
|
||||
"This method was introduced in version 0.23.\n"
|
||||
"This method was introduced in version 0.23. The 'keep_hv' optional parameter was added in version 0.27.\n"
|
||||
) +
|
||||
method_ext ("minkowsky_sum", &minkowsky_sum_pe, gsi::arg ("e"), gsi::arg ("resolve_holes"),
|
||||
"@brief Computes the Minkowsky sum of the polygon and an edge\n"
|
||||
|
|
|
|||
|
|
@ -1412,9 +1412,10 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"See \\round_corners for a description of this method. This version returns a new region instead of "
|
||||
"modifying self (out-of-place)."
|
||||
) +
|
||||
method ("smooth", &db::Region::smooth, gsi::arg ("d"),
|
||||
method ("smooth", &db::Region::smooth, gsi::arg ("d"), gsi::arg ("keep_hv", false),
|
||||
"@brief Smoothing\n"
|
||||
"@param d The smoothing tolerance (in database units)\n"
|
||||
"@param keep_hv If true, horizontal and vertical edges are maintained\n"
|
||||
"\n"
|
||||
"This method will simplify the merged polygons of the region by removing vertexes if the "
|
||||
"resulting polygon stays equivalent with the original polygon. Equivalence is measured "
|
||||
|
|
@ -1423,9 +1424,10 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"This method modifies the region. \\smoothed is a method that does the same but returns a new "
|
||||
"region without modifying self. Merged semantics applies for this method.\n"
|
||||
) +
|
||||
method ("smoothed", &db::Region::smoothed, gsi::arg ("d"),
|
||||
method ("smoothed", &db::Region::smoothed, gsi::arg ("d"), gsi::arg ("keep_hv", false),
|
||||
"@brief Smoothing\n"
|
||||
"@param d The smoothing tolerance (in database units)\n"
|
||||
"@param keep_hv If true, horizontal and vertical edges are maintained\n"
|
||||
"\n"
|
||||
"See \\smooth for a description of this method. This version returns a new region instead of "
|
||||
"modifying self (out-of-place). It has been introduced in version 0.25."
|
||||
|
|
|
|||
|
|
@ -733,7 +733,8 @@ TEST(11_RoundAndSmoothed)
|
|||
r1_sized -= r1;
|
||||
|
||||
db::Region rounded = r1_sized.rounded_corners (3000, 5000, 100);
|
||||
db::Region smoothed = rounded.smoothed (100);
|
||||
db::Region smoothed = rounded.smoothed (100, false);
|
||||
db::Region smoothed_keep_hv = rounded.smoothed (100, true);
|
||||
|
||||
db::Layout target;
|
||||
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
|
||||
|
|
@ -741,6 +742,7 @@ TEST(11_RoundAndSmoothed)
|
|||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (10, 0)), r1_sized);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), rounded);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (12, 0)), smoothed);
|
||||
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (13, 0)), smoothed_keep_hv);
|
||||
|
||||
CHECKPOINT();
|
||||
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au11.gds");
|
||||
|
|
|
|||
|
|
@ -1188,8 +1188,8 @@ TEST(100)
|
|||
db::Polygon p;
|
||||
p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0]));
|
||||
|
||||
EXPECT_EQ (smooth (p, 5).to_string (), "(0,-100;0,0;50,10;100,-10;150,0;150,-100)");
|
||||
EXPECT_EQ (smooth (p, 20).to_string (), "(0,-100;0,0;150,0;150,-100)");
|
||||
EXPECT_EQ (smooth (p, 5, true).to_string (), "(0,-100;0,0;50,10;100,-10;150,0;150,-100)");
|
||||
EXPECT_EQ (smooth (p, 20, true).to_string (), "(0,-100;0,0;150,0;150,-100)");
|
||||
}
|
||||
|
||||
// smoothing
|
||||
|
|
@ -1207,8 +1207,8 @@ TEST(101)
|
|||
db::Polygon p;
|
||||
p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0]));
|
||||
|
||||
EXPECT_EQ (smooth (p, 5).to_string (), "(100,-10;50,10;0,0;0,100;150,100;150,0)");
|
||||
EXPECT_EQ (smooth (p, 20).to_string (), "(0,0;0,100;150,100;150,0)");
|
||||
EXPECT_EQ (smooth (p, 5, true).to_string (), "(100,-10;50,10;0,0;0,100;150,100;150,0)");
|
||||
EXPECT_EQ (smooth (p, 20, true).to_string (), "(0,0;0,100;150,100;150,0)");
|
||||
}
|
||||
|
||||
// smoothing
|
||||
|
|
@ -1224,8 +1224,8 @@ TEST(102)
|
|||
db::Polygon p;
|
||||
p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0]));
|
||||
|
||||
EXPECT_EQ (smooth (p, 20).to_string (), "()");
|
||||
EXPECT_EQ (smooth (p, 5).to_string (), "(100,-10;150,0;0,0;50,10)");
|
||||
EXPECT_EQ (smooth (p, 20, true).to_string (), "()");
|
||||
EXPECT_EQ (smooth (p, 5, true).to_string (), "(100,-10;150,0;0,0;50,10)");
|
||||
}
|
||||
|
||||
// smoothing
|
||||
|
|
@ -1251,9 +1251,9 @@ TEST(103)
|
|||
db::Polygon p;
|
||||
p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0]));
|
||||
|
||||
EXPECT_EQ (smooth (p, 0).to_string (), "(59881,-249925;56852,-237283;56961,-237258;60061,-236492;63152,-235686;66231,-234839;69300,-233952;69407,-233919;73105,-246382;72992,-246417;69760,-247351;66516,-248243;63261,-249092;59995,-249899)");
|
||||
EXPECT_EQ (smooth (p, 50).to_string (), "(59881,-249925;56852,-237283;63152,-235686;69407,-233919;73105,-246382;69760,-247351)");
|
||||
EXPECT_EQ (smooth (p, 5000).to_string (), "(59881,-249925;56852,-237283;69407,-233919;73105,-246382)");
|
||||
EXPECT_EQ (smooth (p, 0, true).to_string (), "(59881,-249925;56852,-237283;56961,-237258;60061,-236492;63152,-235686;66231,-234839;69300,-233952;69407,-233919;73105,-246382;72992,-246417;69760,-247351;66516,-248243;63261,-249092;59995,-249899)");
|
||||
EXPECT_EQ (smooth (p, 50, true).to_string (), "(59881,-249925;56852,-237283;63152,-235686;69407,-233919;73105,-246382;69760,-247351)");
|
||||
EXPECT_EQ (smooth (p, 5000, true).to_string (), "(59881,-249925;56852,-237283;69407,-233919;73105,-246382)");
|
||||
}
|
||||
|
||||
// smoothing
|
||||
|
|
@ -1272,7 +1272,8 @@ TEST(104)
|
|||
db::Polygon p;
|
||||
p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0]));
|
||||
|
||||
EXPECT_EQ (smooth (p, 12).to_string (), "(-244,-942;-942,-246;248,943;943,246)");
|
||||
EXPECT_EQ (smooth (p, 12, false).to_string (), "(-244,-942;-942,-246;248,943;943,246)");
|
||||
EXPECT_EQ (smooth (p, 12, true).to_string (), "(-245,-942;-942,-247;-942,-246;247,943;248,943;943,246;-244,-942)");
|
||||
}
|
||||
|
||||
// smoothing
|
||||
|
|
@ -1292,11 +1293,46 @@ TEST(105)
|
|||
db::Polygon p;
|
||||
p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0]));
|
||||
|
||||
EXPECT_EQ (smooth (p, 0).to_string (), "(0,0;0,1000;100,1000;100,1100;800,1100;800,1000;2000,1000;2000,0)");
|
||||
EXPECT_EQ (smooth (p, 50).to_string (), "(0,0;0,1000;100,1000;100,1100;800,1100;800,1000;2000,1000;2000,0)");
|
||||
EXPECT_EQ (smooth (p, 80).to_string (), "(0,0;0,1000;100,1100;800,1100;800,1000;2000,1000;2000,0)");
|
||||
EXPECT_EQ (smooth (p, 90).to_string (), "(0,0;100,1100;800,1100;800,1000;2000,1000;2000,0)");
|
||||
EXPECT_EQ (smooth (p, 100).to_string (), "(0,0;0,1000;2000,1000;2000,0)");
|
||||
EXPECT_EQ (smooth (p, 0, false).to_string (), "(0,0;0,1000;100,1000;100,1100;800,1100;800,1000;2000,1000;2000,0)");
|
||||
EXPECT_EQ (smooth (p, 50, false).to_string (), "(0,0;0,1000;100,1000;100,1100;800,1100;800,1000;2000,1000;2000,0)");
|
||||
EXPECT_EQ (smooth (p, 80, false).to_string (), "(0,0;0,1000;100,1100;800,1100;800,1000;2000,1000;2000,0)");
|
||||
EXPECT_EQ (smooth (p, 90, false).to_string (), "(0,0;100,1100;800,1100;800,1000;2000,1000;2000,0)");
|
||||
EXPECT_EQ (smooth (p, 100, false).to_string (), "(0,0;0,1000;2000,1000;2000,0)");
|
||||
EXPECT_EQ (smooth (p, 100, true).to_string (), "(0,0;0,1000;100,1000;100,1100;800,1100;800,1000;2000,1000;2000,0)");
|
||||
}
|
||||
|
||||
// smoothing
|
||||
TEST(106)
|
||||
{
|
||||
db::Point pattern [] = {
|
||||
db::Point (0, 0),
|
||||
db::Point (0, 73235),
|
||||
db::Point (100, 74568),
|
||||
db::Point (700, 82468),
|
||||
db::Point (1200, 90468),
|
||||
db::Point (2000, 106468),
|
||||
db::Point (2300, 114468),
|
||||
db::Point (2700, 130468),
|
||||
db::Point (2800, 138468),
|
||||
db::Point (2800, 154468),
|
||||
db::Point (2700, 162468),
|
||||
db::Point (2300, 178468),
|
||||
db::Point (2000, 186468),
|
||||
db::Point (1200, 202468),
|
||||
db::Point (700, 210468),
|
||||
db::Point (100, 218368),
|
||||
db::Point (0, 219701),
|
||||
db::Point (0, 272971),
|
||||
db::Point (126450, 272971),
|
||||
db::Point (126450, 0),
|
||||
};
|
||||
|
||||
db::Polygon p;
|
||||
p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0]));
|
||||
|
||||
EXPECT_EQ (smooth (p, 0, false).to_string (), "(0,0;0,73235;100,74568;700,82468;1200,90468;2000,106468;2300,114468;2700,130468;2800,138468;2800,154468;2700,162468;2300,178468;2000,186468;1200,202468;700,210468;100,218368;0,219701;0,272971;126450,272971;126450,0)");
|
||||
EXPECT_EQ (smooth (p, 100, false).to_string (), "(0,0;100,74568;1200,90468;2300,114468;2800,138468;2700,162468;2000,186468;700,210468;0,219701;0,272971;126450,272971;126450,0)");
|
||||
EXPECT_EQ (smooth (p, 100, true).to_string (), "(0,0;0,73235;1200,90468;2300,114468;2800,138468;2800,154468;2000,186468;700,210468;0,219701;0,272971;126450,272971;126450,0)");
|
||||
}
|
||||
|
||||
// rounding
|
||||
|
|
@ -1501,7 +1537,7 @@ TEST(203)
|
|||
in.push_back (pp);
|
||||
ep.simple_merge (in, out, false /*no cut line*/);
|
||||
pp = out.front ();
|
||||
pp = smooth (pp, 1);
|
||||
pp = smooth (pp, 1, true);
|
||||
|
||||
EXPECT_EQ (pp.hull ().size (), size_t (300));
|
||||
EXPECT_EQ (extract_rad (pp, rinner, router, n, &pr), true);
|
||||
|
|
@ -1547,7 +1583,7 @@ TEST(204)
|
|||
in.push_back (pp);
|
||||
ep.simple_merge (in, out, false /*no cut line*/);
|
||||
pp = out.front ();
|
||||
pp = smooth (pp, 1);
|
||||
pp = smooth (pp, 1, true);
|
||||
|
||||
EXPECT_EQ (pp.hull ().size (), size_t (200));
|
||||
EXPECT_EQ (extract_rad (pp, rinner, router, n, &pr), true);
|
||||
|
|
|
|||
|
|
@ -739,16 +739,18 @@ CODE
|
|||
# %DRC%
|
||||
# @name smoothed
|
||||
# @brief Applies smoothing
|
||||
# @synopsis expression.smoothed(d)
|
||||
# @synopsis expression.smoothed(d [, keep_hv ])
|
||||
#
|
||||
# This operation acts on polygons and applies polygon smoothing with the tolerance d. See \Layer#smoothed for more details.
|
||||
# This operation acts on polygons and applies polygon smoothing with the tolerance d. 'keep_hv' indicates
|
||||
# whether horizontal and vertical edges are maintained. Default is 'no' which means such edges may be distorted.
|
||||
# See \Layer#smoothed for more details.
|
||||
#
|
||||
# The "smoothed" method is available as a plain function or as a method on \DRC# expressions.
|
||||
# The plain function is equivalent to "primary.smoothed".
|
||||
|
||||
def smoothed(d)
|
||||
def smoothed(d, keep_hv = false)
|
||||
@engine._context("smoothed") do
|
||||
DRCOpNodeFilter::new(@engine, self, :new_smoothed, "smoothed", @engine._make_value(d))
|
||||
DRCOpNodeFilter::new(@engine, self, :new_smoothed, "smoothed", @engine._make_value(d), keep_hv)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1387,7 +1387,7 @@ MainService::cm_round_corners ()
|
|||
std::vector <db::Polygon> in;
|
||||
ep.merge (primary, in, 0 /*min_wc*/, false /*resolve holes*/, true /*min coherence*/);
|
||||
for (std::vector <db::Polygon>::iterator p = in.begin (); p != in.end (); ++p) {
|
||||
*p = smooth (*p, 1);
|
||||
*p = smooth (*p, 1, true);
|
||||
}
|
||||
|
||||
std::vector <db::Polygon> out = in;
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -289,6 +289,9 @@ class DBPolygonTests(unittest.TestCase):
|
|||
p = pya.Polygon( [ pya.Point.new(0, 0), pya.Point.new(10, 50), pya.Point.new(0, 100), pya.Point.new(200, 100), pya.Point.new(200, 0) ])
|
||||
self.assertEqual(str(p.smooth(5)), "(0,0;10,50;0,100;200,100;200,0)")
|
||||
self.assertEqual(str(p.smooth(15)), "(0,0;0,100;200,100;200,0)")
|
||||
p = pya.Polygon( [ pya.Point.new(0, 0), pya.Point.new(10, 50), pya.Point.new(10, 100), pya.Point.new(200, 100), pya.Point.new(200, 0) ])
|
||||
self.assertEqual(str(p.smooth(15, False)), "(0,0;10,100;200,100;200,0)")
|
||||
self.assertEqual(str(p.smooth(15, True)), "(0,0;10,50;10,100;200,100;200,0)")
|
||||
|
||||
# Ellipse constructor
|
||||
p = pya.Polygon.ellipse( pya.Box(-10000, -20000, 30000, 40000), 200 )
|
||||
|
|
|
|||
|
|
@ -304,6 +304,9 @@ class DBPolygon_TestClass < TestBase
|
|||
p = RBA::Polygon::new( [ RBA::Point.new(0, 0), RBA::Point.new(10, 50), RBA::Point.new(0, 100), RBA::Point.new(200, 100), RBA::Point.new(200, 0) ])
|
||||
assert_equal(p.smooth(5).to_s, "(0,0;10,50;0,100;200,100;200,0)")
|
||||
assert_equal(p.smooth(15).to_s, "(0,0;0,100;200,100;200,0)")
|
||||
p = RBA::Polygon::new( [ RBA::Point.new(0, 0), RBA::Point.new(10, 50), RBA::Point.new(10, 100), RBA::Point.new(200, 100), RBA::Point.new(200, 0) ])
|
||||
assert_equal(p.smooth(15, false).to_s, "(0,0;10,100;200,100;200,0)")
|
||||
assert_equal(p.smooth(15, true).to_s, "(0,0;10,50;10,100;200,100;200,0)")
|
||||
|
||||
# Ellipse constructor
|
||||
p = RBA::Polygon::ellipse( RBA::Box::new(-10000, -20000, 30000, 40000), 200 )
|
||||
|
|
|
|||
Loading…
Reference in New Issue