mirror of https://github.com/KLayout/klayout.git
970 lines
33 KiB
C++
970 lines
33 KiB
C++
|
|
/*
|
|
|
|
KLayout Layout Viewer
|
|
Copyright (C) 2006-2016 Matthias Koefferlein
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef HDR_dbEdgeProcessor
|
|
#define HDR_dbEdgeProcessor
|
|
|
|
#include "dbCommon.h"
|
|
|
|
#include "dbTypes.h"
|
|
#include "dbEdge.h"
|
|
#include "dbPolygon.h"
|
|
|
|
#include <vector>
|
|
#include <set>
|
|
|
|
namespace db
|
|
{
|
|
|
|
struct WorkEdge;
|
|
struct CutPoints;
|
|
class EdgeSink;
|
|
|
|
/**
|
|
* @brief A destination for a (sorted) set of edges
|
|
*
|
|
* This receiver can be used as destination for the edge processor.
|
|
* It will receive edge events in the scanline order, this is bottom to
|
|
* top and left to right. Edges will be non-intersecting.
|
|
*
|
|
* This is the base class for such edge receivers.
|
|
*/
|
|
class DB_PUBLIC EdgeSink
|
|
{
|
|
public:
|
|
/**
|
|
* @brief Constructor
|
|
*/
|
|
EdgeSink () { }
|
|
|
|
/**
|
|
* @brief Destructor
|
|
*/
|
|
virtual ~EdgeSink () { };
|
|
|
|
/**
|
|
* @brief Start event
|
|
*
|
|
* This method is called shortly before the first edge is delivered.
|
|
* Specifically, all edges are already cached before this method is called.
|
|
* Thus, inside an implementation of this method, the original source can be
|
|
* discarded.
|
|
*/
|
|
virtual void start () { }
|
|
|
|
/**
|
|
* @brief End event
|
|
*
|
|
* This method is called after the last edge has been delivered.
|
|
*/
|
|
virtual void flush () { }
|
|
|
|
/**
|
|
* @brief Deliver an edge
|
|
*
|
|
* This method delivers an edge that ends or starts at the current scanline.
|
|
*/
|
|
virtual void put (const db::Edge &) { }
|
|
|
|
/**
|
|
* @brief Deliver an edge that crosses the scanline
|
|
*
|
|
* This method is called to deliver an edge that is not starting or ending at the
|
|
* current scanline.
|
|
* Another delivery of a set of crossing edges may happen through the skip_n
|
|
* method which delivers a set of (unspecified) edges which are guaranteed to form
|
|
* a closed sequence, that is one which is starting and ending at a wrap count of 0.
|
|
*/
|
|
virtual void crossing_edge (const db::Edge &) { }
|
|
|
|
/**
|
|
* @brief Deliver an edge set forming a closed sequence
|
|
*
|
|
* See description of "crossing_egde" for details.
|
|
*/
|
|
virtual void skip_n (size_t /*n*/) { }
|
|
|
|
/**
|
|
* @brief Signal the start of a scanline at the given y coordinate
|
|
*/
|
|
virtual void begin_scanline (db::Coord /*y*/) { }
|
|
|
|
/**
|
|
* @brief Signal the end of a scanline at the given y coordinate
|
|
*/
|
|
virtual void end_scanline (db::Coord /*y*/) { }
|
|
};
|
|
|
|
/**
|
|
* @brief A edge container that can be used as a receiver for edges
|
|
*
|
|
* This class reimplements the EdgeSink interface.
|
|
* This receiver simply collects the edges in a container (a vector of edges)
|
|
* which is either kept internally or supplied from the outside.
|
|
*/
|
|
class DB_PUBLIC EdgeContainer
|
|
: public EdgeSink
|
|
{
|
|
public:
|
|
/**
|
|
* @brief Constructor connecting this receiver to an external edge vector
|
|
*/
|
|
EdgeContainer (std::vector<db::Edge> &edges, bool clear = false)
|
|
: EdgeSink (), mp_edges (&edges), m_clear (clear)
|
|
{ }
|
|
|
|
/**
|
|
* @brief Constructor using an internal edge vector
|
|
*/
|
|
EdgeContainer ()
|
|
: EdgeSink (), mp_edges (&m_edges), m_clear (false)
|
|
{ }
|
|
|
|
/**
|
|
* @brief Get the edges collected so far (const version)
|
|
*/
|
|
const std::vector<db::Edge> &edges () const
|
|
{
|
|
return *mp_edges;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the edges collected so far (non-const version)
|
|
*/
|
|
std::vector<db::Edge> &edges ()
|
|
{
|
|
return *mp_edges;
|
|
}
|
|
|
|
/**
|
|
* @brief Implementation of the EdgeSink interface
|
|
*/
|
|
virtual void start ()
|
|
{
|
|
if (m_clear) {
|
|
mp_edges->clear ();
|
|
// The single-shot scheme is a easy way to overcome problems with multiple start/flush brackets (i.e. on size filter)
|
|
m_clear = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Implementation of the EdgeSink interface
|
|
*/
|
|
virtual void put (const db::Edge &e)
|
|
{
|
|
mp_edges->push_back (e);
|
|
}
|
|
|
|
private:
|
|
std::vector<db::Edge> m_edges;
|
|
std::vector<db::Edge> *mp_edges;
|
|
bool m_clear;
|
|
};
|
|
|
|
/**
|
|
* @brief The edge set operator base class
|
|
*
|
|
* This class is an internal class that specifies how the output is formed from
|
|
* a set of intersecting-free input edges.
|
|
* Basically, this object receives events for the edges along the scan line.
|
|
* At the beginning of the scan line, the "reset" method is called to bring the
|
|
* evaluator into a defined state. Each edge has an integer property that can be
|
|
* used to distinguish edges from different polygons or layers.
|
|
*/
|
|
class DB_PUBLIC EdgeEvaluatorBase
|
|
{
|
|
public:
|
|
typedef size_t property_type;
|
|
|
|
EdgeEvaluatorBase () { }
|
|
virtual ~EdgeEvaluatorBase () { }
|
|
|
|
virtual void reset () { }
|
|
virtual void reserve (size_t /*n*/) { }
|
|
virtual int edge (bool /*north*/, bool /*enter*/, property_type /*p*/) { return 0; }
|
|
virtual bool select_edge (bool /*horizontal*/, property_type /*p*/) { return false; }
|
|
virtual int compare_ns () const { return 0; }
|
|
virtual bool is_reset () const { return false; }
|
|
virtual bool prefer_touch () const { return false; }
|
|
virtual bool selects_edges () const { return false; }
|
|
};
|
|
|
|
/**
|
|
* @brief An intersection detector
|
|
*
|
|
* This edge evaluator will not produce output edges but rather record the
|
|
* property pairs of polygons intersecting. Only intersections (overlaps)
|
|
* are recorded. Touching contacts are not recorded.
|
|
*
|
|
* It will build a set of property pairs, where the lower property value
|
|
* is the first one of the pairs.
|
|
*/
|
|
class DB_PUBLIC InteractionDetector
|
|
: public EdgeEvaluatorBase
|
|
{
|
|
public:
|
|
typedef std::set<std::pair<property_type, property_type> > interactions_type;
|
|
typedef interactions_type::const_iterator iterator;
|
|
|
|
/**
|
|
* @brief Constructor
|
|
*
|
|
* The mode parameter selects the interaction check mode.
|
|
* 0 is "overlapping".
|
|
* -1 will select all polygons inside polygons from the other layer.
|
|
* +1 will select all polygons outside polygons from the other layer.
|
|
*
|
|
* In mode -1 and +1, finish () needs to be called before the interactions
|
|
* can be used. In mode -1 and +1, the interactions delivered will contain
|
|
* interactions of the reference property vs. the property of the respective
|
|
* input polygons (property != reference property). In mode +1 these are
|
|
* pseudo-interactions, because "outside" by definition means non-interacting.
|
|
*
|
|
* Mode -1 (inside) and +1 (outside) requires a single property value for the containing region.
|
|
* This property value must be specified in the container_id parameter.
|
|
* For correct operation, the container_id must be the lowest property ID and
|
|
* the interacting edges must have higher property id's.
|
|
* The reported interactions will be (container_id,polygon_id) even for outside mode.
|
|
*/
|
|
InteractionDetector (int mode = 0, property_type container_id = 0);
|
|
|
|
/**
|
|
* @brief Sets the "touching" flag
|
|
*
|
|
* If this flag is set, the interaction will include "touching" interactions in mode 0, i.e.
|
|
* touching shapes will be counted as interacting.
|
|
*/
|
|
void set_include_touching (bool f)
|
|
{
|
|
m_include_touching = f;
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the "touching" flag
|
|
*/
|
|
bool include_touching () const
|
|
{
|
|
return m_include_touching;
|
|
}
|
|
|
|
/**
|
|
* @brief Finish the collection
|
|
*
|
|
* This method must be called in mode -1 and +1 in order to finish the collection.
|
|
*/
|
|
void finish ();
|
|
|
|
/**
|
|
* @brief Iterator delivering the interactions (begin iterator)
|
|
*
|
|
* The iterator delivers pairs of property values. The lower value will be the first one of the pair.
|
|
*/
|
|
iterator begin () const
|
|
{
|
|
return m_interactions.begin ();
|
|
}
|
|
|
|
/**
|
|
* @brief Iterator delivering the interactions (end iterator)
|
|
*/
|
|
iterator end () const
|
|
{
|
|
return m_interactions.end ();
|
|
}
|
|
|
|
virtual void reset ();
|
|
virtual void reserve (size_t n);
|
|
virtual int edge (bool north, bool enter, property_type p);
|
|
virtual int compare_ns () const;
|
|
virtual bool is_reset () const { return m_inside.empty (); }
|
|
virtual bool prefer_touch () const { return m_mode == 0 && m_include_touching; }
|
|
|
|
private:
|
|
int m_mode;
|
|
bool m_include_touching;
|
|
property_type m_container_id;
|
|
std::vector <int> m_wcv_n, m_wcv_s;
|
|
std::set <property_type> m_inside;
|
|
std::set<std::pair<property_type, property_type> > m_interactions;
|
|
std::set<property_type> m_non_interactions;
|
|
};
|
|
|
|
/**
|
|
* @brief A generic inside operator
|
|
*
|
|
* This incarnation of the evaluator class implements an "inside" function
|
|
* based on a generic operator.
|
|
*/
|
|
template <class F>
|
|
class DB_PUBLIC GenericMerge
|
|
: public EdgeEvaluatorBase
|
|
{
|
|
public:
|
|
/**
|
|
* @brief Constructor
|
|
*/
|
|
GenericMerge (const F &function)
|
|
: m_wc_n (0), m_wc_s (0), m_function (function)
|
|
{ }
|
|
|
|
virtual void reset ()
|
|
{
|
|
m_wc_n = m_wc_s = 0;
|
|
}
|
|
|
|
virtual void reserve (size_t /*n*/)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
virtual int edge (bool north, bool enter, property_type /*p*/)
|
|
{
|
|
int *wc = north ? &m_wc_n : &m_wc_s;
|
|
bool t0 = m_function (*wc);
|
|
if (enter) {
|
|
++*wc;
|
|
} else {
|
|
--*wc;
|
|
}
|
|
bool t1 = m_function (*wc);
|
|
if (t1 && ! t0) {
|
|
return 1;
|
|
} else if (! t1 && t0) {
|
|
return -1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
virtual int compare_ns () const
|
|
{
|
|
if (m_function (m_wc_s) && ! m_function (m_wc_n)) {
|
|
return -1;
|
|
} else if (! m_function (m_wc_s) && m_function (m_wc_n)) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
virtual bool is_reset () const
|
|
{
|
|
return (m_wc_n == 0 && m_wc_s == 0);
|
|
}
|
|
|
|
private:
|
|
int m_wc_n, m_wc_s;
|
|
F m_function;
|
|
};
|
|
|
|
/**
|
|
* @brief A helper class to implement the SimpleMerge operator
|
|
*/
|
|
struct ParametrizedInsideFunc
|
|
{
|
|
ParametrizedInsideFunc (int mode)
|
|
: m_mode (mode)
|
|
{
|
|
// .. nothing yet ..
|
|
}
|
|
|
|
inline bool operator() (int wc) const
|
|
{
|
|
if (m_mode > 0) {
|
|
return wc >= m_mode;
|
|
} else if (m_mode < 0) {
|
|
return wc <= m_mode || -wc <= m_mode;
|
|
} else {
|
|
return (wc < 0 ? ((-wc) % 2) : (wc % 2)) != 0;
|
|
}
|
|
}
|
|
|
|
public:
|
|
int m_mode;
|
|
};
|
|
|
|
/**
|
|
* @brief Simple merge operator
|
|
*
|
|
* This incarnation of the evaluator class implements a simple
|
|
* merge criterion for a set of edges. A result is generated if the wrap count (wc)
|
|
* of the edge set satisfies a condition given by "mode". Specifically:
|
|
* mode == 0: even-odd rule (wc = ... -3, -1, 1, 3, ...)
|
|
* mode == 1: wc >= 1
|
|
* mode == -1: wc >= 1 || wc <= -1
|
|
* mode == n: wc >= n
|
|
* mode == -n: wc >= n || wc <= -n
|
|
*/
|
|
class DB_PUBLIC SimpleMerge
|
|
: public GenericMerge<ParametrizedInsideFunc>
|
|
{
|
|
public:
|
|
/**
|
|
* @brief Constructor
|
|
*/
|
|
SimpleMerge (int mode = -1)
|
|
: GenericMerge<ParametrizedInsideFunc> (ParametrizedInsideFunc (mode))
|
|
{ }
|
|
};
|
|
|
|
/**
|
|
* @brief Boolean operations
|
|
*
|
|
* This incarnation of the evaluator class implements a boolean operation
|
|
* (AND, A NOT B, B NOT A, XOR, OR). The mode can be specified in the constructor.
|
|
* It relies on the properties being set in a certain way: bit 0 codes the layer (0 for A, 1 for B)
|
|
* while the other bits are used to distinguish the polygons. For each polygon, a non-zero
|
|
* wrap count rule is applied before the boolean operation's output is formed.
|
|
*/
|
|
class DB_PUBLIC BooleanOp
|
|
: public EdgeEvaluatorBase
|
|
{
|
|
public:
|
|
enum BoolOp {
|
|
And = 1, ANotB = 2, BNotA = 3, Xor = 4, Or = 5
|
|
};
|
|
|
|
/**
|
|
* @brief Constructor
|
|
*
|
|
* @param mode The boolean operation that this object represents
|
|
*/
|
|
BooleanOp (BoolOp mode);
|
|
|
|
virtual void reset ();
|
|
virtual void reserve (size_t n);
|
|
virtual int edge (bool north, bool enter, property_type p);
|
|
virtual int compare_ns () const;
|
|
virtual bool is_reset () const { return m_zeroes == m_wcv_n.size () + m_wcv_s.size (); }
|
|
|
|
protected:
|
|
template <class InsideFunc> bool result (int wca, int wcb, const InsideFunc &inside_a, const InsideFunc &inside_b) const;
|
|
template <class InsideFunc> int edge_impl (bool north, bool enter, property_type p, const InsideFunc &inside_a, const InsideFunc &inside_b);
|
|
template <class InsideFunc> int compare_ns_impl (const InsideFunc &inside_a, const InsideFunc &inside_b) const;
|
|
|
|
private:
|
|
int m_wc_na, m_wc_nb, m_wc_sa, m_wc_sb;
|
|
std::vector <int> m_wcv_n, m_wcv_s;
|
|
BoolOp m_mode;
|
|
size_t m_zeroes;
|
|
};
|
|
|
|
/**
|
|
* @brief Edge vs. Polygon intersection
|
|
*
|
|
* This operator detects edges inside or outside polygons.
|
|
* The polygon edges must be given with property 0, the other edges
|
|
* with properties 1 and higher.
|
|
*
|
|
* The operator will deliver edges inside polygons or outside polygons.
|
|
* It can be configured to include edges on the border of the polygons
|
|
* as being considered "inside the polygon".
|
|
*/
|
|
class DB_PUBLIC EdgePolygonOp
|
|
: public db::EdgeEvaluatorBase
|
|
{
|
|
public:
|
|
/**
|
|
* @brief Constructor
|
|
*
|
|
* @param outside If true, the operator will deliver edges outside the polygon
|
|
* @param include_touching If true, edges on the polygon's border will be considered "inside" of polygons
|
|
* @param polygon_mode Determines how the polygon edges on property 0 are interpreted (see merge operators)
|
|
*/
|
|
EdgePolygonOp (bool outside = false, bool include_touching = true, int polygon_mode = -1);
|
|
|
|
virtual void reset ();
|
|
virtual bool select_edge (bool horizontal, property_type p);
|
|
virtual int edge (bool north, bool enter, property_type p);
|
|
virtual bool is_reset () const;
|
|
virtual bool prefer_touch () const;
|
|
virtual bool selects_edges () const;
|
|
|
|
private:
|
|
bool m_outside, m_include_touching;
|
|
db::ParametrizedInsideFunc m_function;
|
|
int m_wcp_n, m_wcp_s;
|
|
};
|
|
|
|
/**
|
|
* @brief Boolean operations
|
|
*
|
|
* This class implements a boolean operation similar to BooleanOp, but
|
|
* in addition it allows to specify the merge mode for the two inputs.
|
|
* See "SimpleMergeOp" for the definition of the merge modes.
|
|
* This operator is especially useful to implement boolean operations
|
|
* with sized polygons which required a >0 interpretation.
|
|
*/
|
|
class DB_PUBLIC BooleanOp2
|
|
: public BooleanOp
|
|
{
|
|
public:
|
|
/**
|
|
* @brief Constructor
|
|
*
|
|
* @param mode The boolean operation that this object represents
|
|
*/
|
|
BooleanOp2 (BoolOp mode, int wc_mode_a, int wc_mode_b);
|
|
|
|
virtual int edge (bool north, bool enter, property_type p);
|
|
virtual int compare_ns () const;
|
|
|
|
private:
|
|
int m_wc_mode_a, m_wc_mode_b;
|
|
};
|
|
|
|
/**
|
|
* @brief Merge operation
|
|
*
|
|
* This incarnation of the evaluator class implements a merge operation
|
|
* which allows to distinguish polygons (through edge properties) and
|
|
* allows to specify a overlap value. Default is 0 which means that the
|
|
* merge is equivalent to producing all polygins. A overlap value of 1 means
|
|
* that at least two polygons must overlap to produce a result.
|
|
*/
|
|
class DB_PUBLIC MergeOp
|
|
: public EdgeEvaluatorBase
|
|
{
|
|
public:
|
|
/**
|
|
* @brief Constructor
|
|
*
|
|
* @param min_overlap See class description
|
|
*/
|
|
MergeOp (unsigned int min_overlap = 0);
|
|
|
|
virtual void reset ();
|
|
virtual void reserve (size_t n);
|
|
virtual int edge (bool north, bool enter, property_type p);
|
|
virtual int compare_ns () const;
|
|
virtual bool is_reset () const { return m_zeroes == m_wcv_n.size () + m_wcv_s.size (); }
|
|
|
|
private:
|
|
int m_wc_n, m_wc_s;
|
|
std::vector <int> m_wcv_n, m_wcv_s;
|
|
unsigned int m_min_wc;
|
|
size_t m_zeroes;
|
|
};
|
|
|
|
/**
|
|
* @brief The basic edge processor
|
|
*
|
|
* An edge processor takes a set of edges, processes them by removing intersections and
|
|
* applying a custom operator for computing the output edge sets which then are delivered
|
|
* to an EdgeSink receiver object.
|
|
*/
|
|
class DB_PUBLIC EdgeProcessor
|
|
{
|
|
public:
|
|
typedef size_t property_type;
|
|
|
|
/**
|
|
* @brief Default constructor
|
|
*
|
|
* @param report_progress If true, a tl::Progress object will be created to report any progress (warning: this will impose a performance penalty)
|
|
* @param progress_text The description text of the progress object
|
|
*/
|
|
EdgeProcessor (bool report_progress = false, const std::string &progress_desc = std::string ());
|
|
|
|
/**
|
|
* @brief Destructor
|
|
*/
|
|
~EdgeProcessor ();
|
|
|
|
/**
|
|
* @brief Enable progress reporting
|
|
*
|
|
* @param progress_text The description text of the progress object
|
|
*/
|
|
void enable_progress (const std::string &progress_desc = std::string ());
|
|
|
|
/**
|
|
* @brief Disable progress reporting
|
|
*/
|
|
void disable_progress ();
|
|
|
|
/**
|
|
* @brief Reserve space for at least n edges
|
|
*/
|
|
void reserve (size_t n);
|
|
|
|
/**
|
|
* @brief Insert an edge
|
|
*/
|
|
void insert (const db::Edge &e, property_type p = 0);
|
|
|
|
/**
|
|
* @brief Insert an polygon
|
|
*/
|
|
void insert (const db::Polygon &q, property_type p = 0);
|
|
|
|
/**
|
|
* @brief Insert a sequence of edges
|
|
*
|
|
* This method does not reserve for the number of elements required. This must
|
|
* be done explicitly for performance benefits.
|
|
*/
|
|
template <class Iter>
|
|
void insert_sequence (Iter from, Iter to, property_type p = 0)
|
|
{
|
|
for (Iter i = from; i != to; ++i) {
|
|
insert (*i, p);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Insert a sequence of edges (iterator with at_end semantics)
|
|
*
|
|
* This method does not reserve for the number of elements required. This must
|
|
* be done explicitly for performance benefits.
|
|
*/
|
|
template <class Iter>
|
|
void insert_sequence (Iter i, property_type p = 0)
|
|
{
|
|
for ( ; !i.at_end (); ++i) {
|
|
insert (*i, p);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Clear all edges stored currently in this processor
|
|
*/
|
|
void clear ();
|
|
|
|
/**
|
|
* @brief Process the edges stored currently
|
|
*/
|
|
void process (db::EdgeSink &es, EdgeEvaluatorBase &op);
|
|
|
|
/**
|
|
* @brief Merge the given polygons in a simple "non-zero wrapcount" fashion
|
|
*
|
|
* The wrapcount is computed over all polygons, i.e. overlapping polygons may "cancel" if they
|
|
* have different orientation (since a polygon is oriented by construction that is not easy to achieve).
|
|
* The other merge operation provided for this purpose is "merge" which normalizes each polygon individually before
|
|
* merging them. "simple_merge" is somewhat faster and consumes less memory.
|
|
*
|
|
* The result is presented as a set of edges forming closed contours. Hulls are oriented clockwise while
|
|
* holes are oriented counter-clockwise.
|
|
*
|
|
* This is a convenience method that bundles filling of the edges, processing with
|
|
* a SimpleMerge operator and puts the result into an output vector.
|
|
*
|
|
* @param in The input polygons
|
|
* @param out The output edges
|
|
* @param mode The merge mode (see SimpleMerge constructor)
|
|
*/
|
|
void simple_merge (const std::vector<db::Polygon> &in, std::vector <db::Edge> &out, int mode = -1);
|
|
|
|
/**
|
|
* @brief Merge the given polygons in a simple "non-zero wrapcount" fashion into polygons
|
|
*
|
|
* The wrapcount is computed over all polygons, i.e. overlapping polygons may "cancel" if they
|
|
* have different orientation (since a polygon is oriented by construction that is not easy to achieve).
|
|
* The other merge operation provided for this purpose is "merge" which normalizes each polygon individually before
|
|
* merging them. "simple_merge" is somewhat faster and consumes less memory.
|
|
*
|
|
* This method produces polygons and allows to fine-tune the parameters for that purpose.
|
|
*
|
|
* This is a convenience method that bundles filling of the edges, processing with
|
|
* a SimpleMerge operator and puts the result into an output vector.
|
|
*
|
|
* @param in The input polygons
|
|
* @param out The output polygons
|
|
* @param resolve_holes true, if holes should be resolved into the hull
|
|
* @param min_coherence true, if touching corners should be resolved into less connected contours
|
|
* @param mode The merge mode (see SimpleMerge constructor)
|
|
*/
|
|
void simple_merge (const std::vector<db::Polygon> &in, std::vector <db::Polygon> &out, bool resolve_holes = true, bool min_coherence = true, int mode = -1);
|
|
|
|
/**
|
|
* @brief Merge the given edges in a simple "non-zero wrapcount" fashion
|
|
*
|
|
* The egdes provided must form valid closed contours. Contours oriented differently "cancel" each other.
|
|
* Overlapping contours are merged when the orientation is the same.
|
|
*
|
|
* The result is presented as a set of edges forming closed contours. Hulls are oriented clockwise while
|
|
* holes are oriented counter-clockwise.
|
|
*
|
|
* This is a convenience method that bundles filling of the edges, processing with
|
|
* a SimpleMerge operator and puts the result into an output vector.
|
|
*
|
|
* @param in The input edges
|
|
* @param out The output edges
|
|
* @param mode The merge mode (see SimpleMerge constructor)
|
|
*/
|
|
void simple_merge (const std::vector<db::Edge> &in, std::vector <db::Edge> &out, int mode = -1);
|
|
|
|
/**
|
|
* @brief Merge the given edges in a simple "non-zero wrapcount" fashion into polygons
|
|
*
|
|
* The egdes provided must form valid closed contours. Contours oriented differently "cancel" each other.
|
|
* Overlapping contours are merged when the orientation is the same.
|
|
*
|
|
* This method produces polygons and allows to fine-tune the parameters for that purpose.
|
|
*
|
|
* This is a convenience method that bundles filling of the edges, processing with
|
|
* a SimpleMerge operator and puts the result into an output vector.
|
|
*
|
|
* @param in The input edges
|
|
* @param out The output polygons
|
|
* @param resolve_holes true, if holes should be resolved into the hull
|
|
* @param min_coherence true, if touching corners should be resolved into less connected contours
|
|
* @param mode The merge mode (see SimpleMerge constructor)
|
|
*/
|
|
void simple_merge (const std::vector<db::Edge> &in, std::vector <db::Polygon> &out, bool resolve_holes = true, bool min_coherence = true, int mode = -1);
|
|
|
|
/**
|
|
* @brief Merge the given polygons
|
|
*
|
|
* In contrast to "simple_merge", this merge implementation considers each polygon individually before merging them.
|
|
* Thus self-overlaps are effectively removed before the output is computed and holes are correctly merged with the
|
|
* hull. In addition, this method allows to select areas with a higher wrap count which allows to compute overlaps
|
|
* of polygons on the same layer. Because this method merges the polygons before the overlap is computed, self-overlapping
|
|
* polygons do not contribute to higher wrap count areas.
|
|
*
|
|
* The result is presented as a set of edges forming closed contours. Hulls are oriented clockwise while
|
|
* holes are oriented counter-clockwise.
|
|
*
|
|
* This is a convenience method that bundles filling of the edges, processing with
|
|
* a Merge operator and puts the result into an output vector.
|
|
*
|
|
* @param in The input polygons
|
|
* @param out The output edges
|
|
* @param min_wc The minimum wrap count for output (0: all polygons, 1: at least two overlapping)
|
|
*/
|
|
void merge (const std::vector<db::Polygon> &in, std::vector <db::Edge> &out, unsigned int min_wc = 0);
|
|
|
|
/**
|
|
* @brief Merge the given polygons
|
|
*
|
|
* In contrast to "simple_merge", this merge implementation considers each polygon individually before merging them.
|
|
* Thus self-overlaps are effectively removed before the output is computed and holes are correctly merged with the
|
|
* hull. In addition, this method allows to select areas with a higher wrap count which allows to compute overlaps
|
|
* of polygons on the same layer. Because this method merges the polygons before the overlap is computed, self-overlapping
|
|
* polygons do not contribute to higher wrap count areas.
|
|
*
|
|
* This method produces polygons and allows to fine-tune the parameters for that purpose.
|
|
*
|
|
* This is a convenience method that bundles filling of the edges, processing with
|
|
* a Merge operator and puts the result into an output vector.
|
|
*
|
|
* @param in The input polygons
|
|
* @param out The output polygons
|
|
* @param min_wc The minimum wrap count for output (0: all polygons, 1: at least two overlapping)
|
|
* @param resolve_holes true, if holes should be resolved into the hull
|
|
* @param min_coherence true, if touching corners should be resolved into less connected contours
|
|
*/
|
|
void merge (const std::vector<db::Polygon> &in, std::vector <db::Polygon> &out, unsigned int min_wc = 0, bool resolve_holes = true, bool min_coherence = true);
|
|
|
|
/**
|
|
* @brief Size the given polygons
|
|
*
|
|
* This method sizes a set of polygons. Before the sizing is applied, the polygons are merged. After that, sizing is applied
|
|
* on the individual result polygons of the merge step. The result may contain overlapping contours, but no self-overlaps.
|
|
*
|
|
* dx and dy describe the sizing. A positive value indicates oversize (outwards) while a negative one describes undersize (inwards).
|
|
* The sizing applied can be choosen differently in x and y direction. In this case, the sign must be identical for both
|
|
* dx and dy.
|
|
*
|
|
* The result is presented as a set of edges forming closed contours. Hulls are oriented clockwise while
|
|
* holes are oriented counter-clockwise.
|
|
*
|
|
* This is a convenience method that bundles filling of the edges and processing them
|
|
* and which puts the result into an output vector.
|
|
*
|
|
* @param in The input polygons
|
|
* @param dx The sizing value in x direction
|
|
* @param dy The sizing value in y direction
|
|
* @param out The output edges
|
|
* @param mode The sizing mode (see db::Polygon for a description)
|
|
*/
|
|
void size (const std::vector<db::Polygon> &in, db::Coord dx, db::Coord dy, std::vector <db::Edge> &out, unsigned int mode = 2);
|
|
|
|
/**
|
|
* @brief Size the given polygons into polygons
|
|
*
|
|
* This method sizes a set of polygons. Before the sizing is applied, the polygons are merged. After that, sizing is applied
|
|
* on the individual result polygons of the merge step. The result may contain overlapping polygons, but no self-overlapping ones.
|
|
* Polygon overlap occures if the polygons are close enough, so a positive sizing makes polygons overlap.
|
|
*
|
|
* dx and dy describe the sizing. A positive value indicates oversize (outwards) while a negative one describes undersize (inwards).
|
|
* The sizing applied can be choosen differently in x and y direction. In this case, the sign must be identical for both
|
|
* dx and dy.
|
|
*
|
|
* This method produces polygons and allows to fine-tune the parameters for that purpose.
|
|
*
|
|
* This is a convenience method that bundles filling of the edges, processing with
|
|
* a SimpleMerge operator and puts the result into an output vector.
|
|
*
|
|
* @param in The input polygons
|
|
* @param dx The sizing value in x direction
|
|
* @param dy The sizing value in y direction
|
|
* @param out The output polygons
|
|
* @param mode The sizing mode (see db::Polygon for a description)
|
|
* @param resolve_holes true, if holes should be resolved into the hull
|
|
* @param min_coherence true, if touching corners should be resolved into less connected contours
|
|
*/
|
|
void size (const std::vector<db::Polygon> &in, db::Coord dx, db::Coord dy, std::vector <db::Polygon> &out, unsigned int mode = 2, bool resolve_holes = true, bool min_coherence = true);
|
|
|
|
/**
|
|
* @brief Size the given polygons (isotropic)
|
|
*
|
|
* This method is equivalent to calling the anisotropic version with identical dx and dy.
|
|
*
|
|
* @param in The input polygons
|
|
* @param d The sizing value in x direction
|
|
* @param out The output edges
|
|
* @param mode The sizing mode (see db::Polygon for a description)
|
|
*/
|
|
void size (const std::vector<db::Polygon> &in, db::Coord d, std::vector <db::Edge> &out, unsigned int mode = 2)
|
|
{
|
|
size (in, d, d, out, mode);
|
|
}
|
|
|
|
/**
|
|
* @brief Size the given polygons into polygons (isotropic)
|
|
*
|
|
* This method is equivalent to calling the anisotropic version with identical dx and dy.
|
|
*
|
|
* @param in The input polygons
|
|
* @param d The sizing value in x direction
|
|
* @param out The output polygons
|
|
* @param mode The sizing mode (see db::Polygon for a description)
|
|
* @param resolve_holes true, if holes should be resolved into the hull
|
|
* @param min_coherence true, if touching corners should be resolved into less connected contours
|
|
*/
|
|
void size (const std::vector<db::Polygon> &in, db::Coord d, std::vector <db::Polygon> &out, unsigned int mode = 2, bool resolve_holes = true, bool min_coherence = true)
|
|
{
|
|
size (in, d, d, out, mode, resolve_holes, min_coherence);
|
|
}
|
|
|
|
/**
|
|
* @brief Boolean operation for a set of given polygons, creating edges
|
|
*
|
|
* This method computes the result for the given boolean operation on two sets of polygons.
|
|
* The result is presented as a set of edges forming closed contours. Hulls are oriented clockwise while
|
|
* holes are oriented counter-clockwise.
|
|
*
|
|
* This is a convenience method that bundles filling of the edges, processing with
|
|
* a Boolean operator and puts the result into an output vector.
|
|
*
|
|
* @param a The input polygons (first operand)
|
|
* @param b The input polygons (second operand)
|
|
* @param out The output edges
|
|
* @param mode The boolean mode
|
|
*/
|
|
void boolean (const std::vector<db::Polygon> &a, const std::vector<db::Polygon> &b, std::vector <db::Edge> &out, int mode);
|
|
|
|
/**
|
|
* @brief Boolean operation for a set of given polygons, creating polygons
|
|
*
|
|
* This method computes the result for the given boolean operation on two sets of polygons.
|
|
* This method produces polygons on output and allows to fine-tune the parameters for that purpose.
|
|
*
|
|
* This is a convenience method that bundles filling of the edges, processing with
|
|
* a Boolean operator and puts the result into an output vector.
|
|
*
|
|
* @param a The input polygons (first operand)
|
|
* @param b The input polygons (second operand)
|
|
* @param out The output polygons
|
|
* @param mode The boolean mode
|
|
* @param resolve_holes true, if holes should be resolved into the hull
|
|
* @param min_coherence true, if touching corners should be resolved into less connected contours
|
|
*/
|
|
void boolean (const std::vector<db::Polygon> &a, const std::vector<db::Polygon> &b, std::vector <db::Polygon> &out, int mode, bool resolve_holes = true, bool min_coherence = true);
|
|
|
|
/**
|
|
* @brief Boolean operation for a set of given edges, creating edges
|
|
*
|
|
* This method computes the result for the given boolean operation on two sets of edges.
|
|
* The input edges must form closed contours where holes and hulls must be oriented differently.
|
|
* The input edges are processed with a simple non-zero wrap count rule as a whole.
|
|
*
|
|
* The result is presented as a set of edges forming closed contours. Hulls are oriented clockwise while
|
|
* holes are oriented counter-clockwise.
|
|
*
|
|
* This is a convenience method that bundles filling of the edges, processing with
|
|
* a Boolean operator and puts the result into an output vector.
|
|
*
|
|
* @param a The input edges (first operand)
|
|
* @param b The input edges (second operand)
|
|
* @param out The output edges
|
|
* @param mode The boolean mode
|
|
*/
|
|
void boolean (const std::vector<db::Edge> &a, const std::vector<db::Edge> &b, std::vector <db::Edge> &out, int mode);
|
|
|
|
/**
|
|
* @brief Boolean operation for a set of given edges, creating polygons
|
|
*
|
|
* This method computes the result for the given boolean operation on two sets of edges.
|
|
* The input edges must form closed contours where holes and hulls must be oriented differently.
|
|
* The input edges are processed with a simple non-zero wrap count rule as a whole.
|
|
*
|
|
* This method produces polygons on output and allows to fine-tune the parameters for that purpose.
|
|
*
|
|
* This is a convenience method that bundles filling of the edges, processing with
|
|
* a Boolean operator and puts the result into an output vector.
|
|
*
|
|
* @param a The input polygons (first operand)
|
|
* @param b The input polygons (second operand)
|
|
* @param out The output polygons
|
|
* @param mode The boolean mode
|
|
* @param resolve_holes true, if holes should be resolved into the hull
|
|
* @param min_coherence true, if touching corners should be resolved into less connected contours
|
|
*/
|
|
void boolean (const std::vector<db::Edge> &a, const std::vector<db::Edge> &b, std::vector <db::Polygon> &out, int mode, bool resolve_holes = true, bool min_coherence = true);
|
|
|
|
private:
|
|
std::vector <WorkEdge> *mp_work_edges;
|
|
std::vector <CutPoints> *mp_cpvector;
|
|
bool m_report_progress;
|
|
std::string m_progress_desc;
|
|
|
|
static size_t count_edges (const db::Polygon &q)
|
|
{
|
|
size_t n = q.hull ().size ();
|
|
for (unsigned int h = 0; h < q.holes (); ++h) {
|
|
n += q.hole (h).size ();
|
|
}
|
|
return n;
|
|
}
|
|
|
|
static size_t count_edges (const std::vector<db::Polygon> &v)
|
|
{
|
|
size_t n = 0;
|
|
for (std::vector<db::Polygon>::const_iterator p = v.begin (); p != v.end (); ++p) {
|
|
n += count_edges (*p);
|
|
}
|
|
return n;
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|