Multiple Ngons with PShape

edited May 2016 in Questions about Code

I am trying to draw two Ngons (possibly hundreds later) in one Pshape. Faces are not closed properly for some reason. I'd appreciate the help. Thank you.

Pshape

PShape Shape;
float rx=.01;
float scale=100;

void setup() {
  size(800, 800, P3D);
  background(10);
  Shape=createShape();

  Shape.beginShape();
  Shape.fill(255, 255, 255);
  //Shape.noFill();
  Shape.stroke(150, 150, 150);
  Shape.strokeWeight(2);
  Shape.endShape();

  // FACE 1
  Shape.beginShape();
  Shape.vertex(1, 3, 1);
  Shape.vertex(1, 1, 1);
  Shape.vertex(3, 1, 1);
  Shape.vertex(3, -1, 1);
  Shape.vertex(-3, -1, 1);
  Shape.vertex(-3, 1, 1);
  Shape.vertex(-1, 1, 1);
  Shape.vertex(-1, 3, 1);
  Shape.endShape(CLOSE);

  // FACE 2
  Shape.beginShape();
  Shape.vertex(1, 3, -1);
  Shape.vertex(1, 1, -1);
  Shape.vertex(3, 1, -1);
  Shape.vertex(3, -1, -1);
  Shape.vertex(-3, -1, -1);
  Shape.vertex(-3, 1, -1);
  Shape.vertex(-1, 1, -1);
  Shape.vertex(-1, 3, -1);
  Shape.endShape(CLOSE);
}


void draw() {
  background(10);
  translate(width/2, height/2);
  rotateX(rx);
  scale(scale);
  rx+=.01;
  shape(Shape);
}
Tagged:

Answers

  • you're using shape wrongly. but you can create a PShape(GROUP) which holds multiple child PShapes:

    PShape shape;
    float rx=.01;
    float scale=100;
    
    void setup() {
      size(800, 800, P3D);
      background(10);
    
      shape = createShape(GROUP);
      shape.fill(255, 255, 255);
      //shape.noFill();
      shape.stroke(150, 150, 150);
      shape.strokeWeight(2);
    
      // FACE 1
      PShape face1 = createShape();
      face1.beginShape();
      face1.vertex(1, 3, 1);
      face1.vertex(1, 1, 1);
      face1.vertex(3, 1, 1);
      face1.vertex(3, -1, 1);
      face1.vertex(-3, -1, 1);
      face1.vertex(-3, 1, 1);
      face1.vertex(-1, 1, 1);
      face1.vertex(-1, 3, 1);
      face1.endShape(CLOSE);
    
      // FACE 2
      PShape face2 = createShape();
      face2.beginShape();
      face2.vertex(1, 3, -1);
      face2.vertex(1, 1, -1);
      face2.vertex(3, 1, -1);
      face2.vertex(3, -1, -1);
      face2.vertex(-3, -1, -1);
      face2.vertex(-3, 1, -1);
      face2.vertex(-1, 1, -1);
      face2.vertex(-1, 3, -1);
      face2.endShape(CLOSE);
    
      // add children to parent shape
      shape.addChild(face1);
      shape.addChild(face2);
    }
    
    
    void draw() {
      background(10);
      translate(width/2, height/2);
      rotateX(rx);
      scale(scale);
      rx+=.01;
      shape(shape);
    }
    

    NB classes traditionally start with a capital, member traditionally don't. so calling your shape Shape was confusing.

  • Thanks for your answer. Using children is a possibility but it makes things more complicated in my opinion as it creates multiple PShapes parented to one. I am just trying to render Ngon faces instead of only quads or triangles. What is the purpose of endShape(CLOSE) if it is not going to close one face and begin another with the next beginShape? I am planning to have more than a million faces eventually. Does it make sense to create child Pshapes for every single face?

  • But you only have one PShape and yet you call beginShape twice on it. That'll just confuse things.

    I doubt you'd manage 1M faces unless the faces are really simple and you have a decent graphics card. Even then I think you'd struggle without using lower level graphics calls.

  • I understand. Thank you. I made the following codes for comparison. First one uses 1 PShape and draws Quads by beginShape(QUADS) method. I can easily draw 1-2 million quads. The second code creates a PShape for each quad and adds it to 1 main Pshape as children. I can only draw up to 2-3 hundred thousand quads. It is inefficient compared to first code. So I am wondering if there is a way to create multiple Ngons instead of quads without using children.

    --CODE 1 QUADS

    PShape shape;
    float rx=.01;
    float scale=1;
    int facecount=1000000;
    
    void setup() {
      size(800, 800, P3D);
      background(10);
      shape = createShape();  
      shape.beginShape(QUADS);
      shape.noStroke();
      //FACES
      for (int i=-facecount/2; i<facecount/2; i++) {
        float x=50*cos(i/10);
        shape.vertex(-x, -x, i);
        shape.vertex(x, -x, i);
        shape.vertex(x, x, i);
        shape.vertex(-x, x, i);
      }
      shape.endShape();
    }
    
    void draw() {
      background(10);
      translate(width/2, height/2);
      rotateX(rx);
      rotateZ(rx*2);
      scale(scale);
      rx+=.005;
      shape(shape);
    }
    

    --CODE 2 CHILDREN

    PShape shape;
    float rx=.01;
    float scale=1;
    int facecount=100000;
    
    void setup() {
      size(800, 800, P3D);
      background(10);
      shape = createShape(GROUP);
      noStroke(); 
      //FACES 
      for (int i=-facecount/2;i<facecount/2;i++){
        float x=50*cos(i/10);
        PShape face=createShape();
        face.beginShape();
        face.vertex(-x, -x, i);
        face.vertex(x,-x, i);
        face.vertex(x, x, i);
        face.vertex(-x, x, i);
        face.endShape(CLOSE);
        shape.addChild(face);
      }
    }
    
    void draw() {
      background(10);
      lights();
      translate(width/2, height/2);
      rotateX(rx);
      rotateZ(rx*2);
      scale(scale);
      rx+=.01;
      shape(shape);
    }
    
  • Your original shapes are just multiple quads...

  • They are just placeholders. I want to draw triangles, quads or Ngons in one shape as efficiently as drawing only quads with beginShape(QUADS).

  • well, everything's a triangle

    what i'm trying to get at is that you can use triangles to make anything. if you want a cube then that's just 12 triangles. YOU organise them into cubes, the computer just sees them as a list of triangles. so you CAN use one PShape(TRIANGLE) for everything. but moving them could be tricky - you need to remember the structure of the objects somehow - simple enough if all the shapes are the same but if some have 12 triangles and other shapes have 10 triangles then you're going to struggle.

  • Yes you are right. You can triangulate any geometry in theory. I am just trying to understand how PShape works. I guess you can have only triangles, or only quads or a single custom shape. If you have any combination you have to create them separately as children. But it is not as fast as using only one type.

Sign In or Register to comment.