mirror of https://github.com/KLayout/klayout.git
WIP: some refactoring to make functions available for DRC compound operations and to simplify binding
This commit is contained in:
parent
cdcac6f5d3
commit
70ccc50b39
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
) +
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue