First implementation

This commit is contained in:
Matthias Koefferlein 2022-08-29 19:51:19 +02:00
parent 4af9b8b01c
commit 956a27ec69
5 changed files with 234 additions and 89 deletions

View File

@ -797,12 +797,21 @@ DeepEdges::and_or_not_with (const DeepEdges *other, EdgeBoolOp op) const
return dl_out; return dl_out;
} }
DeepLayer std::pair<DeepLayer, DeepLayer>
DeepEdges::edge_region_op (const DeepRegion *other, bool outside, bool include_borders) const DeepEdges::edge_region_op (const DeepRegion *other, EdgePolygonOp::mode_t mode, bool include_borders) const
{ {
DeepLayer dl_out (deep_layer ().derived ()); std::vector<unsigned int> output_layers;
db::EdgeToPolygonLocalOperation op (outside, include_borders); DeepLayer dl_out (deep_layer ().derived ());
output_layers.push_back (dl_out.layer ());
DeepLayer dl_out2;
if (mode == EdgePolygonOp::Both) {
dl_out2 = DeepLayer (deep_layer ().derived ());
output_layers.push_back (dl_out2.layer ());
}
db::EdgeToPolygonLocalOperation op (mode, include_borders);
db::local_processor<db::Edge, db::PolygonRef, db::Edge> proc (const_cast<db::Layout *> (&deep_layer ().layout ()), const_cast<db::Cell *> (&deep_layer ().initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell ()); db::local_processor<db::Edge, db::PolygonRef, db::Edge> proc (const_cast<db::Layout *> (&deep_layer ().layout ()), const_cast<db::Cell *> (&deep_layer ().initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell ());
proc.set_base_verbosity (base_verbosity ()); proc.set_base_verbosity (base_verbosity ());
@ -810,9 +819,9 @@ DeepEdges::edge_region_op (const DeepRegion *other, bool outside, bool include_b
proc.set_area_ratio (deep_layer ().store ()->max_area_ratio ()); proc.set_area_ratio (deep_layer ().store ()->max_area_ratio ());
proc.set_max_vertex_count (deep_layer ().store ()->max_vertex_count ()); proc.set_max_vertex_count (deep_layer ().store ()->max_vertex_count ());
proc.run (&op, deep_layer ().layer (), other->deep_layer ().layer (), dl_out.layer ()); proc.run (&op, deep_layer ().layer (), other->deep_layer ().layer (), output_layers);
return dl_out; return std::make_pair (dl_out, dl_out2);
} }
EdgesDelegate *DeepEdges::intersections (const Edges &other) const EdgesDelegate *DeepEdges::intersections (const Edges &other) const
@ -855,31 +864,6 @@ EdgesDelegate *DeepEdges::and_with (const Edges &other) const
} }
} }
EdgesDelegate *DeepEdges::and_with (const Region &other) const
{
const DeepRegion *other_deep = dynamic_cast <const DeepRegion *> (other.delegate ());
if (empty ()) {
// Nothing to do
return new EmptyEdges ();
} else if (other.empty ()) {
// Nothing to do
return clone ();
} else if (! other_deep) {
return AsIfFlatEdges::not_with (other);
} else {
return new DeepEdges (edge_region_op (other_deep, false /*outside*/, true /*include borders*/));
}
}
EdgesDelegate *DeepEdges::not_with (const Edges &other) const EdgesDelegate *DeepEdges::not_with (const Edges &other) const
{ {
const DeepEdges *other_deep = dynamic_cast <const DeepEdges *> (other.delegate ()); const DeepEdges *other_deep = dynamic_cast <const DeepEdges *> (other.delegate ());
@ -905,6 +889,31 @@ EdgesDelegate *DeepEdges::not_with (const Edges &other) const
} }
} }
EdgesDelegate *DeepEdges::and_with (const Region &other) const
{
const DeepRegion *other_deep = dynamic_cast <const DeepRegion *> (other.delegate ());
if (empty ()) {
// Nothing to do
return new EmptyEdges ();
} else if (other.empty ()) {
// Nothing to do
return clone ();
} else if (! other_deep) {
return AsIfFlatEdges::and_with (other);
} else {
return new DeepEdges (edge_region_op (other_deep, EdgePolygonOp::Inside, true /*include borders*/).first);
}
}
EdgesDelegate *DeepEdges::not_with (const Region &other) const EdgesDelegate *DeepEdges::not_with (const Region &other) const
{ {
const DeepRegion *other_deep = dynamic_cast <const DeepRegion *> (other.delegate ()); const DeepRegion *other_deep = dynamic_cast <const DeepRegion *> (other.delegate ());
@ -925,23 +934,36 @@ EdgesDelegate *DeepEdges::not_with (const Region &other) const
} else { } else {
return new DeepEdges (edge_region_op (other_deep, true /*outside*/, true /*include borders*/)); return new DeepEdges (edge_region_op (other_deep, EdgePolygonOp::Outside, true /*include borders*/).first);
} }
} }
std::pair<EdgesDelegate *, EdgesDelegate *> std::pair<EdgesDelegate *, EdgesDelegate *>
DeepEdges::andnot_with (const Edges &) const DeepEdges::andnot_with (const Edges &other) const
{ {
// @@@ const DeepRegion *other_deep = dynamic_cast <const DeepRegion *> (other.delegate ());
return std::pair<EdgesDelegate *, EdgesDelegate *>();
}
std::pair<EdgesDelegate *, EdgesDelegate *> if (empty ()) {
DeepEdges::andnot_with (const Region &) const
{ // Nothing to do
// @@@ return std::make_pair (new EmptyEdges (), new EmptyEdges ());
return std::pair<EdgesDelegate *, EdgesDelegate *>();
} else if (other.empty ()) {
// Nothing to do
return std::make_pair (new EmptyEdges (), clone ());
} else if (! other_deep) {
return AsIfFlatEdges::andnot_with (other);
} else {
auto res = edge_region_op (other_deep, EdgePolygonOp::Both, true /*include borders*/);
return std::make_pair (new DeepEdges (res.first), new DeepEdges (res.second));
}
} }
EdgesDelegate *DeepEdges::xor_with (const Edges &other) const EdgesDelegate *DeepEdges::xor_with (const Edges &other) const
@ -1037,11 +1059,11 @@ EdgesDelegate *DeepEdges::inside_part (const Region &other) const
} else if (! other_deep) { } else if (! other_deep) {
return AsIfFlatEdges::not_with (other); return AsIfFlatEdges::inside_part (other);
} else { } else {
return new DeepEdges (edge_region_op (other_deep, false /*outside*/, false /*include borders*/)); return new DeepEdges (edge_region_op (other_deep, db::EdgePolygonOp::Inside, false /*include borders*/).first);
} }
} }
@ -1062,19 +1084,39 @@ EdgesDelegate *DeepEdges::outside_part (const Region &other) const
} else if (! other_deep) { } else if (! other_deep) {
return AsIfFlatEdges::not_with (other); return AsIfFlatEdges::outside_part (other);
} else { } else {
return new DeepEdges (edge_region_op (other_deep, true /*outside*/, false /*include borders*/)); return new DeepEdges (edge_region_op (other_deep, db::EdgePolygonOp::Outside, false /*include borders*/).first);
} }
} }
std::pair<EdgesDelegate *, EdgesDelegate *> DeepEdges::inside_outside_part_pair (const Region &) const std::pair<EdgesDelegate *, EdgesDelegate *> DeepEdges::inside_outside_part_pair (const Region &other) const
{ {
// @@@ const DeepRegion *other_deep = dynamic_cast <const DeepRegion *> (other.delegate ());
return std::pair<EdgesDelegate *, EdgesDelegate *>();
if (empty ()) {
// Nothing to do
return std::make_pair (new EmptyEdges (), new EmptyEdges ());
} else if (other.empty ()) {
// Nothing to do
return std::make_pair (new EmptyEdges (), clone ());
} else if (! other_deep) {
return AsIfFlatEdges::inside_outside_part_pair (other);
} else {
auto res = edge_region_op (other_deep, EdgePolygonOp::Both, false /*include borders*/);
return std::make_pair (new DeepEdges (res.first), new DeepEdges (res.second));
}
} }
RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_type ext_o, coord_type ext_i, bool join) const RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_type ext_o, coord_type ext_i, bool join) const
@ -1177,8 +1219,10 @@ class Edge2EdgeInteractingLocalOperation
: public local_operation<db::Edge, db::Edge, db::Edge> : public local_operation<db::Edge, db::Edge, db::Edge>
{ {
public: public:
Edge2EdgeInteractingLocalOperation (EdgeInteractionMode mode, bool inverse) enum output_mode_t { Normal, Inverse, Both };
: m_mode (mode), m_inverse (inverse)
Edge2EdgeInteractingLocalOperation (EdgeInteractionMode mode, output_mode_t output_mode)
: m_mode (mode), m_output_mode (output_mode)
{ {
// .. nothing yet .. // .. nothing yet ..
} }
@ -1191,9 +1235,15 @@ public:
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == (m_output_mode == Both ? 2 : 1));
std::unordered_set<db::Edge> &result = results.front (); 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; db::box_scanner<db::Edge, size_t> scanner;
std::set<db::Edge> others; std::set<db::Edge> others;
@ -1212,17 +1262,25 @@ public:
scanner.insert (o.operator-> (), 1); scanner.insert (o.operator-> (), 1);
} }
if (m_inverse) { if (m_output_mode == Inverse || m_output_mode == Both) {
std::unordered_set<db::Edge> interacting; std::unordered_set<db::Edge> interacting;
edge_interaction_filter<std::unordered_set<db::Edge> > filter (interacting, m_mode); edge_interaction_filter<std::unordered_set<db::Edge> > filter (interacting, m_mode);
scanner.process (filter, 1, db::box_convert<db::Edge> ()); scanner.process (filter, 1, db::box_convert<db::Edge> ());
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
const db::Edge &subject = interactions.subject_shape (i->first); const db::Edge &subject = interactions.subject_shape (i->first);
if (interacting.find (subject) == interacting.end ()) { 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); result.insert (subject);
} }
} }
} else { } else {
@ -1236,7 +1294,7 @@ public:
virtual OnEmptyIntruderHint on_empty_intruder_hint () const virtual OnEmptyIntruderHint on_empty_intruder_hint () const
{ {
if (m_inverse) { if (m_output_mode != Normal) {
return Copy; return Copy;
} else { } else {
return Drop; return Drop;
@ -1250,7 +1308,7 @@ public:
private: private:
EdgeInteractionMode m_mode; EdgeInteractionMode m_mode;
bool m_inverse; output_mode_t m_output_mode;
}; };
class Edge2EdgePullLocalOperation class Edge2EdgePullLocalOperation
@ -1311,8 +1369,10 @@ class Edge2PolygonInteractingLocalOperation
: public local_operation<db::Edge, db::PolygonRef, db::Edge> : public local_operation<db::Edge, db::PolygonRef, db::Edge>
{ {
public: public:
Edge2PolygonInteractingLocalOperation (EdgeInteractionMode mode, bool inverse) enum output_mode_t { Normal, Inverse, Both };
: m_mode (mode), m_inverse (inverse)
Edge2PolygonInteractingLocalOperation (EdgeInteractionMode mode, output_mode_t output_mode)
: m_mode (mode), m_output_mode (output_mode)
{ {
// .. nothing yet .. // .. nothing yet ..
} }
@ -1325,9 +1385,15 @@ public:
virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); 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> &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; db::box_scanner2<db::Edge, size_t, db::Polygon, size_t> scanner;
std::set<db::PolygonRef> others; std::set<db::PolygonRef> others;
@ -1348,17 +1414,26 @@ public:
scanner.insert2 (& heap.back (), 1); scanner.insert2 (& heap.back (), 1);
} }
if (m_inverse) { if (m_output_mode == Inverse || m_output_mode == Both) {
std::unordered_set<db::Edge> interacting; std::unordered_set<db::Edge> interacting;
edge_to_region_interaction_filter<std::unordered_set<db::Edge> > filter (&interacting, m_mode); 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> ()); 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) { for (shape_interactions<db::Edge, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
const db::Edge &subject = interactions.subject_shape (i->first); const db::Edge &subject = interactions.subject_shape (i->first);
if (interacting.find (subject) == interacting.end ()) { 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); result.insert (subject);
} }
} }
} else { } else {
@ -1371,7 +1446,7 @@ public:
virtual OnEmptyIntruderHint on_empty_intruder_hint () const virtual OnEmptyIntruderHint on_empty_intruder_hint () const
{ {
if (m_inverse) { if (m_output_mode != Normal) {
return Copy; return Copy;
} else { } else {
return Drop; return Drop;
@ -1385,7 +1460,7 @@ public:
private: private:
EdgeInteractionMode m_mode; EdgeInteractionMode m_mode;
bool m_inverse; output_mode_t m_output_mode;
}; };
struct ResultInserter struct ResultInserter
@ -1481,7 +1556,7 @@ DeepEdges::selected_interacting_generic (const Region &other, EdgeInteractionMod
DeepLayer dl_out (edges.derived ()); DeepLayer dl_out (edges.derived ());
db::Edge2PolygonInteractingLocalOperation op (mode, inverse); db::Edge2PolygonInteractingLocalOperation op (mode, inverse ? db::Edge2PolygonInteractingLocalOperation::Inverse : db::Edge2PolygonInteractingLocalOperation::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 ()); 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 ());
proc.set_base_verbosity (base_verbosity ()); proc.set_base_verbosity (base_verbosity ());
@ -1492,6 +1567,38 @@ DeepEdges::selected_interacting_generic (const Region &other, EdgeInteractionMod
return new db::DeepEdges (dl_out); return new db::DeepEdges (dl_out);
} }
std::pair<EdgesDelegate *, EdgesDelegate *>
DeepEdges::selected_interacting_pair_generic (const Region &other, EdgeInteractionMode mode) const
{
std::unique_ptr<db::DeepRegion> dr_holder;
const db::DeepRegion *other_deep = dynamic_cast<const db::DeepRegion *> (other.delegate ());
if (! other_deep) {
// if the other region isn't deep, turn into a top-level only deep region to facilitate re-hierarchization
dr_holder.reset (new db::DeepRegion (other, const_cast<db::DeepShapeStore &> (*deep_layer ().store ())));
other_deep = dr_holder.get ();
}
const db::DeepLayer &edges = merged_deep_layer ();
DeepLayer dl_out (edges.derived ());
DeepLayer dl_out2 (edges.derived ());
std::vector<unsigned int> output_layers;
output_layers.reserve (2);
output_layers.push_back (dl_out.layer ());
output_layers.push_back (dl_out2.layer ());
db::Edge2PolygonInteractingLocalOperation op (mode, db::Edge2PolygonInteractingLocalOperation::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 ());
proc.set_base_verbosity (base_verbosity ());
proc.set_threads (edges.store ()->threads ());
proc.run (&op, edges.layer (), other_deep->deep_layer ().layer (), output_layers);
return std::make_pair (new db::DeepEdges (dl_out), new db::DeepEdges (dl_out2));
}
EdgesDelegate * EdgesDelegate *
DeepEdges::selected_interacting_generic (const Edges &other, EdgeInteractionMode mode, bool inverse) const DeepEdges::selected_interacting_generic (const Edges &other, EdgeInteractionMode mode, bool inverse) const
{ {
@ -1507,7 +1614,7 @@ DeepEdges::selected_interacting_generic (const Edges &other, EdgeInteractionMode
DeepLayer dl_out (edges.derived ()); DeepLayer dl_out (edges.derived ());
db::Edge2EdgeInteractingLocalOperation op (mode, inverse); db::Edge2EdgeInteractingLocalOperation op (mode, inverse ? db::Edge2EdgeInteractingLocalOperation::Inverse : db::Edge2EdgeInteractingLocalOperation::Normal);
db::local_processor<db::Edge, db::Edge, 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 ()); db::local_processor<db::Edge, db::Edge, 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 ());
proc.set_base_verbosity (base_verbosity ()); proc.set_base_verbosity (base_verbosity ());
@ -1519,17 +1626,35 @@ DeepEdges::selected_interacting_generic (const Edges &other, EdgeInteractionMode
} }
std::pair<EdgesDelegate *, EdgesDelegate *> std::pair<EdgesDelegate *, EdgesDelegate *>
DeepEdges::selected_interacting_pair_generic (const Edges &edges, EdgeInteractionMode mode) const DeepEdges::selected_interacting_pair_generic (const Edges &other, EdgeInteractionMode mode) const
{ {
// @@@ std::unique_ptr<db::DeepEdges> dr_holder;
return std::pair<EdgesDelegate *, EdgesDelegate *>(); const db::DeepEdges *other_deep = dynamic_cast<const db::DeepEdges *> (other.delegate ());
} if (! other_deep) {
// if the other edge collection isn't deep, turn into a top-level only deep edge collection to facilitate re-hierarchization
dr_holder.reset (new db::DeepEdges (other, const_cast<db::DeepShapeStore &> (*deep_layer ().store ())));
other_deep = dr_holder.get ();
}
std::pair<EdgesDelegate *, EdgesDelegate *> const db::DeepLayer &edges = merged_deep_layer ();
DeepEdges::selected_interacting_pair_generic (const Region &region, EdgeInteractionMode mode) const
{ DeepLayer dl_out (edges.derived ());
// @@@ DeepLayer dl_out2 (edges.derived ());
return std::pair<EdgesDelegate *, EdgesDelegate *>();
std::vector<unsigned int> output_layers;
output_layers.reserve (2);
output_layers.push_back (dl_out.layer ());
output_layers.push_back (dl_out2.layer ());
db::Edge2EdgeInteractingLocalOperation op (mode, db::Edge2EdgeInteractingLocalOperation::Both);
db::local_processor<db::Edge, db::Edge, 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 ());
proc.set_base_verbosity (base_verbosity ());
proc.set_threads (edges.store ()->threads ());
proc.run (&op, edges.layer (), other_deep->deep_layer ().layer (), output_layers);
return std::make_pair (new db::DeepEdges (dl_out), new db::DeepEdges (dl_out2));
} }
RegionDelegate *DeepEdges::pull_generic (const Region &other) const RegionDelegate *DeepEdges::pull_generic (const Region &other) const

View File

@ -182,7 +182,7 @@ private:
void ensure_merged_edges_valid () const; void ensure_merged_edges_valid () const;
const DeepLayer &merged_deep_layer () const; const DeepLayer &merged_deep_layer () const;
DeepLayer and_or_not_with(const DeepEdges *other, EdgeBoolOp op) const; DeepLayer and_or_not_with(const DeepEdges *other, EdgeBoolOp op) const;
DeepLayer edge_region_op (const DeepRegion *other, bool outside, bool include_borders) const; std::pair<DeepLayer, DeepLayer> edge_region_op (const DeepRegion *other, EdgePolygonOp::mode_t op, bool include_borders) const;
EdgePairsDelegate *run_check (db::edge_relation_type rel, const Edges *other, db::Coord d, const db::EdgesCheckOptions &options) const; 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 EdgesDelegate *pull_generic (const Edges &edges) const;
virtual RegionDelegate *pull_generic (const Region &region) const; virtual RegionDelegate *pull_generic (const Region &region) const;

View File

@ -20,12 +20,11 @@
*/ */
#include "dbLocalOperation.h"
#include "dbHierProcessor.h" #include "dbHierProcessor.h"
#include "dbBoxScanner.h" #include "dbBoxScanner.h"
#include "dbRecursiveShapeIterator.h" #include "dbRecursiveShapeIterator.h"
#include "dbBoxConvert.h" #include "dbBoxConvert.h"
#include "dbEdgeProcessor.h"
#include "dbPolygonGenerators.h" #include "dbPolygonGenerators.h"
#include "dbPolygonTools.h" #include "dbPolygonTools.h"
#include "dbLocalOperationUtils.h" #include "dbLocalOperationUtils.h"
@ -366,10 +365,16 @@ EdgeBoolAndOrNotLocalOperation::description () const
void void
EdgeBoolAndOrNotLocalOperation::do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const EdgeBoolAndOrNotLocalOperation::do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == size_t (m_op == EdgeAndNot ? 2 : 1));
std::unordered_set<db::Edge> &result = results.front (); std::unordered_set<db::Edge> &result = results.front ();
EdgeBooleanClusterCollector<std::unordered_set<db::Edge> > cluster_collector (&result, m_op); std::unordered_set<db::Edge> *result2 = 0;
if (results.size () > 1) {
result2 = &results[1];
}
EdgeBooleanClusterCollector<std::unordered_set<db::Edge> > cluster_collector (&result, m_op, result2);
db::box_scanner<db::Edge, size_t> scanner; db::box_scanner<db::Edge, size_t> scanner;
@ -381,7 +386,7 @@ EdgeBoolAndOrNotLocalOperation::do_compute_local (db::Layout * /*layout*/, const
} }
bool any_subject = false; bool any_subject = false;
bool is_and = (m_op == EdgeAnd || m_op == EdgeIntersections); bool is_and = (m_op == EdgeAnd || m_op == EdgeAndNot || m_op == EdgeIntersections);
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) { for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
@ -416,8 +421,8 @@ EdgeBoolAndOrNotLocalOperation::do_compute_local (db::Layout * /*layout*/, const
// --------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------
// EdgeToPolygonLocalOperation implementation // EdgeToPolygonLocalOperation implementation
EdgeToPolygonLocalOperation::EdgeToPolygonLocalOperation (bool outside, bool include_borders) EdgeToPolygonLocalOperation::EdgeToPolygonLocalOperation (EdgePolygonOp::mode_t op, bool include_borders)
: m_outside (outside), m_include_borders (include_borders) : m_op (op), m_include_borders (include_borders)
{ {
// .. nothing yet .. // .. nothing yet ..
} }
@ -425,21 +430,33 @@ EdgeToPolygonLocalOperation::EdgeToPolygonLocalOperation (bool outside, bool inc
OnEmptyIntruderHint OnEmptyIntruderHint
EdgeToPolygonLocalOperation::on_empty_intruder_hint () const EdgeToPolygonLocalOperation::on_empty_intruder_hint () const
{ {
return m_outside ? Copy : Drop; return (m_op == EdgePolygonOp::Inside) ? Copy : Drop;
} }
std::string std::string
EdgeToPolygonLocalOperation::description () const EdgeToPolygonLocalOperation::description () const
{ {
return tl::to_string (m_outside ? tr ("Edge to polygon AND/INSIDE") : tr ("Edge to polygons NOT/OUTSIDE")); if (m_op == EdgePolygonOp::Inside) {
return tl::to_string (tr ("Edge to polygon AND/INSIDE"));
} else if (m_op == EdgePolygonOp::Outside) {
return tl::to_string (tr ("Edge to polygon NOT/OUTSIDE"));
} else {
return tl::to_string (tr ("Edge to polygon ANDNOT/INOUTSIDE"));
}
} }
void void
EdgeToPolygonLocalOperation::do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const EdgeToPolygonLocalOperation::do_compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const
{ {
tl_assert (results.size () == 1); tl_assert (results.size () == size_t (m_op == EdgePolygonOp::Both ? 2 : 1));
std::unordered_set<db::Edge> &result = results.front (); std::unordered_set<db::Edge> &result = results.front ();
std::unordered_set<db::Edge> *result2 = 0;
if (results.size () > 1) {
result2 = &results[1];
}
db::EdgeProcessor ep; db::EdgeProcessor ep;
std::set<db::PolygonRef> others; std::set<db::PolygonRef> others;
@ -456,8 +473,10 @@ EdgeToPolygonLocalOperation::do_compute_local (db::Layout * /*layout*/, const sh
const db::Edge &subject = interactions.subject_shape (i->first); const db::Edge &subject = interactions.subject_shape (i->first);
if (i->second.empty ()) { if (i->second.empty ()) {
// shortcut (outside: keep, otherwise: drop) // shortcut (outside: keep, otherwise: drop)
if (m_outside) { if (m_op == db::EdgePolygonOp::Outside) {
result.insert (subject); result.insert (subject);
} else if (m_op == db::EdgePolygonOp::Both) {
result2->insert (subject);
} }
} else { } else {
ep.insert (subject, 1); ep.insert (subject, 1);
@ -475,7 +494,7 @@ EdgeToPolygonLocalOperation::do_compute_local (db::Layout * /*layout*/, const sh
} }
db::EdgeToEdgeSetGenerator cc (result); db::EdgeToEdgeSetGenerator cc (result);
db::EdgePolygonOp op (m_outside ? db::EdgePolygonOp::Outside : db::EdgePolygonOp::Inside, m_include_borders); db::EdgePolygonOp op (m_op, m_include_borders);
ep.process (cc, op); ep.process (cc, op);
} }

View File

@ -29,6 +29,7 @@
#include "dbLayout.h" #include "dbLayout.h"
#include "dbEdgeBoolean.h" #include "dbEdgeBoolean.h"
#include "dbEdgeProcessor.h"
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
@ -187,7 +188,7 @@ class DB_PUBLIC EdgeBoolAndOrNotLocalOperation
: public local_operation<db::Edge, db::Edge, db::Edge> : public local_operation<db::Edge, db::Edge, db::Edge>
{ {
public: public:
EdgeBoolAndOrNotLocalOperation (EdgeBoolOp op); EdgeBoolAndOrNotLocalOperation (db::EdgeBoolOp op);
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &result, size_t max_vertex_count, double area_ratio) const; virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::Edge> &interactions, std::vector<std::unordered_set<db::Edge> > &result, size_t max_vertex_count, double area_ratio) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
@ -197,7 +198,7 @@ public:
virtual db::Coord dist () const { return 1; } virtual db::Coord dist () const { return 1; }
private: private:
EdgeBoolOp m_op; db::EdgeBoolOp m_op;
}; };
/** /**
@ -210,7 +211,7 @@ class DB_PUBLIC EdgeToPolygonLocalOperation
: public local_operation<db::Edge, db::PolygonRef, db::Edge> : public local_operation<db::Edge, db::PolygonRef, db::Edge>
{ {
public: public:
EdgeToPolygonLocalOperation (bool outside, bool include_borders); EdgeToPolygonLocalOperation (EdgePolygonOp::mode_t op, bool include_borders);
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &result, size_t max_vertex_count, double area_ratio) const; virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &result, size_t max_vertex_count, double area_ratio) const;
virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const;
@ -220,7 +221,7 @@ public:
virtual db::Coord dist () const { return m_include_borders ? 1 : 0; } virtual db::Coord dist () const { return m_include_borders ? 1 : 0; }
private: private:
bool m_outside; db::EdgePolygonOp::mode_t m_op;
bool m_include_borders; bool m_include_borders;
}; };

View File

@ -1181,7 +1181,7 @@ NetlistCompareCore::derive_node_identities_from_singular_match (const NetGraphNo
} }
return tentative ? failed_match : 0; return tentative ? failed_match : 0;
} else if ((! n->has_any_other () && ! n_other->has_any_other ()) || (n->has_unknown_other () && n_other->has_unknown_other ())) { // @@@ } else if ((! n->has_any_other () && ! n_other->has_any_other ()) || (n->has_unknown_other () && n_other->has_unknown_other ())) {
// in tentative mode, reject this choice if both nets are named and // in tentative mode, reject this choice if both nets are named and
// their names differ -> this favors net matching by name // their names differ -> this favors net matching by name