mirror of https://github.com/KLayout/klayout.git
Addressing issue #2011
- "report" can now be late in DRC without internal error Yet, the report will only capture the output layers after the report statement has been called. - Text objects don't create zero-area polygons in deep mode XOR now.
This commit is contained in:
parent
2435e774f4
commit
ffa42653fe
|
|
@ -39,7 +39,9 @@ PolygonRefToShapesGenerator::PolygonRefToShapesGenerator (db::Layout *layout, db
|
|||
void PolygonRefToShapesGenerator::put (const db::Polygon &polygon)
|
||||
{
|
||||
tl::MutexLocker locker (&mp_layout->lock ());
|
||||
if (m_prop_id != 0) {
|
||||
if (polygon.is_empty ()) {
|
||||
// ignore empty polygons
|
||||
} else if (m_prop_id != 0) {
|
||||
mp_shapes->insert (db::PolygonRefWithProperties (db::PolygonRef (polygon, mp_layout->shape_repository ()), m_prop_id));
|
||||
} else {
|
||||
mp_shapes->insert (db::PolygonRef (polygon, mp_layout->shape_repository ()));
|
||||
|
|
@ -58,7 +60,9 @@ PolygonSplitter::PolygonSplitter (PolygonSink &sink, double max_area_ratio, size
|
|||
void
|
||||
PolygonSplitter::put (const db::Polygon &poly)
|
||||
{
|
||||
if (db::suggest_split_polygon (poly, m_max_vertex_count, m_max_area_ratio)) {
|
||||
if (poly.is_empty ()) {
|
||||
// ignore empty polygons
|
||||
} else if (db::suggest_split_polygon (poly, m_max_vertex_count, m_max_area_ratio)) {
|
||||
|
||||
std::vector <db::Polygon> split_polygons;
|
||||
db::split_polygon (poly, split_polygons);
|
||||
|
|
|
|||
|
|
@ -1771,6 +1771,14 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating that the polygon is an empty one
|
||||
*/
|
||||
bool is_empty () const
|
||||
{
|
||||
return m_ctrs.size () == size_t (1) && m_ctrs[0].size () == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the number of points in the polygon
|
||||
*/
|
||||
|
|
@ -1879,6 +1887,7 @@ public:
|
|||
for (typename contour_list_type::iterator h = m_ctrs.begin (); h != m_ctrs.end (); ++h) {
|
||||
h->transform (db::unit_trans<C> (), true /*compress*/, remove_reflected);
|
||||
}
|
||||
m_bbox = m_ctrs [0].bbox ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -2804,6 +2813,7 @@ public:
|
|||
{
|
||||
// compress the polygon by employing the transform method
|
||||
m_hull.transform (db::unit_trans<C> (), true, remove_reflected);
|
||||
m_bbox = m_hull.bbox ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -3022,6 +3032,14 @@ public:
|
|||
return m_hull.is_halfmanhattan ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a value indicating that the polygon is an empty one
|
||||
*/
|
||||
bool is_empty () const
|
||||
{
|
||||
return m_hull.size () == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The number of holes
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1618,18 +1618,34 @@ bool_and_or_not_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layou
|
|||
}
|
||||
}
|
||||
|
||||
db::polygon_ref_generator<TR> pr (layout, result);
|
||||
db::PolygonSplitter splitter (pr, proc->area_ratio (), proc->max_vertex_count ());
|
||||
|
||||
for (auto i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
|
||||
const TR &subject = interactions.subject_shape (i->first);
|
||||
if (others.find (subject) != others.end ()) {
|
||||
|
||||
// shortcut (and: keep, not: drop)
|
||||
// Note that we still normalize and split the polygon, so we get a uniform
|
||||
// behavior.
|
||||
if (m_is_and) {
|
||||
result.insert (subject);
|
||||
db::Polygon poly;
|
||||
subject.instantiate (poly);
|
||||
splitter.put (poly);
|
||||
}
|
||||
|
||||
} else if (i->second.empty ()) {
|
||||
|
||||
// shortcut (not: keep, and: drop)
|
||||
// Note that we still normalize and split the polygon, so we get a uniform
|
||||
// behavior.
|
||||
if (! m_is_and) {
|
||||
result.insert (subject);
|
||||
db::Polygon poly;
|
||||
subject.instantiate (poly);
|
||||
splitter.put (poly);
|
||||
}
|
||||
|
||||
} else {
|
||||
for (auto e = subject.begin_edge (); ! e.at_end(); ++e) {
|
||||
ep.insert (*e, p1);
|
||||
|
|
@ -1649,8 +1665,6 @@ bool_and_or_not_local_operation<TS, TI, TR>::do_compute_local (db::Layout *layou
|
|||
}
|
||||
|
||||
db::BooleanOp op (m_is_and ? db::BooleanOp::And : db::BooleanOp::ANotB);
|
||||
db::polygon_ref_generator<TR> pr (layout, result);
|
||||
db::PolygonSplitter splitter (pr, proc->area_ratio (), proc->max_vertex_count ());
|
||||
db::PolygonGenerator pg (splitter, true, true);
|
||||
ep.set_base_verbosity (50);
|
||||
ep.process (pg, op);
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ TEST(1)
|
|||
|
||||
EXPECT_EQ (empty == p, true);
|
||||
EXPECT_EQ (p.is_box (), false);
|
||||
EXPECT_EQ (p.is_empty (), true);
|
||||
|
||||
std::vector <db::Point> c1, c2, c3;
|
||||
c1.push_back (db::Point (0, 0));
|
||||
|
|
@ -76,6 +77,7 @@ TEST(1)
|
|||
c1.push_back (db::Point (100, 1000));
|
||||
c1.push_back (db::Point (100, 0));
|
||||
p.assign_hull (c1.begin (), c1.end ());
|
||||
EXPECT_EQ (p.is_empty (), false);
|
||||
b = p.box ();
|
||||
EXPECT_EQ (p.holes (), size_t (0));
|
||||
EXPECT_EQ (p.area (), 1000*100);
|
||||
|
|
@ -1404,3 +1406,30 @@ TEST(28)
|
|||
db::Polygon b (db::Box (-1000000000, -1000000000, 1000000000, 1000000000));
|
||||
EXPECT_EQ (b.perimeter (), 8000000000.0);
|
||||
}
|
||||
|
||||
TEST(29)
|
||||
{
|
||||
// Degenerated boxes and compress
|
||||
|
||||
db::Polygon b (db::Box (10, 20, 10, 20));
|
||||
EXPECT_EQ (b.is_empty (), false);
|
||||
EXPECT_EQ (b == db::Polygon (), false);
|
||||
EXPECT_EQ (b.to_string (), "(10,20;10,20;10,20;10,20)");
|
||||
EXPECT_EQ (double (b.area ()), 0.0);
|
||||
|
||||
b.compress (true);
|
||||
|
||||
EXPECT_EQ (b.is_empty (), true);
|
||||
EXPECT_EQ (b == db::Polygon (), true);
|
||||
|
||||
db::SimplePolygon sb (db::Box (10, 20, 10, 20));
|
||||
EXPECT_EQ (sb.is_empty (), false);
|
||||
EXPECT_EQ (sb == db::SimplePolygon (), false);
|
||||
EXPECT_EQ (sb.to_string (), "(10,20;10,20;10,20;10,20)");
|
||||
EXPECT_EQ (double (sb.area ()), 0.0);
|
||||
|
||||
sb.compress (true);
|
||||
|
||||
EXPECT_EQ (sb.is_empty (), true);
|
||||
EXPECT_EQ (sb == db::SimplePolygon (), true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1694,6 +1694,16 @@ TEST(93d_withAngle)
|
|||
run_test (_this, "93", true);
|
||||
}
|
||||
|
||||
TEST(94_texts_in_region_xor)
|
||||
{
|
||||
run_test (_this, "94", false);
|
||||
}
|
||||
|
||||
TEST(94d_texts_in_region_xor)
|
||||
{
|
||||
run_test (_this, "94", true);
|
||||
}
|
||||
|
||||
TEST(100_edge_interaction_with_count)
|
||||
{
|
||||
run_test (_this, "100", false);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
source $drc_test_source
|
||||
target $drc_test_target
|
||||
|
||||
if $drc_test_deep
|
||||
deep
|
||||
end
|
||||
|
||||
l1 = input(1, 0)
|
||||
l2 = input(2, 0)
|
||||
|
||||
l1.output(1, 0)
|
||||
l2.output(2, 0)
|
||||
|
||||
x = l1 ^ l2
|
||||
|
||||
# we detect point-like polygons here by explicitly
|
||||
# iterating. The enlargement makes sure, we have something
|
||||
# to write to the output layout.
|
||||
boxes = x.data.each.collect do |p|
|
||||
RBA::Box::new(p.bbox.enlarged(10, 10))
|
||||
end
|
||||
x.data = RBA::Region::new(boxes)
|
||||
|
||||
x.output(10, 0)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue