Embroidermodder / libembroidery

Library for reading/writing/manipulating machine and design embroidery files
https://www.libembroidery.org
zlib License
45 stars 13 forks source link

embroider flag `--combine` that combines multiple files into one. #174

Open robin-swift opened 2 years ago

robin-swift commented 2 years ago

Copied from old to do list.

tatarize commented 2 years ago

This is absolutely useful and it's one of the things people totally use pyembroidery to do.

The needed routines here are:

Notes

Some DST will have 0 real thread colors and PES will have 5, and when you combine them you need the real thread colors in the PES to remain in the correct location which means they are to be placed after the color changes in the DST, but the actual threadlist doesn't include this data. It needs to to pad out the list with nulls and then write out random colors if asked to write a format that requires it.

The transformations are needed because when you combine the files you do not always want them stuck overlapped. And the coordinate systems in embroidery is usually that the embroidery center is (0,0). Knowing that you're going to translate by X,Y and then scale by SX, SY, and rotate by R is important to positioning the embroidery where you need it.

Include #121 since that's mostly what that code was used for with pyembroidery a non-dependency based quick viewer whether the composing was working well.

Some files can have multiple End commands. While it's not yet a thing here, the VP3 reading format actually permits multiple designs to be combined into the same VP3 file. I've not actually seen it used outside of the actual editor Premier+. This shouldn't really be a problem since they are very rare. But, the VP3 file can have multiple 0x02 flags though I made them with the editor, I've never seen anybody use one. Not sure how this would work with composing different embroideries.

robin-swift commented 2 years ago

Behaviour could be:

embroider --combine filename.pes --offset 50,20 filename2.pes -o newfile.pes

This would take the files "filename.pes" and "filename2.pes" and put them in the same EmbPattern, the affine transformation in @tatarize comment would be requested via --offset and --scale commands, then the output would be defined by the compiler like -o output flag (with the long name --output).

robin-swift commented 2 years ago

Since embroider has the ability to create standard test files, we could make a really simple shell script to test this along the lines of:

embroider --test-file 1 -o test01.pes
embroider --test-file 2 -o test02.pes
embroider --combine test01.pes --offset 50,20 test02.pes -o output.pes
embroider --render output.pes -o output.ppm
display output.ppm
# on windows you just put the filename and it displays it, this is the Linux shell script

Then we'd look at the output to see if it matches the predicted result.

tatarize commented 2 years ago

ImageMagick would allow something like convert -append in-*.jpg out.jpg which is basically appending all the images sideways as such. And there's certainly a need for a kind of batch convert thing.

I think my code from a while back was: https://github.com/EmbroidePy/pyembroidery-CLI and while don't think I'd code a more modern CLI like that. I'd use optparse stuff and entry points to register the script. I would use that kind of pipeline concept.

--

load as a command can load up a series of EmbPattern objects for all the specified files and each command after that applies to all the other patterns in the pipeline.

So embroider --load filename.pes filename2.pes would load two EmbPattern objects into the pipeline. We then specify what we're going to do with them. Somehow saying we want to offset one of them, rather than both. And then combine would combine the 2 patterns in the pipeline

Assuming that we could do embroider --load filename.pes --offset 50,20 --load filename2.pes --combine --output newfile.pes which would load one embpattern into the pipeline, apply an offset to that pattern, load a second file into the pipeline, combine those two patterns (or however many are in the pipeline) and output the patterns in the pipeline (which would just be the 1 combined EmbPattern).

We'd also be able to do embroider --load *.pes --output %F.dst to load up all pes files and save them all out as dst files.


There's also some need for information about the file, like how many stitches they have. Which would likely be the same thing by loading all of them and then rather than saving the data from the pipeline you query statistics about it.

This almost makes me want to take another stab at a good CLI for the python library.


Some of the code here is similar to vpype's pipelining which is quite useful. Make a circle, create a grid of circles, output that grid of circles as an embroidery file. The Python vpype-embroidery thing I wrote (as a plugin for vpype) would have that functionality.


In the end the instructions follow the code, so it's not necessary to define the behavior unless you know how the rest of the commandline stuff works. But, once you have that defined it's really clear what commands do and which commands are needed.

robin-swift commented 2 years ago

The Pipeline

Yes a pipeline of flags is what we should aim for. I agree that convert is the tool to imitate (but with POSIX-style flags).

Assuming that we could do embroider --load filename.pes --offset 50,20 --load filename2.pes --combine --output newfile.pes which would load one embpattern into the pipeline, apply an offset to that pattern, load a second file into the pipeline, combine those two patterns (or however many are in the pipeline) and output the patterns in the pipeline (which would just be the 1 combined EmbPattern).

I'm not sure the load flag is necessary? I think it's implicit.

Batch conversion

We'd also be able to do embroider --load *.pes --output %F.dst to load up all pes files and save them all out as dst files.

The current idea for this was

embroider --to dst filename1.pes filename2.pes

because *.pes means adding in code to do the wildcard expansion. Also the output name is made by changing the input name. The imagemagick solution is

mogrify -format png *.jpg

mogrify doesn't expect an output name either. I chose --to to allow the command to read as a sentence i.e. "embroider to dst the files filename1.pes and filename2.pes".

Batch concatenation

We could do this with just a different flag like

embroider --tile --to dst filename1.pes filename2.pes

without --to the output is pes.