mirror of https://github.com/KLayout/klayout.git
Refactoring: generalization of filter/processor for edges, region
This commit is contained in:
parent
0f2d0605a9
commit
124c4eb61c
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include "dbAsIfFlatEdges.h"
|
||||
#include "dbFlatEdges.h"
|
||||
#include "dbFlatEdgePairs.h"
|
||||
#include "dbFlatRegion.h"
|
||||
#include "dbEmptyEdges.h"
|
||||
#include "dbEdges.h"
|
||||
#include "dbEdgesUtils.h"
|
||||
|
|
@ -362,6 +364,50 @@ AsIfFlatEdges::processed (const EdgeProcessorBase &filter) const
|
|||
return edges.release ();
|
||||
}
|
||||
|
||||
EdgePairsDelegate *
|
||||
AsIfFlatEdges::processed_to_edge_pairs (const EdgeToEdgePairProcessorBase &filter) const
|
||||
{
|
||||
std::auto_ptr<FlatEdgePairs> edge_pairs (new FlatEdgePairs ());
|
||||
|
||||
if (filter.result_must_not_be_merged ()) {
|
||||
edge_pairs->set_merged_semantics (false);
|
||||
}
|
||||
|
||||
std::vector<db::EdgePair> res_edge_pairs;
|
||||
|
||||
for (EdgesIterator e (filter.requires_raw_input () ? begin () : begin_merged ()); ! e.at_end (); ++e) {
|
||||
res_edge_pairs.clear ();
|
||||
filter.process (*e, res_edge_pairs);
|
||||
for (std::vector<db::EdgePair>::const_iterator epr = res_edge_pairs.begin (); epr != res_edge_pairs.end (); ++epr) {
|
||||
edge_pairs->insert (*epr);
|
||||
}
|
||||
}
|
||||
|
||||
return edge_pairs.release ();
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
AsIfFlatEdges::processed_to_polygons (const EdgeToPolygonProcessorBase &filter) const
|
||||
{
|
||||
std::auto_ptr<FlatRegion> region (new FlatRegion ());
|
||||
|
||||
if (filter.result_must_not_be_merged ()) {
|
||||
region->set_merged_semantics (false);
|
||||
}
|
||||
|
||||
std::vector<db::Polygon> res_polygons;
|
||||
|
||||
for (EdgesIterator e (filter.requires_raw_input () ? begin () : begin_merged ()); ! e.at_end (); ++e) {
|
||||
res_polygons.clear ();
|
||||
filter.process (*e, res_polygons);
|
||||
for (std::vector<db::Polygon>::const_iterator pr = res_polygons.begin (); pr != res_polygons.end (); ++pr) {
|
||||
region->insert (*pr);
|
||||
}
|
||||
}
|
||||
|
||||
return region.release ();
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatEdges::filtered (const EdgeFilterBase &filter) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -88,6 +88,8 @@ public:
|
|||
}
|
||||
|
||||
virtual EdgesDelegate *processed (const EdgeProcessorBase &filter) const;
|
||||
virtual EdgePairsDelegate *processed_to_edge_pairs (const EdgeToEdgePairProcessorBase &) const;
|
||||
virtual RegionDelegate *processed_to_polygons (const EdgeToPolygonProcessorBase &) const;
|
||||
|
||||
virtual EdgesDelegate *filter_in_place (const EdgeFilterBase &filter)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "dbAsIfFlatRegion.h"
|
||||
#include "dbFlatRegion.h"
|
||||
#include "dbFlatEdgePairs.h"
|
||||
#include "dbFlatEdges.h"
|
||||
#include "dbEmptyRegion.h"
|
||||
#include "dbRegion.h"
|
||||
#include "dbRegionUtils.h"
|
||||
|
|
@ -252,6 +253,10 @@ RegionDelegate *
|
|||
AsIfFlatRegion::processed (const PolygonProcessorBase &filter) const
|
||||
{
|
||||
std::auto_ptr<FlatRegion> new_region (new FlatRegion ());
|
||||
if (filter.result_must_not_be_merged ()) {
|
||||
new_region->set_merged_semantics (false);
|
||||
}
|
||||
|
||||
std::vector<db::Polygon> poly_res;
|
||||
|
||||
for (RegionIterator p (filter.requires_raw_input () ? begin () : begin_merged ()); ! p.at_end (); ++p) {
|
||||
|
|
@ -267,6 +272,52 @@ AsIfFlatRegion::processed (const PolygonProcessorBase &filter) const
|
|||
return new_region.release ();
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
AsIfFlatRegion::processed_to_edges (const PolygonToEdgeProcessorBase &filter) const
|
||||
{
|
||||
std::auto_ptr<FlatEdges> new_edges (new FlatEdges ());
|
||||
if (filter.result_must_not_be_merged ()) {
|
||||
new_edges->set_merged_semantics (false);
|
||||
}
|
||||
|
||||
std::vector<db::Edge> edge_res;
|
||||
|
||||
for (RegionIterator p (filter.requires_raw_input () ? begin () : begin_merged ()); ! p.at_end (); ++p) {
|
||||
|
||||
edge_res.clear ();
|
||||
filter.process (*p, edge_res);
|
||||
for (std::vector<db::Edge>::const_iterator er = edge_res.begin (); er != edge_res.end (); ++er) {
|
||||
new_edges->insert (*er);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return new_edges.release ();
|
||||
}
|
||||
|
||||
EdgePairsDelegate *
|
||||
AsIfFlatRegion::processed_to_edge_pairs (const PolygonToEdgePairProcessorBase &filter) const
|
||||
{
|
||||
std::auto_ptr<FlatEdgePairs> new_edge_pairs (new FlatEdgePairs ());
|
||||
if (filter.result_must_not_be_merged ()) {
|
||||
new_edge_pairs->set_merged_semantics (false);
|
||||
}
|
||||
|
||||
std::vector<db::EdgePair> edge_pair_res;
|
||||
|
||||
for (RegionIterator p (filter.requires_raw_input () ? begin () : begin_merged ()); ! p.at_end (); ++p) {
|
||||
|
||||
edge_pair_res.clear ();
|
||||
filter.process (*p, edge_pair_res);
|
||||
for (std::vector<db::EdgePair>::const_iterator epr = edge_pair_res.begin (); epr != edge_pair_res.end (); ++epr) {
|
||||
new_edge_pairs->insert (*epr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return new_edge_pairs.release ();
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
AsIfFlatRegion::selected_interacting_generic (const Edges &other, bool inverse) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -113,6 +113,8 @@ public:
|
|||
}
|
||||
|
||||
virtual RegionDelegate *processed (const PolygonProcessorBase &filter) const;
|
||||
virtual EdgesDelegate *processed_to_edges (const PolygonToEdgeProcessorBase &filter) const;
|
||||
virtual EdgePairsDelegate *processed_to_edge_pairs (const PolygonToEdgePairProcessorBase &filter) const;
|
||||
|
||||
virtual RegionDelegate *filter_in_place (const PolygonFilterBase &filter)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -483,59 +483,136 @@ EdgesDelegate *DeepEdges::process_in_place (const EdgeProcessorBase &filter)
|
|||
return processed (filter);
|
||||
}
|
||||
|
||||
EdgesDelegate *DeepEdges::processed (const EdgeProcessorBase &filter) const
|
||||
EdgesDelegate *
|
||||
DeepEdges::processed (const EdgeProcessorBase &filter) const
|
||||
{
|
||||
return processed_impl<db::Edge, db::DeepEdges> (filter);
|
||||
}
|
||||
|
||||
EdgePairsDelegate *
|
||||
DeepEdges::processed_to_edge_pairs (const EdgeToEdgePairProcessorBase &filter) const
|
||||
{
|
||||
return processed_impl<db::EdgePair, db::DeepEdgePairs> (filter);
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
DeepEdges::processed_to_polygons (const EdgeToPolygonProcessorBase &filter) const
|
||||
{
|
||||
return processed_impl<db::Polygon, db::DeepRegion> (filter);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
template <class Result> struct delivery;
|
||||
|
||||
template <>
|
||||
struct delivery<db::Polygon>
|
||||
{
|
||||
delivery (db::Layout *layout, db::Shapes *shapes)
|
||||
: mp_layout (layout), mp_shapes (shapes)
|
||||
{ }
|
||||
|
||||
void put (const db::Polygon &result)
|
||||
{
|
||||
tl::MutexLocker locker (&mp_layout->lock ());
|
||||
mp_shapes->insert (db::PolygonRef (result, mp_layout->shape_repository ()));
|
||||
}
|
||||
|
||||
private:
|
||||
db::Layout *mp_layout;
|
||||
db::Shapes *mp_shapes;
|
||||
};
|
||||
|
||||
template <class Result>
|
||||
struct delivery
|
||||
{
|
||||
delivery (db::Layout *, db::Shapes *shapes)
|
||||
: mp_shapes (shapes)
|
||||
{ }
|
||||
|
||||
void put (const Result &result)
|
||||
{
|
||||
mp_shapes->insert (result);
|
||||
}
|
||||
|
||||
private:
|
||||
db::Shapes *mp_shapes;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <class Result, class OutputContainer>
|
||||
OutputContainer *
|
||||
DeepEdges::processed_impl (const edge_processor<Result> &filter) const
|
||||
{
|
||||
if (! filter.requires_raw_input ()) {
|
||||
ensure_merged_edges_valid ();
|
||||
}
|
||||
|
||||
std::auto_ptr<VariantsCollectorBase> vars;
|
||||
|
||||
if (filter.vars ()) {
|
||||
|
||||
vars.reset (new db::VariantsCollectorBase (filter.vars ()));
|
||||
|
||||
vars->collect (m_deep_layer.layout (), m_deep_layer.initial_cell ());
|
||||
|
||||
// NOTE: m_merged_polygons is mutable, so why is the const_cast needed?
|
||||
const_cast<db::DeepLayer &> (m_deep_layer).separate_variants (*vars);
|
||||
if (filter.wants_variants ()) {
|
||||
const_cast<db::DeepLayer &> (m_deep_layer).separate_variants (*vars);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
db::Layout &layout = const_cast<db::Layout &> (m_deep_layer.layout ());
|
||||
std::vector<db::Edge> res_edges;
|
||||
|
||||
std::auto_ptr<db::DeepEdges> res (new db::DeepEdges (m_deep_layer.derived ()));
|
||||
std::vector<Result> heap;
|
||||
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > to_commit;
|
||||
|
||||
std::auto_ptr<OutputContainer> res (new OutputContainer (m_deep_layer.derived ()));
|
||||
if (filter.result_must_not_be_merged ()) {
|
||||
res->set_merged_semantics (false);
|
||||
}
|
||||
|
||||
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
|
||||
|
||||
const db::Shapes &s = c->shapes (filter.requires_raw_input () ? m_deep_layer.layer () : m_merged_edges.layer ());
|
||||
|
||||
if (vars.get ()) {
|
||||
|
||||
const std::map<db::ICplxTrans, size_t> &v = vars->variants (c->cell_index ());
|
||||
tl_assert (v.size () == size_t (1));
|
||||
const db::ICplxTrans &tr = v.begin ()->first;
|
||||
db::ICplxTrans trinv = tr.inverted ();
|
||||
const std::map<db::ICplxTrans, size_t> &vv = vars->variants (c->cell_index ());
|
||||
for (std::map<db::ICplxTrans, size_t>::const_iterator v = vv.begin (); v != vv.end (); ++v) {
|
||||
|
||||
const db::Shapes &s = c->shapes (filter.requires_raw_input () ? m_deep_layer.layer () : m_merged_edges.layer ());
|
||||
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
||||
|
||||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Edges); ! si.at_end (); ++si) {
|
||||
res_edges.clear ();
|
||||
filter.process (si->edge ().transformed (tr), res_edges);
|
||||
for (std::vector<db::Edge>::const_iterator er = res_edges.begin (); er != res_edges.end (); ++er) {
|
||||
st.insert (er->transformed (trinv));
|
||||
db::Shapes *st;
|
||||
if (vv.size () == 1) {
|
||||
st = & c->shapes (res->deep_layer ().layer ());
|
||||
} else {
|
||||
st = & to_commit [c->cell_index ()] [v->first];
|
||||
}
|
||||
|
||||
delivery<Result> delivery (&layout, st);
|
||||
|
||||
const db::ICplxTrans &tr = v->first;
|
||||
db::ICplxTrans trinv = tr.inverted ();
|
||||
|
||||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Edges); ! si.at_end (); ++si) {
|
||||
heap.clear ();
|
||||
filter.process (si->edge ().transformed (tr), heap);
|
||||
for (typename std::vector<Result>::const_iterator i = heap.begin (); i != heap.end (); ++i) {
|
||||
delivery.put (i->transformed (trinv));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
const db::Shapes &s = c->shapes (filter.requires_raw_input () ? m_deep_layer.layer () : m_merged_edges.layer ());
|
||||
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
||||
delivery<Result> delivery (&layout, &st);
|
||||
|
||||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Edges); ! si.at_end (); ++si) {
|
||||
res_edges.clear ();
|
||||
filter.process (si->edge (), res_edges);
|
||||
for (std::vector<db::Edge>::const_iterator er = res_edges.begin (); er != res_edges.end (); ++er) {
|
||||
st.insert (*er);
|
||||
filter.process (si->edge (), heap);
|
||||
for (typename std::vector<Result>::const_iterator i = heap.begin (); i != heap.end (); ++i) {
|
||||
delivery.put (*i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -543,66 +620,80 @@ EdgesDelegate *DeepEdges::processed (const EdgeProcessorBase &filter) const
|
|||
|
||||
}
|
||||
|
||||
if (! to_commit.empty () && vars.get ()) {
|
||||
res->deep_layer ().commit_shapes (*vars, to_commit);
|
||||
}
|
||||
|
||||
if (filter.result_is_merged ()) {
|
||||
res->set_is_merged (true);
|
||||
}
|
||||
|
||||
return res.release ();
|
||||
}
|
||||
|
||||
EdgesDelegate *DeepEdges::filter_in_place (const EdgeFilterBase &filter)
|
||||
EdgesDelegate *
|
||||
DeepEdges::filter_in_place (const EdgeFilterBase &filter)
|
||||
{
|
||||
// TODO: implement to be really in-place
|
||||
return filtered (filter);
|
||||
}
|
||||
|
||||
EdgesDelegate *DeepEdges::filtered (const EdgeFilterBase &filter) const
|
||||
EdgesDelegate *
|
||||
DeepEdges::filtered (const EdgeFilterBase &filter) const
|
||||
{
|
||||
ensure_merged_edges_valid ();
|
||||
if (! filter.requires_raw_input ()) {
|
||||
ensure_merged_edges_valid ();
|
||||
}
|
||||
|
||||
std::auto_ptr<VariantsCollectorBase> vars;
|
||||
|
||||
if (filter.vars ()) {
|
||||
|
||||
vars.reset (new db::VariantsCollectorBase (filter.vars ()));
|
||||
|
||||
vars->collect (m_merged_edges.layout (), m_merged_edges.initial_cell ());
|
||||
vars->collect (m_deep_layer.layout (), m_deep_layer.initial_cell ());
|
||||
|
||||
// NOTE: m_merged_polygons is mutable, so why is the const_cast needed?
|
||||
const_cast<db::DeepLayer &> (m_merged_edges).separate_variants (*vars);
|
||||
if (filter.wants_variants ()) {
|
||||
const_cast<db::DeepLayer &> (m_deep_layer).separate_variants (*vars);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
db::Layout &layout = m_merged_edges.layout ();
|
||||
db::Layout &layout = const_cast<db::Layout &> (m_deep_layer.layout ());
|
||||
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > to_commit;
|
||||
|
||||
std::auto_ptr<db::DeepEdges> res (new db::DeepEdges (m_merged_edges.derived ()));
|
||||
std::auto_ptr<db::DeepEdges> res (new db::DeepEdges (m_deep_layer.derived ()));
|
||||
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
|
||||
|
||||
const db::Shapes &s = c->shapes (filter.requires_raw_input () ? m_deep_layer.layer () : m_merged_edges.layer ());
|
||||
|
||||
if (vars.get ()) {
|
||||
|
||||
const std::map<db::ICplxTrans, size_t> &v = vars->variants (c->cell_index ());
|
||||
tl_assert (v.size () == size_t (1));
|
||||
const db::ICplxTrans &tr = v.begin ()->first;
|
||||
const std::map<db::ICplxTrans, size_t> &vv = vars->variants (c->cell_index ());
|
||||
for (std::map<db::ICplxTrans, size_t>::const_iterator v = vv.begin (); v != vv.end (); ++v) {
|
||||
|
||||
const db::Shapes &s = c->shapes (m_merged_edges.layer ());
|
||||
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
||||
|
||||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Edges); ! si.at_end (); ++si) {
|
||||
db::Edge edge = si->edge ();
|
||||
if (filter.selected (edge.transformed (tr))) {
|
||||
st.insert (edge);
|
||||
db::Shapes *st;
|
||||
if (vv.size () == 1) {
|
||||
st = & c->shapes (res->deep_layer ().layer ());
|
||||
} else {
|
||||
st = & to_commit [c->cell_index ()] [v->first];
|
||||
}
|
||||
|
||||
const db::ICplxTrans &tr = v->first;
|
||||
|
||||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Edges); ! si.at_end (); ++si) {
|
||||
if (filter.selected (si->edge ().transformed (tr))) {
|
||||
st->insert (*si);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
const db::Shapes &s = c->shapes (m_merged_edges.layer ());
|
||||
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
||||
|
||||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::Edges); ! si.at_end (); ++si) {
|
||||
db::Edge edge = si->edge ();
|
||||
if (filter.selected (edge)) {
|
||||
st.insert (edge);
|
||||
if (filter.selected (si->edge ())) {
|
||||
st.insert (*si);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -610,7 +701,13 @@ EdgesDelegate *DeepEdges::filtered (const EdgeFilterBase &filter) const
|
|||
|
||||
}
|
||||
|
||||
res->set_is_merged (true);
|
||||
if (! to_commit.empty () && vars.get ()) {
|
||||
res->deep_layer ().commit_shapes (*vars, to_commit);
|
||||
}
|
||||
|
||||
if (! filter.requires_raw_input ()) {
|
||||
res->set_is_merged (true);
|
||||
}
|
||||
return res.release ();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,6 +112,8 @@ public:
|
|||
virtual EdgesDelegate *filtered (const EdgeFilterBase &) const;
|
||||
virtual EdgesDelegate *process_in_place (const EdgeProcessorBase &);
|
||||
virtual EdgesDelegate *processed (const EdgeProcessorBase &) const;
|
||||
virtual EdgePairsDelegate *processed_to_edge_pairs (const EdgeToEdgePairProcessorBase &filter) const;
|
||||
virtual RegionDelegate *processed_to_polygons (const EdgeToPolygonProcessorBase &filter) const;
|
||||
|
||||
virtual EdgesDelegate *merged_in_place ();
|
||||
virtual EdgesDelegate *merged () const;
|
||||
|
|
@ -174,6 +176,7 @@ private:
|
|||
EdgePairs run_check (db::edge_relation_type rel, const Edges *other, db::Coord d, bool whole_edges, metrics_type metrics, double ignore_angle, distance_type min_projection, distance_type max_projection) const;
|
||||
EdgesDelegate *selected_interacting_generic (const Edges &edges, bool invert) const;
|
||||
EdgesDelegate *selected_interacting_generic (const Region ®ion, bool invert) const;
|
||||
template <class Result, class OutputContainer> OutputContainer *processed_impl (const edge_processor<Result> &filter) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -912,8 +912,68 @@ DeepRegion::process_in_place (const PolygonProcessorBase &filter)
|
|||
return processed (filter);
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
DeepRegion::processed_to_edges (const PolygonToEdgeProcessorBase &filter) const
|
||||
{
|
||||
return processed_impl<db::Edge, db::DeepEdges> (filter);
|
||||
}
|
||||
|
||||
EdgePairsDelegate *
|
||||
DeepRegion::processed_to_edge_pairs (const PolygonToEdgePairProcessorBase &filter) const
|
||||
{
|
||||
return processed_impl<db::EdgePair, db::DeepEdgePairs> (filter);
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
DeepRegion::processed (const PolygonProcessorBase &filter) const
|
||||
{
|
||||
return processed_impl<db::Polygon, db::DeepRegion> (filter);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
template <class Result> struct delivery;
|
||||
|
||||
template <>
|
||||
struct delivery<db::Polygon>
|
||||
{
|
||||
delivery (db::Layout *layout, db::Shapes *shapes)
|
||||
: mp_layout (layout), mp_shapes (shapes)
|
||||
{ }
|
||||
|
||||
void put (const db::Polygon &result)
|
||||
{
|
||||
tl::MutexLocker locker (&mp_layout->lock ());
|
||||
mp_shapes->insert (db::PolygonRef (result, mp_layout->shape_repository ()));
|
||||
}
|
||||
|
||||
private:
|
||||
db::Layout *mp_layout;
|
||||
db::Shapes *mp_shapes;
|
||||
};
|
||||
|
||||
template <class Result>
|
||||
struct delivery
|
||||
{
|
||||
delivery (db::Layout *, db::Shapes *shapes)
|
||||
: mp_shapes (shapes)
|
||||
{ }
|
||||
|
||||
void put (const Result &result)
|
||||
{
|
||||
mp_shapes->insert (result);
|
||||
}
|
||||
|
||||
private:
|
||||
db::Shapes *mp_shapes;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <class Result, class OutputContainer>
|
||||
OutputContainer *
|
||||
DeepRegion::processed_impl (const polygon_processor<Result> &filter) const
|
||||
{
|
||||
if (! filter.requires_raw_input ()) {
|
||||
ensure_merged_polygons_valid ();
|
||||
|
|
@ -934,10 +994,14 @@ DeepRegion::processed (const PolygonProcessorBase &filter) const
|
|||
|
||||
db::Layout &layout = const_cast<db::Layout &> (m_deep_layer.layout ());
|
||||
|
||||
std::vector<db::Polygon> poly_res;
|
||||
std::vector<Result> heap;
|
||||
std::map<db::cell_index_type, std::map<db::ICplxTrans, db::Shapes> > to_commit;
|
||||
|
||||
std::auto_ptr<db::DeepRegion> res (new db::DeepRegion (m_deep_layer.derived ()));
|
||||
std::auto_ptr<OutputContainer> res (new OutputContainer (m_deep_layer.derived ()));
|
||||
if (filter.result_must_not_be_merged ()) {
|
||||
res->set_merged_semantics (false);
|
||||
}
|
||||
|
||||
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
|
||||
|
||||
const db::Shapes &s = c->shapes (filter.requires_raw_input () ? m_deep_layer.layer () : m_merged_polygons.layer ());
|
||||
|
|
@ -954,7 +1018,7 @@ DeepRegion::processed (const PolygonProcessorBase &filter) const
|
|||
st = & to_commit [c->cell_index ()] [v->first];
|
||||
}
|
||||
|
||||
db::PolygonRefToShapesGenerator pr (&layout, st);
|
||||
delivery<Result> delivery (&layout, st);
|
||||
|
||||
const db::ICplxTrans &tr = v->first;
|
||||
db::ICplxTrans trinv = tr.inverted ();
|
||||
|
|
@ -963,10 +1027,10 @@ DeepRegion::processed (const PolygonProcessorBase &filter) const
|
|||
db::Polygon poly;
|
||||
si->polygon (poly);
|
||||
poly.transform (tr);
|
||||
poly_res.clear ();
|
||||
filter.process (poly, poly_res);
|
||||
for (std::vector<db::Polygon>::const_iterator p = poly_res.begin (); p != poly_res.end (); ++p) {
|
||||
pr.put (p->transformed (trinv));
|
||||
heap.clear ();
|
||||
filter.process (poly, heap);
|
||||
for (typename std::vector<Result>::const_iterator i = heap.begin (); i != heap.end (); ++i) {
|
||||
delivery.put (i->transformed (trinv));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -975,15 +1039,15 @@ DeepRegion::processed (const PolygonProcessorBase &filter) const
|
|||
} else {
|
||||
|
||||
db::Shapes &st = c->shapes (res->deep_layer ().layer ());
|
||||
db::PolygonRefToShapesGenerator pr (&layout, &st);
|
||||
delivery<Result> delivery (&layout, &st);
|
||||
|
||||
for (db::Shapes::shape_iterator si = s.begin (db::ShapeIterator::All); ! si.at_end (); ++si) {
|
||||
db::Polygon poly;
|
||||
si->polygon (poly);
|
||||
poly_res.clear ();
|
||||
filter.process (poly, poly_res);
|
||||
for (std::vector<db::Polygon>::const_iterator p = poly_res.begin (); p != poly_res.end (); ++p) {
|
||||
pr.put (*p);
|
||||
heap.clear ();
|
||||
filter.process (poly, heap);
|
||||
for (typename std::vector<Result>::const_iterator i = heap.begin (); i != heap.end (); ++i) {
|
||||
delivery.put (*i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1022,7 +1086,6 @@ DeepRegion::filtered (const PolygonFilterBase &filter) const
|
|||
|
||||
vars->collect (m_deep_layer.layout (), m_deep_layer.initial_cell ());
|
||||
|
||||
// NOTE: m_merged_polygons is mutable, so why is the const_cast needed?
|
||||
if (filter.wants_variants ()) {
|
||||
const_cast<db::DeepLayer &> (m_deep_layer).separate_variants (*vars);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,6 +140,8 @@ public:
|
|||
|
||||
virtual RegionDelegate *process_in_place (const PolygonProcessorBase &filter);
|
||||
virtual RegionDelegate *processed (const PolygonProcessorBase &filter) const;
|
||||
virtual EdgesDelegate *processed_to_edges (const PolygonToEdgeProcessorBase &filter) const;
|
||||
virtual EdgePairsDelegate *processed_to_edge_pairs (const PolygonToEdgePairProcessorBase &filter) const;
|
||||
virtual RegionDelegate *filter_in_place (const PolygonFilterBase &filter);
|
||||
virtual RegionDelegate *filtered (const PolygonFilterBase &filter) const;
|
||||
|
||||
|
|
@ -221,6 +223,8 @@ protected:
|
|||
void set_is_merged (bool f);
|
||||
|
||||
private:
|
||||
friend class DeepEdges;
|
||||
|
||||
DeepRegion &operator= (const DeepRegion &other);
|
||||
|
||||
DeepLayer m_deep_layer;
|
||||
|
|
@ -240,6 +244,8 @@ private:
|
|||
{
|
||||
return m_merged_polygons;
|
||||
}
|
||||
|
||||
template <class Result, class OutputContainer> OutputContainer *processed_impl (const polygon_processor<Result> &filter) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,6 +78,12 @@ public:
|
|||
void enable_progress (const std::string &progress_desc);
|
||||
void disable_progress ();
|
||||
|
||||
// dummy features to harmonize the interface of region, edges and edge pair delegates
|
||||
void set_merged_semantics (bool) { }
|
||||
bool merged_semantics () const { return false; }
|
||||
void set_is_merged (bool) { }
|
||||
bool is_merged () const { return false; }
|
||||
|
||||
virtual std::string to_string (size_t nmax) const = 0;
|
||||
|
||||
virtual EdgePairsIteratorDelegate *begin () const = 0;
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ public:
|
|||
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;
|
||||
|
|
@ -185,6 +186,11 @@ Edges::reserve (size_t n)
|
|||
flat_edges ()->reserve (n);
|
||||
}
|
||||
|
||||
void Edges::processed (Region &output, const EdgeToPolygonProcessorBase &filter) const
|
||||
{
|
||||
output.set_delegate (mp_delegate->processed_to_polygons (filter));
|
||||
}
|
||||
|
||||
void Edges::extended (Region &output, coord_type ext_b, coord_type ext_e, coord_type ext_o, coord_type ext_i, bool join) const
|
||||
{
|
||||
output.set_delegate (mp_delegate->extended (ext_b, ext_e, ext_o, ext_i, join));
|
||||
|
|
|
|||
|
|
@ -623,6 +623,31 @@ public:
|
|||
return Edges (mp_delegate->processed (filter));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes the edges into polygons
|
||||
*
|
||||
* This method will run the processor over all edges and return a region
|
||||
* with the outputs of the processor.
|
||||
*
|
||||
* Merged semantics applies. In merged semantics, the filter will run over
|
||||
* all merged edges.
|
||||
*/
|
||||
void processed (Region &output, const EdgeToPolygonProcessorBase &filter) const;
|
||||
|
||||
/**
|
||||
* @brief Processes the edges into edge pairs
|
||||
*
|
||||
* This method will run the processor over all edges and return an edge pair collection
|
||||
* with the outputs of the processor.
|
||||
*
|
||||
* Merged semantics applies. In merged semantics, the filter will run over
|
||||
* all merged edges.
|
||||
*/
|
||||
EdgePairs processed (const EdgeToEdgePairProcessorBase &filter) const
|
||||
{
|
||||
return EdgePairs (mp_delegate->processed_to_edge_pairs (filter));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Applies a width check and returns EdgePairs which correspond to violation markers
|
||||
*
|
||||
|
|
|
|||
|
|
@ -40,27 +40,118 @@ namespace db {
|
|||
class DB_PUBLIC EdgeFilterBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
EdgeFilterBase () { }
|
||||
|
||||
virtual ~EdgeFilterBase () { }
|
||||
|
||||
/**
|
||||
* @brief Filters the edge
|
||||
* If this method returns true, the polygon is kept. Otherwise it's discarded.
|
||||
*/
|
||||
virtual bool selected (const db::Edge &edge) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns the transformation reducer for building cell variants
|
||||
* This method may return 0. In this case, not cell variants are built.
|
||||
*/
|
||||
virtual const TransformationReducer *vars () const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the filter wants raw (not merged) input
|
||||
*/
|
||||
virtual bool requires_raw_input () const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the filter wants to build variants
|
||||
* If not true, the filter accepts shape propagation as variant resolution.
|
||||
*/
|
||||
virtual bool wants_variants () const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A base class for polygon processors
|
||||
* @brief A template base class for edge processors
|
||||
*
|
||||
* A polygon processor can turn a edge into something else.
|
||||
*/
|
||||
class DB_PUBLIC EdgeProcessorBase
|
||||
template <class Result>
|
||||
class DB_PUBLIC edge_processor
|
||||
{
|
||||
public:
|
||||
EdgeProcessorBase () { }
|
||||
virtual ~EdgeProcessorBase () { }
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
edge_processor () { }
|
||||
|
||||
virtual void process (const db::Edge &polygon, std::vector<db::Edge> &res) const = 0;
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~edge_processor () { }
|
||||
|
||||
/**
|
||||
* @brief Performs the actual processing
|
||||
* This method will take the input edge from "edge" and puts the results into "res".
|
||||
* "res" can be empty - in this case, the edge will be skipped.
|
||||
*/
|
||||
virtual void process (const db::Edge &edge, std::vector<Result> &res) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns the transformation reducer for building cell variants
|
||||
* This method may return 0. In this case, not cell variants are built.
|
||||
*/
|
||||
virtual const TransformationReducer *vars () const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the result of this operation can be regarded "merged" always.
|
||||
*/
|
||||
virtual bool result_is_merged () const = 0;
|
||||
virtual bool requires_raw_input () const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the result of this operation must not be merged.
|
||||
* This feature can be used, if the result represents "degenerated" objects such
|
||||
* as point-like edges. These must not be merged. Otherwise they disappear.
|
||||
*/
|
||||
virtual bool result_must_not_be_merged () const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the processor wants raw (not merged) input
|
||||
*/
|
||||
virtual bool requires_raw_input () const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the processor wants to build variants
|
||||
* If not true, the processor accepts shape propagation as variant resolution.
|
||||
*/
|
||||
virtual bool wants_variants () const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A edge processor base class
|
||||
*/
|
||||
class DB_PUBLIC EdgeProcessorBase
|
||||
: public edge_processor<db::Edge>
|
||||
{
|
||||
// .. nothing yet ..
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An edge-to-polygon processor base class
|
||||
*/
|
||||
class DB_PUBLIC EdgeToPolygonProcessorBase
|
||||
: public edge_processor<db::Polygon>
|
||||
{
|
||||
// .. nothing yet ..
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An edge-to-edge pair processor base class
|
||||
*/
|
||||
class DB_PUBLIC EdgeToEdgePairProcessorBase
|
||||
: public edge_processor<db::EdgePair>
|
||||
{
|
||||
// .. nothing yet ..
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -70,6 +161,7 @@ enum EdgeBoolOp { EdgeOr, EdgeNot, EdgeXor, EdgeAnd };
|
|||
|
||||
class RecursiveShapeIterator;
|
||||
class EdgeFilterBase;
|
||||
class EdgePairsDelegate;
|
||||
class RegionDelegate;
|
||||
|
||||
/**
|
||||
|
|
@ -159,6 +251,8 @@ public:
|
|||
virtual EdgesDelegate *filtered (const EdgeFilterBase &filter) const = 0;
|
||||
virtual EdgesDelegate *process_in_place (const EdgeProcessorBase &filter) = 0;
|
||||
virtual EdgesDelegate *processed (const EdgeProcessorBase &filter) const = 0;
|
||||
virtual EdgePairsDelegate *processed_to_edge_pairs (const EdgeToEdgePairProcessorBase &filter) const = 0;
|
||||
virtual RegionDelegate *processed_to_polygons (const EdgeToPolygonProcessorBase &filter) const = 0;
|
||||
|
||||
virtual EdgesDelegate *merged_in_place () = 0;
|
||||
virtual EdgesDelegate *merged () const = 0;
|
||||
|
|
|
|||
|
|
@ -80,6 +80,22 @@ struct DB_PUBLIC EdgeLengthFilter
|
|||
return &m_vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Requires merged input
|
||||
*/
|
||||
virtual bool requires_raw_input () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wants to build variants
|
||||
*/
|
||||
virtual bool wants_variants () const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
length_type m_lmin, m_lmax;
|
||||
bool m_inverse;
|
||||
|
|
@ -161,6 +177,22 @@ struct DB_PUBLIC EdgeOrientationFilter
|
|||
return &m_vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Requires merged input
|
||||
*/
|
||||
virtual bool requires_raw_input () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wants to build variants
|
||||
*/
|
||||
virtual bool wants_variants () const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
db::DVector m_emin, m_emax;
|
||||
bool m_inverse;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
|
||||
#include "dbEmptyEdges.h"
|
||||
#include "dbEmptyEdgePairs.h"
|
||||
#include "dbEmptyRegion.h"
|
||||
#include "dbEdges.h"
|
||||
|
||||
|
|
@ -59,6 +60,18 @@ EmptyEdges::extended (coord_type, coord_type, coord_type, coord_type, bool) cons
|
|||
return new EmptyRegion ();
|
||||
}
|
||||
|
||||
EdgePairsDelegate *
|
||||
EmptyEdges::processed_to_edge_pairs (const EdgeToEdgePairProcessorBase &) const
|
||||
{
|
||||
return new EmptyEdgePairs ();
|
||||
}
|
||||
|
||||
RegionDelegate *
|
||||
EmptyEdges::processed_to_polygons (const EdgeToPolygonProcessorBase &) const
|
||||
{
|
||||
return new EmptyRegion ();
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
EmptyEdges::add_in_place (const Edges &other)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ public:
|
|||
virtual EdgesDelegate *filtered (const EdgeFilterBase &) const { return new EmptyEdges (); }
|
||||
virtual EdgesDelegate *process_in_place (const EdgeProcessorBase &) { return this; }
|
||||
virtual EdgesDelegate *processed (const EdgeProcessorBase &) const { return new EmptyEdges (); }
|
||||
virtual EdgePairsDelegate *processed_to_edge_pairs (const EdgeToEdgePairProcessorBase &) const;
|
||||
virtual RegionDelegate *processed_to_polygons (const EdgeToPolygonProcessorBase &) const;
|
||||
|
||||
virtual EdgesDelegate *merged_in_place () { return this; }
|
||||
virtual EdgesDelegate *merged () const { return new EmptyEdges (); }
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
|
||||
#include "dbEmptyRegion.h"
|
||||
#include "dbEmptyEdges.h"
|
||||
#include "dbEmptyEdgePairs.h"
|
||||
#include "dbRegion.h"
|
||||
|
||||
namespace db
|
||||
|
|
@ -82,6 +84,18 @@ EmptyRegion::or_with (const Region &other) const
|
|||
}
|
||||
}
|
||||
|
||||
EdgesDelegate *
|
||||
EmptyRegion::processed_to_edges (const PolygonToEdgeProcessorBase &) const
|
||||
{
|
||||
return new EmptyEdges ();
|
||||
}
|
||||
|
||||
EdgePairsDelegate *
|
||||
EmptyRegion::processed_to_edge_pairs (const PolygonToEdgePairProcessorBase &) const
|
||||
{
|
||||
return new EmptyEdgePairs ();
|
||||
}
|
||||
|
||||
bool
|
||||
EmptyRegion::equals (const Region &other) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ public:
|
|||
virtual RegionDelegate *filtered (const PolygonFilterBase &) const { return new EmptyRegion (); }
|
||||
virtual RegionDelegate *process_in_place (const PolygonProcessorBase &) { return this; }
|
||||
virtual RegionDelegate *processed (const PolygonProcessorBase &) const { return new EmptyRegion (); }
|
||||
virtual EdgesDelegate *processed_to_edges (const PolygonToEdgeProcessorBase &) const;
|
||||
virtual EdgePairsDelegate *processed_to_edge_pairs (const PolygonToEdgePairProcessorBase &) const;
|
||||
|
||||
virtual RegionDelegate *merged_in_place () { return this; }
|
||||
virtual RegionDelegate *merged_in_place (bool, unsigned int) { return this; }
|
||||
|
|
|
|||
|
|
@ -230,6 +230,10 @@ RegionDelegate *FlatRegion::process_in_place (const PolygonProcessorBase &filter
|
|||
m_merged_polygons.clear ();
|
||||
m_is_merged = filter.result_is_merged () && merged_semantics ();
|
||||
|
||||
if (filter.result_must_not_be_merged ()) {
|
||||
set_merged_semantics (false);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ public:
|
|||
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; }
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------
|
||||
|
|
@ -90,6 +91,7 @@ public:
|
|||
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;
|
||||
|
|
@ -116,6 +118,7 @@ public:
|
|||
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;
|
||||
|
|
@ -144,6 +147,7 @@ public:
|
|||
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; }
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------
|
||||
|
|
@ -165,6 +169,7 @@ public:
|
|||
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; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -660,6 +660,32 @@ public:
|
|||
return Region (mp_delegate->processed (filter));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes the polygons into edges
|
||||
*
|
||||
* This method applies a processor returning edges for the polygons.
|
||||
*
|
||||
* Merged semantics applies. In merged semantics, the filter will run over
|
||||
* all merged polygons.
|
||||
*/
|
||||
Edges processed (const PolygonToEdgeProcessorBase &filter) const
|
||||
{
|
||||
return Edges (mp_delegate->processed_to_edges (filter));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes the polygons into edge pairs
|
||||
*
|
||||
* This method applies a processor returning edge pairs for the polygons.
|
||||
*
|
||||
* Merged semantics applies. In merged semantics, the filter will run over
|
||||
* all merged polygons.
|
||||
*/
|
||||
EdgePairs processed (const PolygonToEdgePairProcessorBase &filter) const
|
||||
{
|
||||
return EdgePairs (mp_delegate->processed_to_edge_pairs (filter));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Applies a width check and returns EdgePairs which correspond to violation markers
|
||||
*
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ namespace db {
|
|||
|
||||
class RecursiveShapeIterator;
|
||||
class EdgeFilterBase;
|
||||
class EdgesDelegate;
|
||||
class EdgePairsDelegate;
|
||||
|
||||
/**
|
||||
* @brief A base class for polygon filters
|
||||
|
|
@ -76,24 +78,30 @@ public:
|
|||
};
|
||||
|
||||
/**
|
||||
* @brief A base class for polygon processors
|
||||
* @brief A template base class for polygon processors
|
||||
*
|
||||
* A polygon processor can turn a polygon into something else.
|
||||
*/
|
||||
class DB_PUBLIC PolygonProcessorBase
|
||||
template <class Result>
|
||||
class DB_PUBLIC polygon_processor
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
PolygonProcessorBase () { }
|
||||
polygon_processor () { }
|
||||
|
||||
virtual ~PolygonProcessorBase () { }
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
virtual ~polygon_processor () { }
|
||||
|
||||
/**
|
||||
* @brief Performs the actual processing
|
||||
* This method will take the input polygon from "polygon" and puts the results into "res".
|
||||
* "res" can be empty - in this case, the polygon will be skipped.
|
||||
*/
|
||||
virtual void process (const db::Polygon &polygon, std::vector<db::Polygon> &res) const = 0;
|
||||
virtual void process (const db::Polygon &polygon, std::vector<Result> &res) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns the transformation reducer for building cell variants
|
||||
|
|
@ -106,6 +114,13 @@ public:
|
|||
*/
|
||||
virtual bool result_is_merged () const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the result of this operation must not be merged.
|
||||
* This feature can be used, if the result represents "degenerated" objects such
|
||||
* as point-like edges. These must not be merged. Otherwise they disappear.
|
||||
*/
|
||||
virtual bool result_must_not_be_merged () const = 0;
|
||||
|
||||
/**
|
||||
* @brief Returns true, if the processor wants raw (not merged) input
|
||||
*/
|
||||
|
|
@ -118,6 +133,33 @@ public:
|
|||
virtual bool wants_variants () const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A polygon-to-polygon processor base class
|
||||
*/
|
||||
class DB_PUBLIC PolygonProcessorBase
|
||||
: public polygon_processor<db::Polygon>
|
||||
{
|
||||
// .. nothing yet ..
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A polygon-to-edge processor base class
|
||||
*/
|
||||
class DB_PUBLIC PolygonToEdgeProcessorBase
|
||||
: public polygon_processor<db::Edge>
|
||||
{
|
||||
// .. nothing yet ..
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A polygon-to-edge pair processor base class
|
||||
*/
|
||||
class DB_PUBLIC PolygonToEdgePairProcessorBase
|
||||
: public polygon_processor<db::EdgePair>
|
||||
{
|
||||
// .. nothing yet ..
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The region iterator delegate
|
||||
*/
|
||||
|
|
@ -222,6 +264,8 @@ public:
|
|||
virtual RegionDelegate *filtered (const PolygonFilterBase &filter) const = 0;
|
||||
virtual RegionDelegate *process_in_place (const PolygonProcessorBase &filter) = 0;
|
||||
virtual RegionDelegate *processed (const PolygonProcessorBase &filter) const = 0;
|
||||
virtual EdgesDelegate *processed_to_edges (const PolygonToEdgeProcessorBase &filter) const = 0;
|
||||
virtual EdgePairsDelegate *processed_to_edge_pairs (const PolygonToEdgePairProcessorBase &filter) const = 0;
|
||||
|
||||
virtual RegionDelegate *merged_in_place () = 0;
|
||||
virtual RegionDelegate *merged_in_place (bool min_coherence, unsigned int min_wc) = 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue