CreativeInquiry / PEmbroider

Embroidery Library for Processing
Other
443 stars 28 forks source link

PERLIN error when rendering in p2d #87

Open tatyanade opened 3 years ago

tatyanade commented 3 years ago

Hi @LingDong- This came up in the slack channel issue Aashish posted; when using PGraphics as P2D, most of the hatches work fine but Perlin specifically for HatchRaster has issues - (also issues in P3D, not sure if P3D is w.in our scope ) image

LingDong- commented 3 years ago

Hi @tatyanade

That is a Processing bug unrelated to PEmbroider. For instance, try this example without PEmbroider:

void setup(){
  size(400,200,P2D);

  PGraphics p1 = createGraphics(200,200,P2D); // remove P2D and it works
  PGraphics p2 = createGraphics(200,200);

  p1.beginDraw();
  p1.background(0);
  p1.circle(100,100,40);
  p1.endDraw();

  p2.beginDraw();
  p2.image(p1,0,0);
  p2.endDraw();

  image(p1,0,0);
  image(p2,200,0);
}

Expected behavior is that p1 gets rendered onto p2, and two identical circles should be seen on screen. Instead, p2 is empty, and only p1 is visible. Therefore Processing's image() function is apparently broken for P2D.

So user has to either convert their P2D to the AWT renderer via pixels[], via IO etc., or tell Processing foundation to fix it.

amgadani commented 3 years ago

hmm, why does it work for other hatch types though?

LingDong- commented 3 years ago

Hi @amgadani , depending on the hatch type, the internal algorithm may or may not need to transfer the PGraphics/PImage from one to another some number of times. For some hatch types under certain parameters, 0 transfer is made so it happen to work.

amgadani commented 3 years ago

ahh i see, it feels reasonable to me to expect PEmbroider to do that in these cases and possible output a warning in the console, rather than some cases not work and have it be on the user, what do you think? happy to do the conversion on myside in general but just from a library usage perspective it feels confusing that some would work and some just wouldnt without the user knowing

LingDong- commented 3 years ago

I totally agree. However, the problem is that the functions take PImages as arguments, which is the grandparent class of default renderer, P2D, and P3D. So whenever you're passing a PGraphics, Java is in fact casting it to the base class PImage before giving it to PEmbroider. From PEmbroider's perspective, it just works with PImages, and doesn't have a way of knowing what you converted it from earlier, be it a file loaded from disk, casted from whatever renderer, or just a sequence of bytes that happens to be a valid PImage...

One possibility is that we overload all functions in the library to catch the particular case of P2D/P3D, which I think is pretty verbose given the number of functions we have. The assumption of the PEmbroider library (or any Processing library) is a working implementation of Processing, so I think it might be a better idea to get Processing to fix their bug in this particular case.

Happy to hear about other solutions

EDIT: actually, to make above solution work, the user has to initialize their P2D as processing.opengl.PGraphics2D pg = new processing.opengl.PGraphics2D() and do all the initialization themselves that is otherwise automated by createGraphics. PGraphics pg = createGraphics(w,h,P2D) cannot be used because it casts the result to a regular PGraphics and PGraphics class seems to not include a field indicating type. So I think it's not very realistic...

golanlevin commented 3 years ago

@LingDong- , could you kindly post a bug to https://github.com/processing/processing regarding how Processing's image() function is apparently broken for P2D?