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;
|
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 ®ion, 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
|
||||||
|
|
|
||||||
|
|
@ -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 ®ion) const;
|
virtual RegionDelegate *pull_generic (const Region ®ion) const;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue