We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I'm having trouble making cutout contours using PShapes. The beginContour()/endContour() functions seem to work just fine when I'm drawing directly to the screen, but when I attempt to do it within a PShape definition it comes out like this:
The box on the left is drawn directly to the screen, the box on the right is drawn using a defined PShape. This is the code:
PShape s;
void setup()
{
frameRate(50);
size(500,300);
s = createShape();
s.beginShape();
s.fill(255,0,0);
s.vertex(100,100);
s.vertex(200,100);
s.vertex(200,200);
s.vertex(100,200);
s.beginContour();
s.vertex(125,125);
s.vertex(125,175);
s.vertex(175,175);
s.vertex(175,125);
s.endContour();
s.endShape(CLOSE);
}
void draw()
{
beginShape();
fill(255,0,0);
vertex(100,100);
vertex(200,100);
vertex(200,200);
vertex(100,200);
beginContour();
vertex(125,125);
vertex(125,175);
vertex(175,175);
vertex(175,125);
endContour();
endShape(CLOSE);
shape(s, 200, 0);
}
As you can see, I'm defining both boxes in exactly the same way, yet the PShape seems to ignore my call to beginContour()/endContour(). Is this happening to anyone else? Am I doing something wrong?
Edit: In fact, even when I copy the code from https://processing.org/reference/PShape_beginContour_.html, it gets screwed up in the same way.
Answers
I added this right before endContour:
s.vertex(125, 125);
it helps bu you get an artifact and I am guessing this is cause by the actual stroke color.Kf
Read the reference on contour
Outer and inner ring must be opposite direction iirc
Eg one clockwise, the other amti-clockwise
beginContour() example: https://forum.Processing.org/two/discussion/14071/converting-java-code-to-python-for-dataviz#Item_14
Reference: https://Processing.org/reference/beginContour_.html
@Dullahan -- re:
You are right -- it looks like there is a bug in PShape.beginContour() in recent versions of Processing. This can be seen by the canonical reference example (which contains correct clockwise / counterclockwise vertex order) no longer rendering correctly, as you point out.
The bug report is here:
@kfrajer
Actually, that's a clever solution! If you also put a
s.vertex(100,100);
just before beginContour, it closes the shape up with a stroke line connecting (100,100) and (125,125). If you then put in anoStroke();
then the two shapes look identical! It even seems to hold up to various transformations with no visual artifacts. Unfortunately, if you want an outline, there will always be a stroke line connecting the outside outline and the contour outline.@Chrisir
Don't worry, I did. ;) And my vertices do wind in opposite directions.
@jeremydouglass
Thanks for pointing that out. Guess I'll just have to use kfrajer's solution for the time being.
@Dullahan
If you do
s.noStroke()
then you won't have an artifact but you won't have an outline of the shape. You could the outline manually if you needed. Or even better, you could create a class that will do it for you. It really depends how complex your geometry shape will be. Of course, this is a temporal solution while the bug gets resolved.Kf
Bug resolved as error in documentation -- use CLOSE twice for inner Contour and outer Shape.
https://github.com/processing/processing/issues/4978
I don't get it. Twice? This is what I have:
Kf
@kfrajer -- hmm. Yeah, I'm not sure.
Perhaps respond on the issue 4978 I linked above with that example and a brief explanation? The issue might have been closed for the wrong reasons.
@jeremydouglass I will do a follow up. Stay tune!
Kf
@kfrajer -- Two things I've noticed:
beginContour()
code sequence in draw() and thePShape.beginContour()
code are identical other than being the function / PShape method -- but they give different results.Here is a new illustration:
And here is a new test code:
Here is a second example: Two identical PShape sequences except that one contains "beginContour / endContour" and one does not. One should contain a contour, but instead both render the same end shape.
Now let's do it again, but take those commands out of PShape methods and use the draw functions instead. Again, two identical sequences of vertices, with the only difference being that one uses "beginContour / endContour", and one does not.