mirror of https://github.com/KLayout/klayout.git
First implementation
This commit is contained in:
parent
4af9b8b01c
commit
956a27ec69
|
|
@ -797,12 +797,21 @@ DeepEdges::and_or_not_with (const DeepEdges *other, EdgeBoolOp op) const
|
|||
return dl_out;
|
||||
}
|
||||
|
||||
DeepLayer
|
||||
DeepEdges::edge_region_op (const DeepRegion *other, bool outside, bool include_borders) const
|
||||
std::pair<DeepLayer, DeepLayer>
|
||||
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 ());
|
||||
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_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
|
||||
|
|
@ -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
|
||||
{
|
||||
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
|
||||
{
|
||||
const DeepRegion *other_deep = dynamic_cast <const DeepRegion *> (other.delegate ());
|
||||
|
|
@ -925,23 +934,36 @@ EdgesDelegate *DeepEdges::not_with (const Region &other) const
|
|||
|
||||
} 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 *>
|
||||
DeepEdges::andnot_with (const Edges &) const
|
||||
DeepEdges::andnot_with (const Edges &other) const
|
||||
{
|
||||
// @@@
|
||||
return std::pair<EdgesDelegate *, EdgesDelegate *>();
|
||||
}
|
||||
const DeepRegion *other_deep = dynamic_cast <const DeepRegion *> (other.delegate ());
|
||||
|
||||
std::pair<EdgesDelegate *, EdgesDelegate *>
|
||||
DeepEdges::andnot_with (const Region &) const
|
||||
{
|
||||
// @@@
|
||||
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::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
|
||||
|
|
@ -1037,11 +1059,11 @@ EdgesDelegate *DeepEdges::inside_part (const Region &other) const
|
|||
|
||||
} else if (! other_deep) {
|
||||
|
||||
return AsIfFlatEdges::not_with (other);
|
||||
return AsIfFlatEdges::inside_part (other);
|
||||
|
||||
} 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) {
|
||||
|
||||
return AsIfFlatEdges::not_with (other);
|
||||
return AsIfFlatEdges::outside_part (other);
|
||||
|
||||
} 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
|
||||
{
|
||||
// @@@
|
||||
return std::pair<EdgesDelegate *, EdgesDelegate *>();
|
||||
const DeepRegion *other_deep = dynamic_cast <const DeepRegion *> (other.delegate ());
|
||||
|
||||
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
|
||||
|
|
@ -1177,8 +1219,10 @@ class Edge2EdgeInteractingLocalOperation
|
|||
: public local_operation<db::Edge, db::Edge, db::Edge>
|
||||
{
|
||||
public:
|
||||
Edge2EdgeInteractingLocalOperation (EdgeInteractionMode mode, bool inverse)
|
||||
: m_mode (mode), m_inverse (inverse)
|
||||
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 ..
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
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> *result2 = 0;
|
||||
if (m_output_mode == Both) {
|
||||
result2 = &results[1];
|
||||
}
|
||||
|
||||
db::box_scanner<db::Edge, size_t> scanner;
|
||||
|
||||
std::set<db::Edge> others;
|
||||
|
|
@ -1212,17 +1262,25 @@ public:
|
|||
scanner.insert (o.operator-> (), 1);
|
||||
}
|
||||
|
||||
if (m_inverse) {
|
||||
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 {
|
||||
|
|
@ -1236,7 +1294,7 @@ public:
|
|||
|
||||
virtual OnEmptyIntruderHint on_empty_intruder_hint () const
|
||||
{
|
||||
if (m_inverse) {
|
||||
if (m_output_mode != Normal) {
|
||||
return Copy;
|
||||
} else {
|
||||
return Drop;
|
||||
|
|
@ -1250,7 +1308,7 @@ public:
|
|||
|
||||
private:
|
||||
EdgeInteractionMode m_mode;
|
||||
bool m_inverse;
|
||||
output_mode_t m_output_mode;
|
||||
};
|
||||
|
||||
class Edge2EdgePullLocalOperation
|
||||
|
|
@ -1311,8 +1369,10 @@ class Edge2PolygonInteractingLocalOperation
|
|||
: public local_operation<db::Edge, db::PolygonRef, db::Edge>
|
||||
{
|
||||
public:
|
||||
Edge2PolygonInteractingLocalOperation (EdgeInteractionMode mode, bool inverse)
|
||||
: m_mode (mode), m_inverse (inverse)
|
||||
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 ..
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
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> *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;
|
||||
|
|
@ -1348,17 +1414,26 @@ public:
|
|||
scanner.insert2 (& heap.back (), 1);
|
||||
}
|
||||
|
||||
if (m_inverse) {
|
||||
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 {
|
||||
|
|
@ -1371,7 +1446,7 @@ public:
|
|||
|
||||
virtual OnEmptyIntruderHint on_empty_intruder_hint () const
|
||||
{
|
||||
if (m_inverse) {
|
||||
if (m_output_mode != Normal) {
|
||||
return Copy;
|
||||
} else {
|
||||
return Drop;
|
||||
|
|
@ -1385,7 +1460,7 @@ public:
|
|||
|
||||
private:
|
||||
EdgeInteractionMode m_mode;
|
||||
bool m_inverse;
|
||||
output_mode_t m_output_mode;
|
||||
};
|
||||
|
||||
struct ResultInserter
|
||||
|
|
@ -1481,7 +1556,7 @@ DeepEdges::selected_interacting_generic (const Region &other, EdgeInteractionMod
|
|||
|
||||
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 ());
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
|
|
@ -1492,6 +1567,38 @@ DeepEdges::selected_interacting_generic (const Region &other, EdgeInteractionMod
|
|||
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 *
|
||||
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 ());
|
||||
|
||||
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 ());
|
||||
proc.set_base_verbosity (base_verbosity ());
|
||||
|
|
@ -1519,17 +1626,35 @@ DeepEdges::selected_interacting_generic (const Edges &other, EdgeInteractionMode
|
|||
}
|
||||
|
||||
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
|
||||
{
|
||||
// @@@
|
||||
return std::pair<EdgesDelegate *, EdgesDelegate *>();
|
||||
}
|
||||
std::unique_ptr<db::DeepEdges> dr_holder;
|
||||
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 *>
|
||||
DeepEdges::selected_interacting_pair_generic (const Region ®ion, EdgeInteractionMode mode) const
|
||||
{
|
||||
// @@@
|
||||
return std::pair<EdgesDelegate *, EdgesDelegate *>();
|
||||
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::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
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ private:
|
|||
void ensure_merged_edges_valid () const;
|
||||
const DeepLayer &merged_deep_layer () 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;
|
||||
virtual EdgesDelegate *pull_generic (const Edges &edges) const;
|
||||
virtual RegionDelegate *pull_generic (const Region ®ion) const;
|
||||
|
|
|
|||
|
|
@ -20,12 +20,11 @@
|
|||
|
||||
*/
|
||||
|
||||
|
||||
#include "dbLocalOperation.h"
|
||||
#include "dbHierProcessor.h"
|
||||
#include "dbBoxScanner.h"
|
||||
#include "dbRecursiveShapeIterator.h"
|
||||
#include "dbBoxConvert.h"
|
||||
#include "dbEdgeProcessor.h"
|
||||
#include "dbPolygonGenerators.h"
|
||||
#include "dbPolygonTools.h"
|
||||
#include "dbLocalOperationUtils.h"
|
||||
|
|
@ -366,10 +365,16 @@ EdgeBoolAndOrNotLocalOperation::description () const
|
|||
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
|
||||
{
|
||||
tl_assert (results.size () == 1);
|
||||
tl_assert (results.size () == size_t (m_op == EdgeAndNot ? 2 : 1));
|
||||
|
||||
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;
|
||||
|
||||
|
|
@ -381,7 +386,7 @@ EdgeBoolAndOrNotLocalOperation::do_compute_local (db::Layout * /*layout*/, const
|
|||
}
|
||||
|
||||
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) {
|
||||
|
||||
|
|
@ -416,8 +421,8 @@ EdgeBoolAndOrNotLocalOperation::do_compute_local (db::Layout * /*layout*/, const
|
|||
// ---------------------------------------------------------------------------------------------
|
||||
// EdgeToPolygonLocalOperation implementation
|
||||
|
||||
EdgeToPolygonLocalOperation::EdgeToPolygonLocalOperation (bool outside, bool include_borders)
|
||||
: m_outside (outside), m_include_borders (include_borders)
|
||||
EdgeToPolygonLocalOperation::EdgeToPolygonLocalOperation (EdgePolygonOp::mode_t op, bool include_borders)
|
||||
: m_op (op), m_include_borders (include_borders)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -425,21 +430,33 @@ EdgeToPolygonLocalOperation::EdgeToPolygonLocalOperation (bool outside, bool inc
|
|||
OnEmptyIntruderHint
|
||||
EdgeToPolygonLocalOperation::on_empty_intruder_hint () const
|
||||
{
|
||||
return m_outside ? Copy : Drop;
|
||||
return (m_op == EdgePolygonOp::Inside) ? Copy : Drop;
|
||||
}
|
||||
|
||||
std::string
|
||||
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
|
||||
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> *result2 = 0;
|
||||
if (results.size () > 1) {
|
||||
result2 = &results[1];
|
||||
}
|
||||
|
||||
db::EdgeProcessor ep;
|
||||
|
||||
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);
|
||||
if (i->second.empty ()) {
|
||||
// shortcut (outside: keep, otherwise: drop)
|
||||
if (m_outside) {
|
||||
if (m_op == db::EdgePolygonOp::Outside) {
|
||||
result.insert (subject);
|
||||
} else if (m_op == db::EdgePolygonOp::Both) {
|
||||
result2->insert (subject);
|
||||
}
|
||||
} else {
|
||||
ep.insert (subject, 1);
|
||||
|
|
@ -475,7 +494,7 @@ EdgeToPolygonLocalOperation::do_compute_local (db::Layout * /*layout*/, const sh
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "dbLayout.h"
|
||||
#include "dbEdgeBoolean.h"
|
||||
#include "dbEdgeProcessor.h"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
|
@ -187,7 +188,7 @@ class DB_PUBLIC EdgeBoolAndOrNotLocalOperation
|
|||
: public local_operation<db::Edge, db::Edge, db::Edge>
|
||||
{
|
||||
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 OnEmptyIntruderHint on_empty_intruder_hint () const;
|
||||
|
|
@ -197,7 +198,7 @@ public:
|
|||
virtual db::Coord dist () const { return 1; }
|
||||
|
||||
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:
|
||||
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 OnEmptyIntruderHint on_empty_intruder_hint () const;
|
||||
|
|
@ -220,7 +221,7 @@ public:
|
|||
virtual db::Coord dist () const { return m_include_borders ? 1 : 0; }
|
||||
|
||||
private:
|
||||
bool m_outside;
|
||||
db::EdgePolygonOp::mode_t m_op;
|
||||
bool m_include_borders;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1181,7 +1181,7 @@ NetlistCompareCore::derive_node_identities_from_singular_match (const NetGraphNo
|
|||
}
|
||||
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
|
||||
// their names differ -> this favors net matching by name
|
||||
|
|
|
|||
Loading…
Reference in New Issue