Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[Manta] r1985 - in trunk/scenes: . csafe csafe/CMake csafe/python csafe/src csafe/swig csafe/swig/CMake


Chronological Thread 
  • From: brownlee@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [Manta] r1985 - in trunk/scenes: . csafe csafe/CMake csafe/python csafe/src csafe/swig csafe/swig/CMake
  • Date: Wed, 9 Jan 2008 18:28:31 -0700 (MST)

Author: brownlee
Date: Wed Jan  9 18:28:28 2008
New Revision: 1985

Added:
   trunk/scenes/csafe/
   trunk/scenes/csafe/CMake/
   trunk/scenes/csafe/CMake/FindManta.cmake
   trunk/scenes/csafe/CMake/empty.depend.in
   trunk/scenes/csafe/CMake/make2cmake.py   (contents, props changed)
   trunk/scenes/csafe/CMake/sseTest.cc
   trunk/scenes/csafe/CMakeLists.txt
   trunk/scenes/csafe/python/
   trunk/scenes/csafe/python/Configuration.py
   trunk/scenes/csafe/python/Histogram.py
   trunk/scenes/csafe/python/HistogramGroup.py
   trunk/scenes/csafe/python/SceneInfo.py
   trunk/scenes/csafe/python/SceneMenus.py
   trunk/scenes/csafe/python/TransferF.py
   trunk/scenes/csafe/python/csafe.py
   trunk/scenes/csafe/python/csafe_demo.cfg
   trunk/scenes/csafe/src/
   trunk/scenes/csafe/src/CDGridSpheres.cc
   trunk/scenes/csafe/src/CDGridSpheres.h
   trunk/scenes/csafe/src/CDSWIGIFY.h
   trunk/scenes/csafe/src/CDTest.h
   trunk/scenes/csafe/src/SIMD.hxx
   trunk/scenes/csafe/swig/
   trunk/scenes/csafe/swig/CMake/
   trunk/scenes/csafe/swig/CMakeLists.txt
   trunk/scenes/csafe/swig/example.i
Modified:
   trunk/scenes/CMakeLists.txt
Log:
committing csafe demo into scenes/csafe

Modified: trunk/scenes/CMakeLists.txt
==============================================================================
--- trunk/scenes/CMakeLists.txt (original)
+++ trunk/scenes/CMakeLists.txt Wed Jan  9 18:28:28 2008
@@ -66,6 +66,16 @@
 ENDIF(SCENE_VOLUMETEST)
 ENDIF(FOUND_TEEM AND MANTA_SSE)
 
+IF(FOUND_TEEM AND MANTA_SSE AND BUILD_SWIG_INTERFACE)
+SET(SCENE_CSAFE 0 CACHE BOOL "csafe demo")
+IF(SCENE_CSAFE)
+   INCLUDE_DIRECTORIES(${TEEM_INCLUDE_DIRS})
+   SUBDIRS(csafe)
+#   ADD_LIBRARY(scene_volumeTest volumeTest.cc)
+#   TARGET_LINK_LIBRARIES
+ENDIF(SCENE_CSAFE)
+ENDIF(FOUND_TEEM AND MANTA_SSE AND BUILD_SWIG_INTERFACE)
+
 # octree isosurface
 SET(SCENE_OCTISOVOL 0 CACHE BOOL "octree isosurface")
 IF(SCENE_OCTISOVOL)

Added: trunk/scenes/csafe/CMake/FindManta.cmake
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/CMake/FindManta.cmake    Wed Jan  9 18:28:28 2008
@@ -0,0 +1,92 @@
+###############################################################################
+# This scripts prompts the user to set the variable MANTA_SOURCE_DIR and 
+# MANTA_BUILD_PREFIX. After this is done, the script sets variables:
+#
+# MANTA_INCLUDE               -- Paths containing Manta header files.
+# MANTA_TARGET_LINK_LIBRARIES -- List of Manta shared libraries.  (-l on 
link line)
+# MANTA_LINK_DIRECTORIES      -- Path containing shared libraries (-L on 
link line)
+#
+# Additionally several .cmake scripts from the Manta build are executed to 
+# insure a similar build environment will be used by the project.
+# 
+###############################################################################
+SET(MANTA_SOURCE_DIR ${CMAKE_SOURCE_DIR})
+SET(MANTA_BUILD_PREFIX ${CMAKE_SOURCE_DIR}/buildTigger)
+
+IF   (MANTA_SOURCE_DIR AND MANTA_BUILD_PREFIX)
+
+  # Set the include and link variables.
+  SET(MANTA_INCLUDE
+    ${MANTA_SOURCE_DIR}
+    ${MANTA_BUILD_PREFIX}/include
+    )
+  
+  SET(MANTA_TARGET_LINK_LIBRARIES
+    Manta_Factory
+    Manta_UserInterface
+    Manta_Engine
+    Manta_Model
+    Manta_Image
+    Manta_Interface
+    Manta_Core_XUtils
+    Manta_Core
+    About
+    )
+
+  SET(MANTA_LINK_DIRECTORIES
+    ${MANTA_BUILD_PREFIX}/lib
+    )
+
+
+  # Include Manta header files.
+  INCLUDE_DIRECTORIES(
+    ${MANTA_INCLUDE}
+    )
+  
+  # Include Manta library directory.
+  LINK_DIRECTORIES(
+    ${MANTA_LINK_DIRECTORIES}
+    )
+
+  # Initialize Python/SWIG.
+  SET(CMAKE_SWIG_OUTDIR ${LIBRARY_OUTPUT_PATH})
+  FIND_PATH(SWIG_DIR swig)
+  FIND_PACKAGE(SWIG)
+
+  # Important: Must use Manta's copy of UseSWIG.cmake
+  INCLUDE(${MANTA_SOURCE_DIR}/CMake/MantaUseSWIG.cmake)
+
+  FIND_PACKAGE(PythonLibs)
+  INCLUDE_DIRECTORIES(
+    ${PYTHON_INCLUDE_PATH}
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    )
+
+  # Load Manta macros.
+  INCLUDE(${MANTA_SOURCE_DIR}/CMake/Macros.cmake)
+
+  # Set flags based on the architecture we are on (no compiler stuff)
+  INCLUDE (${MANTA_SOURCE_DIR}/CMake/ConfigArchitecture.cmake)
+
+  # Determine information about the compiler
+  INCLUDE (${MANTA_SOURCE_DIR}/CMake/CompilerInfo.cmake)
+
+  # Set various options based on the build type.
+  INCLUDE (${MANTA_SOURCE_DIR}/CMake/BuildType.cmake)
+
+  # Check if the build supports SSE
+  INCLUDE (${MANTA_SOURCE_DIR}/CMake/CheckSSE.cmake)  
+
+  # Force compilation options for all code that includes Manta headers.
+  FORCE_ADD_FLAGS("-DSCI_NOPERSISTENT")
+
+
+# Otherwise prompt the user to enter the desired Manta build to use.
+ELSE (MANTA_SOURCE_DIR AND MANTA_BUILD_PREFIX)
+
+  SET(MANTA_SOURCE_DIR "" CACHE PATH "Directory Manta was checked out into.")
+  SET(MANTA_BUILD_PREFIX "" CACHE PATH "Build directory containing lib/ bin/ 
etc. sub-directories.")
+
+  MESSAGE(FATAL_ERROR "Manually set the paths MANTA_SOURCE_DIR and 
MANTA_BUILD_PREFIX")
+
+ENDIF(MANTA_SOURCE_DIR AND MANTA_BUILD_PREFIX)

Added: trunk/scenes/csafe/CMake/empty.depend.in
==============================================================================

Added: trunk/scenes/csafe/CMake/make2cmake.py
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/CMake/make2cmake.py      Wed Jan  9 18:28:28 2008
@@ -0,0 +1,30 @@
+#!/usr/bin/python
+
+import os,sys,string
+
+
+if __name__ == "__main__":
+    # Check the argument list size
+    if (len(sys.argv) < 3):
+        sys.stderr.write("USAGE: " + sys.argv[0] + " <input file> <output 
file>\n")
+        sys.exit(1)
+
+    infilename = sys.argv[1]
+    outfilename = sys.argv[2]
+
+    # U is the mode to open the file with universal newline support.
+    infile = open(infilename, "rU")
+    outfile = open(outfilename, "w")
+
+    # Now read the lines
+    lines = map( lambda x: string.strip(x, string.whitespace+"\\"),
+                 infile.readlines() )
+    infile.close()
+    
+    # Now write them
+    outfile.write("SET( MANTA_SWIG_DEPEND\n")
+    for l in lines[1:]:
+        outfile.write(l + "\n")
+    outfile.write(")\n")
+    outfile.close()
+    

Added: trunk/scenes/csafe/CMake/sseTest.cc
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/CMake/sseTest.cc Wed Jan  9 18:28:28 2008
@@ -0,0 +1,22 @@
+#include <emmintrin.h>
+
+static __m128 float_sse_var = _mm_set_ps1(1.f);
+static __m128i int_sse_var  = _mm_set1_epi32(2);
+
+#ifdef MANTA_TEST_GCC
+static __m128i gcc_guy = _mm_set1_epi64x( (long long)1 );
+#endif
+
+#ifdef MANTA_TEST_CAST
+static __m128i cast_float_to_int = _mm_castps_si128(float_sse_var);
+static __m128  cast_int_to_float = _mm_castsi128_ps(cast_float_to_int);
+static __m128d cast_float_to_double = _mm_castps_pd(float_sse_var);
+static __m128  cast_double_to_float = _mm_castpd_ps(cast_float_to_double);
+#endif
+
+int main()
+{
+  return 0;
+}
+
+

Added: trunk/scenes/csafe/CMakeLists.txt
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/CMakeLists.txt   Wed Jan  9 18:28:28 2008
@@ -0,0 +1,168 @@
+
+#
+#  For more information, please see: http://software.sci.utah.edu
+#
+#  The MIT License
+#
+#  Copyright (c) 2005-2006
+#  Scientific Computing and Imaging Institute, University of Utah
+#
+#  License for the specific language governing rights and limitations under
+#  Permission is hereby granted, free of charge, to any person obtaining a
+#  copy of this software and associated documentation files (the "Software"),
+#  to deal in the Software without restriction, including without limitation
+#  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#  and/or sell copies of the Software, and to permit persons to whom the
+#  Software is furnished to do so, subject to the following conditions:
+#
+#  The above copyright notice and this permission notice shall be included
+#  in all copies or substantial portions of the Software.
+#
+#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+#  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
MERCHANTABILITY,
+#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+#  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+#  DEALINGS IN THE SOFTWARE.
+#
+
+###############################################################################
+# Example Manta Project.
+# -- Links to Manta shared libraries.
+# -- Shows how to write Manta components and place them in a separate 
+#    shared library.
+# -- Shows how to create python wrappers for new components.
+# -- Shows how to write python scripts using the new components with Manta.
+# 
+# Abe Stephens
+#
+###############################################################################
+
+###############################################################################
+#
+# STEP ONE: CMake Options
+#
+
+PROJECT (Manta-project)
+
+# Project wide CMake options.
+SET(BUILD_SHARED_LIBS ON)
+SET(CMAKE_VERBOSE_MAKEFILE ON)
+
+# Set and hide output path options.
+SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib CACHE INTERNAL 
+  "Single output directory for building all libraries.")
+SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin CACHE INTERNAL 
+  "Single output directory for building all executables.")
+
+###############################################################################
+#
+# STEP TWO: Locate Manta.
+#
+# This script prompts the user to set the variable MANTA_SOURCE_DIR and 
+# MANTA_BUILD_PREFIX. After this is done, the script sets variables:
+#
+# MANTA_INCLUDE               -- Paths containing Manta header files.
+# MANTA_TARGET_LINK_LIBRARIES -- Path containing Manta shared libs.
+#
+# Additionally several .cmake scripts from the Manta build are executed to 
+# insure a similar build environment will be used by the project.
+INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/CMake/FindManta.cmake)
+#INCLUDE(${MANTA_SOURCE_DIR}/CMake/FindTeem.cmake)
+
+# If certain SCIRun classes are used from Manta it is necessary to define
+# SCI_NOPERSISTENT
+FORCE_ADD_FLAGS(CMAKE_CXX_FLAGS "-DSCI_NOPERSISTENT")
+###############################################################################
+#
+# STEP THREE: Add new code in shared lib.
+# 
+# It's important that new Manta components be compiled into a shared library 
+# so that python bindings may be created for them.
+
+# Include this project's source directory
+INCLUDE_DIRECTORIES(
+  ${CMAKE_CURRENT_SOURCE_DIR}/src
+  )
+#INCLUDE_DIRECTORIES( /scratch/cgribble/teem/linux.64/include )
+#INCLUDE_DIRECTORIES(/Users/scerenon/teem/build/include )
+
+# ADD YOUR OWN SOURCE CODE AND CHANGE LIBRARY NAME HERE.
+ADD_LIBRARY(Example
+#src/CDColorMap.cc
+#src/CDColorMap.h
+#src/CDColorMap2.cc
+#src/CDColorMap2.h
+#src/CDVol.cc
+#src/CDVol.h
+#src/CDVolSSE3.cc
+#src/CDVolSSE3.h
+#src/CDVolTest.cc
+#src/Colorimetry.cc
+#src/Colorimetry.h
+#src/ColorMap.cc
+#src/ColorMap.h
+#src/InhomogeneousParticipatingMedium.cc
+#src/InhomogeneousParticipatingMedium.h
+#src/Physics.cc
+#src/Physics.h
+#src/VolumeReader.cc
+#src/VolumeReader.h
+src/CDSWIGIFY.h
+#src/ExampleTexture.cc
+#src/ExampleTexture.h
+src/CDTest.h
+#src/ParticleCGT.h
+#src/ParticleCGT.cc
+src/CDGridSpheres.cc
+src/CDGridSpheres.h
+)
+
+#ADD_LIBRARY(sphereTest
+#src/sphereTest.cc
+#)
+
+#ADD_LIBRARY(volTest
+#src/CDColorMap.cc
+#src/CDColorMap.h
+#src/CDColorMap2.cc
+#src/CDColorMap2.h
+#src/CDVolSSE3.cc
+#src/CDVolSSE3.h
+#src/CDVolTest.cc
+#src/ParticleCGT.h
+#src/ParticleCGT.cc
+#src/CDGridSpheres.h
+#src/CDGridSpheres.cc
+#)
+
+# CHANGE THE NAME OF YOUR LIBRARY HERE.
+TARGET_LINK_LIBRARIES(Example
+  ${MANTA_TARGET_LINK_LIBRARIES}
+  )
+#TARGET_LINK_LIBRARIES(sphereTest
+#  ${MANTA_TARGET_LINK_LIBRARIES}
+#  )
+#TARGET_LINK_LIBRARIES(volTest
+#  ${MANTA_TARGET_LINK_LIBRARIES}
+#  )
+
+###############################################################################
+#
+# STEP FOUR: Create Python bindings for shared library.
+#
+# See swig/CMakeLists.txt
+#  
+
+SUBDIRS(
+  swig
+  )
+
+# Output a helper script for setting up path variables.
+FILE(WRITE ${CMAKE_BINARY_DIR}/bin/pythonpath.csh
+  "setenv PYTHONPATH 
${MANTA_SOURCE_DIR}/SwigInterface:${MANTA_LINK_DIRECTORIES}:${CMAKE_BINARY_DIR}/lib\n\n")
+FILE(WRITE ${CMAKE_BINARY_DIR}/bin/pythonpath.sh
+  "export 
PYTHONPATH=${MANTA_SOURCE_DIR}/SwigInterface:${MANTA_LINK_DIRECTORIES}:${CMAKE_BINARY_DIR}/lib\n\n")
+
+

Added: trunk/scenes/csafe/python/Configuration.py
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/python/Configuration.py  Wed Jan  9 18:28:28 2008
@@ -0,0 +1,159 @@
+
+import sys, os, time, traceback, types
+import wx
+import SceneInfo
+import Histogram
+import TransferF
+import wxManta
+from example import *
+from manta import *
+
+def WriteConfiguration(scene, filename):
+       f = open(filename, 'w')
+       ts = scene.frame.transferFunctions
+       for i in range(len(ts)):
+               t = ts[i]
+               f.write('[Transfer Function]\n')
+               f.write(t.label+'\n')
+               f.write(str(t.id)+'\n')
+               f.write(str(len(t.colors))+'\n')
+               for j in range(len(t.colors)):
+                       c = t.colors[j]
+                       f.write(str(c[0])+' '+str(c[1])+' '+str(c[2])+' 
'+str(c[3])+' '+str(c[4])+'\n')
+               f.write('\n\n')
+       histoGroups = scene.frame.histoGroups
+       for i in range(len(histoGroups)):
+               h = histoGroups[i]
+               f.write('[Histogram]\n')
+               f.write(h.title+'\n')
+               f.write(str(h.varIndex)+'\n')
+               f.write(str(h.group)+'\n')
+               f.write(str(h.histogram.zoomDMin)+' 
'+str(h.histogram.zoomDMax)+'\n')
+               f.write(str(h.dataMin)+' '+str(h.dataMax)+'\n')
+               f.write(str(h.histogram.cropDMin)+' 
'+str(h.histogram.cropDMax)+'\n')
+               f.write(str(h.transferFID)+'\n')
+               f.write('\n\n')
+       f.write('[Scene Properties]\n')
+       f.write(str(scene.duration)+'\n')
+       f.write(str(scene.ridx)+'\n')
+       f.write(str(scene.radius)+'\n')
+       f.write(str(int(scene.cidx))+'\n')
+       f.write(str(scene.numThreads)+'\n')
+       f.write(str(len(scene.nrrdFiles2))+'\n')
+       for i in range(len(scene.nrrdFiles2)):
+               f.write(scene.nrrdFiles2[i]+'\n')
+       print scene.nrrdFiles
+       print len(scene.nrrdFiles)
+       f.write(str(len(scene.nrrdFiles))+'\n')
+       for i in range(len(scene.nrrdFiles)):
+               f.write(scene.nrrdFiles[i]+'\n')
+       f.close()
+
+def ReadConfiguration(scene, filename):
+       f = open(filename, 'r')
+       
+       ###clear old values
+       #for i in range(len(scene.frame.transferFunctions)):
+       #       scene.frame.transferFunctions[i].Destroy()
+       scene.frame.transferFunctions = []
+       for i in range(len(scene.frame.histoGroups)):
+               scene.frame.histoGroups[i].Destroy()
+       scene.frame.histoGroups = []
+       scene.nrrdFiles = []
+       scene.nrrdFiles2 = []
+
+       ###read in new values
+       lines = f.readlines()
+       for i in range(len(lines)):
+               ##### Transfer Function####
+               if lines[i].find("[Transfer Function]") != -1:
+                       i+=1
+                       name = lines[i].strip()
+                       print name
+                       i+=1
+                       id = int(lines[i].strip())
+                       i+=1
+                       num = int(lines[i].strip())
+                       colors = []
+                       slices = manta_new(vector_ColorSlice())
+                       for j in range(num):
+                               i+=1
+                               line = lines[i].split()
+                               pos = float(line[0])
+                               r = float(line[1])
+                               g = float(line[2])
+                               b = float(line[3])
+                               a = float(line[4])
+                               #colors.append( (pos, r, g, b, a) )
+                               print pos
+                               slices.push_back(ColorSlice(pos, 
RGBAColor(Color(RGBColor(r,g,b)), a)))
+
+                       
scene.frame.transferFunctions.append(TransferF.TransferF(scene.frame, colors, 
id, name, manta_new(RGBAColorMap(slices))))
+               #### Histogram ####
+               elif lines[i].find("[Histogram]") != -1:
+                       i +=1
+                       name = lines[i].strip()
+                       i += 1
+                       index = int(lines[i].strip())
+                       i += 1
+                       group = int(lines[i].strip())
+                       i += 1
+                       zoomInto = lines[i].split()
+                       zoomIntoMin = float(zoomInto[0])
+                       zoomIntoMax = float(zoomInto[1])
+                       i+=1
+                       cropDisplay = lines[i].split()
+                       cropDisplayMin = float(cropDisplay[0])
+                       cropDisplayMax = float(cropDisplay[1])
+                       i+=1
+                       cropColor = lines[i].split()
+                       cropColorMin = float(cropColor[0])
+                       cropColorMax = float(cropColor[1])
+                       i+=1
+                       transferFID = int(lines[i].strip())
+                       histValues1 = []
+                       for i in range(100):
+                               histValues1.append(5.0)
+                       histoGroup = Histogram.HistogramGroup(scene.frame, 
histValues1, cropColorMin, cropColorMax, 300.0, 40.0, 
scene.frame.transferFunctions[transferFID], scene.frame.tPanel, scene, 
transferFID, name)
+                       histoGroup.SetBackgroundColour(wx.Colour(90,90,90))
+                       histoGroup.group = group
+                       scene.frame.histoGroups.append(histoGroup)
+                       #TODO: read these in
+                       if (group == 1):
+                               
scene.test.setVolCMap(scene.frame.transferFunctions[transferFID].cmap)
+                               
scene.frame.transferFunctions[transferFID].cmap.scaleAlphas(.00125)
+                       #if (group == 0):
+                               #scene.test.setClipMinMax(index, 
cropDisplayMin, cropDisplayMax)
+                               #scene.test.setSphereCMinMax(index, 
cropColorMin, cropColorMax)
+                       #else:
+                       #       scene.test.setVolCMinMax(cropColorMin, 
cropColorMax)
+               ##### Scene Properties ####
+               elif lines[i].find("[Scene Properties]") != -1:
+                       i+=1
+                       scene.duration = float(lines[i].strip())        
+                       scene.test.setDuration(scene.duration)
+                       i+=1
+                       scene.ridx = int(lines[i].strip())
+                       scene.test.setRidx(scene.ridx)
+                       i+=1
+                       scene.radius = float(lines[i].strip())
+                       scene.test.setRadius(scene.radius)
+                       i+=1
+                       scene.cidx = int(lines[i].strip())
+                       scene.test.setCidx(scene.cidx)
+                       i+=1
+                       scene.numThreads = int(lines[i].strip())
+                       scene.engine.changeNumWorkers(scene.numThreads)
+                       print "setting numWorkers to: " + 
str(scene.numThreads)
+                       i+=1
+                       numVol = int(lines[i].strip())
+                       for j in range(numVol):
+                               i+=1
+                               scene.nrrdFiles2.append(lines[i].strip())
+                       i+=1
+                       numSphere = int(lines[i].strip())
+                       for j in range(numSphere):
+                               i+=1
+                               scene.nrrdFiles.append(lines[i].strip())
+       scene.frame.LayoutWindow()
+       print "Done reading Configuration file"

Added: trunk/scenes/csafe/python/Histogram.py
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/python/Histogram.py      Wed Jan  9 18:28:28 2008
@@ -0,0 +1,694 @@
+""" File: Histogram.py
+Description:  histogram control, and histogramGroup which is a histogram 
with various controls
+
+"""
+
+import sys, os, time, traceback, types
+import wx
+import wx.html
+import TransferF
+import wx.lib.foldpanelbar
+
+
+data = []
+numBuckets = 1
+hMin = 0.0
+hMax = 1.0
+dMin = 0.0
+dMax = 0.0
+lines = []
+width = 10.0
+height = 20.0
+barWidth = 0.0
+colors = []
+
+def opj(path):
+    #copied from demo.py
+    """Convert paths to the platform-specific separator"""
+    str = apply(os.path.join, tuple(path.split('/')))
+    # HACK: on Linux, a leading / gets lost...
+    if path.startswith('/'):
+        str = '/' + str
+    return str
+
+class HistogramPanel(wx.Panel):
+    def __init__(self, parent,histValues, dataMin, dataMax, width, height, 
transferF, scene, varIndex):
+       self.scene = scene
+       self.varIndex = varIndex
+        self.paddingW = 20.0
+        self.paddingH = 15.0
+        wx.Panel.__init__(self, parent, -1, (0, 0) , (width+self.paddingW, 
height+self.paddingH) )
+        
+       self.dragging = False
+        self.selecting = False
+        self.draggingLeft = False
+        self.draggingRight = False
+        self.dragWidth = 1.0
+        self.cropMin = 0.0  #selected region from [0,1]
+        self.cropMax = 1.0  
+       if (varIndex == 3):  #TODO: take this out!
+               self.cropMin = -0.5
+               self.cropMax = 1.5;
+        self.colorMin = -99999.0
+        self.colorMax = 99999.0
+        self.dMin = dataMin
+       self.dMax = dataMax  #the min and max of displayed data
+        self.zoomDMin = dataMin #min data value of data to display (may not 
be an actual value contianed in data)
+        self.zoomDMax = dataMax #max data value of data to display (may not 
be an actual value contianed in data)
+        self.absoluteDMin = self.dMin  #absolute min of the data
+        self.absoluteDMax = self.dMax
+       self.zooms = []
+        wx.EVT_PAINT(self, self.OnPaint)
+        self.transferF = transferF
+        self.SetValues(histValues, len(histValues), width, height)
+        self.colorDMin = self.dMin
+        self.colorDMax = self.dMax
+        self.Update()
+        self.zoomDMin = self.dMin
+        self.zoomDMax = self.dMax
+        self.Bind(wx.EVT_LEFT_DOWN, self.OnClick)
+        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
+        self.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
+        self.Bind(wx.EVT_MOTION, self.OnMotion)
+        self.Bind( wx.EVT_MOUSEWHEEL, self.OnMouseWheel )
+        self.SetBackgroundColour(wx.Colour(90,90,90))
+       #self.SetForegroundColour(wx.Colour(255,255,255))
+       self.parent = parent
+       
+    def SetHistValues(self, histValues, dataMin, dataMax):
+       self.colorMin = -99999.0
+        self.colorMax = 99999.0
+        self.dMin = dataMin
+        self.dMax = dataMax  #the min and max of displayed data
+        self.zoomDMin = dataMin #min data value of data to display (may not 
be an actual value contianed in data)
+        self.zoomDMax = dataMax #max data value of data to display (may not 
be an actual value contianed in data)
+        self.absoluteDMin = self.dMin  #absolute min of the data
+        self.absoluteDMax = self.dMax
+       self.colorDMin = self.dMin
+        self.colorDMax = self.dMax
+        self.zoomDMin = self.dMin
+        self.zoomDMax = self.dMax
+       self.data = histValues
+       self.numBuckets = len(histValues)
+       self.Update()
+
+    def OnMouseWheel(self, evt):
+        pos = float(evt.GetPosition().x - 
self.paddingW/2.0)/float(self.width)
+        delta = evt.GetWheelDelta()
+        rot = evt.GetWheelRotation()/delta
+        #zoom in if rot > 0, out if ro < 0
+        if (rot > 0):
+            zoomAmount = 0.75 # the smaller the more zooming
+            self.zooms.append( (self.zoomDMin, self.zoomDMax))
+            
+            dWidth = self.zoomDMax - self.zoomDMin
+            self.zoomDMax = (pos + zoomAmount*(1.0 - pos))*dWidth + 
self.zoomDMin
+            self.zoomDMin = (pos - zoomAmount*pos)*dWidth + self.zoomDMin
+            tempMin = self.cropDMin
+            tempMax = self.cropDMax
+            self.Update()
+            self.cropDMin = tempMin
+            self.cropDMax = tempMax
+            self.UpdateCropToD()
+        if (rot < 0):
+            self.ZoomOut()
+    
+    def ZoomIn(self):
+        self.zooms.append( (self.zoomDMin, self.zoomDMax))
+        self.zoomDMin = self.cropDMin
+        self.zoomDMax = self.cropDMax
+        tempMin = self.cropDMin
+        tempMax = self.cropDMax
+        self.Update()
+        self.cropDMin = tempMin
+        self.cropDMax = tempMax
+        self.UpdateCropToD()
+        
+    def ZoomOut(self):
+        if (len(self.zooms)) > 0:
+            zoom = self.zooms.pop()
+            self.zoomDMin = zoom[0]
+            self.zoomDMax = zoom[1]
+            tempMin = self.cropDMin
+            tempMax = self.cropDMax
+            self.Update()
+            self.cropDMin = tempMin
+            self.cropDMax = tempMax
+            self.UpdateCropToD()
+       
+    def OnClick(self, evt):
+        pos = float(evt.GetPosition().x - 
self.paddingW/2.0)/float(self.width)
+        sideLen = 0.05
+        if (abs(pos - float(self.cropMin)) <= float(sideLen)) and (abs(pos - 
float(self.cropMin)) < abs(pos - float(self.cropMax))):
+            self.draggingLeft = True
+            self.draggingRight = False
+            self.cropMin = pos
+        elif (abs(pos - float(self.cropMax)) <= float(sideLen)):
+            self.draggingLeft = False
+            self.draggingRight = True
+            self.cropMax = pos
+        elif (pos >= self.cropMin and pos <= self.cropMax):
+            self.dragging = True
+            self.dragWidth = abs((float(self.cropMax) - float(self.cropMin)))
+        else: #selecting
+            self.selecting = True
+            self.draggingLeft = False
+            self.draggingRight = False
+            self.cropMin = pos
+        self.UpdateDMinMax()
+        print "clicked"
+    
+    def OnLeftUp(self, evt):
+        pos = float(evt.GetPosition().x - 
self.paddingW/2.0)/float(self.width)
+            
+        if self.cropMin > self.cropMax:
+            temp = self.cropMax
+            self.cropMax = self.cropMin
+            self.cropMin = temp
+            self.UpdateDMinMax()
+            self.Refresh()
+            
+        self.dragging = False
+        self.selecting = False
+        self.draggingLeft = False
+        self.draggingRight = False
+       #self.scene.test.setClipMinMax(self.varIndex, self.cropDMin, 
self.cropDMax)
+    
+    def OnRightClick(self, evt):
+        print "right"        
+        
+    def OnMotion(self, evt):
+        #pdc = wx.PaintDC(self)
+        #pdc.Clear()
+        #dc = wx.GCDC(pdc)
+        pos = float(evt.GetPosition().x - 
self.paddingW/2.0)/float(self.width)
+        if self.selecting == True:
+            self.cropMax = pos
+            self.UpdateDMinMax()
+            self.Refresh()
+        if self.dragging == True:
+            cropWidth = self.dragWidth
+            self.cropMin = pos - cropWidth/2.0
+            self.cropMax = pos + cropWidth/2.0
+            if self.cropMin < 0.0:
+                self.cropMin = 0
+            if self.cropMax > 1.0:
+                self.cropMax = 1.0
+            self.UpdateDMinMax()
+            self.Refresh()
+        if self.draggingLeft == True:
+            self.cropMin = pos
+            self.UpdateDMinMax()
+            self.Refresh()
+        elif self.draggingRight == True:
+            self.cropMax = pos
+            self.UpdateDMinMax()
+            self.Refresh()
+       if (self.parent.group != 1):  #if not the volumedata
+              self.scene.test.setClipMinMax(self.varIndex, self.cropDMin, 
self.cropDMax)    
+        #max = float(evt.GetPosition().x)/float(self.width)
+        #dc.SetBrush(wx.Brush( (0,0,0,56) ) )
+        #dc.SetPen(wx.Pen("BLACK", 0) )
+        #cropWidth = abs((float(max) - 
float(self.cropMin))*float(self.width))
+        #dc.DrawRectangle(float(self.cropMin)*float(self.width) , 0, 
cropWidth, self.height)
+        #self.Refresh()
+        
+       
+    def SetValues(self, datavalues, nbuckets, widthn, heightn):
+        self.data = datavalues
+        self.numBuckets = nbuckets
+        self.width = widthn
+        self.height = heightn
+        
+    def SendValues(self, zoomMin, zoomMax, cropMin, cropMax, colorMin, 
colorMax):  #sent from MeasurementsFrame
+        #print "values arrived"
+        self.zooms.append( (self.zoomDMin, self.zoomDMax))
+        self.zoomDMin = zoomMin
+        self.zoomDMax = zoomMax
+        self.colorDMin = colorMin
+        self.colorDMax = colorMax
+        self.Update()
+        min = 0
+        max = 0
+        dWidth = self.dMax - self.dMin
+        self.cropMin = (cropMin - self.dMin)/dWidth
+        self.cropMax = (cropMax - self.dMin)/dWidth
+        if self.cropDMin < 0.0:
+            self.cropDMin = 0.0
+        if self.cropDMin > 1.0:
+            self.cropDMin = 1.0
+        if self.cropDMax < 0.0:
+            self.cropDMax = 0.0
+        if self.cropDMax > 1.0:
+            self.cropDMax = 1.0
+            
+        self.cropDMin = self.cropMin*dWidth + self.dMin #cropped data min
+        self.cropDMax = self.cropMax*dWidth + self.dMin #cropped data max
+       if (self.parent.group == 0):
+               self.scene.test.setSphereCMinMax(self.varIndex, colorMin, 
colorMax)
+       else:
+               self.scene.test.setVolCMinMax(colorMin, colorMax)
+        
+        
+    #update dMin/Max, cropMin/Max based on zoomDMin/Max    
+    def UpdateDMinMax(self):
+       absoluteDWidth = self.absoluteDMax - self.absoluteDMin
+       minBucket = int(float(self.zoomDMin/absoluteDWidth)*self.numBuckets )
+       maxBucket = int(float(self.zoomDMax/absoluteDWidth)*self.numBuckets)
+        if (self.numBuckets > 0):
+          self.dMin = minBucket*(absoluteDWidth/self.numBuckets)
+          self.dMax = maxBucket*(absoluteDWidth/self.numBuckets)
+       else:
+          self.dMin = self.dMax = 0.0
+       dWidth = self.dMax - self.dMin
+        self.cropDMin = self.cropMin*dWidth + self.dMin #cropped data min
+        self.cropDMax = self.cropMax*dWidth + self.dMin #cropped data max
+        
+    def UpdateCropToD(self):
+        dWidth = self.dMax - self.dMin
+        self.cropMin = (self.cropDMin - self.dMin)/dWidth
+        self.cropMax = (self.cropDMax - self.dMin)/dWidth
+        
+        
+    def Update(self):
+
+        self.lines = []
+        width = self.width
+        height = self.height
+        
+        self.UpdateDMinMax()
+        
+        data = self.data
+        
+        numBuckets = self.numBuckets
+        dMin = self.dMin
+        dMax = self.dMax
+       absoluteDMin = self.absoluteDMin
+       absoluteDMax = self.absoluteDMax
+       absWidth = absoluteDMax - absoluteDMin
+       dWidth = dMax - dMin        
+
+     #   lines.append( (0,0, 50, 50) )
+        #function(lines, range(0.0, 1.0))
+        start = float((dMin - absoluteDMin)/absWidth*float(numBuckets))
+        if (numBuckets > 0):
+          step = float((dWidth/absWidth)/float(width))*float(numBuckets)
+       else:
+          step = 0.0
+        end = start + step
+        
+       if (numBuckets > 0):
+           barWidth = self.barWidth = float(width)/float(numBuckets)
+       else:
+          barWidth = self.barWidth = float(width)
+        #print barWidth
+        
+        blx = 0.0 + barWidth/2.0 + self.paddingW/2.0 # bottom left x
+        bly = 0.0 + height - barWidth/2.0
+        
+        hMin = 99999.0 #min and max frequencies
+        hMax = -999999.0
+    
+        
+        #get the minimum and maximum frequencies in displayed range
+        #for i in range(int(numBuckets)):
+ #           frequency = 1.0
+           # filter(lines, range(start, end) )
+           # frequency = len( [x for x in data if (x >= start and x <= end)] 
)
+#            print '%f %f %f' % (frequency, start, end)
+        #   frequency = data[i]
+    #        if frequency < hMin:
+    #            hMin = frequency
+     #       if frequency > hMax:
+     #           hMax = frequency
+            #start += step
+            #end += step
+                
+        colorWidth = float(self.colorDMax - self.colorDMin)
+       croppedHeightValues = int(width)*[0]
+        for i in range(0,width):
+            #frequency = len( [x for x in data if (x >= start and x <= end)] 
)
+           for j in range(int(start), int(end)):
+               croppedHeightValues[i] += data[j]
+           start += step
+           end += step
+       
+       for i in range(0, width):
+           frequency = croppedHeightValues[i]
+           if frequency < hMin:
+               hMin = frequency
+           if frequency > hMax:
+               hMax = frequency
+       if hMax > hMin:
+           for i in range(0, width):
+                frequency = croppedHeightValues[i]
+               barHeightNorm = float(frequency)/float(hMax)
+               #print str(frequency) + " " + str(barHeightNorm)
+                if float(barHeightNorm) > 1.0:
+                    print "error"
+ #               print '%f %f %f %f' % (frequency, start, end, barHeightNorm)
+                colorPos = (( (float(i)/width)*(absoluteDMax-absoluteDMin)) 
+ absoluteDMin- self.colorDMin)/colorWidth
+               #print colorPos
+               color = self.transferF.GetColor(colorPos)
+                self.lines.append( (color, ( blx + i, bly, blx + i, (bly - 
barHeightNorm*height) ) ) )
+        self.Refresh()
+       
+    def OnPaint(self, evt=None):
+        pdc = wx.PaintDC(self)
+        #pdc.Clear()
+       try:
+          dc = wx.GCDC(pdc)
+       except:
+         dc = pdc
+        #gc = wx.GraphicsContext.Create(dc)       
+        dc.SetPen(wx.Pen("BLACK", 1) )
+        #dc.DrawRectangle( 0, 0, width, height) 
+        
+        self.DrawLines(dc)
+        try:
+         brushColor = wx.Colour(0,0,0,56)
+       except:
+         brushColor = wx.Colour(0,0,0)
+        dc.SetBrush(wx.Brush( brushColor ) )
+        dc.SetPen(wx.Pen("BLACK", 0) )
+        cropMin = self.cropMin
+        cropMax = self.cropMax
+        if cropMin < 0.0:
+            cropMin = 0.0
+        if cropMax > 1.0:
+            cropMax = 1.0
+        cropWidth = (float(cropMax) - float(cropMin))*float(self.width)
+        dc.DrawRectangle(float(cropMin)*float(self.width) + 
self.paddingW/2.0 , 0, cropWidth, self.height)
+        
+        #draw cropping texta
+       dc.SetTextForeground(wx.Colour(255,255,255))
+       self.SetForegroundColour(wx.Colour(255,0,0))
+       dc.SetPen(wx.Pen(wx.Colour(255,255,255), 1))
+       dc.SetBrush(wx.Brush(wx.Colour(255,255,255)))
+        dc.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.NORMAL, 
wx.FONTWEIGHT_BOLD))
+        string = str(round(self.cropDMin, 2))
+        extent = dc.GetTextExtent(string)
+        dc.DrawTextPoint(string, (cropMin*self.width - extent[0]/2.0 + 
self.paddingW/2.0,self.height))
+        string = str(round(self.cropDMax, 2))
+        extent = dc.GetTextExtent(string)
+        dc.DrawTextPoint(string, (cropMax*self.width - extent[0]/2.0 + 
self.paddingW/2.0,self.height))
+        
+        #draw min/max text
+        textHeight = extent[1]
+        string = str(round(self.dMin, 2))
+        extent = dc.GetTextExtent(string)
+        dc.DrawTextPoint(string, (self.paddingW/2.0 - 
extent[0]/2.0,self.height + textHeight - 4.0))
+        string = str(round(self.dMax, 2))
+        extent = dc.GetTextExtent(string)
+        dc.DrawTextPoint(string, (self.paddingW/2.0 + self.width - 
extent[0]/2.0,self.height + textHeight  - 4.0))
+        
+    def DrawLines(self, dc):
+
+        #dc.BeginDrawing()
+        for i in range(0, len(self.lines)):
+            #pos = float(i)/float(len(self.lines))
+            a = self.lines[i][0][3]*255.0
+            r = self.lines[i][0][0]*255.0
+            g = self.lines[i][0][1]*255.0
+            b = self.lines[i][0][2]*255.0
+           try:
+               penColor = wx.Colour(r,g,b,a)
+           except:
+               penColor = wx.Colour(r,g,b)
+            dc.SetPen(wx.Pen(penColor, self.barWidth))
+            dc.DrawLine( self.lines[i][1][0], self.lines[i][1][1], 
self.lines[i][1][2], self.lines[i][1][3])
+        
+        #dc.DrawLineList(lines)
+        #dc.DrawLine(0,0,50,50)
+        #dc.EndDrawing()

+
+###################################################################
+####################### Histogram Group ###########################
+###################################################################       
+class HistogramGroup(wx.Panel):
+    def __init__(self, parent, histValues, dataMin, dataMax, width, height, 
transferF, transferFPanel, scene, varIndex, title = "No Name"):
+        wx.Panel.__init__(self, parent, -1, (0, 0) , (width, height) )
+       self.scene = scene
+       self.varIndex = varIndex
+        self.transferF = transferF
+       self.transferFID = transferF.id
+        self.transferFPanel = transferFPanel
+        self.title = title
+        self.parent = parent
+        self.datavalues = histValues
+       self.dataMin = dataMin
+       self.dataMax = dataMax
+        self.numbuckets = len(histValues)
+        self.width = width
+        self.height = height
+       self.group = 0 #0 = spheres, 1 = volume
+        
+        self.CreateElements() 
+    
+    def SetValues(self, histValues, dataMin, dataMax): 
+       self.dataMin = dataMin
+       self.dataMax = dataMax
+       self.datavalues = histValues
+       self.histogram.SetHistValues(histValues, dataMin, dataMax)
+       
+    def SetCMinMax(self, min, max):
+       zoomMin = self.histogram.zoomDMin
+       zoomMax = self.histogram.zoomDMax
+       cropMin = self.histogram.cropDMin
+       cropMax = self.histogram.cropDMax
+       self.histogram.SendValues(zoomMin, zoomMax, cropMin, cropMax, 
float(min), float(max))
+    
+    def OnClick(self, evt):
+        print "clicked histogro"
+        
+    def CreateElements(self):
+        self.vs = vs = wx.BoxSizer( wx.VERTICAL )
+        box1_title = wx.StaticBox( self, -1, self.title )
+        self.histogram = HistogramPanel(self, self.datavalues, self.dataMin, 
self.dataMax, self.width, self.height, self.transferF, self.scene, 
self.varIndex)
+        self.box1 = box1 = wx.StaticBoxSizer( box1_title, wx.VERTICAL )
+        #grid1 = wx.FlexGridSizer( 2, 2, 0, 0 )
+        gbs = wx.GridBagSizer(1,3)
+        self.sizer = box1
+        
+        #wx.EVT_LEFT_DOWN(self.histogram, self.OnClick)
+        #self.SetFocus()
+      #  self.histogram.Bind(wx.EVT_LEFT_DOWN, self.OnClick)
+        
+        gbs.Add(self.histogram,(0, 0), (2, 2) )
+        if self.scene.histogramBMPLoaded == False:
+               self.scene.bmpVis = wx.Bitmap(opj('images/eye.png.8x8'))
+               self.scene.bmpColor = wx.Bitmap(opj('images/color.png.8x8'))
+               self.scene.bmpRuler = wx.Bitmap(opj('images/ruler.png.8x8'))
+                       self.scene.bmpZoomIn = 
wx.Bitmap(opj('images/zoomin.png.8x8'))
+               self.scene.bmpZoomOut = 
wx.Bitmap(opj('images/zoomout.png.8x8'))
+               self.scene.histogramBMPLoaded = True
+       
+       self.bmpVis = self.scene.bmpVis
+       self.bmpColor = self.scene.bmpColor
+       self.bmpRuler = self.scene.bmpRuler
+       self.bmpZoomIn = self.scene.bmpZoomIn
+       self.bmpZoomOut = self.scene.bmpZoomOut
+
+        size = 10
+        visibilityB = wx.BitmapButton(self, -1, self.bmpVis, (0,0), 
style=wx.NO_BORDER)
+        self.visibilityB = visibilityB
+        colorB = wx.BitmapButton(self, -1, self.bmpColor, (0,0), 
style=wx.NO_BORDER)
+        self.colorB = colorB
+        self.rulerB = wx.BitmapButton(self, -1, self.bmpRuler, (0,0), 
style=wx.NO_BORDER)
+        self.zoomInB = wx.BitmapButton(self, -1, self.bmpZoomIn, (0,0), 
style=wx.NO_BORDER)
+        self.zoomOutB = wx.BitmapButton(self, -1, self.bmpZoomOut, (0,0), 
style=wx.NO_BORDER)
+        
+        self.Bind(wx.EVT_BUTTON, self.OnClickVisible, visibilityB)
+        self.Bind(wx.EVT_BUTTON, self.OnClickColor, colorB)
+        self.Bind(wx.EVT_BUTTON, self.OnClickMeasurements, self.rulerB)
+        self.Bind(wx.EVT_BUTTON, self.OnClickZoomIn, self.zoomInB)
+        self.Bind(wx.EVT_BUTTON, self.OnClickZoomOut, self.zoomOutB)
+        
+        
+        vs2 = wx.BoxSizer( wx.VERTICAL )
+        #vs3 = wx.BoxSizer( wx.VERTICAL )
+        #box1_title2 = wx.StaticBox( self, -1, "" )
+        #box2 = wx.StaticBoxSizer( box1_title2, wx.VERTICAL )
+        vs2.Add( visibilityB, wx.ALIGN_CENTRE|wx.ALL, 0, 10)
+        space = (0,0)
+        vs2.AddSpacer(space)
+        vs2.Add( colorB, wx.ALIGN_CENTRE|wx.ALL, 0, 10)
+        vs2.AddSpacer(space)
+        vs2.Add( self.rulerB)
+        vs2.AddSpacer(space)
+       vs3 = wx.BoxSizer(wx.VERTICAL)
+        vs3.Add( self.zoomInB)
+        vs3.AddSpacer(space)
+        vs3.Add( self.zoomOutB )
+        vs2.Layout()
+       vs3.Layout()
+
+       vsH = wx.BoxSizer(wx.HORIZONTAL)
+       vsH.Add(vs2, wx.ALIGN_CENTER|wx.ALL,0)
+       vsH.Add(vs3, wx.ALIGN_CENTER|wx.ALL,0)  
+        #vs3.Layout()
+        gbs.Add(vsH, (0, 2), (2, 1))
+        #gbs.Add(vs3, (0, 3), (2, 1))
+        
+        
+        gbs.Layout()
+        
+        box1.Add( gbs, 0, wx.ALIGN_CENTRE|wx.ALL, 0 )
+        self.box1 = box1
+        vs.Add( box1, 0, wx.ALIGN_CENTRE|wx.ALL, 0 )
+        #vs.Add(grid1, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
+        self.SetSizer( vs )
+        vs.Fit( self )
+        self.visible = True
+    
+    def OnClickMeasurements(self, evt):
+        win = MeasurementsFrame(self.histogram, -1, self.title + " 
Measurements",  self.histogram.zoomDMin, self.histogram.zoomDMax, 
self.histogram.cropDMin, self.histogram.cropDMax, self.histogram.colorDMin, 
self.histogram.colorDMax)
+        win.Show(True)
+        
+    def OnClickZoomIn(self, evt):
+        self.histogram.ZoomIn()
+        
+    def OnClickZoomOut(self, evt):
+        self.histogram.ZoomOut()
+        
+    def Update(self):
+        self.histogram.Update()
+        
+    def OnClickColor(self, evt):
+        self.transferFPanel.SetLabel(self.transferF.GetLabel())
+        self.transferFPanel.SetTransferF(self.transferF)
+        self.transferFPanel.SetUpdateFunction(self.Update())
+        self.transferFPanel.transferFPanel.SetHistogram(self.histogram)
+       if self.varIndex != self.scene.volVar:
+               self.scene.test.setCidx(self.varIndex)        
+               if (self.transferF != None):
+                       self.scene.test.setSphereCMap(self.transferF.cmap)
+
+    def OnClickVisible(self, evt):
+        if self.visible:
+            self.sizer.ShowItems(False)
+            #self.sizer.Show(self.visibilityB, True, True)
+            #self.sizer.Show(self.historgram, False, True)
+            #self.sizer.Show(self.colorB, False, True)
+            self.visible = False
+            box1_title = wx.StaticBox( self, -1, self.title )
+            box = wx.StaticBoxSizer( box1_title, wx.HORIZONTAL )
+            sizer = wx.BoxSizer( wx.HORIZONTAL )
+            box.AddSpacer((100,0))
+            bmpVis = wx.Bitmap(opj('images/eye.png.8x8'))
+            visibilityB = wx.BitmapButton(self, -1, bmpVis, (0,0), (12, 12))
+            box.Add(visibilityB, wx.ALIGN_CENTRE|wx.ALL, 0, 0)
+            self.Bind(wx.EVT_BUTTON, self.OnClickVisible, visibilityB)
+            #p = wx.Panel(self.parent, -1)
+            #text = wx.StaticText(self.parent, -1, "warg?", (20, 10))
+
+            #box.Add(text, wx.ALIGN_CENTRE|wx.ALL, 0, 0 )
+            box.AddSpacer((100,0))
+            #box.Layout()
+            sizer.Add(box)
+            sizer.Layout()
+            self.SetSizer(box)
+            box.Fit(self)
+            #sizer.Fit(self)
+            #self.vs.SetDimension(0,0,0,0)
+            #self.vs.Clear(False)
+            #self.vs.Add( self.visibilityB, wx.ALIGN_CENTRE|wx.ALL, 0, 10)
+            #self.vs.Clear()
+            #self.vs.Fit(self)
+           # self.vs.SetSize(100, 100)
+            #self.vs.Layout()
+            #self.SetMaxSize((100, 10))
+            self.parent.GetSizer().Layout()
+            self.parent.Refresh()
+        else:
+            print "clicked"
+            #self.SetSizer(self.vs)
+            #self.vs.Fit(self)
+            #self.vs.Clear(False)
+            #self.vs.Add(self.box1)
+            #self.sizer.ShowItems(True)
+            #self.visible = True
+            #self.SetSizer( vs )
+            #vs.Fit( self )
+            #self.vs.Layout()
+            self.GetSizer().ShowItems(False)
+            self.GetSizer().Clear()
+            self.CreateElements()
+            self.sizer.ShowItems(True)
+            self.vs.Layout()
+            self.vs.Fit(self)
+            self.parent.GetSizer().Layout()
+            self.parent.Refresh()
+            self.transferFPanel.transferFPanel.SetHistogram(self.histogram)
+            
+            
+class MeasurementsFrame(wx.Frame):
+    def __init__(self, parent, ID, title,  zoomMin, zoomMax, cropMin, 
cropMax, colorMin, colorMax, pos=wx.DefaultPosition, size=wx.DefaultSize, 
style=wx.DEFAULT_FRAME_STYLE):
+        wx.Frame.__init__(self, parent, ID, title, pos, size, style)
+        self.parent = parent
+        panel = wx.Panel(self, -1)
+        vs = wx.BoxSizer( wx.VERTICAL )
+        gbs = wx.GridBagSizer(5,5)
+        
+        self.zoomText = wx.StaticText(self, -1, "Zoom into data values: ", 
(20, 10))
+        self.zoomMinTcl = wx.TextCtrl(self, -1, str(zoomMin), size=(125, -1))
+        self.zoomMaxTcl = wx.TextCtrl(self, -1, str(zoomMax), size=(125, -1))
+        self.cropText = wx.StaticText(self, -1, "Crop displayed data values: 
", (20, 10))
+        self.cropMinTcl = wx.TextCtrl(self, -1, str(cropMin), size=(125, -1))
+        self.cropMaxTcl = wx.TextCtrl(self, -1, str(cropMax), size=(125, -1))
+        self.colorText = wx.StaticText(self, -1, "Crop color values: ", (20, 
10))
+        self.colorMinTcl = wx.TextCtrl(self, -1, str(colorMin), size=(125, 
-1))
+        self.colorMaxTcl = wx.TextCtrl(self, -1, str(colorMax), size=(125, 
-1))
+        self.button = wx.Button(self, -1, "OK")
+        self.cancelB = wx.Button(self, -1, "Cancel")
+        
+        gbs.Add(self.zoomText, (1,0))
+        gbs.Add(self.zoomMinTcl, (1,1))
+        gbs.Add(self.zoomMaxTcl, (1,2))
+        gbs.Add(self.cropText, (2,0))
+        gbs.Add(self.cropMinTcl, (2,1))
+        gbs.Add(self.cropMaxTcl, (2,2))
+        gbs.Add(self.colorText, (3,0))
+        gbs.Add(self.colorMinTcl, (3,1))
+        gbs.Add(self.colorMaxTcl, (3,2))
+        
+        vs2 = wx.BoxSizer( wx.HORIZONTAL )
+        
+        vs2.Add(self.button)
+        vs2.AddSpacer(15)
+        vs2.Add(self.cancelB)
+        vs2.Layout()
+        
+        vs.Add(gbs, -1, wx.ALIGN_CENTRE, 1 )
+        vs.Add(vs2, -1, wx.ALIGN_CENTRE|wx.ALIGN_BOTTOM, 1 )
+
+        vs.Layout()
+        
+        self.SetSizer(vs)
+        vs.Fit(self)
+        self.SetAutoLayout(True)
+        
+        
+        self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.button)
+        self.Bind(wx.EVT_BUTTON, self.OnCancel, self.cancelB)
+        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+        
+    def OnCancel(self, evt):
+        self.Close(True)
+        
+    def OnCloseMe(self, event):
+        zoomMin = self.zoomMinTcl.GetValue()
+        zoomMax = self.zoomMaxTcl.GetValue()
+        cropMin = self.cropMinTcl.GetValue()
+        cropMax = self.cropMaxTcl.GetValue()
+        colorMin = self.colorMinTcl.GetValue()
+        colorMax = self.colorMaxTcl.GetValue()
+        #print "zomMin: " + str(zoomMin)
+        self.parent.SendValues(float(zoomMin), float(zoomMax), 
float(cropMin), float(cropMax), float(colorMin), float(colorMax))
+    
+        self.Close(True)
+
+    def OnCloseWindow(self, event):
+        self.Destroy()
+        

Added: trunk/scenes/csafe/python/HistogramGroup.py
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/python/HistogramGroup.py Wed Jan  9 18:28:28 2008
@@ -0,0 +1,119 @@
+import sys, os, time, traceback, types
+
+import wx
+import wx.html
+
+import Histogram
+#from wxPython.wx import *
+#import images
+#import wx.lib.plot as plot
+
+
+#copied from demo.py
+def opj(path):
+    """Convert paths to the platform-specific separator"""
+    str = apply(os.path.join, tuple(path.split('/')))
+    # HACK: on Linux, a leading / gets lost...
+    if path.startswith('/'):
+        str = '/' + str
+    return str
+
+data = []
+numBuckets = 1
+hMin = 0.0
+hMax = 1.0
+dMin = 0.0
+dMax = 0.0
+lines = []
+width = 10.0
+height = 20.0
+barWidth = 0.0
+
+class HistogramPanel(wx.Panel):
+    def __init__(self, parent, histValues, dataMin, dataMax, width, height):
+        wx.Panel.__init__(self, parent, -1)
+       Histogram.HistogramPanel(self)

+    def OnClickColor(self, evt):
+        dlg = wx.ColourDialog(self)
+        dlg.GetColourData().SetChooseFull(True)
+        
+        if dlg.ShowModal() == wx.ID_OK:
+            color = dlg.GetColourData()
+            
+        dlg.Destroy()
+       
+    def Update(self, datavalues, nbuckets, widthn, heightn):
+        global data
+        global numBuckets
+        global hMin
+        global hMax
+        global lines
+        global width
+        global height
+        global barWidth
+        
+        width = widthn
+        height = heightn
+        
+        data = datavalues
+        data.sort()
+        numBuckets = nbuckets
+        dMin = data[0]
+        dMax = data[len(data)-1]
+     #   lines.append( (0,0, 50, 50) )
+        #function(lines, range(0.0, 1.0))
+        start = dMin
+        step = (dMax - dMin)/numBuckets
+        print repr(step)
+        end = (dMin + step)
+        
+        barWidth = width/numBuckets
+        
+        blx = 10.0 + barWidth/2.0 # bottom left x
+        bly = 10.0 + height + barWidth/2.0
+        
+        hMin = 99999.0
+        hMax = -999999.0
+        
+        
+        
+        for i in range(int(numBuckets)):
+ #           frequency = 1.0
+           # filter(lines, range(start, end) )
+            frequency = len( [x for x in data if (x >= start and x <= end)] )
+#            print '%f %f %f' % (frequency, start, end)
+            if frequency < hMin:
+                hMin = frequency
+            if frequency > hMax:
+                hMax = frequency
+            start += step
+            end += step
+                
+        start = dMin
+        end = dMin + step
+            
+        if hMax > hMin:
+            for i in range(int(numBuckets)):
+                frequency = len( [x for x in data if (x >= start and x <= 
end)] )
+                barHeightNorm = float(frequency - hMin)/float(hMax-hMin)
+                if float (barHeightNorm) > 1.0:
+                    print "error"
+ #               print '%f %f %f %f' % (frequency, start, end, barHeightNorm)
+                lines.append( ( blx + i*barWidth, bly, blx + i*barWidth, 
(bly - barHeightNorm*height) ) )
+                start += step
+                end += step
+       
+    def OnPaint(self, evt=None):
+        dc = wx.PaintDC(self)
+        dc.Clear()
+        self.DrawLines(dc)
+        
+    def DrawLines(self, dc):
+        global lines
+        #dc.BeginDrawing()
+        dc.SetPen(wx.Pen("BLACK", barWidth))
+        dc.DrawLineList(lines)
+        #dc.DrawLine(0,0,50,50)
+        #dc.EndDrawing()
+        

Added: trunk/scenes/csafe/python/SceneInfo.py
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/python/SceneInfo.py      Wed Jan  9 18:28:28 2008
@@ -0,0 +1,18 @@
+import wx
+
+class Scene(wx.Object):
+       def __init__(self):
+               self.volVar = 8  #index used to denote volume
+               self.nrrdFiles = []
+               self.test = None
+               self.ridx = -1
+               self.radius = 0.001
+               self.cidx = -1
+               self.nrrdFiles2 = []
+               self.engine = None
+               self.duration = 10.0
+               self.numThreads = 1
+               self.sceneName = "Untitled"
+               self.sceneWD = "/"
+               self.histogramBMPLoaded = False
+

Added: trunk/scenes/csafe/python/SceneMenus.py
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/python/SceneMenus.py     Wed Jan  9 18:28:28 2008
@@ -0,0 +1,406 @@
+import sys, os, time, traceback, types
+import wx
+import SceneInfo
+import Histogram
+import TransferF
+import wxManta
+from manta import *
+from example import *
+
+
+class AddRemoveFilesFrame(wx.Frame):
+    def __init__(self, parent, id, title, scene):
+       wx.Frame.__init__(self, parent, id, title, None, (700, 700))
+       self.scene = scene
+       self.parent = parent;
+       panel = wx.Panel(self, -1)
+       self.lb1 = wx.ListBox(panel, -1, (0, 0), (600, 200), [], 
wx.LB_EXTENDED)
+
+
+       sizer = wx.BoxSizer(wx.VERTICAL)
+       sizer.Add(self.lb1, -1, wx.ALL|wx.ALIGN_CENTER, 5)
+       hSizer1 = wx.BoxSizer(wx.HORIZONTAL)
+       self.addButton = wx.Button(panel,wx.ID_ADD)
+       self.removeButton = wx.Button(panel, wx.ID_REMOVE)
+       hSizer1.Add(self.addButton, 0, wx.ALL, 3)
+       hSizer1.Add(self.removeButton, 0, wx.ALL, 3)
+       sizer.Add(hSizer1, 0, wx.ALL|wx.ALIGN_CENTER, 5)
+
+       self.lb2 = wx.ListBox(panel, -1, (0,0), (600, 200), [], 
wx.LB_EXTENDED)
+       sizer.Add(self.lb2, -1, wx.ALL|wx.ALIGN_CENTER, 5)
+       hSizer2 = wx.BoxSizer(wx.HORIZONTAL)
+       
+       self.addButton2 = wx.Button(panel,-1, "Add")
+       self.removeButton2 = wx.Button(panel, -1, "Remove")
+       hSizer2.Add(self.addButton2, 0, wx.ALL, 3)
+       hSizer2.Add(self.removeButton2, 0, wx.ALL, 3)
+       sizer.Add(hSizer2, 0, wx.ALL|wx.ALIGN_CENTER, 5)                
+
+
+       self.okButton = wx.Button(panel, wx.ID_OK)
+       self.cancelButton = wx.Button(panel, wx.ID_CANCEL)
+       hSizer2 = wx.BoxSizer(wx.HORIZONTAL)
+       hSizer2.Add(self.okButton, 0, wx.ALL, 3)
+       hSizer2.Add(self.cancelButton, 0, wx.ALL, 3)
+       sizer.Add(hSizer2, 0, wx.ALL|wx.ALIGN_CENTER, 5)
+       
+       panel.SetSizer(sizer)
+
+       selfSizer = wx.BoxSizer()
+       selfSizer.Add(panel, 1, wx.EXPAND)
+       self.SetSizer(selfSizer)
+       self.SetAutoLayout(True)
+
+       self.Bind(wx.EVT_BUTTON, self.OnClickOk, self.okButton)
+       self.Bind(wx.EVT_BUTTON, self.OnClickAdd, self.addButton)
+       self.Bind(wx.EVT_BUTTON, self.OnClickAdd2, self.addButton2)
+       self.Bind(wx.EVT_BUTTON, self.OnClickCancel, self.cancelButton)
+       self.Bind(wx.EVT_BUTTON, self.OnClickRemove, self.removeButton)
+       self.Bind(wx.EVT_BUTTON, self.OnClickRemove2, self.removeButton2)
+       self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+
+       self.lb1.AppendItems(self.scene.nrrdFiles)
+       self.lb2.AppendItems(self.scene.nrrdFiles2)
+       
+    def OnClickOk(self, evt):
+       items = []
+       #items = self.scene.nrrdFiles
+       for i in range(self.lb1.GetCount()):
+               print " appending to spheres: " + str(self.lb1.GetString(i))
+               items.append(str(self.lb1.GetString(i)))
+        self.scene.nrrdFiles = items
+       items2 = []
+        for i in range(self.lb2.GetCount()):
+                print " appending to vols: " + str(self.lb2.GetString(i))
+                items2.append(str(self.lb2.GetString(i)))
+        self.scene.nrrdFiles2 = items2
+        self.Close(True)
+
+       print "self.scene.nrrdFiles2: "
+       for i in range(len(self.scene.nrrdFiles2)):
+               print str(self.scene.nrrdFiles2[i])
+       print "end nrrdFiles2."
+
+    def OnClickCancel(self, evt):
+        self.Close(True)
+
+    def OnClickRemove(self, evt):
+        offset = 0
+        for i in self.lb1.GetSelections():
+            try:
+                self.lb1.Delete(i - offset)
+                offset+=1
+            except:
+                continue
+    
+    def OnClickRemove2(self, evt):
+       offset = 0
+        for i in self.lb2.GetSelections():
+            try:
+                self.lb2.Delete(i - offset)
+                offset+=1
+            except:
+                continue
+        
+    def OnClickAdd(self, evt):
+        wildcard = "Nrrd File (*.nrrd)|*.nrrd|" \
+                  "Nrrd Header (*.nrhd)|*.nrhd|" \
+                   "All files (*.*)|*.*"
+        dlg = wx.FileDialog(self, message="Choose a file(s)",
+           defaultDir=os.getcwd(), defaultFile="",wildcard=wildcard,
+           style=wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR)
+        if dlg.ShowModal() == wx.ID_OK:
+            paths = dlg.GetPaths()
+            selected = self.lb1.GetSelections()
+            index = int(self.lb1.GetCount())
+            if len(selected) > 0:
+                index = int(selected[0])
+            for path in paths:
+                self.lb1.Insert(path, index)
+                index = index+1
+
+        dlg.Destroy()
+
+    def OnClickAdd2(self, evt):
+        wildcard = "Nrrd File (*.nrrd)|*.nrrd|" \
+                  "Nrrd Header (*.nrhd)|*.nrhd|" \
+                   "All files (*.*)|*.*"
+        dlg = wx.FileDialog(self, message="Choose a file(s)",
+           defaultDir=os.getcwd(), defaultFile="",wildcard=wildcard,
+           style=wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR)
+        if dlg.ShowModal() == wx.ID_OK:
+            paths = dlg.GetPaths()
+            selected = self.lb2.GetSelections()
+            index = int(self.lb2.GetCount())
+            if len(selected) > 0:
+                index = int(selected[0])
+            for path in paths:
+                self.lb2.Insert(path, index)
+                index = index+1
+
+        dlg.Destroy()
+
+    
+    def OnCloseMe(self, evt):
+        self.Close(True)
+
+    def OnCloseWindow(self, evt):
+        self.Destroy()
+
+
+
+
+class ScenePropertiesFrame(wx.Frame):
+    def __init__(self, parent, id, title, scene):
+       wx.Frame.__init__(self, parent, id, title, None, (700, 500))
+       self.scene = scene
+       self.parent = parent;
+       panel = wx.Panel(self, -1)
+
+       sizer = wx.BoxSizer(wx.VERTICAL)
+       self.frameText = wx.StaticText(panel,-1, "Go to time: ")
+       self.frameButton = wx.Button(panel, -1,"Set")
+       self.frameTcl = wx.TextCtrl(panel, -1, "", size=(125, -1))       
+       hSizer2 = wx.BoxSizer(wx.HORIZONTAL)
+       hSizer2.Add(self.frameText, 0, wx.ALL, 3)
+       hSizer2.Add(self.frameButton, 0, wx.ALL, 3) 
+       hSizer2.Add(self.frameTcl, 0, wx.ALL, 3)
+       sizer.Add(hSizer2, 0, wx.ALL|wx.ALIGN_CENTER, 5)
+
+       hSizer3 = wx.BoxSizer(wx.HORIZONTAL)
+       self.durText = wx.StaticText(panel, 0, "Set duration (seconds): ")
+       self.durButton = wx.Button(panel,-1, "Set")
+       duration = self.scene.test.getDuration()
+       self.durTcl = wx.TextCtrl(panel, 0, str(duration), size=(125, -1))
+       hSizer3.Add(self.durText, 0, wx.ALL, 3)
+       hSizer3.Add(self.durButton, 0, wx.ALL, 3)
+       hSizer3.Add(self.durTcl, 0, wx.ALL, 3)  
+       sizer.Add(hSizer3, 0 , wx.ALL|wx.ALIGN_CENTER,5 )
+       
+       hSizer4 = wx.BoxSizer(wx.HORIZONTAL)
+       self.ridxText = wx.StaticText(panel, -1, "Radius Index (-1 to use one 
radius): ")
+       self.ridxTcl = wx.TextCtrl(panel,-1,str(scene.ridx),size=(125,-1))
+       hSizer4.Add(self.ridxText,0,wx.ALL,3)
+       hSizer4.Add(self.ridxTcl,0,wx.ALL,3)
+       sizer.Add(hSizer4,0,wx.ALL|wx.ALIGN_CENTER,5)          
+
+       hSizer5 = wx.BoxSizer(wx.HORIZONTAL)
+       self.radText = wx.StaticText(panel, -1, "default radius: ")
+       self.radTcl = wx.TextCtrl(panel,-1,str(scene.radius),size=(125,-1))
+       hSizer5.Add(self.radText,0,wx.ALL,3)
+       hSizer5.Add(self.radTcl,0,wx.ALL,3)
+       sizer.Add(hSizer5,0,wx.ALL|wx.ALIGN_CENTER,5)
+
+       hSizer6 = wx.BoxSizer(wx.HORIZONTAL)
+       self.cidxText = wx.StaticText(panel, -1, "Color Index: ")
+       self.cidxTcl = wx.TextCtrl(panel,-1,str(scene.cidx),size=(125,-1))
+       hSizer6.Add(self.cidxText,0,wx.ALL,3)
+       hSizer6.Add(self.cidxTcl,0,wx.ALL,3)
+       sizer.Add(hSizer6,0,wx.ALL|wx.ALIGN_CENTER,5)
+
+       hSizer7 = wx.BoxSizer(wx.HORIZONTAL)
+       self.npText = wx.StaticText(panel, -1, "Num threads: ")
+       numThreads = int(SWIGIFYGetNumWorkers(self.scene.engine))
+       self.text = wx.TextCtrl(self, -1, str(numThreads), (30, 50), (60, -1))
+       h = self.text.GetSize().height
+       w = self.text.GetSize().width + self.text.GetPosition().x + 2
+       hSizer7.Add(self.npText, 0, wx.ALL,3)
+       hSizer7.Add(self.text,0, wx.ALL, 3)
+       self.npSP = wx.SpinButton(panel, -1, (w,50), (h*2/3,h), 
wx.SP_VERTICAL)
+       self.npSP.SetValue(numThreads)
+       #self.npSP.SetValue(1)
+       self.npSP.SetRange(1, 100)
+       hSizer7.Add(self.npSP,0,wx.ALL,3)
+       sizer.Add(hSizer7,0,wx.ALL|wx.ALIGN_CENTER,5)
+
+
+       self.okButton = wx.Button(panel, wx.ID_OK)
+       sizer.Add(self.okButton, 0, wx.ALL|wx.ALIGN_CENTER, 5)
+
+       panel.SetSizer(sizer)
+
+       selfSizer = wx.BoxSizer()
+       selfSizer.Add(panel, 1, wx.EXPAND)
+       self.SetSizer(selfSizer)
+       self.SetAutoLayout(True)
+
+       self.Bind(wx.EVT_BUTTON, self.OnClickTime, self.frameButton)
+       self.Bind(wx.EVT_BUTTON, self.OnClickDuration, self.durButton)
+       self.Bind(wx.EVT_BUTTON, self.OnClickOK, self.okButton)
+       self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+       self.Bind(wx.EVT_SPIN, self.OnSpinNP, self.npSP)
+
+    def OnSpinNP(self, evt):
+       self.text.SetValue(str(evt.GetPosition()))
+       self.scene.engine.changeNumWorkers(int(evt.GetPosition()))
+       print "num worker threads: " + 
str(SWIGIFYGetNumWorkers(self.scene.engine))
+       self.scene.numThreads = evt.GetPosition()
+
+    def ApplySettings(self):
+       self.scene.radius = float(self.radTcl.GetValue())
+       self.scene.ridx = float(self.ridxTcl.GetValue())
+       self.scene.cidx = float(self.cidxTcl.GetValue())
+       self.scene.numThreads = int(self.text.GetValue())
+       self.scene.engine.changeNumWorkers(int(self.text.GetValue()))
+       print "ridx set to: " + str(self.scene.ridx)
+
+    def OnClickOK(self, evt):
+        self.ApplySettings()
+        self.Close(True)       
+
+    def OnClickCancel(self, evt):
+       self.Close(True)        
+
+    def OnClickTime(self, evt):
+       time = float(self.frameTcl.GetValue())
+       self.scene.test.gotoFrame(time) 
+
+    def OnClickDuration(self, evt):
+       duration = float(self.durTcl.GetValue())
+       self.scene.test.setDuration(duration)
+       self.scene.duration = duration
+
+    def OnCloseMe(self, evt):
+        self.Close(True)
+
+    def OnCloseWindow(self, evt):
+        self.Destroy()
+
+
+class AddHistogramFrame(wx.Frame):
+    def __init__(self, parent, id, title, scene, group, index, name):
+       wx.Frame.__init__(self, parent, id, "Add Histogram", None, (700, 500))
+       self.transferFID = 0
+       self.scene = scene
+       self.parent = parent
+       self.group = group
+       self.index = index
+       self.name = name
+       panel = wx.Panel(self, -1) 
+
+       sizer = wx.BoxSizer(wx.VERTICAL)
+
+       hSizer1 = wx.BoxSizer(wx.HORIZONTAL)
+       list = ['spheres','volume']
+       text1 = wx.StaticText(panel, -1, "Select data type: ")
+       self.ch = wx.Choice(panel,-1,(100, 50), choices=list)
+       hSizer1.Add(text1, 0, wx.ALL,3)
+       hSizer1.Add(self.ch,0,wx.ALL,3)
+       self.Bind(wx.EVT_CHOICE,self.EvtChoice,self.ch)
+       sizer.Add(hSizer1,0,wx.ALL|wx.ALIGN_CENTER,5)
+       self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+
+       hSizer2 = wx.BoxSizer(wx.HORIZONTAL)
+       text2 = wx.StaticText(panel,-1,"Index in data: ")
+       self.indexSP = wx.SpinCtrl(panel, -1, "", (30,50))
+       self.indexSP.SetRange(0, 100)
+       self.indexSP.SetValue(0)
+       hSizer2.Add(text2, 0, wx.ALL,3)
+       hSizer2.Add(self.indexSP, 0, wx.ALL,3)
+       sizer.Add(hSizer2, 0, wx.ALL|wx.ALIGN_CENTER,5)
+
+       hSizer3 = wx.BoxSizer(wx.HORIZONTAL)
+       text3 = wx.StaticText(panel,-1, "Name: ")
+       self.nameTC = wx.TextCtrl(panel, -1, name, size=(180,-1))
+       hSizer3.Add(text3,0,wx.ALL,3)
+       hSizer3.Add(self.nameTC,0,wx.ALL,3)
+       sizer.Add(hSizer3,0,wx.ALL|wx.ALIGN_CENTER,5)
+
+       hSizer5 = wx.BoxSizer(wx.HORIZONTAL)
+       text4 = wx.StaticText(panel, -1, "Select Transfer Function: ")
+       list2 = []
+       for i in range(len(self.scene.frame.transferFunctions)):
+              list2.append(self.scene.frame.transferFunctions[i].label)
+       list2.append('New Transfer Function...')
+       self.transferCH = wx.Choice(panel, -1, (100,50), choices=list2)
+       hSizer5.Add(text4, 0, wx.ALL, 3)
+       hSizer5.Add(self.transferCH,0,wx.ALL,3)
+       sizer.Add(hSizer5,0,wx.ALL|wx.ALIGN_CENTER,5)
+       self.Bind(wx.EVT_CHOICE, self.EvtChoiceTF, self.transferCH)
+       
+       
+       self.okButton = wx.Button(panel, wx.ID_OK)
+       self.cancelButton = wx.Button(panel, wx.ID_CANCEL)
+       hSizer4 = wx.BoxSizer(wx.HORIZONTAL)
+       hSizer4.Add(self.cancelButton, 0, wx.ALL, 3)
+       hSizer4.Add(self.okButton,0,wx.ALL,3)
+       sizer.Add(hSizer4, 0, wx.ALL|wx.ALIGN_CENTER, 5)
+
+       
+        
+       panel.SetSizer(sizer)
+
+       selfSizer = wx.BoxSizer()
+       selfSizer.Add(panel, 1, wx.EXPAND)
+       self.SetSizer(selfSizer)
+       self.SetAutoLayout(True)
+
+       self.Bind(wx.EVT_BUTTON, self.OnClickOK, self.okButton)
+       self.Bind(wx.EVT_BUTTON, self.OnClickCancel, self.cancelButton)
+
+    def EvtChoiceTF(self, e):
+       print "choice"
+       if e.GetString() == 'New Transfer Function...':
+               print "dlg"
+               dlg = wx.TextEntryDialog(self, 'Transfer Function name: ', 
'Choose Name', 'Untitled')
+               if dlg.ShowModal() == wx.ID_OK:
+                       name = dlg.GetValue()
+                       colors = []
+                       histValues1 = []
+                       for i in range(0,100):
+                               histValues1.append(5)
+                       
self.scene.frame.transferFunctions.append(TransferF.TransferF(self, colors, 
len(self.scene.frame.transferFunctions), name, manta_new(CDColorMap(1))))
+                       self.transferCH.Insert(name, 
self.transferCH.GetCount()-1)
+               dlg.Destroy()
+               self.transferFID = self.transferCH.GetCount()-2
+               self.transferCH.SetSelection(self.transferFID)
+       else:
+               self.transferFID = self.transferCH.GetCurrentSelection()
+
+    def OnClickOK(self, evt):
+        self.name = self.nameTC.GetValue()
+        self.index = self.indexSP.GetValue()
+       dataMin = -1.1
+       dataMax = 2.2
+       min = SWIGIFYCreateDouble(0)
+       max = SWIGIFYCreateDouble(100)
+       dataMin = SWIGIFYGetDouble(min)
+       dataMax = SWIGIFYGetDouble(max)
+       histValues1 = []
+       for i in range(0,100):
+           histValues1.append(5)
+       colors = []
+       #t = TransferF.TransferF(self, colors, self.transferFID, self.name, 
manta_new(CDColorMap(1)))
+        histoGroup = Histogram.HistogramGroup(self.scene.frame, histValues1, 
dataMin, dataMax, 300, 40.0, 
self.scene.frame.transferFunctions[self.transferFID], self.scene.tPanel, 
self.scene, self.index, self.name)
+       color = wx.Colour(90,90,90)
+       histoGroup.group = self.group
+        histoGroup.SetBackgroundColour(color)
+       self.scene.frame.histoGroups.append(histoGroup)
+       #self.scene.histoVS.Add(histoGroup,0,wx.ALIGN_CENTER,1)       
+        #self.scene.frame.vs.Layout()
+       self.scene.frame.LayoutWindow()
+        self.Close(True)
+
+    def OnClickCancel(self, evt):
+        self.Close(True)
+
+
+    def EvtChoice(self, e):
+          ch = e.GetString()
+           if ch == 'spheres':
+                 self.group = 0
+           else:
+                 self.group = 1
+          
+    def OnCloseMe(self, evt):
+        self.Close(True)
+
+    def OnCloseWindow(self, evt):
+        self.Destroy()
+
+
+
+
+
+
+

Added: trunk/scenes/csafe/python/TransferF.py
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/python/TransferF.py      Wed Jan  9 18:28:28 2008
@@ -0,0 +1,496 @@
+import sys, os, time, traceback, types
+import wx
+import Histogram
+import random
+import wxManta
+
+# Import the manta module, the mantainterface module which was %import'ed
+# into swig/example.i is automatically included by the manta module.
+from manta import *
+
+# Import your new wrapped code.
+from example import *
+
+colors = [] # (pos, r, g, b, a)
+
+def opj(path):
+    #copied from demo.py
+    """Convert paths to the platform-specific separator"""
+    str = apply(os.path.join, tuple(path.split('/')))
+    # HACK: on Linux, a leading / gets lost...
+    if path.startswith('/'):
+        str = '/' + str
+    return str
+
+class TransferF(wx.Object):
+    def __init__(self, parent, colorsn, id, title="untitled", cmap = None):
+       print "init"
+       self.parent = parent
+        self.colors = colorsn
+       self.id = id
+       if (cmap != None):
+               #slices = cmap.GetColors()
+               num = cmap.GetNumSlices()
+               for i in range(num):
+                       #color = manta_new(vector_ColorSlice())
+                       #color = slices.at(i).color.color
+                       slice = cmap.GetSlice(i)
+                       c = slice.color.color
+                       a = float(slice.color.a)
+                       p = float(slice.value)
+                       c1 = float(SWIGIFYGetColorValue(c, 0))
+                       c2 = float(SWIGIFYGetColorValue(c,1))
+                       c3 = float(SWIGIFYGetColorValue(c,2))
+                       self.colors.append((float(p), float(c1), float(c2), 
float(c3), float(a)))
+        if len(self.colors) < 1.0:
+            #print "appending"
+            self.colors.append((0.0, 0, 0, 0, 1))
+            self.colors.append((1.0, 1, 1, 1, 1))
+            #self.colors.append((0.5, 0, 1, 1, 1))
+            #self.colors.append((0.3, 1, 0, 1, 1))
+        #print len(self.colors)
+        self.colors.sort()
+        #for i in range(0, len(self.colors)):
+        #    print self.colors[i]
+        self.label = title
+       self.cmap = cmap
+
+    def UpdateColorMap(self):
+       self.parent.UpdateColorMap(self)    
+   
+    def GetLabel(self):
+        return self.label
+            
+    def MoveColor(self, index, pos):
+        c = (  pos, self.colors[index][1],self.colors[index][2], 
self.colors[index][3], self.colors[index][4] ) 
+        #c = ( 0.5 , 1, 0, 0, 1)
+        #print index
+        self.colors[index] = c
+        #self.colors.sort()
+            
+    def AddColor(self, color, pos):
+        if (len(color) == 3):
+            self.colors.append( (  pos, color[0], color[1], color[2], 1.0 ) )
+        elif (len(color) == 4):
+                self.colors.append( (  pos, color[0], color[1], color[2], 
color[3] ) )
+        else:
+            blowuphorribly
+        #self.colors.sort()
+        
+    def SetColor(self, index, color):
+        pos = self.colors[index][0]
+        if (len(color) == 3):
+           c = (  pos, color[0], color[1], color[2], 1.0 ) 
+        elif (len(color) == 4):
+                c =  (  pos, color[0], color[1], color[2], color[3] ) 
+        else:
+            blowuphorribly
+        
+        self.colors[index] = c
+#        if (len(color) == 3):
+#            print "setcolor"
+#            print self.colors[1][1]
+#            self.colors[index][1] = color[0]
+#            self.colors[index][2] = color[1]
+#            self.colors[index][3] = color[2]
+#            self.colors[index][4] = 1.0
+#        elif (len(color) == 4):
+#            self.colors[index][1] = color[0]
+#            self.colors[index][2] = color[1]
+#            self.colors[index][3] = color[2]
+#            self.colors[index][4] = color[3]
+#        else:
+#                blowuphorribly
+        
+        
+    def GetColor(self, pos):  #color at position pos, in range [0,1]
+        colors = []
+        for i in range(len(self.colors)):
+            colors.append( (self.colors[i][0], self.colors[i][1], 
self.colors[i][2], self.colors[i][3], self.colors[i][4] ) )
+        colors.sort()
+        
+        if len(colors) < 1:
+            return (0,0,0,1)
+        index1 = 0
+        index2 = 0
+        for i in range(0, len(colors)):
+            if (colors[i][0] <= pos):
+                index1 = i
+            if (colors[i][0] >= pos and index2 == 0):
+                index2 = i
+        if (pos < colors[0][0]):
+            index2 = 0
+        if (colors[len(colors) - 1][0] < pos):
+            index2 = len(colors) - 1
+        
+        
+        #print index1
+        #print index2
+        
+        pos1 = colors[index1][0]
+        pos2 = colors[index2][0]
+        amt1 = amt2 = 0.5
+        length =  pos2 - pos1
+        if length > 0.0: 
+            amt1 = (1.0 - (pos - pos1)/length)
+            amt2 = (1.0 - (pos2 - pos)/length)
+        if index1 == index2:
+            amt1 = amt2 = 0.5
+        a1 = colors[index1][4]
+        a2 = colors[index2][4]
+            
+        color = (colors[index1][1]*amt1 + colors[index2][1]*amt2, 
colors[index1][2]*amt1 + colors[index2][2]*amt2, \
+            colors[index1][3]*amt1 + colors[index2][3]*amt2, 
colors[index1][4]*amt1 + colors[index2][4]*amt2)
+        return color
+        
+    def GetColorAtIndex(self, index):  #get the non interpolated color value
+        colord = self.colors[index]
+        return (colord[1], colord[2], colord[3], colord[4])
+        
+        
+    def GetColorRGB(self, pos):
+        color = self.GetColor(pos)
+        return (color[0]*color[3]*255.0, color[1]*color[3]*255.0, 
color[2]*color[3]*255.0)
+        
+        #return ( ( 0, 0, 0, 0) )
+        
+    def RemoveColor(self, index):
+        self.colors.pop(index)
+        
+
+class TransferFPanel(wx.Panel):
+    def __init__(self, parent, width, height, transferF, 
updateFunction=None):
+       self.backgroundIMG = wx.Image(opj('images/bckgrnd.png'), 
wx.BITMAP_TYPE_PNG).ConvertToBitmap()
+       self.paddingW = 20.0
+        self.paddingH = 20.0
+        self.transferF = transferF
+        self.width = width
+        self.height = height
+        self.parentC = parent
+        self.updateFunction = updateFunction
+        panel = wx.Panel.__init__(self, parent, -1, (0, 0), (width + 
self.paddingW, height + self.paddingH) )
+        wx.EVT_PAINT(self, self.OnPaint)
+        self.Update()
+        self.Bind(wx.EVT_LEFT_DOWN, self.OnClick)
+        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
+        self.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
+        self.Bind(wx.EVT_MOTION, self.OnMotion)
+        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
+        #self.SetFocus()
+        self.colorSelectorWidth = 10.0
+        self.selected = None
+        self.dSelected = None
+        self.histogram = None
+       self.SetBackgroundColour(wx.Colour(90,90,90))
+        
+    def SetUpdateFunction(self, function):
+        self.updateFunction = function
+        
+    def SetTransferF(self, transferF):
+        self.transferF = transferF
+        self.Update()
+        
+        
+    def OnKeyDown(self, evt):
+        print "keyyed"
+        if evt.GetKeyCode() == wx.WXK_DELETE and self.dSelected != None:
+            self.transferF.RemoveColor(self.dSelected)
+            self.Update()
+        self.UpdateHistogram()
+    
+    def OnRightClick(self, evt):
+        x = evt.GetPosition().x - self.paddingW/2.0
+        y = evt.GetPosition().y - self.paddingH/2.0
+        #did they click on a color picker?
+        clicked = False
+        index = -1
+        #print evt.GetPosition().x
+        for i in range(len(self.transferF.colors)):
+            if abs(x - self.transferF.colors[i][0]*self.width) < 
self.colorSelectorWidth/2.0:
+                clicked = True 
+                index = i
+        
+        if clicked:
+            dlg = wx.ColourDialog(self)
+            dlg.GetColourData().SetChooseFull(True)
+            
+            if dlg.ShowModal() == wx.ID_OK:
+               originalC = self.transferF.GetColorAtIndex(index)
+                data = dlg.GetColourData()
+                print "selected color:"
+                print data.GetColour().Get()
+                print index
+                c = data.GetColour().Get()
+                color = []
+                color.append(c[0])
+                color.append(c[1])
+                color.append(c[2])
+               color.append(originalC[3])
+                color[0] /= 255.0
+                color[1] /= 255.0
+                color[2] /= 255.0
+                #print color[0]
+                #print color[1]
+                self.transferF.SetColor(index, color)
+                self.Update()
+                self.Refresh()
+                
+            dlg.Destroy()
+            
+        else: # add a new one
+            dlg = wx.ColourDialog(self)
+            dlg.GetColourData().SetChooseFull(True)
+            data = dlg.GetColourData()
+            
+            if dlg.ShowModal() == wx.ID_OK:
+                data = dlg.GetColourData()
+                print "selected color:"
+                print data.GetColour().Get()
+                print index
+                c = data.GetColour().Get()
+                color = []
+                color.append(c[0])
+                color.append(c[1])
+                color.append(c[2])
+               color.append(1.0 - float(y)/float(self.height))
+                color[0] /= 255.0
+                color[1] /= 255.0
+                color[2] /= 255.0
+                pos = float(x)/float(self.width)
+                #print color[0]
+                #print color[1]
+                self.transferF.AddColor( color, pos)
+                self.Update()
+                
+            dlg.Destroy()
+        self.UpdateHistogram()
+            
+    
+    def SetHistogram(self, histo):
+        self.histogram = histo
+        
+    def UpdateHistogram(self):
+        if self.histogram != None:
+            self.histogram.Update()
+       self.transferF.UpdateColorMap()
+    
+    def OnClick(self, evt):
+        x = evt.GetPosition().x - self.paddingW/2.0
+        if self.selected == None:
+            index = -1
+            #print evt.GetPosition().x
+            for i in range(len(self.transferF.colors)):
+                if abs(x - self.transferF.colors[i][0]*self.width) < 
self.colorSelectorWidth/2.0:
+                    clicked = True 
+                    index = i
+            if index >= 0:
+                self.selected = index
+                self.dSelected = index
+            else:
+                self.dSelected = None
+                self.selected = None
+            self.Refresh()
+        
+    def OnLeftUp(self, evt):
+        self.selected = None
+        self.UpdateHistogram()
+        
+    def OnMotion(self, evt):
+        x = evt.GetPosition().x - self.paddingW/2.0
+       if (x < 0.0):
+           x = 0.0
+       if x > self.width:
+           x = self.width              
+        y = evt.GetPosition().y - self.paddingH/2.0
+       if y < 0.0:
+           y = 0.0
+       if y > self.height:
+           y = self.height
+        if self.selected != None:
+            pos = float(x) / float(self.width)
+            self.transferF.MoveColor(self.selected, pos)
+            colord = self.transferF.GetColorAtIndex(self.selected)
+            a = float(self.height - y)/float(self.height)
+            if a > 1.0:
+                a = 1.0
+            elif a < 0.0:
+                a = 0.0
+            color = (colord[0], colord[1], colord[2], a)
+            self.transferF.SetColor(self.selected, color)
+            self.Update()
+        
+    def Update(self):
+        width = self.width - 2.0
+        height = self.height - 2.0
+        self.barWidth = 1.0
+        
+        blx = 1.0 + self.barWidth/2.0 + self.paddingW/2.0 # bottom left x
+        bly = 0.0 + self.height + self.barWidth/2.0 - 2.0 + self.paddingH/2.0
+
+        self.lines = []
+        for i in range(0, width):
+            color = self.transferF.GetColor( float(i)/float(width) )
+            self.lines.append( (color, ( blx + i*self.barWidth, bly, blx + 
i*self.barWidth, (bly - height) ) ) )
+        self.parentC.Refresh()
+        self.Refresh()
+        if (self.updateFunction != None):
+            self.updateFunction()
+            
+    def AddNewColor(self):
+        dlg = wx.ColourDialog(self)
+        dlg.GetColourData().SetChooseFull(True)
+        data = dlg.GetColourData()
+        
+        if dlg.ShowModal() == wx.ID_OK:
+            data = dlg.GetColourData()
+            c = data.GetColour().Get()
+            color = []
+            color.append(c[0])
+            color.append(c[1])
+            color.append(c[2])
+            color[0] /= 255.0
+            color[1] /= 255.0
+            color[2] /= 255.0
+            self.transferF.AddColor( color, random.random())
+            self.Update()
+            
+        dlg.Destroy()
+        self.UpdateHistogram()
+    
+    def DeleteSelected(self):
+        if self.dSelected != None:
+            self.transferF.RemoveColor(self.dSelected)
+            self.Update()
+        self.UpdateHistogram()
+    
+    def ChooseColorSelected(self):
+        if self.dSelected != None:
+            dlg = wx.ColourDialog(self)
+            dlg.GetColourData().SetChooseFull(True)
+            
+            if dlg.ShowModal() == wx.ID_OK:
+                data = dlg.GetColourData()
+                c = data.GetColour().Get()
+                color = []
+                color.append(c[0])
+                color.append(c[1])
+                color.append(c[2])
+                color[0] /= 255.0
+                color[1] /= 255.0
+                color[2] /= 255.0
+                #print color[0]
+                #print color[1]
+                self.transferF.SetColor(self.dSelected, color)
+                self.Update()
+                self.Refresh()
+                
+            dlg.Destroy()
+            self.UpdateHistogram()
+        
+    def OnPaint(self, evt=None):
+        pdc = wx.PaintDC(self)
+       try:
+          dc = wx.GCDC(pdc)
+       except:
+         dc = pdc
+       
+       lines = self.lines
+        colors = self.transferF.colors
+        dc.SetPen(wx.Pen('BLACK', 2) )
+        left = self.paddingW/2.0
+        top = self.paddingH/2.0
+       originalSize = self.GetClientSize()
+       dc.SetClippingRegion(self.paddingW/2.0,self.paddingH/2.0 
,self.width-1, self.height)
+       imgWidth = self.backgroundIMG.GetWidth()
+        imgHeight = self.backgroundIMG.GetHeight()
+        for x in range(self.paddingW/2.0 + 1, (self.width ), imgWidth):
+                for y in range(self.paddingH/2.0 +2, self.height , 
imgHeight):
+                        dc.DrawBitmap(self.backgroundIMG,x,y, True)
+       
#dc.SetClippingRegion(0-self.paddingW/2.0,0-self.paddingH/2.0,originalSize.width,
 originalSize.height)
+        try:
+          dc = wx.GCDC(pdc)
+        except:
+           dc = pdc
+        numPixels = self.width
+        for i in range(0, len(lines)):
+            a = lines[i][0][3]*255.0
+            r = lines[i][0][0]*255.0
+            g = lines[i][0][1]*255.0
+            b = lines[i][0][2]*255.0
+           try:
+             penColor = wx.Colour(r,g,b,a)
+           except:
+             penColor = wx.Colour(r,g,b)
+            dc.SetPen(wx.Pen(penColor, self.barWidth + 1) )
+            dc.DrawLine( lines[i][1][0], lines[i][1][1], lines[i][1][2], 
lines[i][1][3])
+        for i in range(len(colors)):
+            dc.SetPen(wx.Pen('GRAY', 2) )
+            color = self.transferF.GetColor( colors[i][0] )
+           try:
+               dc.SetBrush(wx.Brush( color, wx.SOLID ) )
+           except:
+               dc.SetBrush(wx.Brush( (color[0], color[1], color[2]), 
wx.SOLID))
+            if i == self.dSelected:
+               dc.SetBrush(wx.Brush( (128,128,128), wx.SOLID ) )
+            recWidth = self.colorSelectorWidth
+            x = colors[i][0]*self.width - recWidth/2.0 + left
+            y = self.height - recWidth + top
+            dc.DrawRectangle(x,y - color[3]*self.height + recWidth/2.0, 
recWidth, recWidth)
+
+class TransferFGroup(wx.Panel):
+    def __init__(self, parent, width, height, transferF, title):
+       self.parentC = parent
+        self.height = height
+        self.width = width
+        self.transferF = transferF
+        wx.Panel.__init__(self, parent, -1, (0, 0) , (width, height) )
+        self.vs = vs = wx.BoxSizer( wx.VERTICAL )
+        self.box1_title = wx.StaticBox( self, -1, title )
+        self.transferFPanel = TransferFPanel(self, width, height, transferF)
+        box1 = self.box1 = wx.StaticBoxSizer( self.box1_title, wx.VERTICAL )
+        self.gbs = gbs = wx.GridBagSizer(5,5)
+        self.sizer = box1
+        
+        gbs.Add(self.transferFPanel,(0, 0), (5, 2) )
+        
+        bmpNew = wx.Bitmap(opj('images/new_16x16.png'))
+        bmpDel = wx.Bitmap(opj('images/delete_16x16.png'))
+        bmpMod = wx.Bitmap(opj('images/color_16x16.png'))
+        self.newColorB = wx.BitmapButton(self, -1, bmpNew, (0,0), 
style=wx.NO_BORDER)
+        self.delColorB = wx.BitmapButton(self, -1, bmpDel, (0,0), 
style=wx.NO_BORDER)
+        self.modifyColorB = wx.BitmapButton(self, -1, bmpMod, (0,0), 
style=wx.NO_BORDER)
+        gbs.Add( self.newColorB, (0, 2) )
+        gbs.Add( self.delColorB, (1, 2) )
+        gbs.Add( self.modifyColorB, (2, 2) )
+        
+        
+        gbs.Layout()
+        
+        box1.Add( gbs, -1, wx.ALIGN_CENTRE|wx.ALL, 5 )
+        vs.Add( box1, -1, wx.ALIGN_CENTRE|wx.ALL, 5 )
+        #vs.Add(grid1, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
+        self.SetSizer( vs )
+        vs.Fit( self )
+        self.visible = True
+        
+        self.Bind(wx.EVT_BUTTON, self.OnClickNew, self.newColorB)
+        self.Bind(wx.EVT_BUTTON, self.OnClickDelete, self.delColorB)
+        self.Bind(wx.EVT_BUTTON, self.OnClickModify, self.modifyColorB)
+        
+    def OnClickNew(self, evt):
+        self.transferFPanel.AddNewColor()
+    
+    def OnClickDelete(self, evt):
+        self.transferFPanel.DeleteSelected()
+        
+    def OnClickModify(self, evt):
+        self.transferFPanel.ChooseColorSelected()
+        
+    def SetLabel(self, label):
+        self.box1_title.SetLabel(label)
+        
+    def SetTransferF(self, transferF):
+        self.transferFPanel.SetTransferF(transferF)
+        
+    def SetUpdateFunction(self, function):
+        print "temporary"

Added: trunk/scenes/csafe/python/csafe.py
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/python/csafe.py  Wed Jan  9 18:28:28 2008
@@ -0,0 +1,473 @@
+#
+#  For more information, please see: http://software.sci.utah.edu
+#
+#  The MIT License
+#
+#  Copyright (c) 2005-2006
+#  Scientific Computing and Imaging Institute, University of Utah
+#
+#  License for the specific language governing rights and limitations under
+#  Permission is hereby granted, free of charge, to any person obtaining a
+#  copy of this software and associated documentation files (the "Software"),
+#  to deal in the Software without restriction, including without limitation
+#  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#  and/or sell copies of the Software, and to permit persons to whom the
+#  Software is furnished to do so, subject to the following conditions:
+#
+#  The above copyright notice and this permission notice shall be included
+#  in all copies or substantial portions of the Software.
+#
+#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+#  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
MERCHANTABILITY,
+#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+#  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+#  DEALINGS IN THE SOFTWARE.
+#
+
+""" File: csafe.py
+Description:  runs csafe demo.  
+see http://code.sci.utah.edu/Manta/index.php/CSAFE for instructions
+
+"""
+
+# Import wxManta gui and some system modules.
+import wxManta
+import getopt, sys
+
+# Import the manta module, the mantainterface module which was %import'ed
+# into swig/example.i is automatically included by the manta module.
+from manta import *
+import sys, os, time, traceback, types
+import wx
+# Import your new wrapped code.
+from example import *
+
+
+import wx.lib.buttons
+import sys, os, time, traceback, types
+import random
+from wxPython.wx import *
+import wx
+import Histogram
+import TestGroup
+import TransferF
+import SceneMenus
+import SceneInfo
+import Configuration
+
+"""
+    \class window with controls
+    \brief a window with controls for manipulating the scene, including 
histograms, menus, and playback controls
+"""
+class MyFrame(wxFrame):
+    def __init__(self, parent, ID, title):
+        wxFrame.__init__(self, parent, ID, title, 
+                    wxDefaultPosition, wxSize(200, 150))
+       self.SetForegroundColour(wx.Colour(255,0,0))
+       self.SetBackgroundColour(wx.Colour(90,90,90))
+        self.scene = SceneInfo.Scene()
+        menuBar = wx.MenuBar()
+        menuFile = wx.Menu()
+        menuFile.Append(101, "&About", "")
+        menuFile.Append(102, "&Save", "")
+        menuFile.Append(103, "Save As...", "")
+        menuFile.Append(104, "Load", "")
+        menuFile.Append(105, "Export Transfer Function")
+        menuFile.Append(106, "Import Transfer Function")
+        menuBar.Append(menuFile, "File")
+        
+        menuScene = wx.Menu()
+        menuScene.Append(201, "&Add/Remove Files", "Add and remove Nrrd 
files to the scene")
+       menuScene.Append(204, "Add &Histogram", "Add a histogram to the 
panel")
+        menuScene.Append(202, "Scene Properties")
+        menuScene.Append(203, "&Generate")
+        menuBar.Append(menuScene, "Scene")
+        
+        menuHelp = wx.Menu()
+        menuBar.Append(menuHelp, "Help")
+       self.SetMenuBar(menuBar)
+
+        self.Bind(wx.EVT_MENU, self.Menu101, id=101)
+        self.Bind(wx.EVT_MENU, self.Menu102, id=102)
+        self.Bind(wx.EVT_MENU, self.Menu103, id=103)
+        self.Bind(wx.EVT_MENU, self.Menu104, id=104)
+        self.Bind(wx.EVT_MENU, self.Menu105, id=105)
+        self.Bind(wx.EVT_MENU, self.Menu106, id=106)
+        self.Bind(wx.EVT_MENU, self.Menu201, id=201)
+        self.Bind(wx.EVT_MENU, self.Menu202, id=202)
+       self.Bind(wx.EVT_MENU, self.Menu203, id=203)
+       self.Bind(wx.EVT_MENU, self.Menu204, id=204)
+
+    def Menu101(self, evt):
+        self.log.write("about")
+
+    def Menu102(self, evt):
+       print "writing file: " + self.scene.sceneName
+       if (self.scene.sceneName != "Untitled"):
+               Configuration.WriteConfiguration(self.scene, 
self.scene.sceneWD + '/' + self.scene.sceneName)
+       else:   
+               self.Menu103(evt)
+  
+    def Menu103(self,evt):
+       dlg = wx.FileDialog(self, message="Save file as...", 
defaultDir=os.getcwd(),
+               defaultFile="", wildcard="*", style=wx.SAVE)
+       if dlg.ShowModal() == wx.ID_OK:
+               path = dlg.GetPath()
+               self.scene.sceneName = dlg.GetFilename()
+               print "filename: " + dlg.GetFilename()
+               self.scene.sceneWD = dlg.GetDirectory()
+               Configuration.WriteConfiguration(self.scene, path)
+
+    def Menu104(self,evt):
+       dlg = wx.FileDialog(self, message="Open file",
+               defaultDir=os.getcwd(),
+               defaultFile="",
+               wildcard="*",
+               style=wx.OPEN|wx.CHANGE_DIR)
+       if dlg.ShowModal() == wx.ID_OK:
+               filename = dlg.GetPath()
+               Configuration.ReadConfiguration(self.scene, filename) 
+               self.scene.sceneWD = dlg.GetDirectory()
+               self.scene.sceneName = dlg.GetFilename()
+               print "filename: " + self.scene.sceneName
+
+    def Menu105(self,evt):
+        self.log.write("export transfer function")
+
+    def Menu106(self,evt):
+        self.log.write("import transfer function")
+
+    def Menu201(self, evt):
+        frame = SceneMenus.AddRemoveFilesFrame(self, -1, "Add/Remove Files", 
self.scene)
+       frame.Show(True)
+
+    def Menu202(self, evt):
+       frame = SceneMenus.ScenePropertiesFrame(self, -1, "Scene Properties", 
self.scene)
+       frame.Show(True)
+    def Menu203(self, evt):
+       self.BuildScene()
+
+    def Menu204(self, evt):
+       group = 0
+       name = "untitled"
+        index = 0
+        frame = SceneMenus.AddHistogramFrame(self,-1, "Add Histogram", 
self.scene, group, index, name)
+       frame.Show(True)
+       print "Added histogram: "
+       print group
+       print index
+       print name
+
+    def BuildScene(self):
+       self.test.setRidx(int(self.scene.ridx))
+       self.test.setRadius(float(self.scene.radius))
+       self.test.clearSphereNrrds();
+       self.test.clearVolNrrds();
+        print "loading volume nrrds: "
+       for i in range(len(self.scene.nrrdFiles2)):
+                print str(self.scene.nrrdFiles2[i])
+       print "end volume list."
+       for i in range(len(self.scene.nrrdFiles2)):
+               self.test.addVolNrrd(self.scene.nrrdFiles2[i])
+        for  i in range(0, len(self.scene.nrrdFiles)):
+                self.test.addSphereNrrd(self.scene.nrrdFiles[i])
+        self.test.loadSphereNrrds()
+       self.test.setVolCMinMax(300, 2100)
+       self.test.loadVolNrrds()
+       self.BuildHistograms()
+
+    def BuildHistograms(self):
+       for i in range(len(self.histoGroups)):
+               print "building histogram: " + self.histoGroups[i].title
+               vol = False
+                if self.histoGroups[i].group == 1:
+                       vol = True
+               histValues1Ptr = SWIGIFYCreateIntArray(100)
+               histValues = []
+               min = SWIGIFYCreateFloat(0)
+               max = SWIGIFYCreateFloat(100)
+               cmin = SWIGIFYCreateFloat(0)
+               cmax = SWIGIFYCreateFloat(100)
+               if (vol == False):
+                       self.test.getHistogram(self.histoGroups[i].varIndex, 
100, histValues1Ptr, min, max)
+               else:
+                       self.test.getVolHistogram(100, histValues1Ptr,min, 
max)
+               dataMin = SWIGIFYGetFloat(min)
+               dataMax = SWIGIFYGetFloat(max)
+               print "dataMin/max: " + str(dataMin) + " " + str(dataMax)
+               for j in range(100):
+                       
histValues.append(SWIGIFYGetIntArrayValue(histValues1Ptr, j))
+                       #print histValues[j]
+               self.histoGroups[i].SetValues(histValues, dataMin, dataMax)
+               if vol == False:
+                       
self.test.getSphereCMinMax(self.histoGroups[i].varIndex, cmin, cmax)
+               else:
+                       self.test.getVolCMinMax(cmin, cmax)     
+               dataCMin = SWIGIFYGetFloat(cmin)
+               dataCMax = SWIGIFYGetFloat(cmax)
+               self.histoGroups[i].SetCMinMax(dataCMin, dataCMax)
+               
+
+    def UpdateColorMap(self, transferF):
+        print "UPDATECOLORMAP"
+       cmap = transferF.cmap
+       t = transferF
+       slices = vector_ColorSlice()
+       t.colors.sort()
+       for i in range(0, len(t.colors)):
+               slices.push_back(ColorSlice(t.colors[i][0], 
RGBAColor(Color(RGBColor(t.colors[i][1], \
+               t.colors[i][2], t.colors[i][3])), t.colors[i][4])))
+       if (cmap != None):
+               cmap.SetColors(slices)
+
+    def OnClick(self, evt):
+        print "clicked main"
+    def OnKeyDown(self, event):
+        print "key down"
+    def OnClickColor(self, evt):
+        dlg = wx.ColourDialog(self)
+        dlg.GetColourData().SetChooseFull(True)
+        
+        if dlg.ShowModal() == wx.ID_OK:
+            color = dlg.GetColourData()
+            
+        dlg.Destroy()
+    def OnClickVisible(self, evt):
+        if self.visible:
+            self.sizer.ShowItems(False)
+            self.sizer.Show(self.visibilityB, True, True)
+            self.visible = False
+        else:
+            self.sizer.ShowItems(True)
+            self.visible = True
+
+    def InitializeScene(self,frame, engine):
+       # Create a scene object.
+       print "warg?\n";
+       scene = manta_new(Scene())
+       eye = manta_new(Vector(0.340429, 0.161851, -0.441882))
+        lookat =     manta_new(   Vector( 0.0411403, 0.0475211, 0.0508046))
+        up =       manta_new( Vector(-0.0893698, 0.980804, 0.173311))
+       fov = 12.0039
+       #TODO: be able to set these in GUI
+       data = manta_new(BasicCameraData(eye,lookat,up,fov,fov))
+       engine.getCamera(0).setBasicCameraData(data)
+       
scene.setBackground(manta_new(ConstantBackground(ColorDB.getNamedColor("SkyBlue3").scaled(0.5))))
+       engine.setShadowAlgorithm(manta_new(NoShadows()))
+
+
+       # Create the checker textures.
+       checker1 = manta_new(CheckerTexture_Color(Color(RGBColor(.6,.6,.6)),
+                                               Color(RGBColor(0,0,0)),
+                                               Vector(1,0,0),
+                                               Vector(0,1,0)))
+
+       constant_color1 = manta_new(Constant_Color(Color(RGBColor(.6,.6,.6))))
+       checker2 = manta_new(CheckerTexture_ColorComponent(0.2, 0.5, 
Vector(1,0,0),Vector(0,1,0)))
+
+       # Create the floor shader.
+       plane_matl = manta_new(Phong(checker1, constant_color1, 32, checker2))
+
+       # Create a group for the scene.
+       world = manta_new(Group())
+
+       # Add the floor
+       floor = manta_new(Parallelogram(plane_matl, Vector(-20,-20,0),
+                                       Vector(40,0,0), Vector(0,40,0)))
+       uniformmap = manta_new(UniformMapper())
+       floor.setTexCoordMapper(uniformmap)
+       self.colorMap1 = colorMap1 = manta_new(RGBAColorMap())
+
+       slices = manta_new(vector_ColorSlice());
+       div = 1.0/255.0;
+       a = 1.0;
+       slices.push_back(ColorSlice(0.0, RGBAColor(Color(RGBColor(0.0, 0.0, 
0.0)), 0*a)));
+       slices.push_back(ColorSlice(0.109804, 
RGBAColor(Color(RGBColor(52*div, 0*div, 0*div)), 0*a)));
+       slices.push_back(ColorSlice(0.2, RGBAColor(Color(RGBColor(102*div, 
2*div, 0)), 0.1*a)));
+       slices.push_back(ColorSlice(0.328571, 
RGBAColor(Color(RGBColor(153*div, 18*div, 0)), 0.216667*a)));
+       slices.push_back(ColorSlice(0.4, RGBAColor(Color(RGBColor(200*div, 
41*div, 0)), 0.23*a)));
+       slices.push_back(ColorSlice(0.5, RGBAColor(Color(RGBColor(230*div, 
71*div, 0)), 0.27*a)));
+       slices.push_back(ColorSlice(0.618367, 
RGBAColor(Color(RGBColor(255*div, 120*div, 0)) , 0.3375*a)));
+       slices.push_back(ColorSlice(0.68, RGBAColor(Color(RGBColor(255*div, 
163*div, 20*div)) , 0.35*a)));
+       slices.push_back(ColorSlice(0.72, RGBAColor(Color(RGBColor(255*div, 
204*div, 55*div)) , 0.37*a)));
+       slices.push_back(ColorSlice(0.79, RGBAColor(Color(RGBColor(255*div, 
228*div, 80*div)) , 0.39*a)));
+       slices.push_back(ColorSlice(0.85, RGBAColor(Color(RGBColor(255*div, 
247*div, 120*div)), 0.43*a)));
+       slices.push_back(ColorSlice(0.92, RGBAColor(Color(RGBColor(255*div, 
255*div, 180*div)), 0.47*a)));
+       slices.push_back(ColorSlice(1.0, RGBAColor(Color(RGBColor(255*div, 
255*div, 255*div)) , 0.5*a)));
+       self.volCMap = manta_new(RGBAColorMap(slices, 64));
+
+
+       self.test = manta_new(CDTest(scene, engine));
+        self.test.initScene();
+       self.test.setVolCMap(self.volCMap);
+        self.scene.test = self.test
+        self.scene.isPlaying = True
+       self.scene.engine = engine
+
+
+       histValues1Ptr = SWIGIFYCreateIntArray(100)
+       histValues1 = []
+       dataMin1 = -1.1
+       dataMax1 = 2.2
+       min = SWIGIFYCreateDouble(0)
+       max = SWIGIFYCreateDouble(100)
+       dataMin1 = SWIGIFYGetDouble(min)
+        dataMax1 = SWIGIFYGetDouble(max)
+        print "datamin: " + str(dataMin1)  + " datamax: " + str(dataMax1)
+       for i in range(0,100):
+               histValues1.append(5);
+
+       scene.getRenderParameters().maxDepth = 5
+
+
+       engine.setScene( scene )
+
+       #################init the GUI######################
+
+       colors = []
+       colors2 = []
+       colors3 = []
+       colors4 = []
+       colors5 = []
+       colors6 = []
+       colors7 = []
+       colors8 = []
+       colors9 = []
+       self.sphereVolCMaps = []
+       for j in range(8):
+          self.sphereVolCMaps.append(manta_new(RGBAColorMap(1)))
+       self.t0 = t0 = TransferF.TransferF(self, colors9, 0, "volume", 
self.volCMap)
+       self.defaultTransferF = TransferF.TransferF(self, colors, 1, "empty", 
self.sphereVolCMaps[0])
+       self.transferFunctions = []
+       self.transferFunctions.append(self.t0)
+
+       self.tPanel = tPanel = TransferF.TransferFGroup(self, 300, 100, 
self.defaultTransferF, "empty")
+       self.scene.tPanel = tPanel
+       tPanel.SetBackgroundColour(wx.Colour(90,90,90))
+       self.Bind(wx.EVT_LEFT_DOWN, self.OnKeyDown)
+
+       self.vs = vs = wx.BoxSizer( wx.VERTICAL )
+       data = []
+       for i in range(0, 1000):
+            data.append(( random.random() + random.random())/2.0 + 0.0)
+       color = wx.Colour(90,90,90)
+        self.scene.histoVS = hvs = wx.BoxSizer(wx.VERTICAL)
+        self.scene.frame = self
+       histoGroup0 = Histogram.HistogramGroup(self, histValues1, dataMin1, 
dataMax1, 300, 40.0, t0, tPanel, self.scene, 8, "volume")
+       histoGroup0.group = 1
+       histoGroup0.SetBackgroundColour(color)
+       tPanel.transferFPanel.SetHistogram(histoGroup0.histogram)
+       self.histoGroups = []
+       self.histoGroups.append(histoGroup0)
+        vs.Add(hvs,0,wx.ALIGN_CENTER|wx.ALL,1)
+
+       animCtrlTitle = wx.StaticBox(self, -1)
+       animCtrlSizer = wx.StaticBoxSizer(animCtrlTitle, wx.HORIZONTAL)
+       self.backBmp = wx.Bitmap("images/back.png.32x32", wx.BITMAP_TYPE_PNG)
+       self.playBmp = wx.Bitmap("images/play.png.64x64", wx.BITMAP_TYPE_PNG)
+       self.pauseBmp = wx.Bitmap("images/pause.png.64x64", 
wx.BITMAP_TYPE_PNG)
+       self.forwardBmp = wx.Bitmap("images/forward.png.32x32", 
wx.BITMAP_TYPE_PNG)
+       self.playB = wx.BitmapButton(self, -1, self.pauseBmp, (20,20), 
style=wx.NO_BORDER)
+       self.forwardB = wx.BitmapButton(self, -1, self.forwardBmp, (20,20), 
style=wx.NO_BORDER)
+       self.backB = wx.BitmapButton(self, -1, self.backBmp, (20,20), 
style=wx.NO_BORDER)
+       
+       self.Bind(wx.EVT_BUTTON, self.OnClickBack, self.backB)
+       self.Bind(wx.EVT_BUTTON, self.OnClickPlay, self.playB)
+       self.Bind(wx.EVT_BUTTON, self.OnClickForward, self.forwardB)
+       animCtrlSizer.Add(self.backB, -1, wx.ALIGN_CENTRE, 1)
+       animCtrlSizer.Add(self.playB, -1, wx.ALIGN_CENTRE, 1)
+       animCtrlSizer.Add(self.forwardB, -1, wx.ALIGN_CENTRE, 1)
+       vs.Add(animCtrlSizer, wx.ALIGN_CENTRE, 5)
+
+       vs.Layout()
+
+       self.SetSizer( vs )
+       vs.Fit( self )
+       self.LayoutWindow()
+#TODO: values hardcoded for now
+       
self.scene.nrrdFiles2.append("/usr/sci/data/Medical/VFemHead/vfhead-crop.nhdr")
+       self.scene.ridx = 6
+       self.scene.cidx = 4
+       self.volCMap.scaleAlphas(0.00125)
+
+    def LayoutWindow(self):
+       self.vs = vs = wx.BoxSizer( wx.VERTICAL )
+        self.scene.histoVS = hvs = wx.BoxSizer(wx.VERTICAL)
+       for i in range(len(self.histoGroups)):
+                hvs.Add(self.histoGroups[i], 0, wx.ALIGN_CENTER, 1)
+        hvs.Add(self.tPanel, 0, wx.ALIGN_CENTRE|wx.ALL, 1 )
+       vs.Add(hvs,0,wx.ALIGN_CENTER|wx.ALL,1)
+
+       animCtrlTitle = wx.StaticBox(self, -1)
+        animCtrlSizer = wx.StaticBoxSizer(animCtrlTitle, wx.HORIZONTAL)
+       animCtrlSizer.Add(self.backB, -1, wx.ALIGN_CENTRE, 1)
+        animCtrlSizer.Add(self.playB, -1, wx.ALIGN_CENTRE, 1)
+        animCtrlSizer.Add(self.forwardB, -1, wx.ALIGN_CENTRE, 1)
+        vs.Add(animCtrlSizer, wx.ALIGN_CENTRE, 5)
+
+       vs.Layout()
+       self.SetSizer(vs)
+       vs.Fit(self)
+       self.Refresh()
+
+    def OnClickBack(self, evt):
+       self.test.backAnimation()
+
+    def OnClickPlay(self, evt):
+       if self.scene.isPlaying:
+               self.test.pauseAnimation()
+               self.scene.isPlaying = False
+               self.playB.SetBitmapFocus(self.playBmp)
+               self.playB.SetBitmapLabel(self.playBmp)
+               self.playB.SetBitmapDisabled(self.playBmp)
+       else:
+               self.test.resumeAnimation()
+               self.scene.isPlaying = True
+               self.playB.SetBitmapFocus(self.pauseBmp)
+               self.playB.SetBitmapLabel(self.pauseBmp)
+               self.playB.SetBitmapDisabled(self.pauseBmp)
+
+    def OnClickForward(self, evt):
+       self.test.forwardAnimation()
+
+# Re:-create the default scene using the example texture.
+def initialize_scene( frame, engine ):
+    frame = MyFrame(None, -1, "Histogram")
+    frame.Show(True)   
+    frame.InitializeScene(frame, engine)       
+    
+
+def usage():
+    print "Usage: python test.py [options]"
+    print "Where options contains one or more of:"
+    print "-n --np=<threads>"
+
+def main():
+
+   num_workers = 1
+   
+   # Parse command line options. Note these have to conform to getopt
+   # So -np would be parsed as -n <space> p. Use --np=<threads> instead.
+   print sys.argv
+   
+
+    
###########################################################################
+    # Create the application.
+   app = wxManta.MantaApp( initialize_scene,
+                            num_workers, (512,512), False, None)
+
+
+    
###########################################################################
+    # Perform any additional setup
+
+    # Start rendering.
+   app.MainLoop()
+
+if __name__ == "__main__":
+    print "starting\n"
+    main()
+
+
+

Added: trunk/scenes/csafe/python/csafe_demo.cfg
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/python/csafe_demo.cfg    Wed Jan  9 18:28:28 2008
@@ -0,0 +1,281 @@
+[Transfer Function]
+volume
+0
+13
+0.0 0.0 0.0 0.0 0.0
+0.10980399698 0.203921571374 0.0 0.0 0.0
+0.20000000298 0.40000000596 0.00784313771874 0.0 0.10000000149
+0.328570991755 0.600000023842 0.0705882385373 0.0 0.216666996479
+0.40000000596 0.784313738346 0.160784319043 0.0 0.230000004172
+0.5 0.901960790157 0.278431385756 0.0 0.270000010729
+0.618367016315 1.0 0.470588237047 0.0 0.33750000596
+0.680000007153 1.0 0.639215707779 0.0784313753247 0.34999999404
+0.72000002861 1.0 0.800000011921 0.215686276555 0.370000004768
+0.790000021458 1.0 0.89411765337 0.313725501299 0.389999985695
+0.850000023842 1.0 0.96862745285 0.470588237047 0.430000007153
+0.920000016689 1.0 1.0 0.705882370472 0.469999998808
+1.0 1.0 1.0 1.0 0.5
+
+
+[Transfer Function]
+x
+1
+12
+0.0 0.0 0.0 1.0 1.0
+0.0909090936184 0.0 0.40000000596 1.0 1.0
+0.181818187237 0.0 0.800000011921 1.0 1.0
+0.272727280855 0.0 1.0 0.800000011921 1.0
+0.363636374474 0.0 1.0 0.40000000596 1.0
+0.454545468092 0.0 1.0 0.0 1.0
+0.54545456171 0.40000000596 1.0 0.0 1.0
+0.636363625526 0.800000011921 1.0 0.0 1.0
+0.727272748947 1.0 0.917647063732 0.0 1.0
+0.818181872368 1.0 0.800000011921 0.0 1.0
+0.909090936184 1.0 0.40000000596 0.0 1.0
+1.0 1.0 0.0 0.0 1.0
+
+
+[Transfer Function]
+y
+2
+12
+0.0 0.0 0.0 1.0 1.0
+0.0909090936184 0.0 0.40000000596 1.0 1.0
+0.181818187237 0.0 0.800000011921 1.0 1.0
+0.272727280855 0.0 1.0 0.800000011921 1.0
+0.363636374474 0.0 1.0 0.40000000596 1.0
+0.454545468092 0.0 1.0 0.0 1.0
+0.54545456171 0.40000000596 1.0 0.0 1.0
+0.636363625526 0.800000011921 1.0 0.0 1.0
+0.727272748947 1.0 0.917647063732 0.0 1.0
+0.818181872368 1.0 0.800000011921 0.0 1.0
+0.909090936184 1.0 0.40000000596 0.0 1.0
+1.0 1.0 0.0 0.0 1.0
+
+
+[Transfer Function]
+z
+3
+12
+0.0 0.0 0.0 1.0 1.0
+0.0909090936184 0.0 0.40000000596 1.0 1.0
+0.181818187237 0.0 0.800000011921 1.0 1.0
+0.272727280855 0.0 1.0 0.800000011921 1.0
+0.363636374474 0.0 1.0 0.40000000596 1.0
+0.454545468092 0.0 1.0 0.0 1.0
+0.54545456171 0.40000000596 1.0 0.0 1.0
+0.636363625526 0.800000011921 1.0 0.0 1.0
+0.727272748947 1.0 0.917647063732 0.0 1.0
+0.818181872368 1.0 0.800000011921 0.0 1.0
+0.909090936184 1.0 0.40000000596 0.0 1.0
+1.0 1.0 0.0 0.0 1.0
+
+
+[Transfer Function]
+p.mass
+4
+12
+0.0 0.0 0.0 1.0 1.0
+0.0909090936184 0.0 0.40000000596 1.0 1.0
+0.181818187237 0.0 0.800000011921 1.0 1.0
+0.272727280855 0.0 1.0 0.800000011921 1.0
+0.363636374474 0.0 1.0 0.40000000596 1.0
+0.454545468092 0.0 1.0 0.0 1.0
+0.54545456171 0.40000000596 1.0 0.0 1.0
+0.636363625526 0.800000011921 1.0 0.0 1.0
+0.727272748947 1.0 0.917647063732 0.0 1.0
+0.818181872368 1.0 0.800000011921 0.0 1.0
+0.909090936184 1.0 0.40000000596 0.0 1.0
+1.0 1.0 0.0 0.0 1.0
+
+
+[Transfer Function]
+p.temperature
+5
+12
+0.0 0.0 0.0 1.0 1.0
+0.0909090936184 0.0 0.40000000596 1.0 1.0
+0.181818187237 0.0 0.800000011921 1.0 1.0
+0.272727280855 0.0 1.0 0.800000011921 1.0
+0.363636374474 0.0 1.0 0.40000000596 1.0
+0.454545468092 0.0 1.0 0.0 1.0
+0.54545456171 0.40000000596 1.0 0.0 1.0
+0.636363625526 0.800000011921 1.0 0.0 1.0
+0.727272748947 1.0 0.917647063732 0.0 1.0
+0.818181872368 1.0 0.800000011921 0.0 1.0
+0.909090936184 1.0 0.40000000596 0.0 1.0
+1.0 1.0 0.0 0.0 1.0
+
+
+[Transfer Function]
+p.stress Trace/3
+6
+12
+0.0 0.0 0.0 1.0 1.0
+0.0909090936184 0.0 0.40000000596 1.0 1.0
+0.181818187237 0.0 0.800000011921 1.0 1.0
+0.272727280855 0.0 1.0 0.800000011921 1.0
+0.363636374474 0.0 1.0 0.40000000596 1.0
+0.454545468092 0.0 1.0 0.0 1.0
+0.54545456171 0.40000000596 1.0 0.0 1.0
+0.636363625526 0.800000011921 1.0 0.0 1.0
+0.727272748947 1.0 0.917647063732 0.0 1.0
+0.818181872368 1.0 0.800000011921 0.0 1.0
+0.909090936184 1.0 0.40000000596 0.0 1.0
+1.0 1.0 0.0 0.0 1.0
+
+
+[Transfer Function]
+R
+7
+12
+0.0 0.0 0.0 1.0 1.0
+0.0909090936184 0.0 0.40000000596 1.0 1.0
+0.181818187237 0.0 0.800000011921 1.0 1.0
+0.272727280855 0.0 1.0 0.800000011921 1.0
+0.363636374474 0.0 1.0 0.40000000596 1.0
+0.454545468092 0.0 1.0 0.0 1.0
+0.54545456171 0.40000000596 1.0 0.0 1.0
+0.636363625526 0.800000011921 1.0 0.0 1.0
+0.727272748947 1.0 0.917647063732 0.0 1.0
+0.818181872368 1.0 0.800000011921 0.0 1.0
+0.909090936184 1.0 0.40000000596 0.0 1.0
+1.0 1.0 0.0 0.0 1.0
+
+
+[Transfer Function]
+Radius from p.volume
+8
+12
+0.0 0.0 0.0 1.0 1.0
+0.0909090936184 0.0 0.40000000596 1.0 1.0
+0.181818187237 0.0 0.800000011921 1.0 1.0
+0.272727280855 0.0 1.0 0.800000011921 1.0
+0.363636374474 0.0 1.0 0.40000000596 1.0
+0.454545468092 0.0 1.0 0.0 1.0
+0.54545456171 0.40000000596 1.0 0.0 1.0
+0.636363625526 0.800000011921 1.0 0.0 1.0
+0.727272748947 1.0 0.917647063732 0.0 1.0
+0.818181872368 1.0 0.800000011921 0.0 1.0
+0.909090936184 1.0 0.40000000596 0.0 1.0
+1.0 1.0 0.0 0.0 1.0
+
+
+[Transfer Function]
+Material Index
+9
+12
+0.0 0.0 0.0 1.0 1.0
+0.0909090936184 0.0 0.40000000596 1.0 1.0
+0.181818187237 0.0 0.800000011921 1.0 1.0
+0.272727280855 0.0 1.0 0.800000011921 1.0
+0.363636374474 0.0 1.0 0.40000000596 1.0
+0.454545468092 0.0 1.0 0.0 1.0
+0.54545456171 0.40000000596 1.0 0.0 1.0
+0.636363625526 0.800000011921 1.0 0.0 1.0
+0.727272748947 1.0 0.917647063732 0.0 1.0
+0.818181872368 1.0 0.800000011921 0.0 1.0
+0.909090936184 1.0 0.40000000596 0.0 1.0
+1.0 1.0 0.0 0.0 1.0
+
+
+[Histogram]
+volume
+0
+1
+300.0 2100.0
+300.0 2100.0
+288.0 2088.0
+0
+
+
+[Histogram]
+x
+1
+0
+-0.0613283030689 0.0587040632963
+-0.0613283030689 0.0587040632963
+-0.0612165068462 0.0576155358553
+1
+
+
+[Histogram]
+y
+2
+0
+3.517361165e-06 0.0709128901362
+3.517361165e-06 0.0709128901362
+0.0 0.0709093727751
+2
+
+
+[Histogram]
+z
+3
+0
+3.00736237129e-12 9.78749994829e-07
+3.00736237129e-12 9.78749994829e-07
+-4.89373493733e-07 1.4681204812e-06
+3
+
+
+[Histogram]
+p.mass
+4
+0
+17.9502124786 5116.43701172
+17.9502124786 5116.43701172
+0.0 5098.48679924
+4
+
+
+[Histogram]
+p.temperature
+5
+0
+-23199981568.0 13832486912.0
+-23199981568.0 13832486912.0
+-22960130457.6 13702013337.6
+5
+
+
+[Histogram]
+p.stress Trace/3
+6
+0
+2.95434688269e-06 0.000362312624929
+2.95434688269e-06 0.000362312624929
+0.0 0.000359358278047
+6
+
+
+[Histogram]
+Radius from p.volume
+8
+0
+0.0 1.0
+0.0 1.0
+0.0 1.0
+8
+
+
+[Histogram]
+Material Index
+9
+0
+-3.40282346639e+38 3.40282346639e+38
+-3.40282346639e+38 3.40282346639e+38
+-3.40282346639e+38 3.40282346639e+38
+9
+
+
+[Scene Properties]
+10.0
+6
+0.001
+4
+8
+1
+/home/collab/brownlee/Data-Explosion/vol/temp_CC_M02_0002.nrrd
+1
+/home/collab/brownlee/Data-Explosion/sphere/spheredata002.crop.nhdr

Added: trunk/scenes/csafe/src/CDGridSpheres.cc
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/src/CDGridSpheres.cc     Wed Jan  9 18:28:28 2008
@@ -0,0 +1,1056 @@
+
+#include <Core/Color/RegularColorMap.h>
+#include <Core/Math/MiscMath.h>
+#include <Core/Math/Trig.h>
+#include <Core/Math/Expon.h>
+#include <Interface/Light.h>
+#include <Interface/LightSet.h>
+#include <Interface/Primitive.h>
+#include <Interface/Packet.h>
+#include <Interface/RayPacket.h>
+#include <Interface/AmbientLight.h>
+#include <Interface/Context.h>
+#include <Interface/ShadowAlgorithm.h>
+#include "CDGridSpheres.h"
+#include <Model/Textures/Constant.h>
+#include <Core/Containers/Array1.h>
+#include <Core/Math/MinMax.h>
+#include <Core/Util/Timer.h>
+
+#include <iostream>
+using std::cerr;
+
+#include <float.h>
+
+using namespace Manta;
+
+CDGridSpheres::CDGridSpheres(float* spheres, int nspheres, int nvars, int 
ncells,
+                         int depth, Real radius, int ridx, RGBAColorMap* 
cmap,
+                         int cidx) :
+  spheres(spheres), nspheres(nspheres), nvars(nvars),
+  radius(radius), ridx(ridx), ncells(ncells), depth(depth),
+  cmap(cmap), cidx(cidx)
+{
+  cerr<<"Initializing GridSpheres\n";
+
+  if (radius <= 0) {
+    if (ridx <= 0)
+      cerr<<"Resetting default radius to 1\n";
+    radius=1;
+  }
+
+  // Compute inverses
+  inv_radius=1/static_cast<Real>(radius);
+  inv_ncells=1/static_cast<Real>(ncells);
+
+  cerr<<"Recomputing min/max for GridSpheres\n";
+
+  // Initialize min/max arrays
+  min=new float[nvars];
+  max=new float[nvars];
+  cmin = new float[nvars];
+  cmax = new float[nvars];
+  clipMins = new float[nvars];
+  clipMaxs = new float[nvars];
+
+  for (int j=0; j<nvars; ++j) {
+    min[j]=FLT_MAX;
+    max[j]=-FLT_MAX;
+    clipMins[j] = -FLT_MAX;
+    clipMaxs[j] = FLT_MAX;
+    cmin[j] = min[j];
+    cmax[j] = max[j];
+  }
+
+  // Find min/max values
+  float* data=spheres;
+  for (int i=0; i<nspheres; ++i) {
+    for (int j=0; j<nvars; ++j) {
+      min[j]=Min(min[j], data[j]);
+      max[j]=Max(max[j], data[j]);
+    }
+
+    data += nvars;
+  }
+  for(int j = 0; j<nvars;j++)
+{
+       cmin[j] = min[j];
+       cmax[j] = max[j];
+}
+
+  counts=0;
+  cells=0;
+
+#ifdef USE_FUNCTION_POINER
+  intersectSphere=0;
+#endif
+}
+
+CDGridSpheres::~CDGridSpheres()
+{
+  delete [] min;
+  delete [] max;
+  delete [] cmin;
+  delete [] cmax;
+  delete [] clipMins;
+  delete [] clipMaxs;
+
+  if (counts)
+    delete[] counts;
+
+  if (cells)
+    delete[] cells;
+
+  if (macrocells)
+    delete [] macrocells;
+}
+
+void CDGridSpheres::preprocess(const PreprocessContext& context)
+{
+  // Preprocess material
+  LitMaterial::preprocess(context);
+
+  // Build grid
+  cerr<<"Building GridSpheres\n";
+
+  WallClockTimer timer;
+  timer.start();
+
+  cerr<<"  min:  ("<<min[0]<<", "<<min[1]<<", "<<min[2]<<")\n";
+  cerr<<"  max:  ("<<max[0]<<", "<<max[1]<<", "<<max[2]<<")\n";
+
+  // Determine the maximum radius
+  float max_radius;
+  if (ridx>0) {
+    cerr<<"  GridSpheres::preprocess - ridx="<<ridx<<'\n';
+    max_radius=max[ridx];
+
+    if (max_radius <= 0) {
+      cerr<<"  max_radius ("<<max_radius<<") <= 0, setting to default radius 
("
+          <<radius<<")\n";
+      max_radius=radius;
+    }
+  } else
+    max_radius=radius;
+
+  // Bound the spheres
+  computeBounds(context, bounds);
+  diagonal=bounds.diagonal();
+  inv_diagonal=Vector(1/diagonal.x(), 1/diagonal.y(), 1/diagonal.z());
+
+  // Determine grid size
+  totalcells=1;
+  for (int i=0; i<=depth; ++i)
+    totalcells *= ncells;
+
+  int totalsize=totalcells*totalcells*totalcells;
+  cerr<<"  Computing "<<totalcells<<'x'<<totalcells<<'x'<<totalcells
+      <<" grid ("<<totalsize<<" cells total)\n";
+
+  // Clear grid data
+  if (counts)
+    delete[] counts;
+
+  if (cells)
+    delete[] cells;
+
+  // Allocate and initialize counts
+  counts=new int[2*totalsize];
+  bzero(counts, 2*totalsize*sizeof(int));
+
+  cerr<<"    0/6:  Allocation took "<<timer.time()<<" seconds\n";
+  
+  // Generate map
+  int* map=new int[totalsize];
+  int idx=0;
+  for (int x=0; x<totalcells; ++x) {
+    for (int y=0; y<totalcells; ++y) {
+      for (int z=0; z<totalcells; ++z) {
+       map[idx++]=mapIdx(x, y, z, depth);
+      }
+    }
+  }
+
+  Real stime=timer.time();
+  cerr<<"    1/6:  Generating map took "<<stime<<" seconds\n";
+  
+  // Compute cell counts
+  float* data=spheres;
+  int tc2=totalcells*totalcells;
+  for (int i=0; i<nspheres; ++i) {
+    Real ctime=timer.time();
+    if (ctime - stime>5.0) {
+      cerr<<i<<"/"<<nspheres<<'\n';
+      stime=ctime;
+    }
+
+    // Compute cell overlap
+    Vector current_radius;
+    if (ridx>0) {
+      if (data[ridx] <= 0)
+        continue;
+
+      current_radius=Vector(data[ridx], data[ridx], data[ridx]);
+    } else {
+      current_radius=Vector(radius, radius, radius);
+    }
+
+    Vector center(data[0], data[1], data[2]);
+    BBox box(center - current_radius, center + current_radius);
+    int sx, sy, sz, ex, ey, ez;
+    transformToLattice(box, sx, sy, sz, ex, ey, ez);
+
+    int idx_x=sx*tc2;
+    for (int x=sx; x<=ex; ++x) {
+      int idx_y=idx_x + sy*totalcells;
+      idx_x += tc2;
+      for (int y=sy; y<=ey; ++y) {
+       int idx=idx_y + sz;
+       idx_y += totalcells;
+       for (int z=sz; z<=ez; ++z) {
+         int aidx=map[idx++];
+         counts[2*aidx + 1]++;
+       }
+      }
+    }
+
+    data += nvars;
+  }
+  
+  cerr<<"    2/6:  Counting cells took "<<timer.time()<<" seconds\n";
+
+  int total=0;
+  for (int i=0; i<totalsize; ++i) {
+    int count=counts[2*i + 1];
+    counts[2*i]=total;
+    total += count;
+  }
+
+  // Allocate cells
+  cerr<<"  Allocating "<<total<<" grid cells ("
+      <<static_cast<Real>(total)/nspheres<<" per object, "
+      <<static_cast<Real>(total)/totalsize<<" per cell)\n";
+
+  cells=new int[total];
+  for (int i=0; i<total; ++i)
+    cells[i]=-1;
+
+  stime=timer.time();
+  cerr<<"    3/6:  Calculating offsets took "<<stime<<" seconds\n";
+
+  // Populate the grid
+  Array1<int> current(totalsize);
+  current.initialize(0);
+  data=spheres;
+  for (int i=0; i<nspheres; ++i) {
+    Real ctime=timer.time();
+    if (ctime - stime>5.0) {
+      cerr<<i<<"/"<<nspheres<<'\n';
+      stime=ctime;
+    }
+
+    // Compute cell overlap
+    Vector current_radius;
+    if (ridx>0) {
+      if (data[ridx] <= 0)
+        continue;
+
+      current_radius=Vector(data[ridx], data[ridx], data[ridx]);
+    } else {
+      current_radius=Vector(radius, radius, radius);
+    }
+
+    Vector center(data[0], data[1], data[2]);
+    BBox box(center - current_radius, center + current_radius);
+    int sx, sy, sz, ex, ey, ez;
+    transformToLattice(box, sx, sy, sz, ex, ey, ez);
+
+    for (int x=sx; x<=ex; ++x) {
+      for (int y=sy; y<=ey; ++y) {
+       int idx=totalcells*(totalcells*x + y) + sz;
+       for (int z=sz; z<=ez; ++z) {
+         int aidx=map[idx++];
+         int cur=current[aidx]++;
+         int pos=counts[2*aidx] + cur;
+         cells[pos]=nvars*i;
+       }
+      }
+    }
+
+    data += nvars;
+  }
+
+  delete [] map;
+
+  cerr<<"    4/6:  Filling grid took "<<timer.time()<<" seconds\n";
+
+  // Verify the grid
+  for (int i=0; i<totalsize; ++i) {
+    if (current[i] != counts[2*i + 1]) {
+      cerr<<"Fatal error:  current="<<current[i]<<", but counts="
+          <<counts[2*i + 1]<<'\n';
+      exit(1);
+    }
+  }
+
+  for (int i=0; i<total; ++i) {
+    if (cells[i]==-1) {
+      cerr<<"Fatal error:  cells["<<i<<"] == -1\n";
+      exit(1);
+    }
+  }
+
+  cerr<<"    5/6:  Verifying grid took "<<timer.time()<<" seconds\n";
+
+  // Build the macrocells
+  if (depth > 0) {
+    macrocells=new MCell*[depth + 1];
+    macrocells[0]=0;
+
+    int size=ncells*ncells*ncells;
+    for (int d=depth; d>=1; d--) {
+      MCell* mcell=new MCell[size];
+      macrocells[d]=mcell;
+
+      float* mm=new float[2*nvars*size];
+      for (int i=0; i<size; ++i) {
+        // Minimum
+       mcell->min=mm;
+       mm += nvars;
+
+        // Maximum
+       mcell->max=mm;
+       mm += nvars;
+
+       mcell++;
+      }
+
+      size *= ncells*ncells*ncells;
+    }
+
+    MCell top;
+    fillMCell(top, depth, 0);
+    if (top.nspheres != total) {
+      cerr<<"Fatal error:  macrocell construction went wrong\n";
+      cerr<<"  Top macrocell:   "<<top.nspheres<<'\n';
+      cerr<<"  Total nspheres:  "<<total<<'\n';
+      exit(1);
+    }
+
+    cerr<<"    6/6:  Calculating macrocells took "<<timer.time()<<" 
seconds\n";
+  } else {
+    macrocells=0;
+    cerr<<"    6/6:  Macrocell hierarchy not built (depth == 0)\n";
+  }
+
+  cerr<<"Done building GridSpheres\n";
+}
+
+void CDGridSpheres::computeBounds(const PreprocessContext& context,
+                                BBox& bbox) const
+{
+  // Determine the maximum radius
+  float max_radius;
+  if (ridx>0) {
+    max_radius=max[ridx];
+
+    if (max_radius <= 0) {
+      cerr<<"  max_radius ("<<max_radius<<") <= 0, setting to default radius 
("
+          <<radius<<")\n";
+      max_radius=radius;
+    }
+  } else
+    max_radius=radius;
+
+  // Bound the spheres
+  Vector mr(max_radius, max_radius, max_radius);
+  bbox.reset(Vector(min[0], min[1], min[2]) - mr,
+             Vector(max[0], max[1], max[2]) + mr);
+
+  const Vector eps3(1.e-3, 1.e-3, 1.e-3);
+  bbox.extendByPoint(bbox.getMin() - eps3);
+  bbox.extendByPoint(bbox.getMax() + eps3);
+
+  Vector diag(bbox.diagonal());
+  bbox.extendByPoint(bbox.getMin() - diag*eps3);
+  bbox.extendByPoint(bbox.getMax() + diag*eps3);
+}
+
+void CDGridSpheres::intersect(const RenderContext& context, RayPacket& rays) 
const
+{
+  Vector bmin=bounds.getMin();
+  Vector bmax=bounds.getMax();
+
+  rays.computeInverseDirections();
+  rays.computeSigns();
+
+#ifdef USE_OPTIMIZED_FCNS
+  // Determine appropriate sphere intersection function for this ray packet
+  SphereIntersectFcn intersectSphere = 
&CDGridSpheres::intersectSphereDefault;
+
+  switch (rays.getAllFlags() & (RayPacket::ConstantOrigin |
+                                RayPacket::NormalizedDirections)) {
+  case RayPacket::ConstantOrigin|RayPacket::NormalizedDirections:
+    // Rays of constant origin and normalized directions
+    intersectSphere=&CDGridSpheres::intersectSphereCOND;
+    break;
+  case RayPacket::ConstantOrigin:
+    // Rays of constant origin for not normalized directions
+    intersectSphere=&CDGridSpheres::intersectSphereCO;
+    break;
+  case RayPacket::NormalizedDirections:
+    // Rays of non-constant origin and normalized directions
+    intersectSphere=&CDGridSpheres::intersectSphereND;
+    break;
+  case 0:
+    // Rays of non-constant origin and non-normalized directions
+    intersectSphere=&CDGridSpheres::intersectSphereDefault;
+    break;
+  }
+#endif // USE_OPTIMIZED_FCNS
+
+  for (int i=rays.begin(); i<rays.end(); ++i) {
+    const Vector origin(rays.getOrigin(i));
+    const Vector direction(rays.getDirection(i));
+    const Vector inv_direction(rays.getInverseDirection(i));
+
+    // Intersect ray with bounding box
+    Real tnear, tfar;
+    int di_dx;
+    int ddx;
+    int didx_dx;
+    int stop_x;
+    if (direction.x()>0) {
+      tnear=(bmin.x() - origin.x())*inv_direction.x();
+      tfar=(bmax.x() - origin.x())*inv_direction.x();
+      di_dx=1;
+      ddx=1;
+      didx_dx=ncells*ncells;
+      stop_x=ncells;
+    } else {
+      tnear=(bmax.x() - origin.x())*inv_direction.x();
+      tfar=(bmin.x() - origin.x())*inv_direction.x();
+      di_dx=-1;
+      ddx=0;
+      didx_dx=-ncells*ncells;
+      stop_x=-1;
+    }
+
+    Real y0, y1;
+    int di_dy;
+    int ddy;
+    int didx_dy;
+    int stop_y;
+    if (direction.y()>0) {
+      y0=(bmin.y() - origin.y())*inv_direction.y();
+      y1=(bmax.y() - origin.y())*inv_direction.y();
+      di_dy=1;
+      ddy=1;
+      didx_dy=ncells;
+      stop_y=ncells;
+    } else {
+      y0=(bmax.y() - origin.y())*inv_direction.y();
+      y1=(bmin.y() - origin.y())*inv_direction.y();
+      di_dy=-1;
+      ddy=0;
+      didx_dy=-ncells;
+      stop_y=-1;
+    }
+
+    if (y0>tnear)
+      tnear=y0;
+    if (y1<tfar)
+      tfar=y1;
+    if (tfar<tnear)
+      continue;
+
+    Real z0, z1;
+    int di_dz;
+    int ddz;
+    int didx_dz;
+    int stop_z;
+    if (direction.z()>0) {
+      z0=(bmin.z() - origin.z())*inv_direction.z();
+      z1=(bmax.z() - origin.z())*inv_direction.z();
+      di_dz=1;
+      ddz=1;
+      didx_dz=1;
+      stop_z=ncells;
+    } else {
+      z0=(bmax.z() - origin.z())*inv_direction.z();
+      z1=(bmin.z() - origin.z())*inv_direction.z();
+      di_dz=-1;
+      ddz=0;
+      didx_dz=-1;
+      stop_z=-1;
+    }
+
+    if (z0>tnear)
+      tnear=z0;
+    if (z1<tfar)
+      tfar=z1;
+    if (tfar<tnear)
+      continue;
+    if (tfar<static_cast<Real>(1.e-6))
+      continue;
+    if (tnear < 0)
+      tnear=0;
+
+    // Compute lattice coordinates
+    Vector p=origin + tnear*direction;
+    Vector lattice=(p - bmin)*inv_diagonal;
+    int ix=Clamp(static_cast<int>(lattice.x()*ncells), 0, ncells - 1);
+    int iy=Clamp(static_cast<int>(lattice.y()*ncells), 0, ncells - 1);
+    int iz=Clamp(static_cast<int>(lattice.z()*ncells), 0, ncells - 1);
+
+    // Compute cell index
+    int idx=(ix*ncells + iy)*ncells + iz;
+
+    // Compute delta t in each direction
+    Real dt_dx=di_dx*diagonal.x()*inv_ncells*inv_direction.x();
+    Real dt_dy=di_dy*diagonal.y()*inv_ncells*inv_direction.y();
+    Real dt_dz=di_dz*diagonal.z()*inv_ncells*inv_direction.z();
+
+    // Compute far edges of the cell
+    Vector next(ix + ddx, iy + ddy, iz + ddz);
+    Vector far=diagonal*next*inv_ncells + bmin;
+
+    // Compute t values at far edges of the cell
+    Vector tnext=(far - origin)*inv_direction;
+
+    // Compute cell corner and direction
+    Vector factor(ncells*inv_diagonal);
+    Vector cellcorner((origin - bmin)*factor);
+    Vector celldir(direction*factor);
+
+    // Traverse the hierarchy
+    traverse(i, rays, depth, tnear, ix, iy, iz, idx, dt_dx, dt_dy, dt_dz,
+             tnext.x(), tnext.y(), tnext.z(),
+             cellcorner, celldir,
+             di_dx, di_dy, di_dz, didx_dx, didx_dy, didx_dz,
+#ifdef USE_OPTIMIZED_FCNS
+             stop_x, stop_y, stop_z, intersectSphere);
+#else
+             stop_x, stop_y, stop_z);
+#endif // USE_OPTIMIZED_FCNS
+  }
+}
+
+void CDGridSpheres::computeNormal(const RenderContext& context,
+                                RayPacket& rays) const
+{
+  rays.computeHitPositions();
+  for (int i=int(rays.begin()); i<int(rays.end()); ++i) {
+    float* data=spheres + rays.scratchpad<int>(i);
+    Vector n=rays.getHitPosition(i) - Vector(data[0], data[1], data[2]);
+
+    if (ridx>0) {
+      if (data[ridx] <= 0)
+        n *= inv_radius;
+      else
+        n /= data[ridx];
+    } else {
+      n *= inv_radius;
+    }
+
+    rays.setNormal(i, n);
+  }
+
+  rays.setFlag(RayPacket::HaveUnitNormals);
+}
+
+void CDGridSpheres::shade(const RenderContext& context, RayPacket& rays) 
const
+{
+  // Compute ambient light
+  ColorArray ambient;
+  activeLights->getAmbientLight()->computeAmbient(context, rays, ambient);
+
+  // Shade a bunch of rays that have intersected the same particle
+  lambertianShade(context, rays, ambient);
+}
+
+void CDGridSpheres::lambertianShade(const RenderContext& context, RayPacket& 
rays,
+                                  ColorArray& totalLight) const
+{
+  // Compute normals
+  rays.computeNormals(context);
+
+  // Compute colors
+  Packet<Color> diffuse;
+  mapDiffuseColors(diffuse, rays);
+
+  // Normalize directions for proper dot product computation
+  rays.normalizeDirections();
+
+  ShadowAlgorithm::StateBuffer shadowState;
+  do {
+    RayPacketData shadowData;
+    RayPacket shadowRays(shadowData, RayPacket::UnknownShape, 0, 0,
+                         rays.getDepth(), 0);
+
+    // Call the shadow algorithm (SA) to generate shadow rays.  We may not be
+    // able to compute all of them, so we pass along a buffer for the SA
+    // object to store it's state.  The firstTime flag tells the SA to fill
+    // in the state rather than using anything in the state buffer.  Most
+    // SAs will only need to store an int or two in the statebuffer.
+    context.shadowAlgorithm->computeShadows(context, shadowState, 
activeLights,
+                                            rays, shadowRays);
+
+    // Normalize directions for proper dot product computation
+    shadowRays.normalizeDirections();
+
+    for (int i=shadowRays.begin(); i < shadowRays.end(); ++i) {
+      if (!shadowRays.wasHit(i)) {
+        // Not in shadow, so compute the direct and specular contributions
+        Vector normal=rays.getNormal(i);
+        Vector shadowdir=shadowRays.getDirection(i);
+        ColorComponent cos_theta=Dot(shadowdir, normal);
+        Color light=shadowRays.getColor(i);
+        for (int j=0; j < Color::NumComponents; ++j)
+          totalLight[j][i] += light[j]*cos_theta;
+      }
+    }
+  } while(!shadowState.done());
+
+  // Sum up diffuse/specular contributions
+  for (int i=rays.begin(); i < rays.end(); ++i) {
+    Color result;
+    for (int j=0;j<Color::NumComponents; ++j)
+      result[j]=totalLight[j][i]*diffuse.colordata[j][i];
+    rays.setColor(i, result);
+  }
+}
+
+void CDGridSpheres::computeHistogram(int index, int numBuckets, int* 
histValues)
+{
+       float dataMin = min[index];
+       float dataMax = max[index];
+       cout << "histogram dataMin/max: " << dataMin << " " << dataMax << 
endl;
+       float scale = (numBuckets-1)/(dataMax - dataMin);
+       for(int i = 0; i < numBuckets; i++)
+               histValues[i] = 0;
+       cout << "nspheres: " << nspheres << endl;
+       for(int i = 0; i < nspheres; i++)
+       {
+               float val = *(spheres + i*nvars + index);
+               static int count = 0; 
+               if (count++ < 100)
+                       cout << "val: " << val << endl;
+               int bucket = int((val-dataMin)*scale);
+               histValues[bucket]++;
+       }
+}
+
+void CDGridSpheres::computeTexCoords2(const RenderContext& context,
+                                    RayPacket& rays) const
+{
+  rays.computeHitPositions();
+  rays.computeNormals(context);
+  for(int i=rays.begin();i<rays.end();i++){
+    Vector n=rays.getNormal(i);
+    Real angle=Clamp(n.z(), (Real)-1, (Real)1);
+    Real theta=Acos(angle);
+    Real phi=Atan2(n.y(), n.x());
+    Real x=phi*(Real)(0.5*M_1_PI);
+    if (x < 0)
+      x += 1;
+    Real y=theta*(Real)M_1_PI;
+    rays.setTexCoords(i, Vector(x, y, 0));
+  }
+
+  rays.setFlag(RayPacket::HaveTexture2|RayPacket::HaveTexture3);
+}
+
+void CDGridSpheres::computeTexCoords3(const RenderContext& context,
+                                    RayPacket& rays) const
+{
+  rays.computeHitPositions();
+  rays.computeNormals(context);
+  for(int i=rays.begin();i<rays.end();i++){
+    Vector n=rays.getNormal(i);
+    Real angle=Clamp(n.z(), (Real)-1, (Real)1);
+    Real theta=Acos(angle);
+    Real phi=Atan2(n.y(), n.x());
+    Real x=phi*(Real)(0.5*M_1_PI);
+    if (x < 0)
+      x += 1;
+    Real y=theta*(Real)M_1_PI;
+    rays.setTexCoords(i, Vector(x, y, 0));
+  }
+
+  rays.setFlag(RayPacket::HaveTexture2|RayPacket::HaveTexture3);
+}
+
+void CDGridSpheres::traverse(int ray_idx, RayPacket& rays, int depth, Real 
tnear,
+                           int ix, int iy, int iz, int idx,
+                           Real dt_dx, Real dt_dy, Real dt_dz,
+                           Real tnext_x, Real tnext_y, Real tnext_z,
+                           const Vector& cellcorner, const Vector& celldir,
+                           int di_dx, int di_dy, int di_dz,
+                           int didx_dx, int didx_dy, int didx_dz,
+#ifdef USE_OPTIMIZED_FCNS
+                           int stop_x, int stop_y, int stop_z,
+                           SphereIntersectFcn intersectSphere) const
+#else
+                           int stop_x, int stop_y, int stop_z) const
+#endif // USE_OPTIMIZED_FCNS
+{
+  if (depth>0) {
+    // Traverse the macrocell layers
+    MCell* mcells=macrocells[depth];
+    while (tnear < rays.getMinT(ray_idx)) {
+      MCell& mcell=mcells[idx];
+      if (mcell.nspheres > 0) {
+        // XXX:  Range checking would go here...  Ignore for now
+       for(int j = 0; j < nvars; j++)
+        {
+                if (mcell.min[j] > clipMaxs[j])
+                        return;
+                if (mcell.max[j] < clipMins[j])
+                        return;
+        }
+
+        // Compute lattice coordinates
+        int new_ix=Clamp(static_cast<int>((cellcorner.x() + 
tnear*celldir.x() - ix)*ncells), 0, ncells - 1);
+        int new_iy=Clamp(static_cast<int>((cellcorner.y() + 
tnear*celldir.y() - iy)*ncells), 0, ncells - 1);
+        int new_iz=Clamp(static_cast<int>((cellcorner.z() + 
tnear*celldir.z() - iz)*ncells), 0, ncells - 1);
+
+        // Compute new cell index
+        int new_idx=((idx*ncells + new_ix)*ncells + new_iy)*ncells + new_iz;
+
+        // Compute new delta t in each direction
+        Real new_dt_dx=dt_dx*inv_ncells;
+        Real new_dt_dy=dt_dy*inv_ncells;
+        Real new_dt_dz=dt_dz*inv_ncells;
+
+        // Compute new t values at far edges of the cell
+        Vector signs=rays.getSigns(ray_idx);
+        Real new_tnext_x=tnext_x + (1 - 2*signs.x())*new_ix*new_dt_dx +
+          (1 - signs.x())*(new_dt_dx - dt_dx);
+        Real new_tnext_y=tnext_y + (1 - 2*signs.y())*new_iy*new_dt_dy +
+          (1 - signs.y())*(new_dt_dy - dt_dy);
+        Real new_tnext_z=tnext_z + (1 - 2*signs.z())*new_iz*new_dt_dz +
+          (1 - signs.z())*(new_dt_dz - dt_dz);
+      
+        // Compute new cell corner and direction
+        Vector new_cellcorner=(cellcorner - Vector(ix, iy, iz))*ncells;
+        Vector new_celldir=celldir*ncells;
+
+        // Descend to next depth in the hierarchy
+        traverse(ray_idx, rays, depth - 1, tnear,
+                 new_ix, new_iy, new_iz,
+                 new_idx,
+                 new_dt_dx, new_dt_dy, new_dt_dz,
+                 new_tnext_x, new_tnext_y, new_tnext_z,
+                 new_cellcorner, new_celldir,
+                 di_dx, di_dy, di_dz,
+                 didx_dx, didx_dy, didx_dz,
+#ifdef USE_OPTIMIZED_FCNS
+                 stop_x, stop_y, stop_z, intersectSphere);
+#else
+                 stop_x, stop_y, stop_z);
+#endif // USE_OPTIMIZED_FCNS
+      }
+
+      // March to next macrocell at the current depth
+      if (tnext_x<tnext_y && tnext_x<tnext_z) {
+        ix += di_dx;
+        if (ix == stop_x)
+          break;
+        tnear=tnext_x;
+        tnext_x += dt_dx;
+        idx += didx_dx;
+      } else if (tnext_y<tnext_z) {
+        iy += di_dy;
+        if (iy == stop_y)
+          break;
+        tnear=tnext_y;
+        tnext_y += dt_dy;
+        idx += didx_dy;
+      } else {
+        iz += di_dz;
+        if (iz == stop_z)
+          break;
+        tnear=tnext_z;
+        tnext_z += dt_dz;
+        idx += didx_dz;
+      }
+    }
+  } else {
+    // Traverse cells, intersecting spheres along the way as necessary
+    while (tnear < rays.getMinT(ray_idx)) {
+      int start=counts[2*idx];
+      int nsph=counts[2*idx + 1];
+      for (int j=0; j<nsph; ++j) {
+       float* data=spheres + cells[start + j];
+
+        // XXX:  Range checking would go here...  Ignore for now
+       for(int k = 0; k < nvars; k++)
+       {
+               if (data[k] < clipMins[k])
+                       break;
+               if (data[k] > clipMaxs[k])
+                       break;
+       }
+        // Sphere is in range, determine it's radius (squared)
+        float radius2;
+        if (ridx>0) {
+          float current_radius=data[ridx];
+          if (current_radius <= 0)
+            continue;
+          
+          radius2=current_radius*current_radius;
+        } else {
+          radius2=radius*radius;
+        }
+
+#ifdef USE_OPTIMIZED_FCNS
+        // Intersect the sphere using the appropriately optimized function
+        (*this.*intersectSphere)(rays, ray_idx, start + j,
+                                 Vector(data[0], data[1], data[2]), radius2);
+#else
+        intersectSphereDefault(rays, ray_idx, start + j,
+                               Vector(data[0], data[1], data[2]), radius2);
+#endif
+      }
+
+      // March to the next cell
+      if (tnext_x < tnext_y && tnext_x < tnext_z) {
+        ix += di_dx;
+        if (ix == stop_x)
+          break;
+        tnear=tnext_x;
+        tnext_x += dt_dx;
+       idx += didx_dx;
+      } else if (tnext_y < tnext_z){
+        iy += di_dy;
+        if (iy == stop_y)
+          break;
+        tnear=tnext_y;
+        tnext_y += dt_dy;
+       idx += didx_dy;
+      } else {
+        iz += di_dz;
+        if (iz == stop_z)
+          break;
+        tnear=tnext_z;
+        tnext_z += dt_dz;
+       idx += didx_dz;
+      }
+    }
+  }
+}
+
+#ifdef USE_OPTIMIZED_FCNS
+void CDGridSpheres::intersectSphereCOND(RayPacket& rays, int ray_idx, int 
idx,
+                                      const Vector& center, float radius2) 
const
+{
+//  if (clip(cells[idx]))
+//     return;
+  // Rays of constant origin and normalized directions
+  Vector O(rays.getOrigin(0) - center);
+  Real C=Dot(O, O) - radius2;
+  Vector D(rays.getDirection(ray_idx));
+  Real B=Dot(O, D);
+  Real disc=B*B - C;
+  if (disc >= 0) {
+    Real r=Sqrt(disc);
+    Real t0=-(r + B);
+    if (t0 > T_EPSILON) {
+      if (rays.hit(ray_idx, t0, this, this, this))
+        rays.scratchpad<int>(ray_idx)=cells[idx];
+    } else {
+      Real t1=r - B;
+      if (rays.hit(ray_idx, t1, this, this, this))
+        rays.scratchpad<int>(ray_idx)=cells[idx];
+    }
+  }
+}
+
+void CDGridSpheres::intersectSphereCO(RayPacket& rays, int ray_idx, int idx,
+                                    const Vector& center, float radius2) 
const
+{
+ // if (clip(cells[idx]))
+//     return;
+  // Rays of constant origin for not normalized directions
+  Vector O(rays.getOrigin(0) - center);
+  Real C=Dot(O, O) - radius2;
+  Vector D(rays.getDirection(ray_idx));
+  Real A=Dot(D, D);
+  Real B=Dot(O, D);
+  Real disc=B*B - A*C;
+  if (disc >= 0) {
+    Real r=Sqrt(disc);
+    Real t0=-(r + B)/A;
+    if (t0 > T_EPSILON) {
+      if (rays.hit(ray_idx, t0, this, this, this))
+        rays.scratchpad<int>(ray_idx)=cells[idx];
+    } else {
+      Real t1=(r - B)/A;
+      if (rays.hit(ray_idx, t1, this, this, this))
+        rays.scratchpad<int>(ray_idx)=cells[idx];
+    }
+  }
+}
+
+void CDGridSpheres::intersectSphereND(RayPacket& rays, int ray_idx, int idx,
+                                    const Vector& center, float radius2) 
const
+{
+ // if (clip(cells[idx]))
+//     return;
+  // Rays of non-constant origin and normalized directions
+  Vector O(rays.getOrigin(ray_idx) - center);
+  Vector D(rays.getDirection(ray_idx));
+  Real B=Dot(O, D);
+  Real C=Dot(O, O) - radius2;
+  Real disc=B*B - C;
+  if (disc >= 0) {
+    Real r=Sqrt(disc);
+    Real t0=-(r + B);
+    if (t0 > T_EPSILON) {
+      if (rays.hit(ray_idx, t0, this, this, this))
+        rays.scratchpad<int>(ray_idx)=cells[idx];
+    } else {
+      Real t1=r - B;
+      if (rays.hit(ray_idx, t1, this, this, this))
+        rays.scratchpad<int>(ray_idx)=cells[idx];
+    }
+  }
+}
+#endif // USE_OPTIMIZED_FCNS
+
+void CDGridSpheres::intersectSphereDefault(RayPacket& rays, int ray_idx, int 
idx,
+                                         const Vector& center,
+                                         float radius2) const
+{
+ // if (clip(cells[idx]))
+//     return;
+  // Rays of non-constant origin and non-normalized directions
+  Vector O(rays.getOrigin(ray_idx) - center);
+  Vector D(rays.getDirection(ray_idx));
+  Real A=Dot(D, D);
+  Real B=Dot(O, D);
+  Real C=Dot(O, O) - radius2;
+  Real disc=B*B - A*C;
+  if (disc >= 0) {
+    Real r=Sqrt(disc);
+    Real t0=-(r + B)/A;
+    if (t0 > T_EPSILON) {
+      if (rays.hit(ray_idx, t0, this, this, this))
+        rays.scratchpad<int>(ray_idx)=cells[idx];
+    } else {
+      Real t1=(r - B)/A;
+      if (rays.hit(ray_idx, t1, this, this, this));
+      rays.scratchpad<int>(ray_idx)=cells[idx];
+    }
+  }
+}
+
+void CDGridSpheres::transformToLattice(const BBox& box, int& sx, int& sy, 
int& sz,
+                                     int& ex, int& ey, int& ez) const
+{
+  Vector s=(box.getMin() - bounds.getMin())*inv_diagonal;
+  sx=static_cast<int>(s.x()*totalcells);
+  sy=static_cast<int>(s.y()*totalcells);
+  sz=static_cast<int>(s.z()*totalcells);
+  Clamp(sx, 0, totalcells - 1);
+  Clamp(sy, 0, totalcells - 1);
+  Clamp(sz, 0, totalcells - 1);
+  
+  Vector e=(box.getMax() - bounds.getMin())*inv_diagonal;
+  ex=static_cast<int>(e.x()*totalcells);
+  ey=static_cast<int>(e.y()*totalcells);
+  ez=static_cast<int>(e.z()*totalcells);
+  Clamp(ex, 0, totalcells - 1);
+  Clamp(ey, 0, totalcells - 1);
+  Clamp(ez, 0, totalcells - 1);
+}
+
+int CDGridSpheres::mapIdx(int ix, int iy, int iz, int depth)
+{
+  if (depth==0) {
+    return (ix*ncells + iy)*ncells + iz;
+  } else {
+    int idx=mapIdx(static_cast<int>(ix*inv_ncells),
+                   static_cast<int>(iy*inv_ncells),
+                   static_cast<int>(iz*inv_ncells),
+                   depth - 1);
+    int nx=ix%ncells;
+    int ny=iy%ncells;
+    int nz=iz%ncells;
+    
+    return ((idx*ncells + nx)*ncells + ny)*ncells + nz;
+  }
+}
+
+void CDGridSpheres::fillMCell(MCell& mcell, int depth, int startidx) const
+{
+  mcell.nspheres=0;
+  mcell.min=new float[2*nvars];
+  mcell.max=mcell.min + nvars;
+  
+  // Initialize min/max
+  for (int i=0; i<nvars; ++i) {
+    mcell.min[i]=FLT_MAX;
+    mcell.max[i]=-FLT_MAX;
+  }
+  
+  // Determine min/max
+  int ncells3=ncells*ncells*ncells;
+  if (depth>0) {
+    MCell* mcells=macrocells[depth];
+    for (int i=0; i<ncells3; ++i) {
+      int idx=startidx + i;
+      fillMCell(mcells[idx], depth - 1, idx*ncells*ncells*ncells);
+      mcell.nspheres += mcells[idx].nspheres;
+      for (int j=0; j<nvars; ++j) {
+        if (mcells[idx].min[j]<mcell.min[j])
+          mcell.min[j]=mcells[idx].min[j];
+        if (mcells[idx].max[j]>mcell.max[j])
+          mcell.max[j]=mcells[idx].max[j];
+      }
+    }
+  } else {
+    for (int i=0; i<ncells3; ++i) {
+      int idx=startidx + i;
+      int nsph=counts[2*idx + 1];
+      mcell.nspheres += nsph;
+      int s=counts[2*idx];
+      for (int j=0; j<nsph; ++j) {
+        float* data=spheres + cells[s + j];
+        for (int k=0; k<nvars; ++k) {
+          if (data[k]<mcell.min[k])
+            mcell.min[k]=data[k];
+          if (data[k]>mcell.max[k])
+            mcell.max[k]=data[k];
+        }
+      }
+    }
+  }
+}
+
+void CDGridSpheres::mapDiffuseColors(Packet<Color>& diffuse, RayPacket& 
rays) const
+{
+  for (int i=int(rays.begin()); i<int(rays.end()); ++i) {
+    int particle=rays.scratchpad<int>(i);
+    float value=*(spheres + particle + cidx);
+    float minimum=cmin[cidx];
+    float normalized=(value - minimum)/(cmax[cidx] - minimum);
+    //int ncolors=cmap->blended.size() - 1;
+    //int idx=SCIRun::Clamp(static_cast<int>(ncolors*normalized), 0, 
ncolors);
+    //diffuse.set(i, cmap->blended[idx]);
+    diffuse.set(i, cmap->GetColor(normalized).color);
+  }
+}
+
+bool CDGridSpheres::clip(int s) const
+{
+       for(int j = 0; j < nvars; j++)
+       {
+               float v = *(spheres + s + j);
+               if (v < clipMins[j] || v > clipMaxs[j])
+                       return true;
+       }
+       return false;
+}
+

Added: trunk/scenes/csafe/src/CDGridSpheres.h
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/src/CDGridSpheres.h      Wed Jan  9 18:28:28 2008
@@ -0,0 +1,140 @@
+//! Filename: CDGridSpheres.h
+/*!
+    same as Grispheres, but with small changes to incorporate csafe demo.  
TODO: incorporate changes into main Gridspheres file
+*/
+
+#ifndef Manta_Model_CDGridSpheres_h
+#define Manta_Model_CDGridSpheres_h
+
+#include <Core/Color/Color.h>
+#include <Core/Geometry/BBox.h>
+#include <Interface/RayPacket.h>
+#include <Interface/TexCoordMapper.h>
+#include <Interface/Texture.h>
+#include <Model/Primitives/PrimitiveCommon.h>
+#include <Model/Materials/LitMaterial.h>
+#include <Model/Materials/Volume.h>
+
+#define USE_OPTIMIZED_FCNS
+
+namespace Manta {
+  class RegularColorMap;
+
+  class CDGridSpheres : public PrimitiveCommon, public LitMaterial,
+                      public TexCoordMapper
+  {
+  public:
+    CDGridSpheres(float* spheres, int nspheres, int nvars, int ncells, int 
depth,
+                Real radius, int ridx, RGBAColorMap* cmap, int cidx);
+    ~CDGridSpheres(void);
+
+    void preprocess(const PreprocessContext&);
+
+    void computeBounds(const PreprocessContext& context,
+                       BBox& bbox) const;
+    void intersect(const RenderContext& context, RayPacket& rays) const;
+    void computeNormal(const RenderContext& context, RayPacket& rays) const;
+
+    virtual void shade(const RenderContext& context, RayPacket& rays) const;
+
+    void computeTexCoords2(const RenderContext& context,
+                                  RayPacket& rays) const;
+    void computeTexCoords3(const RenderContext& context,
+                                  RayPacket& rays) const;
+    void setCMinMax(int index, float min, float max) { cmin[index] = min; 
cmax[index] = max; }
+    void getCMinMax(int index, float& min, float& max) { min = cmin[index]; 
max = cmax[index]; }
+    void computeHistogram(int index, int numBuckets, int* histValues); 
//index is data index to use.  histValues should be of size numBuckets
+    void getMinMax(int index, float& dmin, float&dmax)
+       {
+               dmin = min[index];
+               dmax = max[index];
+       }
+    void setCidx(int cidx) { this->cidx = cidx; }
+    void setCMap(RGBAColorMap* map) { cmap = map; }
+    bool clip(int s) const;
+    void setClipMinMax(int index, float clipMin, float clipMax)
+{
+       clipMins[index] = clipMin;
+       clipMaxs[index] = clipMax;
+}
+  protected:
+#ifdef USE_OPTIMIZED_FCNS
+    typedef void (CDGridSpheres::*SphereIntersectFcn)(RayPacket&, int, int,
+                                                    const Vector&, float) 
const;
+#endif
+
+    struct MCell {
+      int nspheres;
+      float* max;
+      float* min;
+    };
+
+    void traverse(int i, RayPacket& rays, int depth,
+                  Real tnear,
+                  int ix, int iy, int iz,
+                  int idx,
+                  Real dt_dx, Real dt_dy, Real dt_dz,
+                  Real tnext_x, Real tnext_y, Real tnext_z,
+                  const Vector& corner, const Vector& celldir,
+                  int di_dx, int di_dy, int di_dz,
+                  int didx_dx, int didx_dy,
+#ifdef USE_OPTIMIZED_FCNS
+                  int didx_dz, int stop_x, int stop_y, int stop_z,
+                  SphereIntersectFcn intersectSphere) const;
+#else
+                  int didx_dz, int stop_x, int stop_y, int stop_z) const;
+#endif // USE_OPTIMIZED_FCNS
+    void transformToLattice(const BBox& box, int& sx, int& sy, int& sz,
+                            int& ex, int& ey, int& ez) const;
+    int mapIdx(int ix, int iy, int iz, int depth);
+    void fillMCell(MCell& mcell, int depth, int startidx) const;
+    void mapDiffuseColors(Packet<Color>& diffuse, RayPacket& rays) const;
+
+#ifdef USE_OPTIMIZED_FCNS
+    // Sphere intersection functions
+    void intersectSphereCOND(RayPacket& rays, int ray_idx, int idx,
+                             const Vector& center, float radius2) const;
+    void intersectSphereCO(RayPacket& rays, int ray_idx, int idx,
+                           const Vector& center, float radius2) const;
+    void intersectSphereND(RayPacket& rays, int ray_idx, int idx,
+                           const Vector& center, float radius2) const;
+#endif // USE_OPTIMIZED_FCNS
+    void intersectSphereDefault(RayPacket& rays, int ray_idx, int idx,
+                                const Vector& center, float radius2) const;
+
+    void lambertianShade(const RenderContext& context, RayPacket& rays,
+                         ColorArray& totalLight) const;
+
+    float* spheres;
+    int nspheres;
+    int nvars;
+    Real radius;
+    Real inv_radius;
+    int ridx;
+
+    Vector diagonal;
+    Vector inv_diagonal;
+    int totalcells;
+
+    int* counts;
+    int* cells;
+    float* min;
+    float* max;
+    float* cmin;  //specified min/max values to override actual ones(used 
for coloring)
+    float* cmax;  
+    float* clipMins;  //clip data by these values (array of nvars size)
+    float* clipMaxs;
+    BBox bounds;
+
+    int ncells;
+    int depth;
+    Real inv_ncells;
+
+    MCell** macrocells;
+
+    RGBAColorMap* cmap;
+    int cidx;
+  };
+}
+
+#endif

Added: trunk/scenes/csafe/src/CDSWIGIFY.h
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/src/CDSWIGIFY.h  Wed Jan  9 18:28:28 2008
@@ -0,0 +1,25 @@
+//! Filename: CDSWIGIFY.h
+/*!
+    these functions are purely to fix weird issues with communicating 
between c++
+    and python using swig.
+*/
+
+#include <Interface/MantaInterface.h>
+using namespace Manta;
+
+int* SWIGIFYCreateIntArray(int size)
+{
+       return new int[size];
+}
+
+double SWIGIFYGetIntArrayValue(int* array, int i) { return array[i]; }
+
+double* SWIGIFYCreateDouble(double val) { return new double(val);}
+float* SWIGIFYCreateFloat(float val) { return new float(val); }
+
+double SWIGIFYGetDouble(double* val) { return *val; }
+float SWIGIFYGetFloat(float* val) { return *val; }
+int SWIGIFYGetInt(int* val) { return *val; }
+int SWIGIFYGetNumWorkers(MantaInterface* i) { return i->numWorkers(); }
+
+float SWIGIFYGetColorValue(Color c, int i) { return c[i]; }

Added: trunk/scenes/csafe/src/CDTest.h
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/src/CDTest.h     Wed Jan  9 18:28:28 2008
@@ -0,0 +1,596 @@
+//! Filename: CDTest.h
+/*!
+    This file is a "bridge" between python code and c++ code to simplify 
dealing with 
+    templated classes, etc. for the csafe demo.
+*/
+
+#ifndef CDTEST_H
+#define CDTEST_H
+
+#include <Model/Materials/Volume.h>
+#include <Core/Color/Color.h>
+#include <Core/Geometry/Vector.h>
+#include <Core/Exceptions/IllegalArgument.h>
+#include <Core/Util/Args.h>
+#include <Interface/Context.h>
+#include <Interface/LightSet.h>
+#include <Interface/MantaInterface.h>
+#include <Model/Groups/Group.h>
+#include <Model/Lights/PointLight.h>
+#include <Model/Groups/GriddedGroup.h>
+#include "CDGridSpheres.h"
+#include <Engine/Factory/Factory.h>
+#include <Model/MiscObjects/CuttingPlane.h>
+#include <iostream>
+#include <math.h>
+#include <Core/Exceptions/IllegalArgument.h>
+#include <Core/Geometry/Vector.h>
+#include <Core/Util/Args.h>
+#include <Interface/Context.h>
+#include <Interface/LightSet.h>
+#include <Interface/MantaInterface.h>
+#include <Model/Backgrounds/ConstantBackground.h>
+#include <Model/Lights/PointLight.h>
+#include <Model/Readers/ParticleNRRD.h>
+#include <Core/Thread/Thread.h>
+#include <Model/Cameras/PinholeCamera.h>
+#include <Model/MiscObjects/KeyFrameAnimation.h>
+#include <Model/AmbientLights/ConstantAmbient.h>
+#include <Model/Primitives/Cube.h>
+#include <Model/Materials/Lambertian.h>
+#include <teem/nrrd.h>
+
+#include <vector>
+#include <string>
+
+using namespace std;
+using namespace Manta;
+
+
+/*!
+\class CDTest
+\brief c++ Bridge for running csafe code
+\author Carson Brownlee
+Description: used for running c++ heavy code for csafe demo
+*/
+class CDTest
+{
+public:
+    //! CDTest constructor
+    /*!
+    \param pass in the scene, or NULL and set it later
+    \param pass in MantaInterface used for rendering
+    */
+       CDTest(Scene* scene, MantaInterface* interface)
+       {
+               _scene = scene;
+               _ridx = 6;
+               _cidx = 4;
+               _radius = 0.0003;
+               numFrames = numFrames1 = numFrames2 = 0;
+               //_readContext = context;
+               _manta_interface = interface;
+               _forceDataMin = -FLT_MAX;
+               _forceDataMax = -FLT_MAX;
+       }
+       
+       //! sets the scene object, necessary for initializing scene and 
loading spheres/volume
+       /*!
+    \param scene to set
+       */
+       void setScene(Scene* scene)
+       {
+               _scene = scene;
+       }
+       
+       //! initializes the scene, must do before rendering
+       /*!
+       */
+       void initScene()
+       {
+         _world = new Group();
+       _scene->setBackground(new ConstantBackground(Color(RGB(0, 0, 0)))); 
+        _scene->setObject(_world);
+
+         LightSet* lights = new LightSet();
+       lights->add(new PointLight(Vector(-500, 300, -300), 
Color(RGB(.8,.8,.8))));
+
+       lights->setAmbientLight(new ConstantAmbient(Color(RGB(.4,.4,.4))));
+         _scene->setLights(lights);
+       Group*   group = new Group();
+       Primitive* prim = new Cube( new Lambertian(Color(RGBColor(1,0,0))), 
Vector(-0.1, -0.1, 0.4)*0, Vector(0.1, 0.1, 0.7)*0);  
+               _sphereAnimation= new KeyFrameAnimation();
+               _volAnimation = new KeyFrameAnimation();
+ Primitive* prim2 = new Cube( new Lambertian(Color(RGBColor(0,0,1))), 
Vector(-0.1, -0.1, 0.4), Vector(0.1, 0.1, .7));
+               group->add(prim);
+               Group* group2 = new Group();
+               group2->add(prim2);
+               _world->add(_sphereAnimation);
+               _world->add(_volAnimation);
+               _sphereAnimation->setDuration(15);
+               _volAnimation->setDuration(15);
+               duration = 10;
+               numFrames1 = numFrames2 = numFrames = 1;
+
+               _minBound = Vector(-0.001, -0.101, -0.001);
+               _maxBound = Vector( 0.101, 0.201, 0.101);
+
+
+vector<ColorSlice> slices;
+float div = 1.0/255.0;
+float a = 0.1;
+slices.push_back(ColorSlice(0.0f, RGBAColor(Color(RGB(0, 0, 0)) * div, 
0*a)));
+  slices.push_back(ColorSlice(0.109804f, RGBAColor(Color(RGB(52, 0, 0)) * 
div, 0*a)));
+  slices.push_back(ColorSlice(0.01f, RGBAColor(Color(RGB(102, 2, 0)) * div, 
0.1*a)));
+  slices.push_back(ColorSlice(0.328571f, RGBAColor(Color(RGB(153, 18, 0)) * 
div, 0.216667*a)));
+  slices.push_back(ColorSlice(0.4f, RGBAColor(Color(RGB(200, 41, 0)) * div, 
0.23*a)));
+  slices.push_back(ColorSlice(0.5f, RGBAColor(Color(RGB(230, 71, 0)) * div, 
0.27*a)));
+  slices.push_back(ColorSlice(0.618367f, RGBAColor(Color(RGB(255, 120, 0)) * 
div, 0.3375*a)));
+  slices.push_back(ColorSlice(0.68f, RGBAColor(Color(RGB(255, 163, 20)) * 
div, 0.35*a)));
+  slices.push_back(ColorSlice(0.72f, RGBAColor(Color(RGB(255, 204, 55)) * 
div, 0.37*a)));
+  slices.push_back(ColorSlice(0.79f, RGBAColor(Color(RGB(255, 228, 80)) * 
div, 0.39*a)));
+  slices.push_back(ColorSlice(0.85f, RGBAColor(Color(RGB(255, 247, 120)) * 
div, 0.43*a)));
+  slices.push_back(ColorSlice(0.92f, RGBAColor(Color(RGB(255, 255, 180)) * 
div, 0.47*a)));
+  slices.push_back(ColorSlice(1.0f, RGBAColor(Color(RGB(255, 255, 255)) * 
div, 0.5*a)));
+_volCMap = new RGBAColorMap(slices, 64);
+
+
+       }
+       
+       //! add a sphere file to be loaded
+       /*!
+          \param file to be loaded later
+       */
+       void addSphereNrrd(string file)
+       {
+               _nrrdFilenames.push_back(file);
+       }
+       
+       //! clear list of sphere files
+       /*!
+       */
+       void clearSphereNrrds()
+       {
+               _nrrdFilenames.clear();
+               numFrames1 = 0;
+               numFrames = numFrames2;
+       }
+       
+       //! add volume nrrd file to be loaded
+       /*!
+          \param file to add to be loaded later
+       */
+       void addVolNrrd(string file)
+       {
+               _nrrdFilenames2.push_back(file);
+       }
+       
+       //! clear list of volume files
+       /*!
+       */
+       void clearVolNrrds()
+       {
+               _nrrdFilenames2.clear();
+               numFrames2 = 0;
+               numFrames = numFrames1;
+       }
+       
+       //! load list of sphere nrrd files
+       /*!
+          
+       */
+       void loadSphereNrrds()
+       {       
+               LightSet* lights = _scene->getLights();
+               PreprocessContext context(_manta_interface, 0, 1, lights);
+               _nrrds.clear();
+               for(vector<string>::iterator i = _nrrdFilenames.begin(); i != 
_nrrdFilenames.end(); i++)
+               {
+                       cout << "Loading Nrrd file: " << *i << "...\n";
+                       ParticleNRRD* pnrrd = new ParticleNRRD();
+                       pnrrd->readFile(*i);
+                       _spherePNrrds.push_back(pnrrd);
+                       Group* group = new Group();
+                       RGBAColorMap* cmap = new RGBAColorMap(1);
+                       CDGridSpheres* grid = new 
CDGridSpheres(pnrrd->getParticleData(), pnrrd->getNParticles(), 
pnrrd->getNVars(), 6, 2,0.0001, _ridx, cmap , _cidx); 
+                       grid->setCMinMax(4, 299.50411987304688, 
500.59423828125);
+                       //TODO: unhardcode this!
+                       cout << "reprocess\n";
+                       grid->preprocess(context);
+                       cout << "donepreprocess\n";
+                       group->add(grid);
+                       _sphereGrids.push_back(grid);
+                       if (pnrrd->getNVars() > _sphereMins.size())
+                       {
+                               for(size_t j = _sphereMins.size(); j < 
pnrrd->getNVars(); j++)
+                               {
+                                       _sphereMins.push_back(FLT_MAX);
+                                       _sphereMaxs.push_back(-FLT_MAX);
+                               }
+                       }
+                       for(int j = 0; j < int(_sphereMins.size()); j++)
+                       {
+                               float min,max;
+                               grid->getMinMax(j, min, max);
+                               if (_sphereMins[j] > min)
+                                       _sphereMins[j] = min;
+                               if (_sphereMaxs[j] < max)
+                                       _sphereMaxs[j] = max;
+                       }
+                       _sphereAnimation->push_back(group);
+                       numFrames1++;
+                        //Nrrd *new_nrrd = nrrdNew();
+       
////////////////////////////////////////////////////////////////////////////
+       // Attempt to open the nrrd
+       //if (nrrdLoad( new_nrrd, i->c_str(), 0 )) {
+       //      char *reason = biffGetDone( NRRD );
+       //      std::cout << "WARNING Loading Nrrd Failed: " << reason << 
std::endl;
+       //      exit(__LINE__);
+   // }
+
+       // Check to make sure the nrrd is the proper dimensions.
+   // if (new_nrrd->dim != 3) {
+   //  std::cout << "WARNING Nrrd must three dimension RGB" << std::endl;
+   //  exit(__LINE__);
+  //  }
+
+                       //_nrrds.push_back(new_nrrd);
+                       cout << "Loading " << *i << " done.\n";
+               } 
+               updateFrames();
+       }
+       
+       //! clear list of volume files
+       /*!
+       */
+       void loadVolNrrds()
+       {
+                               for(vector<string>::iterator i = 
_nrrdFilenames2.begin(); i != _nrrdFilenames2.end(); i++)
+                               {
+                                               cout << "Loading Nrrd file: " 
<< *i << "...\n";
+                                               Group* group = new Group();
+                       Volume<float>* mat = new Volume<float>(*i, _volCMap, 
_minBound, _maxBound, 0.00125, 10, 3, _forceDataMin, _forceDataMax);
+                       Primitive* vol = new Cube(mat, _minBound - 
Vector(0.001, 0.001, 0.001), _maxBound + Vector(0.001, 0.001, 0.001));
+                                               group->add(vol);
+                                               
_volAnimation->push_back(group);
+                       _vols.push_back(mat);
+                                               numFrames2++;
+                                                //Nrrd *new_nrrd = nrrdNew();
+       
////////////////////////////////////////////////////////////////////////////
+       // Attempt to open the nrrd
+       //if (nrrdLoad( new_nrrd, i->c_str(), 0 )) {
+       //      char *reason = biffGetDone( NRRD );
+       //      std::cout << "WARNING Loading Nrrd Failed: " << reason << 
std::endl;
+       //      exit(__LINE__);
+   // }
+
+       // Check to make sure the nrrd is the proper dimensions.
+   // if (new_nrrd->dim != 3) {
+   //  std::cout << "WARNING Nrrd must three dimension RGB" << std::endl;
+   //  exit(__LINE__);
+  //  }
+                                               cout << "Loading " << *i << " 
done.\n";
+                               }
+               updateFrames();
+       }
+       
+       //! update the frame cieling
+       /*!
+       */
+       void updateFrames()
+       {
+               numFrames = std::max(numFrames1, numFrames2);
+       }
+       
+       //! pause animation
+       /*!
+       */
+       void pauseAnimation() { _sphereAnimation->pauseAnimation(); 
_volAnimation->pauseAnimation(); }
+       
+       //! resume animation
+       /*!
+       */
+       void resumeAnimation() { _sphereAnimation->resumeAnimation(); 
_volAnimation->resumeAnimation();}
+       
+       //! go to a time in animation
+       /*!
+          \param time to go to
+       */
+       void gotoFrame(float time) { _sphereAnimation->setTime(time); 
_volAnimation->setTime(time); }
+       
+       //! skip ahead one frame
+       /*!
+       */
+       void forwardAnimation()
+       {
+               cout << _sphereAnimation->getTime() << endl;
+               float step;
+               if (numFrames == 0)
+                       step = 0;
+               else
+                       step = duration/float(numFrames);
+               float st = _sphereAnimation->getTime();
+               st = std::max(st, 0.0f);
+               float vt = _volAnimation->getTime();
+               vt = std::max(vt, 0.0f);
+               
+               _sphereAnimation->setTime( _sphereAnimation->getTime() + 
step);
+               _volAnimation->setTime(_volAnimation->getTime()+step);
+       }
+       
+       //! skip back one frame
+       /*!
+       */
+       void backAnimation()
+       {
+               float step;
+               if (numFrames == 0)
+                       step = 0;
+               else
+                       step     = duration/float(numFrames);
+               _sphereAnimation->setTime( _sphereAnimation->getTime() - 
step);
+               _volAnimation->setTime(_volAnimation->getTime()-step);
+       } 
+       
+       //! get the duration of the animation in seconds
+       /*!
+          \return duration in seconds of animation
+       */
+       float getDuration()
+       {
+               return duration;
+       }
+       
+       //! set the duration of animation in seconds
+       /*!
+          \param number of seconds animation takes
+       */
+       void setDuration(float time)
+       {
+               duration = time;
+               _sphereAnimation->setDuration(time);
+               _volAnimation->setDuration(time);
+       }
+       
+       //! computes histogram of spherefiles
+       /*!
+          \param index of data to compute histogram of
+          \param number of buckets to compute, ie 100 bars
+          \param an allocated list of ints to store the values, must be size 
numBuckets
+          \param will return min
+          \param will return max
+       */
+       void getHistogram(int index, int numBuckets, int* histValues, float* 
min, float* max)
+       {
+               for(int i = 0; i < numBuckets; i++)
+                                               histValues[i] = 0;
+               for(size_t i = 0; i < _spherePNrrds.size(); i++)
+               {
+                       ParticleNRRD* pnrrd = _spherePNrrds[i];
+                       float dataMin = _sphereMins[index];
+                                       float dataMax = _sphereMaxs[index];
+                       cout << "histo dataMin/Max: " << dataMin << " " << 
dataMax << endl;
+                                       float scale;
+                       if (dataMin != dataMax)
+                                       scale = (numBuckets-1)/(dataMax - 
dataMin);
+                       else
+                                       continue;
+                                        for(int j = 0; j < 
int(pnrrd->getNParticles()); j++)
+                                        {
+                                                                       float 
val = *(pnrrd->getParticleData() + j*pnrrd->getNVars() + index);
+                               int bucket = int((val-dataMin)*scale);
+                                 static int count = 0; if (val > 0.06 && 
count++ < 20) cout << "val: " << val << " " << bucket << endl;
+                                                                       
histValues[bucket]++;
+                                       }
+               }
+               if (int(_sphereMins.size()) > index)
+               {
+                       *min = _sphereMins[index];
+                       *max = _sphereMaxs[index];
+               }
+               else
+               {
+                       *min = -FLT_MAX;
+                       *max = FLT_MAX;
+               }
+       }
+       
+       //! compute histogram for volume data
+       /*!
+          \param number of buckets to compute, ie 100 bars
+          \param an allocated list of ints to store the values, must be size 
numBuckets
+          \param will return min
+          \param will return max
+       */
+       void getVolHistogram(int numBuckets, int* histValues, float* min, 
float* max)
+       {
+               cout << "computing volume histogram for " << _vols.size() << 
" volumes\n";
+               *min = FLT_MAX;
+               *max = -FLT_MAX;
+               for(int i = 0; i < numBuckets; i++)
+                                               histValues[i] = 0;
+               for (int i = 0; i < int(_vols.size()); i++)
+               {
+                       if (_vols[i] == NULL)
+                               continue;
+                       int* histValues2 = new int[numBuckets];
+                       _vols[i]->computeHistogram(numBuckets, histValues2);  
  
+                       for(int j = 0; j < numBuckets; j++)
+                               histValues[j] += histValues2[j];
+                       double nmin, nmax;
+                       _vols[i]->getMinMax(&nmin, &nmax);
+                       *min= std::min(float(nmin), *min);
+                       *max = std::max(float(nmax), *max);
+                       cout << "compared min/max: " << nmin << " " << nmax 
<< endl;
+               }
+               cout << "histogram computed: min/max: " << *min << " " << 
*max << endl;
+       }
+       
+       //! get the colormap used for the volume
+       /*!
+          \return colormap used for volume
+       */
+       RGBAColorMap* getVolCMap() { return _volCMap; }
+       
+       //! set the colormap for volume
+       /*!
+          \param colormap
+       */
+       void setVolCMap(RGBAColorMap* map) { _volCMap = map; }
+       
+       //! set the colormap for spheres
+       /*!
+          \param colormap
+       */
+       void setSphereCMap(RGBAColorMap* map)   {
+               for(int i =0; i < int(_sphereGrids.size()); i++)
+                       _sphereGrids[i]->setCMap(map);
+       }
+       
+       //! set minimum and maximum clipping region for a specific index into 
spheres
+       /*!
+          \param index into data
+          \param min
+          \param max
+       */
+       void setClipMinMax(int index, float min, float max)
+       {
+               if (index >= int(_sphereMins.size()))
+                       return;
+               for(int i = 0; i < int(_sphereGrids.size()); i++)
+                       if (_sphereGrids[i]) 
_sphereGrids[i]->setClipMinMax(index, min, max);
+       }
+       
+       //! set the minimum and maximum data values used for normalizing 
color data
+       /*!
+          \param index into data
+          \param min
+          \param max
+       */
+       void setSphereCMinMax(int index, float min, float max)   //set the 
min max for normalizing color data
+       {
+               if (index >= int(_sphereMins.size()))
+                       return;
+               for(int i =0; i < int(_sphereGrids.size()); i++)
+                       _sphereGrids[i]->setCMinMax(index, min, max);
+       }
+       
+       //! get the min and max being used for normalizing color values
+       /*!
+          \param index into data
+          \param returns min
+          \param returns max
+       */
+       void getSphereCMinMax(int index, float& min, float& max)
+       {
+               if(index >= int(_sphereMins.size()))
+               {
+                       min = -FLT_MAX;
+                       max = FLT_MAX;
+                       return;
+               }
+               for(int i =0;i<int(_sphereGrids.size());i++)
+                       _sphereGrids[i]->getCMinMax(index, min, max);
+
+       }
+       
+       //! set minimum and maximum data values for volume data, should be 
called before loading
+       /*!
+          \param min
+          \param max
+       */
+       void setVolCMinMax(float min, float max)
+       {
+               _forceDataMin = min;
+               _forceDataMax = max;
+       }
+       
+       //! get the min and max data values used for normalizing color values
+       /*!
+          \param returns min
+          \param returns max
+       */
+       void getVolCMinMax(float& min, float& max)
+       {
+               min = FLT_MAX;
+               max = -FLT_MAX;
+               for(int i =0;i<int(_vols.size());i++)
+               {
+                       if (_vols[i] == NULL)
+                               continue;
+                       double min1, max1;
+                       _vols[i]->getMinMax(&min1, &max1);
+                       min = std::min(min, float(min1));
+                       max = std::max(max, float(max1));
+               }
+       }
+
+    //! sets radius index used for spheredata
+       /*!
+          \param radius index
+       */
+       void setRidx(int ridx) { _ridx = ridx; }
+       
+       //! get radius index
+       /*!
+          \return radius index
+       */
+       int getRidx() { return _ridx; }
+       
+       //! set default radius of spheres
+       /*!
+          \param radius
+       */
+       void setRadius(float radius) { _radius = radius; }
+       
+       //! get the default radius of spheres
+       /*!
+          \return default radius
+       */
+       float getRadius() { return _radius; } 
+       
+       //! set color index, what index colormap uses
+       /*!
+          \param color index to use
+       */
+       void setCidx(int cidx) {
+                _cidx = cidx; 
+               for(int i =0; i < int(_sphereGrids.size()); i++)
+                       _sphereGrids[i]->setCidx(cidx); 
+       }
+       
+       //! get color index
+       /*!
+          \return color index
+       */
+       int getCidx() { return _cidx; }
+
+
+       MantaInterface* _manta_interface;
+       RGBAColorMap* _volCMap;
+       Vector _minBound;
+       Vector _maxBound;
+       float _forceDataMin;
+       float _forceDataMax;
+       int _cidx;
+       int _ridx;
+       float _radius;
+       float duration;  //number of seconds for animation
+       int numFrames;   //number of keyframes
+       int numFrames1, numFrames2;
+       ReadContext* _readContext;
+       vector<string> _nrrdFilenames;
+       vector<string> _nrrdFilenames2;
+       vector<Nrrd*> _nrrds;
+       vector<ParticleNRRD*> _spherePNrrds;
+       vector<CDGridSpheres*> _sphereGrids;
+       vector<Volume<float>*> _vols;
+       vector<float> _sphereMins;
+       vector<float> _sphereMaxs;
+       Group* _world;
+       Scene* _scene;
+       KeyFrameAnimation* _sphereAnimation;
+       KeyFrameAnimation* _volAnimation;
+};
+
+#endif

Added: trunk/scenes/csafe/src/SIMD.hxx
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/src/SIMD.hxx     Wed Jan  9 18:28:28 2008
@@ -0,0 +1,35 @@
+#ifndef VEC_SIMD_HXX
+#define VEC_SIMD_HXX
+
+#include <Core/Math/SSEDefs.h>
+
+typedef float float4[4];
+#define cast4_fi _mm_cvttps_epi32
+
+#define splat4(vec, which) _mm_shuffle_ps( (vec), (vec), _MM_SHUFFLE(which, 
which, which, which))
+#define swizzle4(vec_a, vec_b, f0, f1, f2, f3) _mm_shuffle_ps( (vec_a), 
(vec_b), _MM_SHUFFLE(f3, f2, f1, f0) )
+
+#define none4(mask) (getmask4( (mask) ) == 0x0)
+#define all4(mask) (getmask4( (mask) ) == 0xf)
+#define any4(mask) (getmask4( (mask) ) != 0x0)
+
+
+inline sse_t cross(const sse_t &a, const sse_t &b)
+{
+  const sse_t a_yzxw = swizzle4(a, a, 1, 2, 0, 3);
+  const sse_t b_zxyw = swizzle4(b, b, 2, 0, 1, 3);
+  const sse_t a_zxyw = swizzle4(a, a, 2, 0, 1, 3);
+  const sse_t b_yzxw = swizzle4(b, b, 1, 2, 0, 3);
+  return sub4(mul4(a_yzxw,b_zxyw),
+              mul4(b_yzxw,a_zxyw));
+}
+
+inline sse_t calcNormal(const sse_t &a, const sse_t &b, const sse_t &c)
+{
+  const sse_t ca = sub4(c,a);
+  const sse_t ba = sub4(b,a);
+  return cross(ba, ca);
+}
+
+
+#endif //VEC_SIMD_HXX

Added: trunk/scenes/csafe/swig/CMakeLists.txt
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/swig/CMakeLists.txt      Wed Jan  9 18:28:28 2008
@@ -0,0 +1,60 @@
+
+#
+#  For more information, please see: http://software.sci.utah.edu
+#
+#  The MIT License
+#
+#  Copyright (c) 2005-2006
+#  Scientific Computing and Imaging Institute, University of Utah
+#
+#  License for the specific language governing rights and limitations under
+#  Permission is hereby granted, free of charge, to any person obtaining a
+#  copy of this software and associated documentation files (the "Software"),
+#  to deal in the Software without restriction, including without limitation
+#  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+#  and/or sell copies of the Software, and to permit persons to whom the
+#  Software is furnished to do so, subject to the following conditions:
+#
+#  The above copyright notice and this permission notice shall be included
+#  in all copies or substantial portions of the Software.
+#
+#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+#  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
MERCHANTABILITY,
+#  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+#  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+#  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+#  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+#  DEALINGS IN THE SOFTWARE.
+#
+
+  # Initialize Python/SWIG.
+  SET(CMAKE_SWIG_OUTDIR ${LIBRARY_OUTPUT_PATH})
+  FIND_PATH(SWIG_DIR swig)
+  FIND_PACKAGE(SWIG)
+
+  # Important: Must use Manta's copy of UseSWIG.cmake
+  INCLUDE(${CMAKE_SOURCE_DIR}/CMake/MantaUseSWIG.cmake)
+
+
+# CHANGE NAME OF SWIG INCLUDE FILE HERE.
+SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES CPLUSPLUS ON)
+SET_SOURCE_FILES_PROPERTIES(example.i 
+  PROPERTIES SWIG_FLAGS 
"-I${CMAKE_SOURCE_DIR}/SwigInterface;-Wall;-DSCI_NOPERSISTENT")
+
+# Add the python module "example" corresponding to shared lib _example.so
+# CHANGE NAME OF PYTHON MODULE HERE.
+SWIG_ADD_MODULE(example python example.i)
+
+# CHANGE NAME OF PYTHON MODULE HERE.
+SWIG_LINK_LIBRARIES(example
+  ${PYTHON_LIBRARIES}
+  ${MANTA_TARGET_LINK_LIBRARIES}
+  
+  # ADD ALL PROJECT SHARED LIBS HERE
+  Example
+  # swigpy
+  )
+
+
+
+

Added: trunk/scenes/csafe/swig/example.i
==============================================================================
--- (empty file)
+++ trunk/scenes/csafe/swig/example.i   Wed Jan  9 18:28:28 2008
@@ -0,0 +1,146 @@
+/*
+  Swig wrapper file for Example Manta Project.
+  Abe Stephens
+*/
+
+/*
+  For more information, please see: http://software.sci.utah.edu
+
+  The MIT License
+
+  Copyright (c) 2005-2006
+  Scientific Computing and Imaging Institute, University of Utah
+
+  License for the specific language governing rights and limitations under
+  Permission is hereby granted, free of charge, to any person obtaining a
+  copy of this software and associated documentation files (the "Software"),
+  to deal in the Software without restriction, including without limitation
+  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+  and/or sell copies of the Software, and to permit persons to whom the
+  Software is furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included
+  in all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+  DEALINGS IN THE SOFTWARE.
+*/
+
+%module example
+%{
+#include <vector.h>
+%}
+
+%include "std_string.i"
+%include "std_vector.i"
+%include "exception.i"
+
+
+// Import mantainterface.i which is the "Manta Interface" swig file. This
+// includes wrappers for interfaces which your code might implement
+// as well as wrappers for the core utilites. 
+
+// Wrappers for the manta implementation (Model/, Engine/, Image/, 
+// etc.) is not contained in this file. Python scripts that use both
+// your wrapped classes and the manta wrapped classes should import python 
+// modules "manta" and "example" (your new module). See python/test.py.
+
+%{
+namespace Manta {
+  class Group;
+  class Mesh;
+  class AccelerationStructure;
+  class OpaqueShadower;
+  class LitMaterial;
+};
+%}
+//class ColorSlice;
+%import mantainterface.i
+
+// Since ExampleTexture's parent class is a template, it must be explicitly 
instantiated.
+//namespace Manta {
+//  %template(Texture_Color) Texture<Color>;
+//}
+
+//template class Manta::CDVolSSE<double>;
+//namespace Manta {
+//     %template(double_CDVolSSE) Manta::CDVolSSE<double>;
+//}
+//%{
+//     class Manta::ColorSlice;
+//%}
+//%{
+//namespace Manta {
+//     class ColorSlice;  
+//};
+//%}
+
+//%template(vector_wector) ::std::vector<int>;
+
+//namespace Manta {
+       
+ //      %template(vector_ColorSlice) ::std::vector<ColorSlice>;
+//}
+
+%{
+
+//#include <Model/Materials/LitMaterial.h>
+
+#include <Model/Materials/Volume.h>
+//#include <CDColorMap.h>
+//#include <CDVolSSE2.h>
+//#include <ColorMap.h>
+
+//#include <Model/Groups/GriddedGroup.h>
+//template class Manta::GridArray3<float>;
+//template class Manta::CDVolSSE<double>;
+//namespace Manta {
+//        %template(double_CDVolSSE) Manta::CDVolSSE<double>;
+//}
+
+//namespace Manta {
+//  class ColorMap;
+//}
+//#include <Colorimetry.h>
+
+//#include <InhomogeneousParticipatingMedium.h>
+//#include <Physics.h>
+//#include <VolumeReader.h>
+#include <CDSWIGIFY.h>
+#include <CDTest.h>
+//#include <ExampleTexture.h>
+%}
+%template(vector_ColorSlice) ::std::vector<ColorSlice>;
+//namespace Manta {
+//        %template(double_CDVolSSE) Manta::CDVolSSE<double>;
+//}
+
+
+//namespace Manta {
+//     %template(vector_ColorSlice) vector<ColorSlice>;
+//}
+
+//%include <ExampleTexture.h>
+%include <CDTest.h>
+%include <Model/Materials/Volume.h>
+//%include <CDColorMap.h>
+//%include <CDVolSSE2.h>
+//%include <ColorMap.h>
+//%include <Colorimetry.h>
+//%include <InhomogeneousParticipatingMedium.h>
+//%include <Physics.h>
+//%include <VolumeReader.h>
+%include <CDSWIGIFY.h>
+//namespace Manta {
+// %template(vector_ColorSlice) std::vector<Manta::ColorSlice>;
+//}
+//namespace Manta {
+//        %template(double_CDVolSSE) Manta::CDVolSSE<double>;
+//}
+





  • [Manta] r1985 - in trunk/scenes: . csafe csafe/CMake csafe/python csafe/src csafe/swig csafe/swig/CMake, brownlee, 01/09/2008

Archive powered by MHonArc 2.6.16.

Top of page