Exclude child from PShape to create mask is it possible?

I try to create a donnut with PShape, but this mission is more difficult than I think, I I don’t find a methode like pshape.exclude(group_a) or pshape.remove(group_a) or something like that there is a way do to that?

PVector [] pts_a;
PVector [] pts_b;
PShape s;
PShape group_a;
PShape group_b;
void setup() {
  size(300,300);
  generate_mask();
}

void draw() {
  background(255);
  s.fill(255,0,0);
  s.noStroke();
  shape(s);
}

void keyPressed() {
  generate_mask();
}


void generate_mask() {
  pts_a = new PVector[4];
  pts_a[0] = new PVector(0,0);
  pts_a[1] = new PVector(width,0);
  pts_a[2] = new PVector(width,height);
  pts_a[3] = new PVector(0,height);
  
  pts_b = new PVector[4];
  for(int i = 0 ; i < pts_b.length ; i++) {
    pts_b[i] = new PVector(random(width),random(height));
  }
  s = createShape(GROUP);
  group_a = createShape();
  group_b = createShape();
   
  group_a.beginShape();
  for(int i = 0 ; i < pts_a.length ; i++) {
    group_a.vertex(pts_a[i].x,pts_a[i].y);
  }
  group_a.endShape(CLOSE);
  
  group_b.beginShape();
  for(int i = 0 ; i < pts_b.length ; i++) {
    group_b.vertex(pts_b[i].x,pts_b[i].y);
  }
  group_b.endShape(CLOSE);
  
  s.addChild(group_a);
  s.addChild(group_b);
}

the result expected is something like that :
mask
And if it’s possible with PShape my second step is to code that without PShape only with vertex with my proper class, but I’m lock on the first step :frowning:

Hi @Stanlepunk,

Not sure to fully understand your issue, could the beginContour() method be a solution to your problem ?

1 Like

Sorry for my cheapr english and explication. Your solution is on the way what i need, but the behavior is very weird, my purpose is see the background on the delimited zony by the four points.

PVector [] pts_ext;
PVector [] pts_int;
PShape s;

void setup() {
  size(300,300);
  generate_mask();
}

void draw() {
  background(255);
  // fill(255,0,0);
  // noStroke();
  shape(s);

  stroke(0);
  strokeWeight(10);
  for(int i = 0 ; i < pts_int.length ; i++) {
    point(pts_int[i].x,pts_int[i].y);
  }
}

void keyPressed() {
  generate_mask();
}


void generate_mask() {
  pts_ext = new PVector[4];
  pts_ext[0] = new PVector(0,0);
  pts_ext[1] = new PVector(width,0);
  pts_ext[2] = new PVector(width,height);
  pts_ext[3] = new PVector(0,height);
  
  pts_int = new PVector[4];
  int marge = 50;
  pts_int[0] = new PVector(marge,marge);
  pts_int[1] = new PVector(width-marge,marge);
  pts_int[2] = new PVector(width-marge,height-marge);
  pts_int[3] = new PVector(marge,height-marge);
  s = createShape(); 
  s.beginShape();
  s.fill(255,0,0);
  s.strokeWeight(1);
  s.stroke(0);
  for(int i = 0 ; i < pts_ext.length ; i++) {
    s.vertex(pts_ext[i].x,pts_ext[i].y);
  }
  // s.vertex(pts_ext[0].x,pts_ext[0].y);
  
  s.beginContour();
  for(int i = 0 ; i < pts_int.length ; i++) {
    s.vertex(pts_int[i].x,pts_int[i].y);
  }
  s.vertex(pts_int[0].x,pts_int[0].y);
  s.endContour();
  
  s.endShape(CLOSE);
}

Interesting, it looks like there is a bug in PShape.beginContour().

According to @jeremydouglass’s answer the solution is to create a shape without calling the PShape method.

def setup():
    size(100, 100)
    
    background(52)
    translate(width/2, height/2)

    beginShape()
    noStroke()

    vertex(-50,-50)
    vertex(50,-50)
    vertex(50,50)
    vertex(-50,50)

    beginContour()
    vertex(-20,-20)
    vertex(-20,20)
    vertex(20,20)
    vertex(20, -20)
    endContour()

    endShape(CLOSE)

PS: don’t forget that “the exterior shape and the interior contour must wind in opposite directions.”. In your code the vertices of your interior contour should go in counterclockwise order (pts_int[0], pts_int[3], pts_int[2], pts_int[1]).

That is right – for more discussion of this open bug, see:

2 Likes

I try to find a way to fix the bug, but it’s too complex for methe relation between PShape, PGraphics and PGraphicsJava2D:frowning: That may be one of the reasons why in Processing 4 project it’s write :

Improve or replace PShape

    PShape has grown very complex and should probably be handled differently.
    When started, we were looking for a lightweight (a few Kb) way to do SVG. Nowadays, size footprint isn't much of an issue, so it might be better to get improved support by using something like Batik underneath.
1 Like