EmbroidePy / pyembroidery

pyembroidery library for reading and writing a variety of embroidery formats.
MIT License
181 stars 33 forks source link

Dst Reader Thread values #149

Open kaalleen opened 2 years ago

kaalleen commented 2 years ago

Hey there. This is maybe interesting for you (value => values)

https://github.com/EmbroidePy/pyembroidery/blob/06225f67ddb410678763850e2a77738d68b0245f/pyembroidery/DstReader.py#L44

Reference: https://github.com/inkstitch/pyembroidery/pull/93

tatarize commented 2 years ago

Thanks I had a commit that fixed it but had neglected pushing it to master somehow. I saw the Commit on the inkstitch thing, since I check through there, here and there to check for broken file format things.


Also, worth noting, I wrote a rather nice generic writer bit of code. The goal is similar to some other work I did with for pen plotters where there's a bunch of hobbyist machines and the gcode format is going to be fairly different depending on how a person implements the diy code. This was the problem with gcode pen plotters, they could implement some M command to pick the pen up or down or use a z-axis, etc. So the question was how do you write gcode so generally that any gcode works. The answer became vpype-gcode ( https://github.com/plottertools/vpype-gcode ).

I've since expanded the idea to cover pyembroidery code. Basically it's a method of writing any pure ascii output to disk. So if you wanted to write a specific text format, some gcode, svg, some HPGL, or any other type format, you can just specify the parts of code. So you give it what it should do each time it hits a new color block, or each time it hits a new stitch block within that color block, what it should do for end stitches or jump stitches etc. Basically there's only so many parts it has when it goes over an embroidery file with only so many commands.

https://github.com/EmbroidePy/pyembroidery/pull/146

The idea was in part to make sure that the gcode writers could be brought back into alignment without losing anything. So rather than adding a different flag in each different type of gcode you wrote out, you could just define the parts of the text for the gcode and write generic ascii text output created looping over the commands and the different parts of code. Largely with an updating dictionary being used to replace format strings.

from pyembroidery import *
import sys

gcode_writer_dict = {
    "scale": (0.1, -0.1),
    "thread_change_command": NEEDLE_SET,
    "write_speeds": True,
    "pattern_start": "G21 G90 F6000 (mm units, absolute positioning, speed)\n",
    "thread_entry": "(Thread{thread_index}: {thread_color} {thread_description} {thread_brand} {thread_catalog_number})\n",
    "color_start": "G00 X{x:.3f} Y{y:.3f} (Starting new location)\n",
    "stitch": "G01 X{x:.3f} Y{y:.3f}\n",
    "slow": "F1000\n",
    "fast": "F6000\n",
    "needle_set": {None: ("{cmd_needle}", "default value {cmd_needle}\n"), "1": "G0A51\n", "2": "G0B8\n"},
    "end": "M30\n",
}

EmbPattern.write_embroidery(
    GenericWriter,
    EmbPattern(sys.argv[1]),
    f"{sys.argv[1]}.gcode",
    gcode_writer_dict,
)

Basically I ran into somebody #142 who was doing some entirely different gcode conversion replacing the internal circuits of a working machine with stepper motors and many heads into being controlled with a GRBL device. The gcode built into inkstitch's pyembroidery and my own uses a moving z value which is used to turn the hand-crank of a sewing machine for a refit that way. But, there's other styles of gcode and maybe something needed to catch them all.

Fixed: 93601f80a034135cac526901215b3b24fe0d5e0d

tatarize commented 2 years ago

TLDR; you'd end up making a dialog like this for inkstitch and have it export embroidery in a generic code according to a defined json that gives the particular pre-formated ascii parts the right values.

image

kaalleen commented 2 years ago

Thank you for the additional info. Ink/Stitch at the moment has this dialog for custom commands: gcode-export

I am not sure, how to integrate the other options like 'slow' and 'fast' or specific needle info - since there is no setting for those in Ink/Stitch (yet). Honestly I always feel a bit unsure working on the pyembroidery integration into Ink/Stitch, because I do not really feel up to the task. I try to compensate as much as I can. The gcode writer in Ink/Stitch has some additional options for laser cutting, etc. So when I started the Ink/Stitch pyembroidery update lately I decided to keep our old gcode writer/reader and not to update this part. Those things are time intensive for me and there are so many other things I want to work on.

Since we are here, there is an other thing I wanted ask. It maybe is a stupid question though. The setup.py in the inkstitch pyembroidery fork is the exact as yours. Does that mean trouble, should we update?

tatarize commented 2 years ago

I'd be happy to write you an essay or two on the formats and such. In fact, the code in pyembroidery is written specifically to try to make sure it was understandable. I also documented the formats as best as I could.

SLOW and FAST are only used in .U01 type embroidery and change commands a little bit (literally just a bit). These are marked within the plotting to slow down and speed up the machine. There's some other machines that can respect these commands and in gcode you'd do something like change the direct speed of the movement. So a custom gcode command for SLOW could be S1000 and FAST would be S5000. Sometimes there's places in a sew out where you keep breaking the thread, the ability to slow down at those spots is helpful, but only a few file formats have such commands.

The needle info is also .U01. It has commands that aren't color changes but change the needle. The biggest distinction is that they occur at the start of the embroidery file. They do things like switch to needle 5 and encode that. So rather than programming the machine with what needle you'd use. It embeds that info into the actual code. There's some use for that within gcode too.

I noticed that the gcode writer was different and I've done some work with pen-plotters too and hang out in a fairly nice plotter discord: https://discord.gg/5R6rASwf

Part of those interactions had me write an extension for a popular generative art program they use to write generic gcode, since a number of the plotter enthusiasts had made their own and getting the format right was basically a per-machine basis. -- Attach a thing to strings it pulls to move itself up-and-down a wall sort of things. And figured I could bridge the gap between the different versions of pyembroidery, so that if Lex ever gets over #1, he could save a lot of work and just use the copy of pyembroidery on pypi, without updating a bunch of times and finding bugs that were fixed the previous year or whatnot.

Most of the point of the project is that it could be more-or-less complete in finite amount of time, and would, regardless what happens with the rest the project be independently useful.


The setup.py is used for installing the program on pypi so that it can be downloaded with pip. So you can do pip install pyembroidery and get a copy of pyembroidery. It's sometimes used in the local directory so you can do pip install . and it'll read that file. This is especially helpful when you're testing things.

So if I change something within pyembroidery and I need to update I run my batch program:

cd C:\Users\Tat\PycharmProjects\pyembroidery
mkdir old_dist
move dist\* old_dist
python setup.py sdist bdist_wheel --universal
twine.exe upload dist\*

Which updates the pyembroidery to whatever version is set in the setup.py file and sends it to pypi. Then usually the requirements peg things to a particular version, if that's needed. And usually the last number are minor bug fixes and the second to the last number is changed when a potentially breaking change is added. So I'm at 1.4.36 so the last 36 or so things have just been small changes that shouldn't break anything. And the last breaking change was Jul of 2019. https://github.com/EmbroidePy/pyembroidery/releases/tag/1.4.0 where I changed the .supported_formats() code to include versions and list those out. So you can more easily do things like request a PESv6 or PESv1. -- Before that the other change was a switch to Needle-Set since this required some logic changes to the core of the module.

Mostly setup.py part of best practices which I've been following for years now. Inkstitch's fork's version could be edited to call it something else, or deleted, or left alone. It won't really harm anything. Really the easier thing would be to just use pyembroidery directly via pypi, and the suggestion for the generic writer was to make sure that different gcode could be treated equally. The hope would be to permit a more unified version, and the gcode there got in the way. In theory with the generic writer a few json files could be used to define a particular version of gcode or generic writer code and since the code is very general, you can basically get it to write anything (including different variations of gcode).