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

Saturday, 26 November 2011

Further Prototyping of my Povwriter Library in ruby-processing

Update 22 December I have gone on to modify my java povwriter library, incorporating some of ideas developed here. This sketch is incompatible with that new library, however old library is still available here.

It really is much easier to prototype in ruby/ruby processing vs java/vanilla processing. Recently I had the idea of splitting up the povray files as follows:-
  1. pov.ini to hold size (resolution) and quality (ray-trace parameter
  2. pov.pov to hold template (camera/background etc)
  3. pov.inc to hold mesh data etc from the processing sketch
In this iteration of prototyping I get to do 1 and 2, as 3 will involve a rewrite of my povwriter library, which I'm putting off until is clear whether beginRaw/endRaw will work in processing 2.0 (scheduled for release in Spring 2012?). I have decided less is definetly more for my gui, there are now only 3 quality options and the raytrace button now also initiates the recording of the PovRAY files as well as starting PovRAY. Further I've split the ini writer/povray runner into a new class as follows:-



# Demonstrates how you can use my povwriter libary
# in Ruby-Processing, to export to PovRAY

load_libraries 'povwriter', 'control_panel'
import 'povexport'
require 'ini_writer'

DATA = [-1, 0, 1]
attr_reader :exporter, :precord, :pquality, :type, :pview, :povfile

def setup
  size 1000, 1000, P3D
  @povfile = "balls.pov"
  @precord = false
  @pview = false
  @exporter = PovExporter.new self
  control_panel do |c|
    c.title = "Render as PovRAY"
    c.menu(:quality, ['instant', 'medium', 'high'], 'instant') {|m| load_quality_choice(m) }
    c.button :choose_template
    c.button :raytrace
    c.button :exit!
  end
  # uncomment next enter the path to povray executable on mac/windows/linux (or possibly jedit linux)  
  exporter.set_povray_path('/usr/local/bin/povray') # choice is saved in '.povwriter/povwriter.properties'
  # uncomment following line to adjust degenerate triangle cut off (area squared)
  # export.set_epsilon("0.001")
  exporter.store_settings    # uncomment this line to save settings   
  no_stroke
  sphere_detail(18)
end

def draw
  lights          # this needs to be outside the record loop
  if (precord)
    no_lights     # let PovRAY do the lighting
    no_loop       # don't loop while recording sketch
    begin_raw("povexport.RawPovray", data_path(povfile))
  end
  if pview
    pov_image = load_image(data_path(povfile.gsub("pov", "png")))
    update_pixels
    background(255) # clear the screen   
    image(pov_image, 0, 0)
  else
    render
  end
  if (precord)
    end_raw
    @precord = false
    puts "done recording"
    trace = IniWriter.new(data_path(povfile), width, height, pquality)
    trace.raytrace exporter.get_povray_path
    @pview = true
  end
end

def exit!
  exit
end

def render()
  background(0)
  translate(width*0.7, height/2, -width)
  DATA.each do |y|
    DATA.each do |x|
      DATA.each do |z|
        push_matrix
        translate(120*x, 120*y, 120*z)
        fill(rand * 255, rand * 255, rand * 255) # a nice test for my colorFactory class
        exporter.sphere(60) # use a better sphere primitive for ray tracing
        pop_matrix
      end
    end
  end
end



################################### Independent of sketch ############################

def raytrace
  @precord = true
end

def choose_template
  exporter.choose_template
end

def load_quality_choice(item)
  @pquality = item
end



Here is the ini writer class..................

require 'pathname'

INI = {'instant' => 'quick.ini', 'medium' => 'medium.ini', 'high' => 'quality.ini'}
QUALITY = {'instant' => 4, 'medium' => 6, 'high' => 11}

class IniWriter

  attr_reader :name, :width, :height, :qual, :base, :ini
 def initialize name, width, height, qual
   @name, @width, @height, @qual = name, width, height, qual
   init
 end

 def init
   @base = File.dirname(name)
   if (QUALITY[qual] < 6 && width > 300)
     @height *= 300.0/width
     @width = 300
   end
 end

 def write
   @ini = File.join(base, INI[qual])
   file = open(ini, 'w')
   file.puts("; #{ini}")
   file.puts("Input_File_Name='#{name}'")
   file.puts("width=#{width}")
   file.puts("height=#{height}")
   file.puts("quality=#{QUALITY[qual]}")
   file.puts("Antialias=true") unless QUALITY[qual] < 10
   file.puts("Output_File_Type=N8")
   file.puts("Output_File_Name='#{name.gsub('pov', 'png')}'")
   file.close
 end

 def raytrace povray_path
   write
   system([povray_path, ini].join(" "))
 end
end


Wednesday, 16 November 2011

Exporting Sketches from Ruby-Processing to PovRAY, features control panel

It has taken a lot longer that it should have done, but finally I got round to exploring my vanilla processing povwriter library in ruby processing. Thanks to the latest version of ruby-processing, we can use the vanilla processing library from the sketchbook folder. This works fine and dandy at present, but I can foresee potential conflicts with libraries that have been modified to run with processing-2.0, but then lots of libraries are probably going to get screwed along the way to the new version (my povwriter library for one does not work with processing-2.0). Here's one of my povwriter example files translated to ruby:-



# Demonstrates how you can use my povwriter libary
# in Ruby-Processing, to export to PovRAY

load_libraries 'povwriter', 'control_panel'
import 'povexport'

DATA = [-1, 0, 1]
attr_reader :exporter, :precord, :pquality, :type, :pview, :memory, :povfile

def setup
  size 300, 300, P3D
  @povfile = "balls.pov"
  @precord = false
  @exporter = PovExporter.new self
  control_panel do |c|
    c.title = "Render as PovRAY"
    c.menu(:quality, ['low', 'medium', 'high', 'highest'], 'high') {|m| load_quality_choice(m) }
    c.menu(:image_type, ['png', 'jpeg', 'tga'], 'png') {|m| load_image_type(m) }
    c.menu(:memory, ['low', 'default', 'high', 'none'], 'default') {|m| load_memory_choice(m) }
    c.checkbox :antialias
    c.button :choose_template
    c.button :record
    c.button :raytrace
    c.button :view
    c.button :exit!
  end
  # uncomment next enter the path to povray executable on mac/windows/linux (or possibly jedit linux)  
  exporter.set_povray_path('/usr/local/bin/povray') # choice is saved in '.povwriter/povwriter.properties'
  # uncomment following line to adjust degenerate triangle cut off (area squared)
  # export.set_epsilon("0.001")
  exporter.store_settings    # uncomment this line to save settings   
  no_stroke
  sphere_detail(18)
end

def draw
  lights          # this needs to be outside the record loop
  if (precord)
    no_lights   # let PovRAY do the lighting
    no_loop       # don't loop while recording sketch
    begin_raw("povexport.RawPovray", data_path(povfile))
  end
  if pview
    background(0) # clear the screen
    image(load_image(data_path("balls.png")), 0, 0)
    no_loop
  else
    render
  end
  if (precord)
    end_raw
    @precord = false
    puts "done recording"
    loop
  end
end

def exit!
  exit
end

def render()
  background(0)
  translate(width*0.7, height/2, -width)
  DATA.each do |y|
    DATA.each do |x|
      DATA.each do |z|
        push_matrix
        translate(120*x, 120*y, 120*z)
        fill(rand * 255, rand * 255, rand * 255) # a nice test for my colorFactory class
        exporter.sphere(60) # use a better sphere primitive for ray tracing
        pop_matrix
      end
    end
  end
end

################################### Independent of sketch ############################
def record
  @precord = true
end

def raytrace
  Kernel.system([exporter.get_povray_path, povray_options, povray_scene].join(" "))
end

def choose_template
  exporter.choose_template
end

def view
  @pview = true
end

def povray_scene
  return "+I#{data_path(povfile)}"
end

def povray_options
  aa = @antialias ? "+A" : ""
  return "+IM#{memory} +W#{width} +H#{height} +Q#{pquality} #{aa} +F#{type}"
end


def load_quality_choice(item)
  map = {'low' => 0, 'medium' => 5, 'high' => 9, 'highest' => 11}
  @pquality = map[item]
end

def load_memory_choice(item)
  map = {'low' => 56, 'default' => 128, 'high' => 1024, 'none' => 0}
  @memory = map[item]
end

def load_image_type(item)
  map = {'png' => 'N', 'jpeg' => 'J', 'tga' => 'C'}
  @type = map[item]
end

Sketch now modified to use the excellent control panel of ruby-processing. Here I am using a custom sphere for raytracing, ideally I would just call the PovRAY sphere primitive, but that is a bit more complicated than it appears at first sight (see my vanilla processing blog). Presently everything is exported as a simple triangle mesh (ideally this would be a PovRAY mesh2 object). Make life easy for yourself and wrap drawing logic in a function such as render. Click on images below to see full size....

Live Display of PovRAY rendering

Viewing Rendered image in processing sketch



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