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

Saturday 4 February 2012

Using the Control Panel With Toxiclibs

Here is a recent sketch modified to use the ruby processing control panel (doesn't want to work with opengl with current release), next obvious variant to include sliders for resolution and or upper and lower boundary levels.
#
# This example implements a custom VolumetricSpace using an implicit function
# to calculate each voxel. This is slower than the default array or HashMap
# based implementations, but also has much less memory requirements and so might
# be an interesting and more viable approach for very highres voxel spaces
# (e.g. >32 million voxels). This implementation here also demonstrates how to
# achieve an upper boundary on the iso value (in addition to the one given and
# acting as lower threshold when computing the iso surface)
#
# Copyright (c) 2010 Karsten Schmidt & ruby-processing version Martin Prout 2012
# This sketch relies on a custom toxiclibscore library for PovRAY export, and
# features the ruby-processing control panel (doesn't seem to work with opengl)
# This library is free software you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation either
# version 2.1 of the License, or (at your option) any later version.
# 
# http://creativecommons.org/licenses/LGPL/2.1/
# 
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
# 
# You should have received a copy of the GNU Lesser General Public
# License along with this library if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#

load_libraries 'toxiclibscore', 'toxiclibs_p5', 'volumeutils', 'control_panel'
include_package 'toxi.geom'
include_package 'toxi.geom.mesh'
include_package 'toxi.volume'
include_package 'toxi.processing'

RES = 64
ISO = 0.2
MAX_ISO = 0.66

attr_reader :mesh, :gfx, :is_wire_frame, :curr_zoom

def setup()
  size(720,720, P3D)
  @curr_zoom = 1.0
  control_panel do |c|
    c.title = "Implicit Function"
    c.slider :curr_zoom, 0.5..4.0, 1.0
    c.button :wire_frame_view
    c.button :smooth
    c.button :save_sketch_view
    c.button :export_to_povray
    c.button :exit!
  end
  @gfx = ToxiclibsSupport.new(self)
  vol = EvaluatingVolume.new(Vec3D.new(400,400,400), RES, RES, RES, MAX_ISO)
  surface = HashIsoSurface.new(vol)
  @mesh = WETriangleMesh.new()
  surface.compute_surface_mesh(mesh, ISO)
  @is_wire_frame = false
end

def draw()
  background(0)
  translate(width / 2.0, height / 2.0, 0)
  rotate_x(mouse_y * 0.01)
  rotate_y(mouse_x * 0.01)
  scale(curr_zoom)
  if (is_wire_frame)
    no_fill()
    stroke(255)
  else
    fill(255)
    no_stroke()
    lights()
  end
  @gfx.mesh(mesh, true)
end

def wire_frame_view
  @is_wire_frame = !is_wire_frame
end

def smooth
  LaplacianSmooth.new().filter(mesh, 1)
end

def export_to_povray
  file_id = "implicit"
  pw = create_writer(file_id + ".inc")
  mesh.saveAsPOV(pw)
  pw.flush()
  pw.close()
  exit()
end

def save_sketch_view
  save_frame("implicit.png")
end

class EvaluatingVolume < VolumetricSpace
  include Processing::Proxy
  include_package 'toxi.math'
  attr_reader :upper_bound, :lut
  FREQ = PI * 3.8

  def initialize(scal_vec, resX, resY, resZ, upper_limit)
    super(scal_vec, resX, resY, resZ)
    @upper_bound = upper_limit
    @lut=SinCosLUT.new()
  end

  def clear()
    # nothing to do here
  end

  def getVoxelAt(i)
    getVoxel(i % resX, (i % sliceRes) / resX, i / sliceRes)
  end

  def getVoxel(x, y, z)  # can't overload so we renamed
    val = 0
    if (x > 0 && x < resX1 && y > 0 && y < resY1 && z > 0 && z < resZ1)
      xx = x * 1.0 / resX - 0.5  # NB: careful about integer division !!!
      yy = y * 1.0 / resY - 0.5
      zz = z * 1.0 / resZ - 0.5
      #val = lut.sin(xx * FREQ) + lut.cos(yy * FREQ) + lut.sin(zz * FREQ)
      val = lut.sin(xx * FREQ) * (xx * FREQ) + lut.sin(yy * FREQ) * (yy * FREQ) + lut.sin(zz * FREQ) * (zz * FREQ)
      #val = lut.cos(xx * FREQ) * lut.sin(yy* FREQ) + lut.cos(yy* FREQ) * lut.sin(zz* FREQ) + lut.cos(zz* FREQ)* lut.sin(xx* FREQ);
      if (val > upper_bound)
        val = 0
      end
    end
    return val
  end
end
Screenshot of ruby processing sketch

No comments:

Post a Comment

Followers

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