diff --git a/src/plugins/tools/netx/db_plugin/dbHierProcessor.cc b/src/plugins/tools/netx/db_plugin/dbHierProcessor.cc index b5e25f8b6..47ab20388 100644 --- a/src/plugins/tools/netx/db_plugin/dbHierProcessor.cc +++ b/src/plugins/tools/netx/db_plugin/dbHierProcessor.cc @@ -289,8 +289,8 @@ struct InteractionRegistrationShape2Inst : db::box_scanner_receiver2 { public: - InteractionRegistrationShape2Inst (db::Layout *layout, unsigned int intruder_layer, std::map > *result) - : mp_layout (layout), m_intruder_layer (intruder_layer), mp_result (result) + InteractionRegistrationShape2Inst (db::Layout *layout, unsigned int intruder_layer, db::Coord dist, std::map > *result) + : mp_layout (layout), m_intruder_layer (intruder_layer), m_dist (dist), mp_result (result) { // nothing yet .. } @@ -300,11 +300,11 @@ public: const db::Cell &intruder_cell = mp_layout->cell (inst->object ().cell_index ()); db::box_convert inst_bc (*mp_layout, m_intruder_layer); - for (db::CellInstArray::iterator n = inst->begin_touching (ref->box ().enlarged (db::Vector (-1, -1)), inst_bc); !n.at_end (); ++n) { + for (db::CellInstArray::iterator n = inst->begin_touching (ref->box ().enlarged (db::Vector (m_dist - 1, m_dist - 1)), inst_bc); !n.at_end (); ++n) { db::ICplxTrans tn = inst->complex_trans (*n); - db::Box region = ref->box ().transformed (tn.inverted ()) & intruder_cell.bbox (m_intruder_layer); + db::Box region = ref->box ().transformed (tn.inverted ()).enlarged (db::Vector (m_dist, m_dist)) & intruder_cell.bbox (m_intruder_layer).enlarged (db::Vector (m_dist, m_dist)); if (! region.empty ()) { // @@@ TODO: should be lighter, cache, handle arrays .. @@ -312,7 +312,7 @@ public: si.shape_flags (polygon_ref_flags ()); while (! si.at_end ()) { - // @@@ should be easier to transform references + // @@@ it should be easier to transform references const db::PolygonRef *ref2 = si.shape ().basic_ptr (db::PolygonRef::tag ()); db::Polygon poly = ref2->obj ().transformed (tn * si.trans () * db::ICplxTrans (ref2->trans ())); (*mp_result)[*ref].push_back (db::PolygonRef (poly, mp_layout->shape_repository())); @@ -329,11 +329,12 @@ public: private: db::Layout *mp_layout; unsigned int m_intruder_layer; + db::Coord m_dist; std::map > *mp_result; }; static bool -instances_interact (const db::Layout *layout1, const db::CellInstArray *inst1, unsigned int layer1, const db::Layout *layout2, const db::CellInstArray *inst2, unsigned int layer2) +instances_interact (const db::Layout *layout1, const db::CellInstArray *inst1, unsigned int layer1, const db::Layout *layout2, const db::CellInstArray *inst2, unsigned int layer2, db::Coord dist) { // TODO: this algorithm is not in particular effective for identical arrays @@ -347,7 +348,7 @@ instances_interact (const db::Layout *layout1, const db::CellInstArray *inst1, u db::ICplxTrans tn1 = inst1->complex_trans (*n); db::ICplxTrans tni1 = tn1.inverted (); - db::Box ibox1 = tn1 * cell1.bbox (layer1); + db::Box ibox1 = tn1 * cell1.bbox (layer1).enlarged (db::Vector (dist, dist)); if (! ibox1.empty ()) { @@ -361,7 +362,9 @@ instances_interact (const db::Layout *layout1, const db::CellInstArray *inst1, u } db::ICplxTrans tn2 = inst2->complex_trans (*k); - db::Box ibox2 = tn2 * cell2.bbox (layer2); + + // NOTE: we need to enlarge both subject *and* intruder boxes - either ubject comes close to intruder or the other way around + db::Box ibox2 = tn2 * cell2.bbox (layer2).enlarged (db::Vector (dist, dist)); db::ICplxTrans tn21 = tni1 * tn2; if (! relative_trans_seen.insert (tn21).second) { @@ -396,8 +399,8 @@ struct InteractionRegistrationInst2Inst : db::box_scanner_receiver2 { public: - InteractionRegistrationInst2Inst (const db::Layout *subject_layout, unsigned int subject_layer, const db::Layout *intruder_layout, unsigned int intruder_layer, std::map, std::set > > *result) - : mp_subject_layout (subject_layout), mp_intruder_layout (intruder_layout), m_subject_layer (subject_layer), m_intruder_layer (intruder_layer), mp_result (result) + InteractionRegistrationInst2Inst (const db::Layout *subject_layout, unsigned int subject_layer, const db::Layout *intruder_layout, unsigned int intruder_layer, db::Coord dist, std::map, std::set > > *result) + : mp_subject_layout (subject_layout), mp_intruder_layout (intruder_layout), m_subject_layer (subject_layer), m_intruder_layer (intruder_layer), m_dist (dist), mp_result (result) { // nothing yet .. } @@ -408,7 +411,7 @@ public: // NOTE: self-interactions are possible for arrays: different elements of the // array may interact which is a cell-external interaction. if ((*inst1 != *inst2 || inst1->size () > 1) - && instances_interact (mp_subject_layout, inst1, m_subject_layer, mp_intruder_layout, inst2, m_intruder_layer)) { + && instances_interact (mp_subject_layout, inst1, m_subject_layer, mp_intruder_layout, inst2, m_intruder_layer, m_dist)) { (*mp_result) [inst1].first.insert (inst2); } } @@ -416,20 +419,21 @@ public: private: const db::Layout *mp_subject_layout, *mp_intruder_layout; unsigned int m_subject_layer, m_intruder_layer; + db::Coord m_dist; std::map, std::set > > *mp_result; }; static bool -instance_shape_interacts (const db::Layout *layout, const db::CellInstArray *inst, unsigned int layer, const db::PolygonRef &ref) +instance_shape_interacts (const db::Layout *layout, const db::CellInstArray *inst, unsigned int layer, const db::PolygonRef &ref, db::Coord dist) { const db::Cell &cell = layout->cell (inst->object ().cell_index ()); db::box_convert inst_bc (*layout, layer); db::Box rbox = ref.box (); - for (db::CellInstArray::iterator n = inst->begin_touching (rbox.enlarged (db::Vector (-1, -1)), inst_bc); ! n.at_end (); ++n) { + for (db::CellInstArray::iterator n = inst->begin_touching (rbox.enlarged (db::Vector (dist - 1, dist - 1)), inst_bc); ! n.at_end (); ++n) { db::ICplxTrans tn = inst->complex_trans (*n); - db::Box cbox = (tn * cell.bbox (layer)) & rbox; + db::Box cbox = (tn * cell.bbox (layer)).enlarged (db::Vector (dist, dist)) & rbox.enlarged (db::Vector (dist, dist)); if (! cbox.empty ()) { @@ -452,15 +456,15 @@ struct InteractionRegistrationInst2Shape : db::box_scanner_receiver2 { public: - InteractionRegistrationInst2Shape (const db::Layout *subject_layout, unsigned int subject_layer, std::map, std::set > > *result) - : mp_subject_layout (subject_layout), m_subject_layer (subject_layer), mp_result (result) + InteractionRegistrationInst2Shape (const db::Layout *subject_layout, unsigned int subject_layer, db::Coord dist, std::map, std::set > > *result) + : mp_subject_layout (subject_layout), m_subject_layer (subject_layer), m_dist (dist), mp_result (result) { // nothing yet .. } void add (const db::CellInstArray *inst, int, const db::PolygonRef *ref, int) { - if (instance_shape_interacts (mp_subject_layout, inst, m_subject_layer, *ref)) { + if (instance_shape_interacts (mp_subject_layout, inst, m_subject_layer, *ref, m_dist)) { (*mp_result) [inst].second.insert (*ref); } } @@ -468,6 +472,7 @@ public: private: const db::Layout *mp_subject_layout; unsigned int m_subject_layer; + db::Coord m_dist; std::map, std::set > > *mp_result; }; @@ -482,10 +487,10 @@ LocalProcessor::LocalProcessor (db::Layout *layout, db::Cell *top) // .. nothing yet .. } -void LocalProcessor::run (LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer, db::Coord dist) +void LocalProcessor::run (LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer) { LocalProcessorContexts contexts; - compute_contexts (contexts, op, subject_layer, intruder_layer, dist); + compute_contexts (contexts, op, subject_layer, intruder_layer); compute_results (contexts, op, output_layer); } @@ -496,7 +501,7 @@ void LocalProcessor::push_results (db::Cell *cell, unsigned int output_layer, co } } -void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, const LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer, db::Coord dist) +void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, const LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer) { tl::SelfTimer timer (tl::verbosity () >= 21, tl::to_string (tr ("Computing contexts for ")) + description ()); @@ -506,10 +511,10 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, const L contexts.set_description (op->description ()); std::pair, std::set > intruders; - compute_contexts (contexts, 0, 0, mp_top, db::ICplxTrans (), dist, intruders); + compute_contexts (contexts, 0, 0, mp_top, db::ICplxTrans (), intruders, op->dist ()); } -void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, db::LocalProcessorCellContext *parent_context, db::Cell *parent, db::Cell *cell, const db::ICplxTrans &cell_inst, db::Coord dist, const std::pair, std::set > &intruders) +void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, db::LocalProcessorCellContext *parent_context, db::Cell *parent, db::Cell *cell, const db::ICplxTrans &cell_inst, const std::pair, std::set > &intruders, db::Coord dist) { if (tl::verbosity () >= 30) { if (! parent) { @@ -549,7 +554,7 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, db::Loc { db::box_scanner2 scanner; - InteractionRegistrationInst2Inst rec (mp_layout, contexts.subject_layer (), mp_layout, contexts.intruder_layer (), &interactions); + InteractionRegistrationInst2Inst rec (mp_layout, contexts.subject_layer (), mp_layout, contexts.intruder_layer (), dist, &interactions); for (db::Cell::const_iterator i = cell->begin (); !i.at_end (); ++i) { if (! inst_bcs (i->cell_inst ()).empty ()) { @@ -566,12 +571,12 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, db::Loc } } - scanner.process (rec, 0, inst_bcs, inst_bci); + scanner.process (rec, dist, inst_bcs, inst_bci); } { db::box_scanner2 scanner; - InteractionRegistrationInst2Shape rec (mp_layout, contexts.subject_layer (), &interactions); + InteractionRegistrationInst2Shape rec (mp_layout, contexts.subject_layer (), dist, &interactions); for (db::Cell::const_iterator i = cell->begin (); !i.at_end (); ++i) { if (! inst_bcs (i->cell_inst ()).empty ()) { @@ -586,7 +591,7 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, db::Loc scanner.insert2 (i->basic_ptr (db::PolygonRef::tag ()), 0); } - scanner.process (rec, 0, inst_bcs, db::box_convert ()); + scanner.process (rec, dist, inst_bcs, db::box_convert ()); } for (std::map, std::set > >::const_iterator i = interactions.begin (); i != interactions.end (); ++i) { @@ -597,7 +602,7 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, db::Loc db::ICplxTrans tn = i->first->complex_trans (*n); db::ICplxTrans tni = tn.inverted (); - db::Box nbox = tn * child_cell.bbox (contexts.subject_layer ()); + db::Box nbox = tn * child_cell.bbox (contexts.subject_layer ()).enlarged (db::Vector (dist, dist)); if (! nbox.empty ()) { @@ -619,7 +624,7 @@ void LocalProcessor::compute_contexts (LocalProcessorContexts &contexts, db::Loc } } - compute_contexts (contexts, context, cell, &child_cell, tn, dist, intruders_below); + compute_contexts (contexts, context, cell, &child_cell, tn, intruders_below, dist); } @@ -684,14 +689,14 @@ LocalProcessor::compute_local_cell (LocalProcessorContexts &contexts, db::Cell * scanner.insert2 (i->basic_ptr (db::PolygonRef::tag ()), 0); } - scanner.process (rec, 0, db::box_convert (), db::box_convert ()); + scanner.process (rec, op->dist (), db::box_convert (), db::box_convert ()); } if (! shapes_subject.empty () && ! (cell->begin ().at_end () && intruders.first.empty ())) { db::box_scanner2 scanner; - InteractionRegistrationShape2Inst rec (mp_layout, contexts.intruder_layer (), &interactions); + InteractionRegistrationShape2Inst rec (mp_layout, contexts.intruder_layer (), op->dist (), &interactions); for (db::Shapes::shape_iterator i = shapes_subject.begin (polygon_ref_flags ()); !i.at_end (); ++i) { scanner.insert1 (i->basic_ptr (db::PolygonRef::tag ()), 0); @@ -708,7 +713,7 @@ LocalProcessor::compute_local_cell (LocalProcessorContexts &contexts, db::Cell * } } - scanner.process (rec, 0, db::box_convert (), inst_bci); + scanner.process (rec, op->dist (), db::box_convert (), inst_bci); } diff --git a/src/plugins/tools/netx/db_plugin/dbHierProcessor.h b/src/plugins/tools/netx/db_plugin/dbHierProcessor.h index 6113e50d7..56c7a0b20 100644 --- a/src/plugins/tools/netx/db_plugin/dbHierProcessor.h +++ b/src/plugins/tools/netx/db_plugin/dbHierProcessor.h @@ -52,6 +52,7 @@ public: virtual void compute_local (db::Layout *layout, const std::map > &interactions, std::set &result) const = 0; virtual on_empty_intruder_mode on_empty_intruder_hint () const = 0; virtual std::string description () const = 0; + virtual db::Coord dist () const { return 0; } }; class DB_PLUGIN_PUBLIC BoolAndOrNotLocalOperation @@ -212,8 +213,8 @@ class DB_PLUGIN_PUBLIC LocalProcessor { public: LocalProcessor (db::Layout *layout, db::Cell *top); - void run (LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer, db::Coord dist = 0); - void compute_contexts (LocalProcessorContexts &contexts, const LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer, db::Coord dist = 0); + void run (LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layer); + void compute_contexts (LocalProcessorContexts &contexts, const LocalOperation *op, unsigned int subject_layer, unsigned int intruder_layer); void compute_results (LocalProcessorContexts &contexts, const LocalOperation *op, unsigned int output_layer); void set_description (const std::string &d) @@ -233,7 +234,7 @@ private: db::Cell *mp_top; std::string m_description; - void compute_contexts (LocalProcessorContexts &contexts, db::LocalProcessorCellContext *parent_context, db::Cell *parent, db::Cell *cell, const db::ICplxTrans &cell_inst, db::Coord dist, const std::pair, std::set > &intruders); + void compute_contexts (LocalProcessorContexts &contexts, db::LocalProcessorCellContext *parent_context, db::Cell *parent, db::Cell *cell, const db::ICplxTrans &cell_inst, const std::pair, std::set > &intruders, db::Coord dist); void push_results (db::Cell *cell, unsigned int output_layer, const std::set &result) const; void compute_local_cell (LocalProcessorContexts &contexts, db::Cell *cell, const LocalOperation *op, const std::pair, std::set > &intruders, std::set &result); }; diff --git a/src/plugins/tools/netx/testdata/hlp1.oas b/src/plugins/tools/netx/testdata/hlp1.oas index 17754711a..7dee89a07 100644 Binary files a/src/plugins/tools/netx/testdata/hlp1.oas and b/src/plugins/tools/netx/testdata/hlp1.oas differ diff --git a/src/plugins/tools/netx/testdata/hlp10.oas b/src/plugins/tools/netx/testdata/hlp10.oas index 707800ad0..9a51e38d1 100644 Binary files a/src/plugins/tools/netx/testdata/hlp10.oas and b/src/plugins/tools/netx/testdata/hlp10.oas differ diff --git a/src/plugins/tools/netx/testdata/hlp2.oas b/src/plugins/tools/netx/testdata/hlp2.oas index 65b25366b..b344983c4 100644 Binary files a/src/plugins/tools/netx/testdata/hlp2.oas and b/src/plugins/tools/netx/testdata/hlp2.oas differ diff --git a/src/plugins/tools/netx/testdata/hlp3.oas b/src/plugins/tools/netx/testdata/hlp3.oas index 765d95764..10ecef81b 100644 Binary files a/src/plugins/tools/netx/testdata/hlp3.oas and b/src/plugins/tools/netx/testdata/hlp3.oas differ diff --git a/src/plugins/tools/netx/testdata/hlp4.oas b/src/plugins/tools/netx/testdata/hlp4.oas index 0e43780b4..9da959541 100644 Binary files a/src/plugins/tools/netx/testdata/hlp4.oas and b/src/plugins/tools/netx/testdata/hlp4.oas differ diff --git a/src/plugins/tools/netx/testdata/hlp5.oas b/src/plugins/tools/netx/testdata/hlp5.oas index 709b3a865..501a1625e 100644 Binary files a/src/plugins/tools/netx/testdata/hlp5.oas and b/src/plugins/tools/netx/testdata/hlp5.oas differ diff --git a/src/plugins/tools/netx/testdata/hlp6.oas b/src/plugins/tools/netx/testdata/hlp6.oas index a21da1c9c..29ec3733c 100644 Binary files a/src/plugins/tools/netx/testdata/hlp6.oas and b/src/plugins/tools/netx/testdata/hlp6.oas differ diff --git a/src/plugins/tools/netx/testdata/hlp7.oas b/src/plugins/tools/netx/testdata/hlp7.oas index a167833a8..a8c2a5649 100644 Binary files a/src/plugins/tools/netx/testdata/hlp7.oas and b/src/plugins/tools/netx/testdata/hlp7.oas differ diff --git a/src/plugins/tools/netx/testdata/hlp8.oas b/src/plugins/tools/netx/testdata/hlp8.oas index 27ca4eb75..670bec10b 100644 Binary files a/src/plugins/tools/netx/testdata/hlp8.oas and b/src/plugins/tools/netx/testdata/hlp8.oas differ diff --git a/src/plugins/tools/netx/testdata/hlp9.oas b/src/plugins/tools/netx/testdata/hlp9.oas index 3baf603e0..c12644748 100644 Binary files a/src/plugins/tools/netx/testdata/hlp9.oas and b/src/plugins/tools/netx/testdata/hlp9.oas differ diff --git a/src/plugins/tools/netx/unit_tests/dbHierProcessorTests.cc b/src/plugins/tools/netx/unit_tests/dbHierProcessorTests.cc index afb862b97..7034f412f 100644 --- a/src/plugins/tools/netx/unit_tests/dbHierProcessorTests.cc +++ b/src/plugins/tools/netx/unit_tests/dbHierProcessorTests.cc @@ -39,6 +39,41 @@ enum TestMode TMNot = 1 }; +/** + * @brief A new processor class which and/nots with a sized version of the intruder + */ +class BoolAndOrNotWithSizedLocalOperation + : public db::BoolAndOrNotLocalOperation +{ +public: + BoolAndOrNotWithSizedLocalOperation (bool is_and, db::Coord dist) + : BoolAndOrNotLocalOperation (is_and), m_dist (dist) + { + // .. nothing yet .. + } + + virtual void compute_local (db::Layout *layout, const std::map > &interactions, std::set &result) const + { + std::map > sized_interactions = interactions; + for (std::map >::iterator i = sized_interactions.begin (); i != sized_interactions.end (); ++i) { + for (std::vector::iterator j = i->second.begin (); j != i->second.end (); ++j) { + db::Polygon poly = j->obj ().transformed (j->trans ()); + poly.size (m_dist, m_dist); + *j = db::PolygonRef (poly, layout->shape_repository ()); + } + } + BoolAndOrNotLocalOperation::compute_local (layout, sized_interactions, result); + } + + db::Coord dist () const + { + return m_dist; + } + +private: + db::Coord m_dist; +}; + /** * @brief Turns a layer into polygons and polygon references * The hierarchical processor needs polygon references and can't work on polygons directly. @@ -75,7 +110,7 @@ std::string contexts_to_s (db::Layout *layout, db::LocalProcessorContexts &conte return res; } -void run_test_bool (tl::TestBase *_this, const char *file, TestMode mode, int out_layer_num, db::Coord enl = 0, std::string *context_doc = 0) +void run_test_bool (tl::TestBase *_this, const char *file, TestMode mode, int out_layer_num, std::string *context_doc = 0) { db::Layout layout_org; @@ -120,7 +155,60 @@ void run_test_bool (tl::TestBase *_this, const char *file, TestMode mode, int ou proc.run (&op, l1, l2, lout); } else { db::LocalProcessorContexts contexts; - proc.compute_contexts (contexts, &op, l1, l2, enl); + proc.compute_contexts (contexts, &op, l1, l2); + *context_doc = contexts_to_s (&layout_org, contexts); + proc.compute_results (contexts, &op, lout); + } + + db::compare_layouts (_this, layout_org, testdata (file), lmap, false /*skip other layers*/, db::AsPolygons); +} + +void run_test_bool_with_size (tl::TestBase *_this, const char *file, TestMode mode, db::Coord dist, int out_layer_num, std::string *context_doc = 0) +{ + db::Layout layout_org; + + unsigned int l1 = 0, l2 = 0, lout = 0; + db::LayerMap lmap; + + { + tl::InputStream stream (testdata (file)); + db::Reader reader (stream); + + db::LayerProperties p; + + p.layer = 1; + p.datatype = 0; + lmap.map (db::LDPair (1, 0), l1 = layout_org.insert_layer ()); + layout_org.set_properties (l1, p); + + p.layer = 2; + p.datatype = 0; + lmap.map (db::LDPair (2, 0), l2 = layout_org.insert_layer ()); + layout_org.set_properties (l2, p); + + p.layer = out_layer_num; + p.datatype = 0; + lmap.map (db::LDPair (out_layer_num, 0), lout = layout_org.insert_layer ()); + layout_org.set_properties (lout, p); + + db::LoadLayoutOptions options; + options.get_options ().layer_map = lmap; + options.get_options ().create_other_layers = false; + reader.read (layout_org, options); + } + + layout_org.clear_layer (lout); + normalize_layer (layout_org, l1); + normalize_layer (layout_org, l2); + + BoolAndOrNotWithSizedLocalOperation op (mode == TMAnd, dist); + db::LocalProcessor proc (&layout_org, &layout_org.cell (*layout_org.begin_top_down ())); + + if (! context_doc) { + proc.run (&op, l1, l2, lout); + } else { + db::LocalProcessorContexts contexts; + proc.compute_contexts (contexts, &op, l1, l2); *context_doc = contexts_to_s (&layout_org, contexts); proc.compute_results (contexts, &op, lout); } @@ -228,7 +316,7 @@ TEST(BasicAnd9) { // Top-level ring structure, AND std::string doc; - run_test_bool (_this, "hlp9.oas", TMAnd, 100, 0, &doc); + run_test_bool (_this, "hlp9.oas", TMAnd, 100, &doc); EXPECT_EQ (doc, // This means: the interaction test is strong enough, so it does not see interactions between the // ring and the cells embedded inside the ring. So there is only one cell context. Some shapes @@ -244,7 +332,7 @@ TEST(BasicNot9) { // Top-level ring structure, NOT std::string doc; - run_test_bool (_this, "hlp9.oas", TMNot, 101, 0, &doc); + run_test_bool (_this, "hlp9.oas", TMNot, 101, &doc); EXPECT_EQ (doc, // This means: the interaction test is strong enough, so it does not see interactions between the // ring and the cells embedded inside the ring. So there is only one cell context. Some shapes @@ -268,3 +356,143 @@ TEST(BasicNot10) run_test_bool (_this, "hlp10.oas", TMNot, 101); } +TEST(BasicAndWithSize1) +{ + // Simple flat AND + run_test_bool_with_size (_this, "hlp1.oas", TMAnd, 1500, 102); +} + +TEST(BasicNotWithSize1) +{ + // Simple flat NOT + run_test_bool_with_size (_this, "hlp1.oas", TMNot, 1500, 103); +} + +TEST(BasicAndWithSize2) +{ + // Up/down and down/up interactions, AND + run_test_bool_with_size (_this, "hlp2.oas", TMAnd, 1500, 102); +} + +TEST(BasicNotWithSize2) +{ + // Up/down and down/up interactions, NOT + run_test_bool_with_size (_this, "hlp2.oas", TMNot, 1500, 103); +} + +TEST(BasicAndWithSize3) +{ + // Variant building, AND + run_test_bool_with_size (_this, "hlp3.oas", TMAnd, 1500, 102); +} + +TEST(BasicNotWithSize3) +{ + // Variant building, NOT + run_test_bool_with_size (_this, "hlp3.oas", TMNot, 1500, 103); +} + +TEST(BasicAndWithSize4) +{ + // Sibling interactions, variant building, AND + run_test_bool_with_size (_this, "hlp4.oas", TMAnd, 1500, 102); +} + +TEST(BasicNotWithSize4) +{ + // Sibling interactions, variant building, NOT + run_test_bool_with_size (_this, "hlp4.oas", TMNot, 1500, 103); +} + +TEST(BasicAndWithSize5) +{ + // Variant building with intermediate hierarchy, AND + run_test_bool_with_size (_this, "hlp5.oas", TMAnd, 1500, 102); +} + +TEST(BasicNotWithSize5) +{ + // Variant building with intermediate hierarchy, NOT + run_test_bool_with_size (_this, "hlp5.oas", TMNot, 1500, 103); +} + +TEST(BasicAndWithSize6) +{ + // Extreme variants (copy, vanishing), AND + run_test_bool_with_size (_this, "hlp6.oas", TMAnd, 1500, 102); +} + +TEST(BasicNotWithSize6) +{ + // Extreme variants (copy, vanishing), NOT + run_test_bool_with_size (_this, "hlp6.oas", TMNot, 1500, 103); +} + +TEST(BasicAndWithSize7) +{ + // Context replication - direct and indirect, AND + run_test_bool_with_size (_this, "hlp7.oas", TMAnd, 1500, 102); +} + +TEST(BasicNotWithSize7) +{ + // Context replication - direct and indirect, NOT + run_test_bool_with_size (_this, "hlp7.oas", TMNot, 1500, 103); +} + +TEST(BasicAndWithSize8) +{ + // Mixed sibling-parent contexts, AND + run_test_bool_with_size (_this, "hlp8.oas", TMAnd, 1500, 102); +} + +TEST(BasicNotWithSize8) +{ + // Mixed sibling-parent contexts, NOT + run_test_bool_with_size (_this, "hlp8.oas", TMNot, 1500, 103); +} + +TEST(BasicAndWithSize9) +{ + // Top-level ring structure, AND + std::string doc; + run_test_bool_with_size (_this, "hlp9.oas", TMAnd, 1500, 102, &doc); + EXPECT_EQ (doc, + // This means: the interaction test is strong enough, so it does not see interactions between the + // ring and the cells embedded inside the ring. So there is only one cell context. Some shapes + // from atop the CHILD cell don't interact with shapes inside CHILD, so there are 4 shapes rather than + // 6. And the shapes from top inside the ring are not seen by the RING's subject shapes. + "TOP[1] 0 insts, 0 shapes (1 times)\n" + "RING[1] 0 insts, 0 shapes (1 times)\n" + "CHILD1[1] 0 insts, 6 shapes (2 times)\n" + ); +} + +TEST(BasicNotWithSize9) +{ + // Top-level ring structure, NOT + std::string doc; + run_test_bool_with_size (_this, "hlp9.oas", TMNot, 1500, 103, &doc); + EXPECT_EQ (doc, + // This means: the interaction test is strong enough, so it does not see interactions between the + // ring and the cells embedded inside the ring. So there is only one cell context. Some shapes + // from atop the CHILD cell don't interact with shapes inside CHILD, so there are 4 shapes rather than + // 6. And the shapes from top inside the ring are not seen by the RING's subject shapes. + "TOP[1] 0 insts, 0 shapes (1 times)\n" + "RING[1] 0 insts, 0 shapes (1 times)\n" + "CHILD1[1] 0 insts, 6 shapes (2 times)\n" + ); +} + +TEST(BasicAndWithSize10) +{ + // Array instances, AND + run_test_bool_with_size (_this, "hlp10.oas", TMAnd, 150, 102); +} + +TEST(BasicNotWithSize10) +{ + // Array instances, NOT + run_test_bool_with_size (_this, "hlp10.oas", TMNot, 150, 103); +} +