Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0

Saturday 27 April 2013

Hemesh mesh to VBO (PShape) in ruby-processing

Here is a sketch, pretty rich in ruby-processing syntax, including:-
  1. The building of a multi-dimensional array in ruby
  2. The casting of a multi-dimensional ruby array to a java array of float[][]
  3. Using "each" with a java iterator (it is so easy)
  4. Using bit shifting to create a color int
  5. Using the PShape vbo object
  6. A rubified do while block
The sketch:-
load_libraries :hemesh, :vbo

include_package 'wblut.math'
include_package 'wblut.processing'
include_package 'wblut.core'
include_package 'wblut.hemesh'
include_package 'wblut.geom'

RES = 20

attr_reader :mesh_ret, :inv_mesh_ret, :render

def setup
  size(800, 800, P3D)
  smooth(8)
  values = []               # build a multi-dimensional array in ruby
  (0 .. RES).each do |i|    # the inclusive range is intentional here
    valu = []
    (0 .. RES).each do |j|
      val = []
      (0 .. RES).each do |k|
        val << 2.1 * noise(0.35 * i, 0.35 * j, 0.35 * k)
      end
      valu << val
    end
    values << valu
  end

  creator = HEC_IsoSurface.new
  creator.set_resolution(RES,RES, RES) # number of cells in x,y,z direction
  creator.set_size(400.0/RES, 400.0/RES, 400.0/RES) # cell size

  # JRuby requires a bit of help to determine correct 'java args', particulary with 
  # overloaded arrays args as seen below. Note we are saying we have an 'array' of  
  # 'float array' here, where the values can also be double[][][].

  creator.set_values(values.to_java(Java::float[][])) # the grid points

  creator.set_isolevel(1)   # isolevel to mesh
  creator.set_invert(false) # invert mesh
  creator.set_boundary(100) # value of isoFunction outside grid
  # use creator.clear_boundary to set boundary values to "no value".
  # A boundary value of "no value" results in an open mesh

  mesh = HE_Mesh.new(creator)
  # mesh.modify(HEM_Smooth.new.set_iterations(10).setAutoRescale(true))
  creator.set_invert(true)

  inv_mesh = HE_Mesh.new(creator)
  inv_mesh.modify(HEM_Smooth.new.set_iterations(10).set_auto_rescale(true))
  @render = MeshToVBO.new(self)
  no_stroke
  # no color args produces a default light grey fill
  @mesh_ret = render.meshToVBO(mesh, color(200, 0, 0))
  @inv_mesh_ret = render.meshToVBO(inv_mesh, color(0, 0, 200))
end

def draw
  background(120)
  lights
  define_lights
  translate(400, 400)
  rotate_y(mouse_x.to_f / width * TWO_PI)  # use TWO_PI until processing-2.0b9
  rotate_x(mouse_y.to_f / height * TWO_PI) # then we can use TAU
  shape(inv_mesh_ret)
  shape(mesh_ret)
end

def define_lights
  ambient(20, 20, 20)
  ambient_light(60, 60, 60)
  point_light(30, 30, 30, 0, 0, 0)
  directional_light(40, 40, 50, 1, 0, 0)
  spot_light(30, 30, 30, 0, 40, 200, 0, -0.5, 0.5, PI / 2, 2)
end

Here is the mesh to vbo library
# mesh_to_vbo.rb
module MS
  include_package 'java.util'
  include_package 'processing'
  include_package 'processing.core'
  include_package 'wblut.geom'
  include_package 'wblut.hemesh'
end

class MeshToVBO
  include Processing::Proxy
  include MS
  attr_reader :parent

  def initialize(parent)
    @parent = parent
  end

  def meshToVBO(mesh, col = nil)
    tri_mesh = mesh.get
    tri_mesh.triangulate
    retained = parent.create_shape
    retained.begin_shape(TRIANGLES)
    if col
      retained.fill(col)
    else # we will have a light grey color, created by bit shifting
      fcol = (255 >> 24) & 0xFF|(211 >> 16) & 0xFF|(211 >> 8) & 0xFF|211
      retained.fill(fcol)
    end
    retained.ambient(50)
    retained.specular(50)
    mesh.fItr.each do |face|  # call each on the hemesh mesh iterator
      he = face.getHalfedge
      begin      # this block is the ruby equivalent of do while
        vx = he.getVertex
        vn = vx.getVertexNormal
        retained.normal(vn.xf, vn.yf, vn.zf)
        retained.vertex(vx.xf, vx.yf, vx.zf)
        he = he.getNextInFace
      end while (he != face.getHalfedge)
    end
    retained.end_shape
    return retained
  end
end

No comments:

Post a Comment

Followers

Blog Archive

About Me

My photo
I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2