From 99887a15f04f90a9ef9d67c41406ae761089d5a2 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 17 Jan 2023 00:51:21 +0100 Subject: [PATCH] WIP: refactoring, enabling properties for flat processing --- src/db/db/dbAsIfFlatEdges.cc | 20 +-- src/db/db/dbAsIfFlatRegion.cc | 69 ++++---- src/db/db/dbAsIfFlatRegion.h | 1 + src/db/db/dbAsIfFlatTexts.cc | 4 +- src/db/db/dbDeepRegion.cc | 2 +- src/db/db/dbEdgePairs.h | 4 +- src/db/db/dbEdges.h | 6 +- src/db/db/dbFlatRegion.cc | 10 +- src/db/db/dbGenericShapeIterator.h | 166 +++++++++++++++--- src/db/db/dbHierProcessor.cc | 11 +- src/db/db/dbLocalOperation.cc | 58 +++--- src/db/db/dbLocalOperation.h | 14 +- src/db/db/dbOriginalLayerEdges.cc | 2 +- src/db/db/dbRegion.h | 8 +- src/db/db/dbShapeFlags.h | 15 +- src/db/db/dbTexts.h | 4 +- src/db/unit_tests/dbHierNetsProcessorTests.cc | 6 +- 17 files changed, 270 insertions(+), 130 deletions(-) diff --git a/src/db/db/dbAsIfFlatEdges.cc b/src/db/db/dbAsIfFlatEdges.cc index b25e01d92..40f0ae8d3 100644 --- a/src/db/db/dbAsIfFlatEdges.cc +++ b/src/db/db/dbAsIfFlatEdges.cc @@ -104,7 +104,7 @@ AsIfFlatEdges::selected_interacting_generic (const Region &other, EdgeInteractio db::box_scanner2 scanner (report_progress (), progress_desc ()); - AddressableEdgeDelivery e (begin_merged (), has_valid_merged_edges ()); + AddressableEdgeDelivery e (begin_merged ()); for ( ; ! e.at_end (); ++e) { scanner.insert1 (e.operator-> (), 0); @@ -150,7 +150,7 @@ AsIfFlatEdges::selected_interacting_generic (const Edges &edges, EdgeInteraction db::box_scanner scanner (report_progress (), progress_desc ()); - AddressableEdgeDelivery e (begin_merged (), has_valid_merged_edges ()); + AddressableEdgeDelivery e (begin_merged ()); for ( ; ! e.at_end (); ++e) { scanner.insert (e.operator-> (), 0); @@ -201,7 +201,7 @@ AsIfFlatEdges::selected_interacting_pair_generic (const Region ®ion, EdgeInte db::box_scanner2 scanner (report_progress (), progress_desc ()); - AddressableEdgeDelivery e (begin_merged (), has_valid_merged_edges ()); + AddressableEdgeDelivery e (begin_merged ()); for ( ; ! e.at_end (); ++e) { scanner.insert1 (e.operator-> (), 0); @@ -245,7 +245,7 @@ AsIfFlatEdges::selected_interacting_pair_generic (const Edges &other, EdgeIntera db::box_scanner scanner (report_progress (), progress_desc ()); - AddressableEdgeDelivery e (begin_merged (), has_valid_merged_edges ()); + AddressableEdgeDelivery e (begin_merged ()); for ( ; ! e.at_end (); ++e) { scanner.insert (e.operator-> (), 0); @@ -281,7 +281,7 @@ AsIfFlatEdges::pull_generic (const Edges &edges) const { db::box_scanner scanner (report_progress (), progress_desc ()); - AddressableEdgeDelivery e (begin (), has_valid_edges ()); + AddressableEdgeDelivery e (begin ()); for ( ; ! e.at_end (); ++e) { scanner.insert (e.operator-> (), 1); @@ -310,7 +310,7 @@ AsIfFlatEdges::pull_generic (const Region &other) const db::box_scanner2 scanner (report_progress (), progress_desc ()); - AddressableEdgeDelivery e (begin (), true); + AddressableEdgeDelivery e (begin ()); for ( ; ! e.at_end (); ++e) { scanner.insert1 (e.operator-> (), 0); @@ -487,7 +487,7 @@ AsIfFlatEdges::extended (coord_type ext_b, coord_type ext_e, coord_type ext_o, c db::box_scanner scanner (report_progress (), progress_desc ()); scanner.reserve (count ()); - AddressableEdgeDelivery e (begin (), has_valid_edges ()); + AddressableEdgeDelivery e (begin ()); size_t n = 0; for ( ; ! e.at_end (); ++e) { @@ -733,7 +733,7 @@ AsIfFlatEdges::run_check (db::edge_relation_type rel, const Edges *other, db::Co db::box_scanner scanner (report_progress (), progress_desc ()); scanner.reserve (count () + (other ? other->count () : 0)); - AddressableEdgeDelivery e (begin_merged (), has_valid_merged_edges ()); + AddressableEdgeDelivery e (begin_merged ()); size_t n = 0; for ( ; ! e.at_end (); ++e) { @@ -774,7 +774,7 @@ AsIfFlatEdges::boolean (const Edges *other, EdgeBoolOp op) const db::box_scanner scanner (report_progress (), progress_desc ()); scanner.reserve (count () + (other ? other->count () : 0)); - AddressableEdgeDelivery e (begin (), has_valid_edges ()); + AddressableEdgeDelivery e (begin ()); for ( ; ! e.at_end (); ++e) { if (! e->is_degenerate ()) { @@ -808,7 +808,7 @@ AsIfFlatEdges::boolean_andnot (const Edges *other) const db::box_scanner scanner (report_progress (), progress_desc ()); scanner.reserve (count () + (other ? other->count () : 0)); - AddressableEdgeDelivery e (begin (), has_valid_edges ()); + AddressableEdgeDelivery e (begin ()); for ( ; ! e.at_end (); ++e) { if (! e->is_degenerate ()) { diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index e2041ea13..ed807ce49 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -1493,41 +1493,7 @@ AsIfFlatRegion::and_with (const Region &other, PropertyConstraint property_const return new EmptyRegion (); } else { - - // @@@ TODO: implement property constraint - - // Generic case - db::EdgeProcessor ep (report_progress (), progress_desc ()); - ep.set_base_verbosity (base_verbosity ()); - - // count edges and reserve memory - size_t n = 0; - for (RegionIterator p (begin ()); ! p.at_end (); ++p) { - n += p->vertices (); - } - for (RegionIterator p (other.begin ()); ! p.at_end (); ++p) { - n += p->vertices (); - } - ep.reserve (n); - - // insert the polygons into the processor - n = 0; - for (RegionIterator p (begin ()); ! p.at_end (); ++p, n += 2) { - ep.insert (*p, n); - } - n = 1; - for (RegionIterator p (other.begin ()); ! p.at_end (); ++p, n += 2) { - ep.insert (*p, n); - } - - std::unique_ptr new_region (new FlatRegion (true)); - db::BooleanOp op (db::BooleanOp::And); - db::ShapeGenerator pc (new_region->raw_polygons (), true /*clear*/); - db::PolygonGenerator pg (pc, false /*don't resolve holes*/, min_coherence ()); - ep.process (pg, op); - - return new_region.release (); - + return and_or_not_with (true, other, property_constraint); } } @@ -1550,8 +1516,14 @@ AsIfFlatRegion::not_with (const Region &other, PropertyConstraint property_const return clone (); } else { + return and_or_not_with (false, other, property_constraint); + } +} - // @@@ TODO: implement property constraint +RegionDelegate * +AsIfFlatRegion::and_or_not_with (bool is_and, const Region &other, PropertyConstraint property_constraint) const +{ + if (property_constraint == db::IgnoreProperties) { // Generic case db::EdgeProcessor ep (report_progress (), progress_desc ()); @@ -1578,17 +1550,38 @@ AsIfFlatRegion::not_with (const Region &other, PropertyConstraint property_const } std::unique_ptr new_region (new FlatRegion (true)); - db::BooleanOp op (db::BooleanOp::ANotB); + db::BooleanOp op (is_and ? db::BooleanOp::And : db::BooleanOp::ANotB); db::ShapeGenerator pc (new_region->raw_polygons (), true /*clear*/); db::PolygonGenerator pg (pc, false /*don't resolve holes*/, min_coherence ()); ep.process (pg, op); return new_region.release (); + } else { + + db::generic_shape_iterator polygons (db::make_wp_iter (begin ())); + + std::unique_ptr output (new FlatRegion ()); + std::vector results; + results.push_back (&output->raw_polygons ()); + + db::bool_and_or_not_local_operation_with_properties op (is_and, output->properties_repository (), properties_repository (), &other.properties_repository (), property_constraint); + + db::local_processor proc; + proc.set_base_verbosity (base_verbosity ()); + proc.set_description (progress_desc ()); + proc.set_report_progress (report_progress ()); + + std::vector > others; + others.push_back (db::make_wp_iter (other.begin ())); + + proc.run_flat (polygons, others, std::vector (), &op, results); + + return output.release (); + } } - std::pair AsIfFlatRegion::andnot_with (const Region &other, PropertyConstraint property_constraint) const { diff --git a/src/db/db/dbAsIfFlatRegion.h b/src/db/db/dbAsIfFlatRegion.h index 99c1596e1..8c85c2072 100644 --- a/src/db/db/dbAsIfFlatRegion.h +++ b/src/db/db/dbAsIfFlatRegion.h @@ -284,6 +284,7 @@ protected: void update_bbox (const db::Box &box); void invalidate_bbox (); void merge_polygons_to (db::Shapes &output, bool min_coherence, unsigned int min_wc) const; + RegionDelegate *and_or_not_with (bool is_and, const Region &other, PropertyConstraint property_constraint) const; 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; diff --git a/src/db/db/dbAsIfFlatTexts.cc b/src/db/db/dbAsIfFlatTexts.cc index 4f742cd36..386090cbe 100644 --- a/src/db/db/dbAsIfFlatTexts.cc +++ b/src/db/db/dbAsIfFlatTexts.cc @@ -334,7 +334,7 @@ AsIfFlatTexts::selected_interacting_generic (const Region &other, bool inverse) db::box_scanner2 scanner (report_progress (), progress_desc ()); - AddressableTextDelivery e (begin (), has_valid_texts ()); + AddressableTextDelivery e (begin ()); for ( ; ! e.at_end (); ++e) { scanner.insert1 (e.operator-> (), 0); @@ -380,7 +380,7 @@ AsIfFlatTexts::pull_generic (const Region &other) const db::box_scanner2 scanner (report_progress (), progress_desc ()); - AddressableTextDelivery e (begin (), has_valid_texts ()); + AddressableTextDelivery e (begin ()); for ( ; ! e.at_end (); ++e) { scanner.insert1 (e.operator-> (), 0); diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 24f789c70..9fa57117b 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -796,7 +796,7 @@ DeepRegion::and_or_not_with (const DeepRegion *other, bool and_op, db::PropertyC } else { - db::BoolAndOrNotLocalOperationWithProperties op (and_op, &deep_layer ().layout (), &other->deep_layer ().layout (), property_constraint); + db::BoolAndOrNotLocalOperationWithProperties op (and_op, &dl_out.layout ().properties_repository (), &deep_layer ().layout ().properties_repository (), &other->deep_layer ().layout ().properties_repository (), property_constraint); db::local_processor proc (const_cast (&deep_layer ().layout ()), const_cast (&deep_layer ().initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell (), deep_layer ().breakout_cells (), other->deep_layer ().breakout_cells ()); proc.set_base_verbosity (base_verbosity ()); diff --git a/src/db/db/dbEdgePairs.h b/src/db/db/dbEdgePairs.h index 0c6e780d2..7fed916a4 100644 --- a/src/db/db/dbEdgePairs.h +++ b/src/db/db/dbEdgePairs.h @@ -100,7 +100,7 @@ public: } }; -typedef addressable_shape_delivery_gen AddressableEdgePairDelivery; +typedef addressable_shape_delivery AddressableEdgePairDelivery; class EdgePairs; @@ -496,7 +496,7 @@ public: */ AddressableEdgePairDelivery addressable_edge_pairs () const { - return AddressableEdgePairDelivery (begin (), has_valid_edge_pairs ()); + return AddressableEdgePairDelivery (begin ()); } /** diff --git a/src/db/db/dbEdges.h b/src/db/db/dbEdges.h index 4589ec118..ed1d3dbfc 100644 --- a/src/db/db/dbEdges.h +++ b/src/db/db/dbEdges.h @@ -95,7 +95,7 @@ public: } }; -typedef addressable_shape_delivery_gen AddressableEdgeDelivery; +typedef addressable_shape_delivery AddressableEdgeDelivery; class Edges; @@ -1449,7 +1449,7 @@ public: */ AddressableEdgeDelivery addressable_edges () const { - return AddressableEdgeDelivery (begin (), has_valid_edges ()); + return AddressableEdgeDelivery (begin ()); } /** @@ -1468,7 +1468,7 @@ public: */ AddressableEdgeDelivery addressable_merged_edges () const { - return AddressableEdgeDelivery (begin_merged (), has_valid_merged_edges ()); + return AddressableEdgeDelivery (begin_merged ()); } /** diff --git a/src/db/db/dbFlatRegion.cc b/src/db/db/dbFlatRegion.cc index 01ab71303..fdb07ca37 100644 --- a/src/db/db/dbFlatRegion.cc +++ b/src/db/db/dbFlatRegion.cc @@ -39,11 +39,6 @@ FlatRegion::FlatRegion () init (); } -FlatRegion::~FlatRegion () -{ - // .. nothing yet .. -} - FlatRegion::FlatRegion (const FlatRegion &other) : MutableRegion (other), mp_polygons (other.mp_polygons), mp_merged_polygons (other.mp_merged_polygons), mp_properties_repository (other.mp_properties_repository) { @@ -69,6 +64,11 @@ FlatRegion::FlatRegion (bool is_merged) m_is_merged = is_merged; } +FlatRegion::~FlatRegion () +{ + // .. nothing yet .. +} + void FlatRegion::set_is_merged (bool m) { m_is_merged = m; diff --git a/src/db/db/dbGenericShapeIterator.h b/src/db/db/dbGenericShapeIterator.h index 4510a0d39..d396b80fd 100644 --- a/src/db/db/dbGenericShapeIterator.h +++ b/src/db/db/dbGenericShapeIterator.h @@ -181,7 +181,7 @@ public: const_cast (mp_shapes)->update (); } m_iter = mp_shapes->begin (shape_flags ()); - m_is_addressable = shape_flags () == shape_flags_pure () || mp_shapes->begin (shape_flags () - shape_flags_pure ()).at_end (); + m_is_addressable = ! shape_flags_with_props () && (shape_flags () == shape_flags_pure () || mp_shapes->begin (shape_flags () - shape_flags_pure ()).at_end ()); set (); } @@ -305,9 +305,23 @@ public: : mp_delegate (other.mp_delegate ? other.mp_delegate->clone () : 0) { } + generic_shape_iterator (generic_shape_iterator &&other) + : mp_delegate (0) + { + std::swap (mp_delegate, other.mp_delegate); + } + ~generic_shape_iterator () { delete mp_delegate; + mp_delegate = 0; + } + + generic_shape_iterator &set_delegate (generic_shape_iterator_delegate_base *delegate) + { + delete mp_delegate; + mp_delegate = delegate; + return *this; } generic_shape_iterator &operator= (const generic_shape_iterator &other) @@ -393,12 +407,108 @@ public: }; /** - * @brief A helper class allowing delivery of addressable edges + * @brief Wraps a generic shape iterator to provide a property-enabled one + */ + +template +class DB_PUBLIC generic_shape_iterator_with_properties_delegate + : public generic_shape_iterator_delegate_base > +{ +public: + generic_shape_iterator_with_properties_delegate (generic_shape_iterator &&basic) + : m_basic (basic) + { + set (); + } + + generic_shape_iterator_with_properties_delegate (generic_shape_iterator_delegate_base *delegate) + : m_basic (delegate) + { + set (); + } + + generic_shape_iterator_with_properties_delegate (const generic_shape_iterator &basic) + : m_basic (basic) + { + set (); + } + + generic_shape_iterator_with_properties_delegate *clone () const + { + return new generic_shape_iterator_with_properties_delegate (m_basic); + } + + virtual void do_reset (const db::Box ®ion, bool overlapping) + { + m_basic.reset (region, overlapping); + } + + virtual db::Box bbox () const + { + return m_basic.bbox (); + } + + virtual bool is_addressable () const + { + return false; + } + + virtual bool at_end () const + { + return m_basic.at_end (); + } + + virtual void increment () + { + ++m_basic; + set (); + } + + virtual const db::object_with_properties *get () const + { + return &m_object; + } + + virtual db::properties_id_type prop_id () const + { + return m_object.properties_id (); + } + + virtual bool equals (const generic_shape_iterator_delegate_base > *other) const + { + const generic_shape_iterator_with_properties_delegate *other_cast = dynamic_cast *> (other); + return other_cast && m_basic == other_cast->m_basic; + } + +private: + db::generic_shape_iterator m_basic; + db::object_with_properties m_object; + + void set () + { + m_object = db::object_with_properties (*m_basic, m_basic.prop_id ()); + } +}; + +template +generic_shape_iterator > make_wp_iter (generic_shape_iterator &&basic) +{ + return generic_shape_iterator > ().set_delegate (new generic_shape_iterator_with_properties_delegate (basic)); +} + +template +generic_shape_iterator > make_wp_iter (db::generic_shape_iterator_delegate_base *delegate) +{ + return generic_shape_iterator > ().set_delegate (new generic_shape_iterator_with_properties_delegate (delegate)); +} + +/** + * @brief A helper class allowing delivery of addressable objects * * In some applications (i.e. box scanner), shapes need to be taken * by address. An iterator cannot always deliver addressable objects. - * This class help providing this ability by keeping a temporary copy - * if required. + * The addressable_shape_delivery class help providing this ability by keeping temporary copies + * if required on a heap. */ template @@ -443,6 +553,11 @@ public: } } + const value_type &operator* () const + { + return *operator-> (); + } + db::properties_id_type prop_id () const { return m_iter.prop_id (); @@ -454,26 +569,6 @@ private: std::list m_heap; }; -template -class DB_PUBLIC addressable_shape_delivery_gen - : public addressable_shape_delivery_impl -{ -public: - addressable_shape_delivery_gen () - : addressable_shape_delivery_impl () - { } - - explicit addressable_shape_delivery_gen (const Iter &iter, bool iterator_is_addressable) - : addressable_shape_delivery_impl (iter, iterator_is_addressable) - { } - - addressable_shape_delivery_gen &operator++ () - { - addressable_shape_delivery_impl::inc (); - return *this; - } -}; - template class DB_PUBLIC addressable_shape_delivery : public addressable_shape_delivery_impl > @@ -496,6 +591,29 @@ public: } }; +template +class DB_PUBLIC unaddressable_shape_delivery + : public addressable_shape_delivery_impl > +{ +public: + typedef db::generic_shape_iterator iter_type; + + unaddressable_shape_delivery () + : addressable_shape_delivery_impl () + { } + + explicit unaddressable_shape_delivery (const iter_type &iter) + : addressable_shape_delivery_impl (iter, true) + { } + + unaddressable_shape_delivery &operator++ () + { + addressable_shape_delivery_impl::inc (); + return *this; + } +}; + + } #endif diff --git a/src/db/db/dbHierProcessor.cc b/src/db/db/dbHierProcessor.cc index 7fd0a4c01..09a7d2f85 100644 --- a/src/db/db/dbHierProcessor.cc +++ b/src/db/db/dbHierProcessor.cc @@ -446,6 +446,7 @@ template class DB_PUBLIC local_processor_cell_context; template class DB_PUBLIC local_processor_cell_context; template class DB_PUBLIC local_processor_cell_context; +template class DB_PUBLIC local_processor_cell_context; template class DB_PUBLIC local_processor_cell_context; template class DB_PUBLIC local_processor_cell_context; template class DB_PUBLIC local_processor_cell_context; @@ -760,6 +761,7 @@ template class DB_PUBLIC local_processor_cell_contexts; template class DB_PUBLIC local_processor_cell_contexts; template class DB_PUBLIC local_processor_cell_contexts; +template class DB_PUBLIC local_processor_cell_contexts; template class DB_PUBLIC local_processor_cell_contexts; template class DB_PUBLIC local_processor_cell_contexts; template class DB_PUBLIC local_processor_cell_contexts; @@ -865,6 +867,7 @@ template class DB_PUBLIC shape_interactions; template class DB_PUBLIC shape_interactions; template class DB_PUBLIC shape_interactions; template class DB_PUBLIC shape_interactions; +template class DB_PUBLIC shape_interactions; template class DB_PUBLIC shape_interactions; template class DB_PUBLIC shape_interactions; template class DB_PUBLIC shape_interactions; @@ -1337,6 +1340,7 @@ template class DB_PUBLIC local_processor_context_computation_task; template class DB_PUBLIC local_processor_context_computation_task; template class DB_PUBLIC local_processor_context_computation_task; +template class DB_PUBLIC local_processor_context_computation_task; template class DB_PUBLIC local_processor_context_computation_task; template class DB_PUBLIC local_processor_context_computation_task; template class DB_PUBLIC local_processor_context_computation_task; @@ -1400,6 +1404,7 @@ template class DB_PUBLIC local_processor_result_computation_task; template class DB_PUBLIC local_processor_result_computation_task; template class DB_PUBLIC local_processor_result_computation_task; +template class DB_PUBLIC local_processor_result_computation_task; template class DB_PUBLIC local_processor_result_computation_task; template class DB_PUBLIC local_processor_result_computation_task; template class DB_PUBLIC local_processor_result_computation_task; @@ -2246,11 +2251,10 @@ local_processor::run_flat (const generic_shape_iterator &subject if (needs_isolated_subjects) { - addressable_shape_delivery is (subjects); + unaddressable_shape_delivery is (subjects); for ( ; !is.at_end (); ++is) { - const TS *shape = is.operator-> (); unsigned int id = interactions.next_id (); - interactions.add_subject (id, *shape); + interactions.add_subject (id, *is); } unsigned int il_index = 0; @@ -2415,6 +2419,7 @@ template class DB_PUBLIC local_processor; template class DB_PUBLIC local_processor; template class DB_PUBLIC local_processor; template class DB_PUBLIC local_processor; +template class DB_PUBLIC local_processor; template class DB_PUBLIC local_processor; template class DB_PUBLIC local_processor; template class DB_PUBLIC local_processor; diff --git a/src/db/db/dbLocalOperation.cc b/src/db/db/dbLocalOperation.cc index 80d3c1ea2..6fb2e517c 100644 --- a/src/db/db/dbLocalOperation.cc +++ b/src/db/db/dbLocalOperation.cc @@ -95,6 +95,7 @@ template class DB_PUBLIC local_operation; template class DB_PUBLIC local_operation; template class DB_PUBLIC local_operation; template class DB_PUBLIC local_operation; +template class DB_PUBLIC local_operation; template class DB_PUBLIC local_operation; template class DB_PUBLIC local_operation; template class DB_PUBLIC local_operation; @@ -193,56 +194,60 @@ BoolAndOrNotLocalOperation::do_compute_local (db::Layout *layout, const shape_in // --------------------------------------------------------------------------------------------- // BoolAndOrNotLocalOperationWithProperties implementation -BoolAndOrNotLocalOperationWithProperties::BoolAndOrNotLocalOperationWithProperties (bool is_and, const db::Layout *subject_layout, const db::Layout *intruder_layout, db::PropertyConstraint property_constraint) - : m_is_and (is_and), m_property_constraint (property_constraint), mp_subject_layout (subject_layout), mp_intruder_layout (intruder_layout) +template +bool_and_or_not_local_operation_with_properties::bool_and_or_not_local_operation_with_properties (bool is_and, db::PropertiesRepository *target_pr, const db::PropertiesRepository *subject_pr, const db::PropertiesRepository *intruder_pr, db::PropertyConstraint property_constraint) + : m_is_and (is_and), m_property_constraint (property_constraint), mp_target_pr (target_pr), mp_subject_pr (subject_pr), mp_intruder_pr (intruder_pr) { // .. nothing yet .. } +template OnEmptyIntruderHint -BoolAndOrNotLocalOperationWithProperties::on_empty_intruder_hint () const +bool_and_or_not_local_operation_with_properties::on_empty_intruder_hint () const { return m_is_and ? Drop : Copy; } +template std::string -BoolAndOrNotLocalOperationWithProperties::description () const +bool_and_or_not_local_operation_with_properties::description () const { return m_is_and ? tl::to_string (tr ("AND operation")) : tl::to_string (tr ("NOT operation")); } +template void -BoolAndOrNotLocalOperationWithProperties::do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const +bool_and_or_not_local_operation_with_properties::do_compute_local (db::Layout *layout, const shape_interactions, db::object_with_properties > &interactions, std::vector > > &results, size_t max_vertex_count, double area_ratio) const { - db::PropertyMapper pms (*layout, *mp_subject_layout); - db::PropertyMapper pmi (*layout, *mp_intruder_layout); + db::PropertyMapper pms (*mp_target_pr, *mp_subject_pr); + db::PropertyMapper pmi (*mp_target_pr, *mp_intruder_pr); tl_assert (results.size () == 1); - std::unordered_set &result = results.front (); + std::unordered_set > &result = results.front (); db::EdgeProcessor ep; - std::map, std::set > > by_prop_id; + std::map, std::set > > by_prop_id; - for (shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { + for (auto i = interactions.begin (); i != interactions.end (); ++i) { - const db::PolygonRefWithProperties &subject = interactions.subject_shape (i->first); + const db::object_with_properties &subject = interactions.subject_shape (i->first); if (i->second.empty ()) { if (! m_is_and) { - result.insert (db::PolygonRefWithProperties (subject, pms (subject.properties_id ()))); + result.insert (db::object_with_properties (subject, pms (subject.properties_id ()))); } } else { db::properties_id_type prop_id_s = pms (subject.properties_id ()); - std::pair, std::set > &shapes_by_prop = by_prop_id [prop_id_s]; + auto &shapes_by_prop = by_prop_id [prop_id_s]; shapes_by_prop.first.push_front (subject); - for (shape_interactions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { - const db::PolygonRefWithProperties &intruder = interactions.intruder_shape (*j).second; + for (auto j = i->second.begin (); j != i->second.end (); ++j) { + const db::object_with_properties &intruder = interactions.intruder_shape (*j).second; db::properties_id_type prop_id_i = (m_property_constraint != db::NoPropertyConstraint ? pmi (intruder.properties_id ()) : prop_id_s); if ((prop_id_i != prop_id_s) == (m_property_constraint == db::DifferentPropertiesConstraint)) { shapes_by_prop.second.insert (intruder); @@ -258,23 +263,23 @@ BoolAndOrNotLocalOperationWithProperties::do_compute_local (db::Layout *layout, ep.clear (); size_t p1 = 0, p2 = 1; - const std::set &others = p2s->second.second; + const std::set &others = p2s->second.second; db::properties_id_type prop_id = p2s->first; for (auto s = p2s->second.first.begin (); s != p2s->second.first.end (); ++s) { - const db::PolygonRef &subject = *s; + const TS &subject = *s; if (others.find (subject) != others.end ()) { if (m_is_and) { - result.insert (db::PolygonRefWithProperties (subject, prop_id)); + result.insert (db::object_with_properties (subject, prop_id)); } } else if (others.empty ()) { // shortcut (not: keep, and: drop) if (! m_is_and) { - result.insert (db::PolygonRefWithProperties (subject, prop_id)); + result.insert (db::object_with_properties (subject, prop_id)); } } else { - for (db::PolygonRef::polygon_edge_iterator e = subject.begin_edge (); ! e.at_end(); ++e) { + for (auto e = subject.begin_edge (); ! e.at_end(); ++e) { ep.insert (*e, p1); } p1 += 2; @@ -284,24 +289,24 @@ BoolAndOrNotLocalOperationWithProperties::do_compute_local (db::Layout *layout, if (! others.empty () && p1 > 0) { - for (std::set::const_iterator o = others.begin (); o != others.end (); ++o) { - for (db::PolygonRef::polygon_edge_iterator e = o->begin_edge (); ! e.at_end(); ++e) { + for (auto o = others.begin (); o != others.end (); ++o) { + for (auto e = o->begin_edge (); ! e.at_end(); ++e) { ep.insert (*e, p2); } p2 += 2; } - std::unordered_set result_wo_props; + std::unordered_set result_wo_props; db::BooleanOp op (m_is_and ? db::BooleanOp::And : db::BooleanOp::ANotB); - db::PolygonRefGenerator pr (layout, result_wo_props); + db::polygon_ref_generator pr (layout, result_wo_props); db::PolygonSplitter splitter (pr, area_ratio, max_vertex_count); db::PolygonGenerator pg (splitter, true, true); ep.set_base_verbosity (50); ep.process (pg, op); for (auto r = result_wo_props.begin (); r != result_wo_props.end (); ++r) { - result.insert (db::PolygonRefWithProperties (*r, prop_id)); + result.insert (db::object_with_properties (*r, prop_id)); } } @@ -309,6 +314,9 @@ BoolAndOrNotLocalOperationWithProperties::do_compute_local (db::Layout *layout, } } +template class bool_and_or_not_local_operation_with_properties; +template class bool_and_or_not_local_operation_with_properties; + // --------------------------------------------------------------------------------------------- // TwoBoolAndNotLocalOperation implementation diff --git a/src/db/db/dbLocalOperation.h b/src/db/db/dbLocalOperation.h index cfc3471d9..0a11660bd 100644 --- a/src/db/db/dbLocalOperation.h +++ b/src/db/db/dbLocalOperation.h @@ -150,22 +150,26 @@ private: /** * @brief Implements a boolean AND or NOT operation with property handling */ -class DB_PUBLIC BoolAndOrNotLocalOperationWithProperties - : public local_operation +template +class DB_PUBLIC bool_and_or_not_local_operation_with_properties + : public local_operation, db::object_with_properties, db::object_with_properties > { public: - BoolAndOrNotLocalOperationWithProperties (bool is_and, const db::Layout *subject_layout, const db::Layout *intruder_layout, db::PropertyConstraint property_constraint); + bool_and_or_not_local_operation_with_properties (bool is_and, db::PropertiesRepository *target_pr, const db::PropertiesRepository *subject_pr, const db::PropertiesRepository *intruder_pr, db::PropertyConstraint property_constraint); - virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &result, size_t max_vertex_count, double area_ratio) const; + virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions, db::object_with_properties > &interactions, std::vector > > &result, size_t max_vertex_count, double area_ratio) const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual std::string description () const; private: bool m_is_and; db::PropertyConstraint m_property_constraint; - const db::Layout *mp_subject_layout, *mp_intruder_layout; + db::PropertiesRepository *mp_target_pr; + const db::PropertiesRepository *mp_subject_pr, *mp_intruder_pr; }; +typedef bool_and_or_not_local_operation_with_properties BoolAndOrNotLocalOperationWithProperties; + /** * @brief Implements a boolean AND plus NOT operation * diff --git a/src/db/db/dbOriginalLayerEdges.cc b/src/db/db/dbOriginalLayerEdges.cc index 0e91adf21..d110f4a17 100644 --- a/src/db/db/dbOriginalLayerEdges.cc +++ b/src/db/db/dbOriginalLayerEdges.cc @@ -305,7 +305,7 @@ OriginalLayerEdges::ensure_merged_edges_valid () const db::box_scanner scanner (report_progress (), progress_desc ()); scanner.reserve (count ()); - AddressableEdgeDelivery e (begin (), has_valid_edges ()); + AddressableEdgeDelivery e (begin ()); for ( ; ! e.at_end (); ++e) { if (! e->is_degenerate ()) { diff --git a/src/db/db/dbRegion.h b/src/db/db/dbRegion.h index 7fb282a3e..4c3a312f1 100644 --- a/src/db/db/dbRegion.h +++ b/src/db/db/dbRegion.h @@ -1122,7 +1122,7 @@ public: /** * @brief Boolean XOR operator with options * - * TODO: property constraints are not implemented propertly yet. + * TODO: property constraints are not implemented properly yet. */ Region bool_xor (const Region &other, PropertyConstraint prop_constraint = db::IgnoreProperties) const { @@ -1147,7 +1147,7 @@ public: * This method does not necessarily merge the region. To ensure the region * is merged, call merge afterwards. * - * TODO: property constraints are not implemented propertly yet. + * TODO: property constraints are not implemented properly yet. */ Region &bool_xor_with (const Region &other, PropertyConstraint prop_constraint = db::IgnoreProperties) { @@ -1170,7 +1170,7 @@ public: * * This method merges the polygons of both regions. * - * TODO: property constraints are not implemented propertly yet. + * TODO: property constraints are not implemented properly yet. */ Region bool_or (const Region &other, PropertyConstraint prop_constraint = db::IgnoreProperties) const { @@ -1189,7 +1189,7 @@ public: /** * @brief In-place boolean OR operator with options * - * TODO: property constraints are not implemented propertly yet. + * TODO: property constraints are not implemented properly yet. */ Region &bool_or_with (const Region &other, PropertyConstraint prop_constraint = db::IgnoreProperties) { diff --git a/src/db/db/dbShapeFlags.h b/src/db/db/dbShapeFlags.h index e97faf416..1032845da 100644 --- a/src/db/db/dbShapeFlags.h +++ b/src/db/db/dbShapeFlags.h @@ -36,10 +36,12 @@ struct shape_flags_traits { static unsigned int generic () { return 0; } static unsigned int pure () { return 0; } + static bool with_props () { return false; } }; template <> struct shape_flags_traits + : public shape_flags_traits { static unsigned int generic () { return 1 << db::ShapeIterator::PolygonRef; } static unsigned int pure () { return 1 << db::ShapeIterator::PolygonRef; } @@ -47,6 +49,7 @@ struct shape_flags_traits template <> struct shape_flags_traits + : public shape_flags_traits { static unsigned int generic () { return 1 << db::ShapeIterator::TextRef; } static unsigned int pure () { return 1 << db::ShapeIterator::TextRef; } @@ -54,6 +57,7 @@ struct shape_flags_traits template <> struct shape_flags_traits + : public shape_flags_traits { static unsigned int generic () { return db::ShapeIterator::Boxes; } static unsigned int pure () { return 1 << db::ShapeIterator::Box; } @@ -61,6 +65,7 @@ struct shape_flags_traits template <> struct shape_flags_traits + : public shape_flags_traits { static unsigned int generic () { return db::ShapeIterator::Paths; } static unsigned int pure () { return 1 << db::ShapeIterator::Path; } @@ -68,6 +73,7 @@ struct shape_flags_traits template <> struct shape_flags_traits + : public shape_flags_traits { static unsigned int generic () { return db::ShapeIterator::Polygons; } static unsigned int pure () { return 1 << db::ShapeIterator::Polygon; } @@ -75,6 +81,7 @@ struct shape_flags_traits template <> struct shape_flags_traits + : public shape_flags_traits { static unsigned int generic () { return db::ShapeIterator::Polygons; } static unsigned int pure () { return 1 << db::ShapeIterator::SimplePolygon; } @@ -82,6 +89,7 @@ struct shape_flags_traits template <> struct shape_flags_traits + : public shape_flags_traits { static unsigned int generic () { return db::ShapeIterator::Edges; } static unsigned int pure () { return 1 << db::ShapeIterator::Edge; } @@ -89,6 +97,7 @@ struct shape_flags_traits template <> struct shape_flags_traits + : public shape_flags_traits { static unsigned int generic () { return db::ShapeIterator::EdgePairs; } static unsigned int pure () { return 1 << db::ShapeIterator::EdgePair; } @@ -96,6 +105,7 @@ struct shape_flags_traits template <> struct shape_flags_traits + : public shape_flags_traits { static unsigned int generic () { return db::ShapeIterator::Texts; } static unsigned int pure () { return 1 << db::ShapeIterator::Text; } @@ -103,13 +113,14 @@ struct shape_flags_traits template struct shape_flags_traits > + : public shape_flags_traits { - static unsigned int generic () { return shape_flags_traits::generic (); } - static unsigned int pure () { return shape_flags_traits::pure (); } + static bool with_props () { return true; } }; template unsigned int shape_flags () { return shape_flags_traits::generic (); } template unsigned int shape_flags_pure () { return shape_flags_traits::pure (); } +template bool shape_flags_with_props () { return shape_flags_traits::with_props (); } /** * @brief Converter helpers for changing a shape to an object of a specific type diff --git a/src/db/db/dbTexts.h b/src/db/db/dbTexts.h index 885987a8b..0e34ac77c 100644 --- a/src/db/db/dbTexts.h +++ b/src/db/db/dbTexts.h @@ -100,7 +100,7 @@ public: } }; -typedef addressable_shape_delivery_gen AddressableTextDelivery; +typedef addressable_shape_delivery AddressableTextDelivery; class Texts; @@ -522,7 +522,7 @@ public: */ AddressableTextDelivery addressable_texts () const { - return AddressableTextDelivery (begin (), has_valid_texts ()); + return AddressableTextDelivery (begin ()); } /** diff --git a/src/db/unit_tests/dbHierNetsProcessorTests.cc b/src/db/unit_tests/dbHierNetsProcessorTests.cc index a3faa6048..c95d73f3e 100644 --- a/src/db/unit_tests/dbHierNetsProcessorTests.cc +++ b/src/db/unit_tests/dbHierNetsProcessorTests.cc @@ -132,15 +132,15 @@ TEST(0_Develop) db::local_processor proc (&ly2, &top2); { - db::BoolAndOrNotLocalOperationWithProperties n2n (true, &ly2, &ly2, db::SamePropertiesConstraint); + db::BoolAndOrNotLocalOperationWithProperties n2n (true, &ly2.properties_repository (), &ly2.properties_repository (), &ly2.properties_repository (), db::SamePropertiesConstraint); proc.run (&n2n, wmetal1, wmetal2, out1); } { - db::BoolAndOrNotLocalOperationWithProperties n2n (true, &ly2, &ly2, db::DifferentPropertiesConstraint); + db::BoolAndOrNotLocalOperationWithProperties n2n (true, &ly2.properties_repository (), &ly2.properties_repository (), &ly2.properties_repository (), db::DifferentPropertiesConstraint); proc.run (&n2n, wmetal1, wmetal2, out2); } { - db::BoolAndOrNotLocalOperationWithProperties n2n (true, &ly2, &ly2, db::NoPropertyConstraint); + db::BoolAndOrNotLocalOperationWithProperties n2n (true, &ly2.properties_repository (), &ly2.properties_repository (), &ly2.properties_repository (), db::NoPropertyConstraint); proc.run (&n2n, wmetal1, wmetal2, out3); }