Since the release of the toxiclibs gem (example below use gem version 0.3.0.pre), it is now quite easy to work with the toxiclibs libraries in JRubyArt see sketch below. This being a bare sketch should be run with 'k9 run implicit.rb'
require 'toxiclibs'
load_library :mesh_to_vbo
RES = 64
ISO = 0.2
MAX_ISO = 0.66
attr_reader :mesh, :vbo, :curr_zoom, :implicit
def setup
size(720,720, P3D)
Processing::ArcBall.init(self)
@vbo = MeshToVBO.new(self)
@curr_zoom = 1
vol = EvaluatingVolume.new(TVec3D.new(400,400,400), RES, RES, RES, MAX_ISO)
surface = Volume::HashIsoSurface.new(vol)
@mesh = Toxi::WETriangleMesh.new
surface.compute_surface_mesh(mesh, ISO)
@is_wire_frame = false
no_stroke
@implicit = vbo.meshToVBO(mesh, true)
implicit.setFill(color(222, 222, 222))
implicit.setAmbient(color(50, 50, 50))
implicit.setShininess(color(10, 10, 10))
implicit.setSpecular(color(50, 50, 50))
end
def draw
background(0)
lights
define_lights
shape(implicit)
end
def key_pressed
case key
when 'l', 'L'
Toxi::LaplacianSmooth.new.filter(mesh, 1)
@implicit = vbo.meshToVBO(mesh, true)
implicit.setFill(color(222, 222, 222))
implicit.setAmbient(color(50, 50, 50))
implicit.setShininess(color(10, 10, 10))
implicit.setSpecular(color(50, 50, 50))
when 's', 'S'
save_frame("implicit.png")
end
end
def define_lights
ambient_light(50, 50, 50)
point_light(30, 30, 30, 200, -150, 0)
directional_light(0, 30, 50, 1, 0, 0)
spot_light(30, 30, 30, 0, 40, 200, 0, -0.5, -0.5, PI / 2, 2)
end
class EvaluatingVolume < Volume::VolumetricSpace
attr_reader :upper_bound, :lut
FREQ = Math::PI * 3.8
def initialize(scal_vec, resX, resY, resZ, upper_limit)
super(scal_vec, resX, resY, resZ)
@upper_bound = upper_limit
end
def clear
end
def getVoxelAt(i)
getVoxel(i % resX, (i % sliceRes) / resX, i / sliceRes)
end
def getVoxel(x, y, z)
val = 0
if (x > 0 && x < resX1 && y > 0 && y < resY1 && z > 0 && z < resZ1)
xx = x * 1.0 / resX - 0.5
yy = y * 1.0 / resY - 0.5
zz = z * 1.0 / resZ - 0.5
val = Math.cos(xx * FREQ) * Math.sin(yy* FREQ) + Math.cos(yy* FREQ) * Math.sin(zz* FREQ) + Math.cos(zz* FREQ)* Math.sin(xx* FREQ)
if (val > upper_bound)
val = 0
end
end
return val
end
end
The library code:-
class MeshToVBO
PShape = Java::ProcessingCore::PShape
attr_reader :parent
def initialize(parent)
@parent = parent
end
def meshToVBO(mesh, smth)
retained = parent.create_shape
retained.begin_shape(PShape::TRIANGLES)
if smth
mesh.compute_vertex_normals
mesh.getFaces.each do |f|
retained.normal(f.a.normal.x, f.a.normal.y, f.a.normal.z)
retained.vertex(f.a.x, f.a.y, f.a.z)
retained.normal(f.b.normal.x, f.b.normal.y, f.b.normal.z)
retained.vertex(f.b.x, f.b.y, f.b.z)
retained.normal(f.c.normal.x, f.c.normal.y, f.c.normal.z)
retained.vertex(f.c.x, f.c.y, f.c.z)
end
else
mesh.get_faces.each do |f|
retained.normal(f.normal.x, f.normal.y, f.normal.z)
retained.vertex(f.a.x, f.a.y, f.a.z)
retained.vertex(f.b.x, f.b.y, f.b.z)
retained.vertex(f.c.x, f.c.y, f.c.z)
end
end
retained.end_shape
retained
end
def meshToRetained(mesh, smth)
mesh.map { |m| meshToVBO(m, smth) }
end
end