Addressed issue #663 by internal merging of the intruders.

This commit is contained in:
Matthias Koefferlein 2020-10-28 23:01:54 +01:00
parent c71d884e7e
commit 50ee44b6e2
9 changed files with 149 additions and 35 deletions

View File

@ -42,7 +42,7 @@
#include <sstream>
#define USE_LOCAL_PROCESSOR // @@@
#define USE_LOCAL_PROCESSOR // comment out for original implementation based on a single scan
namespace db
{
@ -419,8 +419,8 @@ AsIfFlatRegion::selected_interacting_generic (const Edges &other, bool inverse,
ResultCountingInserter inserter (counted_results);
db::box_scanner2<db::Polygon, size_t, db::Edge, size_t> scanner (report_progress (), progress_desc ());
scanner.reserve1 (size ());
scanner.reserve2 (other.size ());
scanner.reserve1 (count ());
scanner.reserve2 (other.count ());
std::auto_ptr<FlatRegion> output (new FlatRegion (false));
region_to_edge_interaction_filter<db::Polygon, db::Edge, ResultCountingInserter> filter (inserter, false, counting /*get all in counting mode*/);
@ -497,10 +497,10 @@ AsIfFlatRegion::selected_interacting_generic (const Texts &other, bool inverse,
ResultCountingInserter inserter (counted_results);
db::box_scanner2<db::Polygon, size_t, db::Text, size_t> scanner (report_progress (), progress_desc ());
scanner.reserve1 (size ());
scanner.reserve2 (other.size ());
scanner.reserve1 (count ());
scanner.reserve2 (other.count ());
region_to_text_interaction_filter<ResultCountingInserter, db::Text> filter (inserter, false, counting /*get all in counting mode*/);
region_to_text_interaction_filter<db::Polygon, db::Text, ResultCountingInserter> filter (inserter, false, counting /*get all in counting mode*/);
AddressablePolygonDelivery p (begin_merged ());
@ -694,8 +694,8 @@ AsIfFlatRegion::pull_generic (const Edges &other) const
#else
db::box_scanner2<db::Polygon, size_t, db::Edge, size_t> scanner (report_progress (), progress_desc ());
scanner.reserve1 (size ());
scanner.reserve2 (other.size ());
scanner.reserve1 (count ());
scanner.reserve2 (other.count ());
std::auto_ptr<FlatEdges> output (new FlatEdges (false));
region_to_edge_interaction_filter<db::Polygon, db::Edge, db::Shapes, db::Edge> filter (output->raw_edges (), false);
@ -749,8 +749,8 @@ AsIfFlatRegion::pull_generic (const Texts &other) const
}
db::box_scanner2<db::Polygon, size_t, db::Text, size_t> scanner (report_progress (), progress_desc ());
scanner.reserve1 (size ());
scanner.reserve2 (other.size ());
scanner.reserve1 (count ());
scanner.reserve2 (other.count ());
std::auto_ptr<FlatTexts> output (new FlatTexts (false));
region_to_text_interaction_filter<db::Polygon, db::Text, db::Shapes, db::Text> filter (output->raw_texts (), false);
@ -1030,7 +1030,7 @@ AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons,
check.set_min_projection (min_projection);
check.set_max_projection (max_projection);
db::check_local_operation<db::Polygon, db::Polygon, db::EdgePair> op (check, different_polygons, other != 0, shielded);
db::check_local_operation<db::Polygon, db::Polygon, db::EdgePair> op (check, different_polygons, other != 0, other->is_merged (), shielded);
db::local_processor<db::Polygon, db::Polygon, db::EdgePair> proc;
proc.set_base_verbosity (base_verbosity ());
@ -1050,7 +1050,7 @@ AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons,
std::auto_ptr<FlatEdgePairs> result (new FlatEdgePairs ());
db::box_scanner<db::Polygon, size_t> scanner (report_progress (), progress_desc ());
scanner.reserve (size () + (other ? other->size () : 0));
scanner.reserve (count () + (other ? other->count () : 0));
AddressablePolygonDelivery p (begin_merged ());
@ -1082,7 +1082,7 @@ AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons,
check.set_max_projection (max_projection);
edge2edge_check<db::FlatEdgePairs> edge_check (check, *result, different_polygons, other != 0 /*requires different layers*/, shielded);
poly2poly_check<db::FlatEdgePairs> poly_check (edge_check);
poly2poly_check<db::Polygon, db::FlatEdgePairs> poly_check (edge_check);
do {
scanner.process (poly_check, d, db::box_convert<db::Polygon> ());

View File

@ -1364,7 +1364,7 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons
std::auto_ptr<db::DeepEdgePairs> res (new db::DeepEdgePairs (polygons.derived ()));
db::CheckLocalOperation op (check, different_polygons, other_deep != 0, shielded);
db::CheckLocalOperation op (check, different_polygons, other_deep != 0, other->is_merged (), shielded);
db::local_processor<db::PolygonRef, db::PolygonRef, db::EdgePair> proc (const_cast<db::Layout *> (&polygons.layout ()),
const_cast<db::Cell *> (&polygons.initial_cell ()),

View File

@ -27,21 +27,6 @@
namespace db
{
// -----------------------------------------------------------------------------------------------
// class PolygonRefGenerator
PolygonRefGenerator::PolygonRefGenerator (db::Layout *layout, std::unordered_set<db::PolygonRef> &polyrefs)
: PolygonSink (), mp_layout (layout), mp_polyrefs (&polyrefs)
{
// .. nothing yet ..
}
void PolygonRefGenerator::put (const db::Polygon &polygon)
{
tl::MutexLocker locker (&mp_layout->lock ());
mp_polyrefs->insert (db::PolygonRef (polygon, mp_layout->shape_repository ()));
}
// -----------------------------------------------------------------------------------------------
// class EdgeToEdgeSetGenerator

View File

@ -30,6 +30,7 @@
#include "dbLayout.h"
#include "dbPolygonGenerators.h"
#include "dbHash.h"
#include "tlThreads.h"
#include <unordered_set>
@ -63,25 +64,65 @@ private:
const Trans m_trans;
};
class DB_PUBLIC PolygonRefGenerator
template <class T>
class DB_PUBLIC polygon_ref_generator;
template <>
class DB_PUBLIC polygon_ref_generator<db::PolygonRef>
: public PolygonSink
{
public:
/**
* @brief Constructor
*/
PolygonRefGenerator (db::Layout *layout, std::unordered_set<db::PolygonRef> &polyrefs);
polygon_ref_generator (db::Layout *layout, std::unordered_set<db::PolygonRef> &polyrefs)
: PolygonSink (), mp_layout (layout), mp_polyrefs (&polyrefs)
{
// .. nothing yet ..
}
/**
* @brief Implementation of the PolygonSink interface
*/
virtual void put (const db::Polygon &polygon);
void put (const db::Polygon &polygon)
{
tl::MutexLocker locker (&mp_layout->lock ());
mp_polyrefs->insert (db::PolygonRef (polygon, mp_layout->shape_repository ()));
}
private:
db::Layout *mp_layout;
std::unordered_set<db::PolygonRef> *mp_polyrefs;
};
template <>
class DB_PUBLIC polygon_ref_generator<db::Polygon>
: public PolygonSink
{
public:
/**
* @brief Constructor
*/
polygon_ref_generator (db::Layout *, std::unordered_set<db::Polygon> &polygons)
: mp_polygons (&polygons)
{
// .. nothing yet ..
}
/**
* @brief Implementation of the PolygonSink interface
*/
virtual void put (const db::Polygon &polygon)
{
mp_polygons->insert (polygon);
}
private:
std::unordered_set<db::Polygon> *mp_polygons;
};
typedef polygon_ref_generator<db::PolygonRef> PolygonRefGenerator;
class DB_PUBLIC EdgeToEdgeSetGenerator
: public EdgeSink
{

View File

@ -46,6 +46,31 @@ static inline const db::PolygonRef *push_polygon_to_heap (db::Layout *layout, co
return &heap.back ();
}
static inline bool needs_merge (const std::unordered_set<db::PolygonRef> &polygons)
{
if (polygons.empty ()) {
return false;
} else if (polygons.size () > 1) {
return true;
} else if (polygons.begin ()->obj ().is_box ()) {
return false;
} else {
return true;
}
}
static inline bool needs_merge (const std::unordered_set<db::Polygon> &polygons)
{
if (polygons.empty ()) {
return false;
} else if (polygons.size () > 1) {
return true;
} else if (polygons.begin ()->is_box ()) {
return false;
} else {
return true;
}
}
struct ResultInserter
{
@ -117,8 +142,8 @@ private:
// ---------------------------------------------------------------------------------------------------------------
template <class TS, class TI, class TR>
check_local_operation<TS, TI, TR>::check_local_operation (const EdgeRelationFilter &check, bool different_polygons, bool has_other, bool shielded)
: m_check (check), m_different_polygons (different_polygons), m_has_other (has_other), m_shielded (shielded)
check_local_operation<TS, TI, TR>::check_local_operation (const EdgeRelationFilter &check, bool different_polygons, bool has_other, bool other_is_merged, bool shielded)
: m_check (check), m_different_polygons (different_polygons), m_has_other (has_other), m_other_is_merged (other_is_merged), m_shielded (shielded)
{
// .. nothing yet ..
}
@ -152,6 +177,30 @@ check_local_operation<TS, TI, TR>::compute_local (db::Layout *layout, const shap
n += 2;
}
// merge the intruders to remove inner edges
if (! m_other_is_merged && needs_merge (polygons)) {
db::EdgeProcessor ep;
ep.clear ();
size_t i = 0;
for (typename std::unordered_set<TI>::const_iterator o = polygons.begin (); o != polygons.end (); ++o) {
for (typename TI::polygon_edge_iterator e = o->begin_edge (); ! e.at_end(); ++e) {
ep.insert (*e, i);
}
++i;
}
polygons.clear ();
db::polygon_ref_generator<TI> ps (layout, polygons);
db::PolygonGenerator pg (ps, false /*don't resolve holes*/, false);
db::SimpleMerge op (1 /*wc>0*/);
ep.process (pg, op);
}
n = 1;
for (typename std::unordered_set<TI>::const_iterator o = polygons.begin (); o != polygons.end (); ++o) {
scanner.insert (push_polygon_to_heap (layout, *o, heap), n);

View File

@ -27,6 +27,7 @@
#include "dbCommon.h"
#include "dbEdgePairRelations.h"
#include "dbLocalOperation.h"
#include "dbEdgeProcessor.h"
namespace db
{
@ -36,7 +37,7 @@ class check_local_operation
: public local_operation<TS, TI, TR>
{
public:
check_local_operation (const EdgeRelationFilter &check, bool different_polygons, bool has_other, bool shielded);
check_local_operation (const EdgeRelationFilter &check, bool different_polygons, bool has_other, bool other_is_merged, bool shielded);
virtual void compute_local (db::Layout * /*layout*/, const shape_interactions<TS, TI> &interactions, std::vector<std::unordered_set<TR> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const;
@ -48,6 +49,7 @@ private:
EdgeRelationFilter m_check;
bool m_different_polygons;
bool m_has_other;
bool m_other_is_merged;
bool m_shielded;
};

View File

@ -2228,3 +2228,40 @@ TEST(issue_400_with_region)
CHECKPOINT();
db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/deep_region_au400c.gds");
}
TEST(issue_663_separation_from_inside)
{
db::Layout ly;
{
std::string fn (tl::testsrc ());
fn += "/testdata/algo/issue-663.oas.gz";
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);
unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0));
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
unsigned int l10 = ly.get_layer (db::LayerProperties (10, 0));
unsigned int l11 = ly.get_layer (db::LayerProperties (11, 0));
db::DeepShapeStore dss;
db::Region r1_flat (db::RecursiveShapeIterator (ly, top_cell, l1));
db::Region r2_flat (db::RecursiveShapeIterator (ly, top_cell, l2));
db::Region r1_deep (db::RecursiveShapeIterator (ly, top_cell, l1), dss);
db::Region r2_deep (db::RecursiveShapeIterator (ly, top_cell, l2), dss);
db::EdgePairs ep_flat = r1_flat.separation_check (r2_flat, 2000);
db::EdgePairs ep_deep = r1_deep.separation_check (r2_deep, 2000);
ep_flat.insert_into_as_polygons (&ly, top_cell_index, l10, 0);
ep_deep.insert_into_as_polygons (&ly, top_cell_index, l11, 0);
CHECKPOINT();
db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/algo/deep_region_au663.gds");
}

BIN
testdata/algo/deep_region_au663.gds vendored Normal file

Binary file not shown.

BIN
testdata/algo/issue-663.oas.gz vendored Normal file

Binary file not shown.