mirror of https://github.com/KLayout/klayout.git
WIP: first implementation. Testing needed.
This commit is contained in:
parent
595075a88a
commit
24759c7174
|
|
@ -27,6 +27,7 @@
|
||||||
#include "dbCommon.h"
|
#include "dbCommon.h"
|
||||||
#include "dbBoxScanner.h"
|
#include "dbBoxScanner.h"
|
||||||
#include "dbEdgesDelegate.h"
|
#include "dbEdgesDelegate.h"
|
||||||
|
#include "dbEdgeBoolean.h"
|
||||||
#include "dbBoxScanner.h"
|
#include "dbBoxScanner.h"
|
||||||
#include "dbPolygonTools.h"
|
#include "dbPolygonTools.h"
|
||||||
|
|
||||||
|
|
@ -138,6 +139,11 @@ public:
|
||||||
return boolean (&other, EdgeOr);
|
return boolean (&other, EdgeOr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual EdgesDelegate *intersections (const Edges &other) const
|
||||||
|
{
|
||||||
|
return boolean (&other, EdgeIntersections);
|
||||||
|
}
|
||||||
|
|
||||||
virtual EdgesDelegate *add_in_place (const Edges &other)
|
virtual EdgesDelegate *add_in_place (const Edges &other)
|
||||||
{
|
{
|
||||||
return add (other);
|
return add (other);
|
||||||
|
|
|
||||||
|
|
@ -751,11 +751,11 @@ EdgesDelegate *DeepEdges::merged () const
|
||||||
}
|
}
|
||||||
|
|
||||||
DeepLayer
|
DeepLayer
|
||||||
DeepEdges::and_or_not_with (const DeepEdges *other, bool and_op) const
|
DeepEdges::and_or_not_with (const DeepEdges *other, EdgeBoolOp op) const
|
||||||
{
|
{
|
||||||
DeepLayer dl_out (m_deep_layer.derived ());
|
DeepLayer dl_out (m_deep_layer.derived ());
|
||||||
|
|
||||||
db::EdgeBoolAndOrNotLocalOperation op (and_op);
|
db::EdgeBoolAndOrNotLocalOperation local_op (op);
|
||||||
|
|
||||||
db::local_processor<db::Edge, db::Edge, db::Edge> proc (const_cast<db::Layout *> (&m_deep_layer.layout ()), const_cast<db::Cell *> (&m_deep_layer.initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell ());
|
db::local_processor<db::Edge, db::Edge, db::Edge> proc (const_cast<db::Layout *> (&m_deep_layer.layout ()), const_cast<db::Cell *> (&m_deep_layer.initial_cell ()), &other->deep_layer ().layout (), &other->deep_layer ().initial_cell ());
|
||||||
proc.set_base_verbosity (base_verbosity ());
|
proc.set_base_verbosity (base_verbosity ());
|
||||||
|
|
@ -763,7 +763,7 @@ DeepEdges::and_or_not_with (const DeepEdges *other, bool and_op) const
|
||||||
proc.set_area_ratio (m_deep_layer.store ()->max_area_ratio ());
|
proc.set_area_ratio (m_deep_layer.store ()->max_area_ratio ());
|
||||||
proc.set_max_vertex_count (m_deep_layer.store ()->max_vertex_count ());
|
proc.set_max_vertex_count (m_deep_layer.store ()->max_vertex_count ());
|
||||||
|
|
||||||
proc.run (&op, m_deep_layer.layer (), other->deep_layer ().layer (), dl_out.layer ());
|
proc.run (&local_op, m_deep_layer.layer (), other->deep_layer ().layer (), dl_out.layer ());
|
||||||
|
|
||||||
return dl_out;
|
return dl_out;
|
||||||
}
|
}
|
||||||
|
|
@ -786,6 +786,26 @@ DeepEdges::edge_region_op (const DeepRegion *other, bool outside, bool include_b
|
||||||
return dl_out;
|
return dl_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EdgesDelegate *DeepEdges::intersections (const Edges &other) const
|
||||||
|
{
|
||||||
|
const DeepEdges *other_deep = dynamic_cast <const DeepEdges *> (other.delegate ());
|
||||||
|
|
||||||
|
if (empty () || other.empty ()) {
|
||||||
|
|
||||||
|
// Nothing to do
|
||||||
|
return new EmptyEdges ();
|
||||||
|
|
||||||
|
} else if (! other_deep) {
|
||||||
|
|
||||||
|
return AsIfFlatEdges::intersections (other);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return new DeepEdges (and_or_not_with (other_deep, EdgeIntersections));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EdgesDelegate *DeepEdges::and_with (const Edges &other) const
|
EdgesDelegate *DeepEdges::and_with (const Edges &other) const
|
||||||
{
|
{
|
||||||
const DeepEdges *other_deep = dynamic_cast <const DeepEdges *> (other.delegate ());
|
const DeepEdges *other_deep = dynamic_cast <const DeepEdges *> (other.delegate ());
|
||||||
|
|
@ -801,7 +821,7 @@ EdgesDelegate *DeepEdges::and_with (const Edges &other) const
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
return new DeepEdges (and_or_not_with (other_deep, true));
|
return new DeepEdges (and_or_not_with (other_deep, EdgeAnd));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -851,7 +871,7 @@ EdgesDelegate *DeepEdges::not_with (const Edges &other) const
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
return new DeepEdges (and_or_not_with (other_deep, false));
|
return new DeepEdges (and_or_not_with (other_deep, EdgeNot));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -903,8 +923,8 @@ EdgesDelegate *DeepEdges::xor_with (const Edges &other) const
|
||||||
|
|
||||||
// Implement XOR as (A-B)+(B-A) - only this implementation
|
// Implement XOR as (A-B)+(B-A) - only this implementation
|
||||||
// is compatible with the local processor scheme
|
// is compatible with the local processor scheme
|
||||||
DeepLayer n1 (and_or_not_with (other_deep, false));
|
DeepLayer n1 (and_or_not_with (other_deep, EdgeNot));
|
||||||
DeepLayer n2 (other_deep->and_or_not_with (this, false));
|
DeepLayer n2 (other_deep->and_or_not_with (this, EdgeNot));
|
||||||
|
|
||||||
n1.add_from (n2);
|
n1.add_from (n2);
|
||||||
return new DeepEdges (n1);
|
return new DeepEdges (n1);
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include "dbAsIfFlatEdges.h"
|
#include "dbAsIfFlatEdges.h"
|
||||||
#include "dbDeepShapeStore.h"
|
#include "dbDeepShapeStore.h"
|
||||||
|
#include "dbEdgeBoolean.h"
|
||||||
#include "dbEdgePairs.h"
|
#include "dbEdgePairs.h"
|
||||||
|
|
||||||
namespace db {
|
namespace db {
|
||||||
|
|
@ -132,6 +133,8 @@ public:
|
||||||
virtual EdgesDelegate *add_in_place (const Edges &other);
|
virtual EdgesDelegate *add_in_place (const Edges &other);
|
||||||
virtual EdgesDelegate *add (const Edges &other) const;
|
virtual EdgesDelegate *add (const Edges &other) const;
|
||||||
|
|
||||||
|
virtual EdgesDelegate *intersections (const Edges &other) const;
|
||||||
|
|
||||||
virtual EdgesDelegate *inside_part (const Region &other) const;
|
virtual EdgesDelegate *inside_part (const Region &other) const;
|
||||||
virtual EdgesDelegate *outside_part (const Region &other) const;
|
virtual EdgesDelegate *outside_part (const Region &other) const;
|
||||||
|
|
||||||
|
|
@ -168,7 +171,7 @@ private:
|
||||||
void init ();
|
void init ();
|
||||||
void ensure_merged_edges_valid () const;
|
void ensure_merged_edges_valid () const;
|
||||||
const DeepLayer &merged_deep_layer () const;
|
const DeepLayer &merged_deep_layer () const;
|
||||||
DeepLayer and_or_not_with(const DeepEdges *other, bool and_op) const;
|
DeepLayer and_or_not_with(const DeepEdges *other, EdgeBoolOp op) const;
|
||||||
DeepLayer edge_region_op (const DeepRegion *other, bool outside, bool include_borders) const;
|
DeepLayer edge_region_op (const DeepRegion *other, bool outside, bool include_borders) const;
|
||||||
EdgePairsDelegate *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;
|
EdgePairsDelegate *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;
|
||||||
virtual EdgesDelegate *pull_generic (const Edges &edges) const;
|
virtual EdgesDelegate *pull_generic (const Edges &edges) const;
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@
|
||||||
#define HDR_dbEdgeBoolean
|
#define HDR_dbEdgeBoolean
|
||||||
|
|
||||||
#include "dbEdge.h"
|
#include "dbEdge.h"
|
||||||
#include "dbEdgesDelegate.h"
|
|
||||||
#include "dbBoxScanner.h"
|
#include "dbBoxScanner.h"
|
||||||
|
|
||||||
#include "tlIntervalMap.h"
|
#include "tlIntervalMap.h"
|
||||||
|
|
@ -32,6 +31,11 @@
|
||||||
namespace db
|
namespace db
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A common definition for the boolean operations available on edges
|
||||||
|
*/
|
||||||
|
enum EdgeBoolOp { EdgeOr, EdgeNot, EdgeXor, EdgeAnd, EdgeIntersections };
|
||||||
|
|
||||||
struct OrJoinOp
|
struct OrJoinOp
|
||||||
{
|
{
|
||||||
void operator() (int &v, int n)
|
void operator() (int &v, int n)
|
||||||
|
|
@ -216,7 +220,15 @@ struct EdgeBooleanClusterCollector
|
||||||
: public db::cluster_collector<db::Edge, size_t, EdgeBooleanCluster<OutputContainer> >
|
: public db::cluster_collector<db::Edge, size_t, EdgeBooleanCluster<OutputContainer> >
|
||||||
{
|
{
|
||||||
EdgeBooleanClusterCollector (OutputContainer *output, EdgeBoolOp op)
|
EdgeBooleanClusterCollector (OutputContainer *output, EdgeBoolOp op)
|
||||||
: db::cluster_collector<db::Edge, size_t, EdgeBooleanCluster<OutputContainer> > (EdgeBooleanCluster<OutputContainer> (output, op), op != EdgeAnd /*report single*/)
|
: db::cluster_collector<db::Edge, size_t, EdgeBooleanCluster<OutputContainer> > (EdgeBooleanCluster<OutputContainer> (output, op == EdgeIntersections ? EdgeAnd : op), op != EdgeAnd && op != EdgeIntersections /*report single*/),
|
||||||
|
mp_intersections (op == EdgeIntersections ? output : 0)
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
|
EdgeBooleanClusterCollector (OutputContainer *output, OutputContainer *intersections, EdgeBoolOp op)
|
||||||
|
: db::cluster_collector<db::Edge, size_t, EdgeBooleanCluster<OutputContainer> > (EdgeBooleanCluster<OutputContainer> (output, op), op != EdgeAnd /*report single*/),
|
||||||
|
mp_intersections (intersections)
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
@ -227,12 +239,27 @@ struct EdgeBooleanClusterCollector
|
||||||
// 1.) not degenerate
|
// 1.) not degenerate
|
||||||
// 2.) parallel with some tolerance of roughly 1 dbu
|
// 2.) parallel with some tolerance of roughly 1 dbu
|
||||||
// 3.) connected
|
// 3.) connected
|
||||||
|
// In intersection-detection mode, identify intersection points otherwise
|
||||||
|
// and insert into the intersections container as degenerated edges.
|
||||||
|
|
||||||
if (! o1->is_degenerate () && ! o2->is_degenerate ()
|
if (! o1->is_degenerate () && ! o2->is_degenerate ()
|
||||||
&& fabs ((double) db::vprod (*o1, *o2)) < db::coord_traits<db::Coord>::prec_distance () * std::min (o1->double_length (), o2->double_length ())
|
&& fabs ((double) db::vprod (*o1, *o2)) < db::coord_traits<db::Coord>::prec_distance () * std::min (o1->double_length (), o2->double_length ())
|
||||||
&& (o1->p1 () == o2->p1 () || o1->p1 () == o2->p2 () || o1->p2 () == o2->p1 () || o1->p2 () == o2->p2 () || o1->coincident (*o2))) {
|
&& (o1->p1 () == o2->p1 () || o1->p1 () == o2->p2 () || o1->p2 () == o2->p1 () || o1->p2 () == o2->p2 () || o1->coincident (*o2))) {
|
||||||
|
|
||||||
db::cluster_collector<db::Edge, size_t, EdgeBooleanCluster<OutputContainer> >::add (o1, p1, o2, p2);
|
db::cluster_collector<db::Edge, size_t, EdgeBooleanCluster<OutputContainer> >::add (o1, p1, o2, p2);
|
||||||
|
|
||||||
|
} else if (mp_intersections && p1 != p2) {
|
||||||
|
|
||||||
|
std::pair<bool, db::Point> ip = o1->intersect_point (*o2);
|
||||||
|
if (ip.first) {
|
||||||
|
mp_intersections->insert (db::Edge (ip.second, ip.second));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
OutputContainer *mp_intersections;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -950,6 +950,16 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Intersections with other edges
|
||||||
|
* Intersections are similar to "AND", but will also report
|
||||||
|
* non-parallel intersections between crossing edges.
|
||||||
|
*/
|
||||||
|
Edges intersections (const Edges &other) const
|
||||||
|
{
|
||||||
|
return Edges (mp_delegate->intersections (other));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief returns the extended edges
|
* @brief returns the extended edges
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -155,11 +155,6 @@ class DB_PUBLIC EdgeToEdgePairProcessorBase
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A common definition for the boolean operations available on edges
|
|
||||||
*/
|
|
||||||
enum EdgeBoolOp { EdgeOr, EdgeNot, EdgeXor, EdgeAnd };
|
|
||||||
|
|
||||||
class RecursiveShapeIterator;
|
class RecursiveShapeIterator;
|
||||||
class EdgeFilterBase;
|
class EdgeFilterBase;
|
||||||
class EdgePairsDelegate;
|
class EdgePairsDelegate;
|
||||||
|
|
@ -267,6 +262,7 @@ public:
|
||||||
virtual EdgesDelegate *or_with (const Edges &other) const = 0;
|
virtual EdgesDelegate *or_with (const Edges &other) const = 0;
|
||||||
virtual EdgesDelegate *add_in_place (const Edges &other) = 0;
|
virtual EdgesDelegate *add_in_place (const Edges &other) = 0;
|
||||||
virtual EdgesDelegate *add (const Edges &other) const = 0;
|
virtual EdgesDelegate *add (const Edges &other) const = 0;
|
||||||
|
virtual EdgesDelegate *intersections (const Edges &other) const = 0;
|
||||||
|
|
||||||
virtual RegionDelegate *extended (coord_type ext_b, coord_type ext_e, coord_type ext_o, coord_type ext_i, bool join) const = 0;
|
virtual RegionDelegate *extended (coord_type ext_b, coord_type ext_e, coord_type ext_o, coord_type ext_i, bool join) const = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ public:
|
||||||
virtual EdgesDelegate *or_with (const Edges &other) const;
|
virtual EdgesDelegate *or_with (const Edges &other) const;
|
||||||
virtual EdgesDelegate *add_in_place (const Edges &other);
|
virtual EdgesDelegate *add_in_place (const Edges &other);
|
||||||
virtual EdgesDelegate *add (const Edges &other) const;
|
virtual EdgesDelegate *add (const Edges &other) const;
|
||||||
|
virtual EdgesDelegate *intersections (const Edges &) const { return new EmptyEdges (); }
|
||||||
|
|
||||||
virtual RegionDelegate *extended (coord_type, coord_type, coord_type, coord_type, bool) const;
|
virtual RegionDelegate *extended (coord_type, coord_type, coord_type, coord_type, bool) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -177,8 +177,8 @@ std::string SelfOverlapMergeLocalOperation::description () const
|
||||||
// ---------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------
|
||||||
// EdgeBoolAndOrNotLocalOperation implementation
|
// EdgeBoolAndOrNotLocalOperation implementation
|
||||||
|
|
||||||
EdgeBoolAndOrNotLocalOperation::EdgeBoolAndOrNotLocalOperation (bool is_and)
|
EdgeBoolAndOrNotLocalOperation::EdgeBoolAndOrNotLocalOperation (EdgeBoolOp op)
|
||||||
: m_is_and (is_and)
|
: m_op (op)
|
||||||
{
|
{
|
||||||
// .. nothing yet ..
|
// .. nothing yet ..
|
||||||
}
|
}
|
||||||
|
|
@ -186,19 +186,27 @@ EdgeBoolAndOrNotLocalOperation::EdgeBoolAndOrNotLocalOperation (bool is_and)
|
||||||
local_operation<db::Edge, db::Edge, db::Edge>::on_empty_intruder_mode
|
local_operation<db::Edge, db::Edge, db::Edge>::on_empty_intruder_mode
|
||||||
EdgeBoolAndOrNotLocalOperation::on_empty_intruder_hint () const
|
EdgeBoolAndOrNotLocalOperation::on_empty_intruder_hint () const
|
||||||
{
|
{
|
||||||
return m_is_and ? Drop : Copy;
|
return (m_op == EdgeAnd || m_op == EdgeIntersections) ? Drop : Copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
EdgeBoolAndOrNotLocalOperation::description () const
|
EdgeBoolAndOrNotLocalOperation::description () const
|
||||||
{
|
{
|
||||||
return m_is_and ? tl::to_string (tr ("Edge AND operation")) : tl::to_string (tr ("Edge NOT operation"));
|
if (m_op == EdgeIntersections) {
|
||||||
|
return tl::to_string (tr ("Edge INTERSECTION operation"));
|
||||||
|
} else if (m_op == EdgeAnd) {
|
||||||
|
return tl::to_string (tr ("Edge AND operation"));
|
||||||
|
} else if (m_op == EdgeNot) {
|
||||||
|
return tl::to_string (tr ("Edge NOT operation"));
|
||||||
|
} else {
|
||||||
|
return std::string ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
EdgeBoolAndOrNotLocalOperation::compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::unordered_set<db::Edge> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
|
EdgeBoolAndOrNotLocalOperation::compute_local (db::Layout * /*layout*/, const shape_interactions<db::Edge, db::Edge> &interactions, std::unordered_set<db::Edge> &result, size_t /*max_vertex_count*/, double /*area_ratio*/) const
|
||||||
{
|
{
|
||||||
EdgeBooleanClusterCollector<std::unordered_set<db::Edge> > cluster_collector (&result, m_is_and ? EdgeAnd : EdgeNot);
|
EdgeBooleanClusterCollector<std::unordered_set<db::Edge> > cluster_collector (&result, m_op);
|
||||||
|
|
||||||
db::box_scanner<db::Edge, size_t> scanner;
|
db::box_scanner<db::Edge, size_t> scanner;
|
||||||
|
|
||||||
|
|
@ -210,17 +218,18 @@ EdgeBoolAndOrNotLocalOperation::compute_local (db::Layout * /*layout*/, const sh
|
||||||
}
|
}
|
||||||
|
|
||||||
bool any_subject = false;
|
bool any_subject = false;
|
||||||
|
bool is_and = (m_op == EdgeAnd || m_op == EdgeIntersections);
|
||||||
|
|
||||||
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
for (shape_interactions<db::Edge, db::Edge>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||||
|
|
||||||
const db::Edge &subject = interactions.subject_shape (i->first);
|
const db::Edge &subject = interactions.subject_shape (i->first);
|
||||||
if (others.find (subject) != others.end ()) {
|
if (others.find (subject) != others.end ()) {
|
||||||
if (m_is_and) {
|
if (is_and) {
|
||||||
result.insert (subject);
|
result.insert (subject);
|
||||||
}
|
}
|
||||||
} else if (i->second.empty ()) {
|
} else if (i->second.empty ()) {
|
||||||
// shortcut (not: keep, and: drop)
|
// shortcut (not: keep, and: drop)
|
||||||
if (! m_is_and) {
|
if (! is_and) {
|
||||||
result.insert (subject);
|
result.insert (subject);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
#include "dbCommon.h"
|
#include "dbCommon.h"
|
||||||
|
|
||||||
#include "dbLayout.h"
|
#include "dbLayout.h"
|
||||||
|
#include "dbEdgeBoolean.h"
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
@ -151,7 +152,7 @@ class DB_PUBLIC EdgeBoolAndOrNotLocalOperation
|
||||||
: public local_operation<db::Edge, db::Edge, db::Edge>
|
: public local_operation<db::Edge, db::Edge, db::Edge>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EdgeBoolAndOrNotLocalOperation (bool is_and);
|
EdgeBoolAndOrNotLocalOperation (EdgeBoolOp op);
|
||||||
|
|
||||||
virtual void compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::Edge> &interactions, std::unordered_set<db::Edge> &result, size_t max_vertex_count, double area_ratio) const;
|
virtual void compute_local (db::Layout *layout, const shape_interactions<db::Edge, db::Edge> &interactions, std::unordered_set<db::Edge> &result, size_t max_vertex_count, double area_ratio) const;
|
||||||
virtual on_empty_intruder_mode on_empty_intruder_hint () const;
|
virtual on_empty_intruder_mode on_empty_intruder_hint () const;
|
||||||
|
|
@ -161,7 +162,7 @@ public:
|
||||||
virtual db::Coord dist () const { return 1; }
|
virtual db::Coord dist () const { return 1; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_is_and;
|
EdgeBoolOp m_op;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -943,6 +943,13 @@ Class<db::Edges> dec_Edges ("db", "Edges",
|
||||||
"\n"
|
"\n"
|
||||||
"This method has been introduced in version 0.26.1\n"
|
"This method has been introduced in version 0.26.1\n"
|
||||||
) +
|
) +
|
||||||
|
method ("intersections", &db::Edges::intersections, gsi::arg ("other"),
|
||||||
|
"@brief Computes the intersections between this edges and other edges\n"
|
||||||
|
"This computation is like an AND operation, but also including crossing points between non-coincident edges as "
|
||||||
|
"degenerated (point-like) edges.\n"
|
||||||
|
"\n"
|
||||||
|
"This method has been introduced in version 0.26.2\n"
|
||||||
|
) +
|
||||||
method ("inside_part", &db::Edges::inside_part, gsi::arg ("other"),
|
method ("inside_part", &db::Edges::inside_part, gsi::arg ("other"),
|
||||||
"@brief Returns the parts of the edges of this edge collection which are inside the polygons of the region\n"
|
"@brief Returns the parts of the edges of this edge collection which are inside the polygons of the region\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
|
||||||
|
|
@ -1601,6 +1601,16 @@ CODE
|
||||||
# This method is available for polygon and edge layers. Edges can be selected
|
# This method is available for polygon and edge layers. Edges can be selected
|
||||||
# with respect to other edges or polygons.
|
# with respect to other edges or polygons.
|
||||||
|
|
||||||
|
# %DRC%
|
||||||
|
# @name intersections
|
||||||
|
# @brief Returns the intersection points of intersecting edge segments for two edge collections
|
||||||
|
# @synopsis layer.intersections(edges)
|
||||||
|
# This operation is similar to the "&" operator, but it does also report intersection points
|
||||||
|
# between non-colinear, but intersection edges. Such points are reported as point-like,
|
||||||
|
# degenerated edge objects.
|
||||||
|
#
|
||||||
|
# This method is available for edge layers. The argument must be an edge layer.
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name inside_part
|
# @name inside_part
|
||||||
# @brief Returns the parts of the edges inside the given region
|
# @brief Returns the parts of the edges inside the given region
|
||||||
|
|
@ -1731,7 +1741,6 @@ CODE
|
||||||
end
|
end
|
||||||
|
|
||||||
%w(inside_part outside_part).each do |f|
|
%w(inside_part outside_part).each do |f|
|
||||||
# In tiled mode, there are no modifying versions. Emulate using the non-modifying one.
|
|
||||||
eval <<"CODE"
|
eval <<"CODE"
|
||||||
def #{f}(other)
|
def #{f}(other)
|
||||||
other.requires_region("#{f}")
|
other.requires_region("#{f}")
|
||||||
|
|
@ -1746,6 +1755,21 @@ CODE
|
||||||
CODE
|
CODE
|
||||||
end
|
end
|
||||||
|
|
||||||
|
%w(intersections).each do |f|
|
||||||
|
eval <<"CODE"
|
||||||
|
def #{f}(other)
|
||||||
|
other.requires_edges("#{f}")
|
||||||
|
requires_edges("#{f}")
|
||||||
|
if @engine.is_tiled?
|
||||||
|
@data = @engine._tcmd(@data, 0, @data.class, :#{f}, other.data)
|
||||||
|
DRCLayer::new(@engine, @data)
|
||||||
|
else
|
||||||
|
DRCLayer::new(@engine, @engine._tcmd(@data, 0, @data.class, :#{f}, other.data))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
CODE
|
||||||
|
end
|
||||||
|
|
||||||
# %DRC%
|
# %DRC%
|
||||||
# @name rectangles
|
# @name rectangles
|
||||||
# @brief Selects all rectangle polygons from the input
|
# @brief Selects all rectangle polygons from the input
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue