WIP: first code pieces

This commit is contained in:
Matthias Koefferlein 2022-08-27 21:31:40 +02:00
parent d2ab4fc743
commit 318a462cb4
15 changed files with 790 additions and 107 deletions

View File

@ -95,11 +95,11 @@ AsIfFlatEdges::to_string (size_t nmax) const
}
EdgesDelegate *
AsIfFlatEdges::selected_interacting_generic (const Region &other, bool inverse) const
AsIfFlatEdges::selected_interacting_generic (const Region &other, EdgeInteractionMode mode, bool inverse) const
{
// shortcuts
if (other.empty () || empty ()) {
return new EmptyEdges ();
return ((mode == EdgesOutside) == inverse) ? new EmptyEdges () : clone ();
}
db::box_scanner2<db::Edge, size_t, db::Polygon, size_t> scanner (report_progress (), progress_desc ());
@ -120,17 +120,17 @@ AsIfFlatEdges::selected_interacting_generic (const Region &other, bool inverse)
if (! inverse) {
edge_to_region_interaction_filter<FlatEdges> filter (*output);
edge_to_region_interaction_filter<FlatEdges> filter (output.get (), mode);
scanner.process (filter, 1, db::box_convert<db::Edge> (), db::box_convert<db::Polygon> ());
} else {
std::set<db::Edge> interacting;
edge_to_region_interaction_filter<std::set<db::Edge> > filter (interacting);
std::set<db::Edge> result;
edge_to_region_interaction_filter<std::set<db::Edge> > filter (&result, mode);
scanner.process (filter, 1, db::box_convert<db::Edge> (), db::box_convert<db::Polygon> ());
for (EdgesIterator o (begin_merged ()); ! o.at_end (); ++o) {
if (interacting.find (*o) == interacting.end ()) {
if (result.find (*o) == result.end ()) {
output->insert (*o);
}
}
@ -141,8 +141,13 @@ AsIfFlatEdges::selected_interacting_generic (const Region &other, bool inverse)
}
EdgesDelegate *
AsIfFlatEdges::selected_interacting_generic (const Edges &edges, bool inverse) const
AsIfFlatEdges::selected_interacting_generic (const Edges &edges, EdgeInteractionMode mode, bool inverse) const
{
// shortcuts
if (edges.empty () || empty ()) {
return ((mode == EdgesOutside) == inverse) ? new EmptyEdges () : clone ();
}
db::box_scanner<db::Edge, size_t> scanner (report_progress (), progress_desc ());
AddressableEdgeDelivery e (begin_merged (), has_valid_merged_edges ());
@ -161,17 +166,17 @@ AsIfFlatEdges::selected_interacting_generic (const Edges &edges, bool inverse) c
if (! inverse) {
edge_interaction_filter<FlatEdges> filter (*output);
edge_interaction_filter<FlatEdges> filter (*output, mode);
scanner.process (filter, 1, db::box_convert<db::Edge> ());
} else {
std::set<db::Edge> interacting;
edge_interaction_filter<std::set<db::Edge> > filter (interacting);
std::set<db::Edge> result;
edge_interaction_filter<std::set<db::Edge> > filter (result, mode);
scanner.process (filter, 1, db::box_convert<db::Edge> ());
for (EdgesIterator o (begin_merged ()); ! o.at_end (); ++o) {
if (interacting.find (*o) == interacting.end ()) {
if (result.find (*o) == result.end ()) {
output->insert (*o);
}
}
@ -181,6 +186,95 @@ AsIfFlatEdges::selected_interacting_generic (const Edges &edges, bool inverse) c
return output.release ();
}
std::pair<EdgesDelegate *, EdgesDelegate *>
AsIfFlatEdges::selected_interacting_pair_generic (const Region &region, EdgeInteractionMode mode) const
{
// shortcuts
if (region.empty () || empty ()) {
if (mode != EdgesOutside) {
return std::make_pair (new EmptyEdges (), clone ());
} else {
return std::make_pair (clone (), new EmptyEdges ());
}
}
db::box_scanner2<db::Edge, size_t, db::Polygon, size_t> scanner (report_progress (), progress_desc ());
AddressableEdgeDelivery e (begin_merged (), has_valid_merged_edges ());
for ( ; ! e.at_end (); ++e) {
scanner.insert1 (e.operator-> (), 0);
}
AddressablePolygonDelivery p = region.addressable_polygons ();
for ( ; ! p.at_end (); ++p) {
scanner.insert2 (p.operator-> (), 1);
}
std::unique_ptr<FlatEdges> output (new FlatEdges (true));
std::unique_ptr<FlatEdges> output2 (new FlatEdges (true));
std::set<db::Edge> result;
edge_to_region_interaction_filter<std::set<db::Edge> > filter (&result, mode);
scanner.process (filter, 1, db::box_convert<db::Edge> (), db::box_convert<db::Polygon> ());
for (EdgesIterator o (begin_merged ()); ! o.at_end (); ++o) {
if (result.find (*o) == result.end ()) {
output->insert (*o);
} else {
output2->insert (*o);
}
}
return std::make_pair (output.release (), output2.release ());
}
std::pair<EdgesDelegate *, EdgesDelegate *>
AsIfFlatEdges::selected_interacting_pair_generic (const Edges &other, EdgeInteractionMode mode) const
{
// shortcuts
if (other.empty () || empty ()) {
if (mode != EdgesOutside) {
return std::make_pair (new EmptyEdges (), clone ());
} else {
return std::make_pair (clone (), new EmptyEdges ());
}
}
db::box_scanner<db::Edge, size_t> scanner (report_progress (), progress_desc ());
AddressableEdgeDelivery e (begin_merged (), has_valid_merged_edges ());
for ( ; ! e.at_end (); ++e) {
scanner.insert (e.operator-> (), 0);
}
AddressableEdgeDelivery ee = other.addressable_edges ();
for ( ; ! ee.at_end (); ++ee) {
scanner.insert (ee.operator-> (), 1);
}
std::unique_ptr<FlatEdges> output (new FlatEdges (true));
std::unique_ptr<FlatEdges> output2 (new FlatEdges (true));
std::set<db::Edge> results;
edge_interaction_filter<std::set<db::Edge> > filter (results, mode);
scanner.process (filter, 1, db::box_convert<db::Edge> ());
for (EdgesIterator o (begin_merged ()); ! o.at_end (); ++o) {
if (results.find (*o) == results.end ()) {
output->insert (*o);
} else {
output2->insert (*o);
}
}
return std::make_pair (output.release (), output2.release ());
}
EdgesDelegate *
AsIfFlatEdges::pull_generic (const Edges &edges) const
{
@ -199,7 +293,7 @@ AsIfFlatEdges::pull_generic (const Edges &edges) const
}
std::unique_ptr<FlatEdges> output (new FlatEdges (true));
edge_interaction_filter<FlatEdges> filter (*output);
edge_interaction_filter<FlatEdges> filter (*output, EdgesInteract);
scanner.process (filter, 1, db::box_convert<db::Edge> ());
return output.release ();
@ -229,7 +323,7 @@ AsIfFlatEdges::pull_generic (const Region &other) const
std::unique_ptr<FlatRegion> output (new FlatRegion (true));
edge_to_region_interaction_filter<FlatRegion> filter (*output);
edge_to_region_interaction_filter<FlatRegion> filter (output.get (), EdgesInteract);
scanner.process (filter, 1, db::box_convert<db::Edge> (), db::box_convert<db::Polygon> ());
return output.release ();
@ -250,27 +344,112 @@ AsIfFlatEdges::pull_interacting (const Region &other) const
EdgesDelegate *
AsIfFlatEdges::selected_interacting (const Edges &other) const
{
return selected_interacting_generic (other, false);
return selected_interacting_generic (other, EdgesInteract, false);
}
EdgesDelegate *
AsIfFlatEdges::selected_not_interacting (const Edges &other) const
{
return selected_interacting_generic (other, true);
return selected_interacting_generic (other, EdgesInteract, true);
}
EdgesDelegate *
AsIfFlatEdges::selected_interacting (const Region &other) const
{
return selected_interacting_generic (other, false);
return selected_interacting_generic (other, EdgesInteract, false);
}
EdgesDelegate *
AsIfFlatEdges::selected_not_interacting (const Region &other) const
{
return selected_interacting_generic (other, true);
return selected_interacting_generic (other, EdgesInteract, true);
}
std::pair<EdgesDelegate *, EdgesDelegate *>
AsIfFlatEdges::selected_interacting_pair (const Region &other) const
{
return selected_interacting_pair_generic (other, EdgesInteract);
}
std::pair<EdgesDelegate *, EdgesDelegate *>
AsIfFlatEdges::selected_interacting_pair (const Edges &other) const
{
return selected_interacting_pair_generic (other, EdgesInteract);
}
EdgesDelegate *
AsIfFlatEdges::selected_outside (const Region &other) const
{
return selected_interacting_generic (other, EdgesOutside, false);
}
EdgesDelegate *
AsIfFlatEdges::selected_not_outside (const Region &other) const
{
return selected_interacting_generic (other, EdgesOutside, true);
}
std::pair<EdgesDelegate *, EdgesDelegate *>
AsIfFlatEdges::selected_outside_pair (const Region &other) const
{
return selected_interacting_pair_generic (other, EdgesOutside);
}
EdgesDelegate *
AsIfFlatEdges::selected_inside (const Region &other) const
{
return selected_interacting_generic (other, EdgesInside, false);
}
EdgesDelegate *
AsIfFlatEdges::selected_not_inside (const Region &other) const
{
return selected_interacting_generic (other, EdgesInside, true);
}
std::pair<EdgesDelegate *, EdgesDelegate *>
AsIfFlatEdges::selected_inside_pair (const Region &other) const
{
return selected_interacting_pair_generic (other, EdgesInside);
}
EdgesDelegate *
AsIfFlatEdges::selected_outside (const Edges &other) const
{
return selected_interacting_generic (other, EdgesOutside, false);
}
EdgesDelegate *
AsIfFlatEdges::selected_not_outside (const Edges &other) const
{
return selected_interacting_generic (other, EdgesOutside, true);
}
std::pair<EdgesDelegate *, EdgesDelegate *>
AsIfFlatEdges::selected_outside_pair (const Edges &other) const
{
return selected_interacting_pair_generic (other, EdgesOutside);
}
EdgesDelegate *
AsIfFlatEdges::selected_inside (const Edges &other) const
{
return selected_interacting_generic (other, EdgesInside, false);
}
EdgesDelegate *
AsIfFlatEdges::selected_not_inside (const Edges &other) const
{
return selected_interacting_generic (other, EdgesInside, true);
}
std::pair<EdgesDelegate *, EdgesDelegate *>
AsIfFlatEdges::selected_inside_pair (const Edges &other) const
{
return selected_interacting_pair_generic (other, EdgesInside);
}
namespace
{
@ -584,18 +763,50 @@ AsIfFlatEdges::boolean (const Edges *other, EdgeBoolOp op) const
return output.release ();
}
EdgesDelegate *
AsIfFlatEdges::edge_region_op (const Region &other, bool outside, bool include_borders) const
std::pair<EdgesDelegate *, EdgesDelegate *>
AsIfFlatEdges::boolean_andnot (const Edges *other) const
{
std::unique_ptr<FlatEdges> output (new FlatEdges (true));
std::unique_ptr<FlatEdges> output2 (new FlatEdges (true));
EdgeBooleanClusterCollectorToShapes cluster_collector (&output->raw_edges (), EdgeAndNot, &output2->raw_edges ());
db::box_scanner<db::Edge, size_t> scanner (report_progress (), progress_desc ());
scanner.reserve (count () + (other ? other->count () : 0));
AddressableEdgeDelivery e (begin (), has_valid_edges ());
for ( ; ! e.at_end (); ++e) {
if (! e->is_degenerate ()) {
scanner.insert (e.operator-> (), 0);
}
}
AddressableEdgeDelivery ee;
if (other) {
ee = other->addressable_edges ();
for ( ; ! ee.at_end (); ++ee) {
if (! ee->is_degenerate ()) {
scanner.insert (ee.operator-> (), 1);
}
}
}
scanner.process (cluster_collector, 1, db::box_convert<db::Edge> ());
return std::make_pair (output.release (), output2.release ());
}
std::pair<EdgesDelegate *, EdgesDelegate *>
AsIfFlatEdges::edge_region_op (const Region &other, db::EdgePolygonOp::mode_t mode, bool include_borders) const
{
// shortcuts
if (other.empty ()) {
if (! outside) {
return new EmptyEdges ();
if (other.empty () || empty ()) {
if (mode != db::EdgePolygonOp::Outside) {
return std::make_pair (new EmptyEdges (), clone ());
} else {
return clone ();
return std::make_pair (clone (), new EmptyEdges ());
}
} else if (empty ()) {
return new EmptyEdges ();
}
db::EdgeProcessor ep (report_progress (), progress_desc ());
@ -610,12 +821,18 @@ AsIfFlatEdges::edge_region_op (const Region &other, bool outside, bool include_b
ep.insert (*e, 1);
}
std::unique_ptr<FlatEdges> output_second;
std::unique_ptr<db::EdgeShapeGenerator> cc_second;
if (mode == db::EdgePolygonOp::Both) {
cc_second.reset (new db::EdgeShapeGenerator (output_second->raw_edges (), true /*clear*/, 2 /*second tag*/));
}
std::unique_ptr<FlatEdges> output (new FlatEdges (false));
db::EdgeShapeGenerator cc (output->raw_edges (), true /*clear*/);
db::EdgePolygonOp op (outside, include_borders);
db::EdgeShapeGenerator cc (output->raw_edges (), true /*clear*/, 1 /*tag*/, cc_second.get ());
db::EdgePolygonOp op (mode, include_borders);
ep.process (cc, op);
return output.release ();
return std::make_pair (output.release (), output_second.release ());
}
EdgesDelegate *

View File

@ -28,6 +28,8 @@
#include "dbBoxScanner.h"
#include "dbEdgesDelegate.h"
#include "dbEdgeBoolean.h"
#include "dbEdgeProcessor.h"
#include "dbEdgesUtils.h"
#include "dbBoxScanner.h"
#include "dbPolygonTools.h"
@ -115,19 +117,29 @@ public:
return boolean (&other, EdgeAnd);
}
virtual EdgesDelegate *and_with (const Region &other) const
{
return edge_region_op (other, false /*inside*/, true /*include borders*/);
}
virtual EdgesDelegate *not_with (const Edges &other) const
{
return boolean (&other, EdgeNot);
}
virtual std::pair<EdgesDelegate *, EdgesDelegate *> andnot_with (const Edges &other) const
{
return boolean_andnot (&other);
}
virtual EdgesDelegate *and_with (const Region &other) const
{
return edge_region_op (other, db::EdgePolygonOp::Inside, true /*include borders*/).first;
}
virtual EdgesDelegate *not_with (const Region &other) const
{
return edge_region_op (other, true /*outside*/, true /*include borders*/);
return edge_region_op (other, db::EdgePolygonOp::Outside, true /*include borders*/).first;
}
virtual std::pair<EdgesDelegate *, EdgesDelegate *> andnot_with (const Region &other) const
{
return edge_region_op (other, db::EdgePolygonOp::Both, true /*include borders*/);
}
virtual EdgesDelegate *xor_with (const Edges &other) const
@ -154,12 +166,17 @@ public:
virtual EdgesDelegate *inside_part (const Region &other) const
{
return edge_region_op (other, false /*inside*/, false /*don't include borders*/);
return edge_region_op (other, db::EdgePolygonOp::Inside, false /*don't include borders*/).first;
}
virtual EdgesDelegate *outside_part (const Region &other) const
{
return edge_region_op (other, true /*outside*/, false /*don't include borders*/);
return edge_region_op (other, db::EdgePolygonOp::Outside, false /*don't include borders*/).first;
}
virtual std::pair<EdgesDelegate *, EdgesDelegate *> inside_outside_part_pair (const Region &other) const
{
return edge_region_op (other, db::EdgePolygonOp::Both, false /*don't include borders*/);
}
virtual RegionDelegate *extended (coord_type ext_b, coord_type ext_e, coord_type ext_o, coord_type ext_i, bool join) const;
@ -170,6 +187,21 @@ public:
virtual EdgesDelegate *selected_not_interacting (const Edges &) const;
virtual EdgesDelegate *selected_interacting (const Region &) const;
virtual EdgesDelegate *selected_not_interacting (const Region &) const;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair (const Region &other) const;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair (const Edges &other) const;
virtual EdgesDelegate *selected_outside (const Edges &other) const;
virtual EdgesDelegate *selected_not_outside (const Edges &other) const;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_outside_pair (const Edges &other) const;
virtual EdgesDelegate *selected_inside (const Edges &other) const;
virtual EdgesDelegate *selected_not_inside (const Edges &other) const;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_inside_pair (const Edges &other) const;
virtual EdgesDelegate *selected_outside (const Region &other) const;
virtual EdgesDelegate *selected_not_outside (const Region &other) const;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_outside_pair (const Region &other) const;
virtual EdgesDelegate *selected_inside (const Region &other) const;
virtual EdgesDelegate *selected_not_inside (const Region &other) const;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_inside_pair (const Region &other) const;
virtual EdgesDelegate *in (const Edges &, bool) const;
@ -184,8 +216,10 @@ protected:
EdgePairsDelegate *run_check (db::edge_relation_type rel, const Edges *other, db::Coord d, const EdgesCheckOptions &options) const;
virtual EdgesDelegate *pull_generic (const Edges &edges) const;
virtual RegionDelegate *pull_generic (const Region &region) const;
virtual EdgesDelegate *selected_interacting_generic (const Edges &edges, bool inverse) const;
virtual EdgesDelegate *selected_interacting_generic (const Region &region, bool inverse) const;
virtual EdgesDelegate *selected_interacting_generic (const Edges &edges, EdgeInteractionMode mode, bool inverse) const;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair_generic (const Edges &edges, EdgeInteractionMode mode) const;
virtual EdgesDelegate *selected_interacting_generic (const Region &region, EdgeInteractionMode mode, bool inverse) const;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair_generic (const Region &region, EdgeInteractionMode mode) const;
AsIfFlatEdges &operator= (const AsIfFlatEdges &other);
AsIfFlatEdges (const AsIfFlatEdges &other);
@ -195,7 +229,8 @@ private:
virtual db::Box compute_bbox () const;
EdgesDelegate *boolean (const Edges *other, EdgeBoolOp op) const;
EdgesDelegate *edge_region_op (const Region &other, bool outside, bool include_borders) const;
std::pair<EdgesDelegate *, EdgesDelegate *> boolean_andnot (const Edges *other) const;
std::pair<EdgesDelegate *, EdgesDelegate *> edge_region_op(const Region &other, db::EdgePolygonOp::mode_t mode, bool include_borders) const;
};
}

View File

@ -930,6 +930,20 @@ EdgesDelegate *DeepEdges::not_with (const Region &other) const
}
}
std::pair<EdgesDelegate *, EdgesDelegate *>
DeepEdges::andnot_with (const Edges &) const
{
// @@@
return std::pair<EdgesDelegate *, EdgesDelegate *>();
}
std::pair<EdgesDelegate *, EdgesDelegate *>
DeepEdges::andnot_with (const Region &) const
{
// @@@
return std::pair<EdgesDelegate *, EdgesDelegate *>();
}
EdgesDelegate *DeepEdges::xor_with (const Edges &other) const
{
const DeepEdges *other_deep = dynamic_cast <const DeepEdges *> (other.delegate ());
@ -1057,6 +1071,12 @@ EdgesDelegate *DeepEdges::outside_part (const Region &other) const
}
}
std::pair<EdgesDelegate *, EdgesDelegate *> DeepEdges::inside_outside_part_pair (const Region &) const
{
// @@@
return std::pair<EdgesDelegate *, EdgesDelegate *>();
}
RegionDelegate *DeepEdges::extended (coord_type ext_b, coord_type ext_e, coord_type ext_o, coord_type ext_i, bool join) const
{
const db::DeepLayer &edges = merged_deep_layer ();
@ -1157,8 +1177,8 @@ class Edge2EdgeInteractingLocalOperation
: public local_operation<db::Edge, db::Edge, db::Edge>
{
public:
Edge2EdgeInteractingLocalOperation (bool inverse)
: m_inverse (inverse)
Edge2EdgeInteractingLocalOperation (EdgeInteractionMode mode, bool inverse)
: m_mode (mode), m_inverse (inverse)
{
// .. nothing yet ..
}
@ -1195,7 +1215,7 @@ public:
if (m_inverse) {
std::unordered_set<db::Edge> interacting;
edge_interaction_filter<std::unordered_set<db::Edge> > filter (interacting);
edge_interaction_filter<std::unordered_set<db::Edge> > filter (interacting, m_mode);
scanner.process (filter, 1, db::box_convert<db::Edge> ());
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
@ -1207,7 +1227,7 @@ public:
} else {
edge_interaction_filter<std::unordered_set<db::Edge> > filter (result);
edge_interaction_filter<std::unordered_set<db::Edge> > filter (result, m_mode);
scanner.process (filter, 1, db::box_convert<db::Edge> ());
}
@ -1229,6 +1249,7 @@ public:
}
private:
EdgeInteractionMode m_mode;
bool m_inverse;
};
@ -1270,7 +1291,7 @@ public:
scanner.insert (o.operator-> (), 0);
}
edge_interaction_filter<std::unordered_set<db::Edge> > filter (result);
edge_interaction_filter<std::unordered_set<db::Edge> > filter (result, EdgesInteract);
scanner.process (filter, 1, db::box_convert<db::Edge> ());
}
@ -1290,8 +1311,8 @@ class Edge2PolygonInteractingLocalOperation
: public local_operation<db::Edge, db::PolygonRef, db::Edge>
{
public:
Edge2PolygonInteractingLocalOperation (bool inverse)
: m_inverse (inverse)
Edge2PolygonInteractingLocalOperation (EdgeInteractionMode mode, bool inverse)
: m_mode (mode), m_inverse (inverse)
{
// .. nothing yet ..
}
@ -1330,7 +1351,7 @@ public:
if (m_inverse) {
std::unordered_set<db::Edge> interacting;
edge_to_region_interaction_filter<std::unordered_set<db::Edge> > filter (interacting);
edge_to_region_interaction_filter<std::unordered_set<db::Edge> > filter (&interacting, m_mode);
scanner.process (filter, 1, db::box_convert<db::Edge> (), db::box_convert<db::Polygon> ());
for (shape_interactions<db::Edge, db::PolygonRef>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
@ -1342,7 +1363,7 @@ public:
} else {
edge_to_region_interaction_filter<std::unordered_set<db::Edge> > filter (result);
edge_to_region_interaction_filter<std::unordered_set<db::Edge> > filter (&result, m_mode);
scanner.process (filter, 1, db::box_convert<db::Edge> (), db::box_convert<db::Polygon> ());
}
@ -1363,6 +1384,7 @@ public:
}
private:
EdgeInteractionMode m_mode;
bool m_inverse;
};
@ -1427,7 +1449,7 @@ public:
}
ResultInserter inserter (layout, result);
edge_to_region_interaction_filter<ResultInserter> filter (inserter);
edge_to_region_interaction_filter<ResultInserter> filter (&inserter, EdgesInteract);
scanner.process (filter, 1, db::box_convert<db::Edge> (), db::box_convert<db::Polygon> ());
}
@ -1445,7 +1467,7 @@ public:
}
EdgesDelegate *
DeepEdges::selected_interacting_generic (const Region &other, bool inverse) const
DeepEdges::selected_interacting_generic (const Region &other, EdgeInteractionMode mode, bool inverse) const
{
std::unique_ptr<db::DeepRegion> dr_holder;
const db::DeepRegion *other_deep = dynamic_cast<const db::DeepRegion *> (other.delegate ());
@ -1459,7 +1481,7 @@ DeepEdges::selected_interacting_generic (const Region &other, bool inverse) cons
DeepLayer dl_out (edges.derived ());
db::Edge2PolygonInteractingLocalOperation op (inverse);
db::Edge2PolygonInteractingLocalOperation op (mode, inverse);
db::local_processor<db::Edge, db::PolygonRef, db::Edge> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ());
proc.set_base_verbosity (base_verbosity ());
@ -1471,7 +1493,7 @@ DeepEdges::selected_interacting_generic (const Region &other, bool inverse) cons
}
EdgesDelegate *
DeepEdges::selected_interacting_generic (const Edges &other, bool inverse) const
DeepEdges::selected_interacting_generic (const Edges &other, EdgeInteractionMode mode, bool inverse) const
{
std::unique_ptr<db::DeepEdges> dr_holder;
const db::DeepEdges *other_deep = dynamic_cast<const db::DeepEdges *> (other.delegate ());
@ -1485,7 +1507,7 @@ DeepEdges::selected_interacting_generic (const Edges &other, bool inverse) const
DeepLayer dl_out (edges.derived ());
db::Edge2EdgeInteractingLocalOperation op (inverse);
db::Edge2EdgeInteractingLocalOperation op (mode, inverse);
db::local_processor<db::Edge, db::Edge, db::Edge> proc (const_cast<db::Layout *> (&edges.layout ()), const_cast<db::Cell *> (&edges.initial_cell ()), &other_deep->deep_layer ().layout (), &other_deep->deep_layer ().initial_cell ());
proc.set_base_verbosity (base_verbosity ());
@ -1496,6 +1518,20 @@ DeepEdges::selected_interacting_generic (const Edges &other, bool inverse) const
return new db::DeepEdges (dl_out);
}
std::pair<EdgesDelegate *, EdgesDelegate *>
DeepEdges::selected_interacting_pair_generic (const Edges &edges, EdgeInteractionMode mode) const
{
// @@@
return std::pair<EdgesDelegate *, EdgesDelegate *>();
}
std::pair<EdgesDelegate *, EdgesDelegate *>
DeepEdges::selected_interacting_pair_generic (const Region &region, EdgeInteractionMode mode) const
{
// @@@
return std::pair<EdgesDelegate *, EdgesDelegate *>();
}
RegionDelegate *DeepEdges::pull_generic (const Region &other) const
{
std::unique_ptr<db::DeepRegion> dr_holder;

View File

@ -133,10 +133,12 @@ public:
virtual EdgesDelegate *merged () const;
virtual EdgesDelegate *and_with (const Edges &other) const;
virtual EdgesDelegate *and_with (const Region &other) const;
virtual EdgesDelegate *not_with (const Edges &other) const;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> andnot_with (const Edges &) const;
virtual EdgesDelegate *and_with (const Region &other) const;
virtual EdgesDelegate *not_with (const Region &other) const;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> andnot_with (const Region &) const;
virtual EdgesDelegate *xor_with (const Edges &other) const;
@ -149,6 +151,7 @@ public:
virtual EdgesDelegate *inside_part (const Region &other) const;
virtual EdgesDelegate *outside_part (const Region &other) const;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> inside_outside_part_pair (const Region &) const;
virtual RegionDelegate *extended (coord_type ext_b, coord_type ext_e, coord_type ext_o, coord_type ext_i, bool join) const;
@ -183,8 +186,10 @@ private:
EdgePairsDelegate *run_check (db::edge_relation_type rel, const Edges *other, db::Coord d, const db::EdgesCheckOptions &options) const;
virtual EdgesDelegate *pull_generic (const Edges &edges) const;
virtual RegionDelegate *pull_generic (const Region &region) const;
virtual EdgesDelegate *selected_interacting_generic (const Edges &edges, bool invert) const;
virtual EdgesDelegate *selected_interacting_generic (const Region &region, bool invert) const;
virtual EdgesDelegate *selected_interacting_generic (const Edges &edges, EdgeInteractionMode mode, bool inverse) const;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair_generic (const Edges &edges, EdgeInteractionMode mode) const;
virtual EdgesDelegate *selected_interacting_generic (const Region &region, EdgeInteractionMode mode, bool inverse) const;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair_generic (const Region &region, EdgeInteractionMode mode) const;
DeepEdges *apply_filter (const EdgeFilterBase &filter) const;
template <class Result, class OutputContainer> OutputContainer *processed_impl (const edge_processor<Result> &filter) const;

View File

@ -36,7 +36,7 @@ namespace db
/**
* @brief A common definition for the boolean operations available on edges
*/
enum EdgeBoolOp { EdgeOr, EdgeNot, EdgeXor, EdgeAnd, EdgeIntersections };
enum EdgeBoolOp { EdgeOr, EdgeNot, EdgeXor, EdgeAnd, EdgeIntersections, EdgeAndNot /*not always supported*/ };
struct OrJoinOp
{
@ -87,7 +87,13 @@ struct EdgeBooleanCluster
typedef db::Edge::coord_type coord_type;
EdgeBooleanCluster (OutputContainer *output, EdgeBoolOp op)
: mp_output (output), m_op (op)
: mp_output (output), mp_output2 (0), m_op (op)
{
// .. nothing yet ..
}
EdgeBooleanCluster (OutputContainer *output, OutputContainer *output2, EdgeBoolOp op)
: mp_output (output), mp_output2 (output2), m_op (op)
{
// .. nothing yet ..
}
@ -99,11 +105,13 @@ struct EdgeBooleanCluster
// shortcut for single edge
if (begin () + 1 == end ()) {
if (begin ()->second == 0) {
if (m_op != EdgeAnd) {
if (m_op == EdgeAndNot) {
mp_output2->insert (*(begin ()->first));
} else if (m_op != EdgeAnd) {
mp_output->insert (*(begin ()->first));
}
} else {
if (m_op != EdgeAnd && m_op != EdgeNot) {
if (m_op != EdgeAnd && m_op != EdgeNot && m_op != EdgeAndNot) {
mp_output->insert (*(begin ()->first));
}
}
@ -174,19 +182,34 @@ struct EdgeBooleanCluster
if (b.begin () == b.end ()) {
// optimize for empty b
if (m_op != EdgeAnd) {
OutputContainer *oc = 0;
if (m_op == EdgeAndNot) {
oc = mp_output;
} else if (m_op != EdgeAnd) {
oc = mp_output;
}
if (oc) {
for (tl::interval_map<db::Coord, int>::const_iterator ib = b.begin (); ib != b.end (); ++ib) {
if (ib->second > 0) {
mp_output->insert (db::Edge (p1 + db::Vector (d * (ib->first.first * n)), p1 + db::Vector (d * (ib->first.second * n))));
oc->insert (db::Edge (p1 + db::Vector (d * (ib->first.first * n)), p1 + db::Vector (d * (ib->first.second * n))));
} else if (ib->second < 0) {
mp_output->insert (db::Edge (p1 + db::Vector (d * (ib->first.second * n)), p1 + db::Vector (d * (ib->first.first * n))));
oc->insert (db::Edge (p1 + db::Vector (d * (ib->first.second * n)), p1 + db::Vector (d * (ib->first.first * n))));
}
}
}
} else {
if (m_op == EdgeAnd) {
tl::interval_map<db::Coord, int> q2;
if (m_op == EdgeAnd || m_op == EdgeAndNot) {
if (m_op == EdgeAndNot) {
q2 = q;
for (tl::interval_map<db::Coord, int>::const_iterator ib = b.begin (); ib != b.end (); ++ib) {
q2.add (ib->first.first, ib->first.second, ib->second, not_jop);
}
}
for (tl::interval_map<db::Coord, int>::const_iterator ib = b.begin (); ib != b.end (); ++ib) {
q.add (ib->first.first, ib->first.second, ib->second, and_jop);
}
@ -208,12 +231,20 @@ struct EdgeBooleanCluster
}
}
for (tl::interval_map<db::Coord, int>::const_iterator iq = q2.begin (); iq != q2.end (); ++iq) {
if (iq->second > 0) {
mp_output2->insert (db::Edge (p1 + db::Vector (d * (iq->first.first * n)), p1 + db::Vector (d * (iq->first.second * n))));
} else if (iq->second < 0) {
mp_output2->insert (db::Edge (p1 + db::Vector (d * (iq->first.second * n)), p1 + db::Vector (d * (iq->first.first * n))));
}
}
}
}
private:
OutputContainer *mp_output;
OutputContainer *mp_output, *mp_output2;
db::EdgeBoolOp m_op;
};
@ -221,8 +252,8 @@ template <class OutputContainer>
struct EdgeBooleanClusterCollector
: public db::cluster_collector<db::Edge, size_t, EdgeBooleanCluster<OutputContainer> >
{
EdgeBooleanClusterCollector (OutputContainer *output, EdgeBoolOp op)
: db::cluster_collector<db::Edge, size_t, EdgeBooleanCluster<OutputContainer> > (EdgeBooleanCluster<OutputContainer> (output, op == EdgeIntersections ? EdgeAnd : op), op != EdgeAnd && op != EdgeIntersections /*report single*/),
EdgeBooleanClusterCollector (OutputContainer *output, EdgeBoolOp op, OutputContainer *output2 = 0)
: db::cluster_collector<db::Edge, size_t, EdgeBooleanCluster<OutputContainer> > (EdgeBooleanCluster<OutputContainer> (output, output2, op == EdgeIntersections ? EdgeAnd : op), op != EdgeAnd && op != EdgeIntersections /*report single*/),
mp_output (output), mp_intersections (op == EdgeIntersections ? output : 0)
{
// .. nothing yet ..
@ -377,6 +408,12 @@ public:
typedef Iterator const_iterator;
ShapesToOutputContainerAdaptor ()
: mp_shapes (0)
{
// .. nothing yet ..
}
ShapesToOutputContainerAdaptor (db::Shapes &shapes)
: mp_shapes (&shapes)
{
@ -413,8 +450,14 @@ struct DB_PUBLIC EdgeBooleanClusterCollectorToShapes
{
}
EdgeBooleanClusterCollectorToShapes (db::Shapes *output, EdgeBoolOp op, db::Shapes *output2)
: EdgeBooleanClusterCollector<ShapesToOutputContainerAdaptor> (&m_adaptor, op, &m_adaptor2), m_adaptor (*output), m_adaptor2 (*output2)
{
}
private:
ShapesToOutputContainerAdaptor m_adaptor;
ShapesToOutputContainerAdaptor m_adaptor2;
};
}

View File

@ -560,8 +560,8 @@ private:
// -------------------------------------------------------------------------------
// EdgePolygonOp implementation
EdgePolygonOp::EdgePolygonOp (bool outside, bool include_touching, int polygon_mode)
: m_outside (outside), m_include_touching (include_touching),
EdgePolygonOp::EdgePolygonOp (EdgePolygonOp::mode_t mode, bool include_touching, int polygon_mode)
: m_mode (mode), m_include_touching (include_touching),
m_function (polygon_mode),
m_wcp_n (0), m_wcp_s (0)
{
@ -572,27 +572,30 @@ void EdgePolygonOp::reset ()
m_wcp_n = m_wcp_s = 0;
}
bool EdgePolygonOp::select_edge (bool horizontal, property_type p)
int EdgePolygonOp::select_edge (bool horizontal, property_type p)
{
if (p == 0) {
return 0;
}
return false;
bool inside;
} else if (horizontal) {
bool res;
if (horizontal) {
if (m_include_touching) {
res = (m_function (m_wcp_n) || m_function (m_wcp_s));
inside = (m_function (m_wcp_n) || m_function (m_wcp_s));
} else {
res = (m_function (m_wcp_n) && m_function (m_wcp_s));
inside = (m_function (m_wcp_n) && m_function (m_wcp_s));
}
return m_outside ? !res : res;
} else {
inside = m_function (m_wcp_n);
}
return m_outside ? !m_function (m_wcp_n) : m_function (m_wcp_n);
if (m_mode == Inside) {
return inside ? 1 : 0;
} else if (m_mode == Outside) {
return inside ? 0 : 1;
} else {
return inside ? 1 : 2;
}
}
@ -1705,10 +1708,11 @@ public:
void select_edge (const WorkEdge &e)
{
if (mp_op->select_edge (e.dy () == 0, e.prop)) {
mp_es->put (e);
int tag = mp_op->select_edge (e.dy () == 0, e.prop);
if (tag > 0) {
mp_es->put (e, (unsigned int) tag);
#ifdef DEBUG_EDGE_PROCESSOR
printf ("put(%s)\n", e.to_string().c_str());
printf ("put(%s, %d)\n", e.to_string().c_str(), tag);
#endif
}
}

View File

@ -87,6 +87,15 @@ public:
*/
virtual void put (const db::Edge &) { }
/**
* @brief Deliver a tagged edge
*
* This method delivers an edge that ends or starts at the current scanline.
* This version includes a tag which is generated when using "select_edge".
* A tag is a value > 0 returned by "select_edge".
*/
virtual void put (const db::Edge &, int /*tag*/) { }
/**
* @brief Deliver an edge that crosses the scanline
*
@ -130,15 +139,15 @@ 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)
EdgeContainer (std::vector<db::Edge> &edges, bool clear = false, int tag = 0, EdgeContainer *chained = 0)
: EdgeSink (), mp_edges (&edges), m_clear (clear), m_tag (tag), mp_chained (chained)
{ }
/**
* @brief Constructor using an internal edge vector
*/
EdgeContainer ()
: EdgeSink (), mp_edges (&m_edges), m_clear (false)
EdgeContainer (int tag = 0, EdgeContainer *chained = 0)
: EdgeSink (), mp_edges (&m_edges), m_clear (false), m_tag (tag), mp_chained (chained)
{ }
/**
@ -167,6 +176,9 @@ public:
// The single-shot scheme is a easy way to overcome problems with multiple start/flush brackets (i.e. on size filter)
m_clear = false;
}
if (mp_chained) {
mp_chained->start ();
}
}
/**
@ -175,12 +187,30 @@ public:
virtual void put (const db::Edge &e)
{
mp_edges->push_back (e);
if (mp_chained) {
mp_chained->put (e);
}
}
/**
* @brief Implementation of the EdgeSink interface
*/
virtual void put (const db::Edge &e, int tag)
{
if (m_tag == 0 || tag == m_tag) {
mp_edges->push_back (e);
}
if (mp_chained) {
mp_chained->put (e, tag);
}
}
private:
std::vector<db::Edge> m_edges;
std::vector<db::Edge> *mp_edges;
bool m_clear;
int m_tag;
EdgeContainer *mp_chained;
};
/**
@ -204,7 +234,7 @@ public:
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 select_edge (bool /*horizontal*/, property_type /*p*/) { return 0; }
virtual int compare_ns () const { return 0; }
virtual bool is_reset () const { return false; }
virtual bool prefer_touch () const { return false; }
@ -491,6 +521,15 @@ class DB_PUBLIC EdgePolygonOp
: public db::EdgeEvaluatorBase
{
public:
/**
* @brief The operation mode
*/
enum mode_t {
Inside = 0, // Selects inside edges
Outside = 1, // Selects outside edges
Both = 2 // Selects both (inside -> tag #1, outside -> tag #2)
};
/**
* @brief Constructor
*
@ -498,17 +537,18 @@ public:
* @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);
EdgePolygonOp (mode_t mode = Inside, bool include_touching = true, int polygon_mode = -1);
virtual void reset ();
virtual bool select_edge (bool horizontal, property_type p);
virtual int 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;
mode_t m_mode;
bool m_include_touching;
db::ParametrizedInsideFunc m_function;
int m_wcp_n, m_wcp_s;
};

View File

@ -1037,6 +1037,242 @@ public:
return Edges (mp_delegate->selected_not_interacting (other));
}
/**
* @brief Selects all edges of this edge collection which are completely outside polygons from the region
*
* Merged semantics applies.
*/
Edges &select_outside (const Region &other)
{
set_delegate (mp_delegate->selected_outside (other));
return *this;
}
/**
* @brief Selects all edges of this edge collection which are not completely outside polygons from the region
*
* Merged semantics applies.
*/
Edges &select_not_outside (const Region &other)
{
set_delegate (mp_delegate->selected_not_outside (other));
return *this;
}
/**
* @brief Returns all edges of this edge collection which are completely outside polygons from the region
*
* This method is an out-of-place version of select_outside.
*
* Merged semantics applies.
*/
Edges selected_outside (const Region &other) const
{
return Edges (mp_delegate->selected_outside (other));
}
/**
* @brief Returns all edges of this edge collection which are not completely outside polygons from the region
*
* This method is an out-of-place version of select_not_outside.
*
* Merged semantics applies.
*/
Edges selected_not_outside (const Region &other) const
{
return Edges (mp_delegate->selected_not_outside (other));
}
/**
* @brief Returns all edges of this which are completely outside polygons from the region and the opposite ones at the same time
*
* This method is equivalent to calling selected_outside and selected_not_outside, but faster.
*
* Merged semantics applies.
*/
std::pair<Edges, Edges> selected_outside_differential (const Region &other) const
{
std::pair<db::EdgesDelegate *, db::EdgesDelegate *> p = mp_delegate->selected_outside_pair (other);
return std::pair<Edges, Edges> (Edges (p.first), Edges (p.second));
}
/**
* @brief Selects all edges of this edge collection which are completely inside polygons from the region
*
* Merged semantics applies.
*/
Edges &select_inside (const Region &other)
{
set_delegate (mp_delegate->selected_inside (other));
return *this;
}
/**
* @brief Selects all edges of this edge collection which are not completely inside polygons from the region
*
* Merged semantics applies.
*/
Edges &select_not_inside (const Region &other)
{
set_delegate (mp_delegate->selected_not_inside (other));
return *this;
}
/**
* @brief Returns all edges of this which are completely inside polygons from the region
*
* This method is an out-of-place version of select_inside.
*
* Merged semantics applies.
*/
Edges selected_inside (const Region &other) const
{
return Edges (mp_delegate->selected_inside (other));
}
/**
* @brief Returns all edges of this which are not completely inside polygons from the region
*
* This method is an out-of-place version of select_not_inside.
*
* Merged semantics applies.
*/
Edges selected_not_inside (const Region &other) const
{
return Edges (mp_delegate->selected_not_inside (other));
}
/**
* @brief Returns all edges of this which are completely inside polygons from the region and the opposite ones at the same time
*
* This method is equivalent to calling selected_inside and selected_not_inside, but faster.
*
* Merged semantics applies.
*/
std::pair<Edges, Edges> selected_inside_differential (const Region &other) const
{
std::pair<db::EdgesDelegate *, db::EdgesDelegate *> p = mp_delegate->selected_inside_pair (other);
return std::pair<Edges, Edges> (Edges (p.first), Edges (p.second));
}
/**
* @brief Selects all edges of this edge collection which are completely outside edges from the other edge collection
*
* Merged semantics applies.
*/
Edges &select_outside (const Edges &other)
{
set_delegate (mp_delegate->selected_outside (other));
return *this;
}
/**
* @brief Selects all edges of this edge collection which are not completely outside edges from the other edge collection
*
* Merged semantics applies.
*/
Edges &select_not_outside (const Edges &other)
{
set_delegate (mp_delegate->selected_not_outside (other));
return *this;
}
/**
* @brief Returns all edges of this edge collection which are completely outside edges from the other edge collection
*
* This method is an out-of-place version of select_outside.
*
* Merged semantics applies.
*/
Edges selected_outside (const Edges &other) const
{
return Edges (mp_delegate->selected_outside (other));
}
/**
* @brief Returns all edges of this edge collection which are not completely outside edges from the other edge collection
*
* This method is an out-of-place version of select_not_outside.
*
* Merged semantics applies.
*/
Edges selected_not_outside (const Edges &other) const
{
return Edges (mp_delegate->selected_not_outside (other));
}
/**
* @brief Returns all edges of this which are completely outside edges from the other edge collection and the opposite ones at the same time
*
* This method is equivalent to calling selected_outside and selected_not_outside, but faster.
*
* Merged semantics applies.
*/
std::pair<Edges, Edges> selected_outside_differential (const Edges &other) const
{
std::pair<db::EdgesDelegate *, db::EdgesDelegate *> p = mp_delegate->selected_outside_pair (other);
return std::pair<Edges, Edges> (Edges (p.first), Edges (p.second));
}
/**
* @brief Selects all edges of this edge collection which are completely inside edges from the other edge collection
*
* Merged semantics applies.
*/
Edges &select_inside (const Edges &other)
{
set_delegate (mp_delegate->selected_inside (other));
return *this;
}
/**
* @brief Selects all edges of this edge collection which are not completely inside edges from the other edge collection
*
* Merged semantics applies.
*/
Edges &select_not_inside (const Edges &other)
{
set_delegate (mp_delegate->selected_not_inside (other));
return *this;
}
/**
* @brief Returns all edges of this which are completely inside edgess from the other edge collection
*
* This method is an out-of-place version of select_inside.
*
* Merged semantics applies.
*/
Edges selected_inside (const Edges &other) const
{
return Edges (mp_delegate->selected_inside (other));
}
/**
* @brief Returns all edges of this which are not completely inside edges from the other edge collection
*
* This method is an out-of-place version of select_not_inside.
*
* Merged semantics applies.
*/
Edges selected_not_inside (const Edges &other) const
{
return Edges (mp_delegate->selected_not_inside (other));
}
/**
* @brief Returns all edges of this which are completely inside edges from the other edge collection and the opposite ones at the same time
*
* This method is equivalent to calling selected_inside and selected_not_inside, but faster.
*
* Merged semantics applies.
*/
std::pair<Edges, Edges> selected_inside_differential (const Edges &other) const
{
std::pair<db::EdgesDelegate *, db::EdgesDelegate *> p = mp_delegate->selected_inside_pair (other);
return std::pair<Edges, Edges> (Edges (p.first), Edges (p.second));
}
/**
* @brief Selects all edges of this edge set which overlap or touch with edges from the other edge set
*

View File

@ -294,9 +294,11 @@ public:
virtual EdgesDelegate *merged () const = 0;
virtual EdgesDelegate *and_with (const Edges &other) const = 0;
virtual EdgesDelegate *and_with (const Region &other) const = 0;
virtual EdgesDelegate *not_with (const Edges &other) const = 0;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> andnot_with (const Edges &) const = 0;
virtual EdgesDelegate *and_with (const Region &other) const = 0;
virtual EdgesDelegate *not_with (const Region &other) const = 0;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> andnot_with (const Region &) const = 0;
virtual EdgesDelegate *xor_with (const Edges &other) const = 0;
virtual EdgesDelegate *or_with (const Edges &other) const = 0;
virtual EdgesDelegate *add_in_place (const Edges &other) = 0;
@ -307,12 +309,28 @@ public:
virtual EdgesDelegate *inside_part (const Region &other) const = 0;
virtual EdgesDelegate *outside_part (const Region &other) const = 0;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> inside_outside_part_pair (const Region &other) const = 0;
virtual RegionDelegate *pull_interacting (const Region &) const = 0;
virtual EdgesDelegate *pull_interacting (const Edges &) const = 0;
virtual EdgesDelegate *selected_interacting (const Region &other) const = 0;
virtual EdgesDelegate *selected_not_interacting (const Region &other) const = 0;
virtual EdgesDelegate *selected_interacting (const Edges &other) const = 0;
virtual EdgesDelegate *selected_not_interacting (const Edges &other) const = 0;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair (const Region &other) const = 0;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair (const Edges &other) const = 0;
virtual EdgesDelegate *selected_outside (const Region &other) const = 0;
virtual EdgesDelegate *selected_not_outside (const Region &other) const = 0;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_outside_pair (const Region &other) const = 0;
virtual EdgesDelegate *selected_inside (const Region &other) const = 0;
virtual EdgesDelegate *selected_not_inside (const Region &other) const = 0;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_inside_pair (const Region &other) const = 0;
virtual EdgesDelegate *selected_outside (const Edges &other) const = 0;
virtual EdgesDelegate *selected_not_outside (const Edges &other) const = 0;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_outside_pair (const Edges &other) const = 0;
virtual EdgesDelegate *selected_inside (const Edges &other) const = 0;
virtual EdgesDelegate *selected_not_inside (const Edges &other) const = 0;
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_inside_pair (const Edges &other) const = 0;
virtual EdgesDelegate *in (const Edges &other, bool invert) const = 0;

View File

@ -177,7 +177,7 @@ extended_edge (const db::Edge &edge, db::Coord ext_b, db::Coord ext_e, db::Coord
// -------------------------------------------------------------------------------------------------------------
// EdgeSegmentSelector processor
EdgeSegmentSelector::EdgeSegmentSelector (int mode, db::Edges::length_type length, double fraction)
EdgeSegmentSelector::EdgeSegmentSelector (int mode, Edge::distance_type length, double fraction)
: m_mode (mode), m_length (length), m_fraction (fraction)
{ }

View File

@ -34,6 +34,11 @@
namespace db {
/**
* @brief The operation mode for the interaction filters
*/
enum EdgeInteractionMode { EdgesInteract, EdgesInside, EdgesOutside };
class PolygonSink;
/**
@ -249,8 +254,8 @@ class edge_interaction_filter
: public db::box_scanner_receiver<db::Edge, size_t>
{
public:
edge_interaction_filter (OutputContainer &output)
: mp_output (&output)
edge_interaction_filter (OutputContainer &output, EdgeInteractionMode mode)
: mp_output (&output), m_mode (mode)
{
// .. nothing yet ..
}
@ -261,6 +266,7 @@ public:
if (p1 != p2) {
const db::Edge *o = p1 > p2 ? o2 : o1;
const db::Edge *oo = p1 > p2 ? o1 : o2;
// @@@
if (o->intersect (*oo)) {
if (m_seen.insert (o).second) {
mp_output->insert (*o);
@ -272,6 +278,7 @@ public:
private:
OutputContainer *mp_output;
std::set<const db::Edge *> m_seen;
EdgeInteractionMode m_mode;
};
/**
@ -288,8 +295,8 @@ class edge_to_region_interaction_filter
: public db::box_scanner_receiver2<db::Edge, size_t, db::Polygon, size_t>
{
public:
edge_to_region_interaction_filter (OutputContainer &output)
: mp_output (&output)
edge_to_region_interaction_filter (OutputContainer *output, EdgeInteractionMode mode)
: mp_output (output), m_mode (mode)
{
// .. nothing yet ..
}
@ -300,6 +307,7 @@ public:
tl::select (ep, e, p);
if (m_seen.find (ep) == m_seen.end ()) {
// @@@
if (db::interact (*p, *e)) {
m_seen.insert (ep);
mp_output->insert (*ep);
@ -310,6 +318,7 @@ public:
private:
OutputContainer *mp_output;
std::set<const OutputType *> m_seen;
EdgeInteractionMode m_mode;
};
/**
@ -407,7 +416,7 @@ class DB_PUBLIC EdgeSegmentSelector
: public EdgeProcessorBase
{
public:
EdgeSegmentSelector (int mode, db::Edges::length_type length, double fraction);
EdgeSegmentSelector (int mode, Edge::distance_type length, double fraction);
~EdgeSegmentSelector ();
virtual void process (const db::Edge &edge, std::vector<db::Edge> &res) const;
@ -420,7 +429,7 @@ public:
private:
int m_mode;
db::Edges::length_type m_length;
db::Edge::distance_type m_length;
double m_fraction;
db::MagnificationReducer m_vars;
};

View File

@ -75,9 +75,11 @@ public:
virtual EdgesDelegate *merged () const { return new EmptyEdges (); }
virtual EdgesDelegate *and_with (const Edges &) const { return new EmptyEdges (); }
virtual EdgesDelegate *and_with (const Region &) const { return new EmptyEdges (); }
virtual EdgesDelegate *not_with (const Edges &) const { return new EmptyEdges (); }
virtual std::pair<EdgesDelegate *, EdgesDelegate *> andnot_with (const Edges &) const { return std::make_pair (new EmptyEdges (), new EmptyEdges ()); }
virtual EdgesDelegate *and_with (const Region &) const { return new EmptyEdges (); }
virtual EdgesDelegate *not_with (const Region &) const { return new EmptyEdges (); }
virtual std::pair<EdgesDelegate *, EdgesDelegate *> andnot_with (const Region &) const { return std::make_pair (new EmptyEdges (), new EmptyEdges ()); }
virtual EdgesDelegate *xor_with (const Edges &other) const;
virtual EdgesDelegate *or_with (const Edges &other) const;
virtual EdgesDelegate *add_in_place (const Edges &other);
@ -88,12 +90,29 @@ public:
virtual EdgesDelegate *inside_part (const Region &) const { return new EmptyEdges (); }
virtual EdgesDelegate *outside_part (const Region &) const { return new EmptyEdges (); }
virtual std::pair<EdgesDelegate *, EdgesDelegate *> inside_outside_part_pair (const Region &) const { return std::make_pair (new EmptyEdges (), new EmptyEdges ()); }
virtual RegionDelegate *pull_interacting (const Region &) const;
virtual EdgesDelegate *pull_interacting (const Edges &) const { return new EmptyEdges (); }
virtual EdgesDelegate *selected_interacting (const Edges &) const { return new EmptyEdges (); }
virtual EdgesDelegate *selected_not_interacting (const Edges &) const { return new EmptyEdges (); }
virtual EdgesDelegate *selected_interacting (const Region &) const { return new EmptyEdges (); }
virtual EdgesDelegate *selected_not_interacting (const Region &) const { return new EmptyEdges (); }
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair (const Region &) const { return std::make_pair (new EmptyEdges (), new EmptyEdges ()); }
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_interacting_pair (const Edges &) const { return std::make_pair (new EmptyEdges (), new EmptyEdges ()); }
virtual EdgesDelegate *selected_outside (const Region &) const { return new EmptyEdges (); }
virtual EdgesDelegate *selected_not_outside (const Region &) const { return new EmptyEdges (); }
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_outside_pair (const Region &) const { return std::make_pair (new EmptyEdges (), new EmptyEdges ()); }
virtual EdgesDelegate *selected_inside (const Region &) const { return new EmptyEdges (); }
virtual EdgesDelegate *selected_not_inside (const Region &) const { return new EmptyEdges (); }
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_inside_pair (const Region &) const { return std::make_pair (new EmptyEdges (), new EmptyEdges ()); }
virtual EdgesDelegate *selected_outside (const Edges &) const { return new EmptyEdges (); }
virtual EdgesDelegate *selected_not_outside (const Edges &) const { return new EmptyEdges (); }
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_outside_pair (const Edges &) const { return std::make_pair (new EmptyEdges (), new EmptyEdges ()); }
virtual EdgesDelegate *selected_inside (const Edges &) const { return new EmptyEdges (); }
virtual EdgesDelegate *selected_not_inside (const Edges &) const { return new EmptyEdges (); }
virtual std::pair<EdgesDelegate *, EdgesDelegate *> selected_inside_pair (const Edges &) const { return std::make_pair (new EmptyEdges (), new EmptyEdges ()); }
virtual EdgesDelegate *in (const Edges &, bool) const { return new EmptyEdges (); }

View File

@ -475,7 +475,7 @@ EdgeToPolygonLocalOperation::do_compute_local (db::Layout * /*layout*/, const sh
}
db::EdgeToEdgeSetGenerator cc (result);
db::EdgePolygonOp op (m_outside, m_include_borders);
db::EdgePolygonOp op (m_outside ? db::EdgePolygonOp::Outside : db::EdgePolygonOp::Inside, m_include_borders);
ep.process (cc, op);
}

View File

@ -105,8 +105,8 @@ public:
*
* @param clear_shapes If true, the shapes container is cleared on the start event.
*/
EdgeShapeGenerator (db::Shapes &shapes, bool clear_shapes = false)
: EdgeSink (), mp_shapes (&shapes), m_clear_shapes (clear_shapes)
EdgeShapeGenerator (db::Shapes &shapes, bool clear_shapes = false, int tag = 0, EdgeShapeGenerator *chained = 0)
: EdgeSink (), mp_shapes (&shapes), m_clear_shapes (clear_shapes), m_tag (tag), mp_chained (chained)
{ }
/**
@ -115,6 +115,22 @@ public:
virtual void put (const db::Edge &edge)
{
mp_shapes->insert (edge);
if (mp_chained) {
mp_chained->put (edge);
}
}
/**
* @brief Implementation of the EdgeSink interface
*/
virtual void put (const db::Edge &edge, int tag)
{
if (m_tag == 0 || m_tag == tag) {
mp_shapes->insert (edge);
}
if (mp_chained) {
mp_chained->put (edge, tag);
}
}
/**
@ -127,11 +143,16 @@ public:
// The single-shot scheme is a easy way to overcome problems with multiple start/flush brackets (i.e. on size filter)
m_clear_shapes = false;
}
if (mp_chained) {
mp_chained->start ();
}
}
private:
db::Shapes *mp_shapes;
bool m_clear_shapes;
int m_tag;
EdgeShapeGenerator *mp_chained;
};
/**

View File

@ -2051,7 +2051,7 @@ TEST(32)
std::vector<db::Edge> out;
db::EdgeContainer ec (out);
db::EdgePolygonOp op (false, false /*not including touch*/);
db::EdgePolygonOp op (db::EdgePolygonOp::Inside, false /*not including touch*/);
ep.process (ec, op);
@ -2114,7 +2114,7 @@ TEST(33)
std::vector<db::Edge> out;
db::EdgeContainer ec (out);
db::EdgePolygonOp op (true, true /*including touch*/);
db::EdgePolygonOp op (db::EdgePolygonOp::Outside, true /*including touch*/);
ep.process (ec, op);