WIP: more tests, debugging

This commit is contained in:
Matthias Koefferlein 2020-12-26 17:06:44 +01:00
parent cc6ad01529
commit 8d6dd23850
7 changed files with 149 additions and 18 deletions

View File

@ -871,18 +871,27 @@ std::string CompoundRegionLogicalCaseSelectOperationNode::generated_description
return r + CompoundRegionMultiInputOperationNode::description ();
}
template <class T>
void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local (db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<T> > &results, size_t max_vertex_count, double area_ratio) const
CompoundRegionLogicalCaseSelectOperationNode::ResultType
CompoundRegionLogicalCaseSelectOperationNode::result_type () const
{
ResultType result = Region;
for (size_t i = 1; i < children (); i += 2) {
if (i == 1) {
result = child (i)->result_type ();
} else {
tl_assert (result == child (i)->result_type ());
}
}
return result;
}
template <class T, class TR>
void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local (db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio) const
{
bool ok = false;
for (unsigned int ci = 0; ci < children (); ++ci) {
if (! ok && ci % 2 == 1) {
// skip false branches
continue;
}
shape_interactions<T, T> computed;
const shape_interactions<T, T> &child_interactions = interactions_for_child<T, T> (interactions, ci, computed);
@ -890,14 +899,24 @@ void CompoundRegionLogicalCaseSelectOperationNode::implement_compute_local (db::
if (ci % 2 == 0) {
ok = node->compute_local_bool<T> (layout, child_interactions, max_vertex_count, area_ratio);
if (ci + 1 < children ()) {
} else {
ok = node->compute_local_bool<T> (layout, child_interactions, max_vertex_count, area_ratio);
continue;
} else {
// executes the following statement as default branch
ok = true;
}
}
if (ok) {
if (m_multi_layer && results.size () > size_t (ci / 2)) {
std::vector<std::unordered_set<T> > one;
one.push_back (std::unordered_set<T> ());
std::vector<std::unordered_set<TR> > one;
one.push_back (std::unordered_set<TR> ());
node->compute_local (layout, child_interactions, one, max_vertex_count, area_ratio);
results[ci / 2].swap (one.front ());

View File

@ -130,20 +130,23 @@ public:
if (result_type () == Region) {
std::vector<std::unordered_set<T> > res;
res.push_back (std::unordered_set<T> ());
compute_local (layout, interactions, res, max_vertex_count, area_ratio);
return ! res.empty ();
return ! res.front ().empty ();
} else if (result_type () == Edges) {
std::vector<std::unordered_set<db::Edge> > res;
res.push_back (std::unordered_set<db::Edge> ());
compute_local (layout, interactions, res, max_vertex_count, area_ratio);
return ! res.empty ();
return ! res.front ().empty ();
} else if (result_type () == EdgePairs) {
std::vector<std::unordered_set<db::EdgePair> > res;
res.push_back (std::unordered_set<db::EdgePair> ());
compute_local (layout, interactions, res, max_vertex_count, area_ratio);
return ! res.empty ();
return ! res.front ().empty ();
} else {
return false;
@ -664,7 +667,7 @@ public:
virtual std::string generated_description () const;
// specifies the result type
virtual ResultType result_type () const { return Region; }
virtual ResultType result_type () const;
// the different computation slots
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Polygon> > &results, size_t max_vertex_count, double area_ratio) const
@ -677,9 +680,29 @@ public:
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
}
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
{
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
}
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
{
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
}
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::PolygonRef, db::PolygonRef> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const
{
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
}
virtual void do_compute_local (db::Layout *layout, const shape_interactions<db::Polygon, db::Polygon> &interactions, std::vector<std::unordered_set<db::EdgePair> > &results, size_t max_vertex_count, double area_ratio) const
{
implement_compute_local (layout, interactions, results, max_vertex_count, area_ratio);
}
private:
template <class T>
void implement_compute_local (db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<T> > &results, size_t max_vertex_count, double area_ratio) const;
template <class T, class TR>
void implement_compute_local (db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<TR> > &results, size_t max_vertex_count, double area_ratio) const;
bool m_multi_layer;
};

View File

@ -87,6 +87,17 @@ void CornerDetectorCore::detect_corners (const db::Polygon &poly, const CornerPo
}
}
// -----------------------------------------------------------------------------------
// Extents implementation
void Extents::process (const db::Polygon &poly, std::vector<db::Polygon> &result) const
{
db::Box b = poly.box ();
if (! b.empty ()) {
result.push_back (db::Polygon (b));
}
}
// -----------------------------------------------------------------------------------
// RelativeExtents implementation
@ -105,7 +116,7 @@ void RelativeExtents::process (const db::Polygon &poly, std::vector<db::Polygon>
const TransformationReducer *RelativeExtents::vars () const
{
if (m_dx == 0 && m_dy == 0 && fabs (m_fx1) < db::epsilon && fabs (m_fy1) < db::epsilon && fabs (m_fx2) < db::epsilon && fabs (m_fy2) < db::epsilon) {
if (m_dx == 0 && m_dy == 0 && fabs (m_fx1) < db::epsilon && fabs (m_fy1) < db::epsilon && fabs (1.0 - m_fx2) < db::epsilon && fabs (1.0 - m_fy2) < db::epsilon) {
return 0;
} else if (m_dx == m_dy && fabs (m_fx1 - m_fy1) < db::epsilon && fabs (1.0 - (m_fx1 + m_fx2)) < db::epsilon && fabs (m_fx2 - m_fy2) < db::epsilon && fabs (1.0 - (m_fy1 + m_fy2)) < db::epsilon) {
return & m_isotropic_reducer;

View File

@ -158,6 +158,27 @@ public:
// -----------------------------------------------------------------------------------
// Extents
/**
* @brief A processor delivering the extents (bounding box) of the merged polygons
*/
class DB_PUBLIC Extents
: public db::PolygonProcessorBase
{
public:
Extents ()
{
// .. nothing yet ..
}
void process (const db::Polygon &poly, std::vector<db::Polygon> &result) const;
virtual const TransformationReducer *vars () const { return 0; }
virtual bool result_is_merged () const { return false; }
virtual bool result_must_not_be_merged () const { return false; }
virtual bool requires_raw_input () const { return false; }
virtual bool wants_variants () const { return false; } // variants are too common, so don't do this
};
/**
* @brief A processor delivering the relative extents (bounding box) of the merged polygons
* This processor allows over- or undersizing of the resulting box by a given amount and delivery

View File

@ -29,6 +29,7 @@
#include "dbCompoundOperation.h"
#include "dbReader.h"
#include "dbRecursiveShapeIterator.h"
#include "dbRegionUtils.h"
#include "dbTestSupport.h"
#include "tlStream.h"
@ -337,3 +338,59 @@ TEST(8_PullWithEdgeOperation)
db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/drc/compound_au8.gds");
}
TEST(9_LogicalSelectOperation)
{
db::Layout ly;
{
std::string fn (tl::testsrc ());
fn += "/testdata/drc/compound_9.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
}
db::RegionCheckOptions check_options;
check_options.metrics = db::Projection;
unsigned int l1 = ly.get_layer (db::LayerProperties (1, 0));
db::Region r (db::RecursiveShapeIterator (ly, ly.cell (*ly.begin_top_down ()), l1));
unsigned int l2 = ly.get_layer (db::LayerProperties (2, 0));
db::Region r2 (db::RecursiveShapeIterator (ly, ly.cell (*ly.begin_top_down ()), l2));
// the if/then ladder is:
//
// if (area > 10um2) return sized(+50nm)
// else if (is_rectangle) return sized(-50nm)
// else return bbox
db::CompoundRegionOperationPrimaryNode *primary = new db::CompoundRegionOperationPrimaryNode ();
std::vector<db::CompoundRegionOperationNode *> inputs;
db::CompoundRegionFilterOperationNode *condition1 = new db::CompoundRegionFilterOperationNode (new db::RegionAreaFilter (0, 10000000, true), primary, true);
inputs.push_back (condition1);
db::CompoundRegionSizeOperationNode *result1 = new db::CompoundRegionSizeOperationNode (50, 50, 2, primary);
inputs.push_back (result1);
db::CompoundRegionFilterOperationNode *condition2 = new db::CompoundRegionFilterOperationNode (new db::RectangleFilter (false), primary, true);
inputs.push_back (condition2);
db::CompoundRegionSizeOperationNode *result2 = new db::CompoundRegionSizeOperationNode (-50, -50, 2, primary);
inputs.push_back (result2);
db::CompoundRegionProcessingOperationNode *result_default = new db::CompoundRegionProcessingOperationNode (new db::Extents (), primary, true);
inputs.push_back (result_default);
db::CompoundRegionLogicalCaseSelectOperationNode select_node (false, inputs);
db::Region res = r.cop_to_region (select_node);
unsigned int l1000 = ly.get_layer (db::LayerProperties (1000, 0));
res.insert_into (&ly, *ly.begin_top_down (), l1000);
CHECKPOINT();
db::compare_layouts (_this, ly, tl::testsrc () + "/testdata/drc/compound_au9.gds");
}

BIN
testdata/drc/compound_9.gds vendored Normal file

Binary file not shown.

BIN
testdata/drc/compound_au9.gds vendored Normal file

Binary file not shown.