diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index 9547a71cf..b5655efe7 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -378,28 +378,77 @@ AsIfFlatRegion::processed_to_edge_pairs (const PolygonToEdgePairProcessorBase &f return new_edge_pairs.release (); } -RegionDelegate * -AsIfFlatRegion::selected_interacting_generic (const Edges &other, bool inverse, size_t min_count, size_t max_count) const +namespace { + +class OutputPairHolder { +public: + OutputPairHolder (InteractingOutputMode output_mode, bool merged_semantics) + { + if (output_mode == None) { + return; + } + + if (output_mode == Positive || output_mode == Negative || output_mode == PositiveAndNegative) { + m_positive.reset (new FlatRegion (merged_semantics)); + m_results.push_back (& m_positive->raw_polygons ()); + } else { + m_results.push_back ((db::Shapes *) 0); + } + + if (output_mode == PositiveAndNegative) { + m_negative.reset (new FlatRegion (merged_semantics)); + m_results.push_back (& m_negative->raw_polygons ()); + } + } + + std::pair region_pair () + { + return std::make_pair (m_positive.release (), m_negative.release ()); + } + + const std::vector &results () { return m_results; } + +private: + std::unique_ptr m_positive, m_negative; + std::vector m_results; +}; + +} + +std::pair +AsIfFlatRegion::selected_interacting_generic (const Edges &other, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const +{ + OutputPairHolder oph (output_mode, merged_semantics ()); + + if (output_mode == None) { + return oph.region_pair (); + } + min_count = std::max (size_t (1), min_count); - if (max_count < min_count || other.empty ()) { - if (! inverse) { - return new EmptyRegion (); + // shortcut + if (empty ()) { + if (output_mode == Positive || output_mode == Negative) { + return std::make_pair (const_cast (this), (RegionDelegate *) 0); } else { - return clone (); + return std::make_pair (const_cast (this), const_cast (this)); + } + } else if (max_count < min_count || other.empty ()) { + if (output_mode == Positive) { + return std::make_pair (new EmptyRegion (), (RegionDelegate *) 0); + } else if (output_mode == Negative) { + return std::make_pair (const_cast (this), (RegionDelegate *) 0); + } else { + return std::make_pair (new EmptyRegion (), const_cast (this)); } - } else if (empty ()) { - return clone (); } bool counting = !(min_count == 1 && max_count == std::numeric_limits::max ()); -#if defined(USE_LOCAL_PROCESSOR) - db::RegionIterator polygons (begin_merged ()); - db::interacting_with_edge_local_operation op (inverse, min_count, max_count, true); + db::interacting_with_edge_local_operation op (output_mode, min_count, max_count, true); db::local_processor proc; proc.set_base_verbosity (base_verbosity ()); @@ -413,71 +462,42 @@ AsIfFlatRegion::selected_interacting_generic (const Edges &other, bool inverse, std::vector results; results.push_back (&output->raw_polygons ()); - proc.run_flat (polygons, others, std::vector (), &op, results); + proc.run_flat (polygons, others, std::vector (), &op, oph.results ()); - return output.release (); - -#else - std::unordered_map > counted_results; - ResultCountingInserter inserter (counted_results); - - db::box_scanner2 scanner (report_progress (), progress_desc ()); - scanner.reserve1 (count ()); - scanner.reserve2 (other.count ()); - - std::unique_ptr output (new FlatRegion (false)); - region_to_edge_interaction_filter filter (inserter, false, counting /*get all in counting mode*/); - - AddressablePolygonDelivery p (begin_merged ()); - - for ( ; ! p.at_end (); ++p) { - scanner.insert1 (p.operator-> (), 0); - if (inverse) { - inserter.init (p.operator-> ()); - } - } - - AddressableEdgeDelivery e (counting ? other.addressable_merged_edges () : other.addressable_edges ()); - - for ( ; ! e.at_end (); ++e) { - scanner.insert2 (e.operator-> (), 0); - } - - scanner.process (filter, 1, db::box_convert (), db::box_convert ()); - - // select hits based on their count - - for (std::unordered_map >::const_iterator r = counted_results.begin (); r != counted_results.end (); ++r) { - bool hit = r->second >= min_count && r->second <= max_count; - if (hit != inverse) { - output->insert (*r->first); - } - } - - return output.release (); -#endif + return oph.region_pair (); } -RegionDelegate * -AsIfFlatRegion::selected_interacting_generic (const Texts &other, bool inverse, size_t min_count, size_t max_count) const +std::pair +AsIfFlatRegion::selected_interacting_generic (const Texts &other, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const { - min_count = std::max (size_t (1), min_count); + OutputPairHolder oph (output_mode, merged_semantics ()); - if (max_count < min_count || other.empty ()) { - if (! inverse) { - return new EmptyRegion (); - } else { - return clone (); - } - } else if (empty ()) { - return clone (); + if (output_mode == None) { + return oph.region_pair (); } -#if defined(USE_LOCAL_PROCESSOR) + min_count = std::max (size_t (1), min_count); + + // shortcut + if (empty ()) { + if (output_mode == Positive || output_mode == Negative) { + return std::make_pair (const_cast (this), (RegionDelegate *) 0); + } else { + return std::make_pair (const_cast (this), const_cast (this)); + } + } else if (max_count < min_count || other.empty ()) { + if (output_mode == Positive) { + return std::make_pair (new EmptyRegion (), (RegionDelegate *) 0); + } else if (output_mode == Negative) { + return std::make_pair (const_cast (this), (RegionDelegate *) 0); + } else { + return std::make_pair (new EmptyRegion (), const_cast (this)); + } + } db::RegionIterator polygons (begin_merged ()); - db::interacting_with_text_local_operation op (inverse, min_count, max_count); + db::interacting_with_text_local_operation op (output_mode, min_count, max_count); db::local_processor proc; proc.set_base_verbosity (base_verbosity ()); @@ -487,84 +507,58 @@ AsIfFlatRegion::selected_interacting_generic (const Texts &other, bool inverse, std::vector > others; others.push_back (other.begin ()); - std::unique_ptr output (new FlatRegion (merged_semantics ())); - std::vector results; - results.push_back (&output->raw_polygons ()); + proc.run_flat (polygons, others, std::vector (), &op, oph.results ()); - proc.run_flat (polygons, others, std::vector (), &op, results); - - return output.release (); - -#else - bool counting = !(min_count == 1 && max_count == std::numeric_limits::max ()); - - std::unordered_map > counted_results; - ResultCountingInserter inserter (counted_results); - - db::box_scanner2 scanner (report_progress (), progress_desc ()); - scanner.reserve1 (count ()); - scanner.reserve2 (other.count ()); - - region_to_text_interaction_filter filter (inserter, false, counting /*get all in counting mode*/); - - AddressablePolygonDelivery p (begin_merged ()); - - for ( ; ! p.at_end (); ++p) { - scanner.insert1 (p.operator-> (), 0); - if (inverse) { - inserter.init (p.operator-> ()); - } - } - - AddressableTextDelivery e (other.addressable_texts ()); - - for ( ; ! e.at_end (); ++e) { - scanner.insert2 (e.operator-> (), 0); - } - - scanner.process (filter, 1, db::box_convert (), db::box_convert ()); - - // select hits based on their count - - std::unique_ptr output (new FlatRegion (true)); - - for (std::unordered_map >::const_iterator r = counted_results.begin (); r != counted_results.end (); ++r) { - bool hit = r->second >= min_count && r->second <= max_count; - if (hit != inverse) { - output->insert (*r->first); - } - } - - return output.release (); -#endif + return oph.region_pair (); } -RegionDelegate * -AsIfFlatRegion::selected_interacting_generic (const Region &other, int mode, bool touching, bool inverse, size_t min_count, size_t max_count) const + +std::pair +AsIfFlatRegion::selected_interacting_generic (const Region &other, int mode, bool touching, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const { + OutputPairHolder oph (output_mode, merged_semantics ()); + + if (output_mode == None) { + return oph.region_pair (); + } + min_count = std::max (size_t (1), min_count); // shortcut if (empty ()) { - return clone (); + if (output_mode == Positive || output_mode == Negative) { + return std::make_pair (const_cast (this), (RegionDelegate *) 0); + } else { + return std::make_pair (const_cast (this), const_cast (this)); + } } else if (max_count < min_count || other.empty ()) { // clear, if b is empty and // * mode is inside, enclosing or interacting and inverse is false ("inside" or "interacting") // * mode is outside and inverse is true ("not outside") - if ((mode <= 0) != inverse) { - return new EmptyRegion (); + if ((mode <= 0)) { + if (output_mode == Positive) { + return std::make_pair (new EmptyRegion (), (RegionDelegate *) 0); + } else if (output_mode == Negative) { + return std::make_pair (const_cast (this), (RegionDelegate *) 0); + } else { + return std::make_pair (new EmptyRegion (), const_cast (this)); + } } else { - return clone (); + if (output_mode == Positive) { + return std::make_pair (const_cast (this), (RegionDelegate *) 0); + } else if (output_mode == Negative) { + return std::make_pair (new EmptyRegion (), (RegionDelegate *) 0); + } else { + return std::make_pair (const_cast (this), new EmptyRegion ()); + } } } -#if defined(USE_LOCAL_PROCESSOR) - bool counting = !(min_count == 1 && max_count == std::numeric_limits::max ()); db::RegionIterator polygons (begin_merged ()); - db::interacting_local_operation op (mode, touching, inverse, min_count, max_count, true); + db::interacting_local_operation op (mode, touching, output_mode, min_count, max_count, true); db::local_processor proc; proc.set_base_verbosity (base_verbosity ()); @@ -574,121 +568,9 @@ AsIfFlatRegion::selected_interacting_generic (const Region &other, int mode, boo std::vector > others; others.push_back ((mode < 0 || counting) ? other.begin_merged () : other.begin ()); - std::unique_ptr output (new FlatRegion (merged_semantics ())); - std::vector results; - results.push_back (&output->raw_polygons ()); + proc.run_flat (polygons, others, std::vector (), &op, oph.results ()); - proc.run_flat (polygons, others, std::vector (), &op, results); - - return output.release (); - -#else - db::EdgeProcessor ep (report_progress (), progress_desc ()); - ep.set_base_verbosity (base_verbosity ()); - - size_t n = 0; - size_t nstart = 0; - - if (mode < -1) { - - // in enclosing mode self must be primary and other the secondary. For other - // modes it's the other way round - - for (RegionIterator p (begin_merged ()); ! p.at_end (); ++p, ++n) { - if (mode > 0 || p->box ().touches (other.bbox ())) { - ep.insert (*p, n); - } - } - - nstart = n; - - } - - if (min_count == size_t (1) && max_count == std::numeric_limits::max ()) { - - if (mode < 0) { - - // NOTE: on "inside" or "enclosing", the other region must be merged - for (RegionIterator p = other.begin_merged (); ! p.at_end (); ++p) { - if (p->box ().touches (bbox ())) { - ep.insert (*p, n); - } - } - - } else { - - for (RegionIterator p = other.begin (); ! p.at_end (); ++p) { - if (p->box ().touches (bbox ())) { - ep.insert (*p, n); - } - } - - } - - ++n; - - } else { - - // with counting we need to separate the other polygons by different properties - - // cannot only have min_count/max_count in outside mode - tl_assert (mode <= 0); - - for (RegionIterator p = other.begin_merged (); ! p.at_end (); ++p) { - if (p->box ().touches (bbox ())) { - ep.insert (*p, n); - } - ++n; - } - - } - - if (mode >= -1) { - - nstart = n; - - for (RegionIterator p (begin_merged ()); ! p.at_end (); ++p, ++n) { - if (mode > 0 || p->box ().touches (other.bbox ())) { - ep.insert (*p, n); - } - } - - } - - // there should be at least one element to look at for primary - tl_assert (nstart > 0); - - db::InteractionDetector id (mode, nstart - 1); - id.set_include_touching (touching); - db::EdgeSink es; - ep.process (es, id); - id.finish (); - - std::unique_ptr output (new FlatRegion (false)); - - std::map interaction_counts; - for (db::InteractionDetector::iterator i = id.begin (); i != id.end () ; ++i) { - if (i->first < nstart && i->second >= nstart) { - interaction_counts [mode < -1 ? i->first : i->second] += 1; - } - } - - output->reserve (n); - - n = (mode < -1 ? 0 : nstart); - for (RegionIterator p (begin_merged ()); ! p.at_end (); ++p, ++n) { - size_t count = 0; - std::map ::const_iterator c = interaction_counts.find (n); - if (c != interaction_counts.end ()) { - count = c->second; - } - if ((count >= min_count && count <= max_count) != inverse) { - output->insert (*p); - } - } - - return output.release (); -#endif + return oph.region_pair (); } EdgesDelegate * diff --git a/src/db/db/dbAsIfFlatRegion.h b/src/db/db/dbAsIfFlatRegion.h index eecec66d3..d2b8ff9e3 100644 --- a/src/db/db/dbAsIfFlatRegion.h +++ b/src/db/db/dbAsIfFlatRegion.h @@ -139,72 +139,107 @@ public: virtual RegionDelegate *selected_outside (const Region &other) const { - return selected_interacting_generic (other, 1, false, false); + return selected_interacting_generic (other, 1, false, Positive, size_t (0), std::numeric_limits::max ()).first; } virtual RegionDelegate *selected_not_outside (const Region &other) const { - return selected_interacting_generic (other, 1, false, true); + return selected_interacting_generic (other, 1, false, Negative, size_t (0), std::numeric_limits::max ()).first; + } + + virtual std::pair selected_outside_pair (const Region &other) const + { + return selected_interacting_generic (other, 1, false, PositiveAndNegative, size_t (0), std::numeric_limits::max ()); } virtual RegionDelegate *selected_inside (const Region &other) const { - return selected_interacting_generic (other, -1, true, false); + return selected_interacting_generic (other, -1, true, Positive, size_t (0), std::numeric_limits::max ()).first; } virtual RegionDelegate *selected_not_inside (const Region &other) const { - return selected_interacting_generic (other, -1, true, true); + return selected_interacting_generic (other, -1, true, Negative, size_t (0), std::numeric_limits::max ()).first; + } + + virtual std::pair selected_inside_pair (const Region &other) const + { + return selected_interacting_generic (other, -1, true, PositiveAndNegative, size_t (0), std::numeric_limits::max ()); } virtual RegionDelegate *selected_enclosing (const Region &other, size_t min_count, size_t max_count) const { - return selected_interacting_generic (other, -2, false, false, min_count, max_count); + return selected_interacting_generic (other, -2, false, Positive, min_count, max_count).first; } virtual RegionDelegate *selected_not_enclosing (const Region &other, size_t min_count, size_t max_count) const { - return selected_interacting_generic (other, -2, false, true, min_count, max_count); + return selected_interacting_generic (other, -2, false, Negative, min_count, max_count).first; + } + + virtual std::pair selected_enclosing_pair (const Region &other, size_t min_count, size_t max_count) const + { + return selected_interacting_generic (other, -2, false, PositiveAndNegative, min_count, max_count); } virtual RegionDelegate *selected_interacting (const Region &other, size_t min_count, size_t max_count) const { - return selected_interacting_generic (other, 0, true, false, min_count, max_count); + return selected_interacting_generic (other, 0, true, Positive, min_count, max_count).first; } virtual RegionDelegate *selected_not_interacting (const Region &other, size_t min_count, size_t max_count) const { - return selected_interacting_generic (other, 0, true, true, min_count, max_count); + return selected_interacting_generic (other, 0, true, Negative, min_count, max_count).first; + } + + virtual std::pair selected_interacting_pair (const Region &other, size_t min_count, size_t max_count) const + { + return selected_interacting_generic (other, 0, true, PositiveAndNegative, min_count, max_count); } virtual RegionDelegate *selected_interacting (const Edges &other, size_t min_count, size_t max_count) const { - return selected_interacting_generic (other, false, min_count, max_count); + return selected_interacting_generic (other, Positive, min_count, max_count).first; } virtual RegionDelegate *selected_not_interacting (const Edges &other, size_t min_count, size_t max_count) const { - return selected_interacting_generic (other, true, min_count, max_count); + return selected_interacting_generic (other, Negative, min_count, max_count).first; + } + + virtual std::pair selected_interacting_pair (const Edges &other, size_t min_count, size_t max_count) const + { + return selected_interacting_generic (other, PositiveAndNegative, min_count, max_count); } virtual RegionDelegate *selected_interacting (const Texts &other, size_t min_count, size_t max_count) const { - return selected_interacting_generic (other, false, min_count, max_count); + return selected_interacting_generic (other, Positive, min_count, max_count).first; } virtual RegionDelegate *selected_not_interacting (const Texts &other, size_t min_count, size_t max_count) const { - return selected_interacting_generic (other, true, min_count, max_count); + return selected_interacting_generic (other, Negative, min_count, max_count).first; + } + + virtual std::pair selected_interacting_pair (const Texts &other, size_t min_count, size_t max_count) const + { + return selected_interacting_generic (other, PositiveAndNegative, min_count, max_count); } virtual RegionDelegate *selected_overlapping (const Region &other, size_t min_count, size_t max_count) const { - return selected_interacting_generic (other, 0, false, false, min_count, max_count); + return selected_interacting_generic (other, 0, false, Positive, min_count, max_count).first; } virtual RegionDelegate *selected_not_overlapping (const Region &other, size_t min_count, size_t max_count) const { - return selected_interacting_generic (other, 0, false, true, min_count, max_count); + return selected_interacting_generic (other, 0, false, Negative, min_count, max_count).first; + } + + virtual std::pair selected_overlapping_pair (const Region &other, size_t min_count, size_t max_count) const + { + return selected_interacting_generic (other, 0, false, PositiveAndNegative, min_count, max_count); } virtual RegionDelegate *pull_inside (const Region &other) const @@ -245,9 +280,9 @@ protected: virtual EdgePairsDelegate *run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, const RegionCheckOptions &options) const; virtual EdgePairsDelegate *run_single_polygon_check (db::edge_relation_type rel, db::Coord d, const RegionCheckOptions &options) const; - virtual RegionDelegate *selected_interacting_generic (const Region &other, int mode, bool touching, bool inverse, size_t min_count = 1, size_t max_count = std::numeric_limits::max ()) const; - virtual RegionDelegate *selected_interacting_generic (const Edges &other, bool inverse, size_t min_count = 1, size_t max_count = std::numeric_limits::max ()) const; - virtual RegionDelegate *selected_interacting_generic (const Texts &other, bool inverse, size_t min_count = 1, size_t max_count = std::numeric_limits::max ()) const; + virtual std::pair selected_interacting_generic (const Region &other, int mode, bool touching, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const; + virtual std::pair selected_interacting_generic (const Edges &other, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const; + virtual std::pair selected_interacting_generic (const Texts &other, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const; virtual RegionDelegate *pull_generic (const Region &other, int mode, bool touching) const; virtual EdgesDelegate *pull_generic (const Edges &other) const; virtual TextsDelegate *pull_generic (const Texts &other) const; diff --git a/src/db/db/dbCompoundOperation.cc b/src/db/db/dbCompoundOperation.cc index d0d175149..db4aedd84 100644 --- a/src/db/db/dbCompoundOperation.cc +++ b/src/db/db/dbCompoundOperation.cc @@ -1060,13 +1060,13 @@ template void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_lo // --------------------------------------------------------------------------------------------- CompoundRegionInteractOperationNode::CompoundRegionInteractOperationNode (CompoundRegionOperationNode *a, CompoundRegionOperationNode *b, int mode, bool touching, bool inverse, size_t min_count, size_t max_count) - : compound_region_generic_operation_node (&m_op, a, b), m_op (mode, touching, inverse, min_count, max_count, b->is_merged ()) + : compound_region_generic_operation_node (&m_op, a, b), m_op (mode, touching, inverse ? Negative : Positive, min_count, max_count, b->is_merged ()) { // .. nothing yet .. } CompoundRegionInteractOperationNode::CompoundRegionInteractOperationNode (db::Region *a, db::Region *b, int mode, bool touching, bool inverse, size_t min_count, size_t max_count) - : compound_region_generic_operation_node (&m_op, a, b), m_op (mode, touching, inverse, min_count, max_count, b->is_merged ()) + : compound_region_generic_operation_node (&m_op, a, b), m_op (mode, touching, inverse ? Negative : Positive, min_count, max_count, b->is_merged ()) { // .. nothing yet .. } @@ -1080,7 +1080,7 @@ CompoundRegionInteractOperationNode::generated_description () const // --------------------------------------------------------------------------------------------- CompoundRegionInteractWithEdgeOperationNode::CompoundRegionInteractWithEdgeOperationNode (CompoundRegionOperationNode *a, CompoundRegionOperationNode *b, bool inverse, size_t min_count, size_t max_count) - : compound_region_generic_operation_node (&m_op, a, b), m_op (inverse, min_count, max_count, b->is_merged ()) + : compound_region_generic_operation_node (&m_op, a, b), m_op (inverse ? Negative : Positive, min_count, max_count, b->is_merged ()) { // .. nothing yet .. } diff --git a/src/db/db/dbCompoundOperation.h b/src/db/db/dbCompoundOperation.h index 4f211a239..c7d285465 100644 --- a/src/db/db/dbCompoundOperation.h +++ b/src/db/db/dbCompoundOperation.h @@ -753,7 +753,8 @@ public: virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions & /*interactions*/, std::vector > & /*results*/, size_t /*max_vertex_count*/, double /*area_ratio*/) const { } private: - db::interacting_local_operation m_op; + typedef db::interacting_local_operation op_type; + op_type m_op; }; class DB_PUBLIC CompoundRegionInteractWithEdgeOperationNode diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index bc49410e9..db74b18ff 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -1519,9 +1519,67 @@ DeepRegion::run_single_polygon_check (db::edge_relation_type rel, db::Coord d, c return res.release (); } -RegionDelegate * -DeepRegion::selected_interacting_generic (const Region &other, int mode, bool touching, bool inverse, size_t min_count, size_t max_count) const +namespace { + +class InteractingResultHolder +{ +public: + InteractingResultHolder (InteractingOutputMode output_mode, bool is_merged, const db::DeepLayer &polygons) + : m_output_mode (output_mode), m_is_merged (is_merged) + { + if (m_output_mode == Positive || m_output_mode == Negative) { + m_dl1 = db::DeepLayer (polygons.derived ()); + } else if (m_output_mode == PositiveAndNegative) { + m_dl1 = db::DeepLayer (polygons.derived ()); + m_dl2 = db::DeepLayer (polygons.derived ()); + } + } + + std::vector layers () const + { + std::vector l; + if (m_output_mode == Positive || m_output_mode == Negative) { + l.push_back (m_dl1.layer ()); + } else if (m_output_mode == PositiveAndNegative) { + l.push_back (m_dl1.layer ()); + l.push_back (m_dl2.layer ()); + } + return l; + } + + std::pair result_pair () + { + if (m_output_mode == Positive || m_output_mode == Negative) { + db::DeepRegion *res = new db::DeepRegion (m_dl1); + res->set_is_merged (m_is_merged); + return std::pair (res, 0); + } else if (m_output_mode == PositiveAndNegative) { + db::DeepRegion *res1 = new db::DeepRegion (m_dl1); + res1->set_is_merged (m_is_merged); + db::DeepRegion *res2 = new db::DeepRegion (m_dl2); + res2->set_is_merged (m_is_merged); + return std::pair (res1, res2); + } else { + return std::pair (0, 0); + } + } + +private: + InteractingOutputMode m_output_mode; + bool m_is_merged; + DeepLayer m_dl1, m_dl2; +}; + +} + +std::pair +DeepRegion::selected_interacting_generic (const Region &other, int mode, bool touching, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const +{ + if (output_mode == None) { + return std::pair (0, 0); + } + bool counting = !(min_count == 1 && max_count == std::numeric_limits::max ()); // with these flag set to true, the resulting polygons are broken again. @@ -1539,9 +1597,7 @@ DeepRegion::selected_interacting_generic (const Region &other, int mode, bool to // NOTE: on "inside" or with counting, the other polygons must be merged const db::DeepLayer &other_polygons = (mode < 0 || counting) ? other_deep->merged_deep_layer () : other_deep->deep_layer (); - DeepLayer dl_out (polygons.derived ()); - - db::InteractingLocalOperation op (mode, touching, inverse, min_count, max_count, true); + db::InteractingLocalOperation op (mode, touching, output_mode, min_count, max_count, true); db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_polygons.layout (), &other_polygons.initial_cell (), polygons.breakout_cells (), other_polygons.breakout_cells ()); proc.set_description (progress_desc ()); @@ -1553,17 +1609,16 @@ DeepRegion::selected_interacting_generic (const Region &other, int mode, bool to proc.set_max_vertex_count (polygons.store ()->max_vertex_count ()); } - proc.run (&op, polygons.layer (), other_polygons.layer (), dl_out.layer ()); + bool result_is_merged = (! split_after && ((mode < 0 && other.merged_semantics ()) || other.is_merged ()) && (merged_semantics () || is_merged ())); + InteractingResultHolder orh (output_mode, result_is_merged, polygons); - db::DeepRegion *res = new db::DeepRegion (dl_out); - if (! split_after && ((mode < 0 && other.merged_semantics ()) || other.is_merged ()) && (merged_semantics () || is_merged ())) { - res->set_is_merged (true); - } - return res; + proc.run (&op, polygons.layer (), other_polygons.layer (), orh.layers ()); + + return orh.result_pair (); } -RegionDelegate * -DeepRegion::selected_interacting_generic (const Edges &other, bool inverse, size_t min_count, size_t max_count) const +std::pair +DeepRegion::selected_interacting_generic (const Edges &other, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const { bool counting = !(min_count == 1 && max_count == std::numeric_limits::max ()); @@ -1580,9 +1635,7 @@ DeepRegion::selected_interacting_generic (const Edges &other, bool inverse, size const db::DeepLayer &polygons = merged_deep_layer (); - DeepLayer dl_out (polygons.derived ()); - - db::InteractingWithEdgeLocalOperation op (inverse, min_count, max_count, true); + db::InteractingWithEdgeLocalOperation op (output_mode, min_count, max_count, true); db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), polygons.breakout_cells (), other_deep->deep_layer ().breakout_cells ()); proc.set_description (progress_desc ()); @@ -1594,13 +1647,12 @@ DeepRegion::selected_interacting_generic (const Edges &other, bool inverse, size proc.set_max_vertex_count (polygons.store ()->max_vertex_count ()); } - proc.run (&op, polygons.layer (), counting ? other_deep->merged_deep_layer ().layer () : other_deep->deep_layer ().layer (), dl_out.layer ()); + bool result_is_merged = (! split_after && other.is_merged () && (merged_semantics () || is_merged ())); + InteractingResultHolder orh (output_mode, result_is_merged, polygons); - db::DeepRegion *res = new db::DeepRegion (dl_out); - if (! split_after) { - res->set_is_merged (other.is_merged () && (merged_semantics () || is_merged ())); - } - return res; + proc.run (&op, polygons.layer (), counting ? other_deep->merged_deep_layer ().layer () : other_deep->deep_layer ().layer (), orh.layers ()); + + return orh.result_pair (); } RegionDelegate * @@ -1706,8 +1758,9 @@ DeepRegion::pull_generic (const Texts &other) const return res; } -RegionDelegate * -DeepRegion::selected_interacting_generic (const Texts &other, bool inverse, size_t min_count, size_t max_count) const + +std::pair +DeepRegion::selected_interacting_generic (const Texts &other, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const { // with these flag set to true, the resulting polygons are broken again. bool split_after = false; @@ -1722,9 +1775,7 @@ DeepRegion::selected_interacting_generic (const Texts &other, bool inverse, size const db::DeepLayer &polygons = merged_deep_layer (); - DeepLayer dl_out (polygons.derived ()); - - db::InteractingWithTextLocalOperation op (inverse, min_count, max_count); + db::InteractingWithTextLocalOperation op (output_mode, min_count, max_count); db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell (), polygons.breakout_cells (), other_deep->deep_layer ().breakout_cells ()); proc.set_description (progress_desc ()); @@ -1736,13 +1787,12 @@ DeepRegion::selected_interacting_generic (const Texts &other, bool inverse, size proc.set_max_vertex_count (polygons.store ()->max_vertex_count ()); } - proc.run (&op, polygons.layer (), other_deep->deep_layer ().layer (), dl_out.layer ()); + bool result_is_merged = (! split_after && (merged_semantics () || is_merged ())); + InteractingResultHolder orh (output_mode, result_is_merged, polygons); - db::DeepRegion *res = new db::DeepRegion (dl_out); - if (! split_after) { - res->set_is_merged (merged_semantics () || is_merged ()); - } - return res; + proc.run (&op, polygons.layer (), other_deep->deep_layer ().layer (), orh.layers ()); + + return orh.result_pair (); } } diff --git a/src/db/db/dbDeepRegion.h b/src/db/db/dbDeepRegion.h index 138350c07..c15913f2c 100644 --- a/src/db/db/dbDeepRegion.h +++ b/src/db/db/dbDeepRegion.h @@ -140,9 +140,9 @@ protected: virtual EdgePairsDelegate *run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, const RegionCheckOptions &options) const; virtual EdgePairsDelegate *run_single_polygon_check (db::edge_relation_type rel, db::Coord d, const RegionCheckOptions &options) const; - virtual RegionDelegate *selected_interacting_generic (const Region &other, int mode, bool touching, bool inverse, size_t min_count, size_t max_count) const; - virtual RegionDelegate *selected_interacting_generic (const Edges &other, bool inverse, size_t min_count, size_t max_count) const; - virtual RegionDelegate *selected_interacting_generic (const Texts &other, bool inverse, size_t min_count, size_t max_count) const; + virtual std::pair selected_interacting_generic (const Region &other, int mode, bool touching, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const; + virtual std::pair selected_interacting_generic (const Edges &other, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const; + virtual std::pair selected_interacting_generic (const Texts &other, InteractingOutputMode output_mode, size_t min_count, size_t max_count) const; virtual RegionDelegate *pull_generic (const Region &other, int mode, bool touching) const; virtual EdgesDelegate *pull_generic (const Edges &other) const; virtual TextsDelegate *pull_generic (const Texts &other) const; diff --git a/src/db/db/dbEmptyRegion.h b/src/db/db/dbEmptyRegion.h index 6e99c8938..89e82c68a 100644 --- a/src/db/db/dbEmptyRegion.h +++ b/src/db/db/dbEmptyRegion.h @@ -108,18 +108,25 @@ public: virtual RegionDelegate *selected_outside (const Region &) const { return new EmptyRegion (); } virtual RegionDelegate *selected_not_outside (const Region &) const { return new EmptyRegion (); } + virtual std::pair selected_outside_pair (const Region &) const { return std::make_pair (new EmptyRegion (), new EmptyRegion ()); } virtual RegionDelegate *selected_inside (const Region &) const { return new EmptyRegion (); } virtual RegionDelegate *selected_not_inside (const Region &) const { return new EmptyRegion (); } + virtual std::pair selected_inside_pair (const Region &) const { return std::make_pair (new EmptyRegion (), new EmptyRegion ()); } virtual RegionDelegate *selected_enclosing (const Region &, size_t, size_t) const { return new EmptyRegion (); } virtual RegionDelegate *selected_not_enclosing (const Region &, size_t, size_t) const { return new EmptyRegion (); } + virtual std::pair selected_enclosing_pair (const Region &, size_t, size_t) const { return std::make_pair (new EmptyRegion (), new EmptyRegion ()); } virtual RegionDelegate *selected_interacting (const Region &, size_t, size_t) const { return new EmptyRegion (); } virtual RegionDelegate *selected_not_interacting (const Region &, size_t, size_t) const { return new EmptyRegion (); } + virtual std::pair selected_interacting_pair (const Region &, size_t, size_t) const { return std::make_pair (new EmptyRegion (), new EmptyRegion ()); } virtual RegionDelegate *selected_interacting (const Edges &, size_t, size_t) const { return new EmptyRegion (); } virtual RegionDelegate *selected_not_interacting (const Edges &, size_t, size_t) const { return new EmptyRegion (); } + virtual std::pair selected_interacting_pair (const Edges &, size_t, size_t) const { return std::make_pair (new EmptyRegion (), new EmptyRegion ()); } virtual RegionDelegate *selected_interacting (const Texts &, size_t, size_t) const { return new EmptyRegion (); } virtual RegionDelegate *selected_not_interacting (const Texts &, size_t, size_t) const { return new EmptyRegion (); } + virtual std::pair selected_interacting_pair (const Texts &, size_t, size_t) const { return std::make_pair (new EmptyRegion (), new EmptyRegion ()); } virtual RegionDelegate *selected_overlapping (const Region &, size_t, size_t) const { return new EmptyRegion (); } virtual RegionDelegate *selected_not_overlapping (const Region &, size_t, size_t) const { return new EmptyRegion (); } + virtual std::pair selected_overlapping_pair (const Region &, size_t, size_t) const { return std::make_pair (new EmptyRegion (), new EmptyRegion ()); } virtual RegionDelegate *pull_inside (const Region &) const { return new EmptyRegion (); } virtual RegionDelegate *pull_interacting (const Region &) const { return new EmptyRegion (); } virtual EdgesDelegate *pull_interacting (const Edges &) const { return new EmptyEdges (); } diff --git a/src/db/db/dbHierProcessor.cc b/src/db/db/dbHierProcessor.cc index 6b534eabb..df90ff1ba 100644 --- a/src/db/db/dbHierProcessor.cc +++ b/src/db/db/dbHierProcessor.cc @@ -1280,6 +1280,14 @@ void local_processor::run (local_operation *op, unsigned run (op, subject_layer, il, ol); } +template +void local_processor::run (local_operation *op, unsigned int subject_layer, unsigned int intruder_layer, const std::vector &output_layers) +{ + std::vector ol, il; + il.push_back (intruder_layer); + run (op, subject_layer, il, output_layers); +} + template void local_processor::run (local_operation *op, unsigned int subject_layer, const std::vector &intruder_layers, unsigned int output_layer) { diff --git a/src/db/db/dbHierProcessor.h b/src/db/db/dbHierProcessor.h index 71ecdb311..c65da727f 100644 --- a/src/db/db/dbHierProcessor.h +++ b/src/db/db/dbHierProcessor.h @@ -419,6 +419,7 @@ public: local_processor (db::Layout *layout = 0, db::Cell *top = 0, const std::set *breakout_cells = 0); local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_cell, const std::set *subject_breakout_cells = 0, const std::set *intruder_breakout_cells = 0); void run (local_operation *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layers); + void run (local_operation *op, unsigned int subject_layer, unsigned int intruder_layer, const std::vector &output_layers); void run (local_operation *op, unsigned int subject_layer, const std::vector &intruder_layers, const std::vector &output_layers); void run (local_operation *op, unsigned int subject_layer, const std::vector &intruder_layers, unsigned int output_layer); void compute_contexts (local_processor_contexts &contexts, const local_operation *op, unsigned int subject_layer, const std::vector &intruder_layers) const; diff --git a/src/db/db/dbLocalOperation.h b/src/db/db/dbLocalOperation.h index abf6b4165..972e36c96 100644 --- a/src/db/db/dbLocalOperation.h +++ b/src/db/db/dbLocalOperation.h @@ -54,6 +54,11 @@ enum OnEmptyIntruderHint { */ Copy, + /** + * @brief Copy the subject shape to the second result + */ + CopyToSecond, + /** * @brief Drop the subject shape */ diff --git a/src/db/db/dbRegionDelegate.h b/src/db/db/dbRegionDelegate.h index 593e4ed1d..a5178f606 100644 --- a/src/db/db/dbRegionDelegate.h +++ b/src/db/db/dbRegionDelegate.h @@ -281,18 +281,25 @@ public: virtual RegionDelegate *selected_outside (const Region &other) const = 0; virtual RegionDelegate *selected_not_outside (const Region &other) const = 0; + virtual std::pair selected_outside_pair (const Region &other) const = 0; virtual RegionDelegate *selected_inside (const Region &other) const = 0; virtual RegionDelegate *selected_not_inside (const Region &other) const = 0; + virtual std::pair selected_inside_pair (const Region &other) const = 0; virtual RegionDelegate *selected_enclosing (const Region &other, size_t min_count, size_t max_count) const = 0; virtual RegionDelegate *selected_not_enclosing (const Region &other, size_t min_count, size_t max_count) const = 0; + virtual std::pair selected_enclosing_pair (const Region &other, size_t min_count, size_t max_count) const = 0; virtual RegionDelegate *selected_interacting (const Region &other, size_t min_count, size_t max_count) const = 0; virtual RegionDelegate *selected_not_interacting (const Region &other, size_t min_count, size_t max_count) const = 0; + virtual std::pair selected_interacting_pair (const Region &other, size_t min_count, size_t max_count) const = 0; virtual RegionDelegate *selected_interacting (const Edges &other, size_t min_count, size_t max_count) const = 0; virtual RegionDelegate *selected_not_interacting (const Edges &other, size_t min_count, size_t max_count) const = 0; + virtual std::pair selected_interacting_pair (const Edges &other, size_t min_count, size_t max_count) const = 0; virtual RegionDelegate *selected_interacting (const Texts &other, size_t min_count, size_t max_count) const = 0; virtual RegionDelegate *selected_not_interacting (const Texts &other, size_t min_count, size_t max_count) const = 0; + virtual std::pair selected_interacting_pair (const Texts &other, size_t min_count, size_t max_count) const = 0; virtual RegionDelegate *selected_overlapping (const Region &other, size_t min_count, size_t max_count) const = 0; virtual RegionDelegate *selected_not_overlapping (const Region &other, size_t min_count, size_t max_count) const = 0; + virtual std::pair selected_overlapping_pair (const Region &other, size_t min_count, size_t max_count) const = 0; virtual RegionDelegate *pull_inside (const Region &other) const = 0; virtual RegionDelegate *pull_interacting (const Region &other) const = 0; virtual EdgesDelegate *pull_interacting (const Edges &other) const = 0; diff --git a/src/db/db/dbRegionLocalOperations.cc b/src/db/db/dbRegionLocalOperations.cc index 0b5f68c42..4ce824442 100644 --- a/src/db/db/dbRegionLocalOperations.cc +++ b/src/db/db/dbRegionLocalOperations.cc @@ -537,8 +537,8 @@ private: } template -interacting_local_operation::interacting_local_operation (int mode, bool touching, bool inverse, size_t min_count, size_t max_count, bool other_is_merged) - : m_mode (mode), m_touching (touching), m_inverse (inverse), m_min_count (std::max (size_t (1), min_count)), m_max_count (max_count), m_other_is_merged (other_is_merged) +interacting_local_operation::interacting_local_operation (int mode, bool touching, InteractingOutputMode output_mode, size_t min_count, size_t max_count, bool other_is_merged) + : m_mode (mode), m_touching (touching), m_output_mode (output_mode), m_min_count (std::max (size_t (1), min_count)), m_max_count (max_count), m_other_is_merged (other_is_merged) { // .. nothing yet .. } @@ -552,8 +552,13 @@ db::Coord interacting_local_operation::dist () const template void interacting_local_operation::do_compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { - tl_assert (results.size () == 1); - std::unordered_set &result = results.front (); + if (m_output_mode == None) { + return; + } else if (m_output_mode == Positive || m_output_mode == Negative) { + tl_assert (results.size () == 1); + } else { + tl_assert (results.size () == 2); + } db::EdgeProcessor ep; @@ -652,9 +657,21 @@ void interacting_local_operation::do_compute_local (db::Layout * /*l if (c != interaction_counts.end ()) { count = c->second; } - if ((count >= m_min_count && count <= m_max_count) != m_inverse) { - const TS &subject = interactions.subject_shape (i->first); - result.insert (subject); + bool good = (count >= m_min_count && count <= m_max_count); + if (good) { + if (m_output_mode == Positive || m_output_mode == PositiveAndNegative) { + const TS &subject = interactions.subject_shape (i->first); + results [0].insert (subject); + } + } else { + if (m_output_mode == Negative) { + const TS &subject = interactions.subject_shape (i->first); + // Yes, it's "positive_result" as this is the first one. + results [0].insert (subject); + } else if (m_output_mode == PositiveAndNegative) { + const TS &subject = interactions.subject_shape (i->first); + results [1].insert (subject); + } } } } @@ -663,11 +680,22 @@ template OnEmptyIntruderHint interacting_local_operation::on_empty_intruder_hint () const { - if ((m_mode <= 0) != m_inverse) { - return OnEmptyIntruderHint::Drop; + if ((m_mode <= 0)) { + if (m_output_mode == Positive) { + return OnEmptyIntruderHint::Drop; + } else if (m_output_mode == Negative) { + return OnEmptyIntruderHint::Copy; + } else if (m_output_mode == PositiveAndNegative) { + return OnEmptyIntruderHint::CopyToSecond; + } } else { - return OnEmptyIntruderHint::Copy; + if (m_output_mode == Positive || m_output_mode == PositiveAndNegative) { + return OnEmptyIntruderHint::Copy; + } else if (m_output_mode == Negative) { + return OnEmptyIntruderHint::Drop; + } } + return OnEmptyIntruderHint::Ignore; } template @@ -761,8 +789,8 @@ template class DB_PUBLIC pull_local_operation -interacting_with_edge_local_operation::interacting_with_edge_local_operation (bool inverse, size_t min_count, size_t max_count, bool other_is_merged) - : m_inverse (inverse), m_min_count (std::max (size_t (1), min_count)), m_max_count (max_count), m_other_is_merged (other_is_merged) +interacting_with_edge_local_operation::interacting_with_edge_local_operation (InteractingOutputMode output_mode, size_t min_count, size_t max_count, bool other_is_merged) + : m_output_mode (output_mode), m_min_count (std::max (size_t (1), min_count)), m_max_count (max_count), m_other_is_merged (other_is_merged) { // .. nothing yet .. } @@ -777,6 +805,14 @@ db::Coord interacting_with_edge_local_operation::dist () const template void interacting_with_edge_local_operation::do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + if (m_output_mode == None) { + return; + } else if (m_output_mode == Positive || m_output_mode == Negative) { + tl_assert (results.size () == 1); + } else { + tl_assert (results.size () == 2); + } + std::unordered_map counted_results; bool counting = !(m_min_count == 1 && m_max_count == std::numeric_limits::max ()); @@ -829,7 +865,7 @@ void interacting_with_edge_local_operation::do_compute_local (db::La const TR *addressable = push_polygon_to_heap (layout, subject, heap); scanner.insert1 (addressable, 0); - if (m_inverse) { + if (m_output_mode == Negative || m_output_mode == PositiveAndNegative) { inserter.init (*addressable); } @@ -839,13 +875,18 @@ void interacting_with_edge_local_operation::do_compute_local (db::La // select hits based on their count - tl_assert (results.size () == 1); - std::unordered_set &result = results.front (); - for (typename std::unordered_map::const_iterator r = counted_results.begin (); r != counted_results.end (); ++r) { bool hit = r->second >= m_min_count && r->second <= m_max_count; - if (hit != m_inverse) { - result.insert (r->first); + if (hit) { + if (m_output_mode == Positive || m_output_mode == PositiveAndNegative) { + results [0].insert (r->first); + } + } else { + if (m_output_mode == Negative) { + results [0].insert (r->first); + } else if (m_output_mode == PositiveAndNegative) { + results [1].insert (r->first); + } } } } @@ -853,10 +894,14 @@ void interacting_with_edge_local_operation::do_compute_local (db::La template OnEmptyIntruderHint interacting_with_edge_local_operation::on_empty_intruder_hint () const { - if (!m_inverse) { + if (m_output_mode == Positive) { return OnEmptyIntruderHint::Drop; - } else { + } else if (m_output_mode == Negative) { return OnEmptyIntruderHint::Copy; + } else if (m_output_mode == PositiveAndNegative) { + return OnEmptyIntruderHint::CopyToSecond; + } else { + return OnEmptyIntruderHint::Ignore; } } @@ -1000,8 +1045,8 @@ template class DB_PUBLIC pull_with_text_local_operation -interacting_with_text_local_operation::interacting_with_text_local_operation (bool inverse, size_t min_count, size_t max_count) - : m_inverse (inverse), m_min_count (std::max (size_t (1), min_count)), m_max_count (max_count) +interacting_with_text_local_operation::interacting_with_text_local_operation (InteractingOutputMode output_mode, size_t min_count, size_t max_count) + : m_output_mode (output_mode), m_min_count (std::max (size_t (1), min_count)), m_max_count (max_count) { // .. nothing yet .. } @@ -1017,6 +1062,14 @@ db::Coord interacting_with_text_local_operation::dist () const template void interacting_with_text_local_operation::do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const { + if (m_output_mode == None) { + return; + } else if (m_output_mode == Positive || m_output_mode == Negative) { + tl_assert (results.size () == 1); + } else { + tl_assert (results.size () == 2); + } + std::unordered_map counted_results; bool counting = !(m_min_count == 1 && m_max_count == std::numeric_limits::max ()); @@ -1042,7 +1095,7 @@ void interacting_with_text_local_operation::do_compute_local (db::La const TR *addressable = push_polygon_to_heap (layout, interactions.subject_shape (i->first), heap); scanner.insert1 (addressable, 0); - if (m_inverse) { + if (m_output_mode == Negative || m_output_mode == PositiveAndNegative) { inserter.init (*addressable); } @@ -1052,13 +1105,19 @@ void interacting_with_text_local_operation::do_compute_local (db::La // select hits based on their count - tl_assert (results.size () == 1); - std::unordered_set &result = results.front (); - for (typename std::unordered_map::const_iterator r = counted_results.begin (); r != counted_results.end (); ++r) { bool hit = r->second >= m_min_count && r->second <= m_max_count; - if (hit != m_inverse) { - result.insert (r->first); + if (hit) { + if (m_output_mode == Positive || m_output_mode == PositiveAndNegative) { + results [0].insert (r->first); + } + } else { + if (m_output_mode == Negative) { + // Yes. It's "positive"! This is the first output. + results [0].insert (r->first); + } else if (m_output_mode == PositiveAndNegative) { + results [1].insert (r->first); + } } } } @@ -1066,10 +1125,14 @@ void interacting_with_text_local_operation::do_compute_local (db::La template OnEmptyIntruderHint interacting_with_text_local_operation::on_empty_intruder_hint () const { - if (!m_inverse) { + if (m_output_mode == Positive) { return OnEmptyIntruderHint::Drop; - } else { + } else if (m_output_mode == Negative) { return OnEmptyIntruderHint::Copy; + } else if (m_output_mode == PositiveAndNegative) { + return OnEmptyIntruderHint::CopyToSecond; + } else { + return OnEmptyIntruderHint::Ignore; } } diff --git a/src/db/db/dbRegionLocalOperations.h b/src/db/db/dbRegionLocalOperations.h index 2b3977c25..d3958e15e 100644 --- a/src/db/db/dbRegionLocalOperations.h +++ b/src/db/db/dbRegionLocalOperations.h @@ -222,12 +222,16 @@ private: typedef check_local_operation CheckLocalOperation; +enum InteractingOutputMode { + None = 0, Positive = 1, Negative = 2, PositiveAndNegative = 3 +}; + template class interacting_local_operation : public local_operation { public: - interacting_local_operation (int mode, bool touching, bool inverse, size_t min_count, size_t max_count, bool other_is_merged); + interacting_local_operation (int mode, bool touching, InteractingOutputMode output_mode, size_t min_count, size_t max_count, bool other_is_merged); virtual db::Coord dist () const; virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const; @@ -237,7 +241,7 @@ public: private: int m_mode; bool m_touching; - bool m_inverse; + InteractingOutputMode m_output_mode; size_t m_min_count, m_max_count; bool m_other_is_merged; }; @@ -268,7 +272,7 @@ class interacting_with_edge_local_operation : public local_operation { public: - interacting_with_edge_local_operation (bool inverse, size_t min_count, size_t max_count, bool other_is_merged); + interacting_with_edge_local_operation (InteractingOutputMode output_mode, size_t min_count, size_t max_count, bool other_is_merged); virtual db::Coord dist () const; virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const; @@ -276,7 +280,7 @@ public: virtual std::string description () const; private: - bool m_inverse; + InteractingOutputMode m_output_mode; size_t m_min_count, m_max_count; bool m_other_is_merged; }; @@ -303,7 +307,7 @@ class interacting_with_text_local_operation : public local_operation { public: - interacting_with_text_local_operation (bool inverse, size_t min_count, size_t max_count); + interacting_with_text_local_operation (InteractingOutputMode output_mode, size_t min_count, size_t max_count); virtual db::Coord dist () const; virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const; @@ -311,7 +315,7 @@ public: virtual std::string description () const; private: - bool m_inverse; + InteractingOutputMode m_output_mode; size_t m_min_count, m_max_count; };