Inkscape
Vector Graphics Editor
|
Intermediate data for computing Boolean operations on paths. More...
#include <intersection-graph.h>
Classes | |
struct | IntersectionVertex |
struct | PathData |
Stores processed intersection information for a single path in an operand path-vector. More... | |
Public Member Functions | |
PathIntersectionGraph (PathVector const &a, PathVector const &b, Coord precision=EPSILON) | |
Construct a path intersection graph for two shapes described via their boundaries. | |
PathVector | getUnion () |
Get the union of the shapes, A ∪ B. | |
PathVector | getIntersection () |
Get the intersection of the shapes, A ∩ B. | |
PathVector | getAminusB () |
Get the difference of the shapes, A ∖ B. | |
PathVector | getBminusA () |
Get the opposite difference of the shapes, B ∖ A. | |
PathVector | getXOR () |
Get the symmetric difference of the shapes, A ∆ B. | |
std::size_t | size () const |
Returns the number of intersections used when computing Boolean operations. | |
std::vector< Point > | intersectionPoints (bool defective=false) const |
Get the geometric points where the two path-vectors intersect. | |
std::vector< Point > | windingPoints () const |
Get the geometric points located on path portions between consecutive intersections. | |
void | fragments (PathVector &in, PathVector &out) const |
bool | valid () const |
Private Types | |
enum | InOutFlag { INSIDE , OUTSIDE , BOTH } |
typedef boost::intrusive::list< IntersectionVertex, boost::intrusive::member_hook< IntersectionVertex, boost::intrusive::list_member_hook<>, &IntersectionVertex::_hook > > | IntersectionList |
typedef boost::intrusive::list< IntersectionVertex, boost::intrusive::member_hook< IntersectionVertex, boost::intrusive::list_member_hook<>, &IntersectionVertex::_proc_hook > > | UnprocessedList |
typedef IntersectionList::iterator | ILIter |
typedef IntersectionList::const_iterator | CILIter |
Private Member Functions | |
PathVector | _getResult (bool enter_a, bool enter_b) |
Compute the partial result of a boolean operation by looking at components containing intersections and stitching the correct path portions between them, depending on the truth table of the operation. | |
void | _handleNonintersectingPaths (PathVector &result, unsigned which, bool inside) |
Select intersection-free path components ahead of a boolean operation based on whether they should be a part of that operation's result. | |
void | _prepareArguments () |
Prepare the operands stored in PathIntersectionGraph::_pv by closing all of their constituent paths and removing degenerate segments from them. | |
bool | _prepareIntersectionLists (Coord precision) |
Compute the lists of intersections between the constituent paths of both operands. | |
void | _assignEdgeWindingParities (Coord precision) |
Determine whether path portions between consecutive intersections lie inside or outside of the other path-vector. | |
void | _assignComponentStatusFromDegenerateIntersections () |
Detect the situation where a path is either entirely inside or entirely outside of the other path-vector and set the status flag accordingly. | |
void | _removeDegenerateIntersections () |
Remove intersections that don't change between in/out. | |
void | _verify () |
Verify that all paths contain an even number of intersections and that the intersection graph does not contain leaves (degree one vertices). | |
ILIter | _getNeighbor (ILIter iter) |
Get an iterator to the corresponding crossing on the other path-vector. | |
PathData & | _getPathData (ILIter iter) |
Get the path data for the path containing the intersection given an iterator to the intersection. | |
Private Attributes | |
PathVector | _pv [2] |
Stores the two operand path-vectors, A at _pv[0] and B at _pv[1]. | |
boost::ptr_vector< IntersectionVertex > | _xs |
Stores all crossings between the two shapes. | |
boost::ptr_vector< PathData > | _components [2] |
Stores the crossing information for the operands. | |
UnprocessedList | _ulist |
Temporarily holds all unprocessed during a boolean operation. | |
bool | _graph_valid |
Whether all intersections are regular. | |
std::vector< Point > | _winding_points |
Stores sample points located on paths of the operand path-vectors, between consecutive intersections. | |
Friends | |
std::ostream & | operator<< (std::ostream &, PathIntersectionGraph const &) |
Format the PathIntersectionGraph for output. | |
Intermediate data for computing Boolean operations on paths.
This class implements the Greiner-Hormann clipping algorithm, with improvements inspired by Foster and Overfelt as well as some original contributions.
For the purposes of boolean operations, a shape is defined as a PathVector using the "even-odd" rule, i.e., regions with odd winding are considered part of the shape, whereas regions with even winding are not.
For this reason, the two path-vectors are sometimes called "shapes" or "operands" of the boolean operation. Each path-vector may contain several paths, which are called either "paths" or "components" in the documentation.
Definition at line 63 of file intersection-graph.h.
|
private |
Definition at line 218 of file intersection-graph.h.
|
private |
Definition at line 217 of file intersection-graph.h.
|
private |
Definition at line 188 of file intersection-graph.h.
|
private |
Definition at line 197 of file intersection-graph.h.
|
private |
Enumerator | |
---|---|
INSIDE | |
OUTSIDE | |
BOTH |
Definition at line 157 of file intersection-graph.h.
Geom::PathIntersectionGraph::PathIntersectionGraph | ( | PathVector const & | a, |
PathVector const & | b, | ||
Coord | precision = EPSILON |
||
) |
Construct a path intersection graph for two shapes described via their boundaries.
The boundaries are passed as path-vectors.
a | – the first operand, also referred to as operand A. |
b | – the second operand, also referred to as operand B. |
precision | – precision setting used for intersection calculations. |
Definition at line 50 of file intersection-graph.cpp.
References _assignComponentStatusFromDegenerateIntersections(), _assignEdgeWindingParities(), _graph_valid, _prepareArguments(), _prepareIntersectionLists(), _pv, _removeDegenerateIntersections(), _verify(), and Geom::PathVector::empty().
|
private |
Detect the situation where a path is either entirely inside or entirely outside of the other path-vector and set the status flag accordingly.
Definition at line 183 of file intersection-graph.cpp.
References _components, INSIDE, and OUTSIDE.
Referenced by PathIntersectionGraph().
|
private |
Determine whether path portions between consecutive intersections lie inside or outside of the other path-vector.
< The index of the other operand
Path time interval from the current crossing to the next one
Definition at line 152 of file intersection-graph.cpp.
References _components, _pv, _winding_points, Geom::cyclic_next(), INSIDE, Geom::PathInterval::inside(), OUTSIDE, Geom::PathVector::pointAt(), Geom::PathVector::size(), w, and Geom::PathVector::winding().
Referenced by PathIntersectionGraph().
|
private |
Get an iterator to the corresponding crossing on the other path-vector.
ILIter | – an iterator to a list of intersections in one of the path-vectors. |
Definition at line 495 of file intersection-graph.cpp.
References _components.
Referenced by _getResult(), and _removeDegenerateIntersections().
|
private |
Get the path data for the path containing the intersection given an iterator to the intersection.
Definition at line 503 of file intersection-graph.cpp.
References _components.
Referenced by _removeDegenerateIntersections().
|
private |
Compute the partial result of a boolean operation by looking at components containing intersections and stitching the correct path portions between them, depending on the truth table of the operation.
enter_a | – whether the path portions contained inside operand A should be part of the boundary of the boolean operation's result. |
enter_b | – whether the path portions contained inside operand B should be part of the boundary of the boolean operation's result. |
These two flags completely determine how to resolve the crossings when building the result and therefore encode which boolean operation we are performing. For example, the boolean intersection corresponds to enter_a == true and enter_b == true, as can be seen by looking at a Venn diagram.
< Whether to traverse the current component in the backwards direction.
< Index of the path in its PathVector
Definition at line 363 of file intersection-graph.cpp.
References _components, _getNeighbor(), _pv, _ulist, _xs, Geom::PathVector::clear(), Geom::cyclic_next(), Geom::cyclic_prior(), Geom::PathVector::erase(), Geom::PathInterval::from_direction(), Geom::GEOM_ERR_INTERSECGRAPH, INSIDE, Geom::PathVectorTime::path_index, Geom::PathIntersectionGraph::IntersectionVertex::pos, result, Geom::reverse(), size(), Geom::PathVector::size(), w, and Geom::PathIntersectionGraph::IntersectionVertex::which.
Referenced by getAminusB(), getBminusA(), getIntersection(), and getUnion().
|
private |
Select intersection-free path components ahead of a boolean operation based on whether they should be a part of that operation's result.
Every component that has intersections will be processed by _getResult(). Here we take care of paths that don't have any intersections. They are either completely inside or completely outside the other path-vector.
result | – output parameter to store the selected components. |
which | – which of the two operands to search for intersection-free paths. |
inside | – If set to true, add paths entirely contained inside the other path-vector to the result. If set to false, add paths entirely outside of the other path-vector instead. |
Definition at line 461 of file intersection-graph.cpp.
References _components, _pv, INSIDE, OUTSIDE, result, Geom::PathVector::size(), w, and Geom::PathVector::winding().
Referenced by getAminusB(), getBminusA(), getIntersection(), and getUnion().
|
private |
Prepare the operands stored in PathIntersectionGraph::_pv by closing all of their constituent paths and removing degenerate segments from them.
Definition at line 77 of file intersection-graph.cpp.
References _pv, size(), and w.
Referenced by PathIntersectionGraph().
|
private |
Compute the lists of intersections between the constituent paths of both operands.
precision | – the precision setting for the sweepline algorithm. |
Definition at line 105 of file intersection-graph.cpp.
References _components, _pv, _xs, Geom::PathIntersectionGraph::IntersectionVertex::defective, Geom::PathVector::intersect(), Geom::PathIntersectionGraph::IntersectionVertex::neighbor, Geom::PathIntersectionGraph::IntersectionVertex::next_edge, OUTSIDE, Geom::PathIntersectionGraph::IntersectionVertex::p, Geom::PathVectorTime::path_index, Geom::PathIntersectionGraph::IntersectionVertex::pos, Geom::PathVector::size(), w, and Geom::PathIntersectionGraph::IntersectionVertex::which.
Referenced by PathIntersectionGraph().
|
private |
Remove intersections that don't change between in/out.
In general, a degenerate intersection can happen at a point where two shapes "kiss" (are tangent) but do not cross into each other.
< Whether this is the last remaining crossing.
Definition at line 209 of file intersection-graph.cpp.
References _components, _getNeighbor(), _getPathData(), _graph_valid, Geom::cyclic_next(), Geom::cyclic_prior(), and Geom::PathIntersectionGraph::PathData::xlist.
Referenced by PathIntersectionGraph().
|
private |
Verify that all paths contain an even number of intersections and that the intersection graph does not contain leaves (degree one vertices).
Definition at line 248 of file intersection-graph.cpp.
References _components, and Geom::cyclic_next().
Referenced by PathIntersectionGraph().
void Geom::PathIntersectionGraph::fragments | ( | PathVector & | in, |
PathVector & | out | ||
) | const |
Definition at line 328 of file intersection-graph.cpp.
References _components, _pv, Geom::cyclic_next(), INSIDE, Geom::PathVector::push_back(), Geom::Path::setStitching(), Geom::PathVector::size(), and w.
PathVector Geom::PathIntersectionGraph::getAminusB | ( | ) |
Get the difference of the shapes, A ∖ B.
A point belongs to the difference if and only if it belongs to A but not to B.
Definition at line 280 of file intersection-graph.cpp.
References _getResult(), _handleNonintersectingPaths(), and result.
PathVector Geom::PathIntersectionGraph::getBminusA | ( | ) |
Get the opposite difference of the shapes, B ∖ A.
A point belongs to the difference if and only if it belongs to B but not to A.
Definition at line 288 of file intersection-graph.cpp.
References _getResult(), _handleNonintersectingPaths(), and result.
PathVector Geom::PathIntersectionGraph::getIntersection | ( | ) |
Get the intersection of the shapes, A ∩ B.
A point belongs to the intersection if and only if it belongs to both shapes.
Definition at line 272 of file intersection-graph.cpp.
References _getResult(), _handleNonintersectingPaths(), and result.
PathVector Geom::PathIntersectionGraph::getUnion | ( | ) |
Get the union of the shapes, A ∪ B.
A point belongs to the union if and only if it belongs to at least one of the operands.
Definition at line 264 of file intersection-graph.cpp.
References _getResult(), _handleNonintersectingPaths(), and result.
Referenced by TEST_F(), TEST_F(), TEST_F(), TEST_F(), TEST_F(), and TEST_F().
PathVector Geom::PathIntersectionGraph::getXOR | ( | ) |
Get the symmetric difference of the shapes, A ∆ B.
A point belongs to the symmetric difference if and only if it belongs to one of the two shapes A or B, but not both. This is equivalent to the logical XOR operation: the elements of A ∆ B are points which are in A XOR in B.
Definition at line 296 of file intersection-graph.cpp.
References Geom::PathVector::begin(), Geom::PathVector::end(), getAminusB(), and getBminusA().
std::vector< Point > Geom::PathIntersectionGraph::intersectionPoints | ( | bool | defective = false | ) | const |
Get the geometric points where the two path-vectors intersect.
Degenerate intersection points, where the shapes merely "kiss", are not retured.
defective | – whether to return only the defective crossings or only the true crossings. |
Definition at line 314 of file intersection-graph.cpp.
References _components, and result.
Referenced by main().
std::size_t Geom::PathIntersectionGraph::size | ( | ) | const |
Returns the number of intersections used when computing Boolean operations.
Definition at line 305 of file intersection-graph.cpp.
References _components, result, and Geom::PathVector::size().
Referenced by _getResult(), and _prepareArguments().
|
inline |
Definition at line 154 of file intersection-graph.h.
References _graph_valid.
|
inline |
Get the geometric points located on path portions between consecutive intersections.
These points were used for the winding number calculations which determined which path portions lie inside the other shape and which lie outside.
Definition at line 147 of file intersection-graph.h.
References _winding_points.
|
friend |
Format the PathIntersectionGraph for output.
Definition at line 509 of file intersection-graph.cpp.
|
private |
Stores the crossing information for the operands.
Definition at line 234 of file intersection-graph.h.
Referenced by _assignComponentStatusFromDegenerateIntersections(), _assignEdgeWindingParities(), _getNeighbor(), _getPathData(), _getResult(), _handleNonintersectingPaths(), _prepareIntersectionLists(), _removeDegenerateIntersections(), _verify(), fragments(), intersectionPoints(), and size().
|
private |
Whether all intersections are regular.
Definition at line 236 of file intersection-graph.h.
Referenced by _removeDegenerateIntersections(), PathIntersectionGraph(), and valid().
|
private |
Stores the two operand path-vectors, A at _pv[0] and B at _pv[1].
Definition at line 232 of file intersection-graph.h.
Referenced by _assignEdgeWindingParities(), _getResult(), _handleNonintersectingPaths(), _prepareArguments(), _prepareIntersectionLists(), fragments(), and PathIntersectionGraph().
|
private |
Temporarily holds all unprocessed during a boolean operation.
Definition at line 235 of file intersection-graph.h.
Referenced by _getResult().
|
private |
Stores sample points located on paths of the operand path-vectors, between consecutive intersections.
Definition at line 240 of file intersection-graph.h.
Referenced by _assignEdgeWindingParities(), and windingPoints().
|
private |
Stores all crossings between the two shapes.
Definition at line 233 of file intersection-graph.h.
Referenced by _getResult(), and _prepareIntersectionLists().