Hello,
Could any one explain me how to change the Stroke and the Fill of a PShape in realtime ? See the code below.
Thank you very much for your help.
PShape D;
void setup() {
size(400, 400, P3D);
D = createShape();
D.beginShape();
D.fill(0, 255, 0);
D.stroke(0);
D.vertex(10, 20, 0);//! sens de création des carrés !
D.vertex(200, 10, 0);
D.vertex(200, 400, 0);
D.vertex(10, 400, 0);
D.endShape(CLOSE);
}
void draw() {
background(120);
changeStroke(color(random(255), 0, 0));
changeCouleur(color(0, random(255), 0));
changePosition(8);
shape(D);
}
void changeCouleur(color uneCouleur) {
D.setFill(color(uneCouleur));
}
void changeStroke(color uneStroke) {
D.setStroke(color(uneStroke));
}
void changePosition(int uneValeur) {
for (int i = 0; i <D.getVertexCount(); i++) {//< ou <=
PVector v = D.getVertex(i);
v.x += random(-1, 1);
v.y += random(-1, 1);
v.z += random(-1, 1);
D.setVertex(i, v);
}
}
As you can see by trying my code… the Fill and the Stroke don’t change…
glv
February 15, 2023, 8:53pm
3
Hello @animalfrommars ,
It works as expected with Processing 3.5.4 and the fill() and stroke() are changing. There is a nice illusion of the background changing.
It does not work as expected with Processing 4.1.3.
Your code with minor changes (color transition instead of random):
PShape D;
void setup() {
size(400, 400, P3D);
D = createShape();
D.beginShape();
D.fill(0, 255, 0);
D.stroke(0);
D.strokeWeight(5);
D.vertex(10, 20, 0);//! sens de création des carrés !
D.vertex(200, 10, 0);
D.vertex(200, 400, 0);
D.vertex(10, 400, 0);
D.endShape(CLOSE);
}
void draw() {
background(120);
int c1 = frameCount%256;
changeStroke(color(c1, 0, 0));
changeCouleur(color(0, c1, 0));
changePosition();
shape(D);
}
void changeCouleur(color uneCouleur) {
D.setFill(color(uneCouleur));
}
void changeStroke(color uneStroke) {
D.setStroke(color(uneStroke));
}
void changePosition() {
for (int i = 0; i <D.getVertexCount(); i++) {//< ou <=
PVector v = D.getVertex(i);
v.x += random(-1, 1);
v.y += random(-1, 1);
v.z += random(-1, 1);
D.setVertex(i, v);
}
}
Processing 3.5.4:
Processing 4.1.3:
Related issue:
opened 07:08PM - 01 Nov 22 UTC
Help Wanted
OpenGL
## Description
The PShape.setVertex() method can update a PShape's geomet… ry and will alter the filled regions but it does not alter the edges. The edges become fixed the first time it is drawn.
This works as expected for the JAVA2D renderer but does not work for P2D or P3D.
## Expected Behavior
When I use PShape.setVertex() in a P2D or P3D sketch, I'd like it work the same as does for JAVA2D.
## Current Behavior
For a P3D sketch, the line does not change from as it is the first time it is drawn. For a P2D sketch the line does change but is not being drawn correctly.
## Steps to Reproduce
1. Run this code:
```
PShape test;
void setup() {
size(500, 500, JAVA2D);
stroke(255, 0, 0);
strokeWeight(15);
fill(255);
test = createShape();
test.beginShape();
for (int i = 0; i < 10; ++i) {
test.vertex(0, 0);
}
test.endShape();
frameRate(5);
}
void draw() {
background(128);
for (int i = 0; i < 10; ++i) {
test.setVertex(i, random(width), random(height));
}
shape(test);
}
```
Observe how the red line is getting updated for every frame and is always drawn in the right location.
2. Change the renderer to `P3D`. You will see that the red line does not change from one frame to the next.
3. Change the renderer to `P2D`. The red line does change from one frame to the next but is not being drawn correctly. It is hard to describe this in words.
## Your Environment
* Processing version: 4.0.1
* Operating System and OS version: Linux Ubuntu
## Possible Causes / Solutions
In the example above, the PShape object is created with all vertices at `0, 0`. The first time `draw()` is called the `setVertex()` method is called to change the values, and those new values are being used to draw the shape. Therefore, the `setVertex()` method is doing its job for the first frame. For later frames, only the filled region changes.
I believe this has something to do with the tesselation process and edges or strokes in PShape? It seems it is supposed to update the tesselated geometry when `setVertex()` is called, and it does do this for the filled regions but not the edges. I know that Processing has an `inGeo` for input geometry and and separate tesselated geometry that gets sent to OpenGL for renderering. The tesselated geometry is getting refreshed for only the filled regions.
If you can spot a work-around for this that triggers the necessary geometry update, I'd greatly appreciate it. I know I can create a new shape in draw() but for my use case, which has a lot more than 10 vertices, I want to re-use one PShape object.
A simple workaround is to create your shape each frame in draw() .
Performance may be an issue for more complex shapes.
References:
:)
svan
February 16, 2023, 4:14am
4
Change it to a class if you want to change multiple parameters at one time:
PVector[] v = new PVector[4];
color GREEN = color(0, 255, 0);
color RED = color(255, 0, 0);
color BLACK = color(0, 0, 0);
class MyShape {
color shapeColor;
color strokeColor;
PVector[] v;
//Constructor
MyShape(color inColor, color inStroke, PVector[] vectorArray) {
shapeColor = inColor;
strokeColor = inStroke;
v = vectorArray;
}
void display() {
fill(shapeColor);
stroke(strokeColor);
beginShape();
for (int i = 0; i < 4; i++) {
vertex(v[i].x, v[i].y, v[i].z);
}
endShape(CLOSE);
}
}
MyShape myShape;
void setup() {
size(400, 450, P3D);
v[0] = new PVector(10, 20, 0);
v[1] = new PVector(200, 10, 0);
v[2] = new PVector(200, 400, 0);
v[3] = new PVector(10, 400, 0);
myShape = new MyShape(GREEN, BLACK, v);
frameRate(10); // Slow it down from default 60
}
void draw() {
background(120);
for (int i = 0; i < 4; i++) {
v[i].x += random(-1, 1);
v[i].y += random(-1, 1);
v[i].z += random(-1, 1);
}
myShape.shapeColor = color(0, random(255), 0);
myShape.strokeColor = color(random(255), 0, 0);
myShape.display();
}
Hello,
Thank you all for your advice and help.
I’ve tried it with a class and it works… i will try the second proposition soon.
I’was wondering if it will work also with the getVertextCount() method wich can be a way to store the index of each vertex ?
Anyway here is my new code, it works good, thanks.
import peasy.PeasyCam;
PeasyCam cam;
MyShape myShape, myShape2, myShape3;
int nbObjets = 200;//2
int nbVectors = nbObjets*4;
PVector[] v = new PVector[nbVectors];
MyShape [] tabMyShape = new MyShape[nbObjets];
color GREEN = color(0, 255, 0);
color RED = color(255, 0, 0);
color BLACK = color(0, 0, 0);
void setup() {
size(800, 800, P3D);
cam = new PeasyCam(this, 400);
for (int i=0; i<nbVectors; i++) {
v[i] = new PVector(int(random(width)), int(random(height)), int(random(-1000, 1000)));
}
for (int i=0; i<nbObjets; i++) {
tabMyShape[i] = new MyShape(GREEN, BLACK, v, i+1);
}
//frameRate(20);
}
void draw() {
background(120);
for (int i = 0; i < nbVectors; i++) {
v[i].x += random(-10, 10);
v[i].y += random(-10, 10);
v[i].z += random(-10, 10);
}
for (int i=0; i<nbObjets; i++) {
tabMyShape[i].shapeColor = color(random(255), random(255));
tabMyShape[i].strokeColor = color(random(255));
tabMyShape[i].display();
}
}
class MyShape {
color shapeColor;
color strokeColor;
int index;
//Constructor
MyShape(color inColor, color inStroke, PVector[] vectorArray, int unIndex) {
shapeColor = inColor;
strokeColor = inStroke;
v = vectorArray;
index = unIndex;
}
void display() {
strokeWeight(int(random(5)));
fill(shapeColor);
stroke(strokeColor);
beginShape();
for(int i=0; i<4; i++){//nbObjets
vertex(v[i+(4*(index-1))].x, v[i+(4*(index-1))].y, v[i+(4*(index-1))].z);
}
endShape(CLOSE);
}
}
You are true, i’ve tried Processing 3.5.4 and 4.1.3 and seen the same things… thanks for the informations.
1 Like