diff --git a/src/db/db/dbAsIfFlatEdges.cc b/src/db/db/dbAsIfFlatEdges.cc index d48fbb0c3..0a6a27a75 100644 --- a/src/db/db/dbAsIfFlatEdges.cc +++ b/src/db/db/dbAsIfFlatEdges.cc @@ -141,7 +141,7 @@ AsIfFlatEdges::selected_interacting_generic (const Region &other, EdgeInteractio db::EdgesIterator edges (begin_merged ()); - db::edge_to_polygon_interacting_local_operation op (mode, inverse ? db::edge_to_polygon_interacting_local_operation::Inverse : db::edge_to_polygon_interacting_local_operation::Normal); + db::edge_to_polygon_interacting_local_operation op (mode, inverse ? db::edge_to_polygon_interacting_local_operation::Inverse : db::edge_to_polygon_interacting_local_operation::Normal, min_count, max_count); db::local_processor proc; proc.set_base_verbosity (base_verbosity ()); @@ -173,7 +173,7 @@ AsIfFlatEdges::selected_interacting_generic (const Edges &other, EdgeInteraction db::EdgesIterator edges (begin_merged ()); - db::Edge2EdgeInteractingLocalOperation op (mode, inverse ? db::Edge2EdgeInteractingLocalOperation::Inverse : db::Edge2EdgeInteractingLocalOperation::Normal); + db::Edge2EdgeInteractingLocalOperation op (mode, inverse ? db::Edge2EdgeInteractingLocalOperation::Inverse : db::Edge2EdgeInteractingLocalOperation::Normal, min_count, max_count); db::local_processor proc; proc.set_base_verbosity (base_verbosity ()); @@ -209,7 +209,7 @@ AsIfFlatEdges::selected_interacting_pair_generic (const Region &other, EdgeInter db::EdgesIterator edges (begin_merged ()); - db::edge_to_polygon_interacting_local_operation op (mode, db::edge_to_polygon_interacting_local_operation::Both); + db::edge_to_polygon_interacting_local_operation op (mode, db::edge_to_polygon_interacting_local_operation::Both, min_count, max_count); db::local_processor proc; proc.set_base_verbosity (base_verbosity ()); @@ -245,7 +245,7 @@ AsIfFlatEdges::selected_interacting_pair_generic (const Edges &other, EdgeIntera db::EdgesIterator edges (begin_merged ()); - db::Edge2EdgeInteractingLocalOperation op (mode, db::Edge2EdgeInteractingLocalOperation::Both); + db::Edge2EdgeInteractingLocalOperation op (mode, db::Edge2EdgeInteractingLocalOperation::Both, min_count, max_count); db::local_processor proc; proc.set_base_verbosity (base_verbosity ()); @@ -280,7 +280,7 @@ AsIfFlatEdges::pull_generic (const Edges &edges) const } std::unique_ptr output (new FlatEdges (true)); - edge_interaction_filter filter (*output, EdgesInteract); + edge_interaction_filter filter (*output, EdgesInteract, size_t (1), std::numeric_limits::max ()); scanner.process (filter, 1, db::box_convert ()); return output.release (); diff --git a/src/db/db/dbDeepEdges.cc b/src/db/db/dbDeepEdges.cc index 39d406d1b..80e90ebe8 100644 --- a/src/db/db/dbDeepEdges.cc +++ b/src/db/db/dbDeepEdges.cc @@ -1370,7 +1370,7 @@ DeepEdges::selected_interacting_generic (const Region &other, EdgeInteractionMod DeepLayer dl_out (edges.derived ()); - db::edge_to_polygon_interacting_local_operation op (mode, inverse ? db::edge_to_polygon_interacting_local_operation::Inverse : db::edge_to_polygon_interacting_local_operation::Normal); + db::edge_to_polygon_interacting_local_operation op (mode, inverse ? db::edge_to_polygon_interacting_local_operation::Inverse : db::edge_to_polygon_interacting_local_operation::Normal, min_count, max_count); db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), edges.breakout_cells (), other_deep->deep_layer ().breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); @@ -1403,7 +1403,7 @@ DeepEdges::selected_interacting_pair_generic (const Region &other, EdgeInteracti output_layers.push_back (dl_out.layer ()); output_layers.push_back (dl_out2.layer ()); - db::edge_to_polygon_interacting_local_operation op (mode, db::edge_to_polygon_interacting_local_operation::Both); + db::edge_to_polygon_interacting_local_operation op (mode, db::edge_to_polygon_interacting_local_operation::Both, min_count, max_count); db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), edges.breakout_cells (), other_deep->deep_layer ().breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); @@ -1430,7 +1430,7 @@ DeepEdges::selected_interacting_generic (const Edges &other, EdgeInteractionMode DeepLayer dl_out (edges.derived ()); - db::Edge2EdgeInteractingLocalOperation op (mode, inverse ? db::Edge2EdgeInteractingLocalOperation::Inverse : db::Edge2EdgeInteractingLocalOperation::Normal); + db::Edge2EdgeInteractingLocalOperation op (mode, inverse ? db::Edge2EdgeInteractingLocalOperation::Inverse : db::Edge2EdgeInteractingLocalOperation::Normal, min_count, max_count); db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), edges.breakout_cells (), other_deep->deep_layer ().breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); @@ -1463,7 +1463,7 @@ DeepEdges::selected_interacting_pair_generic (const Edges &other, EdgeInteractio output_layers.push_back (dl_out.layer ()); output_layers.push_back (dl_out2.layer ()); - db::Edge2EdgeInteractingLocalOperation op (mode, db::Edge2EdgeInteractingLocalOperation::Both); + db::Edge2EdgeInteractingLocalOperation op (mode, db::Edge2EdgeInteractingLocalOperation::Both, min_count, max_count); db::local_processor proc (const_cast (&edges.layout ()), const_cast (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), edges.breakout_cells (), other_deep->deep_layer ().breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); diff --git a/src/db/db/dbEdgesLocalOperations.cc b/src/db/db/dbEdgesLocalOperations.cc index 28bc77979..77e21d06c 100644 --- a/src/db/db/dbEdgesLocalOperations.cc +++ b/src/db/db/dbEdgesLocalOperations.cc @@ -202,8 +202,8 @@ EdgeToPolygonLocalOperation::do_compute_local (db::Layout * /*layout*/, db::Cell // --------------------------------------------------------------------------------------------- // Edge2EdgeInteractingLocalOperation implementation -Edge2EdgeInteractingLocalOperation::Edge2EdgeInteractingLocalOperation (EdgeInteractionMode mode, output_mode_t output_mode) - : m_mode (mode), m_output_mode (output_mode) +Edge2EdgeInteractingLocalOperation::Edge2EdgeInteractingLocalOperation (EdgeInteractionMode mode, output_mode_t output_mode, size_t min_count, size_t max_count) + : m_mode (mode), m_output_mode (output_mode), m_min_count (min_count), m_max_count (max_count) { // .. nothing yet .. } @@ -246,7 +246,7 @@ void Edge2EdgeInteractingLocalOperation::do_compute_local (db::Layout * /*layout if (m_output_mode == Inverse || m_output_mode == Both) { std::unordered_set interacting; - edge_interaction_filter > filter (interacting, m_mode); + edge_interaction_filter > filter (interacting, m_mode, m_min_count, m_max_count); scanner.process (filter, 1, db::box_convert ()); for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { @@ -266,7 +266,7 @@ void Edge2EdgeInteractingLocalOperation::do_compute_local (db::Layout * /*layout } else { - edge_interaction_filter > filter (result, m_mode); + edge_interaction_filter > filter (result, m_mode, m_min_count, m_max_count); scanner.process (filter, 1, db::box_convert ()); } @@ -324,7 +324,7 @@ void Edge2EdgePullLocalOperation::do_compute_local (db::Layout * /*layout*/, db: scanner.insert (o.operator-> (), 0); } - edge_interaction_filter > filter (result, EdgesInteract); + edge_interaction_filter > filter (result, EdgesInteract, size_t (1), std::numeric_limits::max ()); scanner.process (filter, 1, db::box_convert ()); } @@ -344,9 +344,10 @@ std::string Edge2EdgePullLocalOperation::description () const // Edge2EdgePullLocalOperation implementation template -edge_to_polygon_interacting_local_operation::edge_to_polygon_interacting_local_operation (EdgeInteractionMode mode, output_mode_t output_mode) +edge_to_polygon_interacting_local_operation::edge_to_polygon_interacting_local_operation (EdgeInteractionMode mode, output_mode_t output_mode, size_t min_count, size_t max_count) : m_mode (mode), m_output_mode (output_mode) { + // @@@ // .. nothing yet .. } diff --git a/src/db/db/dbEdgesLocalOperations.h b/src/db/db/dbEdgesLocalOperations.h index eea3f1006..1dd45f182 100644 --- a/src/db/db/dbEdgesLocalOperations.h +++ b/src/db/db/dbEdgesLocalOperations.h @@ -89,7 +89,7 @@ class DB_PUBLIC Edge2EdgeInteractingLocalOperation public: enum output_mode_t { Normal, Inverse, Both }; - Edge2EdgeInteractingLocalOperation (EdgeInteractionMode mode, output_mode_t output_mode); + Edge2EdgeInteractingLocalOperation (EdgeInteractionMode mode, output_mode_t output_mode, size_t min_count, size_t max_count); virtual db::Coord dist () const; virtual void do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions &interactions, std::vector > &results, const db::LocalProcessorBase * /*proc*/) const; @@ -99,6 +99,7 @@ public: private: EdgeInteractionMode m_mode; output_mode_t m_output_mode; + size_t m_min_count, m_max_count; }; /** @@ -126,7 +127,7 @@ class DB_PUBLIC_TEMPLATE edge_to_polygon_interacting_local_operation public: enum output_mode_t { Normal, Inverse, Both }; - edge_to_polygon_interacting_local_operation (EdgeInteractionMode mode, output_mode_t output_mode); + edge_to_polygon_interacting_local_operation (EdgeInteractionMode mode, output_mode_t output_mode, size_t min_count, size_t max_count); virtual db::Coord dist () const; virtual void do_compute_local (db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions &interactions, std::vector > &results, const db::LocalProcessorBase * /*proc*/) const; diff --git a/src/db/db/dbEdgesUtils.h b/src/db/db/dbEdgesUtils.h index 939cd6140..42fb2ce03 100644 --- a/src/db/db/dbEdgesUtils.h +++ b/src/db/db/dbEdgesUtils.h @@ -339,16 +339,38 @@ class edge_interaction_filter : public db::box_scanner_receiver { public: - edge_interaction_filter (OutputContainer &output, EdgeInteractionMode mode) - : mp_output (&output), m_mode (mode) + edge_interaction_filter (OutputContainer &output, EdgeInteractionMode mode, size_t min_count, size_t max_count) + : mp_output (&output), m_mode (mode), m_min_count (min_count), m_max_count (max_count) { - // .. nothing yet .. + // NOTE: "counting" does not really make much sense in Outside mode ... + m_counting = !(min_count == 1 && max_count == std::numeric_limits::max ()); } void finish (const db::Edge *o, size_t p) { - if (p == 0 && m_mode == EdgesOutside && m_seen.find (o) == m_seen.end ()) { - mp_output->insert (*o); + if (p != 0) { + return; + } + + if (m_counting) { + + size_t count = 0; + auto i = m_counts.find (o); + if (i != m_counts.end ()) { + count = i->second; + } + + bool match = (count >= m_min_count && count <= m_max_count); + if (match == (m_mode != EdgesOutside)) { + mp_output->insert (*o); + } + + } else { + + if (m_mode == EdgesOutside && m_seen.find (o) == m_seen.end ()) { + mp_output->insert (*o); + } + } } @@ -363,14 +385,22 @@ public: if ((m_mode == EdgesInteract && db::edge_interacts (*o, *oo)) || (m_mode == EdgesInside && db::edge_is_inside (*o, *oo))) { - if (m_seen.insert (o).second) { - mp_output->insert (*o); + if (m_counting) { + m_counts[o] += 1; + } else { + if (m_seen.insert (o).second) { + mp_output->insert (*o); + } } } else if (m_mode == EdgesOutside && ! db::edge_is_outside (*o, *oo)) { // In this case we need to collect edges which are outside always - we report those on "finished". - m_seen.insert (o); + if (m_counting) { + m_counts[o] += 1; + } else { + m_seen.insert (o); + } } @@ -380,7 +410,10 @@ public: private: OutputContainer *mp_output; std::set m_seen; + std::map m_counts; EdgeInteractionMode m_mode; + size_t m_min_count, m_max_count; + bool m_counting; }; /**