Bugfix: size method needs to produce polygon refs so the output is usable as input for booleans too.

This commit is contained in:
Matthias Koefferlein 2019-02-09 22:55:34 +01:00
parent b6dd149f53
commit 7a86f0d878
4 changed files with 82 additions and 9 deletions

View File

@ -34,6 +34,7 @@
#include "dbCellGraphUtils.h"
#include "dbPolygonTools.h"
#include "dbCellVariants.h"
#include "dbLocalOperationUtils.h"
#include "tlTimer.h"
namespace db
@ -279,8 +280,8 @@ namespace {
class ClusterMerger
{
public:
ClusterMerger (unsigned int layer, const db::hier_clusters<db::PolygonRef> &hc, bool min_coherence, bool report_progress, const std::string &progress_desc)
: m_layer (layer), mp_hc (&hc), m_min_coherence (min_coherence), m_ep (report_progress, progress_desc)
ClusterMerger (unsigned int layer, db::Layout &layout, const db::hier_clusters<db::PolygonRef> &hc, bool min_coherence, bool report_progress, const std::string &progress_desc)
: m_layer (layer), mp_layout (&layout), mp_hc (&hc), m_min_coherence (min_coherence), m_ep (report_progress, progress_desc)
{
// .. nothing yet ..
}
@ -341,8 +342,8 @@ public:
// and run the merge step
db::MergeOp op (0);
db::ShapeGenerator pc (s->second);
db::PolygonGenerator pg (pc, false /*don't resolve holes*/, m_min_coherence);
db::PolygonRefToShapesGenerator pr (mp_layout, &s->second);
db::PolygonGenerator pg (pr, false /*don't resolve holes*/, m_min_coherence);
m_ep.process (pg, op);
return s->second;
@ -352,6 +353,7 @@ private:
std::map<std::pair<size_t, db::cell_index_type>, db::Shapes> m_merged_cluster;
std::set<std::pair<size_t, db::cell_index_type> > m_done;
unsigned int m_layer;
db::Layout *mp_layout;
const db::hier_clusters<db::PolygonRef> *mp_hc;
bool m_min_coherence;
db::EdgeProcessor m_ep;
@ -380,7 +382,7 @@ DeepRegion::ensure_merged_polygons_valid () const
// NOTE: using the ClusterMerger we merge bottom-up forming bigger and bigger polygons. This is
// hopefully more efficient that collecting everything and will lead to reuse of parts.
ClusterMerger cm (m_deep_layer.layer (), hc, min_coherence (), report_progress (), progress_desc ());
ClusterMerger cm (m_deep_layer.layer (), layout, hc, min_coherence (), report_progress (), progress_desc ());
cm.set_base_verbosity (base_verbosity ());
// TODO: iterate only over the called cells?
@ -841,8 +843,8 @@ DeepRegion::sized (coord_type d, unsigned int mode) const
const db::Shapes &s = c->shapes (m_merged_polygons.layer ());
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
db::ShapeGenerator pc (st, false /*no clear - already empty*/);
db::PolygonGenerator pg2 (pc, false /*don't resolve holes*/, true /*min. coherence*/);
db::PolygonRefToShapesGenerator pr (&layout, &st);
db::PolygonGenerator pg2 (pr, false /*don't resolve holes*/, true /*min. coherence*/);
db::SizingPolygonFilter siz (pg2, d_with_mag, d_with_mag, mode);
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) {
@ -916,8 +918,8 @@ DeepRegion::sized (coord_type dx, coord_type dy, unsigned int mode) const
const db::Shapes &s = c->shapes (m_merged_polygons.layer ());
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
db::ShapeGenerator pc (st, false /*no clear - already empty*/);
db::PolygonGenerator pg2 (pc, false /*don't resolve holes*/, true /*min. coherence*/);
db::PolygonRefToShapesGenerator pr (&layout, &st);
db::PolygonGenerator pg2 (pr, false /*don't resolve holes*/, true /*min. coherence*/);
db::SizingPolygonFilter siz (pg2, dx_with_mag, dy_with_mag, mode);
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) {

View File

@ -42,6 +42,21 @@ void PolygonRefGenerator::put (const db::Polygon &polygon)
mp_polyrefs->insert (db::PolygonRef (polygon, mp_layout->shape_repository ()));
}
// -----------------------------------------------------------------------------------------------
// class PolygonRefGenerator
PolygonRefToShapesGenerator::PolygonRefToShapesGenerator (db::Layout *layout, db::Shapes *shapes)
: PolygonSink (), mp_layout (layout), mp_shapes (shapes)
{
// .. nothing yet ..
}
void PolygonRefToShapesGenerator::put (const db::Polygon &polygon)
{
tl::MutexLocker locker (&mp_layout->lock ());
mp_shapes->insert (db::PolygonRef (polygon, mp_layout->shape_repository ()));
}
// -----------------------------------------------------------------------------------------------
// class PolygonSplitter

View File

@ -55,6 +55,25 @@ private:
std::unordered_set<db::PolygonRef> *mp_polyrefs;
};
class PolygonRefToShapesGenerator
: public PolygonSink
{
public:
/**
* @brief Constructor specifying an external vector for storing the polygons
*/
PolygonRefToShapesGenerator (db::Layout *layout, db::Shapes *shapes);
/**
* @brief Implementation of the PolygonSink interface
*/
virtual void put (const db::Polygon &polygon);
private:
db::Layout *mp_layout;
db::Shapes *mp_shapes;
};
class PolygonSplitter
: public PolygonSink
{

View File

@ -536,6 +536,43 @@ TEST(9_SizingWithScaleAndXYVariants)
db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/deep_region_au9d.gds");
}
TEST(9_SizingWithBoolean)
{
db::Layout ly;
{
std::string fn (tl::testsrc ());
fn += "/testdata/algo/deep_region_area_peri_l1.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
}
db::cell_index_type top_cell_index = *ly.begin_top_down ();
db::Cell &top_cell = ly.cell (top_cell_index);
db::DeepShapeStore dss;
dss.set_max_vertex_count (4);
dss.set_threads (0);
unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0));
db::Region r1 (db::RecursiveShapeIterator (ly, top_cell, l1), dss);
db::Region r1_sized = r1.sized (2000);
r1_sized -= r1;
db::Region r1_sized_aniso = r1.sized (1000, 2000);
r1_sized_aniso -= r1;
db::Layout target;
unsigned int target_top_cell_index = target.add_cell (ly.cell_name (top_cell_index));
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (1, 0)), r1);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (11, 0)), r1_sized);
target.insert (target_top_cell_index, target.get_layer (db::LayerProperties (12, 0)), r1_sized_aniso);
CHECKPOINT();
db::compare_layouts (_this, target, tl::testsrc () + "/testdata/algo/deep_region_au9e.gds");
}
TEST(100_Integration)
{
db::Layout ly;