Bug 1212 : 3D transparent panel refuses to fill with colour
Last modified: 2010-02-19 06:57




Status:
RESOLVED
Resolution:
INVALID -
Priority:
P2
Severity:
normal

 

Reporter:
MaltaCross
Assigned To:
fry

Attachment Type Created Size Actions

Description:   Opened: 2009-03-17 08:26
I have constructed a 3D construct made up of discrete panels made up with
beginShape/endShape. These panels could be coloured with the function fill().
However, the panel to which a "red handle" is attached, refuses to accept
colouring no matter what one does, and obstinately remains transparent. The
code demonstrating this bug is attached. Note that the code compiles and
runs, but the panel in question refuses to accept colour.


0148 Beta
XP Professional
Pentium IV (3 GHz), 504MB RAM

The code is as follows:


void setup() {
size(700, 512, P3D);

background (255) ;
stroke(0);
strokeWeight (1);
frameRate(5);




xValues = new float [5] [20] ;
yValues = new float [5] [20] ;
zValues = new float [5] [20] ;
}



float zBaseline = -200 ;

float [][] xValues, yValues, zValues;

float y = 8 ; /// y=170 (rotate Y) to see spout colour problem
(zBaseline = -110)


void draw () {

background (255) ;
// camera(width*(2), height/2.0, (height/2.0) / tan(PI*60.0 / 360.0),
width/2.0, height/2.0, 0, 0, 1, 0); // default values


y = y+1 ; println ("y = " + y) ;
if (y==24) {y = 7 ;}
//camera (width/2.0, height/2.0, (height/2.0) / tan(PI*60.0 / 360.0),
width/2.0, height/2.0, 200, 0, 1, 0);

// rotateZ ((PI/24)* (y/2));
// rotateX (PI/2) ;
rotateX ((PI/24)*(y/2));
// rotateY ((PI/24)*(18));


Layer (125, 40, 4) ; // top layer (float yBaseline, int hyp, int layer)
Layer (150, 40, 3) ;
Layer (215, 150, 2) ;
Layer (300, 150, 1) ;
Layer (350, 90, 0) ; // bottom layer


stroke (0) ;

for (int r=0 ; r < 4 ; r ++) { // where 'r' represents layer

for (int s=0 ; s < 12 ; s++) { // loop to draw one layer's facets

int q = 0 ;
if (s !=11) {
q = s + 1 ;
}


if (r==0) {fill (255, 225, 0) ; } // fill with yellow
if (r==1) {fill (200, 225, 0) ; } // fill with green
if (r==2) {fill (200, 200, 0) ; } // fill with dark green



panel (r, r+1, s, q) ; // println ("r , s, q ---> " + r + ", " + s + "
," + q);
}
}



stroke (0) ;

fill (200);

spout() ;

fill (255,0,0);
handle();
}


void handle() {

float thinner = 10 ; int Panel = 11 ;
int handleDepth = 50; float GripThinner = thinner + 15 ;


println (xValues [2] [0] + " , " + zValues [2] [0]);
println (xValues [2] [1] + " , " + zValues [2] [1]);


beginShape(); // upper surface of handle
vertex (xValues [2] [Panel], 240, (zValues [2] [Panel]-thinner));
vertex (xValues [2] [Panel] - handleDepth, 240, (zValues [2]
[Panel])-GripThinner);
vertex ((xValues [2] [0]) - handleDepth, 240, (zValues [2]
[0])+GripThinner) ;
vertex (xValues [2] [0], 240, (zValues [2] [0]+thinner)) ;
endShape(CLOSE) ;

beginShape(); // lower surface of handle
vertex (xValues [2] [Panel], 275, (zValues [2] [Panel]-thinner));
vertex (xValues [2] [Panel] - handleDepth, 275, (zValues [2]
[Panel])-GripThinner);
vertex ((xValues [2] [0]) - handleDepth, 275, (zValues [2]
[0])+GripThinner) ;
vertex (xValues [2] [0], 275, (zValues [2] [0]+thinner)) ;
endShape(CLOSE) ;

beginShape(); // handle grip (closure)
vertex (xValues [2] [Panel] - handleDepth, 275, (zValues [2]
[Panel])-GripThinner);
vertex ((xValues [2] [0]) - handleDepth, 275, (zValues [2]
[0])+GripThinner) ;
vertex ((xValues [2] [0]) - handleDepth, 240, (zValues [2]
[0])+GripThinner) ;
vertex (xValues [2] [Panel] - handleDepth, 240, (zValues [2]
[Panel])-GripThinner);
endShape(CLOSE) ;

}



void spout() {

float zMax = -50 ; float zLow = -35 ;
fill (200) ;


beginShape(); // lower surface of spout
vertex (xValues [2] [5], 275.0, zValues [2] [5]); // bottom corner Low1
vertex (xValues [2] [6], 275.0, zValues [2] [6]); // bottom corner Low2
vertex ((width/2)+190, 200, zBaseline - zMax) ; // top corner High2
vertex ((width/2)+190, 200, zBaseline - zLow) ; // top corner High1
endShape(CLOSE) ;

beginShape(); // upper surface of spout
vertex (xValues [2] [5], 260, zValues [2] [5]); // bottom corner Low8
vertex (xValues [2] [6], 260, zValues [2] [6]); // bottom corner Low9
vertex ((width/2)+180, 200, zBaseline - zMax) ; // top corner High9
vertex ((width/2)+180, 200, zBaseline - zLow) ; // top corner High8
endShape(CLOSE) ;

beginShape(); // distant surface of spout
vertex (xValues [2] [5], 275.0, zValues [2] [5]); // bottom corner Low1
vertex (xValues [2] [5], 260, zValues [2] [5]); // bottom corner Low8

vertex ((width/2)+180, 200, zBaseline - zLow) ; // top corner High9
vertex ((width/2)+190, 200, zBaseline - zLow) ; // top corner High2

endShape(CLOSE) ;



beginShape(); // nearest surface of spout
vertex (xValues [2] [6], 275.0, zValues [2] [6]); // bottom corner Low2
vertex (xValues [2] [6], 260, zValues [2] [6]); // bottom corner Low9
vertex ((width/2)+180, 200, zBaseline - zMax) ; // top corner High8
vertex ((width/2)+190, 200, zBaseline - zMax) ; // top corner High1
endShape(CLOSE) ;

}

void panel (int layerA, int layerB, int start, int next) {
beginShape();
vertex(xValues [layerA] [start], yValues [layerA] [start], zValues [layerA]
[start]);
vertex(xValues [layerB] [start], yValues [layerB] [start], zValues [layerB]
[start]);
vertex(xValues [layerB] [next], yValues [layerB] [next], zValues [layerB]
[next]);
vertex(xValues [layerA] [next], yValues [layerA] [next], zValues [layerA]
[next]);
endShape(CLOSE);
}


void Layer(float yBaseline, int hyp, int layer) {


for (int increment = 0 ; increment < 12 ; increment++){
float tetha = ((PI/12) + (TWO_PI/12) * increment) ;
float deg = degrees(tetha); // println ("the angle is " + deg + " whilst
the increment is " + increment);


float adjacent = hyp * cos(tetha) ;
float opposite = hyp * sin(tetha) ;

point (350 - adjacent, yBaseline, zBaseline - opposite) ;


xValues [layer] [increment] = (width/2) - adjacent ;
yValues [layer] [increment] = yBaseline ;
zValues [layer] [increment] = zBaseline - opposite ;
}
}
Additional Comment #1 From fry 2009-03-17 09:57
can you make a simpler example? this code would take me a while to figure
out just what's going on before even getting to any potential bug.
Additional Comment #2 From fry 2009-03-17 09:58
*** Bug 1211 has been marked as a duplicate of this bug. ***
Additional Comment #3 From MaltaCross 2009-03-18 02:49
(In reply to comment #1)


Hi Fry

please find newer version of code hereunder. Please run this code on
Processing first (the code should compile and run), and then note my
comments hereunder. Also note that clicking on the mouse will freeze the
frame, whilst reclicking will resume the 3D motion.

I tried to simplify this as much as possible. I will try and make the code
clearer.

This demo draws a 3D pot. To the right of the pot there is a greyish spout
attached, whilst on the left the pot has a red handle attached.

The spout is drawn with the method spout(), and the handle is drawn with
the method handle(). These methods work fine, and are not the problem.

The pot is made up of four "rings", with the very top ring representing the
neck of the pot. The top two rings are dark green, the next is a brighter
shade of green, whilst the bottom ring of the pot is yellow.

Each ring is filled in with colour, through the method panel(), whilst the
vertex points of each facet in the panel, are calculated with the method
layer().

As the demo shows, all the facets of the four rings fill up with the
intended colour. The only exception is the facet to which the red handle is
attached, and the facet that is directly underneath it.

All efforts to colour these two panels have failed, and therein lies the
bug which I have discovered. All assistance would be most welcome.

The new code is as follows:


void setup() {
size(700, 512, P3D);

background (255) ;
stroke(0);
strokeWeight (1);
frameRate(5);




xValues = new float [5] [20] ;
yValues = new float [5] [20] ;
zValues = new float [5] [20] ;
}



float zBaseline = -200 ;

float [][] xValues, yValues, zValues;

float y = 8 ;


void draw () {

background (255) ;


y = y+1 ; println ("y = " + y) ;
if (y==24) {y = 7 ;}


// rotateZ ((PI/24)* (y/2));
// rotateX (PI/2) ;
rotateX ((PI/24)*(y/2));
// rotateY ((PI/24)*(18));


Layer (125, 40, 4) ; // top layer (float yBaseline, int hyp, int layer)
Layer (150, 40, 3) ;
Layer (215, 150, 2) ;
Layer (300, 150, 1) ;
Layer (350, 90, 0) ; // bottom layer


stroke (0) ;

for (int r=0 ; r < 4 ; r ++) { // where 'r' represents layer

for (int s=0 ; s < 12 ; s++) { // loop to draw one layer's facets

int q = 0 ;
if (s !=11) {
q = s + 1 ;
}


if (r==0) {fill (255, 225, 0) ; } // fill with yellow
if (r==1) {fill (200, 225, 0) ; } // fill with green
if (r==2) {fill (200, 200, 0) ; } // fill with dark green



panel (r, r+1, s, q) ;
}
}



stroke (0) ;

fill (200);

spout() ;

fill (255,0,0);
handle();
}



float v=0.0 ;
void mousePressed () {

v=v+1 ;
println (mouseX + ", " + mouseY);

if ((v%2)==1) {noLoop() ; print ("y = " + y);} else loop();
}


void handle() {

float thinner = 10 ; int Panel = 11 ;
int handleDepth = 50; float GripThinner = thinner + 15 ;


println (xValues [2] [0] + " , " + zValues [2] [0]);
println (xValues [2] [1] + " , " + zValues [2] [1]);


beginShape(); // upper surface of handle
vertex (xValues [2] [Panel], 240, (zValues [2] [Panel]-thinner));
vertex (xValues [2] [Panel] - handleDepth, 240, (zValues [2]
[Panel])-GripThinner);
vertex ((xValues [2] [0]) - handleDepth, 240, (zValues [2]
[0])+GripThinner) ;
vertex (xValues [2] [0], 240, (zValues [2] [0]+thinner)) ;
endShape(CLOSE) ;

beginShape(); // lower surface of handle
vertex (xValues [2] [Panel], 275, (zValues [2] [Panel]-thinner));
vertex (xValues [2] [Panel] - handleDepth, 275, (zValues [2]
[Panel])-GripThinner);
vertex ((xValues [2] [0]) - handleDepth, 275, (zValues [2]
[0])+GripThinner) ;
vertex (xValues [2] [0], 275, (zValues [2] [0]+thinner)) ;
endShape(CLOSE) ;

beginShape(); // handle grip (closure)
vertex (xValues [2] [Panel] - handleDepth, 275, (zValues [2]
[Panel])-GripThinner);
vertex ((xValues [2] [0]) - handleDepth, 275, (zValues [2]
[0])+GripThinner) ;
vertex ((xValues [2] [0]) - handleDepth, 240, (zValues [2]
[0])+GripThinner) ;
vertex (xValues [2] [Panel] - handleDepth, 240, (zValues [2]
[Panel])-GripThinner);
endShape(CLOSE) ;

}



void spout() {

float zMax = -50 ; float zLow = -35 ;
fill (200) ;


beginShape(); // lower surface of spout
vertex (xValues [2] [5], 275.0, zValues [2] [5]); // bottom corner Low1
vertex (xValues [2] [6], 275.0, zValues [2] [6]); // bottom corner Low2
vertex ((width/2)+190, 200, zBaseline - zMax) ; // top corner High2
vertex ((width/2)+190, 200, zBaseline - zLow) ; // top corner High1
endShape(CLOSE) ;

beginShape(); // upper surface of spout
vertex (xValues [2] [5], 260, zValues [2] [5]); // bottom corner Low8
vertex (xValues [2] [6], 260, zValues [2] [6]); // bottom corner Low9
vertex ((width/2)+180, 200, zBaseline - zMax) ; // top corner High9
vertex ((width/2)+180, 200, zBaseline - zLow) ; // top corner High8
endShape(CLOSE) ;

beginShape(); // distant surface of spout
vertex (xValues [2] [5], 275.0, zValues [2] [5]); // bottom corner Low1
vertex (xValues [2] [5], 260, zValues [2] [5]); // bottom corner Low8

vertex ((width/2)+180, 200, zBaseline - zLow) ; // top corner High9
vertex ((width/2)+190, 200, zBaseline - zLow) ; // top corner High2

endShape(CLOSE) ;



beginShape(); // nearest surface of spout
vertex (xValues [2] [6], 275.0, zValues [2] [6]); // bottom corner Low2
vertex (xValues [2] [6], 260, zValues [2] [6]); // bottom corner Low9
vertex ((width/2)+180, 200, zBaseline - zMax) ; // top corner High8
vertex ((width/2)+190, 200, zBaseline - zMax) ; // top corner High1
endShape(CLOSE) ;

}

void panel (int layerA, int layerB, int start, int next) {
beginShape();
vertex(xValues [layerA] [start], yValues [layerA] [start], zValues [layerA]
[start]);
vertex(xValues [layerB] [start], yValues [layerB] [start], zValues [layerB]
[start]);
vertex(xValues [layerB] [next], yValues [layerB] [next], zValues [layerB]
[next]);
vertex(xValues [layerA] [next], yValues [layerA] [next], zValues [layerA]
[next]);
endShape(CLOSE);
}


void Layer(float yBaseline, int hyp, int layer) {


for (int increment = 0 ; increment < 12 ; increment++){
float tetha = ((PI/12) + (TWO_PI/12) * increment) ;
float deg = degrees(tetha);


float adjacent = hyp * cos(tetha) ;
float opposite = hyp * sin(tetha) ;

point (350 - adjacent, yBaseline, zBaseline - opposite) ;


xValues [layer] [increment] = (width/2) - adjacent ;
yValues [layer] [increment] = yBaseline ;
zValues [layer] [increment] = zBaseline - opposite ;
}
}
Additional Comment #4 From MaltaCross 2009-03-25 07:07
Hi Mr Fry

dare I ask if you had any time to run the code yet?
Additional Comment #5 From fry 2010-02-17 19:30
this is still a ton of code, there are dozens of things that could be
wrong. i need something more specific that would show the problem, because
this isn't something that's ever been reported. is it possible to cull this
down to 5-10 lines that show the issue?
Additional Comment #6 From MaltaCross 2010-02-18 02:51
If the code is cut down, the problem with the obstinately transparent panel will not be
that evident, I think.

May I dare ask if you have copied and pasted the code to Processing, ran it, and
visually verified what the problem is, please?

I am willing to explain the code in detail if you wish. Basically, the draw() routine
consists of drawing a teapot made up four circular layers, plus a spout() and a handle
(). The panel to which the handle affixes remains transparent, whereas it should be
coloured in line with the ring of panels of which it is part of.

The coordinates of the four layers are given at lines 41 to 45. Lines 60 to 62 are
responsible to colour each layer. Accordingly, the transparent panel should instead
show up in colour as per line 61. Instead, it is transparent!
Additional Comment #7 From fry 2010-02-18 05:52
you're getting a tesselation error, usually this is because of an error in
the code where a vertex on a shape is coming back and meeting itself, or a
NaN value for one of the vertices.

but if you don't want to debug your code, you can just change it--these
shouldn't be drawn as polygons. use beginShape(QUAD) which will be more
efficient, and the problem goes away.
Additional Comment #8 From MaltaCross 2010-02-19 06:57
Thanks for your kind advice. An interesting suggestion!