-
Notifications
You must be signed in to change notification settings - Fork 32
Path operations
The operations described on this page relate specifically to path objects. See also Transforming a path and Live Path Effects.
The following method on all shape objects is the Simple Inkscape Scripting equivalent of Inkscape's Path → Object to Path menu option:
Method: to_path(all_curves)
all_curves
is an optional Boolean that defaults to False
. When True
, the generated path will comprise exclusively cubic Bézier curves as opposed to lines, arcs, and quadratic Bézier curves. Move and closepath commands will still be present.
Example:
circle((100, 100), 25, stroke='brown', stroke_width=5)
The above is an ordinary circle. The generated SVG code represents it with a <circle>
:
<circle
cx="100" cy="100" r="25"
style="stroke:brown;fill:none;stroke-width:5" />
We can convert the circle to a path with the to_path
method:
Example:
circle((100, 100), 25, stroke='brown', stroke_width=5).to_path()
Now, the circle is represented with an SVG <path>
instead of an SVG <circle>
:
<path
d="M 100.0 75.0 a 25.0 25.0 0 1 0 25.0 25.0 a 25.0 25.0 0 0 0 -25.0 -25.0 z"
style="stroke:brown;fill:none;stroke-width:5" id="simp-ink-scr-173264-2" />
Note the use of the a
(relative-movement elliptical arc curve) path command in the preceding SVG. Finally, we pass to_path
its optional all_curves
argument:
Example:
circle((100, 100), 25, stroke='brown', stroke_width=5).to_path(all_curves=True)
This time, the generated SVG <path>
comprises primarily C
(cubic Bézier curve) path commands:
<path
d="M 100 75 C 89.8884 75 80.7725 81.0911 76.903 90.4329 C 73.0335 99.7748 75.1724 110.528 82.3223 117.678 C 89.4723 124.828 100.225 126.967 109.567 123.097 C 118.909 119.227 125 110.112 125 100 C 125 93.3696 122.366 87.0107 117.678 82.3223 C 112.989 77.6339 106.63 75 100 75 Z"
style="stroke:brown;fill:none;stroke-width:5" />
At the time of this writing (Inkscape 1.3.2 and inkex 1.3.1), applying to_path
to a text object is extremely slow. (It requires spawning two child copies of Inkscape.) Applying to_path
to a text object does not work correctly in versions of Inkscape prior to 1.2.
Paths can be combined by invoking a path's append
method:
Method: append(obj)
In that call, obj
is either another path object or a list of path objects. Once a path object is appended it is removed from the list of objects to render in the image. append
returns the modified path object.
append
is most commonly used with the even-odd fill rule to cut holes in objects.
Example:
c1 = circle((50, 50), 50, fill='#005500', fill_rule='evenodd').to_path()
c2 = circle((100, 50), 50).to_path()
c1.append(c2)
An alternative to using the even-odd fill rule is to draw outer paths in one direction (e.g., clockwise) and inner paths (holes) in the opposite direction (e.g., counterclockwise). If a path was drawn the wrong direction it can be reversed with
Method: reverse()
which reverses the path represented by a path object. reverse
returns the modified path object.
Example:
box = rect((0, 0), (200, 100), fill='#d4aa00').to_path()
hole1 = rect((25, 25), (75, 75)).to_path()
hole2 = rect((125, 25), (175, 75)).to_path()
box.append([hole1.reverse(), hole2.reverse()])
Simple Inkscape Scripting can automate the application of Boolean path operations. These appear in the Inkscape GUI as Path → Union, Path → Intersection, Path → Exclusion, etc.
Function: apply_path_operation(op, [obj, …])
where op
is the operation to perform and [obj, …]
is a list of path objects to which to apply the operation. apply_path_operation
returns a list of objects that were created or modified by the operation.
Caveat 1: The original objects in the [obj, …])
list are invalidated by apply_path_operation
and subsequently should not be used.
Caveat 2: apply_path_operation
is implemented by spawning a child copy of Inkscape that performs the requested path operations. The function therefore can be rather slow to execute.
The set of available path operations can be determined by running
inkscape --action-list
from the command line and searching for actions that begin with path-
. Remove the path-
and use the rest of the string as the op
argument to apply_path_operation
. At the time of this writing, the following operations are available:
break-apart
combine
cut
difference
division
exclusion
fill-between-paths
fracture
intersection
simplify
split
union
Caveat 3: Pre-1.2 versions of Inkscape require verbs rather than actions for these operations. Run inkscape --verb-list
and search for verbs that begin with Selection
. Remove the Selection
and use the rest of the string as the operation name. For example, Union
, Intersect
, and SymDiff
are the pre-1.2 equivalents of union
, intersection
, and exclusion
.
For example, consider a pair of overlapping circles:
Example:
c1 = circle((60, 60), 50, fill='magenta', stroke_width=4).to_path()
c2 = circle((90, 60), 50, fill='cyan', stroke_width=4).to_path()
In the following code, apply_path_operation
is used to subtract the cyan circle from the magenta circle. The result is a magenta crescent. The code then recolors the crescent yellow.
Example:
c1 = circle((60, 60), 50, fill='magenta', stroke_width=4).to_path()
c2 = circle((90, 60), 50, fill='cyan', stroke_width=4).to_path()
objs = apply_path_operation('difference', [c1, c2])
for o in objs:
o.style(fill='yellow')
As indicated by Caveat 1 above, the original objects, c1
and c2
, are invalid after apply_path_operation
completes and should no longer be used.
For convenience, Simple Inkscape Scripting provides operator overloads for certain path operations:
Operation | Operator | Return type |
---|---|---|
Union | + |
Path |
Difference | - |
Path |
Intersection | * |
Path |
Exclusion | ^ |
Path |
Division | / |
List of paths |
Cut path | // |
List of paths |
These operators correspond to the keyboard shortcuts in Inkscape's Path menu:
Each operator takes two paths as arguments and performs the following steps:
- Move the path specified by the right argument into the same group as the path specified by the left argument—or to the top level if the left path does not lie within a group.
- Raise the right path to the top of the Z-order.
- Perform the specified path operation.
- Return either a single path or a list of paths, as appropriate.
(The first two steps ensure that the outcome matches the corresponding path operation performed manually in the Inkscape GUI.)
Because the overloaded operators are implemented in terms of apply_path_operation
, the same caveats apply to them. Furthermore, the operators fail silently when used in pre-1.2 versions of Inkscape.
To demonstrate overloaded-operator usage, the yellow-crescent example above can be simplified to
Example:
c1 = circle((60, 60), 50, fill='magenta', stroke_width=4).to_path()
c2 = circle((90, 60), 50, fill='cyan', stroke_width=4).to_path()
moon = c1 - c2
moon.style(fill='yellow')