Giter Site home page Giter Site logo

abey79 / vpype Goto Github PK

View Code? Open in Web Editor NEW
654.0 7.0 58.0 17.01 MB

The Swiss-Army-knife command-line tool for plotter vector graphics.

Home Page: https://vpype.readthedocs.io/

License: MIT License

Python 95.54% Batchfile 0.10% NSIS 0.97% GLSL 3.25% Just 0.14%
generative-art pen-plotters svg vector-graphics python3 python-3 plotters hacktoberfest hacktoberfest2020 vpype

vpype's Introduction

banner

vpype

PyPI python Downloads license Test codecov Sonarcloud Status Documentation Status Code style: Black

vpype is the Swiss-Army-knife command-line tool for plotter vector graphics.

Contents

What vpype is?

vpype is the Swiss-Army-knife command-line tool for plotter vector graphics. Here is what it can do:

  • layout existing vector files with precise control on position, scale and page format;
  • optimize existing SVG files for faster and cleaner plots;
  • create HPGL output for vintage plotters;
  • create generative artwork from scratch through built-in commands or plug-ins;
  • create, modify and process multi-layer vector files for multi-colour plots;
  • and much more...

vpype is highly extensible through plug-ins that can greatly extend its capabilities. For example, plug-ins already exists for plotting pixel art, half-toning with hatches, and much more. See below for a list of existing plug-ins.

vpype is also a well documented Python library useful to create generative art and tools for plotters. It includes data structures, utility and I/O functions, as well as a hardware-accelerated flexible viewer for vector graphics. For example, the plotter generative art environment vsketch is built upon vpype.

Check the documentation for a more thorough introduction to vpype.

How does it work?

vpype works by building so-called pipelines of commands, where each command's output is fed to the next command's input. Some commands load geometries into the pipeline (e.g. the read command which loads geometries from a SVG file). Other commands modify these geometries, e.g. by cropping them (crop) or reordering them to minimize pen-up travels (linesort). Finally, some other commands just read the geometries in the pipeline for display purposes (show) or output to file (write).

Pipeline are defined using the vpype's CLI (command-line interface) in a terminal by typing vpype followed by the list of commands, each with their optional parameters and their arguments:

command line

This pipeline uses five commands (in bold):

  • read loads geometries from a SVG file.
  • linemerge merges paths whose extremities are close to each other (within the provided tolerance).
  • linesort reorder paths such as to minimise the pen-up travel.
  • crop, well, crops.
  • write export the resulting geometries to a SVG file.

There are many more commands available in vpype, see the overview below.

Some commands have arguments, which are always required (in italic). For example, a file path must be provided to the read command and dimensions must be provided to the crop commands. A command may also have options which are, well, optional. In this example, --page-size a4 means that the write command will generate a A4-sized SVG (otherwise it would have the same size as in.svg). Likewise, because --center is used, the write command will center geometries on the page before saving the SVG (otherwise the geometries would have been left at their original location).

Examples

Note: The following examples are laid out over multiple lines using end-of-line escaping (\). This is done to highlight the various commands of which the pipeline is made and would typically not be done in real-world use.

Load an SVG file, scale it to a specific size, and export it centered on an A4-sized, ready-to-plot SVG file:

$ vpype \
  read input.svg \
  layout --fit-to-margins 2cm a4 \
  write output.svg

Optimize paths to reduce plotting time (merge connected lines, sort them to minimize pen-up distance, randomize closed paths' seam, and reduce the number of nodes):

$ vpype \
  read input.svg \
  linemerge --tolerance 0.1mm \
  linesort \
  reloop \
  linesimplify \
  write output.svg

Load a SVG and display it in vpype's viewer, which enable close inspection of the layer and path structure):

$ vpype \
  read input.svg \
  show

Load several SVG files and save them as a single, multi-layer SVG file (e.g. for multicolored drawings):

$ vpype \
  forfile "*.svg" \
    read --layer %_i% %_path% \
  end \
  write output.svg

Export a SVG to HPGL for vintage plotters:

$ vpype \
  read input.svg \
  layout --fit-to-margins 2cm --landscape a4 \
  write --device hp7475a output.hpgl

Draw the layer name on a SVG (this example uses property substitution):

$ vpype \
    read input.svg \
    text --layer 1 "{vp_name}" \
    write output.svg

Merge multiple SVG files in a grid layout (this example uses expression substitution):

$ vpype \
    eval "files=glob('*.svg')" \
    eval "cols=3; rows=ceil(len(files)/cols)" \
    grid -o 10cm 10cm "%cols%" "%rows%" \
        read --no-fail "%files[_i] if _i < len(files) else ''%" \
        layout -m 0.5cm 10x10cm \
    end \
    write combined_on_a_grid.svg

An interactive version of the previous example is available in examples/grid.vpy. It makes use of input() expressions to ask parameters from the user:

$ vpype -I examples/grid.vpy
Files [*.svg]?
Number of columns [3]? 4
Column width [10cm]?
Row height [10cm]? 15cm
Margin [0.5cm]?
Output path [output.svg]?

Split a SVG into one file per layer:

$ vpype \
    read input.svg \
    forlayer \
      write "output_%_name or _lid%.svg" \
    end

More examples and recipes are available in the cookbook.

What vpype isn't?

vpype caters to plotter generative art and does not aim to be a general purpose (think Illustrator/InkScape) vector graphic tools. One of the main reason for this is the fact vpype converts everything curvy (circles, bezier curves, etc.) to lines made of small segments. vpype does import metadata such stroke and fill color, stroke width, etc., it only makes partial use of them and does not aim to maintain a full consistency with the SVG specification. These design choices make vpype's rich feature set possible, but limits its use for, e.g., printed media.

Installation

Detailed installation instructions are available in the latest documentation.

TL;DR:

  • Python 3.12 is recommended, but vpype is also compatible with Python 3.10 and 3.11.
  • vpype is published on the Python Package Index and can be installed using pipx:
    pipx install "vpype[all]"
  • A Windows installer is available here, but plug-ins cannot be installed when using this method).
  • A CLI-only version of vpype can be installed using the following command:
    pipx install vpype
    This version does not include the show command but does not require some of the dependencies which are more difficult or impossible to install on some platforms (such as matplotlib, PySide6, and ModernGL).

Documentation

The vpype CLI includes its own, detailed documentation:

vpype --help          # general help and command list
vpype COMMAND --help  # help for a specific command

In addition, the online documentation provides extensive background information on the fundamentals behind vpype, a cookbook covering most common tasks, the vpype API documentation, and much more.

Feature overview

General

  • Easy to use CLI interface with integrated help (vpype --helpand vpype COMMAND --help) and support for arbitrary units (e.g. vpype read input.svg translate 3cm 2in).
  • First-class multi-layer support with global or per-layer processing (e.g. vpype COMMANDNAME --layer 1,3) and optionally-probabilistic layer edition commands (lmove, lcopy, ldelete, lswap, lreverse).
  • Support for per-layer and global properties, which acts as metadata and is used by multiple commands and plug-ins.
  • Support for property and expression substitution in CLI user input.
  • Support for complex, per-layer processing (perlayer).
  • Powerful hardware-accelerated display command with adjustable units, optional per-line coloring, optional pen-up trajectories display and per-layer visibility control (show).
  • Geometry statistics extraction (stat).
  • Support for command history recording (vpype -H [...])
  • Support for RNG seed configuration for generative plug-ins (vpype -s 37 [...]).

Input/Output

  • Single- and multi-layer SVG input with adjustable precision, parallel processing for large SVGs, and supports percent or missing width/height (read).
  • Support for SVG output with fine layout control (page size and orientation, centering), layer support with custom layer names, optional display of pen-up trajectories, various option for coloring (write).
  • Support for HPGL output config-based generation of HPGL code with fine layout control (page size and orientation, centering).
  • Support for pattern-based file collection processing (forfile).

Layout and transforms

  • Easy and flexible layout command for centring and fitting to margin with selectable le horizontal and vertical alignment (layout).
  • Page rotation command (pagerotate).
  • Powerful transform commands for scaling, translating, skewing and rotating geometries (scale, translate, skew, rotate).
  • Support for scaling and cropping to arbitrary dimensions (scaleto, crop).
  • Support for trimming geometries by an arbitrary amount (trim).
  • Arbitrary page size definition (pagesize).

Metadata

Plotting optimization

  • Line merging with optional path reversal and configurable merging threshold (linemerge).
  • Line sorting with optional path reversal (linesort).
  • Line simplification with adjustable accuracy (linesimplify).
  • Closed paths' seam location randomization, to reduce the visibility of pen-up/pen-down artifacts (reloop).
  • Support for generating multiple passes on each line (multipass).

Filters

  • Support for filtering by line lengths or closed-ness (filter).
  • Squiggle filter for shaky-hand or liquid-like styling (squiggles)
  • Support for splitting all lines to their constituent segments (splitall).
  • Support for reversing order of paths within their layers (reverse).
  • Support for splitting layers by drawing distance (splitdist)

Generation

  • Generation of arbitrary primitives including lines, rectangles, circles, ellipses and arcs (line, rect, circle, ellipse, arc).
  • Generation of text using bundled Hershey fonts (text)
  • Generation of grid-like layouts (grid).
  • Generation of a frame around the geometries (frame).
  • Generation of random lines for debug/learning purposes (random)

Extensibility and API

Plug-ins

Here is a list of known vpype plug-ins (please make a pull request if yours is missing):

Contributing

Contributions to this project are welcome and do not necessarily require software development skills! Check the Contributing section of the documentation for more information.

License

This project is licensed under the MIT License - see the LICENSE file for details.

vpype's People

Contributors

abey79 avatar blinsay avatar dependabot[bot] avatar duncangeere avatar f4nu avatar gatesphere avatar ithinkido avatar jakebeamish avatar jamescarruthers avatar jimmykl avatar jonathanpberger avatar loicgoulefert avatar pealco avatar pepijndevos avatar tatarize avatar theomega avatar vytis avatar zoso95 avatar zxsq-cc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

vpype's Issues

Include reading and writing of Embroidery files.

I write the premier embroidery IO library for python. pyembroidery which basically is also entirely based on lines (since thread only goes straight). And it wouldn't be too hard to make vpype support for most embroidery formats. This would be pretty big for embroidery too. The API should be fairly reasonable, lists out the formats that can be read and written to and lets you load them up and get the lines they make.

https://github.com/EmbroidePy/pyembroidery

Embroidery formats are almost entirely commands sent to a xy plotter with a sewing machine head and are very similar to a pen plotter (though the hoop moves rather than the pen head). These formats are old and often limited (computerized embroidery basically predates computers). Threads tend to have colors, but without these random colors will be assigned. pyembroidery would take care of most oddities for you, like how jump stitches work and the max line lengths, cuts. Etc.

It would basically take hooking it up. Pyembroidery has no dependencies.

pattern = EmbPattern("filename.dst")
for block, thread in pattern.get_as_stitchblock():
     list_of_xy_values(block)  # Ignore the 3rd command value.

pattern.stitches will have all the the stitch list of 3 value lists. [X, Y, Stitch]. Would give you a list of tuples of (stitches, threads). For the stitch blocks, only the x ([0]) and y ([1]) matter since all the commands([2]) would entirely be STITCH.

pattern = EmbPattern()
for block in your_list_of_xy_values:
     pattern.add_block(block)
pattern.write("filename.pes")

optimization by --linemerge

When using --linemerge to connect multiple line segments to one single line, the output still contains the old line nodes, and the result is one line, but with multiple nodes. when plotting a line like this the plotter slows down and speed up for each node and the result is a kind of 'ghost' line in the plot. Is it possible to output a mergerd line as a single line between a start and end node, creating the longest possibe single straight line?
image
image
linetest.zip

Preserve layer names

At the moment vpype preserves the layer structure which is a great feature. I use Inkscape plotter extension for sending plots to an HP plotter. I really appreciate the ability to send multi-pen plots with this extension. To use this feature it is necessary to define the layers with names like pen1, pen2.....etc.
This is a super useful feature for me that means I can set up multi-colour plots, hit send and I do not have to worry about changing pens mid plot.
I am very grateful for the line sort and line merge feature in vpype for optimising paths. The difference is huge on many plots. My issue is that when I import a svg into vpype that I have set up in the correct pen layers for optimising then the layer structure is preserved , but the layers are renamed as 1, 2 , 3,...โ€ฆ etc instead of remaining as pen1, pen2, pen3.....etc

image

Confusing behaviour of `scale` parameters

I am trying out vpype and hit a problem early on. At first I thought it's a bug:

vpype read foo.svg scale 10cm 10cm write scaled.svg

However I should have actually used --to to achieve what I want:

vpype read foo.svg scale --to 10cm 10cm write scaled.svg

The resulting file initially was huge as the factor that it was scaled with is actually centimetres converted to px:

INFO:root:executing global processor `scale` (kwargs: {'scale': (377.95275590551176, 377.95275590551176), 'layer': -2, 'absolute': False, 'keep_proportions': False, 'origin_coords': ()})

There could be few things that would have helped me to see what goes wrong:

  1. scale would error out when passed size with units.
  2. scale would default to scale --to when passed size with units.
  3. It could be two separate commands.

SVG export: closed path should be detected and exported with a "closepath" command

From SVG's doc:

A closed subpath differs in behavior from an open subpath whose final coordinate is the initial point of the subpath. The first and last path segments of an open subpath will not be joined, even when the final coordinate of the last path segment is the initial point of the subpath. This will result in the first and last path segments being capped using the current value of stroke-linecap rather than joined using the current value of stroke-linejoin.

"closepath" command => z

-- help command not working

Just tried to look up something for the multipass feature with -- help and it looks like it is no longer working, even vpype -- help general seems down.

Allow arbitrary paper size in `write`

Easy way: add a custom option --page-format and a --paper-size parameter.

Additionally, --page-format could be made to automatically recognise AxB pattern for inch-sized paper.

cc @jbum

Split input paths option

Hi,

Really enjoying using vpype - it's almost perfect for my usecase. Thanks for working on it. The only thing it's missing is the ability to split apart compound SVG paths like the following:

    <path
       d="M863.0296385949076 41.86503242499518 L862.9623748837308 41.521120608316096,862.9623748837308 41.521120608316096,862.8971895200468 41.25611307188438,862.8971895200468 41.25611307188438,862.7908929844685 40.93345873920916,862.7908929844685 40.93345873920916,862.7095183876838 40.891964713829545,862.7095183876838 40.891964713829545,862.5895211666606 40.769597447420004,862.5895211666606 40.769597447420004,862.5164508442873 40.62141491741736,862.5164508442873 40.62141491741736,862.4923675369382 40.420106908523685,862.4923675369382 40.420106908523685,862.5280731822396 40.2623348102656,862.5280731822396 40.2623348102656,862.6102864104688 40.12071548287142,862.6102864104688 40.12071548287142,862.7352607268034 40.0074273134035,862.7352607268034 40.0074273134035,862.8324143565258 39.96596975026054,862.8324143565258 39.96596975026054,862.9071528262286 39.93410175537325,862.9071528262286 39.93410175537325,863.0906672636063 39.9234912444897,863.0906672636063 39.9234912444897,863.2766793641988 39.97960662679129,863.2766793641988 39.97960662679129,863.3198597680265 40.0134800446979,863.3198597680265 40.0134800446979,863.2833154912806 39.75303028785544,863.2833154912806 39.75303028785544,863.2368170239122 39.39952890292069,863.2368170239122 39.39952890292069,863.1458893211085 38.9134872875336,863.1458893211085 38.9134872875336,863.055371818468 39.39497112333156,863.055371818468 39.39497112333156,862.9810526644872 39.613452845717234"
       id="path13" />
    <path
       d="M863.1458893211085 38.9134872875336 L863.1280319406782 36.573924331066564,863.1280319406782 36.573924331066564,863.0744780305056 35.94783126446387,863.0744780305056 35.94783126446387,862.8506819371191 35.37533768582962,862.8506819371191 35.37533768582962,862.5197689078283 34.94646885760864,862.5197689078283 34.94646885760864,862.1622840235327 34.63340409318897,862.1622840235327 34.63340409318897,861.6789953070174 34.39165946378033,861.6789953070174 34.39165946378033,861.0441604191626 34.239429625502716,861.0441604191626 34.239429625502716,860.4894512964853 34.239429625502716,860.4894512964853 34.239429625502716,859.4352642241919 34.22579274897197,859.4352642241919 34.22579274897197,859.3277279725654 40.401912252403804,859.3277279725654 40.401912252403804,860.4280033120643 40.420617379837736,860.4280033120643 40.420617379837736,861.8479795430648 40.43378024729109"
       id="path15" />
    <path
       d="M859.3277279725654 40.401912252403804 L857.3887573797482 40.36953378620246,857.3887573797482 40.36953378620246,857.2999080244373 43.88905118494593,857.2999080244373 43.88905118494593,855.819313324901 43.84908857350825,855.819313324901 43.84908857350825,855.655306184165 43.89156707927919,855.655306184165 43.89156707927919,855.5569037228353 43.96846593650734,855.5569037228353 43.96846593650734,855.4456300919456 43.88296199141486,855.4456300919456 43.88296199141486,855.2812127510466 43.8384780626247,855.2812127510466 43.8384780626247,854.7302501231915 43.82684660911316"
       id="path17" />

Splitting these apart into many single-segment <path> elements can, for certain types of drawing, allow for significantly more optimal draw paths. Currently, vpype doesn't seem to split these apart, and instead just re-orders them amongst themselves.

svgsort does have an option for this:
https://github.com/inconvergent/svgsort/blob/master/svgsort/__init__.py#L86
For now, I've been using this as a pre-processor before vpype, and it's helped a lot for my drawings. Having this as a layer in vpype would be super cool!

Classify lines by colour into layers (`read`)

It would be very useful to be able to sort lines by a range of colours and/or brightness into layers. My end goal would then be to use the sorted layers to apply different hatching to the shapes so that the overlaid shapes create nice shading effects. At the moment it I have not been able to find a way of selecting lines or objects with similar colour / brightness thresholds so that the number of layers generated could be controlled to match the number of pens or effects desired In my case the shapes are separate closed polygons, but are layered on top of each other to achieve a final colour / shade

Updated:
block_test.zip

Linesort breaking straight lines

When using linesort on a drawing with straight lines , I am getting a lot of mini lines instead of a single connected line segment.
I am running this command line

vpype read blockhouse.svg linemerge --tolerance 0.1mm linesort write --layer-label Pen%d --page-format 192x270mm blockhouse_opt.svg

This is the original
Screenshot from 2020-04-30 11-36-51

This is the output
Screenshot from 2020-04-30 11-33-33

this is the plot that I am using

blockhouse.zip

Bug: `read` fails to load certain SVGs

The read command fails on certain SVGs.

This was the call: vpype read -m --layer 1 voronoi.svg

This was the error trace:

Traceback (most recent call last):
  File "/Users/theuser/.pyenv/versions/plotter/bin/vpype", line 8, in <module>
    sys.exit(cli())
  File "/Users/theuser/.pyenv/versions/3.7.7/envs/plotter/lib/python3.7/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/Users/theuser/.pyenv/versions/3.7.7/envs/plotter/lib/python3.7/site-packages/vpype_cli/cli.py", line 72, in main
    return super().main(args=preprocess_argument_list(args), **extra)
  File "/Users/theuser/.pyenv/versions/3.7.7/envs/plotter/lib/python3.7/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/Users/theuser/.pyenv/versions/3.7.7/envs/plotter/lib/python3.7/site-packages/click/core.py", line 1290, in invoke
    return _process_result(rv)
  File "/Users/theuser/.pyenv/versions/3.7.7/envs/plotter/lib/python3.7/site-packages/click/core.py", line 1224, in _process_result
    value = ctx.invoke(self.result_callback, value, **ctx.params)
  File "/Users/theuser/.pyenv/versions/3.7.7/envs/plotter/lib/python3.7/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/Users/theuser/.pyenv/versions/3.7.7/envs/plotter/lib/python3.7/site-packages/vpype_cli/cli.py", line 118, in process_pipeline
    execute_processors(processors)
  File "/Users/theuser/.pyenv/versions/3.7.7/envs/plotter/lib/python3.7/site-packages/vpype_cli/cli.py", line 202, in execute_processors
    state = proc(state)
  File "/Users/theuser/.pyenv/versions/3.7.7/envs/plotter/lib/python3.7/site-packages/vpype/decorators.py", line 154, in global_processor
    state.vector_data = f(state.vector_data, *args, **kwargs)
  File "/Users/theuser/.pyenv/versions/3.7.7/envs/plotter/lib/python3.7/site-packages/vpype_cli/read.py", line 106, in read
    read_svg(file, quantization=quantization, simplify=not no_simplify),
  File "/Users/theuser/.pyenv/versions/3.7.7/envs/plotter/lib/python3.7/site-packages/vpype/io.py", line 163, in read_svg
    doc.flatten_all_paths(), quantization, scale_x, scale_y, offset_x, offset_y, simplify,
  File "/Users/theuser/.pyenv/versions/3.7.7/envs/plotter/lib/python3.7/site-packages/svgpathtools/document.py", line 219, in flatten_all_paths
    path_filter, path_conversions)
  File "/Users/theuser/.pyenv/versions/3.7.7/envs/plotter/lib/python3.7/site-packages/svgpathtools/document.py", line 142, in flatten_all_paths
    path = transform(parse_path(converter(path_elem)), path_tf)
  File "/Users/theuser/.pyenv/versions/3.7.7/envs/plotter/lib/python3.7/site-packages/svgpathtools/parser.py", line 91, in parse_path
    segments.closed = True
  File "/Users/theuser/.pyenv/versions/3.7.7/envs/plotter/lib/python3.7/site-packages/svgpathtools/path.py", line 2241, in closed
    if value and not self._is_closable():
  File "/Users/theuser/.pyenv/versions/3.7.7/envs/plotter/lib/python3.7/site-packages/svgpathtools/path.py", line 2219, in _is_closable
    end = self[-1].end
  File "/Users/theuser/.pyenv/versions/3.7.7/envs/plotter/lib/python3.7/site-packages/svgpathtools/path.py", line 2081, in __getitem__
    return self._segments[index]
IndexError: list index out of range

This is the offending SVG:
voronoi.svg.txt

Page origin variation depepeding on loading orientaion

Depending on how the page is loaded on some plotters the origin point varies for the same paper size. How should this be handled in the config setup for hpgl export ?
#61
Solution Define page orientation with default page size names and orientation names for alternative paper loading orientations e.g a3l

Feature: `fill` command (add fill pattern to closed shapes)

Move over the fill command from abey79/vpype-exploration, adding the following in the process:

  • option for arbitrary orientation
  • open paths should be kept by default
  • documentation
  • (optional) target layer (to send fill pattern to a different layer)
  • (optional) cross-hatched pattern

linesimplify should filter out tiny segments

Tiny segments (start/end point closer to some small threshold) are often generated by 3D to 2D renderers. They increase plotting time and maybe detrimental to plot quality. linesimplify should filter them out.

Feature request: batch file input

I think a killer feature would be to have something like pythons enumerate ontop of a directory

What I am imagining is something like

files = a directory, or user generated list
for i, file in files:
do stuff

I think this would make handling layers easier (right now I just use a shell variable for each file cause), and it would let you do custom grid stuff in a nifty way (today I went to grid some files and my solution ended up being)

read f1

translate 0mm 110mm

read f2

translate 0mm 110mm

...

show

but instead you could do

for i, file in directory:
read file -l i

and
for i, file in files:
read file
translate (i/num_files), (i%num_files)

Crop to Content

I've been using vpype a bunch recently, and have really enjoyed it!

One feature request that I have is the ability to "crop to content". i.e. Given an SVG, find the outer bounding rect of all the paths in it, and crop to that bounding box.

`read` should do an implicit linesimplify

Using small quantisation with read will create unnecessarily large numbers of segment for paths with light curvature. Running linesimplify with tolerance identical to quantisation would avoid this issue. The default behaviour could be disabled with a new option.

resizing and layering is a bit wonky

So I'm trying to do

vpype
read -l 1 $BLUE scale --to 11in 8.5in
read -l 2 $RED scale --to 11in 8.5in
write -l -p a4 --center $OUT

This will only resize the last read layer (so this will rescale red, but not blue). I've tested out the rescaling on both SVGs and they work fine individually.

Scaling and cropping from the centre

I feel like it should be easier to use the centre of the geometries as the origin for scale and crop.

Rotate already uses the centre as the origin by default, which I think is correct. I feel like scale should also operate from the centre by default as this would be the most common use case during pen plotting. If you think this might confuse users, allowing --origin center might be a good compromise. One can, of course, always use --center in the write command to fix this, but I don't think that giving users an alternative here is a bad idea.

With crop it's a little trickier because it uses X and Y rather than --origin. But again - I feel like a common use case would be cropping in from all the edges evenly, and this is currently very difficult to calculate manually. Might be worth thinking about refactoring this to use --origin too, so it matches the other commands?

OSError: [WinError 126] The specified module could not be found

Hello, new user here, but cannot get vpype to launch successfully.

Everything on this page worked for me, up until the last two steps:
https://github.com/abey79/vpype/blob/master/INSTALL.md

Recently moved from Mac Os to Windows 10 and it's a little getting used to. Almost none of the instructions worked for me so it took me an hour to figure out how to get it all installed and working.. I ran from one error into the next. Eventually it all works but I run into the error in the title when I run Vpype.

What I'm using:
Python 3.7.9
Virtualenv
Shapely-1.7.1-cp37-cp37m-win_amd64.whl (for Py 3.7)

When running vpype --help, it says:
(my-vpype-env) C:\Users\ohmar>vpype --help
Traceback (most recent call last):
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.2544.0_x64__qbz5n2kfra8p0\lib\runpy.py", line 193, in run_module_as_main
"main", mod_spec)
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.2544.0_x64__qbz5n2kfra8p0\lib\runpy.py", line 85, in run_code
exec(code, run_globals)
File "C:\Users\ohmar\my-vpype-env\Scripts\vpype.exe_main
.py", line 4, in
File "c:\users\ohmar\my-vpype-env\lib\site-packages\vpype_cli_init
.py", line 2, in
from .blocks import *
File "c:\users\ohmar\my-vpype-env\lib\site-packages\vpype_cli\blocks.py", line 5, in
from vpype import LengthType, VectorData, block_processor
File "c:\users\ohmar\my-vpype-env\lib\site-packages\vpype_init_.py", line 4, in
from .decorators import *
File "c:\users\ohmar\my-vpype-env\lib\site-packages\vpype\decorators.py", line 8, in
from .layers import LayerType, VpypeState, multiple_to_layer_ids, single_to_layer_id
File "c:\users\ohmar\my-vpype-env\lib\site-packages\vpype\layers.py", line 6, in
from .model import VectorData
File "c:\users\ohmar\my-vpype-env\lib\site-packages\vpype\model.py", line 10, in
from .line_index import LineIndex
File "c:\users\ohmar\my-vpype-env\lib\site-packages\vpype\line_index.py", line 5, in
from scipy.spatial import cKDTree as KDTree
File "c:\users\ohmar\my-vpype-env\lib\site-packages\scipy_init_.py", line 136, in
from . import distributor_init
File "c:\users\ohmar\my-vpype-env\lib\site-packages\scipy_distributor_init.py", line 61, in
WinDLL(os.path.abspath(filename))
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.2544.0_x64__qbz5n2kfra8p0\lib\ctypes_init
.py", line 364, in init
self._handle = _dlopen(self._name, mode)
OSError: [WinError 126] The specified module could not be found

Is this the place to ask for help? It's pretty intimidating, I pondered going to Stackexchange, but figured this might be too much of a 'niche' error mostly related to vpype, also couldn't find anyone with this similar issue so I decided to ask here, hope that's okay.

I hope someone has a solution.
Thanks,
Marinus

OS X install error

When installing vpype on OS X I get the following error:

 Collecting click>=7.1 (from vpype)
  Could not fetch URL https://pypi.python.org/simple/click/: There was a problem confirming the ssl certificate: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:661) - skipping
  Could not find a version that satisfies the requirement click>=7.1 (from vpype) (from versions: )
No matching distribution found for click>=7.1 (from vpype)

Is this my error, or a bug somewhere?

Windows: crash on start due to automatic seeding (if no -s provided)

  File "c:\users\hhip\desktop\venv_trash\lib\site-packages\vpype_cli\cli.py", line 101, in cli
    seed = np.random.randint(2 ** 32)
  File "mtrand.pyx", line 741, in numpy.random.mtrand.RandomState.randint
  File "_bounded_integers.pyx", line 1350, in numpy.random._bounded_integers._rand_int32
ValueError: high is out of bounds for int32

write: properly set 'width' and 'height' SVG attribute

Setting SVG attribute to values with units should avoid different PPI definition (Illustrator vs. Inkscape) to get in the way.

width and height must be set with proper units (e.g cm) and viewBox must be added (in pixels)

Add programmatic way to run a pipeline

import shlex

import vpype as vp
import vpype_cli

def call_vpype(pipeline, vd: vp.VectorData = vp.VectorData()) -> vp.VectorData:

    @vpype_cli.cli.command(group="vsketch")
    @vp.global_processor
    def vsketchinput(vector_data):
        vector_data.extend(vd)
        return vector_data

    out_vd = vp.VectorData()

    @vpype_cli.cli.command(group="vsketch")
    @vp.global_processor
    def vsketchoutput(vector_data):
        out_vd.extend(vector_data)
        return vector_data

    args = "vsketchinput " + pipeline + " vsketchoutput"
    vpype_cli.cli.main(prog_name="vpype", args=shlex.split(args), standalone_mode=False)
    return out_vd

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.