mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
a431f70ad4
commit
1e323a0421
|
|
@ -28,6 +28,7 @@
|
|||
#include "dbEmptyEdges.h"
|
||||
#include "dbEdges.h"
|
||||
#include "dbEdgesUtils.h"
|
||||
#include "dbEdgesLocalOperations.h"
|
||||
#include "dbEdgeBoolean.h"
|
||||
#include "dbBoxConvert.h"
|
||||
#include "dbRegion.h"
|
||||
|
|
@ -39,6 +40,7 @@
|
|||
#include "dbPolygonGenerators.h"
|
||||
#include "dbPolygon.h"
|
||||
#include "dbPath.h"
|
||||
#include "dbHierProcessor.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
|
|
@ -94,104 +96,107 @@ AsIfFlatEdges::to_string (size_t nmax) const
|
|||
return os.str ();
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::selected_interacting_generic (const Region &other, EdgeInteractionMode mode, bool inverse) const
|
||||
namespace {
|
||||
|
||||
class OutputPairHolder
|
||||
{
|
||||
// shortcuts
|
||||
if (other.empty () || empty ()) {
|
||||
return ((mode == EdgesOutside) == inverse) ? new EmptyEdges () : clone ();
|
||||
}
|
||||
public:
|
||||
OutputPairHolder (int inverse, bool merged_semantics)
|
||||
{
|
||||
m_e1.reset (new FlatEdges (merged_semantics));
|
||||
m_results.push_back (& m_e1->raw_edges ());
|
||||
|
||||
db::box_scanner2<db::Edge, size_t, db::Polygon, size_t> scanner (report_progress (), progress_desc ());
|
||||
|
||||
AddressableEdgeDelivery e (begin_merged ());
|
||||
|
||||
for ( ; ! e.at_end (); ++e) {
|
||||
scanner.insert1 (e.operator-> (), 0);
|
||||
}
|
||||
|
||||
AddressablePolygonDelivery p = (mode == EdgesInside ? other.addressable_merged_polygons () : other.addressable_polygons ());
|
||||
|
||||
for ( ; ! p.at_end (); ++p) {
|
||||
scanner.insert2 (p.operator-> (), 1);
|
||||
}
|
||||
|
||||
std::unique_ptr<FlatEdges> output (new FlatEdges (true));
|
||||
|
||||
if (! inverse) {
|
||||
|
||||
edge_to_region_interaction_filter<FlatEdges> filter (output.get (), mode);
|
||||
scanner.process (filter, 1, db::box_convert<db::Edge> (), db::box_convert<db::Polygon> ());
|
||||
|
||||
} else {
|
||||
|
||||
std::set<db::Edge> result;
|
||||
edge_to_region_interaction_filter<std::set<db::Edge> > filter (&result, mode);
|
||||
scanner.process (filter, 1, db::box_convert<db::Edge> (), db::box_convert<db::Polygon> ());
|
||||
|
||||
for (EdgesIterator o (begin_merged ()); ! o.at_end (); ++o) {
|
||||
if (result.find (*o) == result.end ()) {
|
||||
output->insert (*o);
|
||||
}
|
||||
if (inverse == 0) {
|
||||
m_e2.reset (new FlatEdges (merged_semantics));
|
||||
m_results.push_back (& m_e2->raw_edges ());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return output.release ();
|
||||
std::pair<EdgesDelegate *, EdgesDelegate *> region_pair ()
|
||||
{
|
||||
return std::make_pair (m_e1.release (), m_e2.release ());
|
||||
}
|
||||
|
||||
const std::vector<db::Shapes *> &results () { return m_results; }
|
||||
|
||||
private:
|
||||
std::unique_ptr<FlatEdges> m_e1, m_e2;
|
||||
std::vector<db::Shapes *> m_results;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::selected_interacting_generic (const Edges &edges, EdgeInteractionMode mode, bool inverse) const
|
||||
AsIfFlatEdges::selected_interacting_generic (const Region &other, EdgeInteractionMode mode, bool inverse, size_t min_count, size_t max_count) const
|
||||
{
|
||||
min_count = std::max (size_t (1), min_count);
|
||||
|
||||
// shortcuts
|
||||
if (edges.empty () || empty ()) {
|
||||
if (max_count < min_count || other.empty () || empty ()) {
|
||||
return ((mode == EdgesOutside) == inverse) ? new EmptyEdges () : clone ();
|
||||
}
|
||||
|
||||
db::box_scanner<db::Edge, size_t> scanner (report_progress (), progress_desc ());
|
||||
bool counting = !(min_count == 1 && max_count == std::numeric_limits<size_t>::max ());
|
||||
OutputPairHolder oph (inverse ? 1 : -1, merged_semantics () || is_merged ());
|
||||
|
||||
AddressableEdgeDelivery e (begin_merged ());
|
||||
db::EdgesIterator edges (begin_merged ());
|
||||
|
||||
for ( ; ! e.at_end (); ++e) {
|
||||
scanner.insert (e.operator-> (), 0);
|
||||
db::edge_to_polygon_interacting_local_operation<db::Polygon> op (mode, inverse ? db::edge_to_polygon_interacting_local_operation<db::Polygon>::Inverse : db::edge_to_polygon_interacting_local_operation<db::Polygon>::Normal);
|
||||
|
||||
db::local_processor<db::Edge, db::Polygon, db::Edge> proc;
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
proc.set_description (progress_desc ());
|
||||
proc.set_report_progress (report_progress ());
|
||||
|
||||
std::vector<generic_shape_iterator<db::Polygon> > others;
|
||||
// NOTE: with counting the other region needs to be merged
|
||||
others.push_back (counting ? other.begin_merged () : other.begin ());
|
||||
|
||||
proc.run_flat (edges, others, std::vector<bool> (), &op, oph.results ());
|
||||
|
||||
return oph.region_pair ().first;
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::selected_interacting_generic (const Edges &other, EdgeInteractionMode mode, bool inverse, size_t min_count, size_t max_count) const
|
||||
{
|
||||
min_count = std::max (size_t (1), min_count);
|
||||
|
||||
// @@@
|
||||
// shortcuts
|
||||
if (max_count < min_count || other.empty () || empty ()) {
|
||||
return ((mode == EdgesOutside) == inverse) ? new EmptyEdges () : clone ();
|
||||
}
|
||||
|
||||
// NOTE: "inside" needs merged edges for the other edges as the algorithm works edge by edge
|
||||
AddressableEdgeDelivery ee = (mode == EdgesInside ? edges.addressable_merged_edges () : edges.addressable_edges ());
|
||||
bool counting = !(min_count == 1 && max_count == std::numeric_limits<size_t>::max ());
|
||||
OutputPairHolder oph (inverse ? 1 : -1, merged_semantics () || is_merged ());
|
||||
|
||||
for ( ; ! ee.at_end (); ++ee) {
|
||||
scanner.insert (ee.operator-> (), 1);
|
||||
}
|
||||
db::EdgesIterator edges (begin_merged ());
|
||||
|
||||
std::unique_ptr<FlatEdges> output (new FlatEdges (true));
|
||||
db::Edge2EdgeInteractingLocalOperation op (mode, inverse ? db::Edge2EdgeInteractingLocalOperation::Inverse : db::Edge2EdgeInteractingLocalOperation::Normal);
|
||||
|
||||
if (! inverse) {
|
||||
db::local_processor<db::Edge, db::Edge, db::Edge> proc;
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
proc.set_description (progress_desc ());
|
||||
proc.set_report_progress (report_progress ());
|
||||
|
||||
edge_interaction_filter<FlatEdges> filter (*output, mode);
|
||||
scanner.process (filter, 1, db::box_convert<db::Edge> ());
|
||||
std::vector<generic_shape_iterator<db::Edge> > others;
|
||||
// NOTE: with counting the other edge collection needs to be merged
|
||||
others.push_back (counting ? other.begin_merged () : other.begin ());
|
||||
|
||||
} else {
|
||||
proc.run_flat (edges, others, std::vector<bool> (), &op, oph.results ());
|
||||
|
||||
std::set<db::Edge> result;
|
||||
edge_interaction_filter<std::set<db::Edge> > filter (result, mode);
|
||||
scanner.process (filter, 1, db::box_convert<db::Edge> ());
|
||||
|
||||
for (EdgesIterator o (begin_merged ()); ! o.at_end (); ++o) {
|
||||
if (result.find (*o) == result.end ()) {
|
||||
output->insert (*o);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return output.release ();
|
||||
return oph.region_pair ().first;
|
||||
}
|
||||
|
||||
std::pair<EdgesDelegate *, EdgesDelegate *>
|
||||
AsIfFlatEdges::selected_interacting_pair_generic (const Region ®ion, EdgeInteractionMode mode) const
|
||||
AsIfFlatEdges::selected_interacting_pair_generic (const Region &other, EdgeInteractionMode mode, size_t min_count, size_t max_count) const
|
||||
{
|
||||
min_count = std::max (size_t (1), min_count);
|
||||
|
||||
// @@@
|
||||
// shortcuts
|
||||
if (region.empty () || empty ()) {
|
||||
if (max_count < min_count || other.empty () || empty ()) {
|
||||
if (mode != EdgesOutside) {
|
||||
return std::make_pair (new EmptyEdges (), clone ());
|
||||
} else {
|
||||
|
|
@ -199,43 +204,35 @@ AsIfFlatEdges::selected_interacting_pair_generic (const Region ®ion, EdgeInte
|
|||
}
|
||||
}
|
||||
|
||||
db::box_scanner2<db::Edge, size_t, db::Polygon, size_t> scanner (report_progress (), progress_desc ());
|
||||
bool counting = !(min_count == 1 && max_count == std::numeric_limits<size_t>::max ());
|
||||
OutputPairHolder oph (0, merged_semantics () || is_merged ());
|
||||
|
||||
AddressableEdgeDelivery e (begin_merged ());
|
||||
db::EdgesIterator edges (begin_merged ());
|
||||
|
||||
for ( ; ! e.at_end (); ++e) {
|
||||
scanner.insert1 (e.operator-> (), 0);
|
||||
}
|
||||
db::edge_to_polygon_interacting_local_operation<db::Polygon> op (mode, db::edge_to_polygon_interacting_local_operation<db::Polygon>::Both);
|
||||
|
||||
AddressablePolygonDelivery p = region.addressable_merged_polygons ();
|
||||
db::local_processor<db::Edge, db::Polygon, db::Edge> proc;
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
proc.set_description (progress_desc ());
|
||||
proc.set_report_progress (report_progress ());
|
||||
|
||||
for ( ; ! p.at_end (); ++p) {
|
||||
scanner.insert2 (p.operator-> (), 1);
|
||||
}
|
||||
std::vector<generic_shape_iterator<db::Polygon> > others;
|
||||
// NOTE: with counting the other region needs to be merged
|
||||
others.push_back (counting ? other.begin_merged () : other.begin ());
|
||||
|
||||
std::unique_ptr<FlatEdges> output (new FlatEdges (true));
|
||||
std::unique_ptr<FlatEdges> output2 (new FlatEdges (true));
|
||||
proc.run_flat (edges, others, std::vector<bool> (), &op, oph.results ());
|
||||
|
||||
std::set<db::Edge> result;
|
||||
edge_to_region_interaction_filter<std::set<db::Edge> > filter (&result, mode);
|
||||
scanner.process (filter, 1, db::box_convert<db::Edge> (), db::box_convert<db::Polygon> ());
|
||||
|
||||
for (EdgesIterator o (begin_merged ()); ! o.at_end (); ++o) {
|
||||
if (result.find (*o) == result.end ()) {
|
||||
output2->insert (*o);
|
||||
} else {
|
||||
output->insert (*o);
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_pair (output.release (), output2.release ());
|
||||
return oph.region_pair ();
|
||||
}
|
||||
|
||||
std::pair<EdgesDelegate *, EdgesDelegate *>
|
||||
AsIfFlatEdges::selected_interacting_pair_generic (const Edges &other, EdgeInteractionMode mode) const
|
||||
AsIfFlatEdges::selected_interacting_pair_generic (const Edges &other, EdgeInteractionMode mode, size_t min_count, size_t max_count) const
|
||||
{
|
||||
min_count = std::max (size_t (1), min_count);
|
||||
|
||||
// @@@
|
||||
// shortcuts
|
||||
if (other.empty () || empty ()) {
|
||||
if (max_count < min_count || other.empty () || empty ()) {
|
||||
if (mode != EdgesOutside) {
|
||||
return std::make_pair (new EmptyEdges (), clone ());
|
||||
} else {
|
||||
|
|
@ -243,36 +240,25 @@ AsIfFlatEdges::selected_interacting_pair_generic (const Edges &other, EdgeIntera
|
|||
}
|
||||
}
|
||||
|
||||
db::box_scanner<db::Edge, size_t> scanner (report_progress (), progress_desc ());
|
||||
bool counting = !(min_count == 1 && max_count == std::numeric_limits<size_t>::max ());
|
||||
OutputPairHolder oph (0, merged_semantics () || is_merged ());
|
||||
|
||||
AddressableEdgeDelivery e (begin_merged ());
|
||||
db::EdgesIterator edges (begin_merged ());
|
||||
|
||||
for ( ; ! e.at_end (); ++e) {
|
||||
scanner.insert (e.operator-> (), 0);
|
||||
}
|
||||
db::Edge2EdgeInteractingLocalOperation op (mode, db::Edge2EdgeInteractingLocalOperation::Both);
|
||||
|
||||
AddressableEdgeDelivery ee = other.addressable_merged_edges ();
|
||||
db::local_processor<db::Edge, db::Edge, db::Edge> proc;
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
proc.set_description (progress_desc ());
|
||||
proc.set_report_progress (report_progress ());
|
||||
|
||||
for ( ; ! ee.at_end (); ++ee) {
|
||||
scanner.insert (ee.operator-> (), 1);
|
||||
}
|
||||
std::vector<generic_shape_iterator<db::Edge> > others;
|
||||
// NOTE: with counting the other edge collection needs to be merged
|
||||
others.push_back (counting ? other.begin_merged () : other.begin ());
|
||||
|
||||
std::unique_ptr<FlatEdges> output (new FlatEdges (true));
|
||||
std::unique_ptr<FlatEdges> output2 (new FlatEdges (true));
|
||||
proc.run_flat (edges, others, std::vector<bool> (), &op, oph.results ());
|
||||
|
||||
std::set<db::Edge> results;
|
||||
edge_interaction_filter<std::set<db::Edge> > filter (results, mode);
|
||||
scanner.process (filter, 1, db::box_convert<db::Edge> ());
|
||||
|
||||
for (EdgesIterator o (begin_merged ()); ! o.at_end (); ++o) {
|
||||
if (results.find (*o) == results.end ()) {
|
||||
output2->insert (*o);
|
||||
} else {
|
||||
output->insert (*o);
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_pair (output.release (), output2.release ());
|
||||
return oph.region_pair ();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -343,111 +329,111 @@ AsIfFlatEdges::pull_interacting (const Region &other) const
|
|||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::selected_interacting (const Edges &other) const
|
||||
AsIfFlatEdges::selected_interacting (const Edges &other, size_t min_count, size_t max_count) const
|
||||
{
|
||||
return selected_interacting_generic (other, EdgesInteract, false);
|
||||
return selected_interacting_generic (other, EdgesInteract, false, min_count, max_count);
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::selected_not_interacting (const Edges &other) const
|
||||
AsIfFlatEdges::selected_not_interacting (const Edges &other, size_t min_count, size_t max_count) const
|
||||
{
|
||||
return selected_interacting_generic (other, EdgesInteract, true);
|
||||
return selected_interacting_generic (other, EdgesInteract, true, min_count, max_count);
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::selected_interacting (const Region &other) const
|
||||
AsIfFlatEdges::selected_interacting (const Region &other, size_t min_count, size_t max_count) const
|
||||
{
|
||||
return selected_interacting_generic (other, EdgesInteract, false);
|
||||
return selected_interacting_generic (other, EdgesInteract, false, min_count, max_count);
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::selected_not_interacting (const Region &other) const
|
||||
AsIfFlatEdges::selected_not_interacting (const Region &other, size_t min_count, size_t max_count) const
|
||||
{
|
||||
return selected_interacting_generic (other, EdgesInteract, true);
|
||||
return selected_interacting_generic (other, EdgesInteract, true, min_count, max_count);
|
||||
}
|
||||
|
||||
std::pair<EdgesDelegate *, EdgesDelegate *>
|
||||
AsIfFlatEdges::selected_interacting_pair (const Region &other) const
|
||||
AsIfFlatEdges::selected_interacting_pair (const Region &other, size_t min_count, size_t max_count) const
|
||||
{
|
||||
return selected_interacting_pair_generic (other, EdgesInteract);
|
||||
return selected_interacting_pair_generic (other, EdgesInteract, min_count, max_count);
|
||||
}
|
||||
|
||||
std::pair<EdgesDelegate *, EdgesDelegate *>
|
||||
AsIfFlatEdges::selected_interacting_pair (const Edges &other) const
|
||||
AsIfFlatEdges::selected_interacting_pair (const Edges &other, size_t min_count, size_t max_count) const
|
||||
{
|
||||
return selected_interacting_pair_generic (other, EdgesInteract);
|
||||
return selected_interacting_pair_generic (other, EdgesInteract, min_count, max_count);
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::selected_outside (const Region &other) const
|
||||
{
|
||||
return selected_interacting_generic (other, EdgesOutside, false);
|
||||
return selected_interacting_generic (other, EdgesOutside, false, size_t (0), std::numeric_limits<size_t>::max ());
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::selected_not_outside (const Region &other) const
|
||||
{
|
||||
return selected_interacting_generic (other, EdgesOutside, true);
|
||||
return selected_interacting_generic (other, EdgesOutside, true, size_t (0), std::numeric_limits<size_t>::max ());
|
||||
}
|
||||
|
||||
std::pair<EdgesDelegate *, EdgesDelegate *>
|
||||
AsIfFlatEdges::selected_outside_pair (const Region &other) const
|
||||
{
|
||||
return selected_interacting_pair_generic (other, EdgesOutside);
|
||||
return selected_interacting_pair_generic (other, EdgesOutside, size_t (0), std::numeric_limits<size_t>::max ());
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::selected_inside (const Region &other) const
|
||||
{
|
||||
return selected_interacting_generic (other, EdgesInside, false);
|
||||
return selected_interacting_generic (other, EdgesInside, false, size_t (0), std::numeric_limits<size_t>::max ());
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::selected_not_inside (const Region &other) const
|
||||
{
|
||||
return selected_interacting_generic (other, EdgesInside, true);
|
||||
return selected_interacting_generic (other, EdgesInside, true, size_t (0), std::numeric_limits<size_t>::max ());
|
||||
}
|
||||
|
||||
std::pair<EdgesDelegate *, EdgesDelegate *>
|
||||
AsIfFlatEdges::selected_inside_pair (const Region &other) const
|
||||
{
|
||||
return selected_interacting_pair_generic (other, EdgesInside);
|
||||
return selected_interacting_pair_generic (other, EdgesInside, size_t (0), std::numeric_limits<size_t>::max ());
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::selected_outside (const Edges &other) const
|
||||
{
|
||||
return selected_interacting_generic (other, EdgesOutside, false);
|
||||
return selected_interacting_generic (other, EdgesOutside, false, size_t (0), std::numeric_limits<size_t>::max ());
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::selected_not_outside (const Edges &other) const
|
||||
{
|
||||
return selected_interacting_generic (other, EdgesOutside, true);
|
||||
return selected_interacting_generic (other, EdgesOutside, true, size_t (0), std::numeric_limits<size_t>::max ());
|
||||
}
|
||||
|
||||
std::pair<EdgesDelegate *, EdgesDelegate *>
|
||||
AsIfFlatEdges::selected_outside_pair (const Edges &other) const
|
||||
{
|
||||
return selected_interacting_pair_generic (other, EdgesOutside);
|
||||
return selected_interacting_pair_generic (other, EdgesOutside, size_t (0), std::numeric_limits<size_t>::max ());
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::selected_inside (const Edges &other) const
|
||||
{
|
||||
return selected_interacting_generic (other, EdgesInside, false);
|
||||
return selected_interacting_generic (other, EdgesInside, false, size_t (0), std::numeric_limits<size_t>::max ());
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::selected_not_inside (const Edges &other) const
|
||||
{
|
||||
return selected_interacting_generic (other, EdgesInside, true);
|
||||
return selected_interacting_generic (other, EdgesInside, true, size_t (0), std::numeric_limits<size_t>::max ());
|
||||
}
|
||||
|
||||
std::pair<EdgesDelegate *, EdgesDelegate *>
|
||||
AsIfFlatEdges::selected_inside_pair (const Edges &other) const
|
||||
{
|
||||
return selected_interacting_pair_generic (other, EdgesInside);
|
||||
return selected_interacting_pair_generic (other, EdgesInside, size_t (0), std::numeric_limits<size_t>::max ());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -183,12 +183,12 @@ public:
|
|||
|
||||
virtual EdgesDelegate *pull_interacting (const Edges &) const;
|
||||
virtual RegionDelegate *pull_interacting (const Region &) const;
|
||||
virtual EdgesDelegate *selected_interacting (const Edges &) const;
|
||||
virtual EdgesDelegate *selected_not_interacting (const Edges &) const;
|
||||
virtual EdgesDelegate *selected_interacting (const Region &) const;
|
||||
virtual EdgesDelegate *selected_not_interacting (const Region &) const;
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair (const Region &other) const;
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair (const Edges &other) const;
|
||||
virtual EdgesDelegate *selected_interacting (const Edges &, size_t min_count, size_t max_count) const;
|
||||
virtual EdgesDelegate *selected_not_interacting (const Edges &, size_t min_count, size_t max_count) const;
|
||||
virtual EdgesDelegate *selected_interacting (const Region &, size_t min_count, size_t max_count) const;
|
||||
virtual EdgesDelegate *selected_not_interacting (const Region &, size_t min_count, size_t max_count) const;
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair (const Region &other, size_t min_count, size_t max_count) const;
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair (const Edges &other, size_t min_count, size_t max_count) const;
|
||||
|
||||
virtual EdgesDelegate *selected_outside (const Edges &other) const;
|
||||
virtual EdgesDelegate *selected_not_outside (const Edges &other) const;
|
||||
|
|
@ -217,10 +217,10 @@ protected:
|
|||
EdgePairsDelegate *run_check (db::edge_relation_type rel, const Edges *other, db::Coord d, const EdgesCheckOptions &options) const;
|
||||
virtual EdgesDelegate *pull_generic (const Edges &edges) const;
|
||||
virtual RegionDelegate *pull_generic (const Region ®ion) const;
|
||||
virtual EdgesDelegate *selected_interacting_generic (const Edges &edges, EdgeInteractionMode mode, bool inverse) const;
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair_generic (const Edges &edges, EdgeInteractionMode mode) const;
|
||||
virtual EdgesDelegate *selected_interacting_generic (const Region ®ion, EdgeInteractionMode mode, bool inverse) const;
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair_generic (const Region ®ion, EdgeInteractionMode mode) const;
|
||||
virtual EdgesDelegate *selected_interacting_generic (const Edges &edges, EdgeInteractionMode mode, bool inverse, size_t min_count, size_t max_count) const;
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair_generic (const Edges &edges, EdgeInteractionMode mode, size_t min_count, size_t max_count) const;
|
||||
virtual EdgesDelegate *selected_interacting_generic (const Region ®ion, EdgeInteractionMode mode, bool inverse, size_t min_count, size_t max_count) const;
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair_generic (const Region ®ion, EdgeInteractionMode mode, size_t min_count, size_t max_count) const;
|
||||
AsIfFlatEdges &operator= (const AsIfFlatEdges &other);
|
||||
AsIfFlatEdges (const AsIfFlatEdges &other);
|
||||
|
||||
|
|
|
|||
|
|
@ -1354,363 +1354,10 @@ RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_t
|
|||
return res.release ();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class Edge2EdgeInteractingLocalOperation
|
||||
: public local_operation<db::Edge, db::Edge, db::Edge>
|
||||
{
|
||||
public:
|
||||
enum output_mode_t { Normal, Inverse, Both };
|
||||
|
||||
Edge2EdgeInteractingLocalOperation (EdgeInteractionMode mode, output_mode_t output_mode)
|
||||
: m_mode (mode), m_output_mode (output_mode)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual db::Coord dist () const
|
||||
{
|
||||
// touching is sufficient
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase * /*proc*/) const
|
||||
{
|
||||
tl_assert (results.size () == (m_output_mode == Both ? 2 : 1));
|
||||
|
||||
std::unordered_set<db::Edge> &result = results.front ();
|
||||
|
||||
std::unordered_set<db::Edge> *result2 = 0;
|
||||
if (m_output_mode == Both) {
|
||||
result2 = &results[1];
|
||||
}
|
||||
|
||||
db::box_scanner<db::Edge, size_t> scanner;
|
||||
|
||||
std::set<db::Edge> others;
|
||||
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (shape_interactions<db::Edge, db::Edge>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
others.insert (interactions.intruder_shape (*j).second);
|
||||
}
|
||||
}
|
||||
|
||||
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const db::Edge &subject = interactions.subject_shape (i->first);
|
||||
scanner.insert (&subject, 0);
|
||||
}
|
||||
|
||||
for (std::set<db::Edge>::const_iterator o = others.begin (); o != others.end (); ++o) {
|
||||
scanner.insert (o.operator-> (), 1);
|
||||
}
|
||||
|
||||
if (m_output_mode == Inverse || m_output_mode == Both) {
|
||||
|
||||
std::unordered_set<db::Edge> interacting;
|
||||
edge_interaction_filter<std::unordered_set<db::Edge> > filter (interacting, m_mode);
|
||||
scanner.process (filter, 1, db::box_convert<db::Edge> ());
|
||||
|
||||
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
|
||||
const db::Edge &subject = interactions.subject_shape (i->first);
|
||||
if (interacting.find (subject) == interacting.end ()) {
|
||||
if (m_output_mode != Both) {
|
||||
result.insert (subject);
|
||||
} else {
|
||||
result2->insert (subject);
|
||||
}
|
||||
} else if (m_output_mode == Both) {
|
||||
result.insert (subject);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
edge_interaction_filter<std::unordered_set<db::Edge> > filter (result, m_mode);
|
||||
scanner.process (filter, 1, db::box_convert<db::Edge> ());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
virtual OnEmptyIntruderHint on_empty_intruder_hint () const
|
||||
{
|
||||
if (m_mode == EdgesOutside) {
|
||||
return m_output_mode == Both ? Copy : (m_output_mode == Inverse ? Drop : Copy);
|
||||
} else {
|
||||
return m_output_mode == Both ? CopyToSecond : (m_output_mode == Inverse ? Copy : Drop);
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::string description () const
|
||||
{
|
||||
return tl::to_string (tr ("Select interacting edges"));
|
||||
}
|
||||
|
||||
private:
|
||||
EdgeInteractionMode m_mode;
|
||||
output_mode_t m_output_mode;
|
||||
};
|
||||
|
||||
class Edge2EdgePullLocalOperation
|
||||
: public local_operation<db::Edge, db::Edge, db::Edge>
|
||||
{
|
||||
public:
|
||||
Edge2EdgePullLocalOperation ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual db::Coord dist () const
|
||||
{
|
||||
// touching is sufficient
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase * /*proc*/) const
|
||||
{
|
||||
tl_assert (results.size () == 1);
|
||||
std::unordered_set<db::Edge> &result = results.front ();
|
||||
|
||||
db::box_scanner<db::Edge, size_t> scanner;
|
||||
|
||||
std::set<db::Edge> others;
|
||||
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (shape_interactions<db::Edge, db::Edge>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
others.insert (interactions.intruder_shape (*j).second);
|
||||
}
|
||||
}
|
||||
|
||||
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const db::Edge &subject = interactions.subject_shape (i->first);
|
||||
scanner.insert (&subject, 1);
|
||||
}
|
||||
|
||||
for (std::set<db::Edge>::const_iterator o = others.begin (); o != others.end (); ++o) {
|
||||
scanner.insert (o.operator-> (), 0);
|
||||
}
|
||||
|
||||
edge_interaction_filter<std::unordered_set<db::Edge> > filter (result, EdgesInteract);
|
||||
scanner.process (filter, 1, db::box_convert<db::Edge> ());
|
||||
|
||||
}
|
||||
|
||||
virtual OnEmptyIntruderHint on_empty_intruder_hint () const
|
||||
{
|
||||
return Drop;
|
||||
}
|
||||
|
||||
virtual std::string description () const
|
||||
{
|
||||
return tl::to_string (tr ("Select interacting edges from other"));
|
||||
}
|
||||
};
|
||||
|
||||
class Edge2PolygonInteractingLocalOperation
|
||||
: public local_operation<db::Edge, db::PolygonRef, db::Edge>
|
||||
{
|
||||
public:
|
||||
enum output_mode_t { Normal, Inverse, Both };
|
||||
|
||||
Edge2PolygonInteractingLocalOperation (EdgeInteractionMode mode, output_mode_t output_mode)
|
||||
: m_mode (mode), m_output_mode (output_mode)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual db::Coord dist () const
|
||||
{
|
||||
// touching is sufficient
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase * /*proc*/) const
|
||||
{
|
||||
tl_assert (results.size () == size_t (m_output_mode == Both ? 2 : 1));
|
||||
|
||||
std::unordered_set<db::Edge> &result = results.front ();
|
||||
|
||||
std::unordered_set<db::Edge> *result2 = 0;
|
||||
if (m_output_mode == Both) {
|
||||
result2 = &results[1];
|
||||
}
|
||||
|
||||
db::box_scanner2<db::Edge, size_t, db::Polygon, size_t> scanner;
|
||||
|
||||
std::set<db::PolygonRef> others;
|
||||
for (shape_interactions<db::Edge, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (shape_interactions<db::Edge, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
others.insert (interactions.intruder_shape (*j).second);
|
||||
}
|
||||
}
|
||||
|
||||
for (shape_interactions<db::Edge, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const db::Edge &subject = interactions.subject_shape (i->first);
|
||||
scanner.insert1 (&subject, 0);
|
||||
}
|
||||
|
||||
std::list<db::Polygon> heap;
|
||||
for (std::set<db::PolygonRef>::const_iterator o = others.begin (); o != others.end (); ++o) {
|
||||
heap.push_back (o->obj ().transformed (o->trans ()));
|
||||
scanner.insert2 (& heap.back (), 1);
|
||||
}
|
||||
|
||||
if (m_output_mode == Inverse || m_output_mode == Both) {
|
||||
|
||||
std::unordered_set<db::Edge> interacting;
|
||||
edge_to_region_interaction_filter<std::unordered_set<db::Edge> > filter (&interacting, m_mode);
|
||||
scanner.process (filter, 1, db::box_convert<db::Edge> (), db::box_convert<db::Polygon> ());
|
||||
|
||||
for (shape_interactions<db::Edge, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
|
||||
const db::Edge &subject = interactions.subject_shape (i->first);
|
||||
|
||||
if (interacting.find (subject) == interacting.end ()) {
|
||||
if (m_output_mode != Both) {
|
||||
result.insert (subject);
|
||||
} else {
|
||||
result2->insert (subject);
|
||||
}
|
||||
} else if (m_output_mode == Both) {
|
||||
result.insert (subject);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
edge_to_region_interaction_filter<std::unordered_set<db::Edge> > filter (&result, m_mode);
|
||||
scanner.process (filter, 1, db::box_convert<db::Edge> (), db::box_convert<db::Polygon> ());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
virtual OnEmptyIntruderHint on_empty_intruder_hint () const
|
||||
{
|
||||
if (m_mode == EdgesOutside) {
|
||||
return m_output_mode == Both ? Copy : (m_output_mode == Inverse ? Drop : Copy);
|
||||
} else {
|
||||
return m_output_mode == Both ? CopyToSecond : (m_output_mode == Inverse ? Copy : Drop);
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::string description () const
|
||||
{
|
||||
if (m_mode == EdgesInteract) {
|
||||
if (m_output_mode == Inverse) {
|
||||
return tl::to_string (tr ("Select non-interacting edges"));
|
||||
} else if (m_output_mode == Normal) {
|
||||
return tl::to_string (tr ("Select interacting edges"));
|
||||
} else {
|
||||
return tl::to_string (tr ("Select interacting and non-interacting edges"));
|
||||
}
|
||||
} else if (m_mode == EdgesInside) {
|
||||
if (m_output_mode == Inverse) {
|
||||
return tl::to_string (tr ("Select non-inside edges"));
|
||||
} else if (m_output_mode == Normal) {
|
||||
return tl::to_string (tr ("Select inside edges"));
|
||||
} else {
|
||||
return tl::to_string (tr ("Select inside and non-inside edges"));
|
||||
}
|
||||
} else if (m_mode == EdgesOutside) {
|
||||
if (m_output_mode == Inverse) {
|
||||
return tl::to_string (tr ("Select non-outside edges"));
|
||||
} else if (m_output_mode == Normal) {
|
||||
return tl::to_string (tr ("Select outside edges"));
|
||||
} else {
|
||||
return tl::to_string (tr ("Select outside and non-outside edges"));
|
||||
}
|
||||
}
|
||||
return std::string ();
|
||||
}
|
||||
|
||||
private:
|
||||
EdgeInteractionMode m_mode;
|
||||
output_mode_t m_output_mode;
|
||||
};
|
||||
|
||||
struct ResultInserter
|
||||
{
|
||||
typedef db::Polygon value_type;
|
||||
|
||||
ResultInserter (db::Layout *layout, std::unordered_set<db::PolygonRef> &result)
|
||||
: mp_layout (layout), mp_result (&result)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void insert (const db::Polygon &p)
|
||||
{
|
||||
(*mp_result).insert (db::PolygonRef (p, mp_layout->shape_repository ()));
|
||||
}
|
||||
|
||||
private:
|
||||
db::Layout *mp_layout;
|
||||
std::unordered_set<db::PolygonRef> *mp_result;
|
||||
};
|
||||
|
||||
class Edge2PolygonPullLocalOperation
|
||||
: public local_operation<db::Edge, db::PolygonRef, db::PolygonRef>
|
||||
{
|
||||
public:
|
||||
Edge2PolygonPullLocalOperation ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual db::Coord dist () const
|
||||
{
|
||||
// touching is sufficient
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual void do_compute_local (db::Layout *layout, db::Cell * /*cell*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, const db::LocalProcessorBase * /*proc*/) const
|
||||
{
|
||||
tl_assert (results.size () == 1);
|
||||
std::unordered_set<db::PolygonRef> &result = results.front ();
|
||||
|
||||
db::box_scanner2<db::Edge, size_t, db::Polygon, size_t> scanner;
|
||||
|
||||
std::set<db::PolygonRef> others;
|
||||
for (shape_interactions<db::Edge, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (shape_interactions<db::Edge, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
others.insert (interactions.intruder_shape (*j).second);
|
||||
}
|
||||
}
|
||||
|
||||
for (shape_interactions<db::Edge, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const db::Edge &subject = interactions.subject_shape (i->first);
|
||||
scanner.insert1 (&subject, 1);
|
||||
}
|
||||
|
||||
std::list<db::Polygon> heap;
|
||||
for (std::set<db::PolygonRef>::const_iterator o = others.begin (); o != others.end (); ++o) {
|
||||
heap.push_back (o->obj ().transformed (o->trans ()));
|
||||
scanner.insert2 (& heap.back (), 0);
|
||||
}
|
||||
|
||||
ResultInserter inserter (layout, result);
|
||||
edge_to_region_interaction_filter<ResultInserter> filter (&inserter, EdgesInteract);
|
||||
scanner.process (filter, 1, db::box_convert<db::Edge> (), db::box_convert<db::Polygon> ());
|
||||
}
|
||||
|
||||
virtual OnEmptyIntruderHint on_empty_intruder_hint () const
|
||||
{
|
||||
return Drop;
|
||||
}
|
||||
|
||||
virtual std::string description () const
|
||||
{
|
||||
return tl::to_string (tr ("Select interacting regions"));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
DeepEdges::selected_interacting_generic (const Region &other, EdgeInteractionMode mode, bool inverse) const
|
||||
DeepEdges::selected_interacting_generic (const Region &other, EdgeInteractionMode mode, bool inverse, size_t min_count, size_t max_count) const
|
||||
{
|
||||
// @@@
|
||||
std::unique_ptr<db::DeepRegion> dr_holder;
|
||||
const db::DeepRegion *other_deep = dynamic_cast<const db::DeepRegion *> (other.delegate ());
|
||||
if (! other_deep) {
|
||||
|
|
@ -1723,7 +1370,7 @@ DeepEdges::selected_interacting_generic (const Region &other, EdgeInteractionMod
|
|||
|
||||
DeepLayer dl_out (edges.derived ());
|
||||
|
||||
db::Edge2PolygonInteractingLocalOperation op (mode, inverse ? db::Edge2PolygonInteractingLocalOperation::Inverse : db::Edge2PolygonInteractingLocalOperation::Normal);
|
||||
db::edge_to_polygon_interacting_local_operation<db::PolygonRef> op (mode, inverse ? db::edge_to_polygon_interacting_local_operation<db::PolygonRef>::Inverse : db::edge_to_polygon_interacting_local_operation<db::PolygonRef>::Normal);
|
||||
|
||||
db::local_processor<db::Edge, db::PolygonRef, db::Edge> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), edges.breakout_cells (), other_deep->deep_layer ().breakout_cells ());
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
|
|
@ -1735,8 +1382,9 @@ DeepEdges::selected_interacting_generic (const Region &other, EdgeInteractionMod
|
|||
}
|
||||
|
||||
std::pair<EdgesDelegate *, EdgesDelegate *>
|
||||
DeepEdges::selected_interacting_pair_generic (const Region &other, EdgeInteractionMode mode) const
|
||||
DeepEdges::selected_interacting_pair_generic (const Region &other, EdgeInteractionMode mode, size_t min_count, size_t max_count) const
|
||||
{
|
||||
// @@@
|
||||
std::unique_ptr<db::DeepRegion> dr_holder;
|
||||
const db::DeepRegion *other_deep = dynamic_cast<const db::DeepRegion *> (other.delegate ());
|
||||
if (! other_deep) {
|
||||
|
|
@ -1755,7 +1403,7 @@ DeepEdges::selected_interacting_pair_generic (const Region &other, EdgeInteracti
|
|||
output_layers.push_back (dl_out.layer ());
|
||||
output_layers.push_back (dl_out2.layer ());
|
||||
|
||||
db::Edge2PolygonInteractingLocalOperation op (mode, db::Edge2PolygonInteractingLocalOperation::Both);
|
||||
db::edge_to_polygon_interacting_local_operation<db::PolygonRef> op (mode, db::edge_to_polygon_interacting_local_operation<db::PolygonRef>::Both);
|
||||
|
||||
db::local_processor<db::Edge, db::PolygonRef, db::Edge> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), edges.breakout_cells (), other_deep->deep_layer ().breakout_cells ());
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
|
|
@ -1767,8 +1415,9 @@ DeepEdges::selected_interacting_pair_generic (const Region &other, EdgeInteracti
|
|||
}
|
||||
|
||||
EdgesDelegate *
|
||||
DeepEdges::selected_interacting_generic (const Edges &other, EdgeInteractionMode mode, bool inverse) const
|
||||
DeepEdges::selected_interacting_generic (const Edges &other, EdgeInteractionMode mode, bool inverse, size_t min_count, size_t max_count) const
|
||||
{
|
||||
// @@@
|
||||
std::unique_ptr<db::DeepEdges> dr_holder;
|
||||
const db::DeepEdges *other_deep = dynamic_cast<const db::DeepEdges *> (other.delegate ());
|
||||
if (! other_deep) {
|
||||
|
|
@ -1793,8 +1442,9 @@ DeepEdges::selected_interacting_generic (const Edges &other, EdgeInteractionMode
|
|||
}
|
||||
|
||||
std::pair<EdgesDelegate *, EdgesDelegate *>
|
||||
DeepEdges::selected_interacting_pair_generic (const Edges &other, EdgeInteractionMode mode) const
|
||||
DeepEdges::selected_interacting_pair_generic (const Edges &other, EdgeInteractionMode mode, size_t min_count, size_t max_count) const
|
||||
{
|
||||
// @@@
|
||||
std::unique_ptr<db::DeepEdges> dr_holder;
|
||||
const db::DeepEdges *other_deep = dynamic_cast<const db::DeepEdges *> (other.delegate ());
|
||||
if (! other_deep) {
|
||||
|
|
|
|||
|
|
@ -193,10 +193,10 @@ private:
|
|||
EdgePairsDelegate *run_check (db::edge_relation_type rel, const Edges *other, db::Coord d, const db::EdgesCheckOptions &options) const;
|
||||
virtual EdgesDelegate *pull_generic (const Edges &edges) const;
|
||||
virtual RegionDelegate *pull_generic (const Region ®ion) const;
|
||||
virtual EdgesDelegate *selected_interacting_generic (const Edges &edges, EdgeInteractionMode mode, bool inverse) const;
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair_generic (const Edges &edges, EdgeInteractionMode mode) const;
|
||||
virtual EdgesDelegate *selected_interacting_generic (const Region ®ion, EdgeInteractionMode mode, bool inverse) const;
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair_generic (const Region ®ion, EdgeInteractionMode mode) const;
|
||||
virtual EdgesDelegate *selected_interacting_generic (const Edges &edges, EdgeInteractionMode mode, bool inverse, size_t min_count, size_t max_count) const;
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair_generic (const Edges &edges, EdgeInteractionMode mode, size_t min_count, size_t max_count) const;
|
||||
virtual EdgesDelegate *selected_interacting_generic (const Region ®ion, EdgeInteractionMode mode, bool inverse, size_t min_count, size_t max_count) const;
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair_generic (const Region ®ion, EdgeInteractionMode mode, size_t min_count, size_t max_count) const;
|
||||
DeepEdges *apply_filter (const EdgeFilterBase &filter) const;
|
||||
|
||||
template <class Result, class OutputContainer> OutputContainer *processed_impl (const edge_processor<Result> &filter) const;
|
||||
|
|
|
|||
|
|
@ -991,9 +991,9 @@ public:
|
|||
* Merged semantics applies. If merged semantics is chosen, the connected edge parts will be
|
||||
* selected as a whole.
|
||||
*/
|
||||
Edges &select_interacting (const Region &other)
|
||||
Edges &select_interacting (const Region &other, size_t min_count = 1, size_t max_count = std::numeric_limits<size_t>::max ())
|
||||
{
|
||||
set_delegate (mp_delegate->selected_interacting (other));
|
||||
set_delegate (mp_delegate->selected_interacting (other, min_count, max_count));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -1002,9 +1002,9 @@ public:
|
|||
*
|
||||
* This method is an out-of-place version of select_interacting.
|
||||
*/
|
||||
Edges selected_interacting (const Region &other) const
|
||||
Edges selected_interacting (const Region &other, size_t min_count = 1, size_t max_count = std::numeric_limits<size_t>::max ()) const
|
||||
{
|
||||
return Edges (mp_delegate->selected_interacting (other));
|
||||
return Edges (mp_delegate->selected_interacting (other, min_count, max_count));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1013,9 +1013,9 @@ public:
|
|||
* Merged semantics applies. If merged semantics is chosen, the connected edge parts will be
|
||||
* selected as a whole.
|
||||
*/
|
||||
Edges &select_not_interacting (const Region &other)
|
||||
Edges &select_not_interacting (const Region &other, size_t min_count = 1, size_t max_count = std::numeric_limits<size_t>::max ())
|
||||
{
|
||||
set_delegate (mp_delegate->selected_not_interacting (other));
|
||||
set_delegate (mp_delegate->selected_not_interacting (other, min_count, max_count));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -1024,17 +1024,17 @@ public:
|
|||
*
|
||||
* This method is an out-of-place version of select_not_interacting.
|
||||
*/
|
||||
Edges selected_not_interacting (const Region &other) const
|
||||
Edges selected_not_interacting (const Region &other, size_t min_count = 1, size_t max_count = std::numeric_limits<size_t>::max ()) const
|
||||
{
|
||||
return Edges (mp_delegate->selected_not_interacting (other));
|
||||
return Edges (mp_delegate->selected_not_interacting (other, min_count, max_count));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns all edges of this edge set which do not overlap or touch with polygons from the region together with the ones that do not
|
||||
*/
|
||||
std::pair<Edges, Edges> selected_interacting_differential (const Region &other) const
|
||||
std::pair<Edges, Edges> selected_interacting_differential (const Region &other, size_t min_count = 1, size_t max_count = std::numeric_limits<size_t>::max ()) const
|
||||
{
|
||||
std::pair<db::EdgesDelegate *, db::EdgesDelegate *> p = mp_delegate->selected_interacting_pair (other);
|
||||
std::pair<db::EdgesDelegate *, db::EdgesDelegate *> p = mp_delegate->selected_interacting_pair (other, min_count, max_count);
|
||||
return std::pair<Edges, Edges> (Edges (p.first), Edges (p.second));
|
||||
}
|
||||
|
||||
|
|
@ -1280,9 +1280,9 @@ public:
|
|||
* Merged semantics applies. If merged semantics is chosen, the connected edge parts will be
|
||||
* selected as a whole.
|
||||
*/
|
||||
Edges &select_interacting (const Edges &other)
|
||||
Edges &select_interacting (const Edges &other, size_t min_count = 1, size_t max_count = std::numeric_limits<size_t>::max ())
|
||||
{
|
||||
set_delegate (mp_delegate->selected_interacting (other));
|
||||
set_delegate (mp_delegate->selected_interacting (other, min_count, max_count));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -1291,17 +1291,17 @@ public:
|
|||
*
|
||||
* This method is an out-of-place version of select_interacting.
|
||||
*/
|
||||
Edges selected_interacting (const Edges &other) const
|
||||
Edges selected_interacting (const Edges &other, size_t min_count = 1, size_t max_count = std::numeric_limits<size_t>::max ()) const
|
||||
{
|
||||
return Edges (mp_delegate->selected_interacting (other));
|
||||
return Edges (mp_delegate->selected_interacting (other, min_count, max_count));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns all edges of this edge set which do not overlap or touch with edges from the other edge set together with the ones that do not
|
||||
*/
|
||||
std::pair<Edges, Edges> selected_interacting_differential (const Edges &other) const
|
||||
std::pair<Edges, Edges> selected_interacting_differential (const Edges &other, size_t min_count = 1, size_t max_count = std::numeric_limits<size_t>::max ()) const
|
||||
{
|
||||
std::pair<db::EdgesDelegate *, db::EdgesDelegate *> p = mp_delegate->selected_interacting_pair (other);
|
||||
std::pair<db::EdgesDelegate *, db::EdgesDelegate *> p = mp_delegate->selected_interacting_pair (other, min_count, max_count);
|
||||
return std::pair<Edges, Edges> (Edges (p.first), Edges (p.second));
|
||||
}
|
||||
|
||||
|
|
@ -1311,9 +1311,9 @@ public:
|
|||
* Merged semantics applies. If merged semantics is chosen, the connected edge parts will be
|
||||
* selected as a whole.
|
||||
*/
|
||||
Edges &select_not_interacting (const Edges &other)
|
||||
Edges &select_not_interacting (const Edges &other, size_t min_count = 1, size_t max_count = std::numeric_limits<size_t>::max ())
|
||||
{
|
||||
set_delegate (mp_delegate->selected_not_interacting (other));
|
||||
set_delegate (mp_delegate->selected_not_interacting (other, min_count, max_count));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -1322,9 +1322,9 @@ public:
|
|||
*
|
||||
* This method is an out-of-place version of select_not_interacting.
|
||||
*/
|
||||
Edges selected_not_interacting (const Edges &other) const
|
||||
Edges selected_not_interacting (const Edges &other, size_t min_count = 1, size_t max_count = std::numeric_limits<size_t>::max ()) const
|
||||
{
|
||||
return Edges (mp_delegate->selected_not_interacting (other));
|
||||
return Edges (mp_delegate->selected_not_interacting (other, min_count, max_count));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -318,12 +318,12 @@ public:
|
|||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> inside_outside_part_pair (const Region &other) const = 0;
|
||||
virtual RegionDelegate *pull_interacting (const Region &) const = 0;
|
||||
virtual EdgesDelegate *pull_interacting (const Edges &) const = 0;
|
||||
virtual EdgesDelegate *selected_interacting (const Region &other) const = 0;
|
||||
virtual EdgesDelegate *selected_not_interacting (const Region &other) const = 0;
|
||||
virtual EdgesDelegate *selected_interacting (const Edges &other) const = 0;
|
||||
virtual EdgesDelegate *selected_not_interacting (const Edges &other) const = 0;
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair (const Region &other) const = 0;
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair (const Edges &other) const = 0;
|
||||
virtual EdgesDelegate *selected_interacting (const Region &other, size_t min_count, size_t max_count) const = 0;
|
||||
virtual EdgesDelegate *selected_not_interacting (const Region &other, size_t min_count, size_t max_count) const = 0;
|
||||
virtual EdgesDelegate *selected_interacting (const Edges &other, size_t min_count, size_t max_count) const = 0;
|
||||
virtual EdgesDelegate *selected_not_interacting (const Edges &other, size_t min_count, size_t max_count) const = 0;
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair (const Region &other, size_t min_count, size_t max_count) const = 0;
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair (const Edges &other, size_t min_count, size_t max_count) const = 0;
|
||||
|
||||
virtual EdgesDelegate *selected_outside (const Region &other) const = 0;
|
||||
virtual EdgesDelegate *selected_not_outside (const Region &other) const = 0;
|
||||
|
|
|
|||
|
|
@ -199,5 +199,357 @@ EdgeToPolygonLocalOperation::do_compute_local (db::Layout * /*layout*/, db::Cell
|
|||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// Edge2EdgeInteractingLocalOperation implementation
|
||||
|
||||
Edge2EdgeInteractingLocalOperation::Edge2EdgeInteractingLocalOperation (EdgeInteractionMode mode, output_mode_t output_mode)
|
||||
: m_mode (mode), m_output_mode (output_mode)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
db::Coord Edge2EdgeInteractingLocalOperation::dist () const
|
||||
{
|
||||
// touching is sufficient
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Edge2EdgeInteractingLocalOperation::do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase * /*proc*/) const
|
||||
{
|
||||
tl_assert (results.size () == (m_output_mode == Both ? 2 : 1));
|
||||
|
||||
std::unordered_set<db::Edge> &result = results.front ();
|
||||
|
||||
std::unordered_set<db::Edge> *result2 = 0;
|
||||
if (m_output_mode == Both) {
|
||||
result2 = &results[1];
|
||||
}
|
||||
|
||||
db::box_scanner<db::Edge, size_t> scanner;
|
||||
|
||||
std::set<db::Edge> others;
|
||||
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (shape_interactions<db::Edge, db::Edge>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
others.insert (interactions.intruder_shape (*j).second);
|
||||
}
|
||||
}
|
||||
|
||||
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const db::Edge &subject = interactions.subject_shape (i->first);
|
||||
scanner.insert (&subject, 0);
|
||||
}
|
||||
|
||||
for (std::set<db::Edge>::const_iterator o = others.begin (); o != others.end (); ++o) {
|
||||
scanner.insert (o.operator-> (), 1);
|
||||
}
|
||||
|
||||
if (m_output_mode == Inverse || m_output_mode == Both) {
|
||||
|
||||
std::unordered_set<db::Edge> interacting;
|
||||
edge_interaction_filter<std::unordered_set<db::Edge> > filter (interacting, m_mode);
|
||||
scanner.process (filter, 1, db::box_convert<db::Edge> ());
|
||||
|
||||
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
|
||||
const db::Edge &subject = interactions.subject_shape (i->first);
|
||||
if (interacting.find (subject) == interacting.end ()) {
|
||||
if (m_output_mode != Both) {
|
||||
result.insert (subject);
|
||||
} else {
|
||||
result2->insert (subject);
|
||||
}
|
||||
} else if (m_output_mode == Both) {
|
||||
result.insert (subject);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
edge_interaction_filter<std::unordered_set<db::Edge> > filter (result, m_mode);
|
||||
scanner.process (filter, 1, db::box_convert<db::Edge> ());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OnEmptyIntruderHint Edge2EdgeInteractingLocalOperation::on_empty_intruder_hint () const
|
||||
{
|
||||
if (m_mode == EdgesOutside) {
|
||||
return m_output_mode == Both ? Copy : (m_output_mode == Inverse ? Drop : Copy);
|
||||
} else {
|
||||
return m_output_mode == Both ? CopyToSecond : (m_output_mode == Inverse ? Copy : Drop);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Edge2EdgeInteractingLocalOperation::description () const
|
||||
{
|
||||
return tl::to_string (tr ("Select interacting edges"));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// Edge2EdgePullLocalOperation implementation
|
||||
|
||||
Edge2EdgePullLocalOperation::Edge2EdgePullLocalOperation ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
db::Coord Edge2EdgePullLocalOperation::dist () const
|
||||
{
|
||||
// touching is sufficient
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Edge2EdgePullLocalOperation::do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase * /*proc*/) const
|
||||
{
|
||||
tl_assert (results.size () == 1);
|
||||
std::unordered_set<db::Edge> &result = results.front ();
|
||||
|
||||
db::box_scanner<db::Edge, size_t> scanner;
|
||||
|
||||
std::set<db::Edge> others;
|
||||
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (shape_interactions<db::Edge, db::Edge>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
others.insert (interactions.intruder_shape (*j).second);
|
||||
}
|
||||
}
|
||||
|
||||
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const db::Edge &subject = interactions.subject_shape (i->first);
|
||||
scanner.insert (&subject, 1);
|
||||
}
|
||||
|
||||
for (std::set<db::Edge>::const_iterator o = others.begin (); o != others.end (); ++o) {
|
||||
scanner.insert (o.operator-> (), 0);
|
||||
}
|
||||
|
||||
edge_interaction_filter<std::unordered_set<db::Edge> > filter (result, EdgesInteract);
|
||||
scanner.process (filter, 1, db::box_convert<db::Edge> ());
|
||||
|
||||
}
|
||||
|
||||
OnEmptyIntruderHint Edge2EdgePullLocalOperation::on_empty_intruder_hint () const
|
||||
{
|
||||
return Drop;
|
||||
}
|
||||
|
||||
std::string Edge2EdgePullLocalOperation::description () const
|
||||
{
|
||||
return tl::to_string (tr ("Select interacting edges from other"));
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// Edge2EdgePullLocalOperation implementation
|
||||
|
||||
template <class TI>
|
||||
edge_to_polygon_interacting_local_operation<TI>::edge_to_polygon_interacting_local_operation (EdgeInteractionMode mode, output_mode_t output_mode)
|
||||
: m_mode (mode), m_output_mode (output_mode)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
template <class TI>
|
||||
db::Coord edge_to_polygon_interacting_local_operation<TI>::dist () const
|
||||
{
|
||||
// touching is sufficient
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const db::Polygon *deref (const db::Polygon &poly, std::list<db::Polygon> &)
|
||||
{
|
||||
return &poly;
|
||||
}
|
||||
|
||||
static const db::Polygon *deref (const db::PolygonRef &pref, std::list<db::Polygon> &heap)
|
||||
{
|
||||
heap.push_back (pref.obj ().transformed (pref.trans ()));
|
||||
return & heap.back ();
|
||||
}
|
||||
|
||||
template <class TI>
|
||||
void edge_to_polygon_interacting_local_operation<TI>::do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::Edge, TI> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase * /*proc*/) const
|
||||
{
|
||||
tl_assert (results.size () == size_t (m_output_mode == Both ? 2 : 1));
|
||||
|
||||
std::unordered_set<db::Edge> &result = results.front ();
|
||||
|
||||
std::unordered_set<db::Edge> *result2 = 0;
|
||||
if (m_output_mode == Both) {
|
||||
result2 = &results[1];
|
||||
}
|
||||
|
||||
db::box_scanner2<db::Edge, size_t, db::Polygon, size_t> scanner;
|
||||
|
||||
std::set<TI> others;
|
||||
for (typename shape_interactions<db::Edge, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (typename shape_interactions<db::Edge, TI>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
others.insert (interactions.intruder_shape (*j).second);
|
||||
}
|
||||
}
|
||||
|
||||
for (typename shape_interactions<db::Edge, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const db::Edge &subject = interactions.subject_shape (i->first);
|
||||
scanner.insert1 (&subject, 0);
|
||||
}
|
||||
|
||||
std::list<db::Polygon> heap;
|
||||
for (typename std::set<TI>::const_iterator o = others.begin (); o != others.end (); ++o) {
|
||||
scanner.insert2 (deref (*o, heap), 1);
|
||||
}
|
||||
|
||||
if (m_output_mode == Inverse || m_output_mode == Both) {
|
||||
|
||||
std::unordered_set<db::Edge> interacting;
|
||||
edge_to_region_interaction_filter<std::unordered_set<db::Edge> > filter (&interacting, m_mode);
|
||||
scanner.process (filter, 1, db::box_convert<db::Edge> (), db::box_convert<db::Polygon> ());
|
||||
|
||||
for (typename shape_interactions<db::Edge, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
|
||||
const db::Edge &subject = interactions.subject_shape (i->first);
|
||||
|
||||
if (interacting.find (subject) == interacting.end ()) {
|
||||
if (m_output_mode != Both) {
|
||||
result.insert (subject);
|
||||
} else {
|
||||
result2->insert (subject);
|
||||
}
|
||||
} else if (m_output_mode == Both) {
|
||||
result.insert (subject);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
edge_to_region_interaction_filter<std::unordered_set<db::Edge> > filter (&result, m_mode);
|
||||
scanner.process (filter, 1, db::box_convert<db::Edge> (), db::box_convert<db::Polygon> ());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
template <class TI>
|
||||
OnEmptyIntruderHint edge_to_polygon_interacting_local_operation<TI>::on_empty_intruder_hint () const
|
||||
{
|
||||
if (m_mode == EdgesOutside) {
|
||||
return m_output_mode == Both ? Copy : (m_output_mode == Inverse ? Drop : Copy);
|
||||
} else {
|
||||
return m_output_mode == Both ? CopyToSecond : (m_output_mode == Inverse ? Copy : Drop);
|
||||
}
|
||||
}
|
||||
|
||||
template <class TI>
|
||||
std::string edge_to_polygon_interacting_local_operation<TI>::description () const
|
||||
{
|
||||
if (m_mode == EdgesInteract) {
|
||||
if (m_output_mode == Inverse) {
|
||||
return tl::to_string (tr ("Select non-interacting edges"));
|
||||
} else if (m_output_mode == Normal) {
|
||||
return tl::to_string (tr ("Select interacting edges"));
|
||||
} else {
|
||||
return tl::to_string (tr ("Select interacting and non-interacting edges"));
|
||||
}
|
||||
} else if (m_mode == EdgesInside) {
|
||||
if (m_output_mode == Inverse) {
|
||||
return tl::to_string (tr ("Select non-inside edges"));
|
||||
} else if (m_output_mode == Normal) {
|
||||
return tl::to_string (tr ("Select inside edges"));
|
||||
} else {
|
||||
return tl::to_string (tr ("Select inside and non-inside edges"));
|
||||
}
|
||||
} else if (m_mode == EdgesOutside) {
|
||||
if (m_output_mode == Inverse) {
|
||||
return tl::to_string (tr ("Select non-outside edges"));
|
||||
} else if (m_output_mode == Normal) {
|
||||
return tl::to_string (tr ("Select outside edges"));
|
||||
} else {
|
||||
return tl::to_string (tr ("Select outside and non-outside edges"));
|
||||
}
|
||||
}
|
||||
return std::string ();
|
||||
}
|
||||
|
||||
template class edge_to_polygon_interacting_local_operation<db::Polygon>;
|
||||
template class edge_to_polygon_interacting_local_operation<db::PolygonRef>;
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
// Edge2EdgePullLocalOperation implementation
|
||||
|
||||
namespace {
|
||||
|
||||
struct ResultInserter
|
||||
{
|
||||
typedef db::Polygon value_type;
|
||||
|
||||
ResultInserter (db::Layout *layout, std::unordered_set<db::PolygonRef> &result)
|
||||
: mp_layout (layout), mp_result (&result)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void insert (const db::Polygon &p)
|
||||
{
|
||||
(*mp_result).insert (db::PolygonRef (p, mp_layout->shape_repository ()));
|
||||
}
|
||||
|
||||
private:
|
||||
db::Layout *mp_layout;
|
||||
std::unordered_set<db::PolygonRef> *mp_result;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Edge2PolygonPullLocalOperation::Edge2PolygonPullLocalOperation ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
db::Coord Edge2PolygonPullLocalOperation::dist () const
|
||||
{
|
||||
// touching is sufficient
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Edge2PolygonPullLocalOperation::do_compute_local (db::Layout *layout, db::Cell * /*cell*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, const db::LocalProcessorBase * /*proc*/) const
|
||||
{
|
||||
tl_assert (results.size () == 1);
|
||||
std::unordered_set<db::PolygonRef> &result = results.front ();
|
||||
|
||||
db::box_scanner2<db::Edge, size_t, db::Polygon, size_t> scanner;
|
||||
|
||||
std::set<db::PolygonRef> others;
|
||||
for (shape_interactions<db::Edge, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
for (shape_interactions<db::Edge, db::PolygonRef>::iterator2 j = i->second.begin (); j != i->second.end (); ++j) {
|
||||
others.insert (interactions.intruder_shape (*j).second);
|
||||
}
|
||||
}
|
||||
|
||||
for (shape_interactions<db::Edge, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||
const db::Edge &subject = interactions.subject_shape (i->first);
|
||||
scanner.insert1 (&subject, 1);
|
||||
}
|
||||
|
||||
std::list<db::Polygon> heap;
|
||||
for (std::set<db::PolygonRef>::const_iterator o = others.begin (); o != others.end (); ++o) {
|
||||
heap.push_back (o->obj ().transformed (o->trans ()));
|
||||
scanner.insert2 (& heap.back (), 0);
|
||||
}
|
||||
|
||||
ResultInserter inserter (layout, result);
|
||||
edge_to_region_interaction_filter<ResultInserter> filter (&inserter, EdgesInteract);
|
||||
scanner.process (filter, 1, db::box_convert<db::Edge> (), db::box_convert<db::Polygon> ());
|
||||
}
|
||||
|
||||
OnEmptyIntruderHint Edge2PolygonPullLocalOperation::on_empty_intruder_hint () const
|
||||
{
|
||||
return Drop;
|
||||
}
|
||||
|
||||
std::string Edge2PolygonPullLocalOperation::description () const
|
||||
{
|
||||
return tl::to_string (tr ("Select interacting regions"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "dbEdgeBoolean.h"
|
||||
#include "dbEdgeProcessor.h"
|
||||
#include "dbLocalOperation.h"
|
||||
#include "dbEdgesUtils.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
|
@ -79,6 +80,79 @@ private:
|
|||
bool m_include_borders;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Implements edge-to-edge interactions
|
||||
*/
|
||||
class DB_PUBLIC Edge2EdgeInteractingLocalOperation
|
||||
: public local_operation<db::Edge, db::Edge, db::Edge>
|
||||
{
|
||||
public:
|
||||
enum output_mode_t { Normal, Inverse, Both };
|
||||
|
||||
Edge2EdgeInteractingLocalOperation (EdgeInteractionMode mode, output_mode_t output_mode);
|
||||
|
||||
virtual db::Coord dist () const;
|
||||
virtual void do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase * /*proc*/) const;
|
||||
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
|
||||
virtual std::string description () const;
|
||||
|
||||
private:
|
||||
EdgeInteractionMode m_mode;
|
||||
output_mode_t m_output_mode;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Implements edge-to-edge interactions (pull mode)
|
||||
*/
|
||||
class DB_PUBLIC Edge2EdgePullLocalOperation
|
||||
: public local_operation<db::Edge, db::Edge, db::Edge>
|
||||
{
|
||||
public:
|
||||
Edge2EdgePullLocalOperation ();
|
||||
|
||||
virtual db::Coord dist () const;
|
||||
virtual void do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase * /*proc*/) const;
|
||||
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
|
||||
virtual std::string description () const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Implements edge-to-polygon interactions
|
||||
*/
|
||||
template<class TI>
|
||||
class DB_PUBLIC_TEMPLATE edge_to_polygon_interacting_local_operation
|
||||
: public local_operation<db::Edge, TI, db::Edge>
|
||||
{
|
||||
public:
|
||||
enum output_mode_t { Normal, Inverse, Both };
|
||||
|
||||
edge_to_polygon_interacting_local_operation (EdgeInteractionMode mode, output_mode_t output_mode);
|
||||
|
||||
virtual db::Coord dist () const;
|
||||
virtual void do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<db::Edge, TI> &interactions, std::vector<std::unordered_set<db::Edge> > &results, const db::LocalProcessorBase * /*proc*/) const;
|
||||
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
|
||||
virtual std::string description () const;
|
||||
|
||||
private:
|
||||
EdgeInteractionMode m_mode;
|
||||
output_mode_t m_output_mode;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Implements edge-to-polygon interactions (pull mode)
|
||||
*/
|
||||
class DB_PUBLIC Edge2PolygonPullLocalOperation
|
||||
: public local_operation<db::Edge, db::PolygonRef, db::PolygonRef>
|
||||
{
|
||||
public:
|
||||
Edge2PolygonPullLocalOperation ();
|
||||
|
||||
virtual db::Coord dist () const;
|
||||
virtual void do_compute_local (db::Layout *layout, db::Cell * /*cell*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::PolygonRef> > &results, const db::LocalProcessorBase * /*proc*/) const;
|
||||
virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
|
||||
virtual std::string description () const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -94,12 +94,12 @@ public:
|
|||
|
||||
virtual RegionDelegate *pull_interacting (const Region &) const;
|
||||
virtual EdgesDelegate *pull_interacting (const Edges &) const { return new EmptyEdges (); }
|
||||
virtual EdgesDelegate *selected_interacting (const Edges &) const { return new EmptyEdges (); }
|
||||
virtual EdgesDelegate *selected_not_interacting (const Edges &) const { return new EmptyEdges (); }
|
||||
virtual EdgesDelegate *selected_interacting (const Region &) const { return new EmptyEdges (); }
|
||||
virtual EdgesDelegate *selected_not_interacting (const Region &) const { return new EmptyEdges (); }
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair (const Region &) const { return std::make_pair (new EmptyEdges (), new EmptyEdges ()); }
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair (const Edges &) const { return std::make_pair (new EmptyEdges (), new EmptyEdges ()); }
|
||||
virtual EdgesDelegate *selected_interacting (const Edges &, size_t, size_t) const { return new EmptyEdges (); }
|
||||
virtual EdgesDelegate *selected_not_interacting (const Edges &, size_t, size_t) const { return new EmptyEdges (); }
|
||||
virtual EdgesDelegate *selected_interacting (const Region &, size_t, size_t) const { return new EmptyEdges (); }
|
||||
virtual EdgesDelegate *selected_not_interacting (const Region &, size_t, size_t) const { return new EmptyEdges (); }
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair (const Region &, size_t, size_t) const { return std::make_pair (new EmptyEdges (), new EmptyEdges ()); }
|
||||
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair (const Edges &, size_t, size_t) const { return std::make_pair (new EmptyEdges (), new EmptyEdges ()); }
|
||||
|
||||
virtual EdgesDelegate *selected_outside (const Region &) const { return new EmptyEdges (); }
|
||||
virtual EdgesDelegate *selected_not_outside (const Region &) const { return new EmptyEdges (); }
|
||||
|
|
|
|||
|
|
@ -428,14 +428,14 @@ static std::vector<db::Edges> split_outside_with_region (const db::Edges *r, con
|
|||
return as_2edges_vector (r->selected_outside_differential (other));
|
||||
}
|
||||
|
||||
static std::vector<db::Edges> split_interacting_with_edges (const db::Edges *r, const db::Edges &other)
|
||||
static std::vector<db::Edges> split_interacting_with_edges (const db::Edges *r, const db::Edges &other, size_t min_count, size_t max_count)
|
||||
{
|
||||
return as_2edges_vector (r->selected_interacting_differential (other));
|
||||
return as_2edges_vector (r->selected_interacting_differential (other, min_count, max_count));
|
||||
}
|
||||
|
||||
static std::vector<db::Edges> split_interacting_with_region (const db::Edges *r, const db::Region &other)
|
||||
static std::vector<db::Edges> split_interacting_with_region (const db::Edges *r, const db::Region &other, size_t min_count, size_t max_count)
|
||||
{
|
||||
return as_2edges_vector (r->selected_interacting_differential (other));
|
||||
return as_2edges_vector (r->selected_interacting_differential (other, min_count, max_count));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -969,61 +969,107 @@ Class<db::Edges> decl_Edges (decl_dbShapeCollection, "db", "Edges",
|
|||
"\n"
|
||||
"The 'join_with' alias has been introduced in version 0.28.12."
|
||||
) +
|
||||
method ("interacting", (db::Edges (db::Edges::*) (const db::Edges &) const) &db::Edges::selected_interacting, gsi::arg ("other"),
|
||||
method ("interacting", (db::Edges (db::Edges::*) (const db::Edges &, size_t, size_t) const) &db::Edges::selected_interacting, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits<size_t>::max ()), "unlimited"),
|
||||
"@brief Returns the edges of this edge collection which overlap or touch edges from the other edge collection\n"
|
||||
"\n"
|
||||
"@return A new edge collection containing the edges overlapping or touching edges from the other edge collection\n"
|
||||
"\n"
|
||||
"'min_count' and 'max_count' impose a constraint on the number of times an edge of this collection "
|
||||
"has to interact with (different) edges of the other collection to make the edge selected. An edge is "
|
||||
"selected by this method if the number of edges interacting with an edge of this collection is between min_count and max_count "
|
||||
"(including max_count).\n"
|
||||
"\n"
|
||||
"'min_count' and 'max_count' have been introduced in version 0.29."
|
||||
) +
|
||||
method ("not_interacting", (db::Edges (db::Edges::*) (const db::Edges &) const) &db::Edges::selected_not_interacting, gsi::arg ("other"),
|
||||
method ("not_interacting", (db::Edges (db::Edges::*) (const db::Edges &, size_t, size_t) const) &db::Edges::selected_not_interacting, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits<size_t>::max ()), "unlimited"),
|
||||
"@brief Returns the edges of this edge collection which do not overlap or touch edges from the other edge collection\n"
|
||||
"\n"
|
||||
"@return A new edge collection containing the edges not overlapping or touching edges from the other edge collection\n"
|
||||
) +
|
||||
method ("select_interacting", (db::Edges &(db::Edges::*) (const db::Edges &)) &db::Edges::select_interacting, gsi::arg ("other"),
|
||||
"\n"
|
||||
"'min_count' and 'max_count' impose a constraint on the number of times an edge of this collection "
|
||||
"has to interact with (different) edges of the other collection to make the edge selected. An edge is "
|
||||
"not selected by this method if the number of edges interacting with an edge of this collection is between min_count and max_count "
|
||||
"(including max_count).\n"
|
||||
"\n"
|
||||
"'min_count' and 'max_count' have been introduced in version 0.29."
|
||||
) +
|
||||
method ("select_interacting", (db::Edges &(db::Edges::*) (const db::Edges &, size_t, size_t)) &db::Edges::select_interacting, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits<size_t>::max ()), "unlimited"),
|
||||
"@brief Selects the edges from this edge collection which overlap or touch edges from the other edge collection\n"
|
||||
"\n"
|
||||
"@return The edge collection after the edges have been selected (self)\n"
|
||||
) +
|
||||
method ("select_not_interacting", (db::Edges &(db::Edges::*) (const db::Edges &)) &db::Edges::select_not_interacting, gsi::arg ("other"),
|
||||
"\n"
|
||||
"This is the in-place version of \\interacting - i.e. self is modified rather than a new collection is returned.\n"
|
||||
"\n"
|
||||
"'min_count' and 'max_count' have been introduced in version 0.29."
|
||||
) +
|
||||
method ("select_not_interacting", (db::Edges &(db::Edges::*) (const db::Edges &, size_t, size_t)) &db::Edges::select_not_interacting, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits<size_t>::max ()), "unlimited"),
|
||||
"@brief Selects the edges from this edge collection which do not overlap or touch edges from the other edge collection\n"
|
||||
"\n"
|
||||
"@return The edge collection after the edges have been selected (self)\n"
|
||||
) +
|
||||
method_ext ("split_interacting", &split_interacting_with_edges, gsi::arg ("other"),
|
||||
"\n"
|
||||
"This is the in-place version of \\not_interacting - i.e. self is modified rather than a new collection is returned.\n"
|
||||
"\n"
|
||||
"'min_count' and 'max_count' have been introduced in version 0.29."
|
||||
) +
|
||||
method_ext ("split_interacting", &split_interacting_with_edges, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits<size_t>::max ()), "unlimited"),
|
||||
"@brief Selects the edges from this edge collection which do and do not interact with edges from the other collection\n"
|
||||
"\n"
|
||||
"@return A two-element list of edge collections (first: interacting, second: non-interacting)\n"
|
||||
"\n"
|
||||
"This method provides a faster way to compute both interacting and non-interacting edges compared to using separate methods. "
|
||||
"It has been introduced in version 0.28."
|
||||
"It has been introduced in version 0.28.\n"
|
||||
"'min_count' and 'max_count' have been introduced in version 0.29."
|
||||
) +
|
||||
method ("interacting", (db::Edges (db::Edges::*) (const db::Region &) const) &db::Edges::selected_interacting, gsi::arg ("other"),
|
||||
method ("interacting", (db::Edges (db::Edges::*) (const db::Region &, size_t, size_t) const) &db::Edges::selected_interacting, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits<size_t>::max ()), "unlimited"),
|
||||
"@brief Returns the edges from this edge collection which overlap or touch polygons from the region\n"
|
||||
"\n"
|
||||
"@return A new edge collection containing the edges overlapping or touching polygons from the region\n"
|
||||
) +
|
||||
method ("not_interacting", (db::Edges (db::Edges::*) (const db::Region &) const) &db::Edges::selected_not_interacting, gsi::arg ("other"),
|
||||
"\n"
|
||||
"'min_count' and 'max_count' impose a constraint on the number of times an edge of this collection "
|
||||
"has to interact with (different) polygons of the other region to make the edge selected. An edge is "
|
||||
"selected by this method if the number of polygons interacting with an edge of this collection is between min_count and max_count "
|
||||
"(including max_count).\n"
|
||||
"\n"
|
||||
"'min_count' and 'max_count' have been introduced in version 0.29."
|
||||
) +
|
||||
method ("not_interacting", (db::Edges (db::Edges::*) (const db::Region &, size_t, size_t) const) &db::Edges::selected_not_interacting, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits<size_t>::max ()), "unlimited"),
|
||||
"@brief Returns the edges from this edge collection which do not overlap or touch polygons from the region\n"
|
||||
"\n"
|
||||
"@return A new edge collection containing the edges not overlapping or touching polygons from the region\n"
|
||||
) +
|
||||
method ("select_interacting", (db::Edges &(db::Edges::*) (const db::Region &)) &db::Edges::select_interacting, gsi::arg ("other"),
|
||||
"\n"
|
||||
"'min_count' and 'max_count' impose a constraint on the number of times an edge of this collection "
|
||||
"has to interact with (different) polygons of the other region to make the edge selected. An edge is "
|
||||
"not selected by this method if the number of polygons interacting with an edge of this collection is between min_count and max_count "
|
||||
"(including max_count).\n"
|
||||
"\n"
|
||||
"'min_count' and 'max_count' have been introduced in version 0.29."
|
||||
) +
|
||||
method ("select_interacting", (db::Edges &(db::Edges::*) (const db::Region &, size_t, size_t)) &db::Edges::select_interacting, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits<size_t>::max ()), "unlimited"),
|
||||
"@brief Selects the edges from this edge collection which overlap or touch polygons from the region\n"
|
||||
"\n"
|
||||
"@return The edge collection after the edges have been selected (self)\n"
|
||||
) +
|
||||
method ("select_not_interacting", (db::Edges &(db::Edges::*) (const db::Region &)) &db::Edges::select_not_interacting, gsi::arg ("other"),
|
||||
"\n"
|
||||
"This is the in-place version of \\interacting - i.e. self is modified rather than a new collection is returned.\n"
|
||||
"\n"
|
||||
"'min_count' and 'max_count' have been introduced in version 0.29."
|
||||
) +
|
||||
method ("select_not_interacting", (db::Edges &(db::Edges::*) (const db::Region &, size_t, size_t)) &db::Edges::select_not_interacting, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits<size_t>::max ()), "unlimited"),
|
||||
"@brief Selects the edges from this edge collection which do not overlap or touch polygons from the region\n"
|
||||
"\n"
|
||||
"@return The edge collection after the edges have been selected (self)\n"
|
||||
) +
|
||||
method_ext ("split_interacting", &split_interacting_with_region, gsi::arg ("other"),
|
||||
"\n"
|
||||
"This is the in-place version of \\not_interacting - i.e. self is modified rather than a new collection is returned.\n"
|
||||
"\n"
|
||||
"'min_count' and 'max_count' have been introduced in version 0.29."
|
||||
) +
|
||||
method_ext ("split_interacting", &split_interacting_with_region, gsi::arg ("other"), gsi::arg ("min_count", size_t (1)), gsi::arg ("max_count", size_t (std::numeric_limits<size_t>::max ()), "unlimited"),
|
||||
"@brief Selects the edges from this edge collection which do and do not interact with polygons from the other region\n"
|
||||
"\n"
|
||||
"@return A two-element list of edge collections (first: interacting, second: non-interacting)\n"
|
||||
"\n"
|
||||
"This method provides a faster way to compute both interacting and non-interacting edges compared to using separate methods. "
|
||||
"It has been introduced in version 0.28."
|
||||
"It has been introduced in version 0.28.\n"
|
||||
"'min_count' and 'max_count' have been introduced in version 0.29."
|
||||
) +
|
||||
method ("inside", (db::Edges (db::Edges::*) (const db::Edges &) const) &db::Edges::selected_inside, gsi::arg ("other"),
|
||||
"@brief Returns the edges of this edge collection which are inside (completely covered by) edges from the other edge collection\n"
|
||||
|
|
|
|||
Loading…
Reference in New Issue