CreativeInquiry / PEmbroider

Embroidery Library for Processing
Other
442 stars 28 forks source link

Shape Merging #54

Closed tatyanade closed 4 years ago

tatyanade commented 4 years ago

Is there a way to merge shapes (or other boolean shape operations) without drawing them from raster graphics (this is how the example file does it) ? Maybe something more straightforward like :


E.beginMerge();
circle(100,100,100);
circle(150,100,100);
E.endMerge();
golanlevin commented 4 years ago

This would essentially be a set of convenience functions that wrap the PGraphics stuff. @LingDong- , I think it's a good idea.

LingDong- commented 4 years ago

Sorry but I don’t think that’s quite realistic, and very limiting even when implemented.

Firstly @tatyanade’s snippet won’t work out of the box, because E (the PEmbroiderGraphics object) doesn’t (and shouldn’t) know what you’re doing when you call circle. circle is a Processing function, and will simply draw a circle to the screen. So it at least has to be E.circle. Now E.circle is already bounded to the functionality of stitching a circle. So what needs to happen is that E.beginMerge() sets a global state. If the state is set, E.circle() will draw on a secret offscreen buffer, otherwise it stitches the shape. Now, PEmbroider supports some 50 functions from Processing, while Processing have some 100 drawing functions. Most of these drawing functions have overloaded methods, so that’s like another 50 functions. These now all need to be added into our library, basically wrapping everything and introducing massive bloat (and a lot of IF statements). (Or maybe I suck at Java and there's a beautiful way to implement this, please let me know :).

OK, let’s see how much convenience it brings to our user:

Current API:

PGraphics pg = createGraphics(width,height);
pg.beginDraw();
pg.background(0);
pg.noStroke();
pg.circle(100,100,100);
pg.circle(150,100,100);
pg.endDraw();
E.hatchRaster(pg);

Proposed API:

E.beginMerge();
// perhaps we can give the background and stroke a default setting
E.circle(100,100,100);
E.circle(150,100,100);
E.endMerge();

We saved a total of 4 lines, and these lines are actually default settings, if the user need to specify something other than the default, they’ll instead save only 2 lines. If the user's design is more complex than 2 circles, this saving is pretty much negligible.

If you really want unnecessary wrappers, here’s my proposal:

We give an alias to PGrpahics and call it PEmbroiderMerger. It is exactly the same as PGraphics, but under a cooler name. Implemented in one line: class PEmbroiderMerger extends PGraphics{}.

Now we put in more fake duplicate stuff to make it sound real. E.createMerger() which is an alias to createGraphics(), E.processMerger() which is an alias to E.hatchRaster().

PEmbroiderMerger M = E.createMerger();
M.circle(100,100,100);
M.circle(150,100,100);
E.processMerger(M);

This has the huge benefit of convincing the user that we’re using cool secret technology in stead of plain old PGraphics.

;)

LingDong- commented 4 years ago

Actually -- I'm seriously considering the idea. We can give an alias to every function in PGraphics to make it sound a lot cooler.

LingDong- commented 4 years ago

@golanlevin @tatyanade 82de0462f0589d8920a41327d13585354e698622

Screen Shot 2020-06-25 at 1 25 03 AM
golanlevin commented 4 years ago

Whoa that's interesting, head is spinning

golanlevin commented 4 years ago

OK, terrific work. Only request, @LingDong- , could you please rename PEmbroiderBSA to PEmbroiderBooleanShapeGraphics or something similar? The "BSA" is too cryptic.

LingDong- commented 4 years ago

renamed: a244efdb1919569621edee6fbd29c516d46914fb

PEmbroiderBooleanShapeGraphics BSG = new PEmbroiderBooleanShapeGraphics(width,height);