diff --git a/src/db/db/dbAsIfFlatRegion.cc b/src/db/db/dbAsIfFlatRegion.cc index 199aaea72..dad7c691c 100644 --- a/src/db/db/dbAsIfFlatRegion.cc +++ b/src/db/db/dbAsIfFlatRegion.cc @@ -1093,6 +1093,66 @@ AsIfFlatRegion::cop_to_edges (db::CompoundRegionOperationNode &node) return output.release (); } +EdgePairsDelegate * +AsIfFlatRegion::width_check (db::Coord d, const RegionCheckOptions &options) const +{ + return run_single_polygon_check (db::WidthRelation, d, options); +} + +EdgePairsDelegate * +AsIfFlatRegion::space_or_isolated_check (db::Coord d, const RegionCheckOptions &options, bool isolated) const +{ + if (options.opposite_filter != NoOppositeFilter || options.rect_filter != NoSideAllowed) { + // NOTE: we have to use the "foreign" scheme with a filter because only this scheme + // guarantees that all subject shapes are visited. + return run_check (db::SpaceRelation, isolated, foreign_regionptr (), d, options); + } else { + return run_check (db::SpaceRelation, isolated, subject_regionptr (), d, options); + } +} + +EdgePairsDelegate * +AsIfFlatRegion::space_check (db::Coord d, const RegionCheckOptions &options) const +{ + return space_or_isolated_check (d, options, false); +} + +EdgePairsDelegate * +AsIfFlatRegion::isolated_check (db::Coord d, const RegionCheckOptions &options) const +{ + return space_or_isolated_check (d, options, true); +} + +EdgePairsDelegate * +AsIfFlatRegion::notch_check (db::Coord d, const RegionCheckOptions &options) const +{ + return run_single_polygon_check (db::SpaceRelation, d, options); +} + +EdgePairsDelegate * +AsIfFlatRegion::enclosing_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const +{ + return run_check (db::OverlapRelation, true, &other, d, options); +} + +EdgePairsDelegate * +AsIfFlatRegion::overlap_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const +{ + return run_check (db::WidthRelation, true, &other, d, options); +} + +EdgePairsDelegate * +AsIfFlatRegion::separation_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const +{ + return run_check (db::SpaceRelation, true, &other, d, options); +} + +EdgePairsDelegate * +AsIfFlatRegion::inside_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const +{ + return run_check (db::InsideRelation, true, &other, d, options); +} + EdgePairsDelegate * AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, const RegionCheckOptions &options) const { @@ -1107,19 +1167,31 @@ AsIfFlatRegion::run_check (db::edge_relation_type rel, bool different_polygons, check.set_min_projection (options.min_projection); check.set_max_projection (options.max_projection); - db::check_local_operation op (check, different_polygons, other != 0, other && other->is_merged (), options); - db::local_processor proc; proc.set_base_verbosity (base_verbosity ()); std::vector > others; - others.push_back (other ? other->begin () : begin_merged ()); + std::vector foreign; + bool has_other = false; + bool other_is_merged = true; + + if (other == subject_regionptr () || other == foreign_regionptr ()) { + foreign.push_back (other == foreign_regionptr ()); + others.push_back (begin_merged ()); + } else { + foreign.push_back (false); + others.push_back (other->begin ()); + other_is_merged = other->is_merged (); + has_other = true; + } + + db::check_local_operation op (check, different_polygons, has_other, other_is_merged, options); std::auto_ptr output (new FlatEdgePairs ()); std::vector results; results.push_back (&output->raw_edge_pairs ()); - proc.run_flat (polygons, others, std::vector (), &op, results); + proc.run_flat (polygons, others, foreign, &op, results); return output.release (); diff --git a/src/db/db/dbAsIfFlatRegion.h b/src/db/db/dbAsIfFlatRegion.h index 8c9fe7fb9..eecec66d3 100644 --- a/src/db/db/dbAsIfFlatRegion.h +++ b/src/db/db/dbAsIfFlatRegion.h @@ -60,45 +60,14 @@ public: virtual RegionDelegate *cop_to_region (db::CompoundRegionOperationNode &node); virtual EdgesDelegate *cop_to_edges (db::CompoundRegionOperationNode &node); - EdgePairsDelegate *width_check (db::Coord d, const RegionCheckOptions &options) const - { - return run_single_polygon_check (db::WidthRelation, d, options); - } - - EdgePairsDelegate *space_check (db::Coord d, const RegionCheckOptions &options) const - { - return run_check (db::SpaceRelation, false, 0, d, options); - } - - EdgePairsDelegate *isolated_check (db::Coord d, const RegionCheckOptions &options) const - { - return run_check (db::SpaceRelation, true, 0, d, options); - } - - EdgePairsDelegate *notch_check (db::Coord d, const RegionCheckOptions &options) const - { - return run_single_polygon_check (db::SpaceRelation, d, options); - } - - EdgePairsDelegate *enclosing_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const - { - return run_check (db::OverlapRelation, true, &other, d, options); - } - - EdgePairsDelegate *overlap_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const - { - return run_check (db::WidthRelation, true, &other, d, options); - } - - EdgePairsDelegate *separation_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const - { - return run_check (db::SpaceRelation, true, &other, d, options); - } - - EdgePairsDelegate *inside_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const - { - return run_check (db::InsideRelation, true, &other, d, options); - } + EdgePairsDelegate *width_check (db::Coord d, const RegionCheckOptions &options) const; + EdgePairsDelegate *space_check (db::Coord d, const RegionCheckOptions &options) const; + EdgePairsDelegate *isolated_check (db::Coord d, const RegionCheckOptions &options) const; + EdgePairsDelegate *notch_check (db::Coord d, const RegionCheckOptions &options) const; + EdgePairsDelegate *enclosing_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const; + EdgePairsDelegate *overlap_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const; + EdgePairsDelegate *separation_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const; + EdgePairsDelegate *inside_check (const Region &other, db::Coord d, const RegionCheckOptions &options) const; virtual EdgePairsDelegate *grid_check (db::Coord gx, db::Coord gy) const; virtual EdgePairsDelegate *angle_check (double min, double max, bool inverse) const; @@ -298,6 +267,7 @@ private: virtual db::Box compute_bbox () const; static RegionDelegate *region_from_box (const db::Box &b); + EdgePairsDelegate *space_or_isolated_check (db::Coord d, const RegionCheckOptions &options, bool isolated) const; }; } diff --git a/src/db/db/dbCompoundOperation.cc b/src/db/db/dbCompoundOperation.cc index 8a0197dc1..ad8681470 100644 --- a/src/db/db/dbCompoundOperation.cc +++ b/src/db/db/dbCompoundOperation.cc @@ -1487,7 +1487,7 @@ CompoundRegionEdgePairToEdgeProcessingOperationNode::do_compute_local (db::Layou // --------------------------------------------------------------------------------------------- CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (db::edge_relation_type rel, bool different_polygons, db::Coord d, const db::RegionCheckOptions &options) - : CompoundRegionMultiInputOperationNode (), m_check (rel, d, options.metrics), m_different_polygons (different_polygons), m_options (options) + : CompoundRegionMultiInputOperationNode (), m_check (rel, d, options.metrics), m_different_polygons (different_polygons), m_options (options), m_has_other (false), m_is_other_merged (false) { set_description ("check"); @@ -1499,7 +1499,7 @@ CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (db::edge_rel } CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegionOperationNode *input, db::edge_relation_type rel, bool different_polygons, db::Coord d, const db::RegionCheckOptions &options) - : CompoundRegionMultiInputOperationNode (input), m_check (rel, d, options.metrics), m_different_polygons (different_polygons), m_options (options) + : CompoundRegionMultiInputOperationNode (input), m_check (rel, d, options.metrics), m_different_polygons (different_polygons), m_options (options), m_has_other (false), m_is_other_merged (false) { set_description ("check"); @@ -1513,6 +1513,18 @@ CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegi CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegionOperationNode * /*input*/, CompoundRegionOperationNode *other, db::edge_relation_type rel, bool different_polygons, db::Coord d, const db::RegionCheckOptions &options) : CompoundRegionMultiInputOperationNode (other), m_check (rel, d, options.metrics), m_different_polygons (different_polygons), m_options (options) { + m_has_other = false; + std::vector other_inputs = other->inputs (); + if (other_inputs.size () > 1) { + m_has_other = true; + m_is_other_merged = false; // or do we know better? + } else if (other_inputs.size () == 1) { + if (! is_subject_regionptr (other_inputs.front ())) { + m_has_other = true; + m_is_other_merged = other_inputs.front ()->is_merged (); + } + } + set_description ("check"); m_check.set_include_zero (false); @@ -1525,7 +1537,7 @@ CompoundRegionCheckOperationNode::CompoundRegionCheckOperationNode (CompoundRegi db::OnEmptyIntruderHint CompoundRegionCheckOperationNode::on_empty_intruder_hint () const { - return (m_different_polygons || !inputs ().empty ()) ? OnEmptyIntruderHint::Drop : OnEmptyIntruderHint::Ignore; + return (m_different_polygons || m_has_other) ? OnEmptyIntruderHint::Drop : OnEmptyIntruderHint::Ignore; } db::Coord @@ -1543,9 +1555,7 @@ CompoundRegionCheckOperationNode::wants_merged () const void CompoundRegionCheckOperationNode::do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const { - bool other_merged = (children () > 0 && is_subject_regionptr (inputs ()[0])); - - db::check_local_operation op (m_check, m_different_polygons, children () > 0, other_merged, m_options); + db::check_local_operation op (m_check, m_different_polygons, m_has_other, m_is_other_merged, m_options); tl_assert (results.size () == 1); if (results.front ().empty ()) { @@ -1561,9 +1571,7 @@ CompoundRegionCheckOperationNode::do_compute_local (db::Layout *layout, const sh void CompoundRegionCheckOperationNode::do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const { - bool other_merged = (children () > 0 && is_subject_regionptr (inputs ()[0])); - - db::check_local_operation op (m_check, m_different_polygons, children () > 0, other_merged, m_options); + db::check_local_operation op (m_check, m_different_polygons, m_has_other, m_is_other_merged, m_options); tl_assert (results.size () == 1); if (results.front ().empty ()) { diff --git a/src/db/db/dbCompoundOperation.h b/src/db/db/dbCompoundOperation.h index 6aa9e90df..d9e1bb80e 100644 --- a/src/db/db/dbCompoundOperation.h +++ b/src/db/db/dbCompoundOperation.h @@ -1410,6 +1410,8 @@ private: db::EdgeRelationFilter m_check; bool m_different_polygons; db::RegionCheckOptions m_options; + bool m_has_other; + bool m_is_other_merged; }; @@ -1435,35 +1437,14 @@ public: { } protected: - virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) 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 { - for (typename shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { - - const TS &subject_shape = interactions.subject_shape (i->first); - - shape_interactions single_interactions; - - if (on_empty_intruder_hint () == OnEmptyIntruderHint::Drop) { - single_interactions.add_subject_shape (i->first, subject_shape); - } else { - // this includes the subject-without-intruder "interaction" - single_interactions.add_subject (i->first, subject_shape); - } - - const std::vector &intruders = interactions.intruders_for (i->first); - for (typename std::vector::const_iterator ii = intruders.begin (); ii != intruders.end (); ++ii) { - const std::pair &is = interactions.intruder_shape (*ii); - single_interactions.add_intruder_shape (*ii, is.first, is.second); - single_interactions.add_interaction (i->first, *ii); - } - - mp_node->compute_local (layout, single_interactions, results, max_vertex_count, area_ratio); - - } + mp_node->compute_local (layout, interactions, results, max_vertex_count, area_ratio); } virtual db::Coord dist () const { return mp_node->dist (); } virtual OnEmptyIntruderHint on_empty_intruder_hint () const { return mp_node->on_empty_intruder_hint (); } + virtual bool requests_single_subjects () const { return true; } virtual std::string description () const { return mp_node->description (); } const TransformationReducer *vars () const { return mp_node->vars (); } diff --git a/src/db/db/dbDeepEdges.cc b/src/db/db/dbDeepEdges.cc index a31c203b0..a19407a65 100644 --- a/src/db/db/dbDeepEdges.cc +++ b/src/db/db/dbDeepEdges.cc @@ -1078,7 +1078,7 @@ public: return 1; } - virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) 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 { tl_assert (results.size () == 1); std::unordered_set &result = results.front (); @@ -1156,7 +1156,7 @@ public: return 1; } - virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) 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 { tl_assert (results.size () == 1); std::unordered_set &result = results.front (); @@ -1211,7 +1211,7 @@ public: return 1; } - virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) 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 { tl_assert (results.size () == 1); std::unordered_set &result = results.front (); @@ -1310,7 +1310,7 @@ public: return 1; } - virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) 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 { tl_assert (results.size () == 1); std::unordered_set &result = results.front (); @@ -1476,7 +1476,7 @@ public: // .. nothing yet .. } - virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) 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 { tl_assert (results.size () == 1); std::unordered_set &result = results.front (); diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index 58b57dec3..bf9bc9252 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -1429,11 +1429,20 @@ EdgePairsDelegate * DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, const Region *other, db::Coord d, const RegionCheckOptions &options) const { const db::DeepRegion *other_deep = 0; - if (other) { + unsigned int other_layer = 0; + bool other_is_merged = true; + + if (other == subject_regionptr ()) { + other_layer = subject_idlayer (); + } else if (other == foreign_regionptr ()) { + other_layer = foreign_idlayer (); + } else { other_deep = dynamic_cast (other->delegate ()); if (! other_deep) { return db::AsIfFlatRegion::run_check (rel, different_polygons, other, d, options); } + other_layer = other_deep->deep_layer ().layer (); + other_is_merged = other->is_merged (); } const db::DeepLayer &polygons = merged_deep_layer (); @@ -1447,7 +1456,7 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons std::auto_ptr res (new db::DeepEdgePairs (polygons.derived ())); - db::CheckLocalOperation op (check, different_polygons, other_deep != 0, other && other->is_merged (), options); + db::CheckLocalOperation op (check, different_polygons, other_deep != 0, other_is_merged, options); db::local_processor proc (const_cast (&polygons.layout ()), const_cast (&polygons.initial_cell ()), @@ -1459,7 +1468,7 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons proc.set_base_verbosity (base_verbosity ()); proc.set_threads (polygons.store ()->threads ()); - proc.run (&op, polygons.layer (), other_deep ? other_deep->deep_layer ().layer () : polygons.layer (), res->deep_layer ().layer ()); + proc.run (&op, polygons.layer (), other_layer, res->deep_layer ().layer ()); return res.release (); } diff --git a/src/db/db/dbDeepTexts.cc b/src/db/db/dbDeepTexts.cc index f15e8f4f7..2b1bacda5 100644 --- a/src/db/db/dbDeepTexts.cc +++ b/src/db/db/dbDeepTexts.cc @@ -465,7 +465,7 @@ public: return 1; } - virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) 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 { tl_assert (results.size () == 1); std::unordered_set &result = results.front (); @@ -564,7 +564,7 @@ public: return 1; } - virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) 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 { tl_assert (results.size () == 1); std::unordered_set &result = results.front (); diff --git a/src/db/db/dbHierProcessor.h b/src/db/db/dbHierProcessor.h index 049f3d554..ab480c493 100644 --- a/src/db/db/dbHierProcessor.h +++ b/src/db/db/dbHierProcessor.h @@ -77,6 +77,11 @@ public: return m_interactions.end (); } + size_t num_interactions () const + { + return m_interactions.size (); + } + subject_iterator begin_subjects () const { return m_subject_shapes.begin (); @@ -87,6 +92,11 @@ public: return m_subject_shapes.end (); } + size_t num_subjects () const + { + return m_subject_shapes.size (); + } + intruder_iterator begin_intruders () const { return m_intruder_shapes.begin (); @@ -97,6 +107,11 @@ public: return m_intruder_shapes.end (); } + size_t num_intruders () const + { + return m_intruder_shapes.size (); + } + bool has_intruder_shape_id (unsigned int id) const; bool has_subject_shape_id (unsigned int id) const; void add_intruder_shape (unsigned int id, unsigned int layer, const TI &shape); diff --git a/src/db/db/dbLocalOperation.cc b/src/db/db/dbLocalOperation.cc index 9b1d238da..80b492460 100644 --- a/src/db/db/dbLocalOperation.cc +++ b/src/db/db/dbLocalOperation.cc @@ -59,7 +59,7 @@ BoolAndOrNotLocalOperation::description () const } void -BoolAndOrNotLocalOperation::compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const +BoolAndOrNotLocalOperation::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 (); @@ -125,7 +125,7 @@ TwoBoolAndNotLocalOperation::TwoBoolAndNotLocalOperation () } void -TwoBoolAndNotLocalOperation::compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const +TwoBoolAndNotLocalOperation::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 () == 2); @@ -204,7 +204,7 @@ SelfOverlapMergeLocalOperation::SelfOverlapMergeLocalOperation (unsigned int wra } void -SelfOverlapMergeLocalOperation::compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const +SelfOverlapMergeLocalOperation::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 (); @@ -291,7 +291,7 @@ EdgeBoolAndOrNotLocalOperation::description () const } void -EdgeBoolAndOrNotLocalOperation::compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const +EdgeBoolAndOrNotLocalOperation::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 (); @@ -362,7 +362,7 @@ EdgeToPolygonLocalOperation::description () const } void -EdgeToPolygonLocalOperation::compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const +EdgeToPolygonLocalOperation::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 (); diff --git a/src/db/db/dbLocalOperation.h b/src/db/db/dbLocalOperation.h index 9c4233791..cf3d0b98b 100644 --- a/src/db/db/dbLocalOperation.h +++ b/src/db/db/dbLocalOperation.h @@ -89,14 +89,54 @@ public: * @param layout The layout to which the shapes belong * @param interactions The interaction set * @param result The container to which the results are written + * + * If the operation requests single subject mode, the interactions will be split into single subject/intruder clusters */ - virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &result, size_t max_vertex_count, double area_ratio) const = 0; + void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const + { + if (interactions.num_subjects () <= 1 || ! requests_single_subjects ()) { + + do_compute_local (layout, interactions, results, max_vertex_count, area_ratio); + + } else { + + for (typename shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { + + const TS &subject_shape = interactions.subject_shape (i->first); + + shape_interactions single_interactions; + + if (on_empty_intruder_hint () == OnEmptyIntruderHint::Drop) { + single_interactions.add_subject_shape (i->first, subject_shape); + } else { + // this includes the subject-without-intruder "interaction" + single_interactions.add_subject (i->first, subject_shape); + } + + const std::vector &intruders = interactions.intruders_for (i->first); + for (typename std::vector::const_iterator ii = intruders.begin (); ii != intruders.end (); ++ii) { + const std::pair &is = interactions.intruder_shape (*ii); + single_interactions.add_intruder_shape (*ii, is.first, is.second); + single_interactions.add_interaction (i->first, *ii); + } + + do_compute_local (layout, single_interactions, results, max_vertex_count, area_ratio); + + } + + } + } /** * @brief Indicates the desired behaviour when a shape does not have an intruder */ virtual OnEmptyIntruderHint on_empty_intruder_hint () const { return Ignore; } + /** + * @brief If this method returns true, this operation requests single subjects for meal + */ + virtual bool requests_single_subjects () const { return false; } + /** * @brief Gets a description text for this operation */ @@ -107,6 +147,15 @@ public: * A distance of means the shapes must overlap in order to interact. */ virtual db::Coord dist () const { return 0; } + +protected: + /** + * @brief Computes the results from a given set of interacting shapes + * @param layout The layout to which the shapes belong + * @param interactions The interaction set + * @param result The container to which the results are written + */ + virtual void do_compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &result, size_t max_vertex_count, double area_ratio) const = 0; }; /** @@ -118,7 +167,7 @@ class DB_PUBLIC BoolAndOrNotLocalOperation public: BoolAndOrNotLocalOperation (bool is_and); - virtual void 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 &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; @@ -138,7 +187,7 @@ class DB_PUBLIC TwoBoolAndNotLocalOperation public: TwoBoolAndNotLocalOperation (); - virtual void 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 &interactions, std::vector > &result, size_t max_vertex_count, double area_ratio) const; virtual std::string description () const; }; @@ -153,7 +202,7 @@ class DB_PUBLIC SelfOverlapMergeLocalOperation public: SelfOverlapMergeLocalOperation (unsigned int wrap_count); - virtual void 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 &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; @@ -170,7 +219,7 @@ class DB_PUBLIC EdgeBoolAndOrNotLocalOperation public: EdgeBoolAndOrNotLocalOperation (EdgeBoolOp op); - virtual void 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 &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; @@ -193,7 +242,7 @@ class DB_PUBLIC EdgeToPolygonLocalOperation public: EdgeToPolygonLocalOperation (bool outside, bool include_borders); - virtual void 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 &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; diff --git a/src/db/db/dbRegionLocalOperations.cc b/src/db/db/dbRegionLocalOperations.cc index de9e51a34..0746d55d9 100644 --- a/src/db/db/dbRegionLocalOperations.cc +++ b/src/db/db/dbRegionLocalOperations.cc @@ -147,13 +147,12 @@ void insert_into_hash (std::unordered_set &hash, const T &shape) template void -check_local_operation::compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const +check_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 (); - tl_assert (result.empty ()); + std::unordered_set result; - edge2edge_check_negative_or_positive > edge_check (m_check, result, m_options.negative, m_different_polygons, m_has_other, m_options.shielded); + edge2edge_check_negative_or_positive > edge_check (m_check, result, m_options.negative, true, true, m_options.shielded); poly2poly_check poly_check (edge_check); std::list heap; @@ -234,6 +233,8 @@ check_local_operation::compute_local (db::Layout *layout, const shape_in n += 2; } + n = 1; + for (std::set::const_iterator id = ids.begin (); id != ids.end (); ++id) { const TI &ti = interactions.intruder_shape (*id).second; if (polygons.find (ti) == polygons.end ()) { @@ -248,60 +249,156 @@ check_local_operation::compute_local (db::Layout *layout, const shape_in scanner.process (poly_check, m_check.distance (), db::box_convert ()); } while (edge_check.prepare_next_pass ()); + // now also handle the intra-polygon interactions if required + + std::unordered_set intra_polygon_result; + + if (! m_different_polygons && ! m_has_other) { + + for (typename shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { + + std::list heap; + + const TS &subject = interactions.subject_shape (i->first); + scanner.clear (); + scanner.insert (push_polygon_to_heap (layout, subject, heap), 0); + + edge2edge_check_negative_or_positive > edge_check_intra (m_check, intra_polygon_result, m_options.negative, false, false, m_options.shielded); + poly2poly_check poly_check_intra (edge_check_intra); + + do { + scanner.process (poly_check_intra, m_check.distance (), db::box_convert ()); + } while (edge_check_intra.prepare_next_pass ()); + + } + + } + // detect and remove parts of the result which have or do not have results "opposite" // ("opposite" is defined by the projection of edges "through" the subject shape) - if (m_options.opposite_filter != db::NoOppositeFilter && ! result.empty ()) { + if (m_options.opposite_filter != db::NoOppositeFilter && (! result.empty () || ! intra_polygon_result.empty ())) { db::EdgeRelationFilter opp (db::WidthRelation, std::numeric_limits::max (), db::Projection); - std::vector projections; std::unordered_set cleaned_result; - // filter out opposite edges - for (std::unordered_set::const_iterator ep1 = result.begin (); ep1 != result.end (); ++ep1) { + if (m_has_other) { - projections.clear (); + // filter out opposite edges: this is the case of two-layer checks where we can maintain the edge pairs but + // strip them of the filtered-out part. - for (std::unordered_set::const_iterator ep2 = result.begin (); ep2 != result.end (); ++ep2) { + std::vector projections; + for (std::unordered_set::const_iterator ep1 = result.begin (); ep1 != result.end (); ++ep1) { + + projections.clear (); + + for (std::unordered_set::const_iterator ep2 = result.begin (); ep2 != result.end (); ++ep2) { + + if (ep1 == ep2) { + continue; + } + + db::EdgePair ep_opp; + if (opp.check (ep1->first (), ep2->first (), &ep_opp)) { + + bool shielded = false; + for (typename shape_interactions::iterator i = interactions.begin (); i != interactions.end () && ! shielded; ++i) { + shielded = shields_interaction (ep_opp, interactions.subject_shape (i->first)); + } + + if (! shielded) { + projections.push_back (ep_opp.first ()); + } + + } - if (ep1 == ep2) { - continue; } - db::EdgePair ep_opp; - if (opp.check (ep1->first (), ep2->first (), &ep_opp)) { - - bool shielded = false; - for (typename shape_interactions::iterator i = interactions.begin (); i != interactions.end () && ! shielded; ++i) { - shielded = shields_interaction (ep_opp, interactions.subject_shape (i->first)); + if (! projections.empty ()) { + db::Edges ce; + if (m_options.opposite_filter == db::OnlyOpposite) { + ce = db::Edges (ep1->first ()) & db::Edges (projections.begin (), projections.end ()); + } else if (m_options.opposite_filter == db::NotOpposite) { + ce = db::Edges (ep1->first ()) - db::Edges (projections.begin (), projections.end ()); } - - if (! shielded) { - projections.push_back (ep_opp.first ()); + for (db::Edges::const_iterator re = ce.begin (); ! re.at_end (); ++re) { + cleaned_result.insert (db::EdgePair (*re, ep1->second ())); } - + } else if (m_options.opposite_filter == db::NotOpposite) { + cleaned_result.insert (*ep1); } } - if (! projections.empty ()) { - db::Edges ce; - if (m_options.opposite_filter == db::OnlyOpposite) { - ce = db::Edges (ep1->first ()) & db::Edges (projections.begin (), projections.end ()); + } else { + + // this is the single-layer case where we cannot maintain the edge pairs as we don't know how the + // other side will be filtered. For the filtering we only need the first edges and both edges of the + // intra-polygon checks + + std::unordered_set edges; + + for (std::unordered_set::const_iterator ep = result.begin (); ep != result.end (); ++ep) { + edges.insert (ep->first ()); + } + + for (std::unordered_set::const_iterator ep = intra_polygon_result.begin (); ep != intra_polygon_result.end (); ++ep) { + edges.insert (ep->first ()); + edges.insert (ep->second ()); + } + + // filter out opposite edges + std::vector projections; + for (std::unordered_set::const_iterator e1 = edges.begin (); e1 != edges.end (); ++e1) { + + projections.clear (); + + for (std::unordered_set::const_iterator e2 = edges.begin (); e2 != edges.end (); ++e2) { + + if (e1 == e2) { + continue; + } + + db::EdgePair ep_opp; + if (opp.check (*e1, *e2, &ep_opp)) { + + bool shielded = false; + for (typename shape_interactions::iterator i = interactions.begin (); i != interactions.end () && ! shielded; ++i) { + shielded = shields_interaction (ep_opp, interactions.subject_shape (i->first)); + } + + if (! shielded) { + projections.push_back (ep_opp.first ()); + } + + } + + } + + if (! projections.empty ()) { + db::Edges ce; + if (m_options.opposite_filter == db::OnlyOpposite) { + ce = db::Edges (*e1) & db::Edges (projections.begin (), projections.end ()); + } else if (m_options.opposite_filter == db::NotOpposite) { + ce = db::Edges (*e1) - db::Edges (projections.begin (), projections.end ()); + } + for (db::Edges::const_iterator re = ce.begin (); ! re.at_end (); ++re) { + cleaned_result.insert (db::EdgePair (*re, re->swapped_points ())); + } } else if (m_options.opposite_filter == db::NotOpposite) { - ce = db::Edges (ep1->first ()) - db::Edges (projections.begin (), projections.end ()); + cleaned_result.insert (db::EdgePair (*e1, e1->swapped_points ())); } - for (db::Edges::const_iterator re = ce.begin (); ! re.at_end (); ++re) { - cleaned_result.insert (db::EdgePair (*re, ep1->second ())); - } - } else if (m_options.opposite_filter == db::NotOpposite) { - cleaned_result.insert (*ep1); + } } result.swap (cleaned_result); + } else { + + result.insert (intra_polygon_result.begin (), intra_polygon_result.end ()); + } // implements error filtering on rectangles @@ -374,6 +471,8 @@ check_local_operation::compute_local (db::Layout *layout, const shape_in } } + + results.front ().insert (result.begin (), result.end ()); } template @@ -418,7 +517,7 @@ db::Coord interacting_local_operation::dist () const } template -void interacting_local_operation::compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const +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 (); @@ -546,7 +645,7 @@ db::Coord pull_local_operation::dist () const } template -void pull_local_operation::compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const +void pull_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 (); @@ -625,7 +724,7 @@ db::Coord interacting_with_edge_local_operation::dist () const } template -void interacting_with_edge_local_operation::compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const +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 { std::unordered_map counted_results; bool counting = !(m_min_count == 1 && m_max_count == std::numeric_limits::max ()); @@ -710,7 +809,7 @@ db::Coord pull_with_edge_local_operation::dist () const } template -void pull_with_edge_local_operation::compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const +void pull_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 { tl_assert (results.size () == 1); std::unordered_set &result = results.front (); @@ -771,7 +870,7 @@ db::Coord pull_with_text_local_operation::dist () const } template -void pull_with_text_local_operation::compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const +void pull_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 { tl_assert (results.size () == 1); std::unordered_set &result = results.front (); @@ -840,7 +939,7 @@ db::Coord interacting_with_text_local_operation::dist () const template -void interacting_with_text_local_operation::compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const +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 { std::unordered_map counted_results; bool counting = !(m_min_count == 1 && m_max_count == std::numeric_limits::max ()); diff --git a/src/db/db/dbRegionLocalOperations.h b/src/db/db/dbRegionLocalOperations.h index 0ebd5802f..0ea429e15 100644 --- a/src/db/db/dbRegionLocalOperations.h +++ b/src/db/db/dbRegionLocalOperations.h @@ -202,10 +202,9 @@ class check_local_operation public: check_local_operation (const EdgeRelationFilter &check, bool different_polygons, bool has_other, bool other_is_merged, const db::RegionCheckOptions &options); - virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const; - virtual db::Coord dist () const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const; + virtual bool requests_single_subjects () const { return true; } virtual std::string description () const; private: @@ -214,6 +213,8 @@ private: bool m_has_other; bool m_other_is_merged; db::RegionCheckOptions m_options; + + virtual void do_compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const; }; typedef check_local_operation CheckLocalOperation; @@ -226,7 +227,7 @@ public: interacting_local_operation (int mode, bool touching, bool inverse, size_t min_count, size_t max_count); virtual db::Coord dist () const; - virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) 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; virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual std::string description () const; @@ -247,7 +248,7 @@ public: pull_local_operation (int mode, bool touching); virtual db::Coord dist () const; - virtual void compute_local (db::Layout * /*layout*/, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) 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; virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual std::string description () const; @@ -266,7 +267,7 @@ public: interacting_with_edge_local_operation (bool inverse, size_t min_count, size_t max_count); virtual db::Coord dist () const; - virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) 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; virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual std::string description () const; @@ -285,7 +286,7 @@ public: pull_with_edge_local_operation (); virtual db::Coord dist () const; - virtual void compute_local (db::Layout *, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const; + virtual void do_compute_local (db::Layout *, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual std::string description () const; }; @@ -300,7 +301,7 @@ public: interacting_with_text_local_operation (bool inverse, size_t min_count, size_t max_count); virtual db::Coord dist () const; - virtual void compute_local (db::Layout *layout, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) 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; virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual std::string description () const; @@ -319,7 +320,7 @@ public: pull_with_text_local_operation (); virtual db::Coord dist () const; - virtual void compute_local (db::Layout *, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const; + virtual void do_compute_local (db::Layout *, const shape_interactions &interactions, std::vector > &results, size_t /*max_vertex_count*/, double /*area_ratio*/) const; virtual OnEmptyIntruderHint on_empty_intruder_hint () const; virtual std::string description () const; }; diff --git a/src/db/db/dbRegionUtils.cc b/src/db/db/dbRegionUtils.cc index d1d14092f..e489d71db 100644 --- a/src/db/db/dbRegionUtils.cc +++ b/src/db/db/dbRegionUtils.cc @@ -152,7 +152,6 @@ Edge2EdgeCheckBase::feed_pseudo_edges (db::box_scanner &scanne { if (m_pass == 1) { for (std::set >::const_iterator e = m_pseudo_edges.begin (); e != m_pseudo_edges.end (); ++e) { -//printf("@@@ PSEUDO %s[%d]\n", e->first.to_string().c_str(), int(e->second)); fflush(stdout); scanner.insert (&e->first, e->second); } } @@ -258,7 +257,6 @@ Edge2EdgeCheckBase::add (const db::Edge *o1, size_t p1, const db::Edge *o2, size (m_pseudo_edges.find (std::make_pair (*o1, p1)) != m_pseudo_edges.end () || m_pseudo_edges.find (std::make_pair (*o2, p2)) != m_pseudo_edges.end ()) && ! (m_pseudo_edges.find (std::make_pair (*o1, p1)) != m_pseudo_edges.end () && m_pseudo_edges.find (std::make_pair (*o2, p2)) != m_pseudo_edges.end ())) { -//printf("@@@ PASS %d -> %s[%d] x %s[%d]\n", m_pass, o1->to_string().c_str(), int(p1), o2->to_string().c_str(), int(p2)); fflush(stdout); // Overlap or inside checks require input from different layers if ((! m_different_polygons || p1 != p2) && (! m_requires_different_layers || ((p1 ^ p2) & 1) != 0)) { @@ -271,7 +269,6 @@ Edge2EdgeCheckBase::add (const db::Edge *o1, size_t p1, const db::Edge *o2, size std::swap (o1, o2); std::swap (p1, p2); } -//printf("@@@1\n"); fflush(stdout); db::EdgePair ep; if (mp_check->check (*o1, *o2, &ep)) { @@ -280,7 +277,6 @@ Edge2EdgeCheckBase::add (const db::Edge *o1, size_t p1, const db::Edge *o2, size m_ep.push_back (ep); m_e2ep.insert (std::make_pair (std::make_pair (*o1, p1), n * 2)); m_e2ep.insert (std::make_pair (std::make_pair (*o2, p2), n * 2 + 1)); -//printf("@@@ CANCEL %s\n", ep.to_string().c_str()); fflush(stdout); } diff --git a/src/db/db/gsiDeclDbCompoundOperation.cc b/src/db/db/gsiDeclDbCompoundOperation.cc index 5faf6688b..b5bb2fe16 100644 --- a/src/db/db/gsiDeclDbCompoundOperation.cc +++ b/src/db/db/gsiDeclDbCompoundOperation.cc @@ -418,14 +418,25 @@ static db::CompoundRegionOperationNode *new_width_check (db::Coord d, bool whole return new db::CompoundRegionToEdgePairProcessingOperationNode (new db::SinglePolygonCheck (db::WidthRelation, d, options), new_primary (), true /*processor is owned*/); } +static db::CompoundRegionOperationNode *new_space_or_isolated_check (db::Coord d, bool whole_edges, db::metrics_type metrics, const tl::Variant &ignore_angle, const tl::Variant &min_projection, const tl::Variant &max_projection, bool shielded, db::OppositeFilter opposite_filter, db::RectFilter rect_filter, bool negative, bool isolated) +{ + if (opposite_filter != db::NoOppositeFilter || rect_filter != db::NoSideAllowed) { + // NOTE: we have to use the "foreign" scheme with a filter because only this scheme + // guarantees that all subject shapes are visited and receive all intruders. + return new_check_node (new_foreign (), db::SpaceRelation, isolated, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter, negative); + } else { + return new_check_node (db::SpaceRelation, isolated, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter, negative); + } +} + static db::CompoundRegionOperationNode *new_space_check (db::Coord d, bool whole_edges, db::metrics_type metrics, const tl::Variant &ignore_angle, const tl::Variant &min_projection, const tl::Variant &max_projection, bool shielded, db::OppositeFilter opposite_filter, db::RectFilter rect_filter, bool negative) { - return new_check_node (db::SpaceRelation, false, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter, negative); + return new_space_or_isolated_check (d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter, negative, false); } static db::CompoundRegionOperationNode *new_isolated_check (db::Coord d, bool whole_edges, db::metrics_type metrics, const tl::Variant &ignore_angle, const tl::Variant &min_projection, const tl::Variant &max_projection, bool shielded, db::OppositeFilter opposite_filter, db::RectFilter rect_filter, bool negative) { - return new_check_node (db::SpaceRelation, true, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter, negative); + return new_space_or_isolated_check (d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter, negative, true); } static db::CompoundRegionOperationNode *new_notch_check (db::Coord d, bool whole_edges, db::metrics_type metrics, const tl::Variant &ignore_angle, const tl::Variant &min_projection, const tl::Variant &max_projection, bool shielded, bool negative) diff --git a/src/db/unit_tests/dbHierProcessorTests.cc b/src/db/unit_tests/dbHierProcessorTests.cc index df41e0f37..7ae753deb 100644 --- a/src/db/unit_tests/dbHierProcessorTests.cc +++ b/src/db/unit_tests/dbHierProcessorTests.cc @@ -60,7 +60,7 @@ public: // .. nothing yet .. } - virtual void compute_local (db::Layout *layout, const db::shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const + virtual void do_compute_local (db::Layout *layout, const db::shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const { db::shape_interactions sized_interactions = interactions; for (db::shape_interactions::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) { @@ -72,7 +72,7 @@ public: } } - BoolAndOrNotLocalOperation::compute_local (layout, sized_interactions, results, max_vertex_count, area_ratio); + BoolAndOrNotLocalOperation::do_compute_local (layout, sized_interactions, results, max_vertex_count, area_ratio); } db::Coord dist () const @@ -97,7 +97,7 @@ public: // .. nothing yet .. } - virtual void compute_local (db::Layout *layout, const db::shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const + virtual void do_compute_local (db::Layout *layout, const db::shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const { db::shape_interactions sized_interactions = interactions; for (db::shape_interactions::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) { @@ -118,7 +118,7 @@ public: } - SelfOverlapMergeLocalOperation::compute_local (layout, sized_interactions, results, max_vertex_count, area_ratio); + SelfOverlapMergeLocalOperation::do_compute_local (layout, sized_interactions, results, max_vertex_count, area_ratio); } db::Coord dist () const diff --git a/src/drc/unit_tests/drcGenericTests.cc b/src/drc/unit_tests/drcGenericTests.cc index 6ca4b97b4..2f5e766a2 100644 --- a/src/drc/unit_tests/drcGenericTests.cc +++ b/src/drc/unit_tests/drcGenericTests.cc @@ -28,7 +28,7 @@ #include "lymMacro.h" #include "tlFileUtils.h" -static void runTest (tl::TestBase *_this, const std::string &number, bool deep) +static void run_test (tl::TestBase *_this, const std::string &number, bool deep) { std::string rs = tl::testsrc (); rs += "/testdata/drc/drcGenericTests_" + number + ".drc"; @@ -71,20 +71,20 @@ static void runTest (tl::TestBase *_this, const std::string &number, bool deep) TEST(1) { - runTest (_this, "1", false); + run_test (_this, "1", false); } TEST(1d) { - runTest (_this, "1", true); + run_test (_this, "1", true); } TEST(2) { - runTest (_this, "2", false); + run_test (_this, "2", false); } TEST(2d) { - runTest (_this, "2", true); + run_test (_this, "2", true); } diff --git a/src/drc/unit_tests/drcSimpleTests.cc b/src/drc/unit_tests/drcSimpleTests.cc index 3fe63b245..4306e99b7 100644 --- a/src/drc/unit_tests/drcSimpleTests.cc +++ b/src/drc/unit_tests/drcSimpleTests.cc @@ -1077,3 +1077,53 @@ TEST(24_enclosing) db::compare_layouts (_this, layout, au, db::NoNormalization); } +static void run_test (tl::TestBase *_this, const std::string &number, bool deep) +{ + std::string rs = tl::testsrc (); + rs += "/testdata/drc/drcSimpleTests_" + number + ".drc"; + + std::string input = tl::testsrc (); + input += "/testdata/drc/drcSimpleTests_" + number + ".gds"; + + std::string au = tl::testsrc (); + au += "/testdata/drc/drcSimpleTests_au" + number + std::string (deep ? "d" : "") + ".gds"; + + std::string output = _this->tmp_file ("tmp.gds"); + + { + // Set some variables + lym::Macro config; + config.set_text (tl::sprintf ( + "$drc_test_source = '%s'\n" + "$drc_test_target = '%s'\n" + "$drc_test_deep = %s\n" + , input, output, deep ? "true" : "false") + ); + config.set_interpreter (lym::Macro::Ruby); + EXPECT_EQ (config.run (), 0); + } + + lym::Macro drc; + drc.load_from (rs); + EXPECT_EQ (drc.run (), 0); + + db::Layout layout; + + { + tl::InputStream stream (output); + db::Reader reader (stream); + reader.read (layout); + } + + db::compare_layouts (_this, layout, au, db::NoNormalization); +} + +TEST(25_spaceWithOptions) +{ + run_test (_this, "25", false); +} + +TEST(25d_spaceWithOptions) +{ + run_test (_this, "25", true); +} diff --git a/testdata/drc/drcGenericTests_2.drc b/testdata/drc/drcGenericTests_2.drc index 84d9385a2..17a9de05d 100644 --- a/testdata/drc/drcGenericTests_2.drc +++ b/testdata/drc/drcGenericTests_2.drc @@ -21,7 +21,8 @@ l1.drc(space(projection) < 1.0).polygons.output(100, 0) l1.drc(space(euclidian) < 1.0).polygons.output(110, 0) l1.drc(space(projection, projection_limits(0..2.0)) < 1.0).polygons.output(111, 0) l1.drc(space(projection, whole_edges) < 1.0).polygons.output(112, 0) -l1.drc(separation(foreign, projection, only_opposite) < 1.0).polygons.output(113, 0) +l1.drc(space(projection, only_opposite) < 1.0).output(113, 0) +l1.drc(space(projection, not_opposite) < 1.0).output(114, 0) # notch l1.drc(notch(projection) <= 1.0).polygons.output(120, 0) @@ -33,7 +34,11 @@ l1.drc(separation(projection, l2) < 1.0).polygons.output(132, 0) l1.drc(sep(projection, l2) < 1.0).polygons.output(133, 0) # isolation -l1.drc(isolated(projection) < 1.0).polygons.output(140, 0) +l1.drc(isolated(euclidian) < 1.0).polygons.output(140, 0) +l1.drc(isolated(projection, projection_limits(0..2.0)) < 1.0).polygons.output(141, 0) +l1.drc(isolated(projection, whole_edges) < 1.0).polygons.output(142, 0) +l1.drc(isolated(projection, only_opposite) < 1.0).output(143, 0) +l1.drc(isolated(projection, not_opposite) < 1.0).output(144, 0) # enclosing, overlap l2.drc(enclosing(l1, projection) < 1.0).polygons.output(150, 0) diff --git a/testdata/drc/drcGenericTests_2.gds b/testdata/drc/drcGenericTests_2.gds index b4f4fe8c4..b55983b6b 100644 Binary files a/testdata/drc/drcGenericTests_2.gds and b/testdata/drc/drcGenericTests_2.gds differ diff --git a/testdata/drc/drcGenericTests_au2.gds b/testdata/drc/drcGenericTests_au2.gds index 8c43f62e4..b36a5980f 100644 Binary files a/testdata/drc/drcGenericTests_au2.gds and b/testdata/drc/drcGenericTests_au2.gds differ diff --git a/testdata/drc/drcGenericTests_au2d.gds b/testdata/drc/drcGenericTests_au2d.gds index ee983896e..43961a211 100644 Binary files a/testdata/drc/drcGenericTests_au2d.gds and b/testdata/drc/drcGenericTests_au2d.gds differ