Reducing the dependency on CubicSuperPath
What does the merge request do?
CubicSuperPath is a crutch that allows extension authors to think little, but get imperfect results in return (e.g. ambiguity of closed subpaths, approximation with varying / inconsistent number of subpaths for arcs, ill-defined gradient for lines converted to Cubic, etc.) In this MR I add a new API to reduce our dependency on it, and still don't offload much of the lowlevel work to userland code. Three extensions have been ported to show this (plus XAML import, which requires a separate MR).
- The first commit splits the
path.py
file into a module with unchanged external API. - The second commit adds member functions to PathCommand to compute gradient, normal, curvature, point-from-t, t-from-point, splitting, length. The numerical algorithms are partially taken from bezier.py, partially from
svgpathtools
(marked in the code). The API will be extended in the future (e.g.PathCommand.intersects()
). - The other three commits port the Measure extension (the Length part of it), the AddNodes extension and the Convert2Dashes extension, fixing various bugs along the way.
Fixes partially #333, closes #489 (closed)
Implementation notes
Here's a list of the remaining extensions to upgrade (not part of this MR):
Easy to upgrade
Plugin | Superpath | Bezier | Can be expressed without to_curves()
|
Missing functionality |
---|---|---|---|---|
distribute_along_path | x | x | yes | |
jitternodes | x | ? | what to do with arcs? Needs some usability testing | |
ink2canvas | x | yes | Arcs are differently parametrized in HTML5 | |
path_mesh_m2p | x | x | ||
to_absolute | x | x | ||
longshadow | x | x | probably | extension is somewhat broken, I’ll try to repair it |
A bit more difficult, but doable and worth it
Plugin | Superpath | Bezier | Can be expressed without to_curves()
|
Missing functionality |
---|---|---|---|---|
measure | x | x | yes | COG and area for arcs |
dxf_outlines | x | x | yes | properly implemented flatten for all curve types |
dxf12_outlines | x | x | yes | properly implemented flatten for all curve types |
flatten | x | x | yes | properly implemented flatten for all curve types ( will help #163, which propagates to all the others in the list) |
hpgl_encoder | x | x | yes | properly implemented flatten for all curve types |
to_curves()
Fundamentally impossible to express without Plugin | Superpath | Bezier | Can be expressed without to_curves()
|
Missing functionality |
---|---|---|---|---|
path_mesh_p2m | x | no | Meshgradient Patches only support cubic beziers | |
interpolate | x | x | ? | Probably best left alone (interoplation between arc and bezier, anyone?) |
Outside of my expertise
Plugin | Superpath | Bezier | Can be expressed without to_curves()
|
Missing functionality |
---|---|---|---|---|
print_win32 | x | yes | need to convert Arc parameters + World transform. Probably not worth the effort. | |
gcodetools | x | x | no | I’m not going to touch that. There’s about 1000 LOC partially-obsolete path mathematics in there. Some of it might be useful, probably not. |
Diffeomorphisms
They always were incorrect on superpaths (particularly lines) as well → commonly it was recommended to „add nodes“ first, but it would be interesting (as in: a master thesis in computational geometry) to implement them properly.
Plugin | Superpath | Bezier | Can be expressed without to_curves()
|
Missing functionality |
---|---|---|---|---|
path_envelope | x | ? | Should be doable. Perspective transform of a bezier is a rational bezier, which can then be approximated again. Perspective transform of an arc is an arc (?) | |
perspective | x | ? | Same | |
rubberstretch | x | ? | general diffeomorphisms where straight lines become curved are probably out of range for a proper implementation | |
patternalongpath | x | ? | Same | |
twirl | x | ? | Same |
Summary for release notes
- Improve the API for working with path segments, such as: length, split at length, gradient/normal, curvature. Accessible through
path.proxy_iterator()
, the new methods facilitate a lot of whatbezier.py
is traditionally used for, but without the loss of information that inherently happens when converting to CubicSuperPath. - The
Add Nodes
extension now gives symmetric results on arcs, and also splits arcs into smaller arcs. - The
Measure
tool (Length measurement) is now more precise for paths containing arcs, e.g. an arc with radius 50mm now has its length reported as314.1593
(correct value: 314.15926...) instead of314.1602
- The
Convert to dashes
extension is now also more precise for arcs and furthermore doesn't visually change the output for closed subpaths where a dash crosses over the closing position.
Checklist
-
Add unit tests (if applicable) -
Changes to inkex/
are well documented -
Clean merge request history