WIP: some refactoring to make functions available for DRC compound operations and to simplify binding

This commit is contained in:
Matthias Koefferlein 2021-01-01 23:20:11 +01:00
parent cdcac6f5d3
commit 70ccc50b39
15 changed files with 794 additions and 330 deletions

View File

@ -22,25 +22,7 @@
#include "dbCompoundOperation.h"
#include "dbRegion.h"
/*@@@@
TODO:
* Transform variants?
* "result is merged"?
* "requires raw input"?
* edge pair to edge generation nodes (first, second)
* Interactions with shapes over some distance for neighborhood analysis
* Sized subject shapes as inputs for other operations? how to compute distance then?
* how do the logical boolean ops work?
* what is the "multi_input" for case nodes?
*/
#include "dbRegionUtils.h"
namespace db
{
@ -584,16 +566,41 @@ run_poly_bool (CompoundRegionGeometricalBoolOperationNode::GeometricalOp op, db:
// TODO: it's more efficient to feed the EP directly for polygon-to-polygon bools
db::Region ra, rb;
init_region (ra, a);
init_region (rb, b);
if (op == CompoundRegionGeometricalBoolOperationNode::And) {
write_result (layout, res, ra & rb);
} else if (op == CompoundRegionGeometricalBoolOperationNode::Or) {
write_result (layout, res, ra + rb);
} else if (op == CompoundRegionGeometricalBoolOperationNode::Xor) {
write_result (layout, res, ra ^ rb);
} else if (op == CompoundRegionGeometricalBoolOperationNode::Not) {
write_result (layout, res, ra - rb);
if (ra.empty ()) {
if (op == CompoundRegionGeometricalBoolOperationNode::And || op == CompoundRegionGeometricalBoolOperationNode::Not) {
write_result (layout, res, ra);
} else if (op == CompoundRegionGeometricalBoolOperationNode::Or || op == CompoundRegionGeometricalBoolOperationNode::Xor) {
init_region (rb, b);
write_result (layout, res, rb);
}
} else {
init_region (rb, b);
if (rb.empty ()) {
if (op == CompoundRegionGeometricalBoolOperationNode::And) {
write_result (layout, res, rb);
} else {
write_result (layout, res, ra);
}
} else {
if (op == CompoundRegionGeometricalBoolOperationNode::And) {
write_result (layout, res, ra & rb);
} else if (op == CompoundRegionGeometricalBoolOperationNode::Or) {
write_result (layout, res, ra + rb);
} else if (op == CompoundRegionGeometricalBoolOperationNode::Xor) {
write_result (layout, res, ra ^ rb);
} else if (op == CompoundRegionGeometricalBoolOperationNode::Not) {
write_result (layout, res, ra - rb);
}
}
}
}
@ -622,9 +629,22 @@ run_poly_vs_edge_bool (CompoundRegionGeometricalBoolOperationNode::GeometricalOp
init_region (ra, a);
db::Edges eb;
init_edges (eb, b);
write_result (layout, res, eb & ra);
if (ra.empty ()) {
write_result (layout, res, eb);
} else {
init_edges (eb, b);
if (eb.empty ()) {
write_result (layout, res, eb);
} else {
write_result (layout, res, eb & ra);
}
}
}
static void
@ -647,17 +667,25 @@ run_edge_vs_poly_bool (CompoundRegionGeometricalBoolOperationNode::GeometricalOp
return;
}
// TODO: it's more efficient to feed the EP directly for polygon-to-polygon bools
db::Region rb;
init_region (rb, b);
db::Edges ea;
init_edges (ea, a);
if (op == CompoundRegionGeometricalBoolOperationNode::And) {
write_result (layout, res, ea & rb);
} else if (op == CompoundRegionGeometricalBoolOperationNode::Not) {
write_result (layout, res, ea - rb);
if (ea.empty ()) {
write_result (layout, res, ea);
} else {
// TODO: it's more efficient to feed the EP directly for polygon-to-polygon bools
db::Region rb;
init_region (rb, b);
if (op == CompoundRegionGeometricalBoolOperationNode::And) {
write_result (layout, res, ea & rb);
} else if (op == CompoundRegionGeometricalBoolOperationNode::Not) {
write_result (layout, res, ea - rb);
}
}
}
@ -678,16 +706,42 @@ run_bool (CompoundRegionGeometricalBoolOperationNode::GeometricalOp op, db::Layo
{
db::Edges ea, eb;
init_edges (ea, a);
init_edges (eb, b);
if (op == CompoundRegionGeometricalBoolOperationNode::And) {
write_result (layout, res, ea & eb);
} else if (op == CompoundRegionGeometricalBoolOperationNode::Or) {
write_result (layout, res, ea + eb);
} else if (op == CompoundRegionGeometricalBoolOperationNode::Xor) {
write_result (layout, res, ea ^ eb);
} else if (op == CompoundRegionGeometricalBoolOperationNode::Not) {
write_result (layout, res, ea - eb);
if (ea.empty ()) {
if (op == CompoundRegionGeometricalBoolOperationNode::And || op == CompoundRegionGeometricalBoolOperationNode::Not) {
write_result (layout, res, ea);
} else if (op == CompoundRegionGeometricalBoolOperationNode::Or || op == CompoundRegionGeometricalBoolOperationNode::Xor) {
init_edges (eb, b);
write_result (layout, res, eb);
}
} else {
init_edges (eb, b);
if (eb.empty ()) {
if (op == CompoundRegionGeometricalBoolOperationNode::And) {
write_result (layout, res, eb);
} else {
write_result (layout, res, ea);
}
} else {
if (op == CompoundRegionGeometricalBoolOperationNode::And) {
write_result (layout, res, ea & eb);
} else if (op == CompoundRegionGeometricalBoolOperationNode::Or) {
write_result (layout, res, ea + eb);
} else if (op == CompoundRegionGeometricalBoolOperationNode::Xor) {
write_result (layout, res, ea ^ eb);
} else if (op == CompoundRegionGeometricalBoolOperationNode::Not) {
write_result (layout, res, ea - eb);
}
}
}
}
@ -1154,6 +1208,39 @@ CompoundRegionToEdgeProcessingOperationNode::processed (db::Layout *, const db::
// ---------------------------------------------------------------------------------------------
CompoundRegionEdgeProcessingOperationNode::CompoundRegionEdgeProcessingOperationNode (EdgeProcessorBase *proc, CompoundRegionOperationNode *input, bool owns_proc)
: CompoundRegionMultiInputOperationNode (input), mp_proc (proc), m_owns_proc (owns_proc)
{
set_description ("processor");
}
CompoundRegionEdgeProcessingOperationNode::~CompoundRegionEdgeProcessingOperationNode ()
{
if (m_owns_proc) {
delete mp_proc;
mp_proc = 0;
}
}
void
CompoundRegionEdgeProcessingOperationNode::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);
}
void
CompoundRegionEdgeProcessingOperationNode::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);
}
void CompoundRegionEdgeProcessingOperationNode::processed (db::Layout *, const db::Edge &p, std::vector<db::Edge> &res) const
{
mp_proc->process (p, res);
}
// ---------------------------------------------------------------------------------------------
CompoundRegionEdgeToPolygonProcessingOperationNode::CompoundRegionEdgeToPolygonProcessingOperationNode (EdgeToPolygonProcessorBase *proc, CompoundRegionOperationNode *input, bool owns_proc)
: CompoundRegionMultiInputOperationNode (input), mp_proc (proc), m_owns_proc (owns_proc)
{

View File

@ -936,6 +936,46 @@ private:
}
};
class DB_PUBLIC CompoundRegionEdgeProcessingOperationNode
: public CompoundRegionMultiInputOperationNode
{
public:
CompoundRegionEdgeProcessingOperationNode (EdgeProcessorBase *proc, CompoundRegionOperationNode *input, bool owns_proc = false);
~CompoundRegionEdgeProcessingOperationNode ();
// specifies the result type
virtual ResultType result_type () const { return Edges; }
virtual const TransformationReducer *vars () const { return mp_proc->vars (); }
virtual bool wants_variants () const { return mp_proc->wants_variants (); }
virtual bool wants_merged () const { return true; }
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;
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;
private:
EdgeProcessorBase *mp_proc;
bool m_owns_proc;
void processed (db::Layout *, const db::Edge &p, std::vector<db::Edge> &res) const;
template <class T>
void implement_compute_local (db::Layout *layout, const shape_interactions<T, T> &interactions, std::vector<std::unordered_set<db::Edge> > &results, size_t max_vertex_count, double area_ratio) const
{
std::vector<std::unordered_set<db::Edge> > one;
one.push_back (std::unordered_set<db::Edge> ());
child (0)->compute_local (layout, interactions, one, max_vertex_count, area_ratio);
std::vector<db::Edge> res;
for (typename std::unordered_set<db::Edge>::const_iterator p = one.front ().begin (); p != one.front ().end (); ++p) {
res.clear ();
processed (layout, *p, res);
results.front ().insert (res.begin (), res.end ());
}
}
};
class DB_PUBLIC CompoundRegionEdgePairToPolygonProcessingOperationNode
: public CompoundRegionMultiInputOperationNode
{

View File

@ -25,62 +25,12 @@
#include "dbOriginalLayerEdges.h"
#include "dbEmptyEdges.h"
#include "dbFlatEdges.h"
#include "dbEdgesUtils.h"
#include "dbRegion.h"
namespace db
{
namespace
{
// -------------------------------------------------------------------------------------------------------------
// Smoothing processor
class EdgeSegmentSelector
: public EdgeProcessorBase
{
public:
EdgeSegmentSelector (int mode, db::Edges::length_type length, double fraction)
: m_mode (mode), m_length (length), m_fraction (fraction)
{ }
virtual void process (const db::Edge &edge, std::vector<db::Edge> &res) const
{
double l = std::max (edge.double_length () * m_fraction, double (m_length));
if (m_mode < 0) {
res.push_back (db::Edge (edge.p1 (), db::Point (db::DPoint (edge.p1 ()) + db::DVector (edge.d ()) * (l / edge.double_length ()))));
} else if (m_mode > 0) {
res.push_back (db::Edge (db::Point (db::DPoint (edge.p2 ()) - db::DVector (edge.d ()) * (l / edge.double_length ())), edge.p2 ()));
} else {
db::DVector dl = db::DVector (edge.d ()) * (0.5 * l / edge.double_length ());
db::DPoint center = db::DPoint (edge.p1 ()) + db::DVector (edge.p2 () - edge.p1 ()) * 0.5;
res.push_back (db::Edge (db::Point (center - dl), db::Point (center + dl)));
}
}
virtual const TransformationReducer *vars () const { return &m_vars; }
virtual bool result_is_merged () const { return false; }
virtual bool requires_raw_input () const { return false; }
virtual bool result_must_not_be_merged () const { return m_length <= 0; }
virtual bool wants_variants () const { return true; }
private:
int m_mode;
db::Edges::length_type m_length;
double m_fraction;
db::MagnificationReducer m_vars;
};
}
// -------------------------------------------------------------------------------------------------------------
// Edges implementation

View File

@ -174,4 +174,37 @@ extended_edge (const db::Edge &edge, db::Coord ext_b, db::Coord ext_e, db::Coord
return poly;
}
// -------------------------------------------------------------------------------------------------------------
// EdgeSegmentSelector processor
EdgeSegmentSelector::EdgeSegmentSelector (int mode, db::Edges::length_type length, double fraction)
: m_mode (mode), m_length (length), m_fraction (fraction)
{ }
EdgeSegmentSelector::~EdgeSegmentSelector ()
{ }
void
EdgeSegmentSelector::process (const db::Edge &edge, std::vector<db::Edge> &res) const
{
double l = std::max (edge.double_length () * m_fraction, double (m_length));
if (m_mode < 0) {
res.push_back (db::Edge (edge.p1 (), db::Point (db::DPoint (edge.p1 ()) + db::DVector (edge.d ()) * (l / edge.double_length ()))));
} else if (m_mode > 0) {
res.push_back (db::Edge (db::Point (db::DPoint (edge.p2 ()) - db::DVector (edge.d ()) * (l / edge.double_length ())), edge.p2 ()));
} else {
db::DVector dl = db::DVector (edge.d ()) * (0.5 * l / edge.double_length ());
db::DPoint center = db::DPoint (edge.p1 ()) + db::DVector (edge.p2 () - edge.p1 ()) * 0.5;
res.push_back (db::Edge (db::Point (center - dl), db::Point (center + dl)));
}
}
}

View File

@ -336,6 +336,55 @@ private:
*/
db::Polygon extended_edge (const db::Edge &edge, db::Coord ext_b, db::Coord ext_e, db::Coord ext_o, db::Coord ext_i);
/**
* @brief Wraps the extension algorithm into a edge to polygon processor
*/
class DB_PUBLIC ExtendedEdgeProcessor
: public db::EdgeToPolygonProcessorBase
{
public:
ExtendedEdgeProcessor (db::Coord e)
: m_ext_b (e), m_ext_e (e), m_ext_o (e), m_ext_i (e)
{ }
ExtendedEdgeProcessor (db::Coord ext_b, db::Coord ext_e, db::Coord ext_o, db::Coord ext_i)
: m_ext_b (ext_b), m_ext_e (ext_e), m_ext_o (ext_o), m_ext_i (ext_i)
{ }
virtual void process (const Edge &edge, std::vector<db::Polygon> &res) const
{
res.push_back (extended_edge (edge, m_ext_b, m_ext_e, m_ext_o, m_ext_i));
}
private:
db::Coord m_ext_b, m_ext_e, m_ext_o, m_ext_i;
};
/**
* @brief The EdgeSegmentSelector class
*/
class DB_PUBLIC EdgeSegmentSelector
: public EdgeProcessorBase
{
public:
EdgeSegmentSelector (int mode, db::Edges::length_type length, double fraction);
~EdgeSegmentSelector ();
virtual void process (const db::Edge &edge, std::vector<db::Edge> &res) const;
virtual const TransformationReducer *vars () const { return &m_vars; }
virtual bool result_is_merged () const { return false; }
virtual bool requires_raw_input () const { return false; }
virtual bool result_must_not_be_merged () const { return m_length <= 0; }
virtual bool wants_variants () const { return true; }
private:
int m_mode;
db::Edges::length_type m_length;
double m_fraction;
db::MagnificationReducer m_vars;
};
} // namespace db
#endif

View File

@ -32,7 +32,7 @@ namespace db
// FlatTexts implementation
FlatTexts::FlatTexts ()
: AsIfFlatTexts (), m_texts (false)
: AsIfFlatTexts (), mp_texts (new db::Shapes (false))
{
// .. nothing yet ..
}
@ -43,13 +43,13 @@ FlatTexts::~FlatTexts ()
}
FlatTexts::FlatTexts (const FlatTexts &other)
: AsIfFlatTexts (other), m_texts (false)
: AsIfFlatTexts (other), mp_texts (other.mp_texts)
{
m_texts = other.m_texts;
// .. nothing yet ..
}
FlatTexts::FlatTexts (const db::Shapes &texts)
: AsIfFlatTexts (), m_texts (texts)
: AsIfFlatTexts (), mp_texts (new db::Shapes (texts))
{
// .. nothing yet ..
}
@ -61,56 +61,58 @@ void FlatTexts::invalidate_cache ()
void FlatTexts::reserve (size_t n)
{
m_texts.reserve (db::Text::tag (), n);
mp_texts->reserve (db::Text::tag (), n);
}
TextsIteratorDelegate *FlatTexts::begin () const
{
return new FlatTextsIterator (&m_texts);
return new FlatTextsIterator (mp_texts.get_non_const ());
}
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> FlatTexts::begin_iter () const
{
return std::make_pair (db::RecursiveShapeIterator (m_texts), db::ICplxTrans ());
return std::make_pair (db::RecursiveShapeIterator (*mp_texts), db::ICplxTrans ());
}
bool FlatTexts::empty () const
{
return m_texts.empty ();
return mp_texts->empty ();
}
size_t FlatTexts::count () const
{
return m_texts.size ();
return mp_texts->size ();
}
size_t FlatTexts::hier_count () const
{
return m_texts.size ();
return mp_texts->size ();
}
Box FlatTexts::compute_bbox () const
{
m_texts.update_bbox ();
return m_texts.bbox ();
mp_texts->update_bbox ();
return mp_texts->bbox ();
}
TextsDelegate *
FlatTexts::filter_in_place (const TextFilterBase &filter)
{
text_iterator_type pw = m_texts.get_layer<db::Text, db::unstable_layer_tag> ().begin ();
db::Shapes &texts = *mp_texts;
text_iterator_type pw = texts.get_layer<db::Text, db::unstable_layer_tag> ().begin ();
for (TextsIterator p (begin ()); ! p.at_end (); ++p) {
if (filter.selected (*p)) {
if (pw == m_texts.get_layer<db::Text, db::unstable_layer_tag> ().end ()) {
m_texts.get_layer<db::Text, db::unstable_layer_tag> ().insert (*p);
pw = m_texts.get_layer<db::Text, db::unstable_layer_tag> ().end ();
if (pw == texts.get_layer<db::Text, db::unstable_layer_tag> ().end ()) {
texts.get_layer<db::Text, db::unstable_layer_tag> ().insert (*p);
pw = texts.get_layer<db::Text, db::unstable_layer_tag> ().end ();
} else {
m_texts.get_layer<db::Text, db::unstable_layer_tag> ().replace (pw++, *p);
texts.get_layer<db::Text, db::unstable_layer_tag> ().replace (pw++, *p);
}
}
}
m_texts.get_layer<db::Text, db::unstable_layer_tag> ().erase (pw, m_texts.get_layer<db::Text, db::unstable_layer_tag> ().end ());
texts.get_layer<db::Text, db::unstable_layer_tag> ().erase (pw, texts.get_layer<db::Text, db::unstable_layer_tag> ().end ());
return this;
}
@ -147,22 +149,24 @@ TextsDelegate *FlatTexts::add_in_place (const Texts &other)
{
invalidate_cache ();
db::Shapes &texts = *mp_texts;
FlatTexts *other_flat = dynamic_cast<FlatTexts *> (other.delegate ());
if (other_flat) {
m_texts.insert (other_flat->raw_texts ().get_layer<db::Text, db::unstable_layer_tag> ().begin (), other_flat->raw_texts ().get_layer<db::Text, db::unstable_layer_tag> ().end ());
texts.insert (other_flat->raw_texts ().get_layer<db::Text, db::unstable_layer_tag> ().begin (), other_flat->raw_texts ().get_layer<db::Text, db::unstable_layer_tag> ().end ());
} else {
size_t n = m_texts.size ();
size_t n = texts.size ();
for (TextsIterator p (other.begin ()); ! p.at_end (); ++p) {
++n;
}
m_texts.reserve (db::Text::tag (), n);
texts.reserve (db::Text::tag (), n);
for (TextsIterator p (other.begin ()); ! p.at_end (); ++p) {
m_texts.insert (*p);
texts.insert (*p);
}
}
@ -172,7 +176,7 @@ TextsDelegate *FlatTexts::add_in_place (const Texts &other)
const db::Text *FlatTexts::nth (size_t n) const
{
return n < m_texts.size () ? &m_texts.get_layer<db::Text, db::unstable_layer_tag> ().begin () [n] : 0;
return n < mp_texts->size () ? &mp_texts->get_layer<db::Text, db::unstable_layer_tag> ().begin () [n] : 0;
}
bool FlatTexts::has_valid_texts () const
@ -199,13 +203,13 @@ FlatTexts::insert_into_as_polygons (Layout *layout, db::cell_index_type into_cel
void
FlatTexts::insert_into (Layout *layout, db::cell_index_type into_cell, unsigned int into_layer) const
{
layout->cell (into_cell).shapes (into_layer).insert (m_texts);
layout->cell (into_cell).shapes (into_layer).insert (*mp_texts);
}
void
FlatTexts::insert (const db::Text &t)
{
m_texts.insert (t);
mp_texts->insert (t);
invalidate_cache ();
}

View File

@ -28,6 +28,7 @@
#include "dbAsIfFlatTexts.h"
#include "dbShapes.h"
#include "tlCopyOnWrite.h"
namespace db {
@ -110,14 +111,16 @@ public:
void transform (const Trans &trans)
{
if (! trans.is_unity ()) {
for (text_iterator_type p = m_texts.template get_layer<db::Text, db::unstable_layer_tag> ().begin (); p != m_texts.template get_layer<db::Text, db::unstable_layer_tag> ().end (); ++p) {
m_texts.get_layer<db::Text, db::unstable_layer_tag> ().replace (p, p->transformed (trans));
db::Shapes &texts = *mp_texts;
for (text_iterator_type p = texts.template get_layer<db::Text, db::unstable_layer_tag> ().begin (); p != texts.template get_layer<db::Text, db::unstable_layer_tag> ().end (); ++p) {
texts.get_layer<db::Text, db::unstable_layer_tag> ().replace (p, p->transformed (trans));
}
invalidate_cache ();
}
}
db::Shapes &raw_texts () { return m_texts; }
db::Shapes &raw_texts () { return *mp_texts; }
const db::Shapes &raw_texts () const { return *mp_texts; }
protected:
virtual Box compute_bbox () const;
@ -128,7 +131,7 @@ private:
FlatTexts &operator= (const FlatTexts &other);
mutable db::Shapes m_texts;
mutable tl::copy_on_write_ptr<db::Shapes> mp_texts;
};
}

View File

@ -22,6 +22,7 @@
#include "dbRegion.h"
#include "dbRegionUtils.h"
#include "dbOriginalLayerRegion.h"
#include "dbEmptyRegion.h"
#include "dbFlatRegion.h"
@ -36,149 +37,6 @@
namespace db
{
namespace
{
// -------------------------------------------------------------------------------------------------------------
// Strange polygon processor
/**
* @brief A helper class to implement the strange polygon detector
*/
struct StrangePolygonInsideFunc
{
inline bool operator() (int wc) const
{
return wc < 0 || wc > 1;
}
};
class StrangePolygonCheckProcessor
: public PolygonProcessorBase
{
public:
StrangePolygonCheckProcessor () { }
virtual void process (const db::Polygon &poly, std::vector<db::Polygon> &res) const
{
EdgeProcessor ep;
ep.insert (poly);
StrangePolygonInsideFunc inside;
db::GenericMerge<StrangePolygonInsideFunc> op (inside);
db::PolygonContainer pc (res, false);
db::PolygonGenerator pg (pc, false, false);
ep.process (pg, op);
}
virtual const TransformationReducer *vars () const { return 0; }
virtual bool result_is_merged () const { return false; }
virtual bool requires_raw_input () const { return true; }
virtual bool wants_variants () const { return true; }
virtual bool result_must_not_be_merged () const { return false; }
};
// -------------------------------------------------------------------------------------------------------------
// Smoothing processor
class SmoothingProcessor
: public PolygonProcessorBase
{
public:
SmoothingProcessor (db::Coord d) : m_d (d) { }
virtual void process (const db::Polygon &poly, std::vector<db::Polygon> &res) const
{
res.push_back (db::smooth (poly, m_d));
}
virtual const TransformationReducer *vars () const { return &m_vars; }
virtual bool result_is_merged () const { return false; }
virtual bool requires_raw_input () const { return false; }
virtual bool wants_variants () const { return true; }
virtual bool result_must_not_be_merged () const { return false; }
private:
db::Coord m_d;
db::MagnificationReducer m_vars;
};
// -------------------------------------------------------------------------------------------------------------
// Rounded corners processor
class RoundedCornersProcessor
: public PolygonProcessorBase
{
public:
RoundedCornersProcessor (double rinner, double router, unsigned int n)
: m_rinner (rinner), m_router (router), m_n (n)
{ }
virtual void process (const db::Polygon &poly, std::vector<db::Polygon> &res) const
{
res.push_back (db::compute_rounded (poly, m_rinner, m_router, m_n));
}
virtual const TransformationReducer *vars () const { return &m_vars; }
virtual bool result_is_merged () const { return true; } // we believe so ...
virtual bool requires_raw_input () const { return false; }
virtual bool wants_variants () const { return true; }
virtual bool result_must_not_be_merged () const { return false; }
private:
double m_rinner, m_router;
unsigned int m_n;
db::MagnificationReducer m_vars;
};
// -------------------------------------------------------------------------------------------------------------
// Holes decomposition processor
class HolesExtractionProcessor
: public PolygonProcessorBase
{
public:
HolesExtractionProcessor () { }
virtual void process (const db::Polygon &poly, std::vector<db::Polygon> &res) const
{
for (size_t i = 0; i < poly.holes (); ++i) {
res.push_back (db::Polygon ());
res.back ().assign_hull (poly.begin_hole ((unsigned int) i), poly.end_hole ((unsigned int) i));
}
}
virtual const TransformationReducer *vars () const { return 0; }
virtual bool result_is_merged () const { return true; } // we believe so ...
virtual bool requires_raw_input () const { return false; }
virtual bool wants_variants () const { return true; }
virtual bool result_must_not_be_merged () const { return false; }
};
// -------------------------------------------------------------------------------------------------------------
// Hull extraction processor
class HullExtractionProcessor
: public PolygonProcessorBase
{
public:
HullExtractionProcessor () { }
virtual void process (const db::Polygon &poly, std::vector<db::Polygon> &res) const
{
res.push_back (db::Polygon ());
res.back ().assign_hull (poly.begin_hull (), poly.end_hull ());
}
virtual const TransformationReducer *vars () const { return 0; }
virtual bool result_is_merged () const { return true; } // we believe so ...
virtual bool requires_raw_input () const { return false; }
virtual bool wants_variants () const { return true; }
virtual bool result_must_not_be_merged () const { return false; }
};
}
// -------------------------------------------------------------------------------------------------------------
// Region implementation

View File

@ -22,6 +22,7 @@
#include "dbRegionUtils.h"
#include "dbPolygonTools.h"
#include "dbEdgeBoolean.h"
#include "tlSelect.h"
@ -379,6 +380,137 @@ poly2poly_check_base<PolygonType>::enter (const PolygonType &o1, size_t p1, cons
template class poly2poly_check_base<db::Polygon>;
template class poly2poly_check_base<db::PolygonRef>;
// -------------------------------------------------------------------------------------
// SinglePolygonCheck implementation
SinglePolygonCheck::SinglePolygonCheck (db::edge_relation_type rel, db::Coord d, const RegionCheckOptions &options)
: m_relation (rel), m_d (d), m_options (options)
{ }
void
SinglePolygonCheck::process (const db::Polygon &polygon, std::vector<db::EdgePair> &res) const
{
std::unordered_set<db::EdgePair> result;
EdgeRelationFilter check (m_relation, m_d, m_options.metrics);
check.set_include_zero (false);
check.set_whole_edges (m_options.whole_edges);
check.set_ignore_angle (m_options.ignore_angle);
check.set_min_projection (m_options.min_projection);
check.set_max_projection (m_options.max_projection);
edge2edge_check<std::unordered_set<db::EdgePair> > edge_check (check, result, false /*=same polygons*/, false /*=same layers*/, m_options.shielded);
poly2poly_check<db::Polygon, std::unordered_set<db::EdgePair> > poly_check (edge_check);
do {
poly_check.enter (polygon, 0);
} while (edge_check.prepare_next_pass ());
res.insert (res.end (), result.begin (), result.end ());
}
// -------------------------------------------------------------------------------------------------------------
// Strange polygon processor
namespace {
/**
* @brief A helper class to implement the strange polygon detector
*/
struct StrangePolygonInsideFunc
{
inline bool operator() (int wc) const
{
return wc < 0 || wc > 1;
}
};
}
StrangePolygonCheckProcessor::StrangePolygonCheckProcessor () { }
StrangePolygonCheckProcessor::~StrangePolygonCheckProcessor () { }
void
StrangePolygonCheckProcessor::process (const db::Polygon &poly, std::vector<db::Polygon> &res) const
{
EdgeProcessor ep;
ep.insert (poly);
StrangePolygonInsideFunc inside;
db::GenericMerge<StrangePolygonInsideFunc> op (inside);
db::PolygonContainer pc (res, false);
db::PolygonGenerator pg (pc, false, false);
ep.process (pg, op);
}
// -------------------------------------------------------------------------------------------------------------
// Smoothing processor
SmoothingProcessor::SmoothingProcessor (db::Coord d) : m_d (d) { }
SmoothingProcessor::~SmoothingProcessor () { }
void
SmoothingProcessor::process (const db::Polygon &poly, std::vector<db::Polygon> &res) const
{
res.push_back (db::smooth (poly, m_d));
}
// -------------------------------------------------------------------------------------------------------------
// Rounded corners processor
RoundedCornersProcessor::RoundedCornersProcessor (double rinner, double router, unsigned int n)
: m_rinner (rinner), m_router (router), m_n (n)
{ }
RoundedCornersProcessor::~RoundedCornersProcessor ()
{ }
void
RoundedCornersProcessor::process (const db::Polygon &poly, std::vector<db::Polygon> &res) const
{
res.push_back (db::compute_rounded (poly, m_rinner, m_router, m_n));
}
// -------------------------------------------------------------------------------------------------------------
// Holes decomposition processor
HolesExtractionProcessor::HolesExtractionProcessor ()
{
}
HolesExtractionProcessor::~HolesExtractionProcessor ()
{
}
void
HolesExtractionProcessor::process (const db::Polygon &poly, std::vector<db::Polygon> &res) const
{
for (size_t i = 0; i < poly.holes (); ++i) {
res.push_back (db::Polygon ());
res.back ().assign_hull (poly.begin_hole ((unsigned int) i), poly.end_hole ((unsigned int) i));
}
}
// -------------------------------------------------------------------------------------------------------------
// Hull decomposition processor
HullExtractionProcessor::HullExtractionProcessor ()
{
}
HullExtractionProcessor::~HullExtractionProcessor ()
{
}
void
HullExtractionProcessor::process (const db::Polygon &poly, std::vector<db::Polygon> &res) const
{
res.push_back (db::Polygon ());
res.back ().assign_hull (poly.begin_hull (), poly.end_hull ());
}
// -------------------------------------------------------------------------------------
// RegionToEdgeInteractionFilterBase implementation

View File

@ -361,6 +361,113 @@ private:
db::MagnificationAndOrientationReducer m_anisotropic_vars;
};
/**
* @brief A polygon processor filtering strange polygons
*
* "strange polygons" are those which do not have a specific orientation, e.g.
* "8" shape polygons.
*/
class DB_PUBLIC StrangePolygonCheckProcessor
: public PolygonProcessorBase
{
public:
StrangePolygonCheckProcessor ();
~StrangePolygonCheckProcessor ();
virtual void process (const db::Polygon &poly, std::vector<db::Polygon> &res) const;
virtual const TransformationReducer *vars () const { return 0; }
virtual bool result_is_merged () const { return false; }
virtual bool requires_raw_input () const { return true; }
virtual bool wants_variants () const { return true; }
virtual bool result_must_not_be_merged () const { return false; }
};
/**
* @brief A polygon processor applying smoothing
*/
class DB_PUBLIC SmoothingProcessor
: public PolygonProcessorBase
{
public:
SmoothingProcessor (db::Coord d);
~SmoothingProcessor ();
virtual void process (const db::Polygon &poly, std::vector<db::Polygon> &res) const;
virtual const TransformationReducer *vars () const { return &m_vars; }
virtual bool result_is_merged () const { return false; }
virtual bool requires_raw_input () const { return false; }
virtual bool wants_variants () const { return true; }
virtual bool result_must_not_be_merged () const { return false; }
private:
db::Coord m_d;
db::MagnificationReducer m_vars;
};
/**
* @brief A polygon processor generating rounded corners
*/
class DB_PUBLIC RoundedCornersProcessor
: public PolygonProcessorBase
{
public:
RoundedCornersProcessor (double rinner, double router, unsigned int n);
~RoundedCornersProcessor ();
virtual void process (const db::Polygon &poly, std::vector<db::Polygon> &res) const;
virtual const TransformationReducer *vars () const { return &m_vars; }
virtual bool result_is_merged () const { return true; } // we believe so ...
virtual bool requires_raw_input () const { return false; }
virtual bool wants_variants () const { return true; }
virtual bool result_must_not_be_merged () const { return false; }
private:
double m_rinner, m_router;
unsigned int m_n;
db::MagnificationReducer m_vars;
};
/**
* @brief A polygon processor extracting the holes
*/
class DB_PUBLIC HolesExtractionProcessor
: public PolygonProcessorBase
{
public:
HolesExtractionProcessor ();
~HolesExtractionProcessor ();
virtual void process (const db::Polygon &poly, std::vector<db::Polygon> &res) const;
virtual const TransformationReducer *vars () const { return 0; }
virtual bool result_is_merged () const { return true; } // we believe so ...
virtual bool requires_raw_input () const { return false; }
virtual bool wants_variants () const { return true; }
virtual bool result_must_not_be_merged () const { return false; }
};
/**
* @brief A polygon processor extracting the hull
*/
class DB_PUBLIC HullExtractionProcessor
: public PolygonProcessorBase
{
public:
HullExtractionProcessor ();
~HullExtractionProcessor ();
virtual void process (const db::Polygon &poly, std::vector<db::Polygon> &res) const;
virtual const TransformationReducer *vars () const { return 0; }
virtual bool result_is_merged () const { return true; } // we believe so ...
virtual bool requires_raw_input () const { return false; }
virtual bool wants_variants () const { return true; }
virtual bool result_must_not_be_merged () const { return false; }
};
/**
* @brief A helper class for the DRC functionality which acts as an edge pair receiver
*/
@ -589,6 +696,23 @@ public:
}
};
/**
* @brief A class wrapping the single-polygon checks into a polygon-to-edge pair processor
*/
class DB_PUBLIC SinglePolygonCheck
: public PolygonToEdgePairProcessorBase
{
public:
SinglePolygonCheck (db::edge_relation_type rel, db::Coord d, const RegionCheckOptions &options);
virtual void process (const db::Polygon &polygon, std::vector<db::EdgePair> &res) const;
private:
db::edge_relation_type m_relation;
db::Coord m_d;
db::RegionCheckOptions m_options;
};
/**
* @brief A helper class for the region to edge interaction functionality
*/

View File

@ -27,6 +27,7 @@
#include "dbRegionUtils.h"
#include "dbEdgesUtils.h"
#include "dbRegionLocalOperations.h"
#include "dbShapeCollectionUtils.h"
namespace gsi
{
@ -123,47 +124,86 @@ static db::CompoundRegionOperationNode *new_outside (db::CompoundRegionOperation
}
}
static db::CompoundRegionOperationNode *new_hulls (db::CompoundRegionOperationNode *input)
{
return new db::CompoundRegionProcessingOperationNode (new db::HullExtractionProcessor (), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_holes (db::CompoundRegionOperationNode *input)
{
return new db::CompoundRegionProcessingOperationNode (new db::HolesExtractionProcessor (), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_strange_polygons_filter (db::CompoundRegionOperationNode *input)
{
return new db::CompoundRegionProcessingOperationNode (new db::StrangePolygonCheckProcessor (), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_smoothed (db::CompoundRegionOperationNode *input, db::Coord d)
{
return new db::CompoundRegionProcessingOperationNode (new db::SmoothingProcessor (d), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_rounded_corners (db::CompoundRegionOperationNode *input, double rinner, double router, unsigned int n)
{
return new db::CompoundRegionProcessingOperationNode (new db::RoundedCornersProcessor (rinner, router, n), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_case (const std::vector<db::CompoundRegionOperationNode *> &inputs)
{
return new db::CompoundRegionLogicalCaseSelectOperationNode (inputs);
}
static db::CompoundRegionOperationNode *new_corners_as_rectangles_node (db::CompoundRegionOperationNode *input, double angle_start, double angle_end, db::Coord dim = 1)
static db::CompoundRegionOperationNode *new_corners_as_rectangles (db::CompoundRegionOperationNode *input, double angle_start, double angle_end, db::Coord dim = 1)
{
return new db::CompoundRegionProcessingOperationNode (new db::CornersAsRectangles (angle_start, angle_end, dim), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_corners_as_dots_node (db::CompoundRegionOperationNode *input, double angle_start, double angle_end)
static db::CompoundRegionOperationNode *new_corners_as_dots (db::CompoundRegionOperationNode *input, double angle_start, double angle_end)
{
return new db::CompoundRegionToEdgeProcessingOperationNode (new db::CornersAsDots (angle_start, angle_end), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_relative_extents_node (db::CompoundRegionOperationNode *input, double fx1, double fy1, double fx2, double fy2, db::Coord dx, db::Coord dy)
static db::CompoundRegionOperationNode *new_extents (db::CompoundRegionOperationNode *input, db::Coord e)
{
if (input->result_type () == db::CompoundRegionOperationNode::EdgePairs) {
return new db::CompoundRegionEdgePairToPolygonProcessingOperationNode (new db::extents_processor<db::EdgePair> (e, e), input, true /*processor is owned*/);
} else if (input->result_type () == db::CompoundRegionOperationNode::EdgePairs) {
return new db::CompoundRegionEdgeToPolygonProcessingOperationNode (new db::extents_processor<db::Edge> (e, e), input, true /*processor is owned*/);
} else if (input->result_type () == db::CompoundRegionOperationNode::Region) {
return new db::CompoundRegionProcessingOperationNode (new db::extents_processor<db::Polygon> (e, e), input, true /*processor is owned*/);
} else {
input->keep ();
return input;
}
}
static db::CompoundRegionOperationNode *new_relative_extents (db::CompoundRegionOperationNode *input, double fx1, double fy1, double fx2, double fy2, db::Coord dx, db::Coord dy)
{
return new db::CompoundRegionProcessingOperationNode (new db::RelativeExtents (fx1, fy1, fx2, fy2, dx, dy), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_relative_extents_as_edges_node (db::CompoundRegionOperationNode *input, double fx1, double fy1, double fx2, double fy2)
static db::CompoundRegionOperationNode *new_relative_extents_as_edges (db::CompoundRegionOperationNode *input, double fx1, double fy1, double fx2, double fy2)
{
return new db::CompoundRegionToEdgeProcessingOperationNode (new db::RelativeExtentsAsEdges (fx1, fy1, fx2, fy2), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_convex_decomposition_node (db::CompoundRegionOperationNode *input, db::PreferredOrientation mode)
static db::CompoundRegionOperationNode *new_convex_decomposition (db::CompoundRegionOperationNode *input, db::PreferredOrientation mode)
{
return new db::CompoundRegionProcessingOperationNode (new db::ConvexDecomposition (mode), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_trapezoid_decomposition_node (db::CompoundRegionOperationNode *input, db::TrapezoidDecompositionMode mode)
static db::CompoundRegionOperationNode *new_trapezoid_decomposition (db::CompoundRegionOperationNode *input, db::TrapezoidDecompositionMode mode)
{
return new db::CompoundRegionProcessingOperationNode (new db::TrapezoidDecomposition (mode), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_polygon_breaker_node (db::CompoundRegionOperationNode *input, size_t max_vertex_count, double max_area_ratio)
static db::CompoundRegionOperationNode *new_polygon_breaker (db::CompoundRegionOperationNode *input, size_t max_vertex_count, double max_area_ratio)
{
return new db::CompoundRegionProcessingOperationNode (new db::PolygonBreaker (max_vertex_count, max_area_ratio), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_size_node (db::CompoundRegionOperationNode *input, db::Coord dx, db::Coord dy, unsigned int mode)
static db::CompoundRegionOperationNode *new_sized (db::CompoundRegionOperationNode *input, db::Coord dx, db::Coord dy, unsigned int mode)
{
return new db::CompoundRegionProcessingOperationNode (new db::PolygonSizer (dx, dy, mode), input, true /*processor is owned*/);
}
@ -188,37 +228,61 @@ static db::CompoundRegionOperationNode *new_minkowsky_sum_node4 (db::CompoundReg
return new db::CompoundRegionProcessingOperationNode (new db::minkowsky_sum_computation<std::vector<db::Point> > (p), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_edges_node (db::CompoundRegionOperationNode *input)
static db::CompoundRegionOperationNode *new_edges (db::CompoundRegionOperationNode *input)
{
return new db::CompoundRegionToEdgeProcessingOperationNode (new db::PolygonToEdgeProcessor (), input, true /*processor is owned*/);
if (input->result_type () == db::CompoundRegionOperationNode::EdgePairs) {
return new db::CompoundRegionEdgePairToEdgeProcessingOperationNode (new db::EdgePairToEdgesProcessor (), input, true /*processor is owned*/);
} else if (input->result_type () == db::CompoundRegionOperationNode::Region) {
return new db::CompoundRegionToEdgeProcessingOperationNode (new db::PolygonToEdgeProcessor (), input, true /*processor is owned*/);
} else {
input->keep ();
return input;
}
}
static db::CompoundRegionOperationNode *new_edge_length_filter_node (db::CompoundRegionOperationNode *input, db::Edge::distance_type lmin, db::Edge::distance_type lmax, bool inverse)
static db::CompoundRegionOperationNode *new_edge_length_filter (db::CompoundRegionOperationNode *input, bool inverse, db::Edge::distance_type lmin, db::Edge::distance_type lmax)
{
return new db::CompoundRegionEdgeFilterOperationNode (new db::EdgeLengthFilter (lmin, lmax, inverse), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_edge_orientation_filter_node (db::CompoundRegionOperationNode *input, double amin, double amax, bool inverse)
static db::CompoundRegionOperationNode *new_edge_orientation_filter (db::CompoundRegionOperationNode *input, bool inverse, double amin, double amax)
{
return new db::CompoundRegionEdgeFilterOperationNode (new db::EdgeOrientationFilter (amin, amax, inverse), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_edge_pair_to_polygon_node (db::CompoundRegionOperationNode *input, db::Coord e)
static db::CompoundRegionOperationNode *new_polygons (db::CompoundRegionOperationNode *input, db::Coord e)
{
return new db::CompoundRegionEdgePairToPolygonProcessingOperationNode (new db::EdgePairToPolygonProcessor (e), input, true /*processor is owned*/);
if (input->result_type () == db::CompoundRegionOperationNode::EdgePairs) {
return new db::CompoundRegionEdgePairToPolygonProcessingOperationNode (new db::EdgePairToPolygonProcessor (e), input, true /*processor is owned*/);
} else if (input->result_type () == db::CompoundRegionOperationNode::Edges) {
return new db::CompoundRegionEdgeToPolygonProcessingOperationNode (new db::ExtendedEdgeProcessor (e), input, true /*processor is owned*/);
} else {
input->keep ();
return input;
}
}
static db::CompoundRegionOperationNode *new_edge_pair_to_edges_node (db::CompoundRegionOperationNode *input)
static db::CompoundRegionOperationNode *new_extended (db::CompoundRegionOperationNode *input, db::Coord ext_b, db::Coord ext_e, db::Coord ext_o, db::Coord ext_i)
{
return new db::CompoundRegionEdgePairToEdgeProcessingOperationNode (new db::EdgePairToEdgesProcessor (), input, true /*processor is owned*/);
return new db::CompoundRegionEdgeToPolygonProcessingOperationNode (new db::ExtendedEdgeProcessor (ext_b, ext_e, ext_o, ext_i), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_edge_pair_to_first_edges_node (db::CompoundRegionOperationNode *input)
static db::CompoundRegionOperationNode *new_extended_in (db::CompoundRegionOperationNode *input, db::Coord e)
{
return new db::CompoundRegionEdgeToPolygonProcessingOperationNode (new db::ExtendedEdgeProcessor (0, 0, 0, e), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_extended_out (db::CompoundRegionOperationNode *input, db::Coord e)
{
return new db::CompoundRegionEdgeToPolygonProcessingOperationNode (new db::ExtendedEdgeProcessor (0, 0, e, 0), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_edge_pair_to_first_edges (db::CompoundRegionOperationNode *input)
{
return new db::CompoundRegionEdgePairToEdgeProcessingOperationNode (new db::EdgePairToFirstEdgesProcessor (), input, true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_edge_pair_to_second_edges_node (db::CompoundRegionOperationNode *input)
static db::CompoundRegionOperationNode *new_edge_pair_to_second_edges (db::CompoundRegionOperationNode *input)
{
return new db::CompoundRegionEdgePairToEdgeProcessingOperationNode (new db::EdgePairToSecondEdgesProcessor (), input, true /*processor is owned*/);
}
@ -251,42 +315,59 @@ static db::CompoundRegionOperationNode *new_check_node (db::CompoundRegionOperat
);
}
static db::CompoundRegionOperationNode *new_width_check_node (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)
static db::CompoundRegionOperationNode *new_width_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)
{
return new_check_node (db::WidthRelation, false, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, db::NoOppositeFilter, db::NoSideAllowed);
db::RegionCheckOptions options (whole_edges,
metrics,
ignore_angle.is_nil () ? 90 : ignore_angle.to_double (),
min_projection.is_nil () ? db::Region::distance_type (0) : min_projection.to<db::Region::distance_type> (),
max_projection.is_nil () ? std::numeric_limits<db::Region::distance_type>::max () : max_projection.to<db::Region::distance_type> (),
shielded);
return new db::CompoundRegionToEdgePairProcessingOperationNode (new db::SinglePolygonCheck (db::WidthRelation, d, options), new_primary (), true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_space_check_node (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)
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)
{
return new_check_node (db::SpaceRelation, false, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter);
}
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)
{
return new_check_node (db::SpaceRelation, true, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter);
}
static db::CompoundRegionOperationNode *new_notch_check_node (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)
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)
{
return new_check_node (db::SpaceRelation, false, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, db::NoOppositeFilter, db::NoSideAllowed);
db::RegionCheckOptions options (whole_edges,
metrics,
ignore_angle.is_nil () ? 90 : ignore_angle.to_double (),
min_projection.is_nil () ? db::Region::distance_type (0) : min_projection.to<db::Region::distance_type> (),
max_projection.is_nil () ? std::numeric_limits<db::Region::distance_type>::max () : max_projection.to<db::Region::distance_type> (),
shielded);
return new db::CompoundRegionToEdgePairProcessingOperationNode (new db::SinglePolygonCheck (db::SpaceRelation, d, options), new_primary (), true /*processor is owned*/);
}
static db::CompoundRegionOperationNode *new_separation_check_node (db::CompoundRegionOperationNode *input, 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)
static db::CompoundRegionOperationNode *new_separation_check (db::CompoundRegionOperationNode *input, 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)
{
return new_check_node (input, db::SpaceRelation, true, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter);
}
static db::CompoundRegionOperationNode *new_overlap_check_node (db::CompoundRegionOperationNode *input, 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)
static db::CompoundRegionOperationNode *new_overlap_check (db::CompoundRegionOperationNode *input, 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)
{
return new_check_node (input, db::OverlapRelation, true, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter);
}
static db::CompoundRegionOperationNode *new_inside_check_node (db::CompoundRegionOperationNode *input, 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)
static db::CompoundRegionOperationNode *new_inside_check (db::CompoundRegionOperationNode *input, 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)
{
return new_check_node (input, db::InsideRelation, true, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter);
}
static db::CompoundRegionOperationNode *new_perimeter_filter (db::CompoundRegionOperationNode *input, db::coord_traits<db::Coord>::perimeter_type pmin, db::coord_traits<db::Coord>::perimeter_type pmax, bool inverse)
static db::CompoundRegionOperationNode *new_perimeter_filter (db::CompoundRegionOperationNode *input, bool inverse, db::coord_traits<db::Coord>::perimeter_type pmin, db::coord_traits<db::Coord>::perimeter_type pmax)
{
return new db::CompoundRegionFilterOperationNode (new db::RegionPerimeterFilter (pmin, pmax, inverse), input, true);
}
static db::CompoundRegionOperationNode *new_area_filter (db::CompoundRegionOperationNode *input, db::coord_traits<db::Coord>::area_type amin, db::coord_traits<db::Coord>::area_type amax, bool inverse)
static db::CompoundRegionOperationNode *new_area_filter (db::CompoundRegionOperationNode *input, bool inverse, db::coord_traits<db::Coord>::area_type amin, db::coord_traits<db::Coord>::area_type amax)
{
return new db::CompoundRegionFilterOperationNode (new db::RegionAreaFilter (amin, amax, inverse), input, true);
}
@ -301,11 +382,26 @@ static db::CompoundRegionOperationNode *new_rectangle_filter (db::CompoundRegion
return new db::CompoundRegionFilterOperationNode (new db::RectangleFilter (inverse), input, true);
}
static db::CompoundRegionOperationNode *new_bbox_filter (db::CompoundRegionOperationNode *input, db::RegionBBoxFilter::parameter_type parameter, db::coord_traits<db::Coord>::distance_type vmin, db::coord_traits<db::Coord>::distance_type vmax, bool inverse)
static db::CompoundRegionOperationNode *new_bbox_filter (db::CompoundRegionOperationNode *input, db::RegionBBoxFilter::parameter_type parameter, bool inverse, db::coord_traits<db::Coord>::distance_type vmin, db::coord_traits<db::Coord>::distance_type vmax)
{
return new db::CompoundRegionFilterOperationNode (new db::RegionBBoxFilter (vmin, vmax, inverse, parameter), input, true);
}
static db::CompoundRegionOperationNode *new_start_segments (db::CompoundRegionOperationNode *input, db::Edges::length_type length, double fraction)
{
return new db::CompoundRegionEdgeProcessingOperationNode (new db::EdgeSegmentSelector (-1, length, fraction), input, true);
}
static db::CompoundRegionOperationNode *new_end_segments (db::CompoundRegionOperationNode *input, db::Edges::length_type length, double fraction)
{
return new db::CompoundRegionEdgeProcessingOperationNode (new db::EdgeSegmentSelector (1, length, fraction), input, true);
}
static db::CompoundRegionOperationNode *new_centers (db::CompoundRegionOperationNode *input, db::Edges::length_type length, double fraction)
{
return new db::CompoundRegionEdgeProcessingOperationNode (new db::EdgeSegmentSelector (0, length, fraction), input, true);
}
Class<db::CompoundRegionOperationNode> decl_CompoundRegionOperationNode ("db", "CompoundRegionOperationNode",
gsi::constructor ("new_primary", &new_primary,
"@brief Creates a node object representing the primary input"
@ -339,6 +435,26 @@ Class<db::CompoundRegionOperationNode> decl_CompoundRegionOperationNode ("db", "
gsi::constructor ("new_outside", &new_outside, gsi::arg ("a"), gsi::arg ("b"), gsi::arg ("inverse", false),
"@brief Creates a node representing an outside selection operation between the inputs.\n"
) +
gsi::constructor ("new_hulls", &new_hulls, gsi::arg ("input"),
"@brief Creates a node extracting the hulls from polygons.\n"
) +
gsi::constructor ("new_holes", &new_holes, gsi::arg ("input"),
"@brief Creates a node extracting the holes from polygons.\n"
) +
gsi::constructor ("new_strange_polygons_filter", &new_strange_polygons_filter, gsi::arg ("input"),
"@brief Creates a node extracting strange polygons.\n"
"'strange polygons' are ones which cannot be oriented - e.g. '8' shape polygons."
) +
gsi::constructor ("new_smoothed", &new_smoothed, gsi::arg ("input"), gsi::arg ("d"),
"@brief Creates a node smoothing the polygons.\n"
"@param d The tolerance to be applied for the smoothing."
) +
gsi::constructor ("new_rounded_corners", &new_rounded_corners, gsi::arg ("input"), gsi::arg ("rinner"), gsi::arg ("router"), gsi::arg ("n"),
"@brief Creates a node generating rounded corners.\n"
"@param rinner The inner corner radius."
"@param router The outer corner radius."
"@param n The number if points per full circle."
) +
gsi::constructor ("new_case", &new_case, gsi::arg ("inputs"),
"@brief Creates a 'switch ladder' (case statement) compound operation node.\n"
"\n"
@ -347,28 +463,32 @@ Class<db::CompoundRegionOperationNode> decl_CompoundRegionOperationNode ("db", "
"rendered if c2 isn't empty etc. If none of the conditions renders a non-empty set and a default result is present, the default will be "
"returned. Otherwise, the result is empty."
) +
gsi::constructor ("new_corners_as_rectangles", &new_corners_as_rectangles_node, gsi::arg ("input"), gsi::arg ("angle_start"), gsi::arg ("angle_end"), gsi::arg ("dim"),
gsi::constructor ("new_corners_as_rectangles", &new_corners_as_rectangles, gsi::arg ("input"), gsi::arg ("angle_start"), gsi::arg ("angle_end"), gsi::arg ("dim"),
"@brief Creates a node turning corners into rectangles.\n"
) +
gsi::constructor ("new_corners_as_dots", &new_corners_as_dots_node, gsi::arg ("input"), gsi::arg ("angle_start"), gsi::arg ("angle_end"),
gsi::constructor ("new_corners_as_dots", &new_corners_as_dots, gsi::arg ("input"), gsi::arg ("angle_start"), gsi::arg ("angle_end"),
"@brief Creates a node turning corners into dots (single-point edges).\n"
) +
gsi::constructor ("new_relative_extents", &new_relative_extents_node, gsi::arg ("input"), gsi::arg ("fx1"), gsi::arg ("fy1"), gsi::arg ("fx2"), gsi::arg ("fy2"), gsi::arg ("dx"), gsi::arg ("dy"),
"@brief Creates a node returning markers at specified locations of the extend (e.g. at the center).\n"
gsi::constructor ("new_extents", &new_extents, gsi::arg ("input"), gsi::arg ("e", 0),
"@brief Creates a node returning the extents of the objects.\n"
"The 'e' parameter provides a generic enlargement which is applied to the boxes. This is helpful to cover dot-like edges or edge pairs in the input."
) +
gsi::constructor ("new_relative_extents_as_edges", &new_relative_extents_as_edges_node, gsi::arg ("input"), gsi::arg ("fx1"), gsi::arg ("fy1"), gsi::arg ("fx2"), gsi::arg ("fy2"),
"@brief Creates a node returning edges at specified locations of the extend (e.g. at the center).\n"
gsi::constructor ("new_relative_extents", &new_relative_extents, gsi::arg ("input"), gsi::arg ("fx1"), gsi::arg ("fy1"), gsi::arg ("fx2"), gsi::arg ("fy2"), gsi::arg ("dx"), gsi::arg ("dy"),
"@brief Creates a node returning markers at specified locations of the extent (e.g. at the center).\n"
) +
gsi::constructor ("new_convex_decomposition", &new_convex_decomposition_node, gsi::arg ("input"), gsi::arg ("mode"),
gsi::constructor ("new_relative_extents_as_edges", &new_relative_extents_as_edges, gsi::arg ("input"), gsi::arg ("fx1"), gsi::arg ("fy1"), gsi::arg ("fx2"), gsi::arg ("fy2"),
"@brief Creates a node returning edges at specified locations of the extent (e.g. at the center).\n"
) +
gsi::constructor ("new_convex_decomposition", &new_convex_decomposition, gsi::arg ("input"), gsi::arg ("mode"),
"@brief Creates a node providing a composition into convex pieces.\n"
) +
gsi::constructor ("new_trapezoid_decomposition", &new_trapezoid_decomposition_node, gsi::arg ("input"), gsi::arg ("mode"),
gsi::constructor ("new_trapezoid_decomposition", &new_trapezoid_decomposition, gsi::arg ("input"), gsi::arg ("mode"),
"@brief Creates a node providing a composition into trapezoids.\n"
) +
gsi::constructor ("new_polygon_breaker_node", &new_polygon_breaker_node, gsi::arg ("input"), gsi::arg ("max_vertex_count"), gsi::arg ("max_area_ratio"),
gsi::constructor ("new_polygon_breaker", &new_polygon_breaker, gsi::arg ("input"), gsi::arg ("max_vertex_count"), gsi::arg ("max_area_ratio"),
"@brief Creates a node providing a composition into parts with less than the given number of points and a smaller area ratio.\n"
) +
gsi::constructor ("new_size_node", &new_size_node, gsi::arg ("input"), gsi::arg ("dx"), gsi::arg ("dy"), gsi::arg ("mode"),
gsi::constructor ("new_sized", &new_sized, gsi::arg ("input"), gsi::arg ("dx"), gsi::arg ("dy"), gsi::arg ("mode"),
"@brief Creates a node providing sizing.\n"
) +
gsi::constructor ("new_minkowsky_sum", &new_minkowsky_sum_node1, gsi::arg ("input"), gsi::arg ("e"),
@ -383,35 +503,38 @@ Class<db::CompoundRegionOperationNode> decl_CompoundRegionOperationNode ("db", "
gsi::constructor ("new_minkowsky_sum", &new_minkowsky_sum_node4, gsi::arg ("input"), gsi::arg ("p"),
"@brief Creates a node providing a Minkowsky sum with a point sequence forming a contour.\n"
) +
gsi::constructor ("new_width_check", &new_width_check_node, gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max."), gsi::arg ("shielded", true),
gsi::constructor ("new_width_check", &new_width_check, gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max."), gsi::arg ("shielded", true),
"@brief Creates a node providing a width check.\n"
) +
gsi::constructor ("new_space_check", &new_space_check_node, gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max."), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter), gsi::arg ("rect_filter", db::NoSideAllowed),
gsi::constructor ("new_space_check", &new_space_check, gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max."), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter), gsi::arg ("rect_filter", db::NoSideAllowed),
"@brief Creates a node providing a space check.\n"
) +
gsi::constructor ("new_notch_check", &new_notch_check_node, gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max."), gsi::arg ("shielded", true),
gsi::constructor ("new_isolated_check", &new_isolated_check, gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max."), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter), gsi::arg ("rect_filter", db::NoSideAllowed),
"@brief Creates a node providing a isolated polygons (space between different polygons) check.\n"
) +
gsi::constructor ("new_notch_check", &new_notch_check, gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max."), gsi::arg ("shielded", true),
"@brief Creates a node providing a intra-polygon space check.\n"
) +
gsi::constructor ("new_separation_check", &new_separation_check_node, gsi::arg ("input"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max."), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter), gsi::arg ("rect_filter", db::NoSideAllowed),
gsi::constructor ("new_separation_check", &new_separation_check, gsi::arg ("input"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max."), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter), gsi::arg ("rect_filter", db::NoSideAllowed),
"@brief Creates a node providing a separation check.\n"
) +
gsi::constructor ("new_overlap_check", &new_overlap_check_node, gsi::arg ("input"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max."), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter), gsi::arg ("rect_filter", db::NoSideAllowed),
gsi::constructor ("new_overlap_check", &new_overlap_check, gsi::arg ("input"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max."), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter), gsi::arg ("rect_filter", db::NoSideAllowed),
"@brief Creates a node providing an overlap check.\n"
) +
gsi::constructor ("new_inside_check", &new_inside_check_node, gsi::arg ("input"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max."), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter), gsi::arg ("rect_filter", db::NoSideAllowed),
gsi::constructor ("new_inside_check", &new_inside_check, gsi::arg ("input"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max."), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter), gsi::arg ("rect_filter", db::NoSideAllowed),
"@brief Creates a node providing an inside (enclosure) check.\n"
) +
gsi::constructor ("new_perimeter_filter", &new_perimeter_filter, gsi::arg ("input"), gsi::arg ("pmin", 0), gsi::arg ("pmax", std::numeric_limits<db::coord_traits<db::Coord>::perimeter_type>::max (), "max"), gsi::arg ("inverse", false),
gsi::constructor ("new_perimeter_filter", &new_perimeter_filter, gsi::arg ("input"), gsi::arg ("inverse", false), gsi::arg ("pmin", 0), gsi::arg ("pmax", std::numeric_limits<db::coord_traits<db::Coord>::perimeter_type>::max (), "max"),
"@brief Creates a node filtering the input by perimeter.\n"
"This node renders the input if the perimeter is between pmin and pmax (exclusively). If 'inverse' is set to true, the "
"input shape is returned if the perimeter is less than pmin (exclusively) or larger than pmax (inclusively)."
) +
gsi::constructor ("new_area_filter", &new_area_filter, gsi::arg ("input"), gsi::arg ("amin", 0), gsi::arg ("amax", std::numeric_limits<db::coord_traits<db::Coord>::area_type>::max (), "max"), gsi::arg ("inverse", false),
gsi::constructor ("new_area_filter", &new_area_filter, gsi::arg ("input"), gsi::arg ("inverse", false), gsi::arg ("amin", 0), gsi::arg ("amax", std::numeric_limits<db::coord_traits<db::Coord>::area_type>::max (), "max"),
"@brief Creates a node filtering the input by area.\n"
"This node renders the input if the area is between amin and amax (exclusively). If 'inverse' is set to true, the "
"input shape is returned if the area is less than amin (exclusively) or larger than amax (inclusively)."
) +
gsi::constructor ("new_bbox_filter", &new_bbox_filter, gsi::arg ("input"), gsi::arg ("parameter"), gsi::arg ("pmin", 0), gsi::arg ("pmax", std::numeric_limits<db::coord_traits<db::Coord>::area_type>::max (), "max"), gsi::arg ("inverse", false),
gsi::constructor ("new_bbox_filter", &new_bbox_filter, gsi::arg ("input"), gsi::arg ("parameter"), gsi::arg ("inverse", false), gsi::arg ("pmin", 0), gsi::arg ("pmax", std::numeric_limits<db::coord_traits<db::Coord>::area_type>::max (), "max"),
"@brief Creates a node filtering the input by bounding box parameters.\n"
"This node renders the input if the specified bounding box parameter of the input shape is between pmin and pmax (exclusively). If 'inverse' is set to true, the "
"input shape is returned if the parameter is less than pmin (exclusively) or larger than pmax (inclusively)."
@ -422,27 +545,43 @@ Class<db::CompoundRegionOperationNode> decl_CompoundRegionOperationNode ("db", "
gsi::constructor ("new_rectangle_filter", &new_rectangle_filter, gsi::arg ("input"), gsi::arg ("inverse", false),
"@brief Creates a node filtering the input for rectangular shapes (or non-rectangular ones with 'inverse' set to 'true').\n"
) +
gsi::constructor ("new_edges", &new_edges_node, gsi::arg ("input"),
gsi::constructor ("new_edges", &new_edges, gsi::arg ("input"),
"@brief Creates a node converting polygons into it's edges.\n"
) +
gsi::constructor ("new_edge_length_filter", &new_edge_length_filter_node, gsi::arg ("input"), gsi::arg ("lmin", 0), gsi::arg ("lmax", std::numeric_limits<db::Edge::distance_type>::max (), "max"), gsi::arg ("inverse", false),
gsi::constructor ("new_edge_length_filter", &new_edge_length_filter, gsi::arg ("input"), gsi::arg ("inverse", false), gsi::arg ("lmin", 0), gsi::arg ("lmax", std::numeric_limits<db::Edge::distance_type>::max (), "max"),
"@brief Creates a node filtering edges by their length.\n"
) +
gsi::constructor ("new_edge_orientation_filter", &new_edge_orientation_filter_node, gsi::arg ("input"), gsi::arg ("amin"), gsi::arg ("amax"), gsi::arg ("inverse", false),
gsi::constructor ("new_edge_orientation_filter", &new_edge_orientation_filter, gsi::arg ("input"), gsi::arg ("inverse", false), gsi::arg ("amin"), gsi::arg ("amax"),
"@brief Creates a node filtering edges by their orientation.\n"
) +
gsi::constructor ("new_edge_pair_to_polygon", &new_edge_pair_to_polygon_node, gsi::arg ("input"), gsi::arg ("e", 0),
"@brief Creates a node converting edge pairs to polygons.\n"
gsi::constructor ("new_polygons", &new_polygons, gsi::arg ("input"), gsi::arg ("e", 0),
"@brief Creates a node converting the input to polygons.\n"
"@param e The enlargement parameter when converting edges or edge pairs to polygons.\n"
) +
gsi::constructor ("new_edge_pair_to_edges", &new_edge_pair_to_edges_node, gsi::arg ("input"),
"@brief Creates a node converting edge pairs to two edges each.\n"
) +
gsi::constructor ("new_edge_pair_to_first_edges", &new_edge_pair_to_first_edges_node, gsi::arg ("input"),
gsi::constructor ("new_edge_pair_to_first_edges", &new_edge_pair_to_first_edges, gsi::arg ("input"),
"@brief Creates a node delivering the first edge of each edges pair.\n"
) +
gsi::constructor ("new_edge_pair_to_second_edges", &new_edge_pair_to_second_edges_node, gsi::arg ("input"),
gsi::constructor ("new_edge_pair_to_second_edges", &new_edge_pair_to_second_edges, gsi::arg ("input"),
"@brief Creates a node delivering the second edge of each edges pair.\n"
) +
gsi::constructor ("new_start_segments", &new_start_segments, gsi::arg ("input"), gsi::arg ("length"), gsi::arg ("fraction"),
"@brief Creates a node delivering a part at the beginning of each input edge.\n"
) +
gsi::constructor ("new_end_segments", &new_end_segments, gsi::arg ("input"), gsi::arg ("length"), gsi::arg ("fraction"),
"@brief Creates a node delivering a part at the end of each input edge.\n"
) +
gsi::constructor ("new_centers", &new_centers, gsi::arg ("input"), gsi::arg ("length"), gsi::arg ("fraction"),
"@brief Creates a node delivering a part at the center of each input edge.\n"
) +
gsi::constructor ("new_extended", &new_extended, gsi::arg ("input"), gsi::arg ("ext_b"), gsi::arg ("ext_e"), gsi::arg ("ext_o"), gsi::arg ("ext_i"),
"@brief Creates a node delivering a polygonized version of the edges with the four extension parameters.\n"
) +
gsi::constructor ("new_extended_in", &new_extended_in, gsi::arg ("input"), gsi::arg ("e"),
"@brief Creates a node delivering a polygonized, inside-extended version of the edges.\n"
) +
gsi::constructor ("new_extended_out", &new_extended_out, gsi::arg ("input"), gsi::arg ("e"),
"@brief Creates a node delivering a polygonized, inside-extended version of the edges.\n"
) +
method ("description=", &db::CompoundRegionOperationNode::set_description, gsi::arg ("d"),
"@brief Sets the description for this node"
) +

View File

@ -499,7 +499,7 @@ TEST(9_LogicalSelectOperation)
run_test9 (_this, false);
}
TEST(9d_EdgeFilterOperation)
TEST(9d_LogicalSelectOperation)
{
run_test9 (_this, true);
}
@ -575,7 +575,7 @@ TEST(10_LogicalAndNotOperation)
run_test10 (_this, false);
}
TEST(10d_EdgeFilterOperation)
TEST(10d_LogicalAndNotOperation)
{
run_test10 (_this, true);
}
@ -704,3 +704,48 @@ TEST(12d_EdgeBooleanOperations)
{
run_test12 (_this, true);
}
void run_test13 (tl::TestBase *_this, bool deep)
{
db::Layout ly;
{
std::string fn (tl::testsrc ());
fn += "/testdata/drc/compound_13.gds";
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (ly);
}
db::RegionCheckOptions check_options;
check_options.metrics = db::Projection;
db::DeepShapeStore dss;
db::Region r, r2;
prep_layer (ly, 1, r, dss, deep);
prep_layer (ly, 2, r2, dss, deep);
db::CompoundRegionOperationPrimaryNode *primary = new db::CompoundRegionOperationPrimaryNode ();
db::CompoundRegionToEdgeProcessingOperationNode *primary_edges = new db::CompoundRegionToEdgeProcessingOperationNode (new db::PolygonToEdgeProcessor (), primary, true);
db::CompoundRegionEdgeProcessingOperationNode edge_proc (new db::EdgeSegmentSelector (-1, 1000, 0.1), primary_edges, true);
db::Edges res = r.cop_to_edges (edge_proc);
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, make_au ("13", deep));
}
TEST(13_EdgeProcessor)
{
run_test13 (_this, false);
}
TEST(13d_EdgeProcessor)
{
run_test13 (_this, true);
}

BIN
testdata/drc/compound_13.gds vendored Normal file

Binary file not shown.

BIN
testdata/drc/compound_au13.gds vendored Normal file

Binary file not shown.

BIN
testdata/drc/compound_au13d.gds vendored Normal file

Binary file not shown.