WB_Render3D::drawTriangle() got 6 overloaded versions of it:
And outta those 6, there are 2 w/ the 1 parameter signature that is a container:
And 1 w/ 1 parameter that is a single WB_Triangle:
Method WB_IsoSurface::getTriangles() returns a List<WB_Triangle>:
But if we call print type(triangles)
, we’ll find out its actual datatype is:
<type 'org.eclipse.collections.impl.list.mutable.FastList'>
Eclipse.org/collections/javadoc/9.0.0/org/eclipse/collections/impl/list/mutable/FastList.html
Now it seems like when we invoke render.drawTriangle(triangles)
, the overloaded signature chosen is:
Which causes processing.app.SketchException: java.lang.ClassCastException: wblut.geom.WB_Triangle cannot be cast to wblut.geom.WB_Coord
But what we’re looking for is this 1:
I’ve tried searching for some Jython builtin way to force a method invocation to pick a specific signature.
However, if there’s 1, it’s unpublished or it’s almost impossible to find!
As a workaround, I’ve attempted Java’s reflection capabilities.
-
Class::getMethod():
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Class.html#getMethod(java.lang.String,java.lang.Class...) -
Method::invoke():
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/reflect/Method.html#invoke(java.lang.Object,java.lang.Object...)
There’s a subtle diff. between the container parameter type signatures.
The 1 for WB_Coord is a List, but the 1 for WB_Triangle is a Collection.
So in order to grab the overloaded method signature we need we do like this:
method = WB_Render.getMethod('drawTriangle', Collection)
Now, inside draw(), we replace render.drawTriangle(triangles)
w/ method.invoke(render, triangles)
.
Here’s the full sketch solution:
"""
Ref_WB_IsoSurface (v1.0.1)
ported by GoToLoop (2019-Feb-21)
https://Discourse.Processing.org/t/
issue-when-porting-an-example-sketch-from-the-
hemesh-library-to-python-mode/8570/6
https://GitHub.com/wblut/HE_Mesh/blob/master/examples/
geom/isosurface/Ref_WB_IsoSurface/Ref_WB_IsoSurface.pde
"""
add_library('hemesh')
from java.util import Collection
METHOD = WB_Render.getMethod('drawTriangle', Collection)
DIM, N = 51, .07
DRANGE = tuple(range(DIM))
BG, FG, FILL = 070, 0, -1
FPS = 'FPS: '
def setup():
size(800, 700, P3D)
smooth(8)
fill(FILL)
stroke(FG)
creator = WB_IsoSurface()
creator.setSize(8, 8, 8)
creator.isolevel = .6
creator.boundary = -200
creator.gamma = .3
creator.invert = False
creator.setValues(
[[[noise(N*x, N*y, N*z) for z in DRANGE]
for y in DRANGE] for x in DRANGE]
)
global render, triangles
render, triangles = WB_Render(this), creator.triangles
def draw():
background(BG)
lights()
translate(width>>1, height>>1)
rotateY(TAU * mouseX / width)
rotateX(TAU * mouseY / height)
# render.drawTriangle(triangles) # invokes wrong sig!
METHOD.invoke(render, triangles)
this.surface.title = FPS + `this.round(frameRate)`