CreativeInquiry / PEmbroider

Embroidery Library for Processing
Other
442 stars 28 forks source link

stitchwise-TSP vs. objectwise-TSP? #35

Open golanlevin opened 4 years ago

golanlevin commented 4 years ago

@LingDong- , I see some opportunities in which the TSP solver could have a behavior which, though less "optimal" in one sense, might be more user-friendly in another.

Let's call an "object", a cluster of related stitches. For example: all of the stitches inside some polygon. Sometimes, when rendering several different objects, the TSP will render half of an object; jump to another object; and then (eventually) return to complete the remainder of the first object.

From a user's perspective, it might make more sense to complete each object individually. More precisely, to:

Is this an option that would be easy to add to the TSP solver?

LingDong- commented 4 years ago

Hi @golanlevin , I think the request totally make sense. Won't be too easy to add, but definitely doable.

Currently each polyline is associated with a cullGroup, which is how I make sure the same shape doesn't cull with its own strokes. So theoretically I can pass this info to TSP too.

But may I suggest another interface that I think gives users more clarity and control:

E.optimize() can be called multiple times. Each time it is called, the polylines that are currently on the canvas are optimized. Then, they're marked as "solidified" and future calls to TSP will treat them as a whole. So users will insert E.optimize() between what they regard as different "object"s.

What do you think?

golanlevin commented 4 years ago

Hi @LingDong- , this is an interesting proposal. What if there were a beginOptimize() and endOptimize() call, which runs a TSP exclusively on the stitches that were added in between those functions?

LingDong- commented 4 years ago

good idea 👍

LingDong- commented 4 years ago

beginOptimize() and endOptimize() were added in this commit: 946609f67f4c91cf0557491494fedf6f9d10da8b

Sorry forgot to update here. Usage is:

import processing.embroider.*;

void setup(){
  size(1000,500);
  PEmbroiderGraphics E = new PEmbroiderGraphics(this);

  E.fill(0);
  E.hatchSpacing(20);

  // these shapes will be optimized individually
  E.beginOptimize();
  E.rect(10,10,300,300);
  E.endOptimize();

  E.beginOptimize();
  E.rect(50,50,300,300);
  E.endOptimize();

  // these shapes will interleave
  E.beginOptimize();
  E.rect(510,10,300,300);
  E.rect(550,50,300,300);
  E.endOptimize();

  E.visualize(true,true,true);

}
golanlevin commented 4 years ago

Hi @tatyanade, could you please test this out so that we can close this issue.

tatyanade commented 4 years ago

Wanted to say that this as a feature makes a lot of sense, have had some failed embroideries where issues arose on one specific shape/object but since the embroidery was jumping around multiple shapes I had to re-embroider all of the ones that had been started and not finished instead of just being able to redo the one with an issue.

Here are some tests I ran;

the code from above PEmbroider_stitch_vs_object_TSP

PEmbroider_stitch_vs_object_TSP

and then a new one w text

text is a weird one to watch be embroidered since it doesn't write left to right and skips around letters and words which is counter intuitive to watch, especially with cursive since you'd expect it to be one line but! It does do the individual text segment individually.

PEmbroider_stitch_vs_object_TSP_text

PEmbroider_stitch_vs_object_TSP_text

This does cause iterating on code to be slower since it takes longer to visualize - when optimize is at the bottom and its you can comment it out till you're ready to write the file but now you'd have to comment out all the begin/ends which might get tedious without a helper function, especially if you have a lot of individual shapes that you want to retain the order of.

In the example code you @LingDong- put above, would optimize by itself need to be called and the end of the file or would that be redundant since all the shapes being embroidered have had optimize called already?