mirror of https://github.com/KLayout/klayout.git
Bugfix: size method needs to produce polygon refs so the output is usable as input for booleans too.
This commit is contained in:
parent
b6dd149f53
commit
7a86f0d878
|
|
@ -34,6 +34,7 @@
|
||||||
#include "dbCellGraphUtils.h"
|
#include "dbCellGraphUtils.h"
|
||||||
#include "dbPolygonTools.h"
|
#include "dbPolygonTools.h"
|
||||||
#include "dbCellVariants.h"
|
#include "dbCellVariants.h"
|
||||||
|
#include "dbLocalOperationUtils.h"
|
||||||
#include "tlTimer.h"
|
#include "tlTimer.h"
|
||||||
|
|
||||||
namespace db
|
namespace db
|
||||||
|
|
@ -279,8 +280,8 @@ namespace {
|
||||||
class ClusterMerger
|
class ClusterMerger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ClusterMerger (unsigned int layer, const db::hier_clusters<db::PolygonRef> &hc, bool min_coherence, bool report_progress, const std::string &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_hc (&hc), m_min_coherence (min_coherence), m_ep (report_progress, progress_desc)
|
: m_layer (layer), mp_layout (&layout), mp_hc (&hc), m_min_coherence (min_coherence), m_ep (report_progress, progress_desc)
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
@ -341,8 +342,8 @@ public:
|
||||||
|
|
||||||
// and run the merge step
|
// and run the merge step
|
||||||
db::MergeOp op (0);
|
db::MergeOp op (0);
|
||||||
db::ShapeGenerator pc (s->second);
|
db::PolygonRefToShapesGenerator pr (mp_layout, &s->second);
|
||||||
db::PolygonGenerator pg (pc, false /*don't resolve holes*/, m_min_coherence);
|
db::PolygonGenerator pg (pr, false /*don't resolve holes*/, m_min_coherence);
|
||||||
m_ep.process (pg, op);
|
m_ep.process (pg, op);
|
||||||
|
|
||||||
return s->second;
|
return s->second;
|
||||||
|
|
@ -352,6 +353,7 @@ private:
|
||||||
std::map<std::pair<size_t, db::cell_index_type>, db::Shapes> m_merged_cluster;
|
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;
|
std::set<std::pair<size_t, db::cell_index_type> > m_done;
|
||||||
unsigned int m_layer;
|
unsigned int m_layer;
|
||||||
|
db::Layout *mp_layout;
|
||||||
const db::hier_clusters<db::PolygonRef> *mp_hc;
|
const db::hier_clusters<db::PolygonRef> *mp_hc;
|
||||||
bool m_min_coherence;
|
bool m_min_coherence;
|
||||||
db::EdgeProcessor m_ep;
|
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
|
// 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.
|
// 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 ());
|
cm.set_base_verbosity (base_verbosity ());
|
||||||
|
|
||||||
// TODO: iterate only over the called cells?
|
// 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 ());
|
const db::Shapes &s = c->shapes (m_merged_polygons.layer ());
|
||||||
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
||||||
|
|
||||||
db::ShapeGenerator pc (st, false /*no clear - already empty*/);
|
db::PolygonRefToShapesGenerator pr (&layout, &st);
|
||||||
db::PolygonGenerator pg2 (pc, false /*don't resolve holes*/, true /*min. coherence*/);
|
db::PolygonGenerator pg2 (pr, false /*don't resolve holes*/, true /*min. coherence*/);
|
||||||
db::SizingPolygonFilter siz (pg2, d_with_mag, d_with_mag, mode);
|
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) {
|
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 ());
|
const db::Shapes &s = c->shapes (m_merged_polygons.layer ());
|
||||||
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
||||||
|
|
||||||
db::ShapeGenerator pc (st, false /*no clear - already empty*/);
|
db::PolygonRefToShapesGenerator pr (&layout, &st);
|
||||||
db::PolygonGenerator pg2 (pc, false /*don't resolve holes*/, true /*min. coherence*/);
|
db::PolygonGenerator pg2 (pr, false /*don't resolve holes*/, true /*min. coherence*/);
|
||||||
db::SizingPolygonFilter siz (pg2, dx_with_mag, dy_with_mag, mode);
|
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) {
|
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) {
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,21 @@ void PolygonRefGenerator::put (const db::Polygon &polygon)
|
||||||
mp_polyrefs->insert (db::PolygonRef (polygon, mp_layout->shape_repository ()));
|
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
|
// class PolygonSplitter
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,25 @@ private:
|
||||||
std::unordered_set<db::PolygonRef> *mp_polyrefs;
|
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
|
class PolygonSplitter
|
||||||
: public PolygonSink
|
: public PolygonSink
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -536,6 +536,43 @@ TEST(9_SizingWithScaleAndXYVariants)
|
||||||
db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/deep_region_au9d.gds");
|
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)
|
TEST(100_Integration)
|
||||||
{
|
{
|
||||||
db::Layout ly;
|
db::Layout ly;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue