meerk40t / svgelements

SVG Parsing for Elements, Paths, and other SVG Objects.
MIT License
132 stars 29 forks source link

Path fixup methods #136

Closed Sophist-UK closed 2 years ago

Sophist-UK commented 2 years ago
  1. A method to close almost closed subpaths.
  2. (TBA) A method to join coincident subpaths e.g. if they could be a single subpath but instead are separate.
  3. (TBA) A method to convert long-thin closed subpaths (that look like strokes) to PathSegments.

In addition, the following additional functionality has been added to Subpath to support the fixup methods:

tatarize commented 2 years ago

How is a subpath less than another subpath? Occurring earlier in the backing path? Fewer segments? Smaller area?

Modifying subpaths invalidates them. They are intended to be temporary windows into the path. It seems like these bits of functionality should be done on the Path object itself. Likely placed near the function direct_close() which has some limited utility to modify a path in a minor way to ensure some required constraints. There'd be some ability to add things like line_merge (https://vpype.readthedocs.io/en/stable/reference.html#linemerge) within certain tolerances or linesimplify (https://vpype.readthedocs.io/en/stable/reference.html#linesimplify), or even a linesort function directly into the code (minimize distance between subpaths). There are places where functions that alter the Path as a whole go, is typically in the Path code like approximate_arcs_with_cubics(). Though there are other things like #129 or #118 which seem a bit more interesting changes and somehow directly relevant. After all #118 would allow meerk40t/meerk40t#1 to be done.

Sophist-UK commented 2 years ago

A subpath is less than another subpath if it is an earlier subpath. This seemed to me to be intuitive because you can get a subpath by index, but apparently it isn't so intuitive. But if you don't like this I can code the sort key another way.

Closing almost closed subpaths is a Path method rather than a Subpath method. It does operate on the Path object - but it is the subpaths that need to be closed so it uses the Subpath objects because that is what they are for. I do appreciate that Subpaths get invalidated (unless you update them as you update Path). And you are right that my current code does not keep Subpaths in step (but there is no reason why I can't do that). It might be useful to have an invalidation flag - so you have an internal counter for segment changes on the Path object, and you store that counter against a Subpath object when it is created, and you can then check whether the Subpath is invalid or not. Alternatively, we could maintain a list of Subpaths that exist for a Path and update them whenever a Segment change is made so that Subpath's automatically stay in step (which might be rather neat).

I will take a look at vpype linemerge and see how I can reuse this (and improve if possible). I will also use the terminology for the close almost closed code.

vpype linesimplify is akin to Inkscape's Path Simplify. I don't see the relevance to MK, and is not on my list to code.