inkstitch / pyembroidery

libembroidery/EmbroideryFormats converted to python
MIT License
72 stars 28 forks source link

EmbEncoder.constrained_stitch_to stitches multiple times #28

Closed lexelby closed 6 years ago

lexelby commented 6 years ago

Let's say I want to write a DST with a really long stitch in it (5cm horizontal). I would create a pattern and add the stitch with pattern.add_stitch_relative(STITCH, 500, 0).

When the pattern gets normalized for DST, EmbEncoder.constrained_stitch_to will get called and will call EmbEncoder.constrained_step_to with STITCH as the last argument. constrained_step_to will then add STITCH commands in increments of 12.1mm until it's within range of the final destination (here).

Shouldn't this add JUMP commands instead? Otherwise I get extraneous needle penetrations when I asked for a 5cm stitch.

tatarize commented 6 years ago

Actually it should in theory, take the 500, figure that that's 4.13 stitches. So a minimum of 5 stitches to get there and send it as 5 commands of 100. That many jumps though will result in a trim. Is the intent of this to actually be stitched? I mean it asked overtly to stitch there and didn't ask for a trim. Breaking it into multiple stitches will result in long but actual stitches if it avoided the needle penetrations here, it would in theory result in a trim, and move.

You could in theory do stitch, jump, jump, stitch, jump, stitch most machines won't force a trim for that and it would stitch fewer times.

However, for practical reasons nobody stitches a 50mm stitch. 5mm is even on the high side (and you can do that in one command). If the stitches are that long it seems like the assumption should be that the desire is to have it broken into more manageable parts, like the program just said put this stitch here, and keep sewing until you reach this point over here.

I think the problem here is the word "assumption". It belays a point that you could very much have a different intent and the code is currently assuming your intent for you. Rather it needs to have these different interpretations able to be set overtly.

When you say "stitch", do you mean try to get the next needle strike as close to as possible to that next position, and let the machine deal with any impossibility, or with as few extra needle strikes as possible given such-and-such constraints, or does it mean keep stitching until you reach that position?

In a more practical sense you might be able to throw in a jump or two (depending on the machine) and get a needle strike like 300 units away without incurring a needle strike. However, some machines will already need to force a jump even to stitch something as really long as 10. And apparently some will just cut that, instead of trying.

This stuff is the reason an encoder is needed.

lexelby commented 6 years ago

Ah, I see the problem. I forgot about the DST multi-jump-trim thing.

In most machines, I believe it's possible to configure the number of jumps that equate to a trim, or even turn off jumps-to-trim conversion. I get the impression that users are knowledgeable about this trade-off and that if they want to have a super-long stitch, they know they'll need to adjust or turn off jumps-to-trim conversion in the machine. I believe I had a very similar conversation with wwderw at one point and he said as much.

However, for practical reasons nobody stitches a 50mm stitch. 5mm is even on the high side (and you can do that in one command).

Here's one case where it does make sense to do a really long stitch like that: fringe. Say I want to make a flowing rainbow mane for a unicorn. I'd stitch some super-long satin with no underlay and then mow over one end of it with some running stitch to hold it in place. Afterward I clip the threads on the other side to make a hanging row of threads. The effect would be ruined if pyembroidery insisted on breaking the stitch up.

Ultimately, I feel like if the user says "STITCH", they mean stitch, not multi-stitch.

tatarize commented 6 years ago

If @wwderw said it, it's almostly undoubtedly true. That guy knows his stuff really really well.

I added commands for the long stitch contingency (and removed the the jump whatever blah, you can do that better setting a lower max_stitch and using jumps).

You can overtly specify what you want to happen for a too long stitch

CONTINGENCY_NONE = Go away encoder send it to the writer. CONTINGENCY_JUMP_NEEDLE = Add in jumps until you can reach the end of the stitch. CONTINGENCY_SEW_TO = Add in stitches until you can reach the end of the stitch.

This would also be perhaps where things like tie-on and jump needle to the end thing would go. Or whatever action should be taken in the case when the distance requested is too damned far.

I do also need to reassign the stitch command rather tossing it through a freakish if elif block everytime (another reason for NONE, it would result in faster code (not that it's critical))

wwderw commented 6 years ago

As far as stitch lengths, 12.1 mm to 12.7mm is the highest that some machines will do before they will force a trim.

As was mentioned, fringe is one case to where you want to have a long stitch.

Another use case would be for puff. While you can do puff using fill stitches, fill stitches do not look as good as satin stitches do with puff.

Now, you do not want to go hog wild with each one and doing long stitches out the ying yang. That would be no bueno. One reason why machines slow down when trims are turned off when doing those really long stitches is to prevent certain issues (timing being the biggest one, especially on multi-head machines that use step motors (that is getting fewer and fewer as most machines use servo motors now).

lexelby commented 6 years ago

The latest code looks great. Thanks, @tatarize! As far as I'm concerned this can be closed.