abey79 / vsvg

Fast and portable tools for plotter users
http://whisk.rs
MIT License
107 stars 12 forks source link

Elementary path structure #1

Open abey79 opened 1 year ago

abey79 commented 1 year ago

vpype uses one-dimensional Numpy array of complex as basic path type. This means that anything curvy must be linearised and transformed into a polyline. This is why the read command has a -q/--quantization option to control the accuracy of this transformation. One design goal of vpype 2 is to no longer degrade curved paths into polylines.

Another design goal is to support compound paths, i.e. paths made of several, possibly-closing sub-paths. This is used to represent shapes with holes. Proper support for shapes with holes is a strong prerequisite towards a robust hatch filling feature for vpype.

One approach is to support all of SVG primitives: elliptic arcs (including full circles and ellipses), quadratic Beziers, and cubic Bézier. The drawback is the added complexity of dealing with so many primitives. Another approach would be to support only polylines and cubic Bézier. They provide an exact approximation of quadratic bezier and a good approximation of arcs, while generally be nice to work with.

As it turns out, the usvg crate offers facilities to normalise any SVG primitive into paths made of polylines and cubic Bézier only. Its output relies on the BezPath structure from the kurbo crate, which offers a dual representation: draw commands (MoveTo, LineTo, CurveTo, ClosePath) and segments (LineSegment, BezierSegment). Each representation has advantages in different circumstances. Conveniently, BezPath also supports compound paths.

Consequently, my current plan is to use krubo::BezPath as fundamental structure for path representation, and build a Path/Layer/Document hierarchy around it.

abey79 commented 1 year ago

On points

The Point primitive is not included in the SVG spec, but vpype should probably include it. Exporters should (optionally?) turn them into tiny circles with pen-width diameter, like vsketch does.

BezPath([MoveTo(px, py), LineTo(px, py)]) with some API coating could be used as storage.

The added benefit would be transparent handling of single-vertex, degraded lines. They would appear as points, either as expected or conspicuously highlighting bugs or misuse by end user.

Edit: see #10