diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..ed5c51f
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,101 @@
+cmake_minimum_required(VERSION 2.8.4)
+project("radiance")
+
+enable_testing()
+include(CTest)
+
+option(BUILD_SHARED_LIBS "Build radiance using shared libraries?" OFF)
+
+if(NOT WIN32)
+  set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 1) 
+endif()
+set(CPACK_PACKAGING_INSTALL_PREFIX "/")
+set(CPACK_PACKAGE_VERSION_MAJOR 0)
+set(CPACK_PACKAGE_VERSION_MINOR 1)
+set(CPACK_PACKAGE_VERSION_PATCH 3)
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "Radiance ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
+SET(CPACK_RESOURCE_FILE_WELCOME "${radiance_SOURCE_DIR}/welcome.txt")
+SET(CPACK_RESOURCE_FILE_README "${radiance_SOURCE_DIR}/readme.txt")
+SET(CPACK_RESOURCE_FILE_LICENSE "${radiance_SOURCE_DIR}/license.txt") 
+include(CPack)
+
+find_package(Qt4 COMPONENTS QtCore QtGui)
+
+SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
+
+if(WIN32 AND "${CMAKE_C_COMPILER_ID}" MATCHES "^(Intel)$")
+  set(_INTEL_WINDOWS 1)
+endif()
+if(MSVC OR _INTEL_WINDOWS)
+  add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
+endif()
+if(WIN32)
+  add_definitions(-DEZXML_NOMMAP -Dfseeko=fseek -Dstrcasecmp=_stricmp)
+endif()
+
+add_subdirectory("src")
+
+#download and extract radiance support files
+include(ExternalProject)
+set(base "${CMAKE_BINARY_DIR}/Downloads")
+set_property(DIRECTORY PROPERTY EP_BASE ${base})
+ExternalProject_Add(radiance_support
+  URL http://www.radiance-online.org/software/non-cvs/rad4R0supp.tar.gz
+  URL_MD5 123e3e40af59c8b246e1fdbf0661e877
+  CONFIGURE_COMMAND ""
+  BUILD_COMMAND ""
+  INSTALL_COMMAND ""
+)
+
+#install support files.
+set(lib_dir ${base}/Source/radiance_support/lib)
+set(test_dir ${CMAKE_CURRENT_SOURCE_DIR}/test/test\ data)
+install(
+  FILES
+    ${lib_dir}/Earth.cal ${lib_dir}/He.cal ${lib_dir}/He3.cal
+    ${lib_dir}/adobe.cal ${lib_dir}/ball.cal ${lib_dir}/brick.cal
+    ${lib_dir}/brickweave.cal ${lib_dir}/carpet.cal ${lib_dir}/climit.cal
+    ${lib_dir}/corrug.cal ${lib_dir}/covelight.cal ${lib_dir}/cyl.cal
+    ${lib_dir}/dichroic.cal ${lib_dir}/dirt.cal ${lib_dir}/fisheye.cal
+    ${lib_dir}/fishgeom.cal ${lib_dir}/fprism.cal ${lib_dir}/globe.cal
+    ${lib_dir}/gloss.cal ${lib_dir}/grating.cal ${lib_dir}/jigglepic.cal
+    ${lib_dir}/lcp0.cal ${lib_dir}/limit.cal ${lib_dir}/marble.cal
+    ${lib_dir}/orange.cal ${lib_dir}/picture.cal ${lib_dir}/plink.cal
+    ${lib_dir}/prism.cal ${lib_dir}/retrorefl.cal ${lib_dir}/serraglaze.cal
+    ${lib_dir}/slate.cal ${lib_dir}/surf.cal ${lib_dir}/tim1.cal
+    ${lib_dir}/weave.cal ${lib_dir}/winxmit.cal ${lib_dir}/woodpat.cal
+    ${lib_dir}/woodtex.cal ${lib_dir}/wrinkle.cal
+    ${lib_dir}/page1.txt ${lib_dir}/page2.txt
+    ${lib_dir}/Pix.fnt
+    ${lib_dir}/PixOblique.fnt
+    ${lib_dir}/Veerdana.fnt
+    ${lib_dir}/VeerdanaBold.fnt
+    ${lib_dir}/VeerdanaBoldItalic.fnt
+    ${lib_dir}/VeerdanaItalic.fnt
+    ${lib_dir}/helvet.fnt
+    ${lib_dir}/hexbit4x1.fnt
+    ${test_dir}/model.oct
+    ${test_dir}/model.vp
+  DESTINATION bin
+)
+
+install(FILES ${lib_dir}/Earth.hdr DESTINATION bin RENAME Earth.pic)
+install(FILES ${lib_dir}/EarthBig.hdr DESTINATION bin RENAME EarthBig.pic)
+install(FILES ${lib_dir}/alberta.hdr DESTINATION bin RENAME alberta.pic)
+install(FILES ${lib_dir}/brick.hdr DESTINATION bin RENAME brick.pic)
+install(FILES ${lib_dir}/brickweave.hdr DESTINATION bin RENAME brickweave.pic)
+install(FILES ${lib_dir}/cabin.hdr DESTINATION bin RENAME cabin.pic)
+install(FILES ${lib_dir}/forestfl.hdr DESTINATION bin RENAME forestfl.pic)
+install(FILES ${lib_dir}/oakfloor.hdr DESTINATION bin RENAME oakfloor.pic)
+install(FILES ${lib_dir}/pine.hdr DESTINATION bin RENAME pine.pic)
+install(FILES ${lib_dir}/pinebark.hdr DESTINATION bin RENAME pinebark.pic)
+install(FILES ${lib_dir}/podlife.hdr DESTINATION bin RENAME podlife.pic)
+install(FILES ${lib_dir}/richgrove.hdr DESTINATION bin RENAME richgrove.pic)
+install(FILES ${lib_dir}/shingle.hdr DESTINATION bin RENAME shingle.pic)
+install(FILES ${lib_dir}/summercab.hdr DESTINATION bin RENAME summercab.pic)
+install(FILES ${lib_dir}/tulips.hdr DESTINATION bin RENAME tulips.pic)
+
+add_subdirectory(cmake_tests)
+
+include(InstallRequiredSystemLibraries)
+add_subdirectory(InstallRules)
diff --git a/CTestConfig.cmake b/CTestConfig.cmake
new file mode 100644
index 0000000..7648575
--- /dev/null
+++ b/CTestConfig.cmake
@@ -0,0 +1,8 @@
+set(CTEST_PROJECT_NAME "radiance")
+set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")
+
+set(CTEST_DROP_METHOD "http")
+set(CTEST_DROP_SITE "cdash.org")
+set(CTEST_DROP_LOCATION "/CDash/submit.php?project=radiance")
+set(CTEST_DROP_SITE_CDASH TRUE)
+set(CTEST_USE_LAUNCHERS 1)
diff --git a/InstallRules/BundleUtilities.cmake b/InstallRules/BundleUtilities.cmake
new file mode 100644
index 0000000..0143d59
--- /dev/null
+++ b/InstallRules/BundleUtilities.cmake
@@ -0,0 +1,786 @@
+# - Functions to help assemble a standalone bundle application.
+# A collection of CMake utility functions useful for dealing with .app
+# bundles on the Mac and bundle-like directories on any OS.
+#
+# The following functions are provided by this module:
+#   fixup_bundle
+#   copy_and_fixup_bundle
+#   verify_app
+#   get_bundle_main_executable
+#   get_dotapp_dir
+#   get_bundle_and_executable
+#   get_bundle_all_executables
+#   get_item_key
+#   clear_bundle_keys
+#   set_bundle_key_values
+#   get_bundle_keys
+#   copy_resolved_item_into_bundle
+#   copy_resolved_framework_into_bundle
+#   fixup_bundle_item
+#   verify_bundle_prerequisites
+#   verify_bundle_symlinks
+# Requires CMake 2.6 or greater because it uses function, break and
+# PARENT_SCOPE. Also depends on GetPrerequisites.cmake.
+#
+#  FIXUP_BUNDLE(<app> <libs> <dirs>)
+# Fix up a bundle in-place and make it standalone, such that it can be
+# drag-n-drop copied to another machine and run on that machine as long as all
+# of the system libraries are compatible.
+#
+# If you pass plugins to fixup_bundle as the libs parameter, you should install
+# them or copy them into the bundle before calling fixup_bundle. The "libs"
+# parameter is a list of libraries that must be fixed up, but that cannot be
+# determined by otool output analysis. (i.e., plugins)
+#
+# Gather all the keys for all the executables and libraries in a bundle, and
+# then, for each key, copy each prerequisite into the bundle. Then fix each one
+# up according to its own list of prerequisites.
+#
+# Then clear all the keys and call verify_app on the final bundle to ensure
+# that it is truly standalone.
+#
+#  COPY_AND_FIXUP_BUNDLE(<src> <dst> <libs> <dirs>)
+# Makes a copy of the bundle <src> at location <dst> and then fixes up the
+# new copied bundle in-place at <dst>...
+#
+#  VERIFY_APP(<app>)
+# Verifies that an application <app> appears valid based on running analysis
+# tools on it. Calls "message(FATAL_ERROR" if the application is not verified.
+#
+#  GET_BUNDLE_MAIN_EXECUTABLE(<bundle> <result_var>)
+# The result will be the full path name of the bundle's main executable file
+# or an "error:" prefixed string if it could not be determined.
+#
+#  GET_DOTAPP_DIR(<exe> <dotapp_dir_var>)
+# Returns the nearest parent dir whose name ends with ".app" given the full
+# path to an executable. If there is no such parent dir, then simply return
+# the dir containing the executable.
+#
+# The returned directory may or may not exist.
+#
+#  GET_BUNDLE_AND_EXECUTABLE(<app> <bundle_var> <executable_var> <valid_var>)
+# Takes either a ".app" directory name or the name of an executable
+# nested inside a ".app" directory and returns the path to the ".app"
+# directory in <bundle_var> and the path to its main executable in
+# <executable_var>
+#
+#  GET_BUNDLE_ALL_EXECUTABLES(<bundle> <exes_var>)
+# Scans the given bundle recursively for all executable files and accumulates
+# them into a variable.
+#
+#  GET_ITEM_KEY(<item> <key_var>)
+# Given a file (item) name, generate a key that should be unique considering
+# the set of libraries that need copying or fixing up to make a bundle
+# standalone. This is essentially the file name including extension with "."
+# replaced by "_"
+#
+# This key is used as a prefix for CMake variables so that we can associate a
+# set of variables with a given item based on its key.
+#
+#  CLEAR_BUNDLE_KEYS(<keys_var>)
+# Loop over the list of keys, clearing all the variables associated with each
+# key. After the loop, clear the list of keys itself.
+#
+# Caller of get_bundle_keys should call clear_bundle_keys when done with list
+# of keys.
+#
+#  SET_BUNDLE_KEY_VALUES(<keys_var> <context> <item> <exepath> <dirs>
+#                        <copyflag>)
+# Add a key to the list (if necessary) for the given item. If added,
+# also set all the variables associated with that key.
+#
+#  GET_BUNDLE_KEYS(<app> <libs> <dirs> <keys_var>)
+# Loop over all the executable and library files within the bundle (and given
+# as extra <libs>) and accumulate a list of keys representing them. Set
+# values associated with each key such that we can loop over all of them and
+# copy prerequisite libs into the bundle and then do appropriate
+# install_name_tool fixups.
+#
+#  COPY_RESOLVED_ITEM_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>)
+# Copy a resolved item into the bundle if necessary. Copy is not necessary if
+# the resolved_item is "the same as" the resolved_embedded_item.
+#
+#  COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>)
+# Copy a resolved framework into the bundle if necessary. Copy is not necessary
+# if the resolved_item is "the same as" the resolved_embedded_item.
+#
+# By default, BU_COPY_FULL_FRAMEWORK_CONTENTS is not set. If you want full
+# frameworks embedded in your bundles, set BU_COPY_FULL_FRAMEWORK_CONTENTS to
+# ON before calling fixup_bundle. By default,
+# COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE copies the framework dylib itself plus
+# the framework Resources directory.
+#
+#  FIXUP_BUNDLE_ITEM(<resolved_embedded_item> <exepath> <dirs>)
+# Get the direct/non-system prerequisites of the resolved embedded item. For
+# each prerequisite, change the way it is referenced to the value of the
+# _EMBEDDED_ITEM keyed variable for that prerequisite. (Most likely changing to
+# an "@executable_path" style reference.)
+#
+# This function requires that the resolved_embedded_item be "inside" the bundle
+# already. In other words, if you pass plugins to fixup_bundle as the libs
+# parameter, you should install them or copy them into the bundle before
+# calling fixup_bundle. The "libs" parameter is a list of libraries that must
+# be fixed up, but that cannot be determined by otool output analysis. (i.e.,
+# plugins)
+#
+# Also, change the id of the item being fixed up to its own _EMBEDDED_ITEM
+# value.
+#
+# Accumulate changes in a local variable and make *one* call to
+# install_name_tool at the end of the function with all the changes at once.
+#
+# If the BU_CHMOD_BUNDLE_ITEMS variable is set then bundle items will be
+# marked writable before install_name_tool tries to change them.
+#
+#  VERIFY_BUNDLE_PREREQUISITES(<bundle> <result_var> <info_var>)
+# Verifies that the sum of all prerequisites of all files inside the bundle
+# are contained within the bundle or are "system" libraries, presumed to exist
+# everywhere.
+#
+#  VERIFY_BUNDLE_SYMLINKS(<bundle> <result_var> <info_var>)
+# Verifies that any symlinks found in the bundle point to other files that are
+# already also in the bundle... Anything that points to an external file causes
+# this function to fail the verification.
+
+#=============================================================================
+# Copyright 2008-2009 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+# The functions defined in this file depend on the get_prerequisites function
+# (and possibly others) found in:
+#
+get_filename_component(BundleUtilities_cmake_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
+include("${BundleUtilities_cmake_dir}/GetPrerequisites.cmake")
+
+
+function(get_bundle_main_executable bundle result_var)
+  set(result "error: '${bundle}/Contents/Info.plist' file does not exist")
+
+  if(EXISTS "${bundle}/Contents/Info.plist")
+    set(result "error: no CFBundleExecutable in '${bundle}/Contents/Info.plist' file")
+    set(line_is_main_executable 0)
+    set(bundle_executable "")
+
+    # Read Info.plist as a list of lines:
+    #
+    set(eol_char "E")
+    file(READ "${bundle}/Contents/Info.plist" info_plist)
+    string(REGEX REPLACE ";" "\\\\;" info_plist "${info_plist}")
+    string(REGEX REPLACE "\n" "${eol_char};" info_plist "${info_plist}")
+
+    # Scan the lines for "<key>CFBundleExecutable</key>" - the line after that
+    # is the name of the main executable.
+    #
+    foreach(line ${info_plist})
+      if(line_is_main_executable)
+        string(REGEX REPLACE "^.*<string>(.*)</string>.*$" "\\1" bundle_executable "${line}")
+        break()
+      endif(line_is_main_executable)
+
+      if(line MATCHES "^.*<key>CFBundleExecutable</key>.*$")
+        set(line_is_main_executable 1)
+      endif(line MATCHES "^.*<key>CFBundleExecutable</key>.*$")
+    endforeach(line)
+
+    if(NOT "${bundle_executable}" STREQUAL "")
+      if(EXISTS "${bundle}/Contents/MacOS/${bundle_executable}")
+        set(result "${bundle}/Contents/MacOS/${bundle_executable}")
+      else(EXISTS "${bundle}/Contents/MacOS/${bundle_executable}")
+
+        # Ultimate goal:
+        # If not in "Contents/MacOS" then scan the bundle for matching files. If
+        # there is only one executable file that matches, then use it, otherwise
+        # it's an error...
+        #
+        #file(GLOB_RECURSE file_list "${bundle}/${bundle_executable}")
+
+        # But for now, pragmatically, it's an error. Expect the main executable
+        # for the bundle to be in Contents/MacOS, it's an error if it's not:
+        #
+        set(result "error: '${bundle}/Contents/MacOS/${bundle_executable}' does not exist")
+      endif(EXISTS "${bundle}/Contents/MacOS/${bundle_executable}")
+    endif(NOT "${bundle_executable}" STREQUAL "")
+  else(EXISTS "${bundle}/Contents/Info.plist")
+    #
+    # More inclusive technique... (This one would work on Windows and Linux
+    # too, if a developer followed the typical Mac bundle naming convention...)
+    #
+    # If there is no Info.plist file, try to find an executable with the same
+    # base name as the .app directory:
+    #
+  endif(EXISTS "${bundle}/Contents/Info.plist")
+
+  set(${result_var} "${result}" PARENT_SCOPE)
+endfunction(get_bundle_main_executable)
+
+
+function(get_dotapp_dir exe dotapp_dir_var)
+  set(s "${exe}")
+
+  if(s MATCHES "^.*/.*\\.app/.*$")
+    # If there is a ".app" parent directory,
+    # ascend until we hit it:
+    #   (typical of a Mac bundle executable)
+    #
+    set(done 0)
+    while(NOT ${done})
+      get_filename_component(snamewe "${s}" NAME_WE)
+      get_filename_component(sname "${s}" NAME)
+      get_filename_component(sdir "${s}" PATH)
+      set(s "${sdir}")
+      if(sname MATCHES "\\.app$")
+        set(done 1)
+        set(dotapp_dir "${sdir}/${sname}")
+      endif(sname MATCHES "\\.app$")
+    endwhile(NOT ${done})
+  else(s MATCHES "^.*/.*\\.app/.*$")
+    # Otherwise use a directory containing the exe
+    #   (typical of a non-bundle executable on Mac, Windows or Linux)
+    #
+    is_file_executable("${s}" is_executable)
+    if(is_executable)
+      get_filename_component(sdir "${s}" PATH)
+      set(dotapp_dir "${sdir}")
+    else(is_executable)
+      set(dotapp_dir "${s}")
+    endif(is_executable)
+  endif(s MATCHES "^.*/.*\\.app/.*$")
+
+
+  set(${dotapp_dir_var} "${dotapp_dir}" PARENT_SCOPE)
+endfunction(get_dotapp_dir)
+
+
+function(get_bundle_and_executable app bundle_var executable_var valid_var)
+  set(valid 0)
+
+  if(EXISTS "${app}")
+    # Is it a directory ending in .app?
+    if(IS_DIRECTORY "${app}")
+      if(app MATCHES "\\.app$")
+        get_bundle_main_executable("${app}" executable)
+        if(EXISTS "${app}" AND EXISTS "${executable}")
+          set(${bundle_var} "${app}" PARENT_SCOPE)
+          set(${executable_var} "${executable}" PARENT_SCOPE)
+          set(valid 1)
+          #message(STATUS "info: handled .app directory case...")
+        else(EXISTS "${app}" AND EXISTS "${executable}")
+          message(STATUS "warning: *NOT* handled - .app directory case...")
+        endif(EXISTS "${app}" AND EXISTS "${executable}")
+      else(app MATCHES "\\.app$")
+        message(STATUS "warning: *NOT* handled - directory but not .app case...")
+      endif(app MATCHES "\\.app$")
+    else(IS_DIRECTORY "${app}")
+      # Is it an executable file?
+      is_file_executable("${app}" is_executable)
+      if(is_executable)
+        get_dotapp_dir("${app}" dotapp_dir)
+        if(EXISTS "${dotapp_dir}")
+          set(${bundle_var} "${dotapp_dir}" PARENT_SCOPE)
+          set(${executable_var} "${app}" PARENT_SCOPE)
+          set(valid 1)
+          #message(STATUS "info: handled executable file in .app dir case...")
+        else()
+          get_filename_component(app_dir "${app}" PATH)
+          set(${bundle_var} "${app_dir}" PARENT_SCOPE)
+          set(${executable_var} "${app}" PARENT_SCOPE)
+          set(valid 1)
+          #message(STATUS "info: handled executable file in any dir case...")
+        endif()
+      else(is_executable)
+        message(STATUS "warning: *NOT* handled - not .app dir, not executable file...")
+      endif(is_executable)
+    endif(IS_DIRECTORY "${app}")
+  else(EXISTS "${app}")
+    message(STATUS "warning: *NOT* handled - directory/file does not exist...")
+  endif(EXISTS "${app}")
+
+  if(NOT valid)
+    set(${bundle_var} "error: not a bundle" PARENT_SCOPE)
+    set(${executable_var} "error: not a bundle" PARENT_SCOPE)
+  endif(NOT valid)
+
+  set(${valid_var} ${valid} PARENT_SCOPE)
+endfunction(get_bundle_and_executable)
+
+
+function(get_bundle_all_executables bundle exes_var)
+  set(exes "")
+
+  file(GLOB_RECURSE file_list "${bundle}/*")
+  foreach(f ${file_list})
+    is_file_executable("${f}" is_executable)
+    if(is_executable)
+      set(exes ${exes} "${f}")
+    endif(is_executable)
+  endforeach(f)
+
+  set(${exes_var} "${exes}" PARENT_SCOPE)
+endfunction(get_bundle_all_executables)
+
+
+function(get_item_key item key_var)
+  get_filename_component(item_name "${item}" NAME)
+  if(WIN32)
+    string(TOLOWER "${item_name}" item_name)
+  endif()
+  string(REGEX REPLACE "\\." "_" ${key_var} "${item_name}")
+  set(${key_var} ${${key_var}} PARENT_SCOPE)
+endfunction(get_item_key)
+
+
+function(clear_bundle_keys keys_var)
+  foreach(key ${${keys_var}})
+    set(${key}_ITEM PARENT_SCOPE)
+    set(${key}_RESOLVED_ITEM PARENT_SCOPE)
+    set(${key}_DEFAULT_EMBEDDED_PATH PARENT_SCOPE)
+    set(${key}_EMBEDDED_ITEM PARENT_SCOPE)
+    set(${key}_RESOLVED_EMBEDDED_ITEM PARENT_SCOPE)
+    set(${key}_COPYFLAG PARENT_SCOPE)
+  endforeach(key)
+  set(${keys_var} PARENT_SCOPE)
+endfunction(clear_bundle_keys)
+
+
+function(set_bundle_key_values keys_var context item exepath dirs copyflag)
+  get_filename_component(item_name "${item}" NAME)
+
+  get_item_key("${item}" key)
+
+  list(LENGTH ${keys_var} length_before)
+  gp_append_unique(${keys_var} "${key}")
+  list(LENGTH ${keys_var} length_after)
+
+  if(NOT length_before EQUAL length_after)
+    gp_resolve_item("${context}" "${item}" "${exepath}" "${dirs}" resolved_item)
+
+    gp_item_default_embedded_path("${item}" default_embedded_path)
+
+    if(item MATCHES "[^/]+\\.framework/")
+      # For frameworks, construct the name under the embedded path from the
+      # opening "${item_name}.framework/" to the closing "/${item_name}":
+      #
+      string(REGEX REPLACE "^.*(${item_name}.framework/.*/${item_name}).*$" "${default_embedded_path}/\\1" embedded_item "${item}")
+    else(item MATCHES "[^/]+\\.framework/")
+      # For other items, just use the same name as the original, but in the
+      # embedded path:
+      #
+      set(embedded_item "${default_embedded_path}/${item_name}")
+    endif(item MATCHES "[^/]+\\.framework/")
+
+    # Replace @executable_path and resolve ".." references:
+    #
+    string(REPLACE "@executable_path" "${exepath}" resolved_embedded_item "${embedded_item}")
+    get_filename_component(resolved_embedded_item "${resolved_embedded_item}" ABSOLUTE)
+
+    # *But* -- if we are not copying, then force resolved_embedded_item to be
+    # the same as resolved_item. In the case of multiple executables in the
+    # original bundle, using the default_embedded_path results in looking for
+    # the resolved executable next to the main bundle executable. This is here
+    # so that exes in the other sibling directories (like "bin") get fixed up
+    # properly...
+    #
+    if(NOT copyflag)
+      set(resolved_embedded_item "${resolved_item}")
+    endif(NOT copyflag)
+
+    set(${keys_var} ${${keys_var}} PARENT_SCOPE)
+    set(${key}_ITEM "${item}" PARENT_SCOPE)
+    set(${key}_RESOLVED_ITEM "${resolved_item}" PARENT_SCOPE)
+    set(${key}_DEFAULT_EMBEDDED_PATH "${default_embedded_path}" PARENT_SCOPE)
+    set(${key}_EMBEDDED_ITEM "${embedded_item}" PARENT_SCOPE)
+    set(${key}_RESOLVED_EMBEDDED_ITEM "${resolved_embedded_item}" PARENT_SCOPE)
+    set(${key}_COPYFLAG "${copyflag}" PARENT_SCOPE)
+  else(NOT length_before EQUAL length_after)
+    #message("warning: item key '${key}' already in the list, subsequent references assumed identical to first")
+  endif(NOT length_before EQUAL length_after)
+endfunction(set_bundle_key_values)
+
+
+function(get_bundle_keys app libs dirs keys_var)
+  set(${keys_var} PARENT_SCOPE)
+
+  get_bundle_and_executable("${app}" bundle executable valid)
+  if(valid)
+    # Always use the exepath of the main bundle executable for @executable_path
+    # replacements:
+    #
+    get_filename_component(exepath "${executable}" PATH)
+
+    # But do fixups on all executables in the bundle:
+    #
+    get_bundle_all_executables("${bundle}" exes)
+
+    # For each extra lib, accumulate a key as well and then also accumulate
+    # any of its prerequisites. (Extra libs are typically dynamically loaded
+    # plugins: libraries that are prerequisites for full runtime functionality
+    # but that do not show up in otool -L output...)
+    #
+    foreach(lib ${libs})
+      set_bundle_key_values(${keys_var} "${lib}" "${lib}" "${exepath}" "${dirs}" 0)
+
+      set(prereqs "")
+      get_prerequisites("${lib}" prereqs 1 1 "${exepath}" "${dirs}")
+      foreach(pr ${prereqs})
+        set_bundle_key_values(${keys_var} "${lib}" "${pr}" "${exepath}" "${dirs}" 1)
+      endforeach(pr)
+    endforeach(lib)
+
+    # For each executable found in the bundle, accumulate keys as we go.
+    # The list of keys should be complete when all prerequisites of all
+    # binaries in the bundle have been analyzed.
+    #
+    foreach(exe ${exes})
+      # Add the exe itself to the keys:
+      #
+      set_bundle_key_values(${keys_var} "${exe}" "${exe}" "${exepath}" "${dirs}" 0)
+
+      # Add each prerequisite to the keys:
+      #
+      set(prereqs "")
+      get_prerequisites("${exe}" prereqs 1 1 "${exepath}" "${dirs}")
+      foreach(pr ${prereqs})
+        set_bundle_key_values(${keys_var} "${exe}" "${pr}" "${exepath}" "${dirs}" 1)
+      endforeach(pr)
+    endforeach(exe)
+
+    # Propagate values to caller's scope:
+    #
+    set(${keys_var} ${${keys_var}} PARENT_SCOPE)
+    foreach(key ${${keys_var}})
+      set(${key}_ITEM "${${key}_ITEM}" PARENT_SCOPE)
+      set(${key}_RESOLVED_ITEM "${${key}_RESOLVED_ITEM}" PARENT_SCOPE)
+      set(${key}_DEFAULT_EMBEDDED_PATH "${${key}_DEFAULT_EMBEDDED_PATH}" PARENT_SCOPE)
+      set(${key}_EMBEDDED_ITEM "${${key}_EMBEDDED_ITEM}" PARENT_SCOPE)
+      set(${key}_RESOLVED_EMBEDDED_ITEM "${${key}_RESOLVED_EMBEDDED_ITEM}" PARENT_SCOPE)
+      set(${key}_COPYFLAG "${${key}_COPYFLAG}" PARENT_SCOPE)
+    endforeach(key)
+  endif(valid)
+endfunction(get_bundle_keys)
+
+
+function(copy_resolved_item_into_bundle resolved_item resolved_embedded_item)
+  if(WIN32)
+    # ignore case on Windows
+    string(TOLOWER "${resolved_item}" resolved_item_compare)
+    string(TOLOWER "${resolved_embedded_item}" resolved_embedded_item_compare)
+  else()
+    set(resolved_item_compare "${resolved_item}")
+    set(resolved_embedded_item_compare "${resolved_embedded_item}")
+  endif()
+
+  if("${resolved_item_compare}" STREQUAL "${resolved_embedded_item_compare}")
+    message(STATUS "warning: resolved_item == resolved_embedded_item - not copying...")
+  else()
+    #message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy ${resolved_item} ${resolved_embedded_item}")
+    execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${resolved_item}" "${resolved_embedded_item}")
+    if(UNIX AND NOT APPLE)
+      file(RPATH_REMOVE FILE "${resolved_embedded_item}")
+    endif(UNIX AND NOT APPLE)
+  endif()
+
+endfunction(copy_resolved_item_into_bundle)
+
+
+function(copy_resolved_framework_into_bundle resolved_item resolved_embedded_item)
+  if(WIN32)
+    # ignore case on Windows
+    string(TOLOWER "${resolved_item}" resolved_item_compare)
+    string(TOLOWER "${resolved_embedded_item}" resolved_embedded_item_compare)
+  else()
+    set(resolved_item_compare "${resolved_item}")
+    set(resolved_embedded_item_compare "${resolved_embedded_item}")
+  endif()
+
+  if("${resolved_item_compare}" STREQUAL "${resolved_embedded_item_compare}")
+    message(STATUS "warning: resolved_item == resolved_embedded_item - not copying...")
+  else()
+    if(BU_COPY_FULL_FRAMEWORK_CONTENTS)
+      # Full Framework (everything):
+      get_filename_component(resolved_dir "${resolved_item}" PATH)
+      get_filename_component(resolved_dir "${resolved_dir}/../.." ABSOLUTE)
+      get_filename_component(resolved_embedded_dir "${resolved_embedded_item}" PATH)
+      get_filename_component(resolved_embedded_dir "${resolved_embedded_dir}/../.." ABSOLUTE)
+      #message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy_directory '${resolved_dir}' '${resolved_embedded_dir}'")
+      execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory "${resolved_dir}" "${resolved_embedded_dir}")
+    else()
+      # Framework lib itself:
+      #message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy ${resolved_item} ${resolved_embedded_item}")
+      execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${resolved_item}" "${resolved_embedded_item}")
+
+      # Plus Resources, if they exist:
+      string(REGEX REPLACE "^(.*)/[^/]+/[^/]+/[^/]+$" "\\1/Resources" resolved_resources "${resolved_item}")
+      string(REGEX REPLACE "^(.*)/[^/]+/[^/]+/[^/]+$" "\\1/Resources" resolved_embedded_resources "${resolved_embedded_item}")
+      if(EXISTS "${resolved_resources}")
+        #message(STATUS "copying COMMAND ${CMAKE_COMMAND} -E copy_directory '${resolved_resources}' '${resolved_embedded_resources}'")
+        execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory "${resolved_resources}" "${resolved_embedded_resources}")
+      endif()
+    endif()
+    if(UNIX AND NOT APPLE)
+      file(RPATH_REMOVE FILE "${resolved_embedded_item}")
+    endif(UNIX AND NOT APPLE)
+  endif()
+
+endfunction(copy_resolved_framework_into_bundle)
+
+
+function(fixup_bundle_item resolved_embedded_item exepath dirs)
+  # This item's key is "ikey":
+  #
+  get_item_key("${resolved_embedded_item}" ikey)
+
+  # Ensure the item is "inside the .app bundle" -- it should not be fixed up if
+  # it is not in the .app bundle... Otherwise, we'll modify files in the build
+  # tree, or in other varied locations around the file system, with our call to
+  # install_name_tool. Make sure that doesn't happen here:
+  #
+  get_dotapp_dir("${exepath}" exe_dotapp_dir)
+  string(LENGTH "${exe_dotapp_dir}/" exe_dotapp_dir_length)
+  string(LENGTH "${resolved_embedded_item}" resolved_embedded_item_length)
+  set(path_too_short 0)
+  set(is_embedded 0)
+  if(${resolved_embedded_item_length} LESS ${exe_dotapp_dir_length})
+    set(path_too_short 1)
+  endif()
+  if(NOT path_too_short)
+    string(SUBSTRING "${resolved_embedded_item}" 0 ${exe_dotapp_dir_length} item_substring)
+    if("${exe_dotapp_dir}/" STREQUAL "${item_substring}")
+      set(is_embedded 1)
+    endif()
+  endif()
+  if(NOT is_embedded)
+    message("  exe_dotapp_dir/='${exe_dotapp_dir}/'")
+    message("  item_substring='${item_substring}'")
+    message("  resolved_embedded_item='${resolved_embedded_item}'")
+    message("")
+    message("Install or copy the item into the bundle before calling fixup_bundle.")
+    message("Or maybe there's a typo or incorrect path in one of the args to fixup_bundle?")
+    message("")
+    message(FATAL_ERROR "cannot fixup an item that is not in the bundle...")
+  endif()
+
+  set(prereqs "")
+  get_prerequisites("${resolved_embedded_item}" prereqs 1 0 "${exepath}" "${dirs}")
+
+  set(changes "")
+
+  foreach(pr ${prereqs})
+    # Each referenced item's key is "rkey" in the loop:
+    #
+    get_item_key("${pr}" rkey)
+
+    if(NOT "${${rkey}_EMBEDDED_ITEM}" STREQUAL "")
+      set(changes ${changes} "-change" "${pr}" "${${rkey}_EMBEDDED_ITEM}")
+    else(NOT "${${rkey}_EMBEDDED_ITEM}" STREQUAL "")
+      message("warning: unexpected reference to '${pr}'")
+    endif(NOT "${${rkey}_EMBEDDED_ITEM}" STREQUAL "")
+  endforeach(pr)
+
+  if(BU_CHMOD_BUNDLE_ITEMS)
+    execute_process(COMMAND chmod u+w "${resolved_embedded_item}")
+  endif()
+
+  # Change this item's id and all of its references in one call
+  # to install_name_tool:
+  #
+  execute_process(COMMAND install_name_tool
+    ${changes} -id "${${ikey}_EMBEDDED_ITEM}" "${resolved_embedded_item}"
+  )
+endfunction(fixup_bundle_item)
+
+
+function(fixup_bundle app libs dirs)
+  message(STATUS "fixup_bundle")
+  message(STATUS "  app='${app}'")
+  message(STATUS "  libs='${libs}'")
+  message(STATUS "  dirs='${dirs}'")
+
+  get_bundle_and_executable("${app}" bundle executable valid)
+  if(valid)
+    get_filename_component(exepath "${executable}" PATH)
+
+    message(STATUS "fixup_bundle: preparing...")
+    get_bundle_keys("${app}" "${libs}" "${dirs}" keys)
+
+    message(STATUS "fixup_bundle: copying...")
+    list(LENGTH keys n)
+    math(EXPR n ${n}*2)
+
+    set(i 0)
+    foreach(key ${keys})
+      math(EXPR i ${i}+1)
+      if(${${key}_COPYFLAG})
+        message(STATUS "${i}/${n}: copying '${${key}_RESOLVED_ITEM}'")
+      else(${${key}_COPYFLAG})
+        message(STATUS "${i}/${n}: *NOT* copying '${${key}_RESOLVED_ITEM}'")
+      endif(${${key}_COPYFLAG})
+
+      set(show_status 0)
+      if(show_status)
+        message(STATUS "key='${key}'")
+        message(STATUS "item='${${key}_ITEM}'")
+        message(STATUS "resolved_item='${${key}_RESOLVED_ITEM}'")
+        message(STATUS "default_embedded_path='${${key}_DEFAULT_EMBEDDED_PATH}'")
+        message(STATUS "embedded_item='${${key}_EMBEDDED_ITEM}'")
+        message(STATUS "resolved_embedded_item='${${key}_RESOLVED_EMBEDDED_ITEM}'")
+        message(STATUS "copyflag='${${key}_COPYFLAG}'")
+        message(STATUS "")
+      endif(show_status)
+
+      if(${${key}_COPYFLAG})
+        set(item "${${key}_ITEM}")
+        if(item MATCHES "[^/]+\\.framework/")
+          copy_resolved_framework_into_bundle("${${key}_RESOLVED_ITEM}"
+            "${${key}_RESOLVED_EMBEDDED_ITEM}")
+        else()
+          copy_resolved_item_into_bundle("${${key}_RESOLVED_ITEM}"
+            "${${key}_RESOLVED_EMBEDDED_ITEM}")
+        endif()
+      endif(${${key}_COPYFLAG})
+    endforeach(key)
+
+    message(STATUS "fixup_bundle: fixing...")
+    foreach(key ${keys})
+      math(EXPR i ${i}+1)
+      if(APPLE)
+        message(STATUS "${i}/${n}: fixing up '${${key}_RESOLVED_EMBEDDED_ITEM}'")
+        fixup_bundle_item("${${key}_RESOLVED_EMBEDDED_ITEM}" "${exepath}" "${dirs}")
+      else(APPLE)
+        message(STATUS "${i}/${n}: fix-up not required on this platform '${${key}_RESOLVED_EMBEDDED_ITEM}'")
+      endif(APPLE)
+    endforeach(key)
+
+    message(STATUS "fixup_bundle: cleaning up...")
+    clear_bundle_keys(keys)
+
+    message(STATUS "fixup_bundle: verifying...")
+    verify_app("${app}")
+  else(valid)
+    message(SEND_ERROR "error: fixup_bundle: not a valid bundle")
+  endif(valid)
+
+  message(STATUS "fixup_bundle: done")
+endfunction(fixup_bundle)
+
+
+function(copy_and_fixup_bundle src dst libs dirs)
+  execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory "${src}" "${dst}")
+  fixup_bundle("${dst}" "${libs}" "${dirs}")
+endfunction(copy_and_fixup_bundle)
+
+
+function(verify_bundle_prerequisites bundle result_var info_var)
+  set(result 1)
+  set(info "")
+  set(count 0)
+
+  get_bundle_main_executable("${bundle}" main_bundle_exe)
+
+  file(GLOB_RECURSE file_list "${bundle}/*")
+  foreach(f ${file_list})
+    is_file_executable("${f}" is_executable)
+    if(is_executable)
+      get_filename_component(exepath "${f}" PATH)
+      math(EXPR count "${count} + 1")
+
+      message(STATUS "executable file ${count}: ${f}")
+
+      set(prereqs "")
+      get_prerequisites("${f}" prereqs 1 1 "${exepath}" "")
+
+      # On the Mac,
+      # "embedded" and "system" prerequisites are fine... anything else means
+      # the bundle's prerequisites are not verified (i.e., the bundle is not
+      # really "standalone")
+      #
+      # On Windows (and others? Linux/Unix/...?)
+      # "local" and "system" prereqs are fine...
+      #
+      set(external_prereqs "")
+
+      foreach(p ${prereqs})
+        set(p_type "")
+        gp_file_type("${f}" "${p}" p_type)
+
+        if(APPLE)
+          if(NOT "${p_type}" STREQUAL "embedded" AND NOT "${p_type}" STREQUAL "system")
+            set(external_prereqs ${external_prereqs} "${p}")
+          endif()
+        else()
+          if(NOT "${p_type}" STREQUAL "local" AND NOT "${p_type}" STREQUAL "system")
+            set(external_prereqs ${external_prereqs} "${p}")
+          endif()
+        endif()
+      endforeach(p)
+
+      if(external_prereqs)
+        # Found non-system/somehow-unacceptable prerequisites:
+        set(result 0)
+        set(info ${info} "external prerequisites found:\nf='${f}'\nexternal_prereqs='${external_prereqs}'\n")
+      endif(external_prereqs)
+    endif(is_executable)
+  endforeach(f)
+
+  if(result)
+    set(info "Verified ${count} executable files in '${bundle}'")
+  endif(result)
+
+  set(${result_var} "${result}" PARENT_SCOPE)
+  set(${info_var} "${info}" PARENT_SCOPE)
+endfunction(verify_bundle_prerequisites)
+
+
+function(verify_bundle_symlinks bundle result_var info_var)
+  set(result 1)
+  set(info "")
+  set(count 0)
+
+  # TODO: implement this function for real...
+  # Right now, it is just a stub that verifies unconditionally...
+
+  set(${result_var} "${result}" PARENT_SCOPE)
+  set(${info_var} "${info}" PARENT_SCOPE)
+endfunction(verify_bundle_symlinks)
+
+
+function(verify_app app)
+  set(verified 0)
+  set(info "")
+
+  get_bundle_and_executable("${app}" bundle executable valid)
+
+  message(STATUS "===========================================================================")
+  message(STATUS "Analyzing app='${app}'")
+  message(STATUS "bundle='${bundle}'")
+  message(STATUS "executable='${executable}'")
+  message(STATUS "valid='${valid}'")
+
+  # Verify that the bundle does not have any "external" prerequisites:
+  #
+  verify_bundle_prerequisites("${bundle}" verified info)
+  message(STATUS "verified='${verified}'")
+  message(STATUS "info='${info}'")
+  message(STATUS "")
+
+  if(verified)
+    # Verify that the bundle does not have any symlinks to external files:
+    #
+    verify_bundle_symlinks("${bundle}" verified info)
+    message(STATUS "verified='${verified}'")
+    message(STATUS "info='${info}'")
+    message(STATUS "")
+  endif(verified)
+
+  if(NOT verified)
+    message(FATAL_ERROR "error: verify_app failed")
+  endif(NOT verified)
+endfunction(verify_app)
diff --git a/InstallRules/CMakeLists.txt b/InstallRules/CMakeLists.txt
new file mode 100644
index 0000000..16d4ebe
--- /dev/null
+++ b/InstallRules/CMakeLists.txt
@@ -0,0 +1,7 @@
+configure_file(
+   "${CMAKE_CURRENT_SOURCE_DIR}/dependencies.cmake.in"
+   "${CMAKE_CURRENT_BINARY_DIR}/dependencies.cmake"
+   @ONLY
+   )
+install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/dependencies.cmake")
+
diff --git a/InstallRules/GetPrerequisites.cmake b/InstallRules/GetPrerequisites.cmake
new file mode 100644
index 0000000..023b8b5
--- /dev/null
+++ b/InstallRules/GetPrerequisites.cmake
@@ -0,0 +1,840 @@
+# - Functions to analyze and list executable file prerequisites.
+# This module provides functions to list the .dll, .dylib or .so
+# files that an executable or shared library file depends on. (Its
+# prerequisites.)
+#
+# It uses various tools to obtain the list of required shared library files:
+#   dumpbin (Windows)
+#   ldd (Linux/Unix)
+#   otool (Mac OSX)
+# The following functions are provided by this module:
+#   get_prerequisites
+#   list_prerequisites
+#   list_prerequisites_by_glob
+#   gp_append_unique
+#   is_file_executable
+#   gp_item_default_embedded_path
+#     (projects can override with gp_item_default_embedded_path_override)
+#   gp_resolve_item
+#     (projects can override with gp_resolve_item_override)
+#   gp_resolved_file_type
+#     (projects can override with gp_resolved_file_type_override)
+#   gp_file_type
+# Requires CMake 2.6 or greater because it uses function, break, return and
+# PARENT_SCOPE.
+#
+#  GET_PREREQUISITES(<target> <prerequisites_var> <exclude_system> <recurse>
+#                    <dirs>)
+# Get the list of shared library files required by <target>. The list in
+# the variable named <prerequisites_var> should be empty on first entry to
+# this function. On exit, <prerequisites_var> will contain the list of
+# required shared library files.
+#
+# <target> is the full path to an executable file. <prerequisites_var> is the
+# name of a CMake variable to contain the results. <exclude_system> must be 0
+# or 1 indicating whether to include or exclude "system" prerequisites. If
+# <recurse> is set to 1 all prerequisites will be found recursively, if set to
+# 0 only direct prerequisites are listed. <exepath> is the path to the top
+# level executable used for @executable_path replacment on the Mac. <dirs> is
+# a list of paths where libraries might be found: these paths are searched
+# first when a target without any path info is given. Then standard system
+# locations are also searched: PATH, Framework locations, /usr/lib...
+#
+#  LIST_PREREQUISITES(<target> [<recurse> [<exclude_system> [<verbose>]]])
+# Print a message listing the prerequisites of <target>.
+#
+# <target> is the name of a shared library or executable target or the full
+# path to a shared library or executable file. If <recurse> is set to 1 all
+# prerequisites will be found recursively, if set to 0 only direct
+# prerequisites are listed. <exclude_system> must be 0 or 1 indicating whether
+# to include or exclude "system" prerequisites. With <verbose> set to 0 only
+# the full path names of the prerequisites are printed, set to 1 extra
+# informatin will be displayed.
+#
+#  LIST_PREREQUISITES_BY_GLOB(<glob_arg> <glob_exp>)
+# Print the prerequisites of shared library and executable files matching a
+# globbing pattern. <glob_arg> is GLOB or GLOB_RECURSE and <glob_exp> is a
+# globbing expression used with "file(GLOB" or "file(GLOB_RECURSE" to retrieve
+# a list of matching files. If a matching file is executable, its prerequisites
+# are listed.
+#
+# Any additional (optional) arguments provided are passed along as the
+# optional arguments to the list_prerequisites calls.
+#
+#  GP_APPEND_UNIQUE(<list_var> <value>)
+# Append <value> to the list variable <list_var> only if the value is not
+# already in the list.
+#
+#  IS_FILE_EXECUTABLE(<file> <result_var>)
+# Return 1 in <result_var> if <file> is a binary executable, 0 otherwise.
+#
+#  GP_ITEM_DEFAULT_EMBEDDED_PATH(<item> <default_embedded_path_var>)
+# Return the path that others should refer to the item by when the item
+# is embedded inside a bundle.
+#
+# Override on a per-project basis by providing a project-specific
+# gp_item_default_embedded_path_override function.
+#
+#  GP_RESOLVE_ITEM(<context> <item> <exepath> <dirs> <resolved_item_var>)
+# Resolve an item into an existing full path file.
+#
+# Override on a per-project basis by providing a project-specific
+# gp_resolve_item_override function.
+#
+#  GP_RESOLVED_FILE_TYPE(<original_file> <file> <exepath> <dirs> <type_var>)
+# Return the type of <file> with respect to <original_file>. String
+# describing type of prerequisite is returned in variable named <type_var>.
+#
+# Use <exepath> and <dirs> if necessary to resolve non-absolute <file>
+# values -- but only for non-embedded items.
+#
+# Possible types are:
+#   system
+#   local
+#   embedded
+#   other
+# Override on a per-project basis by providing a project-specific
+# gp_resolved_file_type_override function.
+#
+#  GP_FILE_TYPE(<original_file> <file> <type_var>)
+# Return the type of <file> with respect to <original_file>. String
+# describing type of prerequisite is returned in variable named <type_var>.
+#
+# Possible types are:
+#   system
+#   local
+#   embedded
+#   other
+
+#=============================================================================
+# Copyright 2008-2009 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+function(gp_append_unique list_var value)
+  set(contains 0)
+
+  foreach(item ${${list_var}})
+    if("${item}" STREQUAL "${value}")
+      set(contains 1)
+      break()
+    endif("${item}" STREQUAL "${value}")
+  endforeach(item)
+
+  if(NOT contains)
+    set(${list_var} ${${list_var}} "${value}" PARENT_SCOPE)
+  endif(NOT contains)
+endfunction(gp_append_unique)
+
+
+function(is_file_executable file result_var)
+  #
+  # A file is not executable until proven otherwise:
+  #
+  set(${result_var} 0 PARENT_SCOPE)
+
+  get_filename_component(file_full "${file}" ABSOLUTE)
+  string(TOLOWER "${file_full}" file_full_lower)
+
+  # If file name ends in .exe on Windows, *assume* executable:
+  #
+  if(WIN32 AND NOT UNIX)
+    if("${file_full_lower}" MATCHES "\\.exe$")
+      set(${result_var} 1 PARENT_SCOPE)
+      return()
+    endif("${file_full_lower}" MATCHES "\\.exe$")
+
+    # A clause could be added here that uses output or return value of dumpbin
+    # to determine ${result_var}. In 99%+? practical cases, the exe name
+    # match will be sufficient...
+    #
+  endif(WIN32 AND NOT UNIX)
+
+  # Use the information returned from the Unix shell command "file" to
+  # determine if ${file_full} should be considered an executable file...
+  #
+  # If the file command's output contains "executable" and does *not* contain
+  # "text" then it is likely an executable suitable for prerequisite analysis
+  # via the get_prerequisites macro.
+  #
+  if(UNIX)
+    if(NOT file_cmd)
+      find_program(file_cmd "file")
+    endif(NOT file_cmd)
+
+    if(file_cmd)
+      execute_process(COMMAND "${file_cmd}" "${file_full}"
+        OUTPUT_VARIABLE file_ov
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+        )
+
+      # Replace the name of the file in the output with a placeholder token
+      # (the string " _file_full_ ") so that just in case the path name of
+      # the file contains the word "text" or "executable" we are not fooled
+      # into thinking "the wrong thing" because the file name matches the
+      # other 'file' command output we are looking for...
+      #
+      string(REPLACE "${file_full}" " _file_full_ " file_ov "${file_ov}")
+      string(TOLOWER "${file_ov}" file_ov)
+
+      #message(STATUS "file_ov='${file_ov}'")
+      if("${file_ov}" MATCHES "executable")
+        #message(STATUS "executable!")
+        if("${file_ov}" MATCHES "text")
+          #message(STATUS "but text, so *not* a binary executable!")
+        else("${file_ov}" MATCHES "text")
+          set(${result_var} 1 PARENT_SCOPE)
+          return()
+        endif("${file_ov}" MATCHES "text")
+      endif("${file_ov}" MATCHES "executable")
+    else(file_cmd)
+      message(STATUS "warning: No 'file' command, skipping execute_process...")
+    endif(file_cmd)
+  endif(UNIX)
+endfunction(is_file_executable)
+
+
+function(gp_item_default_embedded_path item default_embedded_path_var)
+
+  # On Windows and Linux, "embed" prerequisites in the same directory
+  # as the executable by default:
+  #
+  set(path "@executable_path")
+  set(overridden 0)
+
+  # On the Mac, relative to the executable depending on the type
+  # of the thing we are embedding:
+  #
+  if(APPLE)
+    #
+    # The assumption here is that all executables in the bundle will be
+    # in same-level-directories inside the bundle. The parent directory
+    # of an executable inside the bundle should be MacOS or a sibling of
+    # MacOS and all embedded paths returned from here will begin with
+    # "@executable_path/../" and will work from all executables in all
+    # such same-level-directories inside the bundle.
+    #
+
+    # By default, embed things right next to the main bundle executable:
+    #
+    set(path "@executable_path/../../Contents/MacOS")
+
+    # Embed .dylibs right next to the main bundle executable:
+    #
+    if(item MATCHES "\\.dylib$")
+      set(path "@executable_path/../MacOS")
+      set(overridden 1)
+    endif(item MATCHES "\\.dylib$")
+
+    # Embed frameworks in the embedded "Frameworks" directory (sibling of MacOS):
+    #
+    if(NOT overridden)
+      if(item MATCHES "[^/]+\\.framework/")
+        set(path "@executable_path/../Frameworks")
+        set(overridden 1)
+      endif(item MATCHES "[^/]+\\.framework/")
+    endif(NOT overridden)
+  endif()
+
+  # Provide a hook so that projects can override the default embedded location
+  # of any given library by whatever logic they choose:
+  #
+  if(COMMAND gp_item_default_embedded_path_override)
+    gp_item_default_embedded_path_override("${item}" path)
+  endif(COMMAND gp_item_default_embedded_path_override)
+
+  set(${default_embedded_path_var} "${path}" PARENT_SCOPE)
+endfunction(gp_item_default_embedded_path)
+
+
+function(gp_resolve_item context item exepath dirs resolved_item_var)
+  set(resolved 0)
+  set(resolved_item "${item}")
+
+  # Is it already resolved?
+  #
+  if(IS_ABSOLUTE "${resolved_item}" AND EXISTS "${resolved_item}")
+    set(resolved 1)
+  endif(IS_ABSOLUTE "${resolved_item}" AND EXISTS "${resolved_item}")
+
+  if(NOT resolved)
+    if(item MATCHES "@executable_path")
+      #
+      # @executable_path references are assumed relative to exepath
+      #
+      string(REPLACE "@executable_path" "${exepath}" ri "${item}")
+      get_filename_component(ri "${ri}" ABSOLUTE)
+
+      if(EXISTS "${ri}")
+        #message(STATUS "info: embedded item exists (${ri})")
+        set(resolved 1)
+        set(resolved_item "${ri}")
+      else(EXISTS "${ri}")
+        message(STATUS "warning: embedded item does not exist '${ri}'")
+      endif(EXISTS "${ri}")
+    endif(item MATCHES "@executable_path")
+  endif(NOT resolved)
+
+  if(NOT resolved)
+    if(item MATCHES "@loader_path")
+      #
+      # @loader_path references are assumed relative to the
+      # PATH of the given "context" (presumably another library)
+      #
+      get_filename_component(contextpath "${context}" PATH)
+      string(REPLACE "@loader_path" "${contextpath}" ri "${item}")
+      get_filename_component(ri "${ri}" ABSOLUTE)
+
+      if(EXISTS "${ri}")
+        #message(STATUS "info: embedded item exists (${ri})")
+        set(resolved 1)
+        set(resolved_item "${ri}")
+      else(EXISTS "${ri}")
+        message(STATUS "warning: embedded item does not exist '${ri}'")
+      endif(EXISTS "${ri}")
+    endif(item MATCHES "@loader_path")
+  endif(NOT resolved)
+
+  if(NOT resolved)
+    set(ri "ri-NOTFOUND")
+    find_file(ri "${item}" ${exepath} ${dirs} NO_DEFAULT_PATH)
+    find_file(ri "${item}" ${exepath} ${dirs} /usr/lib)
+    if(ri)
+      #message(STATUS "info: 'find_file' in exepath/dirs (${ri})")
+      set(resolved 1)
+      set(resolved_item "${ri}")
+      set(ri "ri-NOTFOUND")
+    endif(ri)
+  endif(NOT resolved)
+
+  if(NOT resolved)
+    if(item MATCHES "[^/]+\\.framework/")
+      set(fw "fw-NOTFOUND")
+      find_file(fw "${item}"
+        "~/Library/Frameworks"
+        "/Library/Frameworks"
+        "/System/Library/Frameworks"
+      )
+      if(fw)
+        #message(STATUS "info: 'find_file' found framework (${fw})")
+        set(resolved 1)
+        set(resolved_item "${fw}")
+        set(fw "fw-NOTFOUND")
+      endif(fw)
+    endif(item MATCHES "[^/]+\\.framework/")
+  endif(NOT resolved)
+
+  # Using find_program on Windows will find dll files that are in the PATH.
+  # (Converting simple file names into full path names if found.)
+  #
+  if(WIN32 AND NOT UNIX)
+  if(NOT resolved)
+    set(ri "ri-NOTFOUND")
+    find_program(ri "${item}" PATHS "${exepath};${dirs}" NO_DEFAULT_PATH)
+    find_program(ri "${item}" PATHS "${exepath};${dirs}")
+    if(ri)
+      #message(STATUS "info: 'find_program' in exepath/dirs (${ri})")
+      set(resolved 1)
+      set(resolved_item "${ri}")
+      set(ri "ri-NOTFOUND")
+    endif(ri)
+  endif(NOT resolved)
+  endif(WIN32 AND NOT UNIX)
+
+  # Provide a hook so that projects can override item resolution
+  # by whatever logic they choose:
+  #
+  if(COMMAND gp_resolve_item_override)
+    gp_resolve_item_override("${context}" "${item}" "${exepath}" "${dirs}" resolved_item resolved)
+  endif(COMMAND gp_resolve_item_override)
+
+  if(NOT resolved)
+    message(STATUS "
+warning: cannot resolve item '${item}'
+
+  possible problems:
+    need more directories?
+    need to use InstallRequiredSystemLibraries?
+    run in install tree instead of build tree?
+")
+#    message(STATUS "
+#******************************************************************************
+#warning: cannot resolve item '${item}'
+#
+#  possible problems:
+#    need more directories?
+#    need to use InstallRequiredSystemLibraries?
+#    run in install tree instead of build tree?
+#
+#    context='${context}'
+#    item='${item}'
+#    exepath='${exepath}'
+#    dirs='${dirs}'
+#    resolved_item_var='${resolved_item_var}'
+#******************************************************************************
+#")
+  endif(NOT resolved)
+
+  set(${resolved_item_var} "${resolved_item}" PARENT_SCOPE)
+endfunction(gp_resolve_item)
+
+
+function(gp_resolved_file_type original_file file exepath dirs type_var)
+  #message(STATUS "**")
+
+  if(NOT IS_ABSOLUTE "${original_file}")
+    message(STATUS "warning: gp_resolved_file_type expects absolute full path for first arg original_file")
+  endif()
+
+  set(is_embedded 0)
+  set(is_local 0)
+  set(is_system 0)
+
+  set(resolved_file "${file}")
+
+  if("${file}" MATCHES "^@(executable|loader)_path")
+    set(is_embedded 1)
+  endif()
+
+  if(NOT is_embedded)
+    if(NOT IS_ABSOLUTE "${file}")
+      gp_resolve_item("${original_file}" "${file}" "${exepath}" "${dirs}" resolved_file)
+    endif()
+
+    string(TOLOWER "${original_file}" original_lower)
+    string(TOLOWER "${resolved_file}" lower)
+
+    if(UNIX)
+      if(resolved_file MATCHES "^(/lib/|/lib32/|/lib64/|/usr/lib/|/usr/lib32/|/usr/lib64/|/usr/X11R6/|/usr/bin/)")
+        set(is_system 1)
+      endif()
+    endif()
+
+    if(APPLE)
+      if(resolved_file MATCHES "^(/System/Library/|/usr/lib/)")
+        set(is_system 1)
+      endif()
+    endif()
+
+    if(WIN32)
+      string(TOLOWER "$ENV{SystemRoot}" sysroot)
+      string(REGEX REPLACE "\\\\" "/" sysroot "${sysroot}")
+
+      string(TOLOWER "$ENV{windir}" windir)
+      string(REGEX REPLACE "\\\\" "/" windir "${windir}")
+
+      if(lower MATCHES "^(${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*msvc[^/]+dll)")
+        set(is_system 1)
+      endif()
+
+      if(UNIX)
+        # if cygwin, we can get the properly formed windows paths from cygpath
+        find_program(CYGPATH_EXECUTABLE cygpath)
+
+        if(CYGPATH_EXECUTABLE)
+          execute_process(COMMAND ${CYGPATH_EXECUTABLE} -W
+                          OUTPUT_VARIABLE env_windir
+                          OUTPUT_STRIP_TRAILING_WHITESPACE)
+          execute_process(COMMAND ${CYGPATH_EXECUTABLE} -S
+                          OUTPUT_VARIABLE env_sysdir
+                          OUTPUT_STRIP_TRAILING_WHITESPACE)
+          string(TOLOWER "${env_windir}" windir)
+          string(TOLOWER "${env_sysdir}" sysroot)
+
+          if(lower MATCHES "^(${sysroot}/sys(tem|wow)|${windir}/sys(tem|wow)|(.*/)*msvc[^/]+dll)")
+            set(is_system 1)
+          endif()
+        endif(CYGPATH_EXECUTABLE)
+      endif(UNIX)
+    endif(WIN32)
+
+    if(NOT is_system)
+      get_filename_component(original_path "${original_lower}" PATH)
+      get_filename_component(path "${lower}" PATH)
+      if("${original_path}" STREQUAL "${path}")
+        set(is_local 1)
+      endif()
+    endif()
+  endif()
+
+  # Return type string based on computed booleans:
+  #
+  set(type "other")
+
+  if(is_system)
+    set(type "system")
+  elseif(is_embedded)
+    set(type "embedded")
+  elseif(is_local)
+    set(type "local")
+  endif()
+
+  #message(STATUS "gp_resolved_file_type: '${file}' '${resolved_file}'")
+  #message(STATUS "                type: '${type}'")
+
+  if(NOT is_embedded)
+    if(NOT IS_ABSOLUTE "${resolved_file}")
+      if(lower MATCHES "^msvc[^/]+dll" AND is_system)
+        message(STATUS "info: non-absolute msvc file '${file}' returning type '${type}'")
+      else()
+        message(STATUS "warning: gp_resolved_file_type non-absolute file '${file}' returning type '${type}' -- possibly incorrect")
+      endif()
+    endif()
+  endif()
+
+  # Provide a hook so that projects can override the decision on whether a
+  # library belongs to the system or not by whatever logic they choose:
+  #
+  if(COMMAND gp_resolved_file_type_override)
+    gp_resolved_file_type_override("${resolved_file}" type)
+  endif()
+
+  set(${type_var} "${type}" PARENT_SCOPE)
+
+  #message(STATUS "**")
+endfunction()
+
+
+function(gp_file_type original_file file type_var)
+  if(NOT IS_ABSOLUTE "${original_file}")
+    message(STATUS "warning: gp_file_type expects absolute full path for first arg original_file")
+  endif()
+
+  get_filename_component(exepath "${original_file}" PATH)
+
+  set(type "")
+  gp_resolved_file_type("${original_file}" "${file}" "${exepath}" "" type)
+
+  set(${type_var} "${type}" PARENT_SCOPE)
+endfunction(gp_file_type)
+
+
+function(get_prerequisites target prerequisites_var exclude_system recurse exepath dirs)
+  set(verbose 0)
+  set(eol_char "E")
+
+  if(NOT IS_ABSOLUTE "${target}")
+    message("warning: target '${target}' is not absolute...")
+  endif(NOT IS_ABSOLUTE "${target}")
+
+  if(NOT EXISTS "${target}")
+    message("warning: target '${target}' does not exist...")
+  endif(NOT EXISTS "${target}")
+
+  # <setup-gp_tool-vars>
+  #
+  # Try to choose the right tool by default. Caller can set gp_tool prior to
+  # calling this function to force using a different tool.
+  #
+  if("${gp_tool}" STREQUAL "")
+    set(gp_tool "ldd")
+    if(APPLE)
+      set(gp_tool "otool")
+    endif(APPLE)
+    if(WIN32 AND NOT UNIX) # This is how to check for cygwin, har!
+      set(gp_tool "dumpbin")
+    endif(WIN32 AND NOT UNIX)
+  endif("${gp_tool}" STREQUAL "")
+
+  set(gp_tool_known 0)
+
+  if("${gp_tool}" STREQUAL "ldd")
+    set(gp_cmd_args "")
+    set(gp_regex "^[\t ]*[^\t ]+ => ([^\t\(]+) .*${eol_char}$")
+    set(gp_regex_error "not found${eol_char}$")
+    set(gp_regex_fallback "^[\t ]*([^\t ]+) => ([^\t ]+).*${eol_char}$")
+    set(gp_regex_cmp_count 1)
+    set(gp_tool_known 1)
+  endif("${gp_tool}" STREQUAL "ldd")
+
+  if("${gp_tool}" STREQUAL "otool")
+    set(gp_cmd_args "-L")
+    set(gp_regex "^\t([^\t]+) \\(compatibility version ([0-9]+.[0-9]+.[0-9]+), current version ([0-9]+.[0-9]+.[0-9]+)\\)${eol_char}$")
+    set(gp_regex_error "")
+    set(gp_regex_fallback "")
+    set(gp_regex_cmp_count 3)
+    set(gp_tool_known 1)
+  endif("${gp_tool}" STREQUAL "otool")
+
+  if("${gp_tool}" STREQUAL "dumpbin")
+    set(gp_cmd_args "/dependents")
+    set(gp_regex "^    ([^ ].*[Dd][Ll][Ll])${eol_char}$")
+    set(gp_regex_error "")
+    set(gp_regex_fallback "")
+    set(gp_regex_cmp_count 1)
+    set(gp_tool_known 1)
+    set(ENV{VS_UNICODE_OUTPUT} "") # Block extra output from inside VS IDE.
+  endif("${gp_tool}" STREQUAL "dumpbin")
+
+  if(NOT gp_tool_known)
+    message(STATUS "warning: gp_tool='${gp_tool}' is an unknown tool...")
+    message(STATUS "CMake function get_prerequisites needs more code to handle '${gp_tool}'")
+    message(STATUS "Valid gp_tool values are dumpbin, ldd and otool.")
+    return()
+  endif(NOT gp_tool_known)
+
+  set(gp_cmd_paths ${gp_cmd_paths}
+    "C:/Program Files/Microsoft Visual Studio 9.0/VC/bin"
+    "C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/bin"
+    "C:/Program Files/Microsoft Visual Studio 8/VC/BIN"
+    "C:/Program Files (x86)/Microsoft Visual Studio 8/VC/BIN"
+    "C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/BIN"
+    "C:/Program Files (x86)/Microsoft Visual Studio .NET 2003/VC7/BIN"
+    "/usr/local/bin"
+    "/usr/bin"
+    )
+
+  find_program(gp_cmd ${gp_tool} PATHS ${gp_cmd_paths})
+
+  if(NOT gp_cmd)
+    message(STATUS "warning: could not find '${gp_tool}' - cannot analyze prerequisites...")
+    return()
+  endif(NOT gp_cmd)
+
+  if("${gp_tool}" STREQUAL "dumpbin")
+    # When running dumpbin, it also needs the "Common7/IDE" directory in the
+    # PATH. It will already be in the PATH if being run from a Visual Studio
+    # command prompt. Add it to the PATH here in case we are running from a
+    # different command prompt.
+    #
+    get_filename_component(gp_cmd_dir "${gp_cmd}" PATH)
+    get_filename_component(gp_cmd_dlls_dir "${gp_cmd_dir}/../../Common7/IDE" ABSOLUTE)
+    # Use cmake paths as a user may have a PATH element ending with a backslash.
+    # This will escape the list delimiter and create havoc!
+    if(EXISTS "${gp_cmd_dlls_dir}")
+      # only add to the path if it is not already in the path
+      set(gp_found_cmd_dlls_dir 0)
+      file(TO_CMAKE_PATH "$ENV{PATH}" env_path)
+      foreach(gp_env_path_element ${env_path})
+        if("${gp_env_path_element}" STREQUAL "${gp_cmd_dlls_dir}")
+          set(gp_found_cmd_dlls_dir 1)
+        endif()
+      endforeach(gp_env_path_element)
+
+      if(NOT gp_found_cmd_dlls_dir)
+        file(TO_NATIVE_PATH "${gp_cmd_dlls_dir}" gp_cmd_dlls_dir)
+        set(ENV{PATH} "$ENV{PATH};${gp_cmd_dlls_dir}")
+      endif()
+    endif(EXISTS "${gp_cmd_dlls_dir}")
+  endif("${gp_tool}" STREQUAL "dumpbin")
+  #
+  # </setup-gp_tool-vars>
+
+  if("${gp_tool}" STREQUAL "ldd")
+    set(old_ld_env "$ENV{LD_LIBRARY_PATH}")
+    foreach(dir ${exepath} ${dirs})
+      set(ENV{LD_LIBRARY_PATH} "${dir}:$ENV{LD_LIBRARY_PATH}")
+    endforeach(dir)
+  endif("${gp_tool}" STREQUAL "ldd")
+
+
+  # Track new prerequisites at each new level of recursion. Start with an
+  # empty list at each level:
+  #
+  set(unseen_prereqs)
+
+  # Run gp_cmd on the target:
+  #
+  execute_process(
+    COMMAND ${gp_cmd} ${gp_cmd_args} ${target}
+    OUTPUT_VARIABLE gp_cmd_ov
+    )
+
+  if("${gp_tool}" STREQUAL "ldd")
+    set(ENV{LD_LIBRARY_PATH} "${old_ld_env}")
+  endif("${gp_tool}" STREQUAL "ldd")
+
+  if(verbose)
+    message(STATUS "<RawOutput cmd='${gp_cmd} ${gp_cmd_args} ${target}'>")
+    message(STATUS "gp_cmd_ov='${gp_cmd_ov}'")
+    message(STATUS "</RawOutput>")
+  endif(verbose)
+
+  get_filename_component(target_dir "${target}" PATH)
+
+  # Convert to a list of lines:
+  #
+  string(REGEX REPLACE ";" "\\\\;" candidates "${gp_cmd_ov}")
+  string(REGEX REPLACE "\n" "${eol_char};" candidates "${candidates}")
+
+  # check for install id and remove it from list, since otool -L can include a
+  # reference to itself
+  set(gp_install_id)
+  if("${gp_tool}" STREQUAL "otool")
+    execute_process(
+      COMMAND otool -D ${target}
+      OUTPUT_VARIABLE gp_install_id_ov
+      )
+    # second line is install name
+    string(REGEX REPLACE ".*:\n" "" gp_install_id "${gp_install_id_ov}")
+    if(gp_install_id)
+      # trim
+      string(REGEX MATCH "[^\n ].*[^\n ]" gp_install_id "${gp_install_id}")
+      #message("INSTALL ID is \"${gp_install_id}\"")
+    endif(gp_install_id)
+  endif("${gp_tool}" STREQUAL "otool")
+
+  # Analyze each line for file names that match the regular expression:
+  #
+  foreach(candidate ${candidates})
+  if("${candidate}" MATCHES "${gp_regex}")
+
+    # Extract information from each candidate:
+    if(gp_regex_error AND "${candidate}" MATCHES "${gp_regex_error}")
+      string(REGEX REPLACE "${gp_regex_fallback}" "\\1" raw_item "${candidate}")
+    else(gp_regex_error AND "${candidate}" MATCHES "${gp_regex_error}")
+      string(REGEX REPLACE "${gp_regex}" "\\1" raw_item "${candidate}")
+    endif(gp_regex_error AND "${candidate}" MATCHES "${gp_regex_error}")
+
+    if(gp_regex_cmp_count GREATER 1)
+      string(REGEX REPLACE "${gp_regex}" "\\2" raw_compat_version "${candidate}")
+      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" compat_major_version "${raw_compat_version}")
+      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" compat_minor_version "${raw_compat_version}")
+      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" compat_patch_version "${raw_compat_version}")
+    endif(gp_regex_cmp_count GREATER 1)
+
+    if(gp_regex_cmp_count GREATER 2)
+      string(REGEX REPLACE "${gp_regex}" "\\3" raw_current_version "${candidate}")
+      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" current_major_version "${raw_current_version}")
+      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" current_minor_version "${raw_current_version}")
+      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" current_patch_version "${raw_current_version}")
+    endif(gp_regex_cmp_count GREATER 2)
+
+    # Use the raw_item as the list entries returned by this function. Use the
+    # gp_resolve_item function to resolve it to an actual full path file if
+    # necessary.
+    #
+    set(item "${raw_item}")
+
+    # Add each item unless it is excluded:
+    #
+    set(add_item 1)
+
+    if("${item}" STREQUAL "${gp_install_id}")
+      set(add_item 0)
+    endif("${item}" STREQUAL "${gp_install_id}")
+
+    if(add_item AND ${exclude_system})
+      set(type "")
+      gp_resolved_file_type("${target}" "${item}" "${exepath}" "${dirs}" type)
+
+      if("${type}" STREQUAL "system")
+        set(add_item 0)
+      endif("${type}" STREQUAL "system")
+    endif(add_item AND ${exclude_system})
+
+    if(add_item)
+      list(LENGTH ${prerequisites_var} list_length_before_append)
+      gp_append_unique(${prerequisites_var} "${item}")
+      list(LENGTH ${prerequisites_var} list_length_after_append)
+
+      if(${recurse})
+        # If item was really added, this is the first time we have seen it.
+        # Add it to unseen_prereqs so that we can recursively add *its*
+        # prerequisites...
+        #
+        # But first: resolve its name to an absolute full path name such
+        # that the analysis tools can simply accept it as input.
+        #
+        if(NOT list_length_before_append EQUAL list_length_after_append)
+          gp_resolve_item("${target}" "${item}" "${exepath}" "${dirs}" resolved_item)
+          set(unseen_prereqs ${unseen_prereqs} "${resolved_item}")
+        endif(NOT list_length_before_append EQUAL list_length_after_append)
+      endif(${recurse})
+    endif(add_item)
+  else("${candidate}" MATCHES "${gp_regex}")
+    if(verbose)
+      message(STATUS "ignoring non-matching line: '${candidate}'")
+    endif(verbose)
+  endif("${candidate}" MATCHES "${gp_regex}")
+  endforeach(candidate)
+
+  list(LENGTH ${prerequisites_var} prerequisites_var_length)
+  if(prerequisites_var_length GREATER 0)
+    list(SORT ${prerequisites_var})
+  endif(prerequisites_var_length GREATER 0)
+  if(${recurse})
+    set(more_inputs ${unseen_prereqs})
+    foreach(input ${more_inputs})
+      get_prerequisites("${input}" ${prerequisites_var} ${exclude_system} ${recurse} "${exepath}" "${dirs}")
+    endforeach(input)
+  endif(${recurse})
+
+  set(${prerequisites_var} ${${prerequisites_var}} PARENT_SCOPE)
+endfunction(get_prerequisites)
+
+
+function(list_prerequisites target)
+  if("${ARGV1}" STREQUAL "")
+    set(all 1)
+  else("${ARGV1}" STREQUAL "")
+    set(all "${ARGV1}")
+  endif("${ARGV1}" STREQUAL "")
+
+  if("${ARGV2}" STREQUAL "")
+    set(exclude_system 0)
+  else("${ARGV2}" STREQUAL "")
+    set(exclude_system "${ARGV2}")
+  endif("${ARGV2}" STREQUAL "")
+
+  if("${ARGV3}" STREQUAL "")
+    set(verbose 0)
+  else("${ARGV3}" STREQUAL "")
+    set(verbose "${ARGV3}")
+  endif("${ARGV3}" STREQUAL "")
+
+  set(count 0)
+  set(count_str "")
+  set(print_count "${verbose}")
+  set(print_prerequisite_type "${verbose}")
+  set(print_target "${verbose}")
+  set(type_str "")
+
+  get_filename_component(exepath "${target}" PATH)
+
+  set(prereqs "")
+  get_prerequisites("${target}" prereqs ${exclude_system} ${all} "${exepath}" "")
+
+  if(print_target)
+    message(STATUS "File '${target}' depends on:")
+  endif(print_target)
+
+  foreach(d ${prereqs})
+    math(EXPR count "${count} + 1")
+
+    if(print_count)
+      set(count_str "${count}. ")
+    endif(print_count)
+
+    if(print_prerequisite_type)
+      gp_file_type("${target}" "${d}" type)
+      set(type_str " (${type})")
+    endif(print_prerequisite_type)
+
+    message(STATUS "${count_str}${d}${type_str}")
+  endforeach(d)
+endfunction(list_prerequisites)
+
+
+function(list_prerequisites_by_glob glob_arg glob_exp)
+  message(STATUS "=============================================================================")
+  message(STATUS "List prerequisites of executables matching ${glob_arg} '${glob_exp}'")
+  message(STATUS "")
+  file(${glob_arg} file_list ${glob_exp})
+  foreach(f ${file_list})
+    is_file_executable("${f}" is_f_executable)
+    if(is_f_executable)
+      message(STATUS "=============================================================================")
+      list_prerequisites("${f}" ${ARGN})
+      message(STATUS "")
+    endif(is_f_executable)
+  endforeach(f)
+endfunction(list_prerequisites_by_glob)
diff --git a/InstallRules/dependencies.cmake.in b/InstallRules/dependencies.cmake.in
new file mode 100644
index 0000000..01651ab
--- /dev/null
+++ b/InstallRules/dependencies.cmake.in
@@ -0,0 +1,12 @@
+if("${CMAKE_VERSION}" VERSION_LESS "2.8.5")
+  # older CMake, add to CMAKE_MODULE_PATH, use local BundleUtilities and GetPrerequisites
+  set(CMAKE_MODULE_PATH "@CMAKE_CURRENT_SOURCE_DIR@" ${CMAKE_MODULE_PATH})
+endif()
+
+function(gp_item_default_embedded_path_override path)
+  set(path "@executable_path" PARENT_SCOPE)
+endfunction()
+
+include(BundleUtilities)
+
+fixup_bundle("$ENV{DESTDIR}@CMAKE_INSTALL_PREFIX@/bin/rvu@CMAKE_EXECUTABLE_SUFFIX@" "" "@QT_LIBRARY_DIR@")
diff --git a/cmake_tests/CMakeLists.txt b/cmake_tests/CMakeLists.txt
new file mode 100644
index 0000000..54a3818
--- /dev/null
+++ b/cmake_tests/CMakeLists.txt
@@ -0,0 +1,53 @@
+include(FindPerl)
+
+set(office_dir
+  "${radiance_BINARY_DIR}/Downloads/Source/radiance_support/obj/office")
+set(test_dir "${CMAKE_CURRENT_BINARY_DIR}")
+
+configure_file(setup_paths.cmake.in setup_paths.cmake @ONLY)
+# configure these files so that they will be in the binary
+# directory.  This will allow them to include setup_paths.cmake
+# from the binary directory and just use regular variables in the
+# configured files.
+configure_file(test_setup.cmake test_setup.cmake COPYONLY)
+configure_file(test_rtrace.cmake test_rtrace.cmake COPYONLY)
+configure_file(test_rpict.cmake test_rpict.cmake COPYONLY)
+configure_file(test_getinfo.cmake test_getinfo.cmake COPYONLY)
+configure_file(test_pcond.cmake test_pcond.cmake COPYONLY)
+configure_file(test_falsecolor.cmake test_falsecolor.cmake COPYONLY)
+configure_file(test_DC.cmake test_DC.cmake COPYONLY)
+
+add_test(test_setup ${CMAKE_COMMAND}
+  -P ${CMAKE_CURRENT_BINARY_DIR}/test_setup.cmake)
+set_tests_properties(test_setup PROPERTIES FAIL_REGULAR_EXPRESSION
+  "No such file|not found|cannot find file|unexpected character")
+
+add_test(test_rtrace
+  ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/test_rtrace.cmake)
+set_tests_properties(test_rtrace PROPERTIES PASS_REGULAR_EXPRESSION "passed"
+                                            FAIL_REGULAR_EXPRESSION "failed"
+                                            DEPENDS "setup")
+add_test(test_rpict
+  ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/test_rpict.cmake)
+set_tests_properties(test_rpict PROPERTIES PASS_REGULAR_EXPRESSION "passed"
+                                            FAIL_REGULAR_EXPRESSION "failed"
+                                            DEPENDS "setup")
+add_test(test_getinfo
+  ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/test_getinfo.cmake)
+add_test(test_pcond
+  ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/test_pcond.cmake)
+set_tests_properties(test_pcond PROPERTIES PASS_REGULAR_EXPRESSION "passed"
+                                            FAIL_REGULAR_EXPRESSION "failed"
+                                            DEPENDS "setup")
+if(PERL_FOUND)
+  add_test(test_falsecolor
+    ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/test_falsecolor.cmake)
+  set_tests_properties(test_falsecolor PROPERTIES PASS_REGULAR_EXPRESSION "passed"
+                                              FAIL_REGULAR_EXPRESSION "failed"
+                                              DEPENDS "setup")
+  add_test(test_DC
+    ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/test_DC.cmake)
+  set_tests_properties(test_DC PROPERTIES PASS_REGULAR_EXPRESSION "passed"
+                                              FAIL_REGULAR_EXPRESSION "failed"
+                                              DEPENDS "setup")
+endif()
diff --git a/cmake_tests/setup_paths.cmake.in b/cmake_tests/setup_paths.cmake.in
new file mode 100644
index 0000000..0b1d43e
--- /dev/null
+++ b/cmake_tests/setup_paths.cmake.in
@@ -0,0 +1,31 @@
+if(WIN32)
+  set(sep ";")
+else()
+  set(sep ":")
+  set(rtcontrib_threads "-n;2;")
+endif()
+
+
+file(TO_NATIVE_PATH "@radiance_SOURCE_DIR@/src/gen" gen_dir)
+file(TO_NATIVE_PATH "@radiance_SOURCE_DIR@/src/cal/cal" cal_dir)
+file(TO_NATIVE_PATH "@radiance_SOURCE_DIR@/src/rt" rt_dir)
+file(TO_NATIVE_PATH "@radiance_SOURCE_DIR@/src/util" util_dir)
+file(TO_NATIVE_PATH "@radiance_SOURCE_DIR@/src/px" px_dir)
+file(TO_NATIVE_PATH
+  "@radiance_BINARY_DIR@/Downloads/Source/radiance_support/lib" lib_dir)
+file(TO_NATIVE_PATH "@PERL_EXECUTABLE@" perl)
+set(office_dir @office_dir@)
+#office_dir is defined in CMakeLists.txt
+
+if(NOT EXISTS ${lib_dir}/pine.pic)
+  configure_file(${lib_dir}/pine.hdr ${lib_dir}/pine.pic COPYONLY)
+endif()
+
+file(TO_NATIVE_PATH "@radiance_BINARY_DIR@/bin" rpath)
+set(ENV{RAYPATH}
+"${gen_dir}${sep}${cal_dir}${sep}${rt_dir}${sep}${lib_dir}${sep}@office_dir@")
+set(ENV{PATH} "$ENV{PATH}${sep}${rpath}")
+set(test_output_dir
+  @radiance_BINARY_DIR@/Downloads/Source/radiance_support/obj/office/test)
+set(CMAKE_EXECUTABLE_SUFFIX @CMAKE_EXECUTABLE_SUFFIX@)
+message(STATUS "raypath: $ENV{RAYPATH}")
diff --git a/cmake_tests/test_DC.cmake b/cmake_tests/test_DC.cmake
new file mode 100644
index 0000000..a6882e2
--- /dev/null
+++ b/cmake_tests/test_DC.cmake
@@ -0,0 +1,59 @@
+include(setup_paths.cmake)
+
+file(MAKE_DIRECTORY "${test_output_dir}/dc")
+
+set(view_def -x 50 -y 50 -vf model.vp)
+message(STATUS "view_def=${view_def}")
+
+file(WRITE ${office_dir}/test/raytest_dc.sky 
+"void glow skyglow\n0\n0\n4\n1 1 1 0\n\nskyglow source sky\n0\n0\n4\n0 0 1 360
+")
+
+message("Run: oconv${CMAKE_EXECUTABLE_SUFFIX} -f -i test/raytest_model.oct test/raytest_dc.sky")
+execute_process(
+  WORKING_DIRECTORY ${office_dir}
+  COMMAND oconv${CMAKE_EXECUTABLE_SUFFIX} -f -i test/raytest_model.oct test/raytest_dc.sky
+  OUTPUT_FILE test/raytest_model_dc.oct
+)
+
+execute_process(
+  WORKING_DIRECTORY ${office_dir}
+  COMMAND vwrays -d ${view_def}
+  OUTPUT_VARIABLE vwrays_out
+)
+
+message(STATUS "vwrays_out: ${vwrays_out}")
+string(STRIP "${vwrays_out}" vwrays_out)
+separate_arguments(vwrays_out)
+
+message("Run: vwrays${CMAKE_EXECUTABLE_SUFFIX} -ff ${view_def} | rtcontrib${CMAKE_EXECUTABLE_SUFFIX} -ab 1 ${rtcontrib_threads}-V+ -fo -ffc $\(vwrays -d ${view_def}\) -f tregenza.cal -bn 146 -b tbin -o ${test_output_dir}/dc/treg%03d.hdr -m skyglow test/raytest_model_dc.oct")
+execute_process(
+  WORKING_DIRECTORY ${office_dir}
+  COMMAND vwrays${CMAKE_EXECUTABLE_SUFFIX} -ff ${view_def} 
+  COMMAND rtcontrib${CMAKE_EXECUTABLE_SUFFIX} -ab 1 ${rtcontrib_threads}-V+ -fo -ffc ${vwrays_out} -f tregenza.cal -bn 146 -b tbin -o ${test_output_dir}/dc/treg%03d.hdr -m skyglow test/raytest_model_dc.oct
+  RESULT_VARIABLE res
+)
+if(NOT ${res} EQUAL 0)
+  message(FATAL_ERROR "Bad return value from vwrays, res = ${res}")
+endif() 
+
+execute_process( 
+  WORKING_DIRECTORY ${office_dir}
+  COMMAND gensky${CMAKE_EXECUTABLE_SUFFIX} 03 21 12 -a 40 -o 105 -m 105 +s
+  COMMAND ${perl} ${util_dir}/genskyvec.pl -m 1
+  COMMAND dctimestep${CMAKE_EXECUTABLE_SUFFIX} test/dc/treg%03d.hdr
+  COMMAND pfilt${CMAKE_EXECUTABLE_SUFFIX} -1 -x /1 -y /1
+  OUTPUT_FILE test/raytest_timestep.hdr
+  RESULT_VARIABLE res
+)
+
+if(NOT ${res} EQUAL 0)
+  message(FATAL_ERROR "Bad return value, res = ${res}")
+endif()
+
+file(READ ${office_dir}/test/raytest_timestep.hdr test_output)
+if(test_output MATCHES "dctimestep${CMAKE_EXECUTABLE_SUFFIX} test/dc/treg%03d.hdr")
+  message(STATUS "passed")
+else()
+  message(STATUS "failed")
+endif()
diff --git a/cmake_tests/test_falsecolor.cmake b/cmake_tests/test_falsecolor.cmake
new file mode 100644
index 0000000..a99cd3d
--- /dev/null
+++ b/cmake_tests/test_falsecolor.cmake
@@ -0,0 +1,18 @@
+include(setup_paths.cmake)
+
+execute_process(
+  WORKING_DIRECTORY ${office_dir}
+  COMMAND ${perl} ${px_dir}/falsecolor.pl -e -i  test/raytest_rpict.hdr
+  OUTPUT_FILE test/raytest_falsecolor.hdr
+  RESULT_VARIABLE res
+)
+if(NOT ${res} EQUAL 0)
+  message(FATAL_ERROR "Bad return value from falsecolor, res = ${res}")
+endif()
+
+file(READ ${office_dir}/test/raytest_falsecolor.hdr test_output)
+if(test_output MATCHES "minv")
+  message(STATUS "passed")
+else()
+  message(STATUS "failed")
+endif()
diff --git a/cmake_tests/test_getinfo.cmake b/cmake_tests/test_getinfo.cmake
new file mode 100644
index 0000000..ab6734f
--- /dev/null
+++ b/cmake_tests/test_getinfo.cmake
@@ -0,0 +1,19 @@
+include(setup_paths.cmake)
+
+
+execute_process(
+  WORKING_DIRECTORY ${office_dir}
+  COMMAND getinfo${CMAKE_EXECUTABLE_SUFFIX} test/raytest_rpict.hdr
+  OUTPUT_FILE test/raytest_falsecolor.hdr
+  RESULT_VARIABLE res
+)
+if(NOT ${res} EQUAL 0)
+  message(FATAL_ERROR "Bad return value from getinfo, res = ${res}")
+endif()
+
+file(READ ${office_dir}/test/raytest_falsecolor.hdr test_output)
+if(test_output MATCHES "RADIANCE")
+  message(STATUS "passed")
+else()
+  message(STATUS "failed")
+endif()
\ No newline at end of file
diff --git a/cmake_tests/test_pcond.cmake b/cmake_tests/test_pcond.cmake
new file mode 100644
index 0000000..fcc9a25
--- /dev/null
+++ b/cmake_tests/test_pcond.cmake
@@ -0,0 +1,20 @@
+include(setup_paths.cmake)
+
+execute_process(
+  WORKING_DIRECTORY ${office_dir}
+  COMMAND rpict${CMAKE_EXECUTABLE_SUFFIX} -ab 0 -vf model.vp test/raytest_model.oct
+  OUTPUT_FILE test/raytest_rpict.hdr
+  COMMAND pcond${CMAKE_EXECUTABLE_SUFFIX} -h test/raytest_rpict.hdr
+  OUTPUT_FILE test/raytest_rpict_pcd.hdr
+  RESULT_VARIABLE res
+)
+if(NOT ${res} EQUAL 0)
+  message(FATAL_ERROR "Bad return value from pcond, res = ${res}")
+endif()
+
+file(READ ${office_dir}/test/raytest_rpict_pcd.hdr test_output)
+if(test_output MATCHES "pcond -h")
+  message(STATUS "passed")
+else()
+  message(STATUS "failed")
+endif()
\ No newline at end of file
diff --git a/cmake_tests/test_rpict.cmake b/cmake_tests/test_rpict.cmake
new file mode 100644
index 0000000..515a2a2
--- /dev/null
+++ b/cmake_tests/test_rpict.cmake
@@ -0,0 +1,20 @@
+include(setup_paths.cmake)
+
+# run rpict on office model
+execute_process(
+  COMMAND rpict${CMAKE_EXECUTABLE_SUFFIX} -ab 0 -vf model.vp test/raytest_model.oct
+  WORKING_DIRECTORY ${office_dir}
+  OUTPUT_FILE test/raytest_rpict.hdr
+  RESULT_VARIABLE res
+)
+if(NOT ${res} EQUAL 0)
+  message(FATAL_ERROR "Bad return value from rpict, res = ${res}")
+endif()
+
+# scan output file for valid header
+file(READ ${office_dir}/test/raytest_rpict.hdr test_output)
+if(test_output MATCHES "SOFTWARE= RADIANCE")
+  message(STATUS "passed")
+else()
+  message(STATUS "failed")
+endif()
diff --git a/cmake_tests/test_rtrace.cmake b/cmake_tests/test_rtrace.cmake
new file mode 100644
index 0000000..eb4da89
--- /dev/null
+++ b/cmake_tests/test_rtrace.cmake
@@ -0,0 +1,21 @@
+include(setup_paths.cmake)
+file(WRITE ${office_dir}/test/raytest_rtrace.in
+"-23 24.6 5.8 0 1 0
+")
+execute_process(
+  COMMAND rtrace${CMAKE_EXECUTABLE_SUFFIX} -ab 1 test/raytest_model.oct
+  WORKING_DIRECTORY ${office_dir}
+  INPUT_FILE test/raytest_rtrace.in
+  OUTPUT_FILE test/raytest_rtrace.out
+  RESULT_VARIABLE res
+)
+if(NOT ${res} EQUAL 0)
+  message(FATAL_ERROR "Bad return value from rtrace, res = ${res}")
+endif()
+
+file(READ ${office_dir}/test/raytest_rtrace.out test_output)
+if(test_output MATCHES "SOFTWARE= RADIANCE")
+  message(STATUS "passed")
+else()
+  message(STATUS "failed")
+endif()
diff --git a/cmake_tests/test_setup.cmake b/cmake_tests/test_setup.cmake
new file mode 100644
index 0000000..b8ceb40
--- /dev/null
+++ b/cmake_tests/test_setup.cmake
@@ -0,0 +1,30 @@
+include(setup_paths.cmake) # configured file found in the same dir as this file
+
+file(REMOVE_RECURSE ${test_output_dir})
+file(MAKE_DIRECTORY ${test_output_dir})
+
+message("Run: [oconv${CMAKE_EXECUTABLE_SUFFIX} model.b90 desk misc]")
+execute_process(
+  COMMAND oconv${CMAKE_EXECUTABLE_SUFFIX} model.b90 desk misc
+  WORKING_DIRECTORY ${office_dir}
+  OUTPUT_FILE test/raytest_modelb.oct
+  RESULT_VARIABLE res
+)
+if(NOT ${res} EQUAL 0)
+  message(FATAL_ERROR "Bad return value from oconv, res = ${res}")
+endif()
+
+message("Run:
+  [oconv${CMAKE_EXECUTABLE_SUFFIX} -f -i test/raytest_modelb.oct
+  window blinds lights lamp picture]")
+execute_process(
+  COMMAND oconv${CMAKE_EXECUTABLE_SUFFIX}
+  -f -i test/raytest_modelb.oct window blinds lights lamp picture
+  WORKING_DIRECTORY ${office_dir}
+  OUTPUT_FILE test/raytest_model.oct
+  RESULT_VARIABLE res
+)
+
+if(NOT ${res} EQUAL 0)
+  message(FATAL_ERROR "Bad return value from oconv, res = ${res}")
+endif()
diff --git a/license.txt b/license.txt
new file mode 100644
index 0000000..27603d8
--- /dev/null
+++ b/license.txt
@@ -0,0 +1,55 @@
+The Radiance Software License, Version 1.0
+
+Copyright (c) 1990 - 2002 The Regents of the University of California,
+through Lawrence Berkeley National Laboratory.   All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+        notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+
+3. The end-user documentation included with the redistribution,
+          if any, must include the following acknowledgment:
+            "This product includes Radiance software
+                (http://radsite.lbl.gov/)
+                developed by the Lawrence Berkeley National Laboratory
+              (http://www.lbl.gov/)."
+      Alternately, this acknowledgment may appear in the software itself,
+      if and wherever such third-party acknowledgments normally appear.
+
+4. The names "Radiance," "Lawrence Berkeley National Laboratory"
+      and "The Regents of the University of California" must
+      not be used to endorse or promote products derived from this
+      software without prior written permission. For written
+      permission, please contact radiance@radsite.lbl.gov.
+
+5. Products derived from this software may not be called "Radiance",
+      nor may "Radiance" appear in their name, without prior written
+      permission of Lawrence Berkeley National Laboratory.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.   IN NO EVENT SHALL Lawrence Berkeley National Laboratory OR
+ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+====================================================================
+
+This software consists of voluntary contributions made by many
+individuals on behalf of Lawrence Berkeley National Laboratory.   For more
+information on Lawrence Berkeley National Laboratory, please see
+<http://www.lbl.gov/>.
+
diff --git a/readme.txt b/readme.txt
new file mode 100644
index 0000000..86a34d2
--- /dev/null
+++ b/readme.txt
@@ -0,0 +1,4 @@
+Help is avaiable online at the Radiance knowledge database:
+
+http://wwww.radiance-online.org
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..13375e0
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,29 @@
+if(UNIX)
+  find_library(LIB_M m DOC "Path to libm")
+  if(NOT LIB_M)
+    message(FATAL_ERROR "Cannot build radiance without libm.  Please set LIB_M")
+  endif()
+else()
+  set(LIB_M )
+endif()
+
+find_package(OpenGL)
+find_package(X11)
+
+include_directories(common)
+
+add_subdirectory(common)
+add_subdirectory(cal)
+add_subdirectory(cv)
+add_subdirectory(gen)
+add_subdirectory(hd)
+add_subdirectory(meta)
+add_subdirectory(ot)
+add_subdirectory(px)
+add_subdirectory(rt)
+add_subdirectory(util)
+# only use rvu if qt4 is found
+if(QT4_FOUND)
+  add_subdirectory(rvu)
+endif()
+
diff --git a/src/cal/CMakeLists.txt b/src/cal/CMakeLists.txt
new file mode 100644
index 0000000..541b54a
--- /dev/null
+++ b/src/cal/CMakeLists.txt
@@ -0,0 +1,27 @@
+add_executable(cnt cnt.c)
+
+add_executable(ev ev.c)
+target_link_libraries(ev rtrad)
+
+add_executable(histo histo.c)
+target_link_libraries(histo ${LIB_M})
+
+add_executable(icalc calc.c)
+target_link_libraries(icalc rtrad)
+
+add_executable(neaten neat.c)
+
+add_executable(rcalc rcalc.c)
+target_link_libraries(rcalc rtrad)
+
+add_executable(rlam lam.c)
+target_link_libraries(rlam rtrad)
+
+add_executable(tabfunc tabfunc.c)
+target_link_libraries(tabfunc rtrad)
+
+add_executable(total total.c)
+target_link_libraries(total ${LIB_M})
+
+install(TARGETS ev histo icalc neaten rcalc rlam tabfunc total
+  RUNTIME DESTINATION bin)
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
new file mode 100644
index 0000000..f368a0b
--- /dev/null
+++ b/src/common/CMakeLists.txt
@@ -0,0 +1,31 @@
+set(rtrad_SOURCES
+  addobjnotify.c badarg.c biggerlib.c bmalloc.c bmpfile.c bsdf.c bsdf_m.c
+  bsdf_t.c byteswap.c caldefn.c calexpr.c calfunc.c calprnt.c ccolor.c ccyrgb.c
+  chanvalue.c clip.c color.c colrops.c cone.c dircode.c disk2square.c ealloc.c
+  eputs.c erf.c error.c expandarg.c ezxml.c face.c falsecolor.c fdate.c
+  fgetline.c fgetval.c fgetword.c fixargv0.c font.c fputword.c free_os.c
+  fropen.c fvect.c gethomedir.c getlibpath.c getpath.c header.c hilbert.c
+  image.c instance.c invmat4.c lamps.c linregr.c loadbsdf.c loadvars.c lookup.c
+  mat4.c mesh.c modobject.c multisamp.c myhostname.c objset.c octree.c otypes.c
+  paths.c plocate.c portio.c process.c quit.c readfargs.c readmesh.c readobj.c
+  readoct.c resolu.c rexpr.c savqstr.c savestr.c sceneio.c spec_rgb.c tcos.c
+  tmap16bit.c tmapcolrs.c tmapluv.c timegm.c tmaptiff.c tmesh.c tonemap.c
+  urand.c urind.c words.c wordfile.c wputs.c xf.c zeroes.c)
+
+if(UNIX)
+  list(APPEND rtrad_SOURCES unix_process.c strcmp.c)
+else()
+  list(APPEND rtrad_SOURCES win_process.c win_popen.c)
+endif()
+
+add_library(rtrad ${rtrad_SOURCES})
+target_link_libraries(rtrad ${LIB_M})
+if(WIN32)
+  target_link_libraries(rtrad ws2_32)
+endif()
+
+add_library(mgf mgf_parser.c mgf_object.c mgf_xf.c mgf_context.c)
+
+install(TARGETS rtrad mgf
+  LIBRARY DESTINATION bin
+  ARCHIVE DESTINATION bin)
diff --git a/src/common/create_version.cmake b/src/common/create_version.cmake
new file mode 100644
index 0000000..837e8b1
--- /dev/null
+++ b/src/common/create_version.cmake
@@ -0,0 +1,26 @@
+#${CMAKE_COMMAND} -DVERSION_OUT_FILE=v  -DVERSION_IN_FILE=src/util/VERSION -P src/common/create_version.cmake
+find_program(DATE date)
+if(DATE)
+  execute_process(COMMAND ${DATE} OUTPUT_VARIABLE DATE_STR)
+  string(STRIP "${DATE_STR}" DATE_STR)
+endif()
+find_program(WHO whoami)
+if(WHO)
+  execute_process(COMMAND ${WHO} OUTPUT_VARIABLE WHO_STR)
+  string(STRIP "${WHO_STR}" WHO_STR)
+endif()
+find_program(HOSTNAME hostname)
+if(HOSTNAME)
+  execute_process(COMMAND ${HOSTNAME} OUTPUT_VARIABLE HOST_STR)
+  message("DATE= ${DATE_STR}")
+  string(STRIP "${HOST_STR}" HOST_STR)
+endif()
+file(READ "${VERSION_IN_FILE}" VERSION)
+string(STRIP "${VERSION}" VERSION)
+message("${VERSION}")
+file(WRITE "${VERSION_OUT_FILE}"
+"char VersionID[]=\"${VERSION} lastmod ${DATE_STR}"
+" by ${WHO_STR} on ${HOST_STR}\";\n"
+)
+
+# todo actually get the date, user name and hostname in this script
diff --git a/src/cv/CMakeLists.txt b/src/cv/CMakeLists.txt
new file mode 100644
index 0000000..b103608
--- /dev/null
+++ b/src/cv/CMakeLists.txt
@@ -0,0 +1,43 @@
+add_executable(arch2rad arch2rad.c trans.c)
+target_link_libraries(arch2rad rtrad)
+
+add_executable(ies2rad ies2rad.c)
+target_link_libraries(ies2rad rtrad)
+
+add_executable(lampcolor lampcolor.c)
+target_link_libraries(lampcolor rtrad)
+
+add_executable(mgf2rad mgf2rad.c)
+target_link_libraries(mgf2rad mgf rtrad)
+
+add_executable(nff2rad nff2rad.c)
+
+add_executable(obj2rad obj2rad.c trans.c)
+target_link_libraries(obj2rad rtrad)
+
+add_executable(rad2mgf rad2mgf.c)
+target_link_libraries(rad2mgf rtrad)
+
+add_executable(tmesh2rad tmesh2rad.c)
+target_link_libraries(tmesh2rad rtrad)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../meta)
+add_executable(mgf2meta mgf2meta.c)
+target_link_libraries(mgf2meta mgf meta rtrad)
+
+add_executable(mgfilt mgfilt.c)
+target_link_libraries(mgfilt mgf rtrad)
+
+add_executable(3ds2mgf 3ds2mgf.c rayopt3ds.c vect3ds.c)
+target_link_libraries(3ds2mgf rtrad) 
+
+add_executable(mgf2inv mgf2inv.c)
+target_link_libraries(mgf2inv mgf rtrad) 
+
+install(TARGETS 
+    ies2rad nff2rad lampcolor tmesh2rad obj2rad mgf2rad
+    rad2mgf mgf2meta mgfilt mgf2inv 3ds2mgf
+  RUNTIME DESTINATION bin)
+
+INSTALL(FILES source.cal tilt.cal lamp.tab window.cal
+  DESTINATION bin)
diff --git a/src/gen/CMakeLists.txt b/src/gen/CMakeLists.txt
new file mode 100644
index 0000000..49f0a9a
--- /dev/null
+++ b/src/gen/CMakeLists.txt
@@ -0,0 +1,59 @@
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../rt)
+
+add_executable(genbeads genbeads.c hermite3.c)
+target_link_libraries(genbeads ${LIB_M})
+
+add_executable(genblinds genblinds.c)
+target_link_libraries(genblinds ${LIB_M})
+
+add_executable(genbox genbox.c)
+
+add_executable(genbranch genbranch.c)
+target_link_libraries(genbranch ${LIB_M})
+
+add_executable(gencatenary gencat.c)
+target_link_libraries(gencatenary rtrad)
+
+add_executable(genclock genclock.c)
+target_link_libraries(genclock ${LIB_M})
+
+add_executable(gendaylit gendaylit.c sun.c)
+target_link_libraries(gendaylit rtrad)
+
+add_executable(genmarble genmarble.c ../common/random.h)
+target_link_libraries(genmarble ${LIB_M})
+
+add_executable(genprism genprism.c)
+target_link_libraries(genprism ${LIB_M})
+
+add_executable(genrev genrev.c )
+target_link_libraries(genrev rtrad)
+
+add_executable(gensky gensky.c sun.c)
+target_link_libraries(gensky ${LIB_M})
+
+add_executable(gensurf gensurf.c)
+target_link_libraries(gensurf rtrad)
+
+add_executable(genworm genworm.c)
+target_link_libraries(genworm rtrad)
+
+add_executable(mkillum mkillum.c mkillum2.c mkillum3.c)
+target_link_libraries(mkillum raycalls radiance rtrad)
+
+add_executable(mksource mksource.c)
+target_link_libraries(mksource raycalls radiance rtrad)
+
+add_executable(replmarks replmarks.c)
+target_link_libraries(replmarks rtrad)
+
+add_executable(xform xform.c)
+target_link_libraries(xform rtrad)
+
+install(TARGETS genbox gensky xform genblinds genrev genworm gendaylit gensurf
+                genprism replmarks mkillum mksource genclock
+        DESTINATION bin)
+
+install(FILES illum.cal rev.cal skybright.cal surf.cal clockface.hex glaze1.cal
+              glaze2.cal perezlum.cal coeff_perez.dat defangle.dat glaze.csh
+        DESTINATION bin)
diff --git a/src/hd/CMakeLists.txt b/src/hd/CMakeLists.txt
new file mode 100644
index 0000000..df2bc7d
--- /dev/null
+++ b/src/hd/CMakeLists.txt
@@ -0,0 +1,30 @@
+set(VERSION_FILE "${radiance_BINARY_DIR}/src/hd/Version.c")
+add_custom_command(
+  OUTPUT "${VERSION_FILE}"
+  COMMAND "${CMAKE_COMMAND}"
+  -DVERSION_OUT_FILE="${VERSION_FILE}"
+  -DVERSION_IN_FILE="${radiance_SOURCE_DIR}/src/util/VERSION"
+  -P "${radiance_SOURCE_DIR}/src/common/create_version.cmake"
+)
+
+add_executable(genrhgrid genrhgrid.c holo.c)
+target_link_libraries(genrhgrid rtrad)
+
+add_executable(rhcopy rhcopy.c clumpbeams.c holo.c holofile.c)
+target_link_libraries(rhcopy rtrad)
+
+add_executable(rhinfo rhinfo.c holo.c holofile.c)
+target_link_libraries(rhinfo rtrad)
+if(NOT WIN32)
+  add_executable(rholo rholo.c rholo2.c rholo2l.c rholo3.c rholo4.c holo.c
+    holofile.c viewbeams.c ${VERSION_FILE})
+  target_link_libraries(rholo rtrad)
+  add_executable(rhoptimize rhoptimize.c clumpbeams.c holo.c holofile.c)
+  target_link_libraries(rhoptimize rtrad)
+  add_executable(rhpict
+    rhpict.c rhpict2.c holo.c holofile.c viewbeams.c ${VERSION_FILE})
+  target_link_libraries(rhpict rtrad)
+  install(TARGETS rholo rhoptimize rhpict RUNTIME DESTINATION bin) 
+endif()
+
+install(TARGETS genrhgrid rhcopy RUNTIME DESTINATION bin)
diff --git a/src/hd/VERSION b/src/hd/VERSION
new file mode 100644
index 0000000..45c32ae
--- /dev/null
+++ b/src/hd/VERSION
@@ -0,0 +1 @@
+RADIANCE 4.1a
diff --git a/src/meta/CMakeLists.txt b/src/meta/CMakeLists.txt
new file mode 100644
index 0000000..a15d630
--- /dev/null
+++ b/src/meta/CMakeLists.txt
@@ -0,0 +1,61 @@
+set(common_src mfio.c syscalls.c misc.c)
+
+add_executable(bgraph bgraph.c mgvars.c mgraph.c)
+target_link_libraries(bgraph meta rtrad)
+
+add_executable(cv cv.c mfio.c cvhfio.c syscalls.c misc.c)
+target_link_libraries(cv rtrad)
+
+add_executable(dgraph dgraph.c cgraph.c mgvars.c)
+target_link_libraries(dgraph rtrad)
+
+add_executable(gcomp gcomp.c gcalc.c mgvars.c)
+target_link_libraries(gcomp rtrad)
+
+add_executable(igraph igraph.c mgvars.c mgraph.c gcalc.c cgraph.c)
+target_link_libraries(igraph meta rtrad)
+
+add_library(meta metacalls.c primout.c progname.c ${common_src})
+
+add_executable(meta2bmp meta2bmp.c rplot.c plot.c palloc.c ${common_src})
+target_link_libraries(meta2bmp rtrad)
+
+add_executable(meta2tga meta2tga.c rplot.c plot.c palloc.c ${common_src})
+target_link_libraries(meta2tga rtrad)
+
+add_executable(mtext mtext.c primout.c ${common_src})
+target_link_libraries(mtext rtrad)
+
+add_executable(pexpand pexpand.c expand.c segment.c palloc.c ${common_src})
+target_link_libraries(pexpand rtrad)
+
+add_executable(plot4 plot4.c primout.c ${common_src})
+target_link_libraries(plot4 rtrad)
+
+add_executable(plotin plotin.c primout.c ${common_src})
+target_link_libraries(plotin rtrad)
+
+add_executable(psmeta psmeta.c psplot.c ${common_src})
+target_link_libraries(psmeta rtrad)
+
+add_executable(psort psort.c sort.c palloc.c ${common_src})
+target_link_libraries(psort rtrad)
+
+#add_executable(tbar tbar.c tgraph.c primout.c)
+#target_link_libraries(tbar rtrad)
+
+#add_executable(tcurve tcurve.c tgraph.c primout.c)
+#target_link_libraries(tcurve ${LIB_M})
+
+#add_executable(tscat tscat.c tgraph.c primout.c)
+#target_link_libraries(tscat rtrad)
+
+if(X11_FOUND)
+  add_executable(x11meta xmeta.c x11plot.c plot.c palloc.c ${common_src})
+  target_link_libraries(x11meta rtrad ${X11_LIBRARIES})
+  install(TARGETS x11meta RUNTIME DESTINATION bin)
+endif()
+
+install(TARGETS meta2tga pexpand psort cv psmeta plotin bgraph igraph dgraph
+                gcomp plot4 meta2bmp
+        RUNTIME DESTINATION bin)
diff --git a/src/ot/CMakeLists.txt b/src/ot/CMakeLists.txt
new file mode 100644
index 0000000..f74568f
--- /dev/null
+++ b/src/ot/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_executable(getbbox getbbox.c readobj2.c bbox.c init2otypes.c)
+target_link_libraries(getbbox rtrad)
+
+add_executable(obj2mesh obj2mesh.c cvmesh.c wfconv.c o_face.c writemesh.c)
+target_link_libraries(obj2mesh rtrad)
+
+add_executable(oconv oconv.c sphere.c writeoct.c o_face.c o_cone.c o_instance.c bbox.c initotypes.c)
+target_link_libraries(oconv rtrad)
+
+install(TARGETS oconv getbbox obj2mesh RUNTIME DESTINATION bin)
diff --git a/src/px/CMakeLists.txt b/src/px/CMakeLists.txt
new file mode 100644
index 0000000..ee0e217
--- /dev/null
+++ b/src/px/CMakeLists.txt
@@ -0,0 +1,94 @@
+add_executable(pfilt pfilt.c pf2.c pf3.c)
+target_link_libraries(pfilt rtrad)
+
+add_executable(pcond pcond.c pcond2.c pcond3.c pcond4.c warp3d.c)
+target_link_libraries(pcond rtrad)
+
+add_executable(pcwarp pcwarp.c warp3d.c)
+target_link_libraries(pcwarp rtrad)
+
+add_executable(ttyimage ttyimage.c)
+target_link_libraries(ttyimage rtrad)
+
+add_executable(pvalue pvalue.c)
+target_link_libraries(pvalue rtrad)
+
+add_executable(pcompos pcompos.c)
+target_link_libraries(pcompos rtrad)
+
+add_executable(psign psign.c)
+target_link_libraries(psign rtrad)
+
+add_executable(ra_gif ra_gif.c clrtab.c neuclrtab.c)
+target_link_libraries(ra_gif rtrad)
+
+add_executable(ra_ps ra_ps.c)
+target_link_libraries(ra_ps rtrad)
+
+add_executable(ra_ppm ra_ppm.c)
+target_link_libraries(ra_ppm rtrad)
+
+add_executable(ra_bmp ra_bmp.c)
+target_link_libraries(ra_bmp rtrad)
+
+add_executable(ra_t8 ra_t8.c clrtab.c neuclrtab.c)
+target_link_libraries(ra_t8 rtrad)
+
+add_executable(ra_t16 ra_t16.c)
+target_link_libraries(ra_t16 rtrad)
+
+add_executable(ra_rgbe ra_rgbe.c)
+target_link_libraries(ra_rgbe rtrad)
+
+add_executable(ra_pict ra_pict.c)
+target_link_libraries(ra_pict rtrad)
+
+add_executable(ra_hexbit ra_hexbit.c)
+target_link_libraries(ra_hexbit rtrad)
+if(X11_FOUND)
+  add_executable(ximage x11image.c x11raster.c clrtab.c)
+  target_link_libraries(ximage rtrad ${X11_LIBRARIES})
+  add_executable(xshowtrace xshowtrace.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/../common/x11findwind.c)
+  target_link_libraries(xshowtrace rtrad ${X11_LIBRARIES})
+  install(TARGETS ximage xshowtrace RUNTIME DESTINATION bin)
+endif()
+add_executable(pflip pflip.c)
+target_link_libraries(pflip rtrad)
+
+add_executable(protate protate.c)
+target_link_libraries(protate rtrad)
+
+add_executable(pextrem pextrem.c)
+target_link_libraries(pextrem rtrad)
+
+add_executable(pcomb pcomb.c)
+target_link_libraries(pcomb rtrad)
+
+add_executable(pinterp pinterp.c)
+target_link_libraries(pinterp rtrad)
+
+add_executable(ra_xyze ra_xyze.c)
+target_link_libraries(ra_xyze rtrad)
+
+add_executable(macbethcal macbethcal.c pmapgen.c mx3.c warp3d.c)
+target_link_libraries(macbethcal rtrad)
+
+find_package(TIFF)
+mark_as_advanced(CLEAR TIFF_INCLUDE_DIR TIFF_LIBRARY)
+if(TIFF_FOUND)
+  add_executable(ra_tiff ra_tiff.c)
+  target_link_libraries(ra_tiff rtrad ${TIFF_LIBRARIES})
+  install(TARGETS ra_tiff RUNTIME DESTINATION bin)
+  install(FILES ${TIFF_LIBRARIES} DESTINATION bin)
+#TODO: else case
+endif()
+
+install(TARGETS pfilt pflip ttyimage psign pvalue pcompos protate
+  ra_hexbit ra_bmp ra_t8 ra_t16 pcomb pinterp ra_ppm ra_rgbe ra_pict ra_ps
+  pextrem ra_gif ra_xyze macbethcal pcond pcwarp
+  RUNTIME DESTINATION bin)
+
+install(FILES normpat.csh falsecolor.pl pdfblur.csh pmblur.csh pmdblur.csh
+  xyzimage.csh pgblur.csh ra_pfm.csh pbilat.csh
+  DESTINATION bin)
diff --git a/src/rt/CMakeLists.txt b/src/rt/CMakeLists.txt
new file mode 100644
index 0000000..6287d3b
--- /dev/null
+++ b/src/rt/CMakeLists.txt
@@ -0,0 +1,58 @@
+set(VERSION_FILE "${radiance_BINARY_DIR}/src/rt/Version.c")
+add_custom_command(
+  OUTPUT "${VERSION_FILE}"
+  COMMAND "${CMAKE_COMMAND}"
+  -DVERSION_OUT_FILE="${VERSION_FILE}"
+  -DVERSION_IN_FILE="${radiance_SOURCE_DIR}/src/util/VERSION"
+  -P "${radiance_SOURCE_DIR}/src/common/create_version.cmake"
+)
+
+add_library(radiance
+  ambcomp.c ambient.c ambio.c aniso.c data.c dielectric.c fprism.c freeobjmem.c 
+  func.c glass.c initotypes.c m_alias.c m_brdf.c m_bsdf.c m_clip.c m_direct.c
+  m_mirror.c m_mist.c mx_func.c mx_data.c noise3.c normal.c o_face.c o_cone.c
+  o_instance.c o_mesh.c p_data.c p_func.c preload.c raytrace.c renderopts.c
+  source.c sphere.c srcobstr.c srcsupp.c srcsamp.c t_data.c t_func.c text.c
+  "${VERSION_FILE}" virtuals.c)
+
+if(WIN32)
+  set(rayp_SOURCES raypwin.c)
+else()
+  set(rayp_SOURCES raypcalls.c)
+endif()
+
+add_library(raycalls raycalls.c ${rayp_SOURCES} rayfifo.c)
+
+add_executable(rtrace  rtmain.c rtrace.c duphead.c persist.c)
+target_link_libraries(rtrace raycalls radiance rtrad)
+
+add_executable(rpict rpmain.c rpict.c srcdraw.c duphead.c persist.c)
+target_link_libraries(rpict radiance rtrad)
+if(X11_FOUND)
+  set(X11_SOURCES x11.c x11twind.c)
+  add_definitions("-DHAS_X11")
+endif()
+if(QT4_FOUND)
+  add_definitions("-DHAS_QT")
+endif()
+add_executable(rvu
+  rvmain.c rview.c rv2.c rv3.c devtable.c devcomm.c editline.c ${X11_SOURCES}
+  colortab.c)
+target_link_libraries(rvu raycalls radiance rtrad ${X11_LIBRARIES})
+# only link to rvu-qt-lib if qt is found
+if(QT4_FOUND)
+  target_link_libraries(rvu rvu-qt-lib)
+endif()
+
+add_executable(lookamb lookamb.c ambio.c)
+target_link_libraries(lookamb rtrad)
+
+add_test(rtrace_Version ${EXECUTABLE_OUTPUT_PATH}/rtrace -version)
+set_tests_properties(rtrace_Version PROPERTIES
+  PASS_REGULAR_EXPRESSION "RADIANCE")
+
+install(TARGETS radiance raycalls rtrace rpict rvu
+        RUNTIME DESTINATION bin
+        LIBRARY DESTINATION bin
+        ARCHIVE DESTINATION bin)
+install(FILES rayinit.cal DESTINATION bin)
diff --git a/src/rvu/CMakeLists.txt b/src/rvu/CMakeLists.txt
new file mode 100644
index 0000000..467dafd
--- /dev/null
+++ b/src/rvu/CMakeLists.txt
@@ -0,0 +1,22 @@
+
+include(${QT_USE_FILE})
+
+qt4_wrap_cpp(rvu_moc rvuwidget.h mainwindow.h)
+qt4_wrap_ui(rvu_ui mainwindow.ui)
+qt4_wrap_ui(exposure_dialog_ui exposuredialog.ui)
+qt4_wrap_ui(parameter_dialog_ui parameterdialog.ui)
+qt4_wrap_ui(view_dialog_ui viewdialog.ui)
+qt4_wrap_ui(increments_dialog_ui incrementsdialog.ui)
+qt4_wrap_ui(commands_dialog_ui commandsdialog.ui)
+
+include_directories(${radiance_SOURCE_DIR}/src/rt
+  ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
+
+add_library(rvu-qt-lib  qt.c rvuwidget.cxx qt_rvu_main.cxx mainwindow.cxx
+  ${rvu_moc} ${rvu_ui} ${exposure_dialog_ui} ${parameter_dialog_ui}
+  ${view_dialog_ui} ${increments_dialog_ui} ${commands_dialog_ui})
+target_link_libraries(rvu-qt-lib ${QT_LIBRARIES})
+
+install(TARGETS rvu-qt-lib
+        LIBRARY DESTINATION bin
+        ARCHIVE DESTINATION bin)
diff --git a/src/rvu/commandsdialog.ui b/src/rvu/commandsdialog.ui
new file mode 100644
index 0000000..673d6f8
--- /dev/null
+++ b/src/rvu/commandsdialog.ui
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>commandsDialog</class>
+ <widget class="QDialog" name="commandsDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>737</width>
+    <height>894</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Rvu Commands</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QTextEdit" name="textEdit">
+     <property name="documentTitle">
+      <string/>
+     </property>
+     <property name="readOnly">
+      <bool>true</bool>
+     </property>
+     <property name="html">
+      <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;aim&lt;/span&gt; &lt;span style=&quot; font-style:italic;&quot;&gt;[ mag [ x y z ] ]&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	Zoom in by mag on point x y z . The view point is held constant; only the view direction&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	and size are changed. If x y z is missing, the cursor is used to select the view center. A&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	 negative magnification factor means zoom out. The default factor is one.&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;exposure &lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;[ spec ]&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	Adjust exposure. The number spec is a multiplier used to compensate the average&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	exposure. A value of 1 renormalizes the image to the computed average, which is usually&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; 	done immediately after startup. If spec begins with a ’+’ or ’-’, the compensation is&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	interpreted in f-stops (ie. the power of two). If spec begins with an ’=’, an absolute&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	setting is performed. An ’=’ by itself permits interactive display and setting of the&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	exposure. If spec begins with an ’@’, the exposure is adjusted to present similar visibility&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	to what would be experienced in the real environment. If spec is absent, or an ’@’ is&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	followed by nothing, then the cursor is used to pick a specific image location for&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	normalization.&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;focus &lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;[ distance ]&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	Set focus distance for depth-of-field sampling. If a distance in world coordinates is&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	absent, then the cursor is used to choose a point in the scene on which to focus. (The&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	focus distance setting does not affect rendering in &lt;span style=&quot; font-style:italic;&quot;&gt;rvu&lt;/span&gt;, but can be used in &lt;span style=&quot; font-style:italic;&quot;&gt;rpict&lt;/span&gt; with the&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	-pd option to simulate depth-of-field on views saved from &lt;span style=&quot; font-style:italic;&quot;&gt;rvu&lt;/span&gt;.)&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;frame &lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;[ xmin ymin xmax ymax ]&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	Set frame for refinement. If coordinates are absent, the cursor is used to pick frame&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	boundaries. If ‘‘all’’ is specified, the frame is reset to the entire image.&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;free&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	Free cached object structures and associated data. This command may be useful when&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	memory is low and a completely different view is being generated from the one previous.&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;last &lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;[ file ]&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	Restore the previous view. If a view or picture le is specified, the parameters are taken&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	from the last view entry in the file.&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;L&lt;/span&gt; &lt;span style=&quot; font-style:italic;&quot;&gt;[ vw [ rfile ] ]&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	Load parameters for view &lt;span style=&quot; font-style:italic;&quot;&gt;vw&lt;/span&gt; from the &lt;span style=&quot; font-style:italic;&quot;&gt;rad&lt;/span&gt; input file, &lt;span style=&quot; font-style:italic;&quot;&gt;rfile&lt;/span&gt;. Both &lt;span style=&quot; font-style:italic;&quot;&gt;vw&lt;/span&gt; and &lt;span style=&quot; font-style:italic;&quot;&gt;rfile&lt;/span&gt; must be given&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	the first call, but subsequent calls will use the last &lt;span style=&quot; font-style:italic;&quot;&gt;rfile&lt;/span&gt; as a default, and &amp;quot;1&amp;quot; as the default&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	 view (ie. the first view appearing in &lt;span style=&quot; font-style:italic;&quot;&gt;rfile&lt;/span&gt;).&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;move &lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;[ mag [ x y z ] ]&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	Move camera mag times closer to point x y z . For a perspective projection (or fisheye&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	view), only the view point is changed; the view direction and size remain constant. The&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	view size must be modified in a parallel projection since it determines magnification. If&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	&lt;span style=&quot; font-style:italic;&quot;&gt;x y z&lt;/span&gt; is missing, the cursor is used to select the view center. A negative magnification&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	factor decreases the object size. The default factor is one. Care must be taken to avoid&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	moving behind or inside other objects.&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;new &lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;[ nproc ]&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	Restart the image, using the specified number of rendering processes. Usually used after&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	the &amp;quot;set&amp;quot; command.&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;pivot &lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;angle [ elev [ mag [ x y z ] ] ]&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	Similar to the &amp;quot;move&amp;quot; command, but pivots the view about a selected point. The &lt;span style=&quot; font-style:italic;&quot;&gt;angle&lt;/span&gt; is&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	measured in degrees around the view up vector using the right hand rule. The optional&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;	elev&lt;/span&gt; is the elevation in degrees from the pivot point; positive raises the view point to look&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	downward and negative lowers the view point to look upward.&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;quit&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;	&lt;/span&gt;Quit the program.&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;^R&lt;/span&gt;	&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	Redraw the image. Use when the display gets corrupted. On some displays, occassionally&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	forcing a redraw can improve appearance, as more color information is available and the&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	driver can make a better color table selection.&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;rotate &lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;angle [ elev [ mag ] ]&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	Rotate the camera horizontally by &lt;span style=&quot; font-style:italic;&quot;&gt;angle&lt;/span&gt; degrees. If an elevation is specified, the camera&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	looks upward &lt;span style=&quot; font-style:italic;&quot;&gt;elev&lt;/span&gt; degrees. (Negative means look downward.)&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;set &lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;[ var [ val ] ]&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	Check/change program variable. If &lt;span style=&quot; font-style:italic;&quot;&gt;var&lt;/span&gt; is absent, the list of available variables is&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	displayed. If &lt;span style=&quot; font-style:italic;&quot;&gt;val&lt;/span&gt; is absent, the current value of the variable is displayed and changed&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	interactively. Otherwise, the variable &lt;span style=&quot; font-style:italic;&quot;&gt;var&lt;/span&gt; assumes the value &lt;span style=&quot; font-style:italic;&quot;&gt;val&lt;/span&gt;. Variables include:&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	ambient value (av), ambient value weight (aw), ambient bounces (ab),&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	ambient accuracy (aa), ambient divisions (ad), ambi- ent radius (ar),&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	ambient samples (as), black&amp;amp;white (b), back face visibility (bv), direct jitter (dj),&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	direct sampling (ds), direct threshold (dt), direct visibility (dv), irradiance (i),&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	limit weight (lw), limit recursion (lr), medium extinction (me), medium albedo (ma),&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	medium eccentricity (mg), medium sampling (ms), pixel sample (ps), pixel threshold (pt),&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	specular jitter (sj), specular threshold (st), and uncorrelated sampling (u).&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	Once a variable has been changed, the &amp;quot;new&amp;quot; command can be used to recompute the&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	image with the new parameters. If a program variable is not available here, it may show&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	up under some other command or it may be impossible to change once the program is&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	running.&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;trace &lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;[ xbeg ybeg zbeg xdir ydir zdir ]&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;	&lt;/span&gt;Trace a ray. If the ray origin and direction are absent, the cursor is used to pick a location&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	in the image to trace. The object intersected and its material, location and value are&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	displayed.&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;V &lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;[ vw [ rfile ] ]&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	Append the current view as view &lt;span style=&quot; font-style:italic;&quot;&gt;vw&lt;/span&gt; in the rad file &lt;span style=&quot; font-style:italic;&quot;&gt;rfile&lt;/span&gt;. Compliment to &lt;span style=&quot; font-style:italic;&quot;&gt;L&lt;/span&gt; command. Note&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	that the view is simply appended to the file, and previous views with the same name&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	should be removed before using the file with &lt;span style=&quot; font-style:italic;&quot;&gt;rad&lt;/span&gt;.&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;write &lt;/span&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;[ file ]&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	Write picture to &lt;span style=&quot; font-style:italic;&quot;&gt;file&lt;/span&gt;. If argument is missing, the current file name is used.&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;^Z&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;	Stop the program. The screen will be redrawn when the program resumes.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/rvu/exposuredialog.ui b/src/rvu/exposuredialog.ui
new file mode 100644
index 0000000..3283280
--- /dev/null
+++ b/src/rvu/exposuredialog.ui
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>exposureDialog</class>
+ <widget class="QDialog" name="exposureDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>303</width>
+    <height>197</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Exposure</string>
+  </property>
+  <property name="toolTip">
+   <string>adjust exposure here</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="QLabel" name="exposureValueLabel">
+     <property name="text">
+      <string>Current value:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1">
+    <widget class="QLabel" name="exposureValue">
+     <property name="text">
+      <string>1</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QLabel" name="exposureModeLabel">
+     <property name="text">
+      <string>Mode:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1">
+    <widget class="QRadioButton" name="relative">
+     <property name="text">
+      <string>Relative</string>
+     </property>
+     <property name="checked">
+      <bool>true</bool>
+     </property>
+     <attribute name="buttonGroup">
+      <string>modeGroup</string>
+     </attribute>
+    </widget>
+   </item>
+   <item row="1" column="2">
+    <widget class="QRadioButton" name="absolute">
+     <property name="text">
+      <string>Absolute</string>
+     </property>
+     <attribute name="buttonGroup">
+      <string>modeGroup</string>
+     </attribute>
+    </widget>
+   </item>
+   <item row="2" column="1">
+    <widget class="QRadioButton" name="fstop">
+     <property name="text">
+      <string>F-stop</string>
+     </property>
+     <attribute name="buttonGroup">
+      <string>modeGroup</string>
+     </attribute>
+    </widget>
+   </item>
+   <item row="2" column="2">
+    <widget class="QRadioButton" name="natural">
+     <property name="text">
+      <string>Natural</string>
+     </property>
+     <attribute name="buttonGroup">
+      <string>modeGroup</string>
+     </attribute>
+    </widget>
+   </item>
+   <item row="3" column="0">
+    <widget class="QLabel" name="exposureBasedLabel">
+     <property name="text">
+      <string>Based on:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="1">
+    <widget class="QRadioButton" name="average">
+     <property name="text">
+      <string>Average</string>
+     </property>
+     <property name="checked">
+      <bool>true</bool>
+     </property>
+     <attribute name="buttonGroup">
+      <string>basedGroup</string>
+     </attribute>
+    </widget>
+   </item>
+   <item row="3" column="2">
+    <widget class="QRadioButton" name="point">
+     <property name="text">
+      <string>Point</string>
+     </property>
+     <attribute name="buttonGroup">
+      <string>basedGroup</string>
+     </attribute>
+    </widget>
+   </item>
+   <item row="4" column="0">
+    <widget class="QLabel" name="exposureSettingLabel">
+     <property name="text">
+      <string>Setting:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="1">
+    <widget class="QLineEdit" name="exposureSetting">
+     <property name="text">
+      <string>1</string>
+     </property>
+    </widget>
+   </item>
+   <item row="5" column="0" colspan="3">
+    <widget class="QDialogButtonBox" name="exposureButtonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>exposureButtonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>exposureDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>exposureButtonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>exposureDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+ <buttongroups>
+  <buttongroup name="basedGroup"/>
+  <buttongroup name="modeGroup"/>
+ </buttongroups>
+</ui>
diff --git a/src/rvu/incrementsdialog.ui b/src/rvu/incrementsdialog.ui
new file mode 100644
index 0000000..736fa80
--- /dev/null
+++ b/src/rvu/incrementsdialog.ui
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>incrementsDialog</class>
+ <widget class="QDialog" name="incrementsDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>GUI Increments</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0" colspan="2">
+    <widget class="QLabel" name="label">
+     <property name="text">
+      <string>Translation step size</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QLabel" name="label_2">
+     <property name="text">
+      <string>Small:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1">
+    <widget class="QLineEdit" name="small"/>
+   </item>
+   <item row="2" column="0">
+    <widget class="QLabel" name="label_3">
+     <property name="text">
+      <string>Large:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="1">
+    <widget class="QLineEdit" name="large"/>
+   </item>
+   <item row="3" column="0" colspan="2">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>incrementsDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>incrementsDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/src/rvu/main.cxx b/src/rvu/main.cxx
new file mode 100644
index 0000000..dbb32d4
--- /dev/null
+++ b/src/rvu/main.cxx
@@ -0,0 +1,13 @@
+#include <QtGui/QApplication>
+#include <QtGui/QColor>
+
+extern "C" int qt_rvu_run();
+extern "C" int qt_rvu_init(char* name, char* id,
+                           int* xsize, int* ysize);
+
+int main(int argc, char* argv[])
+{
+  int x, y;
+  qt_rvu_init("test", "id", &x, &y);
+  return qt_rvu_run();
+}
diff --git a/src/rvu/mainwindow.cxx b/src/rvu/mainwindow.cxx
new file mode 100644
index 0000000..09ec74d
--- /dev/null
+++ b/src/rvu/mainwindow.cxx
@@ -0,0 +1,1080 @@
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+#include "ui_exposuredialog.h"
+#include "ui_parameterdialog.h"
+#include "ui_viewdialog.h"
+#include "ui_incrementsdialog.h"
+#include "ui_commandsdialog.h"
+
+#include <QtGui/QMessageBox>
+#include <QtGui/QLineEdit>
+#include <QtGui/QCloseEvent>
+#include <QtGui/QFileDialog>
+#include <QtGui/QInputDialog>
+#include <QtCore/QDebug>
+#include <QtCore/QTime>
+#include <QtCore/QTextStream>
+
+#include <iostream>
+
+// Process a command
+extern "C" void qt_process_command(const char*);
+// set the abort flag to stop a render in progress
+extern "C" void qt_set_abort(int );
+extern "C"
+{
+//externs for exposure dialog
+extern VIEW ourview;
+extern double exposure;
+//externs for parameters dialog
+extern COLOR  ambval;   /* ambient value */
+extern int  ambvwt;   /* initial weight for ambient value */
+extern double ambacc;   /* ambient accuracy */
+extern int  ambres;   /* ambient resolution */
+extern int  ambdiv;   /* ambient divisions */
+extern int  ambssamp; /* ambient super-samples */
+extern int  ambounce; /* ambient bounces */
+extern double shadcert; /* shadow testing certainty */
+extern double shadthresh; /* shadow threshold */
+extern int  directvis;  /* light sources visible to eye? */
+extern COLOR  cextinction;  /* global extinction coefficient */
+extern COLOR  salbedo;  /* global scattering albedo */
+extern double seccg;    /* global scattering eccentricity */
+extern double ssampdist;  /* scatter sampling distance */
+extern double specthresh; /* specular sampling threshold */
+extern double specjitter; /* specular sampling jitter */
+extern int  maxdepth; /* maximum recursion depth */
+extern double minweight;  /* minimum ray weight */
+extern double dstrsrc;  /* square source distribution */
+extern double srcsizerat; /* maximum source size/dist. ratio */
+extern int  psample;    /* pixel sample size */
+extern double  maxdiff;   /* max. sample difference */
+void quit(int code);
+}
+MainWindow::MainWindow(int width, int height, const char* name, const char* id)
+{
+  m_ui = new Ui::MainWindow;
+  m_ui->setupUi(this);
+  m_exposureDialog = new QDialog();
+  m_exposureDialogUi = new Ui::exposureDialog;
+  m_exposureDialogUi->setupUi(m_exposureDialog);
+  m_parameterDialog = new QDialog();
+  m_parameterDialogUi = new Ui::parameterDialog;
+  m_parameterDialogUi->setupUi(m_parameterDialog);
+  m_viewDialog = new QDialog();
+  m_viewDialogUi = new Ui::viewDialog;
+  m_viewDialogUi->setupUi(m_viewDialog);
+  this->smallIncrement = 0.1;
+  this->largeIncrement = 0.5;
+  m_incrementsDialog = new QDialog();
+  m_incrementsDialogUi = new Ui::incrementsDialog;
+  m_incrementsDialogUi->setupUi(m_incrementsDialog);
+  m_commandsDialog = new QDialog();
+  m_commandsDialogUi = new Ui::commandsDialog;
+  m_commandsDialogUi->setupUi(m_commandsDialog);
+  this->currentImageName  = "";
+  createActions();
+  connectSlots();
+  m_ui->progressBar->setMinimum(0);
+  m_ui->progressBar->setMaximum(100);
+  setWindowTitle(tr(id));
+  resize(width, height);
+  updatePositionLabels();
+}
+
+MainWindow::~MainWindow()
+{
+  delete m_ui;
+  delete m_exposureDialog;
+  delete m_parameterDialog;
+  delete m_viewDialog;
+  delete m_incrementsDialog;
+  delete m_commandsDialog;
+}
+
+void MainWindow::setProgress(int p)
+{
+  m_ui->progressBar->setValue(p);
+}
+
+RvuWidget* MainWindow::getRvuWidget() const
+{
+  return m_ui->rvuWidget;
+}
+
+void MainWindow::closeEvent(QCloseEvent *event)
+{
+  // Here is a good spot to shut down the rest of the code before exit.
+  this->m_exposureDialog->close();
+  this->m_parameterDialog->close();
+  this->m_viewDialog->close();
+  this->m_incrementsDialog->close();
+  this->m_commandsDialog->close();
+}
+
+void MainWindow::createActions()
+{
+  m_minimizeAction = new QAction(tr("Mi&nimize"), this);
+  connect(m_minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));
+
+  m_maximizeAction = new QAction(tr("Ma&ximize"), this);
+  connect(m_maximizeAction, SIGNAL(triggered()), this, SLOT(showMaximized()));
+
+  m_restoreAction = new QAction(tr("&Restore"), this);
+  connect(m_restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));
+}
+
+void MainWindow::connectSlots()
+{
+  connect(m_ui->exit, SIGNAL(triggered()), qApp, SLOT(quit()));
+  connect(m_ui->pushButton, SIGNAL(clicked()), this, SLOT(buttonPressed()));
+  connect(m_ui->lineEdit, SIGNAL(returnPressed()),
+          this, SLOT(buttonPressed()));
+  connect(m_ui->redraw, SIGNAL(triggered()), this, SLOT(redraw()));
+  connect(m_ui->trace, SIGNAL(triggered()), this, SLOT(traceRay()));
+  connect(m_ui->toggleToolBar, SIGNAL(triggered()),
+          this, SLOT(toggleToolBar()));
+  connect(m_ui->toggleStatusBar, SIGNAL(triggered()),
+          this, SLOT(toggleStatusBar()));
+  connect(m_ui->toggleTranslateTool, SIGNAL(triggered()),
+          this, SLOT(toggleTranslateTool()));
+  connect(m_ui->exposure, SIGNAL(triggered()),
+          this, SLOT(showExposureDialog()));
+  connect(m_ui->parameters, SIGNAL(triggered()),
+          this, SLOT(showParameterDialog()));
+  connect(m_ui->view, SIGNAL(triggered()),
+          this, SLOT(showViewDialog()));
+  connect(m_ui->saveImage, SIGNAL(triggered()),
+          this, SLOT(saveCurrentImage()));
+  connect(m_ui->saveImageAs, SIGNAL(triggered()),
+          this, SLOT(saveImage()));
+  connect(m_ui->loadView, SIGNAL(triggered()),
+          this, SLOT(loadView()));
+  connect(m_ui->backfaceVisibility, SIGNAL(triggered()),
+          this, SLOT(toggleBackfaceVisibility()));
+  connect(m_ui->grayscale, SIGNAL(triggered()),
+          this, SLOT(toggleGrayscale()));
+  connect(m_ui->irradiance, SIGNAL(triggered()),
+          this, SLOT(toggleIrradiance()));
+  connect(m_ui->appendToRif, SIGNAL(triggered()),
+          this, SLOT(appendToRif()));
+  connect(m_ui->appendToView, SIGNAL(triggered()),
+          this, SLOT(appendToView()));
+  connect(m_ui->GUI_Increments, SIGNAL(triggered()),
+          this, SLOT(showIncrementsDialog()));
+  connect(m_ui->commands, SIGNAL(triggered()),
+          this, SLOT(showCommandsDialog()));
+  connect(m_ui->aboutRvu, SIGNAL(triggered()),
+          this, SLOT(showAbout()));
+
+  //movement buttons
+  connect(m_ui->xPlus1Button, SIGNAL(clicked()),
+          this, SLOT(moveXPlusOne()));
+  connect(m_ui->xPlus2Button, SIGNAL(clicked()),
+          this, SLOT(moveXPlusTwo()));
+  connect(m_ui->xMinus1Button, SIGNAL(clicked()),
+          this, SLOT(moveXMinusOne()));
+  connect(m_ui->xMinus2Button, SIGNAL(clicked()),
+          this, SLOT(moveXMinusTwo()));
+  connect(m_ui->yPlus1Button, SIGNAL(clicked()),
+          this, SLOT(moveYPlusOne()));
+  connect(m_ui->yPlus2Button, SIGNAL(clicked()),
+          this, SLOT(moveYPlusTwo()));
+  connect(m_ui->yMinus1Button, SIGNAL(clicked()),
+          this, SLOT(moveYMinusOne()));
+  connect(m_ui->yMinus2Button, SIGNAL(clicked()),
+          this, SLOT(moveYMinusTwo()));
+  connect(m_ui->zPlus1Button, SIGNAL(clicked()),
+          this, SLOT(moveZPlusOne()));
+  connect(m_ui->zPlus2Button, SIGNAL(clicked()),
+          this, SLOT(moveZPlusTwo()));
+  connect(m_ui->zMinus1Button, SIGNAL(clicked()),
+          this, SLOT(moveZMinusOne()));
+  connect(m_ui->zMinus2Button, SIGNAL(clicked()),
+          this, SLOT(moveZMinusTwo()));
+
+  //exposure dialog
+  connect(m_exposureDialogUi->exposureButtonBox, SIGNAL(accepted()),
+          this, SLOT(adjustExposure()));
+  connect(m_exposureDialogUi->exposureButtonBox, SIGNAL(rejected()),
+          this, SLOT(hideExposureDialog()));
+  connect(m_exposureDialogUi->natural, SIGNAL(toggled(bool)),
+          this, SLOT(updatePointRadio()));
+  connect(m_exposureDialogUi->relative, SIGNAL(toggled(bool)),
+          this, SLOT(updatePointRadio()));
+
+  //parameter dialog
+  connect(m_parameterDialogUi->buttonBox, SIGNAL(accepted()),
+          this, SLOT(adjustParameters()));
+  connect(m_parameterDialogUi->buttonBox, SIGNAL(rejected()),
+          this, SLOT(hideParameterDialog()));
+
+  //view dialog
+  connect(m_viewDialogUi->buttonBox, SIGNAL(accepted()),
+          this, SLOT(adjustView()));
+  connect(m_viewDialogUi->buttonBox, SIGNAL(rejected()),
+          this, SLOT(hideViewDialog()));
+
+  //increments dialog
+  connect(m_incrementsDialogUi->buttonBox, SIGNAL(accepted()),
+          this, SLOT(adjustIncrements()));
+  connect(m_incrementsDialogUi->buttonBox, SIGNAL(rejected()),
+          this, SLOT(hideIncrementsDialog()));
+}
+
+void MainWindow::doSubmit()
+{
+  QString command = m_ui->lineEdit->text();
+  bool centerCrossHairs = false;
+  if(command == "aim")
+    {
+    centerCrossHairs = true;
+    }
+  m_ui->lineEdit->setText("");
+  m_ui->progressBar->setEnabled(true);
+  this->setProgress(0);
+  QTime t;
+  t.start();
+  if (command.isEmpty())
+    {
+    this->m_ui->pushButton->setText("Submit");
+    enableInterface(true);
+    return;
+    }
+  qt_process_command(command.toAscii());
+  QString msg;
+  QTextStream(&msg) << "Render Time: " << t.elapsed() << " ms";
+  m_ui->messageBox->appendPlainText(msg);
+  this->m_ui->pushButton->setText("Submit");
+  enableInterface(true);
+  if(centerCrossHairs)
+    {
+    QPoint p = this->m_ui->rvuWidget->geometry().center();
+    this->m_ui->rvuWidget->setPosition(p.x(), p.y());
+    }
+  updatePositionLabels();
+}
+
+
+void MainWindow::buttonPressed()
+{
+  if( m_ui->pushButton->text() == QString("Submit") )
+    {
+    qt_set_abort(0);
+    this->m_ui->pushButton->setText("Abort");
+    enableInterface(false);
+    this->doSubmit();
+    }
+  else if( m_ui->pushButton->text() == QString("Abort") )
+    {
+    qt_set_abort(1);
+    this->m_ui->pushButton->setText("Submit");
+    enableInterface(true);
+    }
+}
+
+void MainWindow::resizeImage(int width, int height)
+{
+  int pad = m_ui->lineEdit->size().height();
+  pad += m_ui->menubar->size().height();
+  pad += m_ui->messageBox->size().height();
+  this->resize(width+4, height+pad+4);
+  this->m_ui->rvuWidget->resizeImage(width, height);
+}
+
+void MainWindow::setStatus(const char* m)
+{
+  m_ui->messageBox->appendPlainText(QString(m).trimmed());
+}
+
+void MainWindow::redraw()
+{
+  runCommand("redraw");
+}
+
+void MainWindow::traceRay()
+{
+  runCommand("t");
+}
+
+void MainWindow::toggleToolBar()
+{
+  m_ui->toolBar->setVisible(m_ui->toggleToolBar->isChecked());
+}
+
+void MainWindow::toggleStatusBar()
+{
+  m_ui->messageBox->setVisible(m_ui->toggleStatusBar->isChecked());
+}
+
+void MainWindow::toggleTranslateTool()
+{
+  m_ui->xWidget->setVisible(m_ui->toggleTranslateTool->isChecked());
+  m_ui->yWidget->setVisible(m_ui->toggleTranslateTool->isChecked());
+  m_ui->zWidget->setVisible(m_ui->toggleTranslateTool->isChecked());
+}
+
+void MainWindow::refreshView(VIEW *nv)
+{
+	if (waitrays() < 0)			/* clear ray queue */
+		quit(1);
+  newview(nv);
+  this->redraw();
+}
+
+void MainWindow::move(int direction, float amount)
+{
+  if( m_ui->pushButton->text() == QString("Abort") )
+    {
+    qt_set_abort(1);
+    return;
+    } 
+  VIEW nv = ourview;
+  nv.vp[direction] = nv.vp[direction] + amount;
+  this->refreshView(&nv);
+  updatePositionLabels();
+}
+
+void MainWindow::moveXPlusOne()
+{
+  this->move(0, this->smallIncrement);
+}
+
+void MainWindow::moveXPlusTwo()
+{
+  this->move(0, this->largeIncrement);
+}
+
+void MainWindow::moveXMinusOne()
+{
+  this->move(0, -1 * this->smallIncrement);
+}
+
+void MainWindow::moveXMinusTwo()
+{
+  this->move(0, -1 * this->largeIncrement);
+}
+
+void MainWindow::moveYPlusOne()
+{
+  this->move(1, this->smallIncrement);
+}
+
+void MainWindow::moveYPlusTwo()
+{
+  this->move(1, this->largeIncrement);
+}
+
+void MainWindow::moveYMinusOne()
+{
+  this->move(1, -1 * this->smallIncrement);
+}
+
+void MainWindow::moveYMinusTwo()
+{
+  this->move(1, -1 * this->largeIncrement);
+}
+
+void MainWindow::moveZPlusOne()
+{
+  this->move(2, this->smallIncrement);
+}
+
+void MainWindow::moveZPlusTwo()
+{
+  this->move(2, this->largeIncrement);
+}
+
+void MainWindow::moveZMinusOne()
+{
+  this->move(2, -1 * this->smallIncrement);
+}
+
+void MainWindow::moveZMinusTwo()
+{
+  this->move(2, -1 * this->largeIncrement);
+}
+
+void MainWindow::updatePositionLabels()
+{
+  m_ui->xValue->setText(QString::number(ourview.vp[0]));
+  m_ui->yValue->setText(QString::number(ourview.vp[1]));
+  m_ui->zValue->setText(QString::number(ourview.vp[2]));
+}
+
+void MainWindow::showExposureDialog()
+{
+  m_exposureDialogUi->exposureValue->setText(QString::number(exposure));
+  m_exposureDialog->show();
+}
+
+void MainWindow::hideExposureDialog()
+{
+  m_exposureDialog->hide();
+}
+
+void MainWindow::showParameterDialog()
+{
+  //ambient tab
+  m_parameterDialogUi->valueX->setText(QString::number(ambval[0]));
+  m_parameterDialogUi->valueY->setText(QString::number(ambval[1]));
+  m_parameterDialogUi->valueZ->setText(QString::number(ambval[2]));
+  m_parameterDialogUi->weight->setText(QString::number(ambvwt));
+  m_parameterDialogUi->accuracy->setText(QString::number(ambacc));
+  m_parameterDialogUi->divisions->setText(QString::number(ambdiv));
+  m_parameterDialogUi->supersamples->setText(QString::number(ambssamp));
+  m_parameterDialogUi->bounces->setText(QString::number(ambounce));
+  m_parameterDialogUi->resolution->setText(QString::number(ambres));
+
+  //direct tab
+  m_parameterDialogUi->certainty->setText(QString::number(shadcert));
+  m_parameterDialogUi->threshold->setText(QString::number(shadthresh));
+  m_parameterDialogUi->visibility->setText(QString::number(directvis));
+  m_parameterDialogUi->jitter->setText(QString::number(dstrsrc));
+  m_parameterDialogUi->sampling->setText(QString::number(srcsizerat));
+  //values on direct tab that I can't find: reflection
+
+  //limit tab
+  m_parameterDialogUi->limit_weight->setText(QString::number(minweight));
+  m_parameterDialogUi->reflection->setText(QString::number(maxdepth));
+
+  //medium tab
+  m_parameterDialogUi->albedoX->setText(QString::number(salbedo[0]));
+  m_parameterDialogUi->albedoY->setText(QString::number(salbedo[1]));
+  m_parameterDialogUi->albedoZ->setText(QString::number(salbedo[2]));
+  m_parameterDialogUi->extinctionX->setText(QString::number(cextinction[0]));
+  m_parameterDialogUi->extinctionY->setText(QString::number(cextinction[1]));
+  m_parameterDialogUi->extinctionZ->setText(QString::number(cextinction[2]));
+  m_parameterDialogUi->eccentricity->setText(QString::number(seccg));
+  m_parameterDialogUi->mistDistance->setText(QString::number(ssampdist));
+
+  //pixel tab
+  m_parameterDialogUi->sample->setText(QString::number(psample));
+  m_parameterDialogUi->px_threshold->setText(QString::number(maxdiff));
+
+  //specular tab
+  m_parameterDialogUi->sp_jitter->setText(QString::number(specjitter));
+  m_parameterDialogUi->sp_threshold->setText(QString::number(specthresh));
+
+  m_parameterDialog->show();
+}
+
+void MainWindow::hideParameterDialog()
+{
+  m_parameterDialog->hide();
+}
+
+void MainWindow::adjustExposure()
+{
+  bool checkForPoint = false;
+
+  QString command = "exposure ";
+
+  if(m_exposureDialogUi->absolute->isChecked())
+    {
+    command += "=";
+    }
+  else if(m_exposureDialogUi->fstop->isChecked())
+    {
+    //TODO: check if the value is positive or not here
+    command += "+";
+    }
+  else if(m_exposureDialogUi->natural->isChecked())
+    {
+    command += "@";
+    checkForPoint = true;
+    }
+  else if(m_exposureDialogUi->relative->isChecked())
+    {
+    checkForPoint = true;
+    }
+
+  if(!(checkForPoint && m_exposureDialogUi->point->isChecked()))
+    {
+    command += m_exposureDialogUi->exposureSetting->text();
+    }
+
+  runCommand(command.toAscii());
+}
+
+void MainWindow::updatePointRadio()
+{
+  if(m_exposureDialogUi->relative->isChecked() ||
+     m_exposureDialogUi->natural->isChecked())
+    {
+    m_exposureDialogUi->point->setEnabled(true);
+    m_exposureDialogUi->average->setEnabled(true);
+    }
+  else
+    {
+    m_exposureDialogUi->point->setEnabled(false);
+    m_exposureDialogUi->average->setEnabled(false);
+    }
+}
+
+void MainWindow::adjustParameters()
+{
+  if(m_parameterDialogUi->valueX->isModified() ||
+     m_parameterDialogUi->valueY->isModified() ||
+     m_parameterDialogUi->valueZ->isModified())
+    {
+    QString command = "set av ";
+    command += m_parameterDialogUi->valueX->text();
+    command += " ";
+    command += m_parameterDialogUi->valueY->text();
+    command += " ";
+    command += m_parameterDialogUi->valueZ->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->weight->isModified())
+    {
+    QString command = "set aw ";
+    command += m_parameterDialogUi->weight->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->accuracy->isModified())
+    {
+    QString command = "set aa ";
+    command += m_parameterDialogUi->accuracy->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->divisions->isModified())
+    {
+    QString command = "set ad ";
+    command += m_parameterDialogUi->divisions->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->supersamples->isModified())
+    {
+    QString command = "set as ";
+    command += m_parameterDialogUi->supersamples->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->bounces->isModified())
+    {
+    QString command = "set ab ";
+    command += m_parameterDialogUi->bounces->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->resolution->isModified())
+    {
+    QString command = "set ar ";
+    command += m_parameterDialogUi->resolution->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->certainty->isModified())
+    {
+    QString command = "set dc ";
+    command += m_parameterDialogUi->certainty->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->threshold->isModified())
+    {
+    QString command = "set dt ";
+    command += m_parameterDialogUi->threshold->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->visibility->isModified())
+    {
+    QString command = "set dv ";
+    command += m_parameterDialogUi->visibility->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->jitter->isModified())
+    {
+    QString command = "set dj ";
+    command += m_parameterDialogUi->jitter->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->sampling->isModified())
+    {
+    QString command = "set ds ";
+    command += m_parameterDialogUi->sampling->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->limit_weight->isModified())
+    {
+    QString command = "set lw ";
+    command += m_parameterDialogUi->limit_weight->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->reflection->isModified())
+    {
+    QString command = "set lr ";
+    command += m_parameterDialogUi->reflection->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->albedoX->isModified() ||
+     m_parameterDialogUi->albedoY->isModified() ||
+     m_parameterDialogUi->albedoZ->isModified())
+    {
+    QString command = "set ma ";
+    command += m_parameterDialogUi->albedoX->text();
+    command += " ";
+    command += m_parameterDialogUi->albedoY->text();
+    command += " ";
+    command += m_parameterDialogUi->albedoZ->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->extinctionX->isModified() ||
+     m_parameterDialogUi->extinctionY->isModified() ||
+     m_parameterDialogUi->extinctionZ->isModified())
+    {
+    QString command = "set me ";
+    command += m_parameterDialogUi->extinctionX->text();
+    command += " ";
+    command += m_parameterDialogUi->extinctionY->text();
+    command += " ";
+    command += m_parameterDialogUi->extinctionZ->text();
+    }
+  if(m_parameterDialogUi->eccentricity->isModified())
+    {
+    QString command = "set mg ";
+    command += m_parameterDialogUi->eccentricity->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->mistDistance->isModified())
+    {
+    QString command = "set ms ";
+    command += m_parameterDialogUi->mistDistance->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->sample->isModified())
+    {
+    QString command = "set ps ";
+    command += m_parameterDialogUi->sample->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->px_threshold->isModified())
+    {
+    QString command = "set pt ";
+    command += m_parameterDialogUi->px_threshold->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->sp_jitter->isModified())
+    {
+    QString command = "set ss ";
+    command += m_parameterDialogUi->sp_jitter->text();
+    runCommand(command.toAscii());
+    }
+  if(m_parameterDialogUi->sp_threshold->isModified())
+    {
+    QString command = "set st ";
+    command += m_parameterDialogUi->sp_threshold->text();
+    runCommand(command.toAscii());
+    }
+  m_parameterDialog->hide();
+}
+
+void MainWindow::showViewDialog()
+{
+  if(ourview.type==VT_PER)
+    {
+    m_viewDialogUi->perspective->setChecked(true);
+    }
+  else if(ourview.type==VT_PAR)
+    {
+    m_viewDialogUi->parallel->setChecked(true);
+    }
+  else if(ourview.type==VT_HEM)
+    {
+    m_viewDialogUi->hemispherical->setChecked(true);
+    }
+  else if(ourview.type==VT_ANG)
+    {
+    m_viewDialogUi->angular->setChecked(true);
+    }
+  else if(ourview.type==VT_CYL)
+    {
+    m_viewDialogUi->cylindrical->setChecked(true);
+    }
+
+  m_viewDialogUi->viewX->setText(QString::number(ourview.vp[0]));
+  m_viewDialogUi->viewY->setText(QString::number(ourview.vp[1]));
+  m_viewDialogUi->viewZ->setText(QString::number(ourview.vp[2]));
+
+  m_viewDialogUi->dirX->setText(QString::number(ourview.vdir[0], 'f', 4));
+  m_viewDialogUi->dirY->setText(QString::number(ourview.vdir[1], 'f', 4));
+  m_viewDialogUi->dirZ->setText(QString::number(ourview.vdir[2], 'f', 4));
+
+  m_viewDialogUi->upX->setText(QString::number(ourview.vup[0]));
+  m_viewDialogUi->upY->setText(QString::number(ourview.vup[1]));
+  m_viewDialogUi->upZ->setText(QString::number(ourview.vup[2]));
+
+  m_viewDialogUi->sizeHoriz->setText(QString::number(ourview.horiz));
+  m_viewDialogUi->sizeVert->setText(QString::number(ourview.vert));
+  m_viewDialogUi->fore->setText(QString::number(ourview.vfore));
+  m_viewDialogUi->aft->setText(QString::number(ourview.vaft));
+  m_viewDialogUi->offsetHoriz->setText(QString::number(ourview.hoff));
+  m_viewDialogUi->offsetVert->setText(QString::number(ourview.voff));
+
+  m_viewDialog->show();
+}
+
+void MainWindow::hideViewDialog()
+{
+  m_viewDialog->hide();
+}
+
+void MainWindow::adjustView()
+{
+  bool changed = false;
+  VIEW nv = ourview;
+
+  //type
+  if(m_viewDialogUi->perspective->isChecked() && nv.type != VT_PER)
+    {
+    nv.type = VT_PER;
+    changed = true;
+    }
+  if(m_viewDialogUi->parallel->isChecked() && nv.type != VT_PAR)
+    {
+    nv.type = VT_PAR;
+    changed = true;
+    }
+  if(m_viewDialogUi->hemispherical->isChecked() && nv.type != VT_HEM)
+    {
+    nv.type = VT_HEM;
+    changed = true;
+    }
+  if(m_viewDialogUi->angular->isChecked() && nv.type != VT_ANG)
+    {
+    nv.type = VT_ANG;
+    changed = true;
+    }
+  if(m_viewDialogUi->cylindrical->isChecked() && nv.type != VT_CYL)
+    {
+    nv.type = VT_CYL;
+    changed = true;
+    }
+
+  //viewpoint
+  if(m_viewDialogUi->viewX->isModified())
+    {
+    bool okay = true;
+    float f = m_viewDialogUi->viewX->text().toFloat(&okay);
+    if(okay)
+      {
+      nv.vp[0] = f;
+      changed = true;
+      }
+    }
+  if(m_viewDialogUi->viewY->isModified())
+    {
+    bool okay = true;
+    float f = m_viewDialogUi->viewY->text().toFloat(&okay);
+    if(okay)
+      {
+      nv.vp[1] = f;
+      changed = true;
+      }
+    }
+  if(m_viewDialogUi->viewZ->isModified())
+    {
+    bool okay = true;
+    float f = m_viewDialogUi->viewZ->text().toFloat(&okay);
+    if(okay)
+      {
+      nv.vp[2] = f;
+      changed = true;
+      }
+    }
+
+  //direction
+  if(m_viewDialogUi->dirX->isModified())
+    {
+    bool okay = true;
+    float f = m_viewDialogUi->dirX->text().toFloat(&okay);
+    if(okay)
+      {
+      nv.vdir[0] = f;
+      changed = true;
+      }
+    }
+  if(m_viewDialogUi->dirY->isModified())
+    {
+    bool okay = true;
+    float f = m_viewDialogUi->dirY->text().toFloat(&okay);
+    if(okay)
+      {
+      nv.vdir[1] = f;
+      changed = true;
+      }
+    }
+  if(m_viewDialogUi->dirZ->isModified())
+    {
+    bool okay = true;
+    float f = m_viewDialogUi->dirZ->text().toFloat(&okay);
+    if(okay)
+      {
+      nv.vdir[2] = f;
+      changed = true;
+      }
+    }
+
+  //up
+  if(m_viewDialogUi->upX->isModified())
+    {
+    bool okay = true;
+    float f = m_viewDialogUi->upX->text().toFloat(&okay);
+    if(okay)
+      {
+      nv.vup[0] = f;
+      changed = true;
+      }
+    }
+  if(m_viewDialogUi->upY->isModified())
+    {
+    bool okay = true;
+    float f = m_viewDialogUi->upY->text().toFloat(&okay);
+    if(okay)
+      {
+      nv.vup[1] = f;
+      changed = true;
+      }
+    }
+  if(m_viewDialogUi->upZ->isModified())
+    {
+    bool okay = true;
+    float f = m_viewDialogUi->upZ->text().toFloat(&okay);
+    if(okay)
+      {
+      nv.vup[2] = f;
+      changed = true;
+      }
+    }
+
+  //size
+  if(m_viewDialogUi->sizeHoriz->isModified())
+    {
+    bool okay = true;
+    double d = m_viewDialogUi->sizeHoriz->text().toDouble(&okay);
+    if(okay)
+      {
+      nv.horiz = d;
+      changed = true;
+      }
+    }
+  if(m_viewDialogUi->sizeVert->isModified())
+    {
+    bool okay = true;
+    double d = m_viewDialogUi->sizeVert->text().toDouble(&okay);
+    if(okay)
+      {
+      nv.vert = d;
+      changed = true;
+      }
+    }
+
+  //clipping plane
+  if(m_viewDialogUi->fore->isModified())
+    {
+    bool okay = true;
+    double d = m_viewDialogUi->fore->text().toDouble(&okay);
+    if(okay)
+      {
+      nv.vfore = d;
+      changed = true;
+      }
+    }
+  if(m_viewDialogUi->aft->isModified())
+    {
+    bool okay = true;
+    double d = m_viewDialogUi->aft->text().toDouble(&okay);
+    if(okay)
+      {
+      nv.vaft = d;
+      changed = true;
+      }
+    }
+
+  //clipping plane
+  if(m_viewDialogUi->offsetHoriz->isModified())
+    {
+    bool okay = true;
+    double d = m_viewDialogUi->offsetHoriz->text().toDouble(&okay);
+    if(okay)
+      {
+      nv.hoff = d;
+      changed = true;
+      }
+    }
+  if(m_viewDialogUi->offsetVert->isModified())
+    {
+    bool okay = true;
+    double d = m_viewDialogUi->offsetVert->text().toDouble(&okay);
+    if(okay)
+      {
+      nv.voff = d;
+      changed = true;
+      }
+    }
+
+  if(changed)
+    {
+    this->refreshView(&nv);
+    }
+}
+
+void MainWindow::enableInterface(bool enable)
+{
+  m_ui->toolBar->setEnabled(enable);
+  m_ui->progressBar->setEnabled(!enable);
+}
+
+void MainWindow::runCommand(const char *command)
+{
+  qt_set_abort(0);
+  this->m_ui->pushButton->setText("Abort");
+  enableInterface(false);
+  qt_process_command(command);
+  qt_set_abort(1);
+  this->m_ui->pushButton->setText("Submit");
+  enableInterface(true);
+}
+
+void MainWindow::pick(int* x, int* y)
+{
+  QCursor oldCursor = this->cursor();
+  this->setCursor(Qt::CrossCursor);
+  this->getRvuWidget()->getPosition(x, y);
+  // restore state
+  this->setCursor(oldCursor);
+}
+  
+void MainWindow::saveImage()
+{
+  this->currentImageName = QFileDialog::getSaveFileName(this, tr("Save File"),
+    "", tr(".hdr images (*.hdr)"));
+  QString command = "write " + this->currentImageName;
+  this->runCommand(command.toAscii());
+}
+
+void MainWindow::saveCurrentImage()
+{
+  if(this->currentImageName == "")
+    {
+	this->saveImage();
+	return;
+	}
+  QString command = "write " + this->currentImageName;
+  this->runCommand(command.toAscii());
+}
+
+void MainWindow::loadView()
+{
+ QString viewFileName = QFileDialog::getOpenFileName(this, tr("Open View File"),
+   "", tr("View Files (*.vp *.vf)"));
+ QString command = "last " + viewFileName;
+ this->runCommand(command.toAscii());
+}
+          
+void MainWindow::toggleGrayscale()
+{
+  QString command = "set b ";
+  if(m_ui->grayscale->isChecked())
+    {
+    command += " 1";
+    }
+  else
+    {
+    command += " 0";
+    }
+  this->runCommand(command.toAscii());
+  this->runCommand("new");
+}
+
+void MainWindow::toggleBackfaceVisibility()
+{
+  QString command = "set bv";
+  if(m_ui->backfaceVisibility->isChecked())
+    {
+    command += " 1";
+    }
+  else
+    {
+    command += " 0";
+    }
+  this->runCommand(command.toAscii());
+  this->runCommand("new");
+}
+
+void MainWindow::toggleIrradiance()
+{
+  QString command = "set i";
+  if(m_ui->irradiance->isChecked())
+    {
+    command += " 1";
+    }
+  else
+    {
+    command += " 0";
+    }
+  this->runCommand(command.toAscii());
+  this->runCommand("new");
+}
+  
+void MainWindow::appendToRif()
+{
+  bool ok;
+  QString viewName = QInputDialog::getText(this, tr("Input view name"),
+                                      tr("Name of view:"), QLineEdit::Normal,
+                                      "", &ok);
+  if (ok && !viewName.isEmpty())
+    {
+    QString radFileName = QFileDialog::getSaveFileName(this, tr("Save File"),
+      "", tr("rad files (*.rif)"), 0, QFileDialog::DontConfirmOverwrite);
+    QString command = "V " + viewName + " " + radFileName;
+    this->runCommand(command.toAscii());
+    }
+}
+
+void MainWindow::appendToView()
+{
+ QString viewFileName = QFileDialog::getSaveFileName(this, tr("Save File"),
+   "", tr("view files (*.vp *.vf)"), 0, QFileDialog::DontConfirmOverwrite);
+ if(viewFileName != "")
+   {
+   QString command = "view " + viewFileName;
+   this->runCommand(command.toAscii());
+   }
+}
+
+void MainWindow::showIncrementsDialog()
+{
+  m_incrementsDialogUi->small->setText(QString::number(this->smallIncrement));
+  m_incrementsDialogUi->large->setText(QString::number(this->largeIncrement));
+  m_incrementsDialog->show();
+}
+
+void MainWindow::hideIncrementsDialog()
+{
+  m_incrementsDialog->hide();
+}
+
+void MainWindow::adjustIncrements()
+{
+  bool okay = true;
+  float f = m_incrementsDialogUi->small->text().toFloat(&okay);
+  if(okay)
+    {
+    this->smallIncrement = f;
+    }
+  f = m_incrementsDialogUi->large->text().toFloat(&okay);
+  if(okay)
+    {
+    this->largeIncrement = f;
+    }
+}
+
+void MainWindow::showCommandsDialog()
+{
+  m_commandsDialog->show();
+}
+
+void MainWindow::showAbout()
+{
+  QString aboutText =
+    "rvu was written mainly by Greg Ward.\nThe Qt-based GUI was developed by Kitware, Inc. in 2011";
+  QMessageBox::about(this, "About rvu", aboutText);
+}
diff --git a/src/rvu/mainwindow.h b/src/rvu/mainwindow.h
new file mode 100644
index 0000000..419efb3
--- /dev/null
+++ b/src/rvu/mainwindow.h
@@ -0,0 +1,126 @@
+
+#ifndef __MainWindow_H
+#define __MainWindow_H
+
+#include <QtGui/QMainWindow>
+#include "fvect.h"
+#include "rpaint.h"
+
+class QAction;
+class QDialog;
+class RvuWidget;
+
+namespace Ui
+{
+class MainWindow;
+class exposureDialog;
+class parameterDialog;
+class viewDialog;
+class incrementsDialog;
+class commandsDialog;
+}
+
+class MainWindow : public QMainWindow
+{
+  Q_OBJECT
+
+public:
+  MainWindow(int width, int height, const char* name, const char* id);
+  ~MainWindow();
+
+  RvuWidget* getRvuWidget() const;
+  void resizeImage(int width, int height);
+  void setStatus(const char*);
+  void setProgress(int);
+  void pick( int* x, int* y);
+protected:
+  void closeEvent(QCloseEvent *event);
+  void doSubmit();
+  void updatePositionLabels();
+  void runCommand(const char *command);
+  void move(int direction, float amount);
+  void refreshView(VIEW *nv);
+
+protected slots:
+  void buttonPressed();
+  void redraw();
+  void traceRay();
+  void saveImage();
+  void saveCurrentImage();
+  void loadView();
+  void toggleToolBar();
+  void toggleTranslateTool();
+  void toggleStatusBar();
+  void moveXPlusOne();
+  void moveXPlusTwo();
+  void moveYPlusOne();
+  void moveYPlusTwo();
+  void moveZPlusOne();
+  void moveZPlusTwo();
+  void moveXMinusOne();
+  void moveXMinusTwo();
+  void moveYMinusOne();
+  void moveYMinusTwo();
+  void moveZMinusOne();
+  void moveZMinusTwo();
+  void showExposureDialog();
+  void hideExposureDialog();
+  void showParameterDialog();
+  void hideParameterDialog();
+  void adjustExposure();
+  void updatePointRadio();
+  void adjustParameters();
+  void showViewDialog();
+  void hideViewDialog();
+  void adjustView();
+  void toggleBackfaceVisibility();
+  void toggleIrradiance();
+  void toggleGrayscale();
+  void appendToRif();
+  void appendToView();
+  void showIncrementsDialog();
+  void hideIncrementsDialog();
+  void adjustIncrements();
+  void showCommandsDialog();
+  void showAbout();
+  /** Enable/disable elements of the UI while rendering. */
+  void enableInterface(bool enable);
+
+private:
+  void createActions();
+  void connectSlots();
+
+  /** Our MainWindow GUI. */
+  Ui::MainWindow *m_ui;
+  QAction *m_minimizeAction;
+  QAction *m_maximizeAction;
+  QAction *m_restoreAction;
+  QAction *m_quitAction;
+
+  /** Exposure Dialog */
+  QDialog *m_exposureDialog;
+  Ui::exposureDialog *m_exposureDialogUi;
+
+  /** Parameter Dialog */
+  QDialog *m_parameterDialog;
+  Ui::parameterDialog *m_parameterDialogUi;
+
+  /** View Dialog */
+  QDialog *m_viewDialog;
+  Ui::viewDialog *m_viewDialogUi;
+  
+  /** Increments Dialog */
+  QDialog *m_incrementsDialog;
+  Ui::incrementsDialog *m_incrementsDialogUi;
+  float smallIncrement;
+  float largeIncrement;
+  
+  /** Commands Dialog */
+  QDialog *m_commandsDialog;
+  Ui::commandsDialog *m_commandsDialogUi;
+  
+  /** save image */
+  QString currentImageName;
+};
+
+#endif
diff --git a/src/rvu/mainwindow.ui b/src/rvu/mainwindow.ui
new file mode 100644
index 0000000..f208d73
--- /dev/null
+++ b/src/rvu/mainwindow.ui
@@ -0,0 +1,745 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>1049</width>
+    <height>917</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>MainWindow</string>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <layout class="QGridLayout" name="gridLayout" rowstretch="3,0,0,0,0,0,0">
+    <item row="0" column="0" rowspan="5" colspan="3">
+     <widget class="RvuWidget" name="rvuWidget" native="true">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+        <horstretch>0</horstretch>
+        <verstretch>1</verstretch>
+       </sizepolicy>
+      </property>
+     </widget>
+    </item>
+    <item row="1" column="3">
+     <widget class="QWidget" name="xWidget" native="true">
+      <property name="minimumSize">
+       <size>
+        <width>123</width>
+        <height>70</height>
+       </size>
+      </property>
+      <widget class="QLabel" name="xValue">
+       <property name="geometry">
+        <rect>
+         <x>23</x>
+         <y>30</y>
+         <width>41</width>
+         <height>16</height>
+        </rect>
+       </property>
+       <property name="text">
+        <string>0.00</string>
+       </property>
+      </widget>
+      <widget class="QPushButton" name="xMinus1Button">
+       <property name="geometry">
+        <rect>
+         <x>74</x>
+         <y>37</y>
+         <width>17</width>
+         <height>17</height>
+        </rect>
+       </property>
+       <property name="font">
+        <font>
+         <pointsize>11</pointsize>
+        </font>
+       </property>
+       <property name="text">
+        <string>-</string>
+       </property>
+      </widget>
+      <widget class="QLabel" name="xLabel">
+       <property name="geometry">
+        <rect>
+         <x>4</x>
+         <y>30</y>
+         <width>16</width>
+         <height>16</height>
+        </rect>
+       </property>
+       <property name="text">
+        <string>X</string>
+       </property>
+      </widget>
+      <widget class="QPushButton" name="xPlus2Button">
+       <property name="geometry">
+        <rect>
+         <x>90</x>
+         <y>17</y>
+         <width>21</width>
+         <height>21</height>
+        </rect>
+       </property>
+       <property name="font">
+        <font>
+         <pointsize>13</pointsize>
+        </font>
+       </property>
+       <property name="text">
+        <string>+</string>
+       </property>
+      </widget>
+      <widget class="QPushButton" name="xMinus2Button">
+       <property name="geometry">
+        <rect>
+         <x>90</x>
+         <y>37</y>
+         <width>21</width>
+         <height>21</height>
+        </rect>
+       </property>
+       <property name="font">
+        <font>
+         <pointsize>13</pointsize>
+        </font>
+       </property>
+       <property name="text">
+        <string>-</string>
+       </property>
+      </widget>
+      <widget class="QPushButton" name="xPlus1Button">
+       <property name="geometry">
+        <rect>
+         <x>74</x>
+         <y>21</y>
+         <width>17</width>
+         <height>17</height>
+        </rect>
+       </property>
+       <property name="font">
+        <font>
+         <pointsize>11</pointsize>
+        </font>
+       </property>
+       <property name="text">
+        <string>+</string>
+       </property>
+      </widget>
+      <widget class="Line" name="xLine">
+       <property name="geometry">
+        <rect>
+         <x>0</x>
+         <y>3</y>
+         <width>118</width>
+         <height>3</height>
+        </rect>
+       </property>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+      </widget>
+     </widget>
+    </item>
+    <item row="2" column="3">
+     <widget class="QWidget" name="yWidget" native="true">
+      <property name="minimumSize">
+       <size>
+        <width>123</width>
+        <height>70</height>
+       </size>
+      </property>
+      <widget class="QPushButton" name="yMinus1Button">
+       <property name="geometry">
+        <rect>
+         <x>74</x>
+         <y>37</y>
+         <width>17</width>
+         <height>17</height>
+        </rect>
+       </property>
+       <property name="font">
+        <font>
+         <pointsize>11</pointsize>
+        </font>
+       </property>
+       <property name="text">
+        <string>-</string>
+       </property>
+      </widget>
+      <widget class="QLabel" name="yLabel">
+       <property name="geometry">
+        <rect>
+         <x>4</x>
+         <y>29</y>
+         <width>16</width>
+         <height>16</height>
+        </rect>
+       </property>
+       <property name="text">
+        <string>Y</string>
+       </property>
+      </widget>
+      <widget class="QPushButton" name="yPlus2Button">
+       <property name="geometry">
+        <rect>
+         <x>90</x>
+         <y>17</y>
+         <width>21</width>
+         <height>21</height>
+        </rect>
+       </property>
+       <property name="font">
+        <font>
+         <pointsize>13</pointsize>
+        </font>
+       </property>
+       <property name="text">
+        <string>+</string>
+       </property>
+      </widget>
+      <widget class="QLabel" name="yValue">
+       <property name="geometry">
+        <rect>
+         <x>23</x>
+         <y>29</y>
+         <width>41</width>
+         <height>16</height>
+        </rect>
+       </property>
+       <property name="text">
+        <string>0.00</string>
+       </property>
+      </widget>
+      <widget class="QPushButton" name="yMinus2Button">
+       <property name="geometry">
+        <rect>
+         <x>90</x>
+         <y>37</y>
+         <width>21</width>
+         <height>21</height>
+        </rect>
+       </property>
+       <property name="font">
+        <font>
+         <pointsize>13</pointsize>
+        </font>
+       </property>
+       <property name="text">
+        <string>-</string>
+       </property>
+      </widget>
+      <widget class="QPushButton" name="yPlus1Button">
+       <property name="geometry">
+        <rect>
+         <x>74</x>
+         <y>21</y>
+         <width>17</width>
+         <height>17</height>
+        </rect>
+       </property>
+       <property name="font">
+        <font>
+         <pointsize>11</pointsize>
+        </font>
+       </property>
+       <property name="text">
+        <string>+</string>
+       </property>
+      </widget>
+      <widget class="Line" name="yLine">
+       <property name="geometry">
+        <rect>
+         <x>0</x>
+         <y>3</y>
+         <width>118</width>
+         <height>3</height>
+        </rect>
+       </property>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+      </widget>
+     </widget>
+    </item>
+    <item row="3" column="3">
+     <widget class="QWidget" name="zWidget" native="true">
+      <property name="minimumSize">
+       <size>
+        <width>123</width>
+        <height>70</height>
+       </size>
+      </property>
+      <widget class="QPushButton" name="zMinus2Button">
+       <property name="geometry">
+        <rect>
+         <x>90</x>
+         <y>37</y>
+         <width>21</width>
+         <height>21</height>
+        </rect>
+       </property>
+       <property name="font">
+        <font>
+         <pointsize>13</pointsize>
+        </font>
+       </property>
+       <property name="text">
+        <string>-</string>
+       </property>
+      </widget>
+      <widget class="QLabel" name="zLabel">
+       <property name="geometry">
+        <rect>
+         <x>4</x>
+         <y>30</y>
+         <width>16</width>
+         <height>16</height>
+        </rect>
+       </property>
+       <property name="text">
+        <string>Z</string>
+       </property>
+      </widget>
+      <widget class="QPushButton" name="zPlus2Button">
+       <property name="geometry">
+        <rect>
+         <x>90</x>
+         <y>17</y>
+         <width>21</width>
+         <height>21</height>
+        </rect>
+       </property>
+       <property name="font">
+        <font>
+         <pointsize>13</pointsize>
+        </font>
+       </property>
+       <property name="text">
+        <string>+</string>
+       </property>
+      </widget>
+      <widget class="QPushButton" name="zMinus1Button">
+       <property name="geometry">
+        <rect>
+         <x>74</x>
+         <y>37</y>
+         <width>17</width>
+         <height>17</height>
+        </rect>
+       </property>
+       <property name="font">
+        <font>
+         <pointsize>11</pointsize>
+        </font>
+       </property>
+       <property name="text">
+        <string>-</string>
+       </property>
+      </widget>
+      <widget class="QPushButton" name="zPlus1Button">
+       <property name="geometry">
+        <rect>
+         <x>74</x>
+         <y>21</y>
+         <width>17</width>
+         <height>17</height>
+        </rect>
+       </property>
+       <property name="font">
+        <font>
+         <pointsize>11</pointsize>
+        </font>
+       </property>
+       <property name="text">
+        <string>+</string>
+       </property>
+      </widget>
+      <widget class="QLabel" name="zValue">
+       <property name="geometry">
+        <rect>
+         <x>23</x>
+         <y>30</y>
+         <width>41</width>
+         <height>16</height>
+        </rect>
+       </property>
+       <property name="text">
+        <string>0.00</string>
+       </property>
+      </widget>
+      <widget class="Line" name="zLine">
+       <property name="geometry">
+        <rect>
+         <x>0</x>
+         <y>3</y>
+         <width>118</width>
+         <height>3</height>
+        </rect>
+       </property>
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+      </widget>
+     </widget>
+    </item>
+    <item row="5" column="0">
+     <widget class="QLineEdit" name="lineEdit">
+      <property name="enabled">
+       <bool>true</bool>
+      </property>
+      <property name="sizeIncrement">
+       <size>
+        <width>2</width>
+        <height>0</height>
+       </size>
+      </property>
+      <property name="text">
+       <string/>
+      </property>
+     </widget>
+    </item>
+    <item row="5" column="1">
+     <widget class="QPushButton" name="pushButton">
+      <property name="text">
+       <string>Submit</string>
+      </property>
+     </widget>
+    </item>
+    <item row="5" column="2" colspan="2">
+     <widget class="QProgressBar" name="progressBar">
+      <property name="enabled">
+       <bool>false</bool>
+      </property>
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="minimumSize">
+       <size>
+        <width>250</width>
+        <height>0</height>
+       </size>
+      </property>
+      <property name="sizeIncrement">
+       <size>
+        <width>1</width>
+        <height>0</height>
+       </size>
+      </property>
+      <property name="value">
+       <number>0</number>
+      </property>
+     </widget>
+    </item>
+    <item row="6" column="0" colspan="4">
+     <widget class="QPlainTextEdit" name="messageBox">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+        <horstretch>0</horstretch>
+        <verstretch>100</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="minimumSize">
+       <size>
+        <width>0</width>
+        <height>100</height>
+       </size>
+      </property>
+      <property name="maximumSize">
+       <size>
+        <width>16777215</width>
+        <height>100</height>
+       </size>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+  <widget class="QMenuBar" name="menubar">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>1049</width>
+     <height>22</height>
+    </rect>
+   </property>
+   <widget class="QMenu" name="fileMenu">
+    <property name="title">
+     <string>File</string>
+    </property>
+    <addaction name="appendToRif"/>
+    <addaction name="appendToView"/>
+    <addaction name="separator"/>
+    <addaction name="loadRif"/>
+    <addaction name="loadView"/>
+    <addaction name="separator"/>
+    <addaction name="saveImage"/>
+    <addaction name="saveImageAs"/>
+    <addaction name="separator"/>
+    <addaction name="exit"/>
+   </widget>
+   <widget class="QMenu" name="viewMenu">
+    <property name="title">
+     <string>View</string>
+    </property>
+    <addaction name="toggleToolBar"/>
+    <addaction name="toggleStatusBar"/>
+   </widget>
+   <widget class="QMenu" name="setMenu">
+    <property name="title">
+     <string>Set</string>
+    </property>
+    <addaction name="backfaceVisibility"/>
+    <addaction name="grayscale"/>
+    <addaction name="irradiance"/>
+    <addaction name="separator"/>
+    <addaction name="exposure"/>
+    <addaction name="parameters"/>
+    <addaction name="view"/>
+    <addaction name="separator"/>
+    <addaction name="GUI_Increments"/>
+   </widget>
+   <widget class="QMenu" name="menuHelp">
+    <property name="title">
+     <string>Help</string>
+    </property>
+    <addaction name="aboutRvu"/>
+    <addaction name="separator"/>
+    <addaction name="commands"/>
+   </widget>
+   <addaction name="fileMenu"/>
+   <addaction name="viewMenu"/>
+   <addaction name="setMenu"/>
+   <addaction name="menuHelp"/>
+  </widget>
+  <widget class="QToolBar" name="toolBar">
+   <property name="windowTitle">
+    <string>toolBar</string>
+   </property>
+   <attribute name="toolBarArea">
+    <enum>TopToolBarArea</enum>
+   </attribute>
+   <attribute name="toolBarBreak">
+    <bool>false</bool>
+   </attribute>
+   <addaction name="exposure"/>
+   <addaction name="redraw"/>
+   <addaction name="parameters"/>
+   <addaction name="trace"/>
+   <addaction name="view"/>
+   <addaction name="separator"/>
+   <addaction name="loadView"/>
+   <addaction name="saveImageAs"/>
+  </widget>
+  <action name="appendToRif">
+   <property name="text">
+    <string>Append view to .rif file</string>
+   </property>
+  </action>
+  <action name="appendToView">
+   <property name="text">
+    <string>Append view to .view file</string>
+   </property>
+  </action>
+  <action name="loadRif">
+   <property name="text">
+    <string>Load .rif</string>
+   </property>
+  </action>
+  <action name="loadView">
+   <property name="text">
+    <string>Load View</string>
+   </property>
+   <property name="toolTip">
+    <string>Load a .view file</string>
+   </property>
+  </action>
+  <action name="saveImage">
+   <property name="text">
+    <string>Save Image</string>
+   </property>
+   <property name="toolTip">
+    <string>Save current image to file</string>
+   </property>
+  </action>
+  <action name="saveImageAs">
+   <property name="text">
+    <string>Save Image as</string>
+   </property>
+   <property name="toolTip">
+    <string>Save current image as a .pic file</string>
+   </property>
+  </action>
+  <action name="saveLog">
+   <property name="text">
+    <string>Save log file as</string>
+   </property>
+  </action>
+  <action name="viewLog">
+   <property name="text">
+    <string>View log file</string>
+   </property>
+  </action>
+  <action name="exit">
+   <property name="text">
+    <string>Exit</string>
+   </property>
+  </action>
+  <action name="toggleToolBar">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Tool Bar</string>
+   </property>
+   <property name="toolTip">
+    <string>Display or Hide the Toolbar</string>
+   </property>
+  </action>
+  <action name="toggleStatusBar">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Status Bar</string>
+   </property>
+   <property name="toolTip">
+    <string>Display or Hide the Status Bar</string>
+   </property>
+  </action>
+  <action name="toggleAngleTool">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Angle Tool</string>
+   </property>
+   <property name="toolTip">
+    <string>Display or Hide the Angle Adjustment Tool</string>
+   </property>
+  </action>
+  <action name="toggleTranslateTool">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Translate Tool</string>
+   </property>
+   <property name="toolTip">
+    <string>Display or Hide the Translate Tool</string>
+   </property>
+  </action>
+  <action name="backfaceVisibility">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Backface Visibility</string>
+   </property>
+  </action>
+  <action name="grayscale">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Grayscale</string>
+   </property>
+  </action>
+  <action name="irradiance">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Irradiance</string>
+   </property>
+  </action>
+  <action name="exposure">
+   <property name="text">
+    <string>Exposure</string>
+   </property>
+  </action>
+  <action name="parameters">
+   <property name="text">
+    <string>Parameters</string>
+   </property>
+  </action>
+  <action name="view">
+   <property name="text">
+    <string>View</string>
+   </property>
+   <property name="toolTip">
+    <string>set view</string>
+   </property>
+  </action>
+  <action name="GUI_Increments">
+   <property name="text">
+    <string>GUI Increments</string>
+   </property>
+  </action>
+  <action name="aboutRvu">
+   <property name="text">
+    <string>About rvu</string>
+   </property>
+  </action>
+  <action name="commands">
+   <property name="text">
+    <string>Commands</string>
+   </property>
+  </action>
+  <action name="defaults">
+   <property name="text">
+    <string>Defaults</string>
+   </property>
+  </action>
+  <action name="redraw">
+   <property name="text">
+    <string>Redraw</string>
+   </property>
+   <property name="toolTip">
+    <string>redraw the scene</string>
+   </property>
+  </action>
+  <action name="trace">
+   <property name="text">
+    <string>Trace</string>
+   </property>
+   <property name="toolTip">
+    <string>trace a ray</string>
+   </property>
+  </action>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>RvuWidget</class>
+   <extends>QWidget</extends>
+   <header>rvuwidget.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/rvu/parameterdialog.ui b/src/rvu/parameterdialog.ui
new file mode 100644
index 0000000..c9f5841
--- /dev/null
+++ b/src/rvu/parameterdialog.ui
@@ -0,0 +1,1007 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>parameterDialog</class>
+ <widget class="QDialog" name="parameterDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>617</width>
+    <height>392</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Parameters</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QTabWidget" name="tabWidget">
+     <property name="cursor">
+      <cursorShape>IBeamCursor</cursorShape>
+     </property>
+     <property name="currentIndex">
+      <number>0</number>
+     </property>
+     <widget class="QWidget" name="ambientTab">
+      <attribute name="title">
+       <string>Ambient</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout">
+       <item row="0" column="2">
+        <spacer name="verticalSpacer_9">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>83</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="1" column="0">
+        <widget class="QLabel" name="label">
+         <property name="text">
+          <string>Value:</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="1">
+        <widget class="QLineEdit" name="valueX">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="2">
+        <widget class="QLabel" name="label_2">
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Weight:</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="3">
+        <widget class="QLineEdit" name="weight">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="4">
+        <widget class="QLabel" name="label_5">
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Super-samples:</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="5">
+        <widget class="QLineEdit" name="supersamples"/>
+       </item>
+       <item row="2" column="1">
+        <widget class="QLineEdit" name="valueY">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="2">
+        <widget class="QLabel" name="label_3">
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Accuracy:</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="3">
+        <widget class="QLineEdit" name="accuracy">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="4">
+        <widget class="QLabel" name="label_6">
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Bounces:</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="5">
+        <widget class="QLineEdit" name="bounces">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="1">
+        <widget class="QLineEdit" name="valueZ">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="2">
+        <widget class="QLabel" name="label_4">
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Divisions:</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="3">
+        <widget class="QLineEdit" name="divisions">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="4">
+        <widget class="QLabel" name="label_7">
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Resolution:</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="5">
+        <widget class="QLineEdit" name="resolution">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="4" column="2">
+        <spacer name="verticalSpacer_10">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>84</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="directTab">
+      <attribute name="title">
+       <string>Direct</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout_2">
+       <item row="0" column="1">
+        <widget class="QLabel" name="label_8">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Certainty:</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="2">
+        <widget class="QLineEdit" name="certainty">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="1">
+        <widget class="QLabel" name="label_9">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Jitter:</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="2">
+        <widget class="QLineEdit" name="jitter">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="0">
+        <spacer name="horizontalSpacer_5">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>153</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="2" column="1">
+        <widget class="QLabel" name="label_10">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Sampling:</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="2">
+        <widget class="QLineEdit" name="sampling">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="3">
+        <spacer name="horizontalSpacer_6">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>153</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="3" column="1">
+        <widget class="QLabel" name="label_11">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Threshold:</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="2">
+        <widget class="QLineEdit" name="threshold">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="4" column="1">
+        <widget class="QLabel" name="label_12">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Visibility:</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="4" column="2">
+        <widget class="QLineEdit" name="visibility">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="limitTab">
+      <attribute name="title">
+       <string>Limit</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout_3">
+       <item row="0" column="2">
+        <spacer name="verticalSpacer">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>73</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="1" column="0">
+        <spacer name="horizontalSpacer">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>173</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="1" column="1">
+        <widget class="QLabel" name="label_13">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Reflection:</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="2">
+        <widget class="QLineEdit" name="reflection">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="3">
+        <spacer name="horizontalSpacer_2">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>143</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="2" column="0">
+        <spacer name="horizontalSpacer_3">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>173</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="2" column="1">
+        <widget class="QLabel" name="label_14">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Weight:</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="2">
+        <widget class="QLineEdit" name="limit_weight">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="3">
+        <spacer name="horizontalSpacer_4">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>143</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="3" column="2">
+        <spacer name="verticalSpacer_2">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>124</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="mediumTab">
+      <attribute name="title">
+       <string>Medium</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout_4">
+       <item row="0" column="1">
+        <spacer name="verticalSpacer_3">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>48</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="1" column="1">
+        <widget class="QLabel" name="label_15">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Scattering albedo:</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="2">
+        <widget class="QLabel" name="label_16">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Extinction coefficient:</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="1">
+        <widget class="QLineEdit" name="albedoX">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="2">
+        <widget class="QLineEdit" name="extinctionX">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="1">
+        <widget class="QLineEdit" name="albedoY">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="2">
+        <widget class="QLineEdit" name="extinctionY">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="4" column="1">
+        <widget class="QLineEdit" name="albedoZ">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="4" column="2">
+        <widget class="QLineEdit" name="extinctionZ">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="5" column="0">
+        <spacer name="horizontalSpacer_7">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>109</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="5" column="1">
+        <widget class="QLabel" name="label_17">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Scattering eccentricity:</string>
+         </property>
+        </widget>
+       </item>
+       <item row="5" column="2">
+        <widget class="QLabel" name="label_18">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Mist sampling distance:</string>
+         </property>
+        </widget>
+       </item>
+       <item row="5" column="3">
+        <spacer name="horizontalSpacer_8">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>108</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="6" column="1">
+        <widget class="QLineEdit" name="eccentricity">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="6" column="2">
+        <widget class="QLineEdit" name="mistDistance">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="7" column="1">
+        <spacer name="verticalSpacer_4">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>28</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="pixelTab">
+      <attribute name="title">
+       <string>Pixel</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout_5">
+       <item row="0" column="1">
+        <spacer name="verticalSpacer_6">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>99</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="1" column="0">
+        <spacer name="horizontalSpacer_9">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>156</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="1" column="1">
+        <widget class="QLabel" name="label_19">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Sample:</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="2">
+        <widget class="QLineEdit" name="sample">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="3">
+        <spacer name="horizontalSpacer_10">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>146</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="2" column="1">
+        <widget class="QLabel" name="label_20">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Threshold</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="2">
+        <widget class="QLineEdit" name="px_threshold"/>
+       </item>
+       <item row="3" column="1">
+        <spacer name="verticalSpacer_5">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>99</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="specularTab">
+      <attribute name="title">
+       <string>Specular</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout_6">
+       <item row="0" column="1">
+        <spacer name="verticalSpacer_7">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>99</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="1" column="0">
+        <spacer name="horizontalSpacer_12">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>155</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="1" column="1">
+        <widget class="QLabel" name="label_22">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Jitter:</string>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="2">
+        <widget class="QLineEdit" name="sp_jitter">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="3">
+        <spacer name="horizontalSpacer_11">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>145</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="2" column="1">
+        <widget class="QLabel" name="label_23">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Threshold:</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="2">
+        <widget class="QLineEdit" name="sp_threshold"/>
+       </item>
+       <item row="3" column="1">
+        <spacer name="verticalSpacer_8">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>99</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>parameterDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>parameterDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/src/rvu/qt.c b/src/rvu/qt.c
new file mode 100644
index 0000000..bd01c46
--- /dev/null
+++ b/src/rvu/qt.c
@@ -0,0 +1,265 @@
+#ifndef lint
+static const char	RCSid[] = "$Id$";
+#endif
+/*
+ *  qt.c - driver for qt
+ */
+#include "math.h"
+#include "copyright.h"
+#include  "standard.h"
+#include  "platform.h"
+#include  "color.h"
+#include  "driver.h"
+#include  "rpaint.h"
+#include "color.h"
+
+static char lastPrompt[1024];
+static const char* currentCommand =0;
+static int abort_render = 0;
+static int progress = 0;
+static int last_total_progress = 0;
+#define GAMMA		2.2		/* default exponent correction */
+
+static dr_closef_t qt_close;
+static dr_clearf_t qt_clear;
+static dr_paintrf_t qt_paintr;
+static dr_getcurf_t qt_getcur;
+static dr_comoutf_t qt_comout;
+static dr_cominf_t qt_comin;
+static dr_flushf_t qt_flush;
+
+static struct driver  qt_driver = {
+  qt_close, qt_clear, qt_paintr, qt_getcur,
+  qt_comout, qt_comin, qt_flush, 1.0
+};
+
+/* functions from qt_rvu_main.cxx */
+extern qt_rvu_init(char*, char*, int*, int* );
+extern qt_resize(int, int);
+extern qt_rvu_paint(int r,int g,int b,int xmin,
+                    int ymin,int xmax,int ymax);
+extern void qt_flush_display();
+extern int qt_rvu_run();
+extern void qt_window_comout(const char*);
+extern void qt_set_progress(int);
+extern int qt_open_text_dialog(char* , const char*);
+
+extern struct driver *
+qt_init(		/* initialize driver */
+  char  *name,
+  char  *id
+)
+{
+  lastPrompt[0] = 0;
+  make_gmap(GAMMA);
+  qt_rvu_init(name, id, &qt_driver.xsiz, &qt_driver.ysiz);
+  return(&qt_driver);
+}
+
+
+static void
+qt_close(void)			/* close our display */
+{
+  fprintf(stderr, "Qt close\n");
+}
+
+static void
+qt_clear(			/* clear our display */
+  int  xres,
+  int  yres
+)
+{
+  qt_resize(xres, yres);
+}
+
+
+static void
+qt_paintr(		/* fill a rectangle */
+  COLOR  col,
+  int  xmin,
+  int  ymin,
+  int  xmax,
+  int  ymax
+)
+{
+  uby8 rgb[3];
+  map_color(rgb, col);
+  qt_rvu_paint(rgb[RED], rgb[GRN], rgb[BLU],
+               xmin, ymin, xmax, ymax);
+}
+
+#define SCALE 1.2
+
+static void
+qt_flush(void)			/* flush output */
+{
+  int p;
+  if(last_total_progress)
+    {
+    progress++;
+    p = pdepth*10 +
+      (int)floor(10 *
+                 atan( SCALE * progress / last_total_progress) * 2.0/3.141593);
+    qt_set_progress(p);
+    }
+  qt_flush_display();
+}
+
+
+static int comincalls = 0;
+static void
+qt_comin(		/* read in command line qt gui */
+  char  *inp,
+  char  *prompt
+)
+{
+  if (prompt && strlen(prompt))
+    {
+    qt_comout(prompt);
+    }
+  if(comincalls < 2)
+    {
+    comincalls++;
+    }
+  /* if prompt is not set, then use the lastPrompt which
+     comes from the last call to comout */
+  if(!prompt)
+    {
+    prompt = lastPrompt;
+    }
+  /* first time call to qt_comin start qt event loop */
+  if(comincalls == 1)
+    {
+    qt_rvu_run();
+    /* when qt is done we are done so exit */
+    exit(0);
+    }
+  /* This code will be called from inside the running
+     qt_rvu_run loop in two cases:
+     1. when a user enters a new command to the text widget. In
+     this case the currentCommand is not null.
+     2. when a command calls comin directly, that is the else
+     case. */
+  if(currentCommand)
+    {
+    /* A user has entered a new command */
+    qt_comout((char*)currentCommand);
+    /* copy the user command into inp, set
+       currentCommand to null so as not to use it again,
+       and then return */
+    strcpy(inp, currentCommand);
+    currentCommand = 0;
+    return;
+    }
+  else
+    {
+    /* in this case comin has been called from inside a
+       command call like view.
+       OK tricky bit here.  If the prompt is empty, it
+       is just trying to get the user to hit enter so that
+       the most recent comout does not scrool away. Since the
+       qt interface has a scroll bar we don't have to do that,
+       and do not want to prompt the user. Also, if the prompt
+       is set to "done: ", then we don't want to prompt the user.
+       In other cases we assume that we are inside a command
+       that is asking for more input and we use a dialog box
+       to get it. */
+    if(strlen(prompt) > 0 && strcmp(prompt, "done: ") != 0)
+      {
+      /* if the user entered new text, then echo that
+         to the output window. */
+      if(qt_open_text_dialog(inp, prompt))
+        {
+        qt_window_comout(inp);
+        }
+      lastPrompt[0] = 0;
+      }
+    }
+}
+
+static void
+qt_comout(		/* write out string to stdout */
+  char	*outp
+)
+{
+  if (!outp)
+    {
+    return;
+    }
+  if (strlen(outp) > 0)
+    {
+    if(outp[strlen(outp)-2] == ':')
+      {
+      strcpy(lastPrompt, outp);
+      }
+    qt_window_comout(outp);
+    }
+}
+
+extern void qt_rvu_get_position(int *x, int *y);
+
+static int
+qt_getcur(		/* get cursor position */
+  int  *xp,
+  int  *yp
+)
+{
+  qt_rvu_get_position(xp, yp);
+  return 0;
+}
+
+void qt_set_abort(int value)
+{
+  dev->inpready = value;
+}
+
+
+/* process one command from the GUI */
+void qt_process_command(const char* com)
+{
+  char  buf[512];
+  buf[0] = 0;
+  /* set the currentCommand to the command */
+  currentCommand = com;
+  /* Call command with no prompt, this will in
+     turn call qt_comin which will use the currentCommand
+     pointer as the command to process */
+  command("");
+  /* after processing a command try to do a render */
+  for ( ; ; )
+    {
+    if (hresolu <= 1<<pdepth && vresolu <= 1<<pdepth)
+      {
+      qt_set_progress(100);
+      qt_comout("done");
+      return;
+      }
+    errno = 0;
+    if (hresolu <= psample<<pdepth && vresolu <= psample<<pdepth)
+      {
+      sprintf(buf, "%d sampling...\n", 1<<pdepth);
+      qt_comout(buf);
+      last_total_progress = progress ? progress:1;
+      progress = 0;
+      rsample();
+      }
+    else
+      {
+      sprintf(buf, "%d refining...\n", 1<<pdepth);
+      qt_comout(buf);
+      last_total_progress = progress ? progress:1;
+      progress = 0;
+      refine(&ptrunk, pdepth+1);
+      }
+    if (dev->inpready)
+      {
+      qt_comout("abort");
+      dev->inpready = 0;
+      pdepth = 10;
+      return;
+      }
+    /* finished this depth */
+    pdepth++;
+    }
+}
+
diff --git a/src/rvu/qt_rvu_main.cxx b/src/rvu/qt_rvu_main.cxx
new file mode 100644
index 0000000..67b20df
--- /dev/null
+++ b/src/rvu/qt_rvu_main.cxx
@@ -0,0 +1,102 @@
+#include <QtGui/QApplication>
+#include <QtGui/QInputDialog>
+#include <QtGui/QColor>
+#include <QtCore/QDir>
+#include <string>
+#include <iostream>
+#include "rvuwidget.h"
+#include "mainwindow.h"
+
+// file level globals
+static RvuWidget* WidgetInstance = 0;
+static MainWindow* MainWindowInstance = 0;
+static QApplication* ApplicationInstance = 0;
+
+// default size of window
+static int XSize = 1024;
+static int YSize = 768;
+
+extern "C"
+int qt_rvu_paint(int r,int g,int b,
+                 int xmin, int ymin, int xmax, int ymax
+  )
+{
+  WidgetInstance->drawRect(xmin, YSize - ymax -1,
+                           abs(xmax-xmin),
+                           abs(ymax-ymin),
+                           QColor(r, g, b));
+  return 0;
+}
+
+extern "C" void qt_set_progress(int p)
+{
+  MainWindowInstance->setProgress(p);
+}
+extern "C" void qt_flush_display()
+{
+  WidgetInstance->update();
+  ApplicationInstance->processEvents();
+}
+
+extern "C" int qt_rvu_run()
+{
+  MainWindowInstance->show();
+  int ret = ApplicationInstance->exec();
+  return ret;
+}
+
+extern "C" void qt_rvu_get_position(int *x, int *y)
+{
+  MainWindowInstance->pick(x, y);
+  *y = YSize - *y -1;
+}
+
+extern "C"
+int qt_rvu_init(char* name, char* id,
+                int* xsize, int* ysize)
+{
+  static int argc = 1;
+  static char * argv[] = {"rvu"};
+  ApplicationInstance = new QApplication(argc, argv);
+  *xsize = XSize;
+  *ysize = YSize;
+  MainWindowInstance = new MainWindow(*xsize, *ysize, name, id);
+  WidgetInstance = MainWindowInstance->getRvuWidget();
+  return 0;
+}
+
+extern "C"
+void qt_window_comout(const char* m)
+{
+  MainWindowInstance->setStatus(m);
+}
+
+extern "C"
+void qt_resize(int X, int Y)
+{
+  XSize = X;
+  YSize = Y;
+  MainWindowInstance->resizeImage(X, Y);
+  MainWindowInstance->show();
+}
+
+// Return 1 if inp was changed
+// Return 0 if no change was made to inp
+extern "C"
+int qt_open_text_dialog(char* inp, const char* prompt)
+{
+  bool ok;
+  QString text = QInputDialog::getText(MainWindowInstance,
+                                       "QInputDialog::getText()",
+                                       prompt, QLineEdit::Normal,
+                                       "", &ok);
+  if (ok && !text.isEmpty())
+    {
+    if(text != inp)
+      {
+      strcpy(inp, text.toAscii());
+      return 1;
+      }
+    }
+  return 0;
+}
diff --git a/src/rvu/rvuwidget.cxx b/src/rvu/rvuwidget.cxx
new file mode 100644
index 0000000..b20dd55
--- /dev/null
+++ b/src/rvu/rvuwidget.cxx
@@ -0,0 +1,81 @@
+#include "rvuwidget.h"
+
+#include <QtGui/QApplication>
+#include <QtGui/QCursor>
+#include <QtGui/QColor>
+#include <QtGui/QPainter>
+#include <QtGui/QPixmap>
+#include <QtGui/QMouseEvent>
+
+RvuWidget::RvuWidget(QWidget* parent) : QWidget(parent), m_x(0), m_y(0)
+{
+  m_image = new QPixmap(200, 200);
+  m_image->fill(QColor(0, 0, 0));
+  m_painter = new QPainter(m_image);
+  m_do_pick = false;
+}
+
+RvuWidget::~RvuWidget()
+{
+  m_painter->end();
+  delete m_painter;
+  delete m_image;
+}
+
+void RvuWidget::resizeImage(int X, int Y)
+{
+  m_painter->end();
+  delete m_image;
+  m_image =  new QPixmap(X, Y);
+  m_image->fill(QColor(0, 0, 0));
+  m_painter->begin(m_image);
+  m_painter->setPen(Qt::NoPen);
+}
+
+void RvuWidget::drawRect(int x, int y, int width, int height,
+                         const QColor &color)
+{
+  m_painter->fillRect(x, y, width, height, color);
+}
+
+void RvuWidget::getPosition(int *x, int *y)
+{
+  this->m_do_pick = true;
+  while(this->m_do_pick)
+    {
+    QApplication::processEvents();
+    }
+  *x = m_x;
+  *y = m_y;
+}
+
+void RvuWidget::paintEvent(QPaintEvent *)
+{
+  QPainter painter(this);
+  // Draw QImage
+  painter.drawPixmap(0, 0, *m_image);
+
+  // Draw the crosshairs
+  painter.setPen(QColor(0, 255, 0));
+  painter.drawLine(m_x - 10, m_y, m_x + 10, m_y);
+  painter.drawLine(m_x, m_y - 10, m_x, m_y + 10);
+}
+
+void RvuWidget::mousePressEvent(QMouseEvent *event)
+{
+  if (event->button() == Qt::LeftButton)
+    {
+    this->m_do_pick = false;
+    // Set the cursor position
+    m_x = event->x();
+    m_y = event->y();
+    }
+  this->repaint();
+}
+
+void RvuWidget::setPosition(int x, int y)
+{
+  m_x = x;
+  m_y = y;
+  this->repaint();
+}
diff --git a/src/rvu/rvuwidget.h b/src/rvu/rvuwidget.h
new file mode 100644
index 0000000..45aecd8
--- /dev/null
+++ b/src/rvu/rvuwidget.h
@@ -0,0 +1,46 @@
+
+#ifndef __RvuWidget_H
+#define __RvuWidget_H
+
+#include <QtGui/QWidget>
+
+class QPixmap;
+class QColor;
+class QMouseEvent;
+class QPainter;
+
+class RvuWidget : public QWidget
+{
+  Q_OBJECT
+
+public:
+  RvuWidget(QWidget* parent = 0);
+  ~RvuWidget();
+
+  /** Draw a rectangle to the widget (stored in a QImage). */
+  void drawRect(int x, int y, int width, int height, const QColor &color);
+
+  /** Resize the stored QImage to the supplied width and height. */
+  void resizeImage(int width, int height);
+
+  void getPosition(int *x, int *y);
+
+  void setPosition(int x, int y);
+protected:
+  /** Simple draws the QImage and the crosshairs. */
+  void paintEvent(QPaintEvent *event);
+
+  /** Receive mouse events, move the crosshairs on left clicks. */
+  void mousePressEvent(QMouseEvent *event);
+
+  /** The QImage that the ray tracing code paints to. */
+  QPixmap *m_image;
+  QPainter *m_painter;
+
+  /** X and Y position of the crosshairs. */
+  int m_x;
+  int m_y;
+  bool m_do_pick;
+};
+
+#endif
diff --git a/src/rvu/viewdialog.ui b/src/rvu/viewdialog.ui
new file mode 100644
index 0000000..faadcc6
--- /dev/null
+++ b/src/rvu/viewdialog.ui
@@ -0,0 +1,556 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>viewDialog</class>
+ <widget class="QDialog" name="viewDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>576</width>
+    <height>456</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>View</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_2">
+   <item>
+    <widget class="QWidget" name="topWidget" native="true">
+     <layout class="QHBoxLayout" name="horizontalLayout">
+      <item>
+       <widget class="QFrame" name="typeFrame">
+        <property name="frameShape">
+         <enum>QFrame::StyledPanel</enum>
+        </property>
+        <property name="frameShadow">
+         <enum>QFrame::Raised</enum>
+        </property>
+        <layout class="QVBoxLayout" name="verticalLayout">
+         <item>
+          <widget class="QLabel" name="label">
+           <property name="text">
+            <string>Type</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QRadioButton" name="angular">
+           <property name="text">
+            <string>Angular</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QRadioButton" name="cylindrical">
+           <property name="text">
+            <string>Cylindrical</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QRadioButton" name="hemispherical">
+           <property name="text">
+            <string>Hemispherical</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QRadioButton" name="parallel">
+           <property name="text">
+            <string>Parallel</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QRadioButton" name="perspective">
+           <property name="text">
+            <string>Perspective</string>
+           </property>
+           <property name="checked">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </item>
+      <item>
+       <widget class="QFrame" name="viewFrame">
+        <property name="frameShape">
+         <enum>QFrame::StyledPanel</enum>
+        </property>
+        <property name="frameShadow">
+         <enum>QFrame::Raised</enum>
+        </property>
+        <layout class="QGridLayout" name="gridLayout">
+         <item row="0" column="0" colspan="2">
+          <widget class="QLabel" name="label_5">
+           <property name="text">
+            <string>Viewpoint</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="0">
+          <widget class="QLabel" name="label_2">
+           <property name="text">
+            <string>X:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1">
+          <widget class="QLineEdit" name="viewX">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="0">
+          <widget class="QLabel" name="label_3">
+           <property name="text">
+            <string>Y:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="1">
+          <widget class="QLineEdit" name="viewY">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="0">
+          <widget class="QLabel" name="label_4">
+           <property name="text">
+            <string>Z:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="1">
+          <widget class="QLineEdit" name="viewZ">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </item>
+      <item>
+       <widget class="QFrame" name="directionFrame">
+        <property name="frameShape">
+         <enum>QFrame::StyledPanel</enum>
+        </property>
+        <property name="frameShadow">
+         <enum>QFrame::Raised</enum>
+        </property>
+        <layout class="QGridLayout" name="gridLayout_2">
+         <item row="0" column="0" colspan="2">
+          <widget class="QLabel" name="label_12">
+           <property name="text">
+            <string>Direction</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="0">
+          <widget class="QLabel" name="label_6">
+           <property name="text">
+            <string>X:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1">
+          <widget class="QLineEdit" name="dirX">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="0">
+          <widget class="QLabel" name="label_7">
+           <property name="text">
+            <string>Y:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="1">
+          <widget class="QLineEdit" name="dirY">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="0">
+          <widget class="QLabel" name="label_8">
+           <property name="text">
+            <string>Z:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="1">
+          <widget class="QLineEdit" name="dirZ">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </item>
+      <item>
+       <widget class="QFrame" name="upFrame">
+        <property name="frameShape">
+         <enum>QFrame::StyledPanel</enum>
+        </property>
+        <property name="frameShadow">
+         <enum>QFrame::Raised</enum>
+        </property>
+        <layout class="QGridLayout" name="gridLayout_3">
+         <item row="0" column="0" colspan="2">
+          <widget class="QLabel" name="label_13">
+           <property name="text">
+            <string>Up</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="0">
+          <widget class="QLabel" name="label_9">
+           <property name="text">
+            <string>X:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1">
+          <widget class="QLineEdit" name="upX">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="0">
+          <widget class="QLabel" name="label_10">
+           <property name="text">
+            <string>Y:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="1">
+          <widget class="QLineEdit" name="upY">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="0">
+          <widget class="QLabel" name="label_11">
+           <property name="text">
+            <string>Z:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="3" column="1">
+          <widget class="QLineEdit" name="upZ">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QWidget" name="bottomWidget" native="true">
+     <layout class="QHBoxLayout" name="horizontalLayout_2">
+      <item>
+       <widget class="QFrame" name="sizeFrame">
+        <property name="frameShape">
+         <enum>QFrame::StyledPanel</enum>
+        </property>
+        <property name="frameShadow">
+         <enum>QFrame::Raised</enum>
+        </property>
+        <layout class="QGridLayout" name="gridLayout_4">
+         <item row="0" column="0">
+          <widget class="QLabel" name="label_16">
+           <property name="text">
+            <string>Size</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="0">
+          <widget class="QLabel" name="label_14">
+           <property name="text">
+            <string>Horiz:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1">
+          <widget class="QLineEdit" name="sizeHoriz">
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="0">
+          <widget class="QLabel" name="label_15">
+           <property name="text">
+            <string>Vert:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="1">
+          <widget class="QLineEdit" name="sizeVert">
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </item>
+      <item>
+       <widget class="QFrame" name="frame_2">
+        <property name="frameShape">
+         <enum>QFrame::StyledPanel</enum>
+        </property>
+        <property name="frameShadow">
+         <enum>QFrame::Raised</enum>
+        </property>
+        <layout class="QGridLayout" name="gridLayout_5">
+         <item row="0" column="0" colspan="2">
+          <widget class="QLabel" name="label_19">
+           <property name="text">
+            <string>Clipping plane</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="0">
+          <widget class="QLabel" name="label_17">
+           <property name="text">
+            <string>Fore:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1">
+          <widget class="QLineEdit" name="fore">
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="0">
+          <widget class="QLabel" name="label_18">
+           <property name="text">
+            <string>Aft:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="1">
+          <widget class="QLineEdit" name="aft">
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </item>
+      <item>
+       <widget class="QFrame" name="frame_3">
+        <property name="frameShape">
+         <enum>QFrame::StyledPanel</enum>
+        </property>
+        <property name="frameShadow">
+         <enum>QFrame::Raised</enum>
+        </property>
+        <layout class="QGridLayout" name="gridLayout_6">
+         <item row="0" column="0">
+          <widget class="QLabel" name="label_22">
+           <property name="text">
+            <string>Offset</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="0">
+          <widget class="QLabel" name="label_20">
+           <property name="text">
+            <string>Horiz:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1">
+          <widget class="QLineEdit" name="offsetHoriz">
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="0">
+          <widget class="QLabel" name="label_21">
+           <property name="text">
+            <string>Vert:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="2" column="1">
+          <widget class="QLineEdit" name="offsetVert">
+           <property name="maximumSize">
+            <size>
+             <width>60</width>
+             <height>16777215</height>
+            </size>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>viewDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>viewDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt
new file mode 100644
index 0000000..0cb2189
--- /dev/null
+++ b/src/util/CMakeLists.txt
@@ -0,0 +1,86 @@
+set(VERSION_FILE "${radiance_BINARY_DIR}/src/util/Version.c")
+add_custom_command(
+  OUTPUT "${VERSION_FILE}"
+  DEPENDS "${radiance_SOURCE_DIR}/src/util/VERSION"
+  COMMAND "${CMAKE_COMMAND}"
+  -DVERSION_OUT_FILE="${VERSION_FILE}"
+  -DVERSION_IN_FILE="${radiance_SOURCE_DIR}/src/util/VERSION"
+  -P "${radiance_SOURCE_DIR}/src/common/create_version.cmake"
+)
+
+add_executable(dctimestep dctimestep.c)
+target_link_libraries(dctimestep rtrad)
+
+add_executable(findglare findglare.c glareval.c glaresrc.c setscan.c)
+target_link_libraries(findglare rtrad)
+
+add_executable(getinfo getinfo.c)
+target_link_libraries(getinfo rtrad)
+
+add_executable(glarendx glarendx.c)
+target_link_libraries(glarendx rtrad)
+
+add_executable(rad rad.c)
+target_link_libraries(rad rtrad)
+if(WIN32)
+  set(netproc_SOURCES win_netproc.c)
+else()
+  set(netproc_SOURCES netproc.c)
+endif()
+add_executable(ranimate ranimate.c ${netproc_SOURCES})
+target_link_libraries(ranimate rtrad)
+
+add_executable(rpiece rpiece.c "${VERSION_FILE}")
+target_link_libraries(rpiece rtrad)
+
+add_executable(rtcontrib
+  rtcontrib.c "${VERSION_FILE}")
+target_link_libraries(rtcontrib rtrad)
+
+add_executable(vwrays vwrays.c)
+target_link_libraries(vwrays rtrad)
+
+add_executable(vwright vwright.c)
+target_link_libraries(vwright rtrad)
+
+#the next few libraries all need to include header files from the rt directory
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../rt)
+
+add_executable(ranimove ranimove.c ranimove1.c ranimove2.c)
+target_link_libraries(ranimove raycalls radiance rtrad)
+
+add_executable(rsensor rsensor.c)
+target_link_libraries(rsensor raycalls radiance rtrad)
+
+if(X11_FOUND)
+  add_executable(xglaresrc
+    xglaresrc.c ${CMAKE_CURRENT_SOURCE_DIR}/../common/x11findwind.c)
+  target_link_libraries(xglaresrc rtrad ${X11_LIBRARIES})
+  install(TARGETS xglaresrc RUNTIME DESTINATION bin)
+endif()
+
+find_library(LIB_RGL "rgl" DOC "Path to librgl")
+if(LIB_RGL)
+  #glrad needs to be able to include OpenGL headers
+  include_directories(${OPENGL_INCLUDE_DIR})
+
+  #check if we have SGIStereo.h
+  find_file(HAVE_SGISTEREO_H "SGIStereo.h" ${OPENGL_INCLUDE_DIR})
+  if(NOT HAVE_SGISTEREO_H)
+    add_definitions(-DNOSTEREO)
+  endif()
+
+  add_executable(glrad glrad.c)
+  target_link_libraries(glrad
+    rtrad ${LIB_RGL} ${OPENGL_LIBRARIES} ${X11_LIBRARIES})
+  install(TARGETS glrad RUNTIME DESTINATION bin)
+endif()
+
+install(TARGETS dctimestep findglare getinfo glarendx rad ranimate rpiece
+                rtcontrib vwrays vwright ranimove rsensor
+        RUNTIME DESTINATION bin)
+install(FILES objview.csh objpict.csh glare.csh dayfact.csh rlux.csh
+              raddepend.csh trad.wsh objline.csh compamb.csh vinfo.csh
+              genambpos.csh fieldcomb.csh genklemsamp.pl genskyvec.pl
+              genBSDF.pl tregsamp.dat
+        DESTINATION bin)
diff --git a/src/util/VERSION b/src/util/VERSION
new file mode 100644
index 0000000..45c32ae
--- /dev/null
+++ b/src/util/VERSION
@@ -0,0 +1 @@
+RADIANCE 4.1a
diff --git a/test/test data/model.oct b/test/test data/model.oct
new file mode 100644
index 0000000..d29e88b
Binary files /dev/null and b/test/test data/model.oct differ
diff --git a/test/test data/model.vp b/test/test data/model.vp
new file mode 100644
index 0000000..500e762
--- /dev/null
+++ b/test/test data/model.vp	
@@ -0,0 +1,3 @@
+rview -vp 0 36 -25 -vd -0.357771 -0.268328 0.894427 -vu 0 1 0 -vh 45 -vv 45 -x 800 -y 800
+rview -vp -3 36 -25 -vd -0.357771 -0.268328 0.894427 -vu 0 1 0 -vh 45 -vv 45 -x 800 -y 800
+rview -vp 8 36 -27 -vd -0.560723 -0.233635 0.794358 -vu 0 1 0 -vh 39.9 -vv 27.5 -x 1000 -y 676
diff --git a/welcome.txt b/welcome.txt
new file mode 100644
index 0000000..4eac764
--- /dev/null
+++ b/welcome.txt
@@ -0,0 +1,2 @@
+Welcome to Radiance!
+
