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

Showing posts with label mesh2. Show all posts
Showing posts with label mesh2. Show all posts

Monday, 12 March 2012

Toxiclibs InflateMesh in ruby-processing (with PovRAY export)

See vanilla processing version here for PovRAY files and a ray-traced image.
#
# Copyright (c) 2010 Karsten Schmidt & ruby-processing version Martin Prout 2012
# 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', 'povmesh', 'verletphysics'
include_package 'povmesh.mesh'
include_package 'toxi.geom'
include_package 'toxi.geom.mesh'
include_package 'toxi.physics'
include_package 'toxi.physics.behaviors'
include_package 'toxi.processing'
include_package 'toxi.physics.constraints'
include_package 'toxi.volume'

attr_reader :mesh, :gfx, :physics, :render, :box, :pm, :inflate

def setup
  size(680, 382, P3D)
  @gfx = ToxiclibsSupport.new(self)
  @pm = POVMesh.new(self)
  @render = true
  init_physics
end

def draw
  physics.update
  box.vertices.values().each { |v| v.set(physics.particles.get(v.id))}
  box.center(nil)
  box.vertices.values().each { |v| physics.particles.get(v.id).set(v)}
  box.compute_face_normals()
  box.face_outwards()
  box.compute_vertex_normals()
  background(51)
  translate(width / 2.0, height / 2.0, 0)
  rotate_x((height / 2 - mouse_x) * 0.01)
  rotate_y((width / 2 - mouse_y) * 0.01)
  no_fill
  lights
  directional_light(255, 255, 255, -200, 1000, 500)
  specular(255)
  shininess(16)
  gfx.origin(Vec3D.new, 50)
  fill(192)
  no_stroke
  if (render)
    gfx.mesh(box, true, 5)
  else
    no_loop
    pm.begin_save(java.io.File.new(sketchPath("box.inc")))
    pm.set_texture(Textures::METAL) # sequential rainbow color 1st is a red?
    pm.saveAsPOV(box)   # default smooth ie normals
    pm.end_save
    exit # no way back
  end
end

def init_physics
  @box = WETriangleMesh.new
  # create a simple start mesh
  #box.addMesh(Cone.new(Vec3D.new(0, 0, 0), Vec3D.new(0, 1, 0), 10, 50, 100).to_mesh(4))
  box.add_mesh(AABB.new(Vec3D.new, 50).to_mesh())
  # then subdivide a few times...
  4.times { box.subdivide }
  @physics = VerletPhysics.new
  physics.set_world_bounds(AABB.new(Vec3D.new, 180))
  # turn mesh vertices into physics particles
  box.vertices.values.each { |v| physics.add_particle(VerletParticle.new(v))}
  # turn mesh edges into springs
  box.edges.values.each do |e|
    a = physics.particles.get((e.a).id)
    b = physics.particles.get((e.b).id)
    physics.add_spring(VerletSpring.new(a, b, a.distance_to(b), 0.005))
  end
end


def key_pressed
  case key
  when 'r'
    init_physics
  when 's'
    @render = false
  end
end

def mouse_pressed
    @inflate = AttractionBehavior.new(Vec3D.new, 400, -0.3, 0.001)
  physics.add_behavior(inflate);
end

def mouse_released
  physics.remove_behavior(inflate)
end

Thursday, 2 February 2012

Export toxiclibs mesh from ruby-processing to PovRAY

Here is my test ruby processing sketch (using my customised toxiclibscore.jar), that exports the toxiclibs mesh as a PovRAY mesh2 object, written to a PovRAY inc file.
#######################################################################
# FtestPOV demonstrates how to save a model as PovRAY mesh2
# format to a Java PrintWriter, called with the processing convenience 
# method create_writer.
#
# Copyright (c) 2012 Martin Prout
#
# This library example 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'
include_package 'toxi.geom'
include_package 'toxi.geom.mesh'
include_package 'toxi.processing'

attr_reader :mesh, :gfx

def setup()
  size(200, 200, P3D)
  @gfx = ToxiclibsSupport.new(self)
  # define a "F" badly
  vert = AABB.fromMinMax(Vec3D.new(-1.0, -4.5, -1.0), Vec3D.new(1.0, 3.5, 1.0))
  box = AABB.fromMinMax(Vec3D.new(1.0, 1.5, -1.0), Vec3D.new(3.0, 3.5, 1.0))
  box2 = AABB.fromMinMax(Vec3D.new(1.0, -2.5, -1.0), Vec3D.new(3.0, -0.5, 1.0))
  @mesh = box.toMesh()
  mesh.addMesh(vert.toMesh())
  mesh.addMesh(box2.toMesh())
end

def draw()
  translate(width/2, height/2)
  scale(15)
  rotate_y(radians(-10))
  gfx.mesh(mesh)
end

def keyPressed()
  if (key == 'e')
    file_id = "FTest"
    pw = create_writer(file_id + ".inc")
    mesh.save_as_pov(pw, false)
    pw.flush()
    pw.close()
    exit()
  end
  if (key == 's')
    save_frame("Frb.png")
  end
end
Here is the pov file, that uses the geometry from the exported ruby-processing sketch, to create a PovRAY scene description file.
// Persistence Of Vision Ray Tracer Scene Description File
// File:  Simple Scene <template for povwriter>
// Vers: 3.7
// Date: January 2012
// Auth: Martin Prout 

#version 3.7;

global_settings{
  assumed_gamma 1.0
  radiosity{
    pretrace_start 0.04
    pretrace_end 0.01
    count 200
    recursion_limit 3
    nearest_count 10
    error_bound 0.5
  }
}

#include "colors.inc"
#include "skies.inc"
#include "FTest.inc"
#include "golds.inc"


//----------------declare scene Settings
#declare camera0 = camera {            // define additional cameras to suit viewing preferences
   location <-1.5, 30.0, -150.0>
   direction <0.0, 0.0, 2.0>
   up  <0.0, 1.0, 0.0>
   right <1.0, 0.0, 0.0>
   look_at <0.0, 25.0, 35.0>
}

#declare light0 = light_source { <100.0, 100.0, -200.0> colour White }

#declare ground0 = plane { <0.0, 1.0, 0.0>, 0.0  // a reflective ground plane
   pigment { NeonBlue }
   finish {reflection 0.15}
}

//------------------end of declare scene settings

// -----------------set the scene

camera { camera0 }              // ------------------------------------------
                                //  The use of declared values makes it possible to easily 
light_source{ light0 }          //  change the way the scene is rendered. Just define an
                                //  additional camera say for your template, and do the
sky_sphere{ S_Cloud3 }          //  substitution here. Retain the original definition and
                                //  you can easily backtrack. Definitions can also be saved
plane{ ground0 }                //  as included file see colors.inc for an example.
                                // ---------------------------------------------  
// -----------------end set the scene
object{
mesh2{aabb}                  // name aabb created by modified toxiclibs library
texture {T_Gold_1A}
scale<5, 5, 5>
rotate<0, 25, 0>
translate<0, 20, 40>
}

Processing sketch

PovRAY rendered

Export ruby-processing sketch to PovRAY mesh2

Updated 8 March hemesh library since 1.70 beta includes export code Here I present how to export from ruby-processing to PovRAY mesh2 format. The beauty of this approach is it does not rely on the processing rendering method, further the mesh2 object is better matched to PovRAY internals then raw triangles so rendering is quicker. However the major advantage is by using the normals calculated by the hemesh library (I'm using svn version 108 here) we get "smooth" surfaces (there is an option to exclude normals and view facets if desired). Here is the ruby processing sketch:-
#######################################################
# twin_iso.rb by Martin Prout aka monkstone
# Original sketch by Frederik Vanhoutte aka wblut
# Using svn(108) hemesh library (wblut)
# to export a ruby-processing sketch)
# to PovRAY mesh2 format (two meshes/one file)
######################################################

load_libraries 'hemesh', 'opengl'
include_package 'wblut.hemesh'
include_package 'wblut.hemesh.core'
include_package 'wblut.hemesh.creators'
include_package 'wblut.hemesh.modifiers'
include_package 'wblut.hemesh.subdividors'
include_package 'wblut.hemesh.tools'
include_package 'wblut.core.processing'

attr_accessor :render, :mesh, :inv_mesh, :display, :creator

def setup()
    size(800, 800, OPENGL)
    @display = true
    res = 20
    count = res + 1
    values=init_array(count, count, count)
    count.times do |i|
        count.times do |j|
            count.times do |k|
                values[i][j][k]=2.1*noise(0.35*i, 0.35*j, 0.35*k)
            end
        end
    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
    creator.set_values(values.to_java(Java::float[][]))# note cast to Javas
    # values can also be double[][][]
    creator.set_isolevel(1)# isolevel to mesh
    creator.set_invert(false)# invert mesh
    creator.set_boundary(100)# value of isoFunction outside grid
    # use creator.clearBoundary() to rest 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(20).set_auto_rescale(true))
    creator.set_invert(true)

    @inv_mesh=HE_Mesh.new(creator)
    inv_mesh.modify(HEM_Smooth.new().set_iterations(3).set_auto_rescale(true))
    @render=WB_Render.new(self)
end

def draw()
    if (display)
        screen_render()
    else
        povray_render()
    end

end

def screen_render()
    background(120)
    lights()
    translate(400, 400, 0)
    rotate_y(mouse_x*1.0/width*TWO_PI)
    rotate_x(mouse_y*1.0/height*TWO_PI)
    no_stroke()
    fill(255)
    render.draw_faces(mesh)
    fill(255, 0, 0)
    render.draw_faces(inv_mesh)
    stroke(0)
    render.draw_edges(mesh)
    stroke(255, 0, 0, 80)
    render.draw_edges(inv_mesh)
end

def povray_render()
    file_id = "mesh0"
    pw = create_writer(file_id + ".inc")
    HET_Export.saveToPOV(mesh, pw)   # (mesh, pw, false) no normals 
    HET_Export.saveToPOV(inv_mesh, pw)  # default is to use normals (smooth faces)
    pw.flush
    pw.close
    exit
end

def init_array(width, height, depth)
    Array.new(width).map!{ Array.new(height).map!{ Array.new(depth)}}
end

def key_pressed()
    case key
    when 'e', 'E'
        @display = false
    when 's', 'S'
        save_frame("twin_iso.png")
    end
end

Here is the associated "pov" file:-
// Persistence Of Vision Ray Tracer Scene Description File
// File:  Simple Scene <template for povwriter>
// Vers: 3.7
// Date: January 2012
// Auth: Martin Prout 

#version 3.7;

global_settings{
  assumed_gamma 1.0
  radiosity{
    pretrace_start 0.04
    pretrace_end 0.01
    count 200
    recursion_limit 3
    nearest_count 10
    error_bound 0.5
  }
}

#include "colors.inc"
#include "skies.inc"
#include "mesh0.inc"
#include "metals.inc"


//----------------declare scene Settings
#declare camera0 = camera {            // define additional cameras to suit viewing preferences
   location <-1.5, 30.0, -150.0>
   direction <0.0, 0.0, 2.0>
   up  <0.0, 1.0, 0.0>
   right <1.0, 0.0, 0.0>
   look_at <0.0, 25.0, 35.0>
}

#declare light0 = light_source { <100.0, 100.0, -200.0> colour White }

#declare ground0 = plane { <0.0, 1.0, 0.0>, 0.0  // a reflective ground plane
   pigment { NeonBlue }
   finish {reflection 0.15}
}

//------------------end of declare scene settings

// -----------------set the scene

camera { camera0 }              // ------------------------------------------
                                //  The use of declared values makes it possible to easily 
light_source{ light0 }          //  change the way the scene is rendered. Just define an
                                //  additional camera say for your template, and do the
sky_sphere{ S_Cloud3 }          //  substitution here. Retain the original definition and
                                //  you can easily backtrack. Definitions can also be saved
plane{ ground0 }                //  as included file see colors.inc for an example.
                                // ---------------------------------------------  
// -----------------end set the scene
object{
mesh2{ obj0 }                  // name obj0 created by modified Hemesh library
texture {T_Silver_5E}
scale<0.3, 0.3, 0.3>
rotate<0, 15, 0>
translate<0, 50, 400>
}

object{
mesh2{ obj2 }                  // name obj2 created by modified Hemesh library (why not 1?)
texture {T_Copper_1A}
scale<0.3, 0.3, 0.3>
rotate<0, 15, 0>
translate<0, 50, 400>
}
PovRAY rendered


Opengl Rendered

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