mirror of https://github.com/KLayout/klayout.git
Addressed issue #663 by internal merging of the intruders.
This commit is contained in:
parent
c71d884e7e
commit
50ee44b6e2
|
|
@ -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> ());
|
||||
|
|
|
|||
|
|
@ -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 ()),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue