Closed enzyme69 closed 10 years ago
There seems to be an issue with n-gon drawing code, it is open GL related, the GL_POLYGON option on only works for concave convex polygons (it might work otherwise but no guarantee).
More about the issue: http://stackoverflow.com/questions/15556929/open-gl-polygon
How to resolve... Hmm don't remember enough about Open GL for that right now.
Drag the degrees slider, and it seems that this is down to drawing polygons from a fan.
Yes I confirm that, something to do with concave and convex. If I go the opposite direction (minus), it is okey. Zeffii explained it well.
By the way, Linus, with "Vectorized Input" and List Input, do we have 30 = maximum Limit on Circles?
Look something weird happens: https://www.dropbox.com/s/vvyjeghk3apyoll/procedural_star_006.blend
Yes GL_POYGON does a triangle fan starting from vert nr 0.
@enzyme69 Well List Input is limited to 32 values for int or float, for pratcial reasons, for more than that I think text input (which is not working properly right now) is the better answer. But you can also use List Join for unlimited (or atleast something like 64*32 values). For vector the limit is 10. But the input into Circle is limited by your computers memory more than anything else. To test make 100 circles like below.
I see, thanks again for this explanation. Maybe I do it like this next time. Safer and more predictable.
But there is something strange in your example, you only have 6*5 matrix from the plane input and if ones sets to 6x6 to get 36 as the number of circles you make something goes wrong with last one. Hmm
Aha...
This is pretty interesting already. Can make my procedural Mandala now.
one circle, one kdtree edges. bam. mandala
:+1: It was List Match then KDTree... let's make Turtle and Tree and LSystem.
Also discovered that sometimes we get callbacks that aren't disabled when using undo a lot. I guess hash(node) #116 is not stable on undo or there is something else going on. Anyway lets focus on the GL_POLYGON issue in this tread.
it's a tricky one, fix it one way and up will pop a scenario where the fix is also not desirable. The best way to go is to stick with convex polygons Jimmy, and clever lists constructing.
The proper way I guess is to tesselate the ngon when drawing it.
yeah, tesselation..I think blender has a function call for that
Some cases might be too complex since one easily can construct faces that simply can't be drawn in rational way with ngons. But a case like this we should be able to handle I think.
There should be some opengl solutions also.
http://www.blender.org/documentation/blender_python_api_2_70a_release/mathutils.geometry.html
mathutils.geometry.tessellate_polygon(veclist_list)
Takes a list of polylines (each point a vector) and returns the point indices for a polyline filled with triangles.
Seems to work well, should be restructured I guess so we call per obj and not per face.
Ugly test code:
v=[data_vector[k][i] for i in pol]
tess_poly=mathutils.geometry.tessellate_polygon([v])
for a,b,c in tess_poly:
glVertex3f(*(data_matrix[i]*data_vector[k][a]))
glVertex3f(*(data_matrix[i]*data_vector[k][b]))
glVertex3f(*(data_matrix[i]*data_vector[k][c]))
Also change to
glBegin(GL_TRIANGLES)
And imported GL_TRIANGLES
Doesn't always work well, though, can't draw cylinder with the new code...
This almost works... But it looks ugly and I don't know enough about open gl.
for j, pol in enumerate(data_polygons[k]):
if shade:
normal_no_ = mathutils.geometry.normal(
data_vector[k][pol[0]],
data_vector[k][pol[1]],
data_vector[k][pol[2]]
)
normal_no = (normal_no_.angle(vectorlight,0))/math.pi
randa = (normal_no * coloa) - 0.1
randb = (normal_no * colob) - 0.1
randc = (normal_no * coloc) - 0.1
else:
randa = ((j/oblen) + coloa) / 2.5
randb = ((j/oblen) + colob) / 2.5
randc = ((j/oblen) + coloc) / 2.5
glColor3f(randa+0.2, randb+0.2, randc+0.2)
if len(pol)>4:
glBegin(GL_TRIANGLES)
v=[data_vector[k][i] for i in pol]
tess_poly=mathutils.geometry.tessellate_polygon([v])
for a,b,c in tess_poly:
glVertex3f(*(data_matrix[i]*data_vector[k][a]))
glVertex3f(*(data_matrix[i]*data_vector[k][b]))
glVertex3f(*(data_matrix[i]*data_vector[k][c]))
elif len(pol)==4:
glBegin(GL_POLYGON)
for point in pol:
vec_corrected = data_matrix[i]*data_vector[k][int(point)]
glVertex3f(*vec_corrected)
else:
glBegin(GL_TRIANGLES)
for point in pol:
vec_corrected = data_matrix[i]*data_vector[k][int(point)]
glVertex3f(*vec_corrected)
glEnd()
glPointSize(1.75)
glLineWidth(1.0)
I would be more inclined to take a hard-line and say for the time being:
don't expect ngons with concave elements to render properly
The fact that it can draw some OK is a convenience, not a final desirable solution. I would must rather have an extra 'tesselate' node.
Agreed, but it is fun to test. Leave it for now until we make an overview of the viewer draw function properly.
see my updated comment, you agree?
Yes.
Convex draws fine, concave doesn't. Somehow I get them mixed up.
cool, back to ListRange, almost testable :)
Also the place to analyse the data isn't in callbacks inner loop but in the node
so either a separate node, or a switch on draw_buttons_ext
to beautify complex ngons. or both, i'm sure it could be handy elsewhere..ie bmesh node could use it.
I was thinking we could preprocess the data a bit so the callback might run quicker and avoid some errors. Apply matrix or use gl matrix etc to avoid a lot extra work.
I realized I made a mistake and this code works for drawing concave n-gons. But it is an ugly solution solving the problem in the wrong place. I think the correct solution is to tesslate the n-gones for the viewdrawer but let bmesh and blender handle that for baking.
#######
# polygons
vectorlight = Vector((-0.66,-0.66,-0.66))
if data_polygons and data_vector:
glLineWidth(1.0)
glEnable(polyholy)
for i, matrix in enumerate(data_matrix): # object
k = i
if i > verlen:
k = verlen
oblen = len(data_polygons[k])
for j, pol in enumerate(data_polygons[k]):
if shade:
normal_no_ = mathutils.geometry.normal(
data_vector[k][pol[0]],
data_vector[k][pol[1]],
data_vector[k][pol[2]]
)
normal_no = (normal_no_.angle(vectorlight,0))/math.pi
randa = (normal_no * coloa) - 0.1
randb = (normal_no * colob) - 0.1
randc = (normal_no * coloc) - 0.1
else:
randa = ((j/oblen) + coloa) / 2.5
randb = ((j/oblen) + colob) / 2.5
randc = ((j/oblen) + coloc) / 2.5
glColor3f(randa+0.2, randb+0.2, randc+0.2)
if len(pol)>4:
glBegin(GL_TRIANGLES)
v=[data_vector[k][i] for i in pol]
tess_poly=mathutils.geometry.tessellate_polygon([v])
for a,b,c in tess_poly:
glVertex3f(*(data_matrix[i]*v[a]))
glVertex3f(*(data_matrix[i]*v[b]))
glVertex3f(*(data_matrix[i]*v[c]))
elif len(pol)==4:
glBegin(GL_POLYGON)
for point in pol:
vec_corrected = data_matrix[i]*data_vector[k][int(point)]
glVertex3f(*vec_corrected)
else:
glBegin(GL_TRIANGLES)
for point in pol:
vec_corrected = data_matrix[i]*data_vector[k][int(point)]
glVertex3f(*vec_corrected)
glEnd()
glPointSize(1.75)
glLineWidth(1.0)
glDisable(polyholy)
Ah, i forgot you were already doing this.
This does work but should we do it as a temporary solution? I don't have to time restructure the code for the viewer draw for some time and since you wanted to make a v2 anyway.
it's up to you, it won't be for a few days until I get around to this.
It is up on github now, ugly hack and all. If causes problems let us just revert and wait for mk2
it'll be useful to test that for a while anyway. perhaps a mode to select we want ngon 5+ drawing routine to have
@nortikin has been quiet probably making something crazy! :D
Yes, Nikita show something crazy, surprise us :)
Sometimes, the Viewer Draw is giving result that is not quite correct. Such as above.