mirror of https://github.com/KLayout/klayout.git
WIP: more tests, debugging
This commit is contained in:
parent
cc6ad01529
commit
8d6dd23850
|
|
@ -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 ());
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue