Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[Manta] r2355 - in trunk: Model/Materials scenes/csafe/python scenes/csafe/src


Chronological Thread 
  • From:
  • To:
  • Subject: [Manta] r2355 - in trunk: Model/Materials scenes/csafe/python scenes/csafe/src
  • Date: Wed, 17 Dec 2008 08:46:54 -0700 (MST)

Author: brownlee
Date: Wed Dec 17 08:46:51 2008
New Revision: 2355

Modified:
   trunk/Model/Materials/Volume.cc
   trunk/Model/Materials/Volume.h
   trunk/scenes/csafe/python/Configuration.py
   trunk/scenes/csafe/python/Histogram.py
   trunk/scenes/csafe/python/SceneInfo.py
   trunk/scenes/csafe/python/SceneMenus.py
   trunk/scenes/csafe/python/csafe_demo.cfg
   trunk/scenes/csafe/python/csafe_scene.py
   trunk/scenes/csafe/src/CDGridSpheres.cc
   trunk/scenes/csafe/src/CDTest.h
Log:
modified csafe GUI to support range culling in volume

Modified: trunk/Model/Materials/Volume.cc
==============================================================================
--- trunk/Model/Materials/Volume.cc     (original)
+++ trunk/Model/Materials/Volume.cc     Wed Dec 17 08:46:51 2008
@@ -16,6 +16,8 @@
     :oldTInc(0.01), _colorScaled(false)
   {
     fillColor(type);
+    squish_scale = 1;
+    squish_min = 0;
     computeHash();
   }
         
@@ -28,74 +30,74 @@
     switch (type) {
     case InvRainbow:
       {
-       float p = 1.0f/11.0f;
-       _slices.push_back(ColorSlice(p*0, RGBAColor(Color(RGB(0, 0, 1)), 1)));
-       _slices.push_back(ColorSlice(p*1, RGBAColor(Color(RGB(0, 0.40000001, 
1)), 1)));
-       _slices.push_back(ColorSlice(p*2, RGBAColor(Color(RGB(0, 0.80000001, 
1)), 1)));
-       _slices.push_back(ColorSlice(p*3, RGBAColor(Color(RGB(0, 1, 
0.80000001)), 1)));
-       _slices.push_back(ColorSlice(p*4, RGBAColor(Color(RGB(0, 1, 
0.40000001)), 1)));
-       _slices.push_back(ColorSlice(p*5, RGBAColor(Color(RGB(0, 1, 0)), 1)));
-       _slices.push_back(ColorSlice(p*6, RGBAColor(Color(RGB(0.40000001, 1, 
0)), 1)));
-       _slices.push_back(ColorSlice(p*7, RGBAColor(Color(RGB(0.80000001, 1, 
0)), 1)));
-       _slices.push_back(ColorSlice(p*8, RGBAColor(Color(RGB(1, 0.91764706, 
0)), 1)));
-       _slices.push_back(ColorSlice(p*9, RGBAColor(Color(RGB(1, 0.80000001, 
0)), 1)));
-       _slices.push_back(ColorSlice(p*10, RGBAColor(Color(RGB(1, 0.40000001, 
0)), 1)));
-       _slices.push_back(ColorSlice(p*11, RGBAColor(Color(RGB(1, 0, 0)), 
1)));
-       break;
+        float p = 1.0f/11.0f;
+        _slices.push_back(ColorSlice(p*0, RGBAColor(Color(RGB(0, 0, 1)), 
1)));
+        _slices.push_back(ColorSlice(p*1, RGBAColor(Color(RGB(0, 0.40000001, 
1)), 1)));
+        _slices.push_back(ColorSlice(p*2, RGBAColor(Color(RGB(0, 0.80000001, 
1)), 1)));
+        _slices.push_back(ColorSlice(p*3, RGBAColor(Color(RGB(0, 1, 
0.80000001)), 1)));
+        _slices.push_back(ColorSlice(p*4, RGBAColor(Color(RGB(0, 1, 
0.40000001)), 1)));
+        _slices.push_back(ColorSlice(p*5, RGBAColor(Color(RGB(0, 1, 0)), 
1)));
+        _slices.push_back(ColorSlice(p*6, RGBAColor(Color(RGB(0.40000001, 1, 
0)), 1)));
+        _slices.push_back(ColorSlice(p*7, RGBAColor(Color(RGB(0.80000001, 1, 
0)), 1)));
+        _slices.push_back(ColorSlice(p*8, RGBAColor(Color(RGB(1, 0.91764706, 
0)), 1)));
+        _slices.push_back(ColorSlice(p*9, RGBAColor(Color(RGB(1, 0.80000001, 
0)), 1)));
+        _slices.push_back(ColorSlice(p*10, RGBAColor(Color(RGB(1, 
0.40000001, 0)), 1)));
+        _slices.push_back(ColorSlice(p*11, RGBAColor(Color(RGB(1, 0, 0)), 
1)));
+        break;
       }
     case Rainbow:
       {
-       float p = 1.0f/11.0f;
-       _slices.push_back(ColorSlice(p*0, RGBAColor(Color(RGB(1, 0, 0)), 1)));
-       _slices.push_back(ColorSlice(p*1, RGBAColor(Color(RGB(1, 0.40000001, 
0)), 1)));
-       _slices.push_back(ColorSlice(p*2, RGBAColor(Color(RGB(0, 0.80000001, 
0)), 1)));
-       _slices.push_back(ColorSlice(p*3, RGBAColor(Color(RGB(1, 0.91764706, 
0)), 1)));
-       _slices.push_back(ColorSlice(p*4, RGBAColor(Color(RGB(0.80000001, 1, 
0)), 1)));
-       _slices.push_back(ColorSlice(p*5, RGBAColor(Color(RGB(0.40000001, 1, 
0)), 1)));
-       _slices.push_back(ColorSlice(p*6, RGBAColor(Color(RGB(0, 1, 0)), 1)));
-       _slices.push_back(ColorSlice(p*7, RGBAColor(Color(RGB(0, 1, 
0.40000001)), 1)));
-       _slices.push_back(ColorSlice(p*8, RGBAColor(Color(RGB(0, 1, 
0.80000001)), 1)));
-       _slices.push_back(ColorSlice(p*9, RGBAColor(Color(RGB(0, 0.80000001, 
1)), 1)));
-       _slices.push_back(ColorSlice(p*10, RGBAColor(Color(RGB(0, 0.40000001, 
1)), 1)));
-       _slices.push_back(ColorSlice(p*11, RGBAColor(Color(RGB(1, 0, 0)), 
1)));
-       break;
+        float p = 1.0f/11.0f;
+        _slices.push_back(ColorSlice(p*0, RGBAColor(Color(RGB(1, 0, 0)), 
1)));
+        _slices.push_back(ColorSlice(p*1, RGBAColor(Color(RGB(1, 0.40000001, 
0)), 1)));
+        _slices.push_back(ColorSlice(p*2, RGBAColor(Color(RGB(0, 0.80000001, 
0)), 1)));
+        _slices.push_back(ColorSlice(p*3, RGBAColor(Color(RGB(1, 0.91764706, 
0)), 1)));
+        _slices.push_back(ColorSlice(p*4, RGBAColor(Color(RGB(0.80000001, 1, 
0)), 1)));
+        _slices.push_back(ColorSlice(p*5, RGBAColor(Color(RGB(0.40000001, 1, 
0)), 1)));
+        _slices.push_back(ColorSlice(p*6, RGBAColor(Color(RGB(0, 1, 0)), 
1)));
+        _slices.push_back(ColorSlice(p*7, RGBAColor(Color(RGB(0, 1, 
0.40000001)), 1)));
+        _slices.push_back(ColorSlice(p*8, RGBAColor(Color(RGB(0, 1, 
0.80000001)), 1)));
+        _slices.push_back(ColorSlice(p*9, RGBAColor(Color(RGB(0, 0.80000001, 
1)), 1)));
+        _slices.push_back(ColorSlice(p*10, RGBAColor(Color(RGB(0, 
0.40000001, 1)), 1)));
+        _slices.push_back(ColorSlice(p*11, RGBAColor(Color(RGB(1, 0, 0)), 
1)));
+        break;
       }
     case InvBlackBody:
       {
-       float p = 1.0f/12.0f;
-       _slices.push_back(ColorSlice(p*0, RGBAColor(Color(RGB(1, 1, 1)), 1)));
-       _slices.push_back(ColorSlice(p*1, RGBAColor(Color(RGB(1, 1, 
0.70588237)), 1)));
-       _slices.push_back(ColorSlice(p*2, RGBAColor(Color(RGB(1, 0.96862745, 
0.47058824)), 1)));
-       _slices.push_back(ColorSlice(p*3, RGBAColor(Color(RGB(1, 0.89411765, 
0.3137255)), 1)));
-       _slices.push_back(ColorSlice(p*4, RGBAColor(Color(RGB(1, 0.80000001, 
0.21568628)), 1)));
-       _slices.push_back(ColorSlice(p*5, RGBAColor(Color(RGB(1, 0.63921571, 
0.078431375)), 1)));
-       _slices.push_back(ColorSlice(p*6, RGBAColor(Color(RGB(1, 0.47058824, 
0)), 1)));
-       _slices.push_back(ColorSlice(p*7, RGBAColor(Color(RGB(0.90196079, 
0.27843139, 0)), 1)));
-       _slices.push_back(ColorSlice(p*8, RGBAColor(Color(RGB(0.78431374, 
0.16078432, 0)), 1)));
-       _slices.push_back(ColorSlice(p*9, RGBAColor(Color(RGB(0.60000002, 
0.070588239, 0)), 1)));
-       _slices.push_back(ColorSlice(p*10, RGBAColor(Color(RGB(0.40000001, 
0.0078431377, 0)), 1)));
-       _slices.push_back(ColorSlice(p*11, RGBAColor(Color(RGB(0.20392157, 0, 
0)), 1)));
-       _slices.push_back(ColorSlice(p*12, RGBAColor(Color(RGB(0, 0, 0)), 
1)));
-       break;
+        float p = 1.0f/12.0f;
+        _slices.push_back(ColorSlice(p*0, RGBAColor(Color(RGB(1, 1, 1)), 
1)));
+        _slices.push_back(ColorSlice(p*1, RGBAColor(Color(RGB(1, 1, 
0.70588237)), 1)));
+        _slices.push_back(ColorSlice(p*2, RGBAColor(Color(RGB(1, 0.96862745, 
0.47058824)), 1)));
+        _slices.push_back(ColorSlice(p*3, RGBAColor(Color(RGB(1, 0.89411765, 
0.3137255)), 1)));
+        _slices.push_back(ColorSlice(p*4, RGBAColor(Color(RGB(1, 0.80000001, 
0.21568628)), 1)));
+        _slices.push_back(ColorSlice(p*5, RGBAColor(Color(RGB(1, 0.63921571, 
0.078431375)), 1)));
+        _slices.push_back(ColorSlice(p*6, RGBAColor(Color(RGB(1, 0.47058824, 
0)), 1)));
+        _slices.push_back(ColorSlice(p*7, RGBAColor(Color(RGB(0.90196079, 
0.27843139, 0)), 1)));
+        _slices.push_back(ColorSlice(p*8, RGBAColor(Color(RGB(0.78431374, 
0.16078432, 0)), 1)));
+        _slices.push_back(ColorSlice(p*9, RGBAColor(Color(RGB(0.60000002, 
0.070588239, 0)), 1)));
+        _slices.push_back(ColorSlice(p*10, RGBAColor(Color(RGB(0.40000001, 
0.0078431377, 0)), 1)));
+        _slices.push_back(ColorSlice(p*11, RGBAColor(Color(RGB(0.20392157, 
0, 0)), 1)));
+        _slices.push_back(ColorSlice(p*12, RGBAColor(Color(RGB(0, 0, 0)), 
1)));
+        break;
       }
 
     case BlackBody:
       {
-       float p = 1.0f/12.0f;
-       _slices.push_back(ColorSlice(p*0, RGBAColor(Color(RGB(0, 0, 0)), 1)));
-       _slices.push_back(ColorSlice(p*1, RGBAColor(Color(RGB(0.20392157, 0, 
0)), 1)));
-       _slices.push_back(ColorSlice(p*2, RGBAColor(Color(RGB(0.40000001, 
0.0078431377, 0)), 1)));
-       _slices.push_back(ColorSlice(p*3, RGBAColor(Color(RGB(0.60000002, 
0.070588239, 0)), 1)));
-       _slices.push_back(ColorSlice(p*4, RGBAColor(Color(RGB(0.78431374, 
0.16078432, 0)), 1)));
-       _slices.push_back(ColorSlice(p*5, RGBAColor(Color(RGB(0.90196079, 
0.27843139, 0)), 1)));
-       _slices.push_back(ColorSlice(p*6, RGBAColor(Color(RGB(1, 0.47058824, 
0)), 1)));
-       _slices.push_back(ColorSlice(p*7, RGBAColor(Color(RGB(1, 0.63921571, 
0.078431375)), 1)));
-       _slices.push_back(ColorSlice(p*8, RGBAColor(Color(RGB(1, 0.80000001, 
0.21568628)), 1)));
-       _slices.push_back(ColorSlice(p*9, RGBAColor(Color(RGB(1, 0.89411765, 
0.3137255)), 1)));
-       _slices.push_back(ColorSlice(p*10, RGBAColor(Color(RGB(1, 0.96862745, 
0.47058824)), 1)));
-       _slices.push_back(ColorSlice(p*11, RGBAColor(Color(RGB(1, 1, 
0.70588237)), 1)));
-       _slices.push_back(ColorSlice(p*12, RGBAColor(Color(RGB(1, 1, 1)), 
1)));
-       break;
+        float p = 1.0f/12.0f;
+        _slices.push_back(ColorSlice(p*0, RGBAColor(Color(RGB(0, 0, 0)), 
1)));
+        _slices.push_back(ColorSlice(p*1, RGBAColor(Color(RGB(0.20392157, 0, 
0)), 1)));
+        _slices.push_back(ColorSlice(p*2, RGBAColor(Color(RGB(0.40000001, 
0.0078431377, 0)), 1)));
+        _slices.push_back(ColorSlice(p*3, RGBAColor(Color(RGB(0.60000002, 
0.070588239, 0)), 1)));
+        _slices.push_back(ColorSlice(p*4, RGBAColor(Color(RGB(0.78431374, 
0.16078432, 0)), 1)));
+        _slices.push_back(ColorSlice(p*5, RGBAColor(Color(RGB(0.90196079, 
0.27843139, 0)), 1)));
+        _slices.push_back(ColorSlice(p*6, RGBAColor(Color(RGB(1, 0.47058824, 
0)), 1)));
+        _slices.push_back(ColorSlice(p*7, RGBAColor(Color(RGB(1, 0.63921571, 
0.078431375)), 1)));
+        _slices.push_back(ColorSlice(p*8, RGBAColor(Color(RGB(1, 0.80000001, 
0.21568628)), 1)));
+        _slices.push_back(ColorSlice(p*9, RGBAColor(Color(RGB(1, 0.89411765, 
0.3137255)), 1)));
+        _slices.push_back(ColorSlice(p*10, RGBAColor(Color(RGB(1, 
0.96862745, 0.47058824)), 1)));
+        _slices.push_back(ColorSlice(p*11, RGBAColor(Color(RGB(1, 1, 
0.70588237)), 1)));
+        _slices.push_back(ColorSlice(p*12, RGBAColor(Color(RGB(1, 1, 1)), 
1)));
+        break;
       }
     case GreyScale:
       _slices.push_back(ColorSlice(0, RGBAColor(Color(RGB(0,0,0)), 1)));
@@ -107,24 +109,24 @@
       break;
     case InvRainbowIso:
       {
-       float p = 1.0f/11.0f;
-       _slices.push_back(ColorSlice(p*0, RGBAColor(Color(RGB(0.528, 0.528, 
1.0)), 1)));
-       _slices.push_back(ColorSlice(p*1, RGBAColor(Color(RGB(0.304, 0.5824, 
1.0)), 1)));
-       _slices.push_back(ColorSlice(p*2, RGBAColor(Color(RGB(0.0, 0.6656, 
0.832)), 1)));
-       _slices.push_back(ColorSlice(p*3, RGBAColor(Color(RGB(0.0, 0.712, 
0.5696)), 1)));
-       _slices.push_back(ColorSlice(p*4, RGBAColor(Color(RGB(0.0, 0.744, 
0.2976)), 1)));
-       _slices.push_back(ColorSlice(p*5, RGBAColor(Color(RGB(0.0, 0.76, 
0.0)), 1)));
-       _slices.push_back(ColorSlice(p*6, RGBAColor(Color(RGB(0.304, 0.76, 
0.0)), 1)));
-       _slices.push_back(ColorSlice(p*7, RGBAColor(Color(RGB(0.5504, 0.688, 
0.0)), 1)));
-       _slices.push_back(ColorSlice(p*8, RGBAColor(Color(RGB(0.68, 0.624, 
0.0)), 1)));
-       _slices.push_back(ColorSlice(p*9, RGBAColor(Color(RGB(0.752, 0.6016, 
0.0)), 1)));
-       _slices.push_back(ColorSlice(p*10, RGBAColor(Color(RGB(1.0, 0.5008, 
0.168)), 1)));
-       _slices.push_back(ColorSlice(p*11, RGBAColor(Color(RGB(1.0, 0.424, 
0.424)), 1)));
-       break;
+        float p = 1.0f/11.0f;
+        _slices.push_back(ColorSlice(p*0, RGBAColor(Color(RGB(0.528, 0.528, 
1.0)), 1)));
+        _slices.push_back(ColorSlice(p*1, RGBAColor(Color(RGB(0.304, 0.5824, 
1.0)), 1)));
+        _slices.push_back(ColorSlice(p*2, RGBAColor(Color(RGB(0.0, 0.6656, 
0.832)), 1)));
+        _slices.push_back(ColorSlice(p*3, RGBAColor(Color(RGB(0.0, 0.712, 
0.5696)), 1)));
+        _slices.push_back(ColorSlice(p*4, RGBAColor(Color(RGB(0.0, 0.744, 
0.2976)), 1)));
+        _slices.push_back(ColorSlice(p*5, RGBAColor(Color(RGB(0.0, 0.76, 
0.0)), 1)));
+        _slices.push_back(ColorSlice(p*6, RGBAColor(Color(RGB(0.304, 0.76, 
0.0)), 1)));
+        _slices.push_back(ColorSlice(p*7, RGBAColor(Color(RGB(0.5504, 0.688, 
0.0)), 1)));
+        _slices.push_back(ColorSlice(p*8, RGBAColor(Color(RGB(0.68, 0.624, 
0.0)), 1)));
+        _slices.push_back(ColorSlice(p*9, RGBAColor(Color(RGB(0.752, 0.6016, 
0.0)), 1)));
+        _slices.push_back(ColorSlice(p*10, RGBAColor(Color(RGB(1.0, 0.5008, 
0.168)), 1)));
+        _slices.push_back(ColorSlice(p*11, RGBAColor(Color(RGB(1.0, 0.424, 
0.424)), 1)));
+        break;
       }
     default:
       cerr<<"RGBAColorMap::fillColor(type="<<type
-         <<"):  Invalid type, using gray scale\n";
+          <<"):  Invalid type, using gray scale\n";
       fillColor(GreyScale);
     }
   }
@@ -138,12 +140,14 @@
     _invRange = 0;
     oldTInc = 0.01f;
     for(size_t i = 0; i < colors.size(); i++)
-      {
-       if (opacities)
-         _slices.push_back(ColorSlice(positions[i], RGBAColor(colors[i], 
opacities[i]) ));
-       else
-         _slices.push_back(ColorSlice(positions[i], RGBAColor(colors[i], 
1.0f) ));
-      }
+    {
+        if (opacities)
+          _slices.push_back(ColorSlice(positions[i], RGBAColor(colors[i], 
opacities[i]) ));
+        else
+          _slices.push_back(ColorSlice(positions[i], RGBAColor(colors[i], 
1.0f) ));
+    }
+    squish_min = 0;
+    squish_scale = 1;
     std::sort(_slices.begin(), _slices.end(), lessThan);
     computeHash();
   }
@@ -156,16 +160,16 @@
     _max = 1;
     _invRange = 0;
     oldTInc = 0.01f;
-    //for(int i = 0; i < colors.size(); i++)
-    //{
+    squish_min = 0;
+    squish_scale = 1;
     _slices = colors;
-    //}
     std::sort(_slices.begin(), _slices.end(), lessThan);
     computeHash();
   }
 
   RGBAColor RGBAColorMap::GetColor(float v)  // get the interpolated color 
at value v (0-1)
   {
+    v = v*squish_scale + squish_min;
     if (_slices.size() == 0)
       return RGBAColor(Color(RGB(0,0,0)), 1.0f);
     int start = 0;
@@ -179,17 +183,17 @@
     int middle;
     while(end > start+1)
       {
-       middle = (start+end)/2;
-       if (v < _slices[middle].value)
-         end = middle;
-       else if (v > _slices[middle].value)
-         start = middle;
-       else
-         return _slices[middle].color;
+        middle = (start+end)/2;
+        if (v < _slices[middle].value)
+          end = middle;
+        else if (v > _slices[middle].value)
+          start = middle;
+        else
+          return _slices[middle].color;
       }
     float interp = (v - _slices[start].value) / (_slices[end].value - 
_slices[start].value);
     return RGBAColor( Color(_slices[start].color.color*(1.0f-interp) + 
_slices[end].color.color*interp), 
-                     _slices[start].color.a*(1.0f-interp) + 
_slices[end].color.a*interp);
+                      _slices[start].color.a*(1.0f-interp) + 
_slices[end].color.a*interp);
         
   }
 
@@ -198,29 +202,14 @@
     return GetColor((v - _min)/_invRange);
   }
 
-  RGBAColor RGBAColorMap::GetPreInterpolatedColor(float v1, float v2, float 
d)
-  {
-    /*int i1 = v1*_numSlices;
-      int i2 = v2*_numSlices;
-      int i3 = d*_numSlices;
-      if (i1 >= _numSlices)
-      i1 = _numSlices-1;
-      if (i2 >= _numSlices)
-      i2 = _numSlices-1;
-      if (i3 >= _numSlices)
-      i3 = _numSlices-1;
-      return RGBAColor(_colors[i1][i2][i3], _opacities[i1][i2][i3]);*/
-    return RGBAColor(0,0,0,1);
-  }
-
   void RGBAColorMap::SetColors(vector<ColorSlice>& colors)
   {
     _slices = colors;
     std::sort(_slices.begin(), _slices.end(), lessThan);
     if (_colorScaled)
       {
-       oldTInc = 0.01;
-       scaleAlphas(tInc);
+        oldTInc = 0.01;
+        scaleAlphas(tInc);
       }
   }
 
@@ -231,81 +220,6 @@
     _invRange = 1.0/(max - min);
   }
 
-  void RGBAColorMap::BuildSlices()
-  {
-    //      Array1<Color>* colors = new Array1<Color>(slices.size());
-    //      sTColors.set_results_ptr(colors);
-    //      Array1<float>* opacities = new Array1<float>(slices.size());
-    //      sTOpacities.set_results_ptr(opacities);
-    //      
-    //      for (int i = 0; i < slices.size(); i++)
-    //      {
-    //              sTColors[i] = slices.color.colorl
-    //              
-    //      }
-  }
-
-  void RGBAColorMap::PreInterpolate()
-  {
-    /*      cout << "PreInterpolating values... ";
-           _colors = new Color**[_numSlices];
-           _opacities = new float**[_numSlices];
-           for(int i = 0; i < _numSlices; i++)
-           {
-           _colors[i] = new Color*[_numSlices];
-           _opacities[i] = new float*[_numSlices];
-           for(int j = 0; j < _numSlices; j++)
-           {
-           _colors[i][j] = new Color[_numSlices];
-           _opacities[i][j] = new float[_numSlices];
-           }
-           }
-           float step = 1.0/_numSlices;
-           for (int sf = 0; sf < _numSlices; sf++)
-           {
-           for(int sb = 0; sb < _numSlices; sb++)
-           {
-           for(int d = 0; d < _numSlices; d++)
-           {
-           float sff = float(sf)/float(_numSlices);
-           float sbf = float(sb)/float(_numSlices);
-           float df = float(d)/float(_numSlices);
-           float Tsf = 0.0f, Tsb = 0.0f;
-           float sumOpacity = 0.0f;
-           Color sumColor(RGB(0,0,0));
-           int minS, maxS;
-           if (sb <= sf)
-           {
-           minS = sb;
-           maxS = sf;
-           }
-           else
-           {
-           minS = sf;
-           maxS = sb;
-           }
-           RGBAColor color(Color(), 1.0);
-           for (int i = minS; i <= maxS; i++)
-           {
-           color = GetColor(float(i)/float(_numSlices));
-           sumOpacity += color.a*step;
-           sumColor += color.color*step;
-           }
-           if (sb == sf)
-           {
-           _colors[sb][sf][d] = color.color;
-           _opacities[sb][sf][d] = color.a;
-           }
-           else
-           {
-           _colors[sb][sf][d] = sumColor*df/fabs(sbf-sff);
-           _opacities[sb][sf][d] = 1.0f - pow(2.718281828, - df/fabs(sbf - 
sff)*sumOpacity);
-           }
-           }
-           }
-           }
-           cout << "done.\n"; */
-  }
 
 
   void RGBAColorMap::computeHash()
@@ -323,12 +237,12 @@
       float val = _slices[a_index].color.a;
       float next_val = _slices[a_index+1].color.a;
       if (val != 0 || next_val != 0) {
-       int start, end;
-       start = (int)(_slices[a_index].value * nindex);
-       end = (int)ceilf(_slices[a_index+1].value * nindex);
-       for (int i = start; i <= end; i++)
-         // Turn on the bits.
-         new_course_hash |= 1ULL << i;
+        int start, end;
+        start = (int)((_slices[a_index].value * squish_scale + 
squish_min)*nindex);
+        end = (int)ceilf(_slices[a_index+1].value * nindex);
+        for (int i = start; i <= end; i++)
+          // Turn on the bits.
+          new_course_hash |= 1ULL << i;
       }
     }
 
@@ -336,12 +250,21 @@
     //size_t num_bits = sizeof(course_hash)*8;
     //  for(size_t i = 0; i < num_bits; i++)
     // if (course_hash & ( 1ULL << i ))
-    // cout << 1;
+    //  cout << 1;
     // else
-    // cout << 0;
+    //  cout << 0;
 
   }
 
+  void RGBAColorMap::squish(float globalMin, float globalMax, float 
squishMin, float squishMax)
+  {
+    squishMin = max(globalMin, squishMin);
+    squishMax = min(globalMax, squishMax);
+    squish_scale = (squishMax - squishMin)/(globalMax - globalMin);
+    squish_min = (squishMin - globalMin)/(globalMax-globalMin);
+    computeHash();
+  }
+
 
   //scale alpha values by t value
   // Preconditions:
@@ -360,9 +283,9 @@
       float val = _slices[a_index].color.a;
       float one_minus_val = 1.0f - val;
       if (one_minus_val >= 1e-6f)
-       _slices[a_index].color.a = 1 - powf(one_minus_val, d2_div_d1);
+        _slices[a_index].color.a = 1 - powf(one_minus_val, d2_div_d1);
       else
-       _slices[a_index].color.a = 1;
+        _slices[a_index].color.a = 1;
     }
     oldTInc = tInc;
     tInc = t;

Modified: trunk/Model/Materials/Volume.h
==============================================================================
--- trunk/Model/Materials/Volume.h      (original)
+++ trunk/Model/Materials/Volume.h      Wed Dec 17 08:46:51 2008
@@ -31,484 +31,486 @@
 namespace Manta
 {
    
-   struct RGBAColor
-   {
+  struct RGBAColor
+    {
       RGBAColor(Color c, float opacity) : color(c), a(opacity) {}
       RGBAColor(float r, float g, float b, float alpha) : 
color(Color(RGB(r,g,b))), a(alpha){ }
       Color color;
       float a; //opacity
-   };
+    };
    
-   struct ColorSlice
-   {
-      ColorSlice() : value(0), color(RGBAColor(Color(RGBColor(0,0,0)), 1.0)) 
{}
-      ColorSlice(float v, RGBAColor c) : value(v), color(c) {}
-      float value;  //0-1 position of slice
-      RGBAColor color;
-   };
+  struct ColorSlice
+  {
+    ColorSlice() : value(0), color(RGBAColor(Color(RGBColor(0,0,0)), 1.0)) {}
+    ColorSlice(float v, RGBAColor c) : value(v), color(c) {}
+    float value;  //0-1 position of slice
+    RGBAColor color;
+  };
    
-   class RGBAColorMap
-      {
-      public:
-         RGBAColorMap(unsigned int type=RGBAColorMap::InvRainbowIso, int 
numSlices = 256);
-         RGBAColorMap(vector<Color>& colors, float* positions, float* 
opacities = NULL, int numSlices = 256);
-         RGBAColorMap(vector<ColorSlice>& colors, int numSlices = 256);
-         virtual ~RGBAColorMap();
-         
-         void fillColor(unsigned int type);
-         virtual RGBAColor GetColor(float v);  // get the interpolated color 
at value v (0-1)
-         RGBAColor GetColorAbs(float v);  //don't use now
-         RGBAColor GetPreInterpolatedColor(float s1, float s2, float d);
-         void SetColors(vector<ColorSlice>& colors);
-         vector<ColorSlice> GetColors() { return _slices; }
-         ColorSlice GetSlice(int i) { return _slices.at(i); }
-         int GetNumSlices() { return _slices.size(); }
-         void SetMinMax(float min, float max);
-         void BuildSlices();
-         void PreInterpolate();
-         void computeHash();
-         void scaleAlphas(float t);
+  class RGBAColorMap
+    {
+    public:
+      RGBAColorMap(unsigned int type=RGBAColorMap::InvRainbowIso, int 
numSlices = 256);
+      RGBAColorMap(vector<Color>& colors, float* positions, float* opacities 
= NULL, int numSlices = 256);
+      RGBAColorMap(vector<ColorSlice>& colors, int numSlices = 256);
+      virtual ~RGBAColorMap();
          
-         float tInc; // t increment value for volume renderers
-         float oldTInc;
-         bool _colorScaled;
-         unsigned long long course_hash;
-         vector<ColorSlice> _slices;
-         int _numSlices;
+      void fillColor(unsigned int type);
+      virtual RGBAColor GetColor(float v);  // get the interpolated color at 
value v (0-1)
+      RGBAColor GetColorAbs(float v);  //don't use now
+      void SetColors(vector<ColorSlice>& colors);
+      vector<ColorSlice> GetColors() { return _slices; }
+      ColorSlice GetSlice(int i) { return _slices.at(i); }
+      int GetNumSlices() { return _slices.size(); }
+      void SetMinMax(float min, float max);
+      void computeHash();
+      void scaleAlphas(float t);
+      void squish(float globalMin, float globalMax, float squishMin, 
+                  float squishMax);
          
-         enum {
-            InvRainbowIso=0,
-            InvRainbow,
-            Rainbow,
-            InvGreyScale,
-            InvBlackBody,
-            BlackBody,
-            GreyScale,
-            Unknown
-         };
+      float tInc; // t increment value for volume renderers
+      float oldTInc, squish_min, squish_scale;
+      bool _colorScaled;
+      unsigned long long course_hash;
+      vector<ColorSlice> _slices;
+      int _numSlices;
          
-      protected:
-         float _min, _max, _invRange;
+      enum {
+        InvRainbowIso=0,
+        InvRainbow,
+        Rainbow,
+        InvGreyScale,
+        InvBlackBody,
+        BlackBody,
+        GreyScale,
+        Unknown
       };
+         
+    protected:
+      float _min, _max, _invRange;
+    };
    
-   struct VMCell
-   {
-     // Need to make sure we have a 64 bit thing
-     unsigned long long course_hash;
-     // The max of unsigned long long is ULLONG_MAX
-     VMCell(): course_hash(0) {}
-      
-     void turn_on_bits(float min, float max, float data_min, float data_max) 
{
-       // We know that we have 64 bits, so figure out where min and max map
-       // into [0..63].
-       int min_index = (int)((min-data_min)/(data_max-data_min)*63);
-       /*      T max_index_prep = ((max-data_min)/(data_max-data_min)*63); */
-       /*      int max_index = max_index_prep-(int)max_index_prep>0? */
-       /*        (int)max_index_prep+1:(int)max_index_prep; */
-       int max_index = 
(int)ceil(double((max-data_min)/(data_max-data_min)*63));
-       // Do some checks
+  struct VMCell
+  {
+    // Need to make sure we have a 64 bit thing
+    unsigned long long course_hash;
+    // The max of unsigned long long is ULLONG_MAX
+    VMCell(): course_hash(0) {}
+      
+    void turn_on_bits(float min, float max, float data_min, float data_max) {
+      // We know that we have 64 bits, so figure out where min and max map
+      // into [0..63].
+      int min_index = (int)((min-data_min)/(data_max-data_min)*63);
+      /*      T max_index_prep = ((max-data_min)/(data_max-data_min)*63); */
+      /*      int max_index = max_index_prep-(int)max_index_prep>0? */
+      /*        (int)max_index_prep+1:(int)max_index_prep; */
+      int max_index = 
(int)ceil(double((max-data_min)/(data_max-data_min)*63));
+      // Do some checks
          
-       // This will handle clamping, I hope.
-       if (min_index > 63)
-        min_index = 63;
-       if (max_index < 0)
-        max_index = 0;
-       if (min_index < 0)
-        min_index = 0;
-       if (max_index > 63)
-        max_index = 63;
-       for (int i = min_index; i <= max_index; i++)
-        course_hash |= 1ULL << i;
-     }
-     inline VMCell& operator |= (const VMCell& v) {
-       course_hash |= v.course_hash;
-       return *this;
-     }
-     inline bool operator & (const VMCell& v) {
-       return (course_hash & v.course_hash) != 0;
-     }
-     friend ostream& operator<<(ostream& out,const VMCell& cell)  {
-       for( int i = 0; i < 64; i++) {
-        unsigned long long bit= cell.course_hash & (1ULL << i);
-        if (bit)
-          out << "1";
-        else
-          out << "0";
-       }
-       return out;
-     }
-   };
-   struct CellData {
-     VMCell cell;
-   };
+      // This will handle clamping, I hope.
+      if (min_index > 63)
+        min_index = 63;
+      if (max_index < 0)
+        max_index = 0;
+      if (min_index < 0)
+        min_index = 0;
+      if (max_index > 63)
+        max_index = 63;
+      for (int i = min_index; i <= max_index; i++)
+        course_hash |= 1ULL << i;
+    }
+    inline VMCell& operator |= (const VMCell& v) {
+      course_hash |= v.course_hash;
+      return *this;
+    }
+    inline bool operator & (const VMCell& v) {
+      return (course_hash & v.course_hash) != 0;
+    }
+    friend ostream& operator<<(ostream& out,const VMCell& cell)  {
+      for( int i = 0; i < 64; i++) {
+        unsigned long long bit= cell.course_hash & (1ULL << i);
+        if (bit)
+          out << "1";
+        else
+          out << "0";
+      }
+      return out;
+    }
+  };
+  struct CellData {
+    VMCell cell;
+  };
    
-   template<class T>
-     class Volume : public PrimitiveCommon, public Material
-     {
-     protected:
-       class HVIsectContext {
-       public:
-        // These parameters could be modified and hold accumulating state
-        Color total;
-        float alpha;
-        // These parameters should not change
-        int dix_dx, diy_dy, diz_dz;
-        VMCell transfunct;
-        double t_inc;
-        double t_min;
-        double t_max;
-        double t_inc_inv;
-        Ray ray;
-       };
-     public:
-       static void newFrame();
-       typedef unsigned long long mcT;
-       vector<mcT> cellVector_mc; // color hashes
+  template<class T>
+    class Volume : public PrimitiveCommon, public Material
+    {
+    protected:
+      class HVIsectContext {
+      public:
+        // These parameters could be modified and hold accumulating state
+        Color total;
+        float alpha;
+        // These parameters should not change
+        int dix_dx, diy_dy, diz_dz;
+        VMCell transfunct;
+        double t_inc;
+        double t_min;
+        double t_max;
+        double t_inc_inv;
+        Ray ray;
+      };
+    public:
+      static void newFrame();
+      typedef unsigned long long mcT;
+      vector<mcT> cellVector_mc; // color hashes
          
-       Volume(GridArray3<T>* data, RGBAColorMap* colorMap, const BBox& 
bounds,
-             double cellStepSize, int depth, Primitive* child = NULL,
-             double forceDataMin = -FLT_MAX, double forceDataMax = -FLT_MAX);
-       virtual ~Volume();
-       void setBounds(BBox bounds);
-       void setColorMap(RGBAColorMap* map) { _colorMap = map; }
-       void getMinMax(double* min, double* max){ *min = _dataMin; *max = 
_dataMax; }
-       void computeHistogram(int numBuckets, int* histValues);
-       virtual void preprocess(const PreprocessContext& context);
-       virtual void shade(const RenderContext & context, RayPacket& rays) 
const;
-       virtual void attenuateShadows(const RenderContext& context, 
RayPacket& shadowRays) const;
-     virtual void intersect(const RenderContext& context, RayPacket& rays) 
const
-     {
-       float vol_t_min[rays.end()];
-       float vol_t_max[rays.end()];
-       float vol_t_child[rays.end()];
-       bool intersected[rays.end()];
-       // This is so our t values have the same scale as other prims, e.g., 
TexTriangle
-       rays.normalizeDirections();
+      Volume(GridArray3<T>* data, RGBAColorMap* colorMap, const BBox& bounds,
+             double cellStepSize, int depth, Primitive* child = NULL,
+             double forceDataMin = -FLT_MAX, double forceDataMax = -FLT_MAX);
+      virtual ~Volume();
+      void setBounds(BBox bounds);
+      void setColorMap(RGBAColorMap* map) { _colorMap = map; }
+      void getMinMax(double* min, double* max){ *min = _dataMin; *max = 
_dataMax; }
+      void computeHistogram(int numBuckets, int* histValues);
+      virtual void preprocess(const PreprocessContext& context);
+      virtual void shade(const RenderContext & context, RayPacket& rays) 
const;
+      virtual void attenuateShadows(const RenderContext& context, RayPacket& 
shadowRays) const;
+      virtual void intersect(const RenderContext& context, RayPacket& rays) 
const
+        {
+          float vol_t_max[rays.end()];
+          float vol_t_min[rays.end()];
+          bool intersected[rays.end()];
+          // This is so our t values have the same scale as other prims, 
e.g., TexTriangle
+          rays.normalizeDirections();
   
-       // Intersection algorithm requires inverse directions computed.
-       rays.computeInverseDirections();
-       rays.computeSigns();
+          // Intersection algorithm requires inverse directions computed.
+          rays.computeInverseDirections();
+          rays.computeSigns();
 
-       // Iterate over each ray.
-       for (int i=rays.begin();i<rays.end();++i) {
-         intersected[i] = false;
-         Real tmin, tmax;
-         // Check for an intersection.
-         if (Intersection::intersectAaBox( _bbox,
-                                           tmin,
-                                           tmax,
-                                           rays.getRay(i),
-                                           rays.getSigns(i),
-                                           rays.getInverseDirection(i))){
-           // Check to see if we are inside the box.
-           //if (tmin > T_EPSILON)
+          // Iterate over each ray.
+          for (int i=rays.begin();i<rays.end();++i) {
+            intersected[i] = false;
+            Real tmin, tmax;
+            // Check for an intersection.
+            if (Intersection::intersectAaBox( _bbox,
+                                              tmin,
+                                              tmax,
+                                              rays.getRay(i),
+                                              rays.getSigns(i),
+                                              rays.getInverseDirection(i))){
+              // Check to see if we are inside the box.
+              //if (tmin > T_EPSILON)
              
-             // rays.hit( i, tmin, getMaterial(), this, getTexCoordMapper() 
);
-           // And use the max intersection if we are.
-           //else
-             //rays.hit( i, tmax, getMaterial(), this, getTexCoordMapper() );
-           vol_t_min[i] = tmin;
-           vol_t_max[i] = tmax;
-           intersected[i] = true;
-           if (_child) {
-             //if we have already hit something inside volume
-             // assume it is child so we don't want to intersect it again
+              // rays.hit( i, tmin, getMaterial(), this, getTexCoordMapper() 
);
+              // And use the max intersection if we are.
+              //else
+              //rays.hit( i, tmax, getMaterial(), this, getTexCoordMapper() 
);
+              vol_t_min[i] = tmin;
+              vol_t_max[i] = tmax;
+              intersected[i] = true;
+              if (_child) {
+                //if we have already hit something inside volume
+                // assume it is child so we don't want to intersect it again
 
-             //TODO: might be better to setup a child ray packet
-             if (rays.wasHit(i) && (rays.getMinT(i) < 
-                                  tmax)) {
-             rays.hit(i, tmin, this, this, getTexCoordMapper() );
-             }
-           }
-         }
-       }
-       if (_child) {
-         _child->intersect(context, rays);
-       }
-       for (int i=rays.begin();i<rays.end();++i) {
-         if (!intersected[i])
-           continue;
-         //put tmin, tmax and child_min onto scratchpad
-         rays.getScratchpad<Real>(0)[i] = vol_t_min[i];
-         rays.getScratchpad<Real>(1)[i] = vol_t_max[i];
-         if (!_child || fabs(rays.getMinT(i) - vol_t_min[i]) < T_EPSILON)
-           rays.getScratchpad<Real>(2)[i] = vol_t_max[i];
-         else
-           rays.getScratchpad<Real>(2)[i] = rays.getMinT(i);
-         rays.hit(i, vol_t_min[i], this, this, getTexCoordMapper() );
-       }
-     }
-virtual void computeNormal(const RenderContext&, RayPacket& rays) const
-{
-  rays.computeHitPositions();
-  for(int i=rays.begin(); i<rays.end(); i++) {
-    Vector hp = rays.getHitPosition(i);
-    if (Abs(hp.x() - _bbox[0][0]) < 0.0001)
-      rays.setNormal(i, Vector(-1, 0, 0 ));
+                //TODO: might be better to setup a child ray packet
+                if (rays.wasHit(i) && (rays.getMinT(i) < 
+                                       tmax)) {
+                  rays.hit(i, tmin, this, this, getTexCoordMapper() );
+                }
+              }
+            }
+          }
+          if (_child) {
+            _child->intersect(context, rays);
+          }
+          for (int i=rays.begin();i<rays.end();++i) {
+            if (!intersected[i])
+              continue;
+            //put tmin, tmax and child_min onto scratchpad
+            rays.getScratchpad<Real>(0)[i] = vol_t_min[i];
+            rays.getScratchpad<Real>(1)[i] = vol_t_max[i];
+            if (!_child || fabs(rays.getMinT(i) - vol_t_min[i]) < T_EPSILON)
+              rays.getScratchpad<Real>(2)[i] = vol_t_max[i];
+            else
+              rays.getScratchpad<Real>(2)[i] = rays.getMinT(i);
+            rays.hit(i, vol_t_min[i], this, this, getTexCoordMapper() );
+          }
+        }
+      virtual void computeNormal(const RenderContext&, RayPacket& rays) const
+        {
+          rays.computeHitPositions();
+          for(int i=rays.begin(); i<rays.end(); i++) {
+            Vector hp = rays.getHitPosition(i);
+            if (Abs(hp.x() - _bbox[0][0]) < 0.0001)
+              rays.setNormal(i, Vector(-1, 0, 0 ));
     
-    else if (Abs(hp.x() - _bbox[1][0]) < 0.0001)
-      rays.setNormal(i, Vector( 1, 0, 0 ));
+            else if (Abs(hp.x() - _bbox[1][0]) < 0.0001)
+              rays.setNormal(i, Vector( 1, 0, 0 ));
     
-    else if (Abs(hp.y() - _bbox[0][1]) < 0.0001)
-      rays.setNormal(i, Vector( 0,-1, 0 ));
+            else if (Abs(hp.y() - _bbox[0][1]) < 0.0001)
+              rays.setNormal(i, Vector( 0,-1, 0 ));
     
-    else if (Abs(hp.y() - _bbox[1][1]) < 0.0001)
-      rays.setNormal(i, Vector( 0, 1, 0 ));
+            else if (Abs(hp.y() - _bbox[1][1]) < 0.0001)
+              rays.setNormal(i, Vector( 0, 1, 0 ));
     
-    else if (Abs(hp.z() - _bbox[0][2]) < 0.0001)
-      rays.setNormal(i, Vector( 0, 0,-1 ));
+            else if (Abs(hp.z() - _bbox[0][2]) < 0.0001)
+              rays.setNormal(i, Vector( 0, 0,-1 ));
     
-    else 
-      rays.setNormal(i, Vector( 0, 0, 1 ));
-  }
-}
+            else 
+              rays.setNormal(i, Vector( 0, 0, 1 ));
+          }
+        }
 
- BBox getBounds();
+      BBox getBounds();
 
-virtual void computeBounds(const PreprocessContext&, BBox& bbox_) const
-{
-  //  bbox.extendByPoint(Point(xmin, ymin, zmin));
-  //  bbox.extendByPoint(Point(xmax, ymax, zmax));
-  bbox_.extendByPoint( _bbox[0] );
-  bbox_.extendByPoint( _bbox[1] );
-}
-       GridArray3<T>* _data;
-       float getValue(int x, int y, int z);
-       GridArray3<VMCell>* macrocells;
-       void calc_mcell(int depth, int ix, int iy, int iz, VMCell& mcell);
-       void parallel_calc_mcell(int cell);
-       void isect(const int depth, double t_sample,
-                 const double dtdx, const double dtdy, const double dtdz,
-                 double next_x, double next_y, double next_z,
-                 int ix, int iy, int iz,
-                 const int startx, const int starty, const int startz,
-                 const Vector& cellcorner, const Vector& celldir,
-                 HVIsectContext &isctx) const;
-       Vector diag;
-       Vector inv_diag;
-     protected:
-       int _nx,_ny,_nz;
-       RGBAColorMap* _colorMap;
-       BBox _bounds;
-       BBox _bbox;
-       Vector _datadiag;
-       Vector _sdiag;
-       Vector _hierdiag;
-       Vector _ihierdiag;
-       int _depth;
-       int* _xsize,*_ysize,*_zsize;
-       double* _ixsize, *_iysize, *_izsize;
-       Vector _cellSize;
-       float _stepSize;
-       float _dataMin;
-       float _dataMax;
-       float _colorScalar;
-       float _maxDistance;
-       Primitive* _child;
-     };
+      virtual void computeBounds(const PreprocessContext&, BBox& bbox_) const
+        {
+          //  bbox.extendByPoint(Point(xmin, ymin, zmin));
+          //  bbox.extendByPoint(Point(xmax, ymax, zmax));
+          bbox_.extendByPoint( _bbox[0] );
+          bbox_.extendByPoint( _bbox[1] );
+        }
+      void setStepSize(T stepSize)
+        {
+          _stepSize = stepSize;
+        }
+      GridArray3<T>* _data;
+      float getValue(int x, int y, int z);
+      GridArray3<VMCell>* macrocells;
+      void calc_mcell(int depth, int ix, int iy, int iz, VMCell& mcell);
+      void parallel_calc_mcell(int cell);
+      void isect(const int depth, double t_sample,
+                 const double dtdx, const double dtdy, const double dtdz,
+                 double next_x, double next_y, double next_z,
+                 int ix, int iy, int iz,
+                 const int startx, const int starty, const int startz,
+                 const Vector& cellcorner, const Vector& celldir,
+                 HVIsectContext &isctx) const;
+      Vector diag;
+      Vector inv_diag;
+    protected:
+      int _nx,_ny,_nz;
+      RGBAColorMap* _colorMap;
+      BBox _bounds;
+      BBox _bbox;
+      Vector _datadiag;
+      Vector _sdiag;
+      Vector _hierdiag;
+      Vector _ihierdiag;
+      int _depth;
+      int* _xsize,*_ysize,*_zsize;
+      double* _ixsize, *_iysize, *_izsize;
+      Vector _cellSize;
+      T _stepSize;
+      float _dataMin;
+      float _dataMax;
+      float _colorScalar;
+      float _maxDistance;
+      Primitive* _child;
+    };
    
-   template<class T>
-     Volume<T>::Volume(GridArray3<T>* data, RGBAColorMap* colorMap, 
-                      const BBox& bounds, double cellStepSize, 
-                      int depth, Primitive* child,
-                      double forceDataMin, double forceDataMax)
-     : _data(data), _colorMap(colorMap), _child(child)
-     {
-       //slightly expand the bounds.
-       _bounds[0] = bounds[0] - bounds.diagonal().length()*T_EPSILON;
-       _bounds[1] = bounds[1] + bounds.diagonal().length()*T_EPSILON;
-      
-       Vector diag = _bounds.diagonal();
-      
-       _cellSize = diag*Vector( 1.0 / (double)(_data->getNx()-1),
-                               1.0 / (double)(_data->getNy()-1),
-                               1.0 / (double)(_data->getNz()-1));
-      
-       //_stepSize = cellStepSize*_cellSize.length()/sqrt(3.0);
-       _stepSize = cellStepSize;
-       _maxDistance = diag.length();
-      
-       float min = 0,max = 0;
-       //_data->getMinMax(&min, &max);
-       min = FLT_MAX;
-       max = -FLT_MAX;
-       //computeMinMax(min, max, *_data);
-       unsigned int size = _data->getNx()*_data->getNy()*_data->getNz();
-       for (int i = 0; i < (int)size; i++)
-        {
-          if ((*_data)[i] < min) min = (*_data)[i];
-          if ((*_data)[i] > max) max = (*_data)[i];
-        }
-       if (forceDataMin != -FLT_MAX || forceDataMax != -FLT_MAX)
-        {
-          min = forceDataMin;
-          max = forceDataMax;
-        }
-       _dataMin = min;
-       _dataMax = max;
-       _colorScalar = 1.0f/(_dataMax - _dataMin);
-       cout << "datamin/max: " << min << " " << max << endl;
-      
-       _depth = depth;
-       if (_depth <= 0)
-         _depth=1;
-       _datadiag = diag;
-       _nx = _data->getNx();
-       _ny = _data->getNy();
-       _nz = _data->getNz();
-       _sdiag = _datadiag/Vector(_nx-1,_ny-1,_nz-1);
-       inv_diag  = diag.inverse();
-      
-       // Compute all the grid stuff
-       _xsize=new int[depth];
-       _ysize=new int[depth];
-       _zsize=new int[depth];
-       int tx=_nx-1;
-       int ty=_ny-1;
-       int tz=_nz-1;
-       for(int i=depth-1;i>=0;i--){
-         int nx=(int)(pow(tx, 1./(i+1))+.9);
-         tx=(tx+nx-1)/nx;
-         _xsize[depth-i-1]=nx;
-         int ny=(int)(pow(ty, 1./(i+1))+.9);
-         ty=(ty+ny-1)/ny;
-         _ysize[depth-i-1]=ny;
-         int nz=(int)(pow(tz, 1./(i+1))+.9);
-         tz=(tz+nz-1)/nz;
-         _zsize[depth-i-1]=nz;
-       }
-       _ixsize=new double[depth];
-       _iysize=new double[depth];
-       _izsize=new double[depth];
-       cerr << "Calculating depths...\n";
-       for(int i=0;i<depth;i++){
-         cerr << "xsize=" << _xsize[i] << ", ysize=" << _ysize[i] << ", 
zsize=" << _zsize[i] << '\n';
-         _ixsize[i]=1./_xsize[i];
-         _iysize[i]=1./_ysize[i];
-         _izsize[i]=1./_zsize[i];
-       }
-       cerr << "X: ";
-       tx=1;
-       for(int i=depth-1;i>=0;i--){
-         cerr << _xsize[i] << ' ';
-         tx*=_xsize[i];
-       }
-       cerr << "(" << tx << ")\n";
-       if(tx<_nx-1){
-         cerr << "TX TOO SMALL!\n";
-         exit(1);
-       }
-       cerr << "Y: ";
-       ty=1;
-       for(int i=depth-1;i>=0;i--){
-         cerr << _ysize[i] << ' ';
-         ty*=_ysize[i];
-       }
-       cerr << "(" << ty << ")\n";
-       if(ty<_ny-1){
-         cerr << "TY TOO SMALL!\n";
-         exit(1);
-       }
-       cerr << "Z: ";
-       tz=1;
-       for(int i=depth-1;i>=0;i--){
-         cerr << _zsize[i] << ' ';
-         tz*=_zsize[i];
-       }
-       cerr << "(" << tz << ")\n";
-       if(tz<_nz-1){
-         cerr << "TZ TOO SMALL!\n";
-         exit(1);
-       }
-       _hierdiag=_datadiag*Vector(tx,ty,tz)/Vector(_nx-1,_ny-1,_nz-1);
-       _ihierdiag=_hierdiag.inverse();
-      
-       if(depth==1){
-         macrocells=0;
-       } else {
-         macrocells=new GridArray3<VMCell>[depth+1];
-         int xs=1;
-         int ys=1;
-         int zs=1;
-         for(int d=depth-1;d>=1;d--){
-          xs*=_xsize[d];
-          ys*=_ysize[d];
-          zs*=_zsize[d];
-          macrocells[d].resize(xs, ys, zs);
-          cerr << "Depth " << d << ": " << xs << "x" << ys << "x" << zs << 
'\n';
-         }
-         cerr << "Building hierarchy\n";
-         VMCell top;
-         calc_mcell(depth-1,0,0,0,top);
-         cerr << "done\n";
-       }
-       //cerr << "**************************************************\n";
-       //print(cerr);
-       //cerr << "**************************************************\n";
-     }
+  template<class T>
+    Volume<T>::Volume(GridArray3<T>* data, RGBAColorMap* colorMap, 
+                      const BBox& bounds, double cellStepSize, 
+                      int depth, Primitive* child,
+                      double forceDataMin, double forceDataMax)
+    : _data(data), _colorMap(colorMap), _child(child)
+    {
+      //slightly expand the bounds.
+      _bounds[0] = bounds[0] - bounds.diagonal().length()*T_EPSILON;
+      _bounds[1] = bounds[1] + bounds.diagonal().length()*T_EPSILON;
+      
+      Vector diag = _bounds.diagonal();
+      
+      _cellSize = diag*Vector( 1.0 / (double)(_data->getNx()-1),
+                               1.0 / (double)(_data->getNy()-1),
+                               1.0 / (double)(_data->getNz()-1));
+      
+      //_stepSize = cellStepSize*_cellSize.length()/sqrt(3.0);
+      _stepSize = cellStepSize;
+      _maxDistance = diag.length();
+      
+      float min = 0,max = 0;
+      //_data->getMinMax(&min, &max);
+      min = FLT_MAX;
+      max = -FLT_MAX;
+      //computeMinMax(min, max, *_data);
+      unsigned int size = _data->getNx()*_data->getNy()*_data->getNz();
+      for (int i = 0; i < (int)size; i++)
+        {
+          if ((*_data)[i] < min) min = (*_data)[i];
+          if ((*_data)[i] > max) max = (*_data)[i];
+        }
+      if (forceDataMin != -FLT_MAX || forceDataMax != -FLT_MAX)
+        {
+          min = forceDataMin;
+          max = forceDataMax;
+        }
+      _dataMin = min;
+      _dataMax = max;
+      _colorScalar = 1.0f/(_dataMax - _dataMin);
+      cout << "datamin/max: " << min << " " << max << endl;
+      
+      _depth = depth;
+      if (_depth <= 0)
+        _depth=1;
+      _datadiag = diag;
+      _nx = _data->getNx();
+      _ny = _data->getNy();
+      _nz = _data->getNz();
+      _sdiag = _datadiag/Vector(_nx-1,_ny-1,_nz-1);
+      inv_diag  = diag.inverse();
+      
+      // Compute all the grid stuff
+      _xsize=new int[depth];
+      _ysize=new int[depth];
+      _zsize=new int[depth];
+      int tx=_nx-1;
+      int ty=_ny-1;
+      int tz=_nz-1;
+      for(int i=depth-1;i>=0;i--){
+        int nx=(int)(pow(tx, 1./(i+1))+.9);
+        tx=(tx+nx-1)/nx;
+        _xsize[depth-i-1]=nx;
+        int ny=(int)(pow(ty, 1./(i+1))+.9);
+        ty=(ty+ny-1)/ny;
+        _ysize[depth-i-1]=ny;
+        int nz=(int)(pow(tz, 1./(i+1))+.9);
+        tz=(tz+nz-1)/nz;
+        _zsize[depth-i-1]=nz;
+      }
+      _ixsize=new double[depth];
+      _iysize=new double[depth];
+      _izsize=new double[depth];
+      cerr << "Calculating depths...\n";
+      for(int i=0;i<depth;i++){
+        cerr << "xsize=" << _xsize[i] << ", ysize=" << _ysize[i] << ", 
zsize=" << _zsize[i] << '\n';
+        _ixsize[i]=1./_xsize[i];
+        _iysize[i]=1./_ysize[i];
+        _izsize[i]=1./_zsize[i];
+      }
+      cerr << "X: ";
+      tx=1;
+      for(int i=depth-1;i>=0;i--){
+        cerr << _xsize[i] << ' ';
+        tx*=_xsize[i];
+      }
+      cerr << "(" << tx << ")\n";
+      if(tx<_nx-1){
+        cerr << "TX TOO SMALL!\n";
+        exit(1);
+      }
+      cerr << "Y: ";
+      ty=1;
+      for(int i=depth-1;i>=0;i--){
+        cerr << _ysize[i] << ' ';
+        ty*=_ysize[i];
+      }
+      cerr << "(" << ty << ")\n";
+      if(ty<_ny-1){
+        cerr << "TY TOO SMALL!\n";
+        exit(1);
+      }
+      cerr << "Z: ";
+      tz=1;
+      for(int i=depth-1;i>=0;i--){
+        cerr << _zsize[i] << ' ';
+        tz*=_zsize[i];
+      }
+      cerr << "(" << tz << ")\n";
+      if(tz<_nz-1){
+        cerr << "TZ TOO SMALL!\n";
+        exit(1);
+      }
+      _hierdiag=_datadiag*Vector(tx,ty,tz)/Vector(_nx-1,_ny-1,_nz-1);
+      _ihierdiag=_hierdiag.inverse();
+      
+      if(depth==1){
+        macrocells=0;
+      } else {
+        macrocells=new GridArray3<VMCell>[depth+1];
+        int xs=1;
+        int ys=1;
+        int zs=1;
+        for(int d=depth-1;d>=1;d--){
+          xs*=_xsize[d];
+          ys*=_ysize[d];
+          zs*=_zsize[d];
+          macrocells[d].resize(xs, ys, zs);
+          cerr << "Depth " << d << ": " << xs << "x" << ys << "x" << zs << 
'\n';
+        }
+        cerr << "Building hierarchy\n";
+        VMCell top;
+        calc_mcell(depth-1,0,0,0,top);
+        cerr << "done\n";
+      }
+      //cerr << "**************************************************\n";
+      //print(cerr);
+      //cerr << "**************************************************\n";
+    }
    
-   template<class T>
-     Volume<T>::~Volume()
-     {
-       delete[] macrocells;
-       delete[] _xsize;
-       delete[] _ysize;
-       delete[] _zsize;
-       delete[] _ixsize;
-       delete[] _iysize;
-       delete[] _izsize;
-     }
+  template<class T>
+    Volume<T>::~Volume()
+    {
+      delete[] macrocells;
+      delete[] _xsize;
+      delete[] _ysize;
+      delete[] _zsize;
+      delete[] _ixsize;
+      delete[] _iysize;
+      delete[] _izsize;
+    }
 
-template<class T>
-BBox Volume<T>::getBounds()
-{
-  return _bounds;
-}
+  template<class T>
+    BBox Volume<T>::getBounds()
+    {
+      return _bounds;
+    }
 
-   template<class T>
-     void Volume<T>::setBounds(BBox bounds)
-     {
-       //slightly expand the bounds.
-       _bounds[0] = bounds[0] - bounds.diagonal().length()*T_EPSILON;
-       _bounds[1] = bounds[1] + bounds.diagonal().length()*T_EPSILON;
-       Vector diag = _bounds.diagonal();
-       _bbox = bounds;
-      
-       _cellSize = diag*Vector( 1.0 / (double)(_data->getNx()-1),
-                               1.0 / (double)(_data->getNy()-1),
-                               1.0 / (double)(_data->getNz()-1));
-      
-       //_stepSize = cellStepSize*_cellSize.length()/sqrt(3.0);
-       _maxDistance = diag.length();
-      
-       if (_depth <= 0)
-         _depth=1;
-       Vector old_datadiag = _datadiag;
-       _datadiag = diag;
-       _sdiag = _datadiag/Vector(_nx-1,_ny-1,_nz-1);
-       inv_diag  = diag.inverse();
-      
-       _hierdiag=_hierdiag*_datadiag/old_datadiag;
-       _ihierdiag=_hierdiag.inverse();
-  }
+  template<class T>
+    void Volume<T>::setBounds(BBox bounds)
+    {
+      //slightly expand the bounds.
+      _bounds[0] = bounds[0] - bounds.diagonal().length()*T_EPSILON;
+      _bounds[1] = bounds[1] + bounds.diagonal().length()*T_EPSILON;
+      Vector diag = _bounds.diagonal();
+      _bbox = bounds;
+      
+      _cellSize = diag*Vector( 1.0 / (double)(_data->getNx()-1),
+                               1.0 / (double)(_data->getNy()-1),
+                               1.0 / (double)(_data->getNz()-1));
+      
+      //_stepSize = cellStepSize*_cellSize.length()/sqrt(3.0);
+      _maxDistance = diag.length();
+      
+      if (_depth <= 0)
+        _depth=1;
+      Vector old_datadiag = _datadiag;
+      _datadiag = diag;
+      _sdiag = _datadiag/Vector(_nx-1,_ny-1,_nz-1);
+      inv_diag  = diag.inverse();
+      
+      _hierdiag=_hierdiag*_datadiag/old_datadiag;
+      _ihierdiag=_hierdiag.inverse();
+    }
    
-   template<class T>
-   void computeMinMax(float& min, float& max, GridArray3<T>& grid)
-   {
+  template<class T>
+    void computeMinMax(float& min, float& max, GridArray3<T>& grid)
+    {
       unsigned int i, total = grid.getNx() * grid.getNy() * grid.getNz();
       
       min = max = grid[0];
       for(i=1; i<total; i++)
-      {
-         if  (min > grid[i]) min = grid[i];
-         else if (max < grid[i]) max = grid[i];
-      }
-   }
+        {
+          if  (min > grid[i]) min = grid[i];
+          else if (max < grid[i]) max = grid[i];
+        }
+    }
    
    
-   template<class T>
-   void Volume<T>::calc_mcell(int depth, int startx, int starty, int startz, 
VMCell& mcell)
-   {
+  template<class T>
+    void Volume<T>::calc_mcell(int depth, int startx, int starty, int 
startz, VMCell& mcell)
+    {
       int endx=startx+_xsize[depth];
       int endy=starty+_ysize[depth];
       int endz=startz+_zsize[depth];
@@ -516,85 +518,85 @@
       int ny = _ny;
       int nz = _nz;
       if(endx>nx-1)
-         endx=nx-1;
+        endx=nx-1;
       if(endy>ny-1)
-         endy=ny-1;
+        endy=ny-1;
       if(endz>nz-1)
-         endz=nz-1;
+        endz=nz-1;
       if(startx>=endx || starty>=endy || startz>=endz){
-         /* This cell won't get used... */
-         return;
+        /* This cell won't get used... */
+        return;
       }
       if(depth==0){
-         // We are at the data level.  Loop over each voxel and compute the
-         // mcell for this group of voxels.
-         GridArray3<T>& data = *_data;
-         float data_min = _dataMin;
-         float data_max = _dataMax;
-         for(int ix=startx;ix<endx;ix++){
-            for(int iy=starty;iy<endy;iy++){
-               for(int iz=startz;iz<endz;iz++){
-                  float rhos[8];
-                  rhos[0]=data(ix, iy, iz);
-                  rhos[1]=data(ix, iy, iz+1);
-                  rhos[2]=data(ix, iy+1, iz);
-                  rhos[3]=data(ix, iy+1, iz+1);
-                  rhos[4]=data(ix+1, iy, iz);
-                  rhos[5]=data(ix+1, iy, iz+1);
-                  rhos[6]=data(ix+1, iy+1, iz);
-                  rhos[7]=data(ix+1, iy+1, iz+1);
-                  float minr=rhos[0];
-                  float maxr=rhos[0];
-                  for(int i=1;i<8;i++){
-                     if(rhos[i]<minr)
-                        minr=rhos[i];
-                     if(rhos[i]>maxr)
-                        maxr=rhos[i];
-                  }
-                  // Figure out what bits to turn on running from min to max.
-                  mcell.turn_on_bits(minr, maxr, data_min, data_max);
-               }
+        // We are at the data level.  Loop over each voxel and compute the
+        // mcell for this group of voxels.
+        GridArray3<T>& data = *_data;
+        float data_min = _dataMin;
+        float data_max = _dataMax;
+        for(int ix=startx;ix<endx;ix++){
+          for(int iy=starty;iy<endy;iy++){
+            for(int iz=startz;iz<endz;iz++){
+              float rhos[8];
+              rhos[0]=data(ix, iy, iz);
+              rhos[1]=data(ix, iy, iz+1);
+              rhos[2]=data(ix, iy+1, iz);
+              rhos[3]=data(ix, iy+1, iz+1);
+              rhos[4]=data(ix+1, iy, iz);
+              rhos[5]=data(ix+1, iy, iz+1);
+              rhos[6]=data(ix+1, iy+1, iz);
+              rhos[7]=data(ix+1, iy+1, iz+1);
+              float minr=rhos[0];
+              float maxr=rhos[0];
+              for(int i=1;i<8;i++){
+                if(rhos[i]<minr)
+                  minr=rhos[i];
+                if(rhos[i]>maxr)
+                  maxr=rhos[i];
+              }
+              // Figure out what bits to turn on running from min to max.
+              mcell.turn_on_bits(minr, maxr, data_min, data_max);
             }
-         }
+          }
+        }
       } else {
-         int nxl=_xsize[depth-1];
-         int nyl=_ysize[depth-1];
-         int nzl=_zsize[depth-1];
-         GridArray3<VMCell>& mcells=macrocells[depth];
-         for(int x=startx;x<endx;x++){
-            for(int y=starty;y<endy;y++){
-               for(int z=startz;z<endz;z++){
-                  // Compute the mcell for this block and store it in tmp
-                  VMCell tmp;
-                  calc_mcell(depth-1, x*nxl, y*nyl, z*nzl, tmp);
-                  // Stash it away
-                  mcells(x,y,z)=tmp;
-                  // Now aggregate all the mcells created for this depth by
-                  // doing a bitwise or.
-                  mcell |= tmp;
-               }
+        int nxl=_xsize[depth-1];
+        int nyl=_ysize[depth-1];
+        int nzl=_zsize[depth-1];
+        GridArray3<VMCell>& mcells=macrocells[depth];
+        for(int x=startx;x<endx;x++){
+          for(int y=starty;y<endy;y++){
+            for(int z=startz;z<endz;z++){
+              // Compute the mcell for this block and store it in tmp
+              VMCell tmp;
+              calc_mcell(depth-1, x*nxl, y*nyl, z*nzl, tmp);
+              // Stash it away
+              mcells(x,y,z)=tmp;
+              // Now aggregate all the mcells created for this depth by
+              // doing a bitwise or.
+              mcell |= tmp;
             }
-         }
+          }
+        }
       }
-   }
+    }
    
-   template<class T>
-   void Volume<T>::preprocess(const PreprocessContext& context)
-   {
+  template<class T>
+    void Volume<T>::preprocess(const PreprocessContext& context)
+    {
       
-   }
+    }
    
    
 #define RAY_TERMINATION_THRESHOLD 0.9
-   template<class T>
-   void Volume<T>::isect(const int depth, double t_sample,
-                         const double dtdx, const double dtdy, const double 
dtdz,
-                         double next_x, double next_y, double next_z,
-                         int ix, int iy, int iz,
-                         const int startx, const int starty, const int 
startz,
-                         const Vector& cellcorner, const Vector& celldir,
-                         HVIsectContext &isctx) const
-   {
+  template<class T>
+    void Volume<T>::isect(const int depth, double t_sample,
+                          const double dtdx, const double dtdy, const double 
dtdz,
+                          double next_x, double next_y, double next_z,
+                          int ix, int iy, int iz,
+                          const int startx, const int starty, const int 
startz,
+                          const Vector& cellcorner, const Vector& celldir,
+                          HVIsectContext &isctx) const
+    {
       int cx=_xsize[depth];
       int cy=_ysize[depth];
       int cz=_zsize[depth];
@@ -602,274 +604,273 @@
       GridArray3<T>& data = *_data;
       
       if(depth==0){
-         int nx = _nx;
-         int ny = _ny;
-         int nz = _nz;
-         for(;;){
-            int gx=startx+ix;
-            int gy=starty+iy;
-            int gz=startz+iz;
+        int nx = _nx;
+        int ny = _ny;
+        int nz = _nz;
+        for(;;){
+          int gx=startx+ix;
+          int gy=starty+iy;
+          int gz=startz+iz;
             
-            // t is our t_sample
+          // t is our t_sample
             
-            // If we have valid samples
-            if(gx<nx-1 && gy<ny-1 && gz<nz-1){
-               float rhos[8];
-               rhos[0]=data(gx, gy, gz);
-               rhos[1]=data(gx, gy, gz+1);
-               rhos[2]=data(gx, gy+1, gz);
-               rhos[3]=data(gx, gy+1, gz+1);
-               rhos[4]=data(gx+1, gy, gz);
-               rhos[5]=data(gx+1, gy, gz+1);
-               rhos[6]=data(gx+1, gy+1, gz);
-               rhos[7]=data(gx+1, gy+1, gz+1);
+          // If we have valid samples
+          if(gx<nx-1 && gy<ny-1 && gz<nz-1){
+            float rhos[8];
+            rhos[0]=data(gx, gy, gz);
+            rhos[1]=data(gx, gy, gz+1);
+            rhos[2]=data(gx, gy+1, gz);
+            rhos[3]=data(gx, gy+1, gz+1);
+            rhos[4]=data(gx+1, gy, gz);
+            rhos[5]=data(gx+1, gy, gz+1);
+            rhos[6]=data(gx+1, gy+1, gz);
+            rhos[7]=data(gx+1, gy+1, gz+1);
                
-               ////////////////////////////////////////////////////////////
-               // get the weights
+            ////////////////////////////////////////////////////////////
+            // get the weights
                
-               Vector weights = cellcorner+celldir*t_sample;
-               double x_weight_high = weights.x()-ix;
-               double y_weight_high = weights.y()-iy;
-               double z_weight_high = weights.z()-iz;
+            Vector weights = cellcorner+celldir*t_sample;
+            double x_weight_high = weights.x()-ix;
+            double y_weight_high = weights.y()-iy;
+            double z_weight_high = weights.z()-iz;
                
                
-               double lz1, lz2, lz3, lz4, ly1, ly2, value;
-               lz1 = rhos[0] * (1 - z_weight_high) + rhos[1] * z_weight_high;
-               lz2 = rhos[2] * (1 - z_weight_high) + rhos[3] * z_weight_high;
-               lz3 = rhos[4] * (1 - z_weight_high) + rhos[5] * z_weight_high;
-               lz4 = rhos[6] * (1 - z_weight_high) + rhos[7] * z_weight_high;
+            double lz1, lz2, lz3, lz4, ly1, ly2, value;
+            lz1 = rhos[0] * (1 - z_weight_high) + rhos[1] * z_weight_high;
+            lz2 = rhos[2] * (1 - z_weight_high) + rhos[3] * z_weight_high;
+            lz3 = rhos[4] * (1 - z_weight_high) + rhos[5] * z_weight_high;
+            lz4 = rhos[6] * (1 - z_weight_high) + rhos[7] * z_weight_high;
                
-               ly1 = lz1 * (1 - y_weight_high) + lz2 * y_weight_high;
-               ly2 = lz3 * (1 - y_weight_high) + lz4 * y_weight_high;
+            ly1 = lz1 * (1 - y_weight_high) + lz2 * y_weight_high;
+            ly2 = lz3 * (1 - y_weight_high) + lz4 * y_weight_high;
                
-               value = ly1 * (1 - x_weight_high) + ly2 * x_weight_high;
-               value = (value - _dataMin)*_colorScalar;
+            value = ly1 * (1 - x_weight_high) + ly2 * x_weight_high;
+            value = (value - _dataMin)*_colorScalar;
                
-               RGBAColor color = _colorMap->GetColor(value);
-               float alpha_factor = color.a*(1-isctx.alpha);
-               if (alpha_factor > 0.001) {
-                  // the point is contributing, so compute the color
+            RGBAColor color = _colorMap->GetColor(value);
+            float alpha_factor = color.a*(1-isctx.alpha);
+            if (alpha_factor > 0.001) {
+              // the point is contributing, so compute the color
                   
-                  /*Light* light=isctx.cx->scene->light(0);
-                   if (light->isOn()) {
+              /*Light* light=isctx.cx->scene->light(0);
+                if (light->isOn()) {
                    
-                   // compute the gradient
-                   Vector gradient;
-                   float dx = ly2 - ly1;
+                // compute the gradient
+                Vector gradient;
+                float dx = ly2 - ly1;
                    
-                   float dy, dy1, dy2;
-                   dy1 = lz2 - lz1;
-                   dy2 = lz4 - lz3;
-                   dy = dy1 * (1 - x_weight_high) + dy2 * x_weight_high;
+                float dy, dy1, dy2;
+                dy1 = lz2 - lz1;
+                dy2 = lz4 - lz3;
+                dy = dy1 * (1 - x_weight_high) + dy2 * x_weight_high;
                    
-                   float dz, dz1, dz2, dz3, dz4, dzly1, dzly2;
-                   dz1 = rhos[1] - rhos[0];
-                   dz2 = rhos[3] - rhos[2];
-                   dz3 = rhos[5] - rhos[4];
-                   dz4 = rhos[7] - rhos[6];
-                   dzly1 = dz1 * (1 - y_weight_high) + dz2 * y_weight_high;
-                   dzly2 = dz3 * (1 - y_weight_high) + dz4 * y_weight_high;
-                   dz = dzly1 * (1 - x_weight_high) + dzly2 * x_weight_high;
-                   float length2 = dx*dx+dy*dy+dz*dz;
-                   if (length2){
-                   // this lets the compiler use a special 1/sqrt() operation
-                   float ilength2 = 1/sqrt(length2);
-                   gradient = Vector(dx*ilength2, dy*ilength2,dz*ilength2);
-                   } else {
-                   gradient = Vector(0,0,0);
-                   }
+                float dz, dz1, dz2, dz3, dz4, dzly1, dzly2;
+                dz1 = rhos[1] - rhos[0];
+                dz2 = rhos[3] - rhos[2];
+                dz3 = rhos[5] - rhos[4];
+                dz4 = rhos[7] - rhos[6];
+                dzly1 = dz1 * (1 - y_weight_high) + dz2 * y_weight_high;
+                dzly2 = dz3 * (1 - y_weight_high) + dz4 * y_weight_high;
+                dz = dzly1 * (1 - x_weight_high) + dzly2 * x_weight_high;
+                float length2 = dx*dx+dy*dy+dz*dz;
+                if (length2){
+                // this lets the compiler use a special 1/sqrt() operation
+                float ilength2 = 1/sqrt(length2);
+                gradient = Vector(dx*ilength2, dy*ilength2,dz*ilength2);
+                } else {
+                gradient = Vector(0,0,0);
+                }
                    
-                   Vector light_dir;
-                   Point current_p = isctx.ray.origin() + 
isctx.ray.direction()*t_sample - this->min.vector();
-                   light_dir = light->get_pos()-current_p;
+                Vector light_dir;
+                Point current_p = isctx.ray.origin() + 
isctx.ray.direction()*t_sample - this->min.vector();
+                light_dir = light->get_pos()-current_p;
                    
-                   Color temp = color(gradient, isctx.ray.direction(),
-                   light_dir.normal(),
-                   *(this->dpy->lookup_color(value)),
-                   light->get_color());
-                   isctx.total += temp * alpha_factor;
-                   } else {*/
-                  isctx.total += color.color*(alpha_factor);
-                  //}
-                  isctx.alpha += alpha_factor;
-               }
-               
+                Color temp = color(gradient, isctx.ray.direction(),
+                light_dir.normal(),
+                *(this->dpy->lookup_color(value)),
+                light->get_color());
+                isctx.total += temp * alpha_factor;
+                } else {*/
+              isctx.total += color.color*(alpha_factor);
+              isctx.alpha += alpha_factor;
             }
+               
+          }
             
-            // Update the new position
-            t_sample += isctx.t_inc;
+          // Update the new position
+          t_sample += isctx.t_inc;
             
-            // If we have overstepped the limit of the ray
-            if(t_sample >= isctx.t_max)
-               break;
+          // If we have overstepped the limit of the ray
+          if(t_sample >= isctx.t_max)
+            break;
             
-            // Check to see if we leave the level or not
-            bool break_forloop = false;
-            while (t_sample > next_x) {
-               // Step in x...
-               next_x+=dtdx;
-               ix+=isctx.dix_dx;
-               if(ix<0 || ix>=cx) {
-                  break_forloop = true;
-                  break;
-               }
+          // Check to see if we leave the level or not
+          bool break_forloop = false;
+          while (t_sample > next_x) {
+            // Step in x...
+            next_x+=dtdx;
+            ix+=isctx.dix_dx;
+            if(ix<0 || ix>=cx) {
+              break_forloop = true;
+              break;
             }
-            while (t_sample > next_y) {
-               next_y+=dtdy;
-               iy+=isctx.diy_dy;
-               if(iy<0 || iy>=cy) {
-                  break_forloop = true;
-                  break;
-               }
+          }
+          while (t_sample > next_y) {
+            next_y+=dtdy;
+            iy+=isctx.diy_dy;
+            if(iy<0 || iy>=cy) {
+              break_forloop = true;
+              break;
             }
-            while (t_sample > next_z) {
-               next_z+=dtdz;
-               iz+=isctx.diz_dz;
-               if(iz<0 || iz>=cz) {
-                  break_forloop = true;
-                  break;
-               }
+          }
+          while (t_sample > next_z) {
+            next_z+=dtdz;
+            iz+=isctx.diz_dz;
+            if(iz<0 || iz>=cz) {
+              break_forloop = true;
+              break;
             }
+          }
             
-            if (break_forloop)
-               break;
+          if (break_forloop)
+            break;
             
-            // This does early ray termination when we don't have anymore
-            // color to collect.
-            if (isctx.alpha >= RAY_TERMINATION_THRESHOLD)
-               break;
-         }
+          // This does early ray termination when we don't have anymore
+          // color to collect.
+          if (isctx.alpha >= RAY_TERMINATION_THRESHOLD)
+            break;
+        }
       } else {
-         GridArray3<VMCell>& mcells=macrocells[depth];
-         for(;;){
-            int gx=startx+ix;
-            int gy=starty+iy;
-            int gz=startz+iz;
-            bool hit = mcells(gx,gy,gz) & isctx.transfunct;
-            if(hit){
-               // Do this cell...
-               int new_cx=_xsize[depth-1];
-               int new_cy=_ysize[depth-1];
-               int new_cz=_zsize[depth-1];
-               int 
new_ix=(int)((cellcorner.x()+t_sample*celldir.x()-ix)*new_cx);
-               int 
new_iy=(int)((cellcorner.y()+t_sample*celldir.y()-iy)*new_cy);
-               int 
new_iz=(int)((cellcorner.z()+t_sample*celldir.z()-iz)*new_cz);
-               if(new_ix<0)
-                  new_ix=0;
-               else if(new_ix>=new_cx)
-                  new_ix=new_cx-1;
-               if(new_iy<0)
-                  new_iy=0;
-               else if(new_iy>=new_cy)
-                  new_iy=new_cy-1;
-               if(new_iz<0)
-                  new_iz=0;
-               else if(new_iz>=new_cz)
-                  new_iz=new_cz-1;
-               double new_dtdx=dtdx*_ixsize[depth-1];
-               double new_dtdy=dtdy*_iysize[depth-1];
-               double new_dtdz=dtdz*_izsize[depth-1];
-               const Vector dir(isctx.ray.direction());
-               double new_next_x;
-               if(dir.x() >= 0){
-                  new_next_x=next_x-dtdx+new_dtdx*(new_ix+1);
-               } else {
-                  new_next_x=next_x-new_ix*new_dtdx;
-               }
-               double new_next_y;
-               if(dir.y() >= 0){
-                  new_next_y=next_y-dtdy+new_dtdy*(new_iy+1);
-               } else {
-                  new_next_y=next_y-new_iy*new_dtdy;
-               }
-               double new_next_z;
-               if(dir.z() >= 0){
-                  new_next_z=next_z-dtdz+new_dtdz*(new_iz+1);
-               } else {
-                  new_next_z=next_z-new_iz*new_dtdz;
-               }
-               int new_startx=gx*new_cx;
-               int new_starty=gy*new_cy;
-               int new_startz=gz*new_cz;
-               Vector cellsize(new_cx, new_cy, new_cz);
-               isect(depth-1, t_sample,
-                     new_dtdx, new_dtdy, new_dtdz,
-                     new_next_x, new_next_y, new_next_z,
-                     new_ix, new_iy, new_iz,
-                     new_startx, new_starty, new_startz,
-                     (cellcorner-Vector(ix, iy, iz))*cellsize, 
celldir*cellsize,
-                     isctx);
+        GridArray3<VMCell>& mcells=macrocells[depth];
+        for(;;){
+          int gx=startx+ix;
+          int gy=starty+iy;
+          int gz=startz+iz;
+          bool hit = mcells(gx,gy,gz) & isctx.transfunct;
+          if(hit){
+            // Do this cell...
+            int new_cx=_xsize[depth-1];
+            int new_cy=_ysize[depth-1];
+            int new_cz=_zsize[depth-1];
+            int 
new_ix=(int)((cellcorner.x()+t_sample*celldir.x()-ix)*new_cx);
+            int 
new_iy=(int)((cellcorner.y()+t_sample*celldir.y()-iy)*new_cy);
+            int 
new_iz=(int)((cellcorner.z()+t_sample*celldir.z()-iz)*new_cz);
+            if(new_ix<0)
+              new_ix=0;
+            else if(new_ix>=new_cx)
+              new_ix=new_cx-1;
+            if(new_iy<0)
+              new_iy=0;
+            else if(new_iy>=new_cy)
+              new_iy=new_cy-1;
+            if(new_iz<0)
+              new_iz=0;
+            else if(new_iz>=new_cz)
+              new_iz=new_cz-1;
+            double new_dtdx=dtdx*_ixsize[depth-1];
+            double new_dtdy=dtdy*_iysize[depth-1];
+            double new_dtdz=dtdz*_izsize[depth-1];
+            const Vector dir(isctx.ray.direction());
+            double new_next_x;
+            if(dir.x() >= 0){
+              new_next_x=next_x-dtdx+new_dtdx*(new_ix+1);
+            } else {
+              new_next_x=next_x-new_ix*new_dtdx;
             }
-            
-            // We need to determine where the next sample is.  We do this
-            // using the closest crossing in x/y/z.  This will be the next
-            // sample point.
-            double closest;
-            if(next_x < next_y && next_x < next_z){
-               // next_x is the closest
-               closest = next_x;
-            } else if(next_y < next_z){
-               closest = next_y;
+            double new_next_y;
+            if(dir.y() >= 0){
+              new_next_y=next_y-dtdy+new_dtdy*(new_iy+1);
             } else {
-               closest = next_z;
+              new_next_y=next_y-new_iy*new_dtdy;
             }
+            double new_next_z;
+            if(dir.z() >= 0){
+              new_next_z=next_z-dtdz+new_dtdz*(new_iz+1);
+            } else {
+              new_next_z=next_z-new_iz*new_dtdz;
+            }
+            int new_startx=gx*new_cx;
+            int new_starty=gy*new_cy;
+            int new_startz=gz*new_cz;
+            Vector cellsize(new_cx, new_cy, new_cz);
+            isect(depth-1, t_sample,
+                  new_dtdx, new_dtdy, new_dtdz,
+                  new_next_x, new_next_y, new_next_z,
+                  new_ix, new_iy, new_iz,
+                  new_startx, new_starty, new_startz,
+                  (cellcorner-Vector(ix, iy, iz))*cellsize, celldir*cellsize,
+                  isctx);
+          }
+            
+          // We need to determine where the next sample is.  We do this
+          // using the closest crossing in x/y/z.  This will be the next
+          // sample point.
+          double closest;
+          if(next_x < next_y && next_x < next_z){
+            // next_x is the closest
+            closest = next_x;
+          } else if(next_y < next_z){
+            closest = next_y;
+          } else {
+            closest = next_z;
+          }
             
-            double step = ceil((closest - t_sample)*isctx.t_inc_inv);
-            t_sample += isctx.t_inc * step;
+          double step = ceil((closest - t_sample)*isctx.t_inc_inv);
+          t_sample += isctx.t_inc * step;
             
-            if(t_sample >= isctx.t_max)
-               break;
+          if(t_sample >= isctx.t_max)
+            break;
             
-            // Now that we have the next sample point, we need to determine
-            // which cell it ended up in.  There are cases (grazing corners
-            // for example) which will make the next sample not be in the
-            // next cell.  Because this case can happen, this code will try
-            // to determine which cell the sample will live.
-            //
-            // Perhaps there is a way to use cellcorner and cellsize to get
-            // ix/y/z.  The result would have to be cast to an int, and then
-            // next_x/y/z would have to be updated as needed. (next_x +=
-            // dtdx * (newix - ix).  The advantage of something like this
-            // would be the lack of branches, but it does use casts.
-            bool break_forloop = false;
-            while (t_sample > next_x) {
-               // Step in x...
-               next_x+=dtdx;
-               ix+=isctx.dix_dx;
-               if(ix<0 || ix>=cx) {
-                  break_forloop = true;
-                  break;
-               }
+          // Now that we have the next sample point, we need to determine
+          // which cell it ended up in.  There are cases (grazing corners
+          // for example) which will make the next sample not be in the
+          // next cell.  Because this case can happen, this code will try
+          // to determine which cell the sample will live.
+          //
+          // Perhaps there is a way to use cellcorner and cellsize to get
+          // ix/y/z.  The result would have to be cast to an int, and then
+          // next_x/y/z would have to be updated as needed. (next_x +=
+          // dtdx * (newix - ix).  The advantage of something like this
+          // would be the lack of branches, but it does use casts.
+          bool break_forloop = false;
+          while (t_sample > next_x) {
+            // Step in x...
+            next_x+=dtdx;
+            ix+=isctx.dix_dx;
+            if(ix<0 || ix>=cx) {
+              break_forloop = true;
+              break;
             }
-            while (t_sample > next_y) {
-               next_y+=dtdy;
-               iy+=isctx.diy_dy;
-               if(iy<0 || iy>=cy) {
-                  break_forloop = true;
-                  break;
-               }
+          }
+          while (t_sample > next_y) {
+            next_y+=dtdy;
+            iy+=isctx.diy_dy;
+            if(iy<0 || iy>=cy) {
+              break_forloop = true;
+              break;
             }
-            while (t_sample > next_z) {
-               next_z+=dtdz;
-               iz+=isctx.diz_dz;
-               if(iz<0 || iz>=cz) {
-                  break_forloop = true;
-                  break;
-               }
+          }
+          while (t_sample > next_z) {
+            next_z+=dtdz;
+            iz+=isctx.diz_dz;
+            if(iz<0 || iz>=cz) {
+              break_forloop = true;
+              break;
             }
-            if (break_forloop)
-               break;
+          }
+          if (break_forloop)
+            break;
             
-            if (isctx.alpha >= RAY_TERMINATION_THRESHOLD)
-               break;
-         }
+          if (isctx.alpha >= RAY_TERMINATION_THRESHOLD)
+            break;
+        }
       }
-   }
+    }
    
 #define RAY_TERMINATION 0.98
-   template<class T>
-   void Volume<T>::shade(const RenderContext & context, RayPacket& rays) 
const
-{
+  template<class T>
+    void Volume<T>::shade(const RenderContext & context, RayPacket& rays) 
const
+    {
       rays.normalizeDirections();
       rays.computeHitPositions();
 
@@ -885,18 +886,18 @@
       Color totals[rays.end()];
       
       for(int rayIndex = rays.begin(); rayIndex < rays.end(); rayIndex++) {
-         Vector origin = rays.getOrigin(rayIndex);
-         if (_bounds.contains(origin)) {
-            //we are inside the volume.
-            tMins[rayIndex] = 0;
-         }
-         else {
-            //we hit the volume from the outside so need to move the ray
-            //origin to the volume hitpoint.
-            origin = rays.getHitPosition(rayIndex);
-            tMins[rayIndex] = rays.getMinT(rayIndex);
-         }
-         if (!(_bounds.contains(rays.getHitPosition(rayIndex))))
+        Vector origin = rays.getOrigin(rayIndex);
+        if (_bounds.contains(origin)) {
+          //we are inside the volume.
+          tMins[rayIndex] = 0;
+        }
+        else {
+          //we hit the volume from the outside so need to move the ray
+          //origin to the volume hitpoint.
+          origin = rays.getHitPosition(rayIndex);
+          tMins[rayIndex] = rays.getMinT(rayIndex);
+        }
+        if (!(_bounds.contains(rays.getHitPosition(rayIndex))))
           {
             float tmin, tmax;
             Intersection::intersectAaBox( _bounds,
@@ -908,201 +909,201 @@
             tMins[rayIndex] = tmin;
             origin = rays.getOrigin(rayIndex) + 
rays.getDirection(rayIndex)*tmin;
           }
-         lRays1.setRay(rayIndex, origin, rays.getDirection(rayIndex));
+        lRays1.setRay(rayIndex, origin, rays.getDirection(rayIndex));
          
-         alphas[rayIndex] = 0;
+        alphas[rayIndex] = 0;
       }
       lRays1.resetHits();
       context.scene->getObject()->intersect(context, lRays1);
       lRays1.computeHitPositions();
       for(int i = rays.begin(); i < rays.end(); i++) {
-         //did we hit something, and if so, was it inside the volume.
-         if (lRays1.wasHit(i) && _bounds.contains(lRays1.getHitPosition(i)))
-            tMaxs[i] = lRays1.getMinT(i) + tMins[i];
-         else {
-            //it's possible that we hit a corner of the volume on entry
-            //and due to precision issues we can't hit the exit part of
-            //the volume. These are rare, but they do happen. Note that
-            //just checking wasHit won't work if there's geometry outside
-            //the volume.
-            tMaxs[i] = -1;
-         }
-         totals[i] = Color(RGB(0,0,0));
+        //did we hit something, and if so, was it inside the volume.
+        if (lRays1.wasHit(i) && _bounds.contains(lRays1.getHitPosition(i)))
+          tMaxs[i] = lRays1.getMinT(i) + tMins[i];
+        else {
+          //it's possible that we hit a corner of the volume on entry
+          //and due to precision issues we can't hit the exit part of
+          //the volume. These are rare, but they do happen. Note that
+          //just checking wasHit won't work if there's geometry outside
+          //the volume.
+          tMaxs[i] = -1;
+        }
+        totals[i] = Color(RGB(0,0,0));
       }
       
       for(int rayIndex = rays.begin(); rayIndex < rays.end(); rayIndex++) {
-         Ray ray = rays.getRay(rayIndex);
-         float t_min = tMins[rayIndex];
-         float t_max = tMaxs[rayIndex];
+        Ray ray = rays.getRay(rayIndex);
+        float t_min = tMins[rayIndex];
+        float t_max = tMaxs[rayIndex];
          
-         const Vector dir(ray.direction());
-         const Vector orig(ray.origin());
-         int dix_dx;
-         int ddx;
-         if(dir.x() >= 0){
-            dix_dx=1;
-            ddx=1;
-         } else {
-            dix_dx=-1;
-            ddx=0;
-         }
-         int diy_dy;
-         int ddy;
-         if(dir.y() >= 0){
-            diy_dy=1;
-            ddy=1;
-         } else {
-            diy_dy=-1;
-            ddy=0;
-         }
-         int diz_dz;
-         int ddz;
-         if(dir.z() >= 0){
-            diz_dz=1;
-            ddz=1;
-         } else {
-            diz_dz=-1;
-            ddz=0;
-         }
+        const Vector dir(ray.direction());
+        const Vector orig(ray.origin());
+        int dix_dx;
+        int ddx;
+        if(dir.x() >= 0){
+          dix_dx=1;
+          ddx=1;
+        } else {
+          dix_dx=-1;
+          ddx=0;
+        }
+        int diy_dy;
+        int ddy;
+        if(dir.y() >= 0){
+          diy_dy=1;
+          ddy=1;
+        } else {
+          diy_dy=-1;
+          ddy=0;
+        }
+        int diz_dz;
+        int ddz;
+        if(dir.z() >= 0){
+          diz_dz=1;
+          ddz=1;
+        } else {
+          diz_dz=-1;
+          ddz=0;
+        }
          
-         Vector start_p(orig+dir*t_min);
-         Vector s((start_p-_bounds.getMin())*_ihierdiag);
-         int cx=_xsize[_depth-1];
-         int cy=_ysize[_depth-1];
-         int cz=_zsize[_depth-1];
-         int ix=(int)(s.x()*cx);
-         int iy=(int)(s.y()*cy);
-         int iz=(int)(s.z()*cz);
-         if(ix>=cx)
-            ix--;
-         if(iy>=cy)
-            iy--;
-         if(iz>=cz)
-            iz--;
-         if(ix<0)
-            ix++;
-         if(iy<0)
-            iy++;
-         if(iz<0)
-            iz++;
+        Vector start_p(orig+dir*t_min);
+        Vector s((start_p-_bounds.getMin())*_ihierdiag);
+        int cx=_xsize[_depth-1];
+        int cy=_ysize[_depth-1];
+        int cz=_zsize[_depth-1];
+        int ix=(int)(s.x()*cx);
+        int iy=(int)(s.y()*cy);
+        int iz=(int)(s.z()*cz);
+        if(ix>=cx)
+          ix--;
+        if(iy>=cy)
+          iy--;
+        if(iz>=cz)
+          iz--;
+        if(ix<0)
+          ix++;
+        if(iy<0)
+          iy++;
+        if(iz<0)
+          iz++;
          
          
-         double next_x, next_y, next_z;
-         double dtdx, dtdy, dtdz;
+        double next_x, next_y, next_z;
+        double dtdx, dtdy, dtdz;
          
-         double icx=_ixsize[_depth-1];
-         double x=_bounds.getMin().x()+_hierdiag.x()*double(ix+ddx)*icx;
-         double xinv_dir=1./dir.x();
-         next_x=Abs((x-orig.x())*xinv_dir); //take Abs so we don't get -inf
-         dtdx=dix_dx*_hierdiag.x()*icx*xinv_dir; //this is +inf when dir.x 
== 0
+        double icx=_ixsize[_depth-1];
+        double x=_bounds.getMin().x()+_hierdiag.x()*double(ix+ddx)*icx;
+        double xinv_dir=1./dir.x();
+        next_x=Abs((x-orig.x())*xinv_dir); //take Abs so we don't get -inf
+        dtdx=dix_dx*_hierdiag.x()*icx*xinv_dir; //this is +inf when dir.x == 0
          
-         double icy=_iysize[_depth-1];
-         double y=_bounds.getMin().y()+_hierdiag.y()*double(iy+ddy)*icy;
-         double yinv_dir=1./dir.y();
-         next_y=Abs((y-orig.y())*yinv_dir);
-         dtdy=diy_dy*_hierdiag.y()*icy*yinv_dir;
+        double icy=_iysize[_depth-1];
+        double y=_bounds.getMin().y()+_hierdiag.y()*double(iy+ddy)*icy;
+        double yinv_dir=1./dir.y();
+        next_y=Abs((y-orig.y())*yinv_dir);
+        dtdy=diy_dy*_hierdiag.y()*icy*yinv_dir;
          
-         double icz=_izsize[_depth-1];
-         double z=_bounds.getMin().z()+_hierdiag.z()*double(iz+ddz)*icz;
-         double zinv_dir=1./dir.z();
-         next_z=Abs((z-orig.z())*zinv_dir);
-         dtdz=diz_dz*_hierdiag.z()*icz*zinv_dir;
+        double icz=_izsize[_depth-1];
+        double z=_bounds.getMin().z()+_hierdiag.z()*double(iz+ddz)*icz;
+        double zinv_dir=1./dir.z();
+        next_z=Abs((z-orig.z())*zinv_dir);
+        dtdz=diz_dz*_hierdiag.z()*icz*zinv_dir;
          
-         Vector cellsize(cx,cy,cz);
-         // cellcorner and celldir can be used to get the location in terms
-         // of the metacell in index space.
-         //
-         // For example if you wanted to get the location at time t (world
-         // space units) in terms of indexspace you would do the following
-         // computation:
-         //
-         // Vector pos = cellcorner + celldir * t + Vector(startx, starty, 
startz);
-         //
-         // If you wanted to get how far you are inside a given cell you
-         // could use the following code:
-         //
-         // Vector weights = cellcorner + celldir * t - Vector(ix, iy, iz);
-         Vector cellcorner((orig-_bounds.getMin())*_ihierdiag*cellsize);
-         Vector celldir(dir*_ihierdiag*cellsize);
+        Vector cellsize(cx,cy,cz);
+        // cellcorner and celldir can be used to get the location in terms
+        // of the metacell in index space.
+        //
+        // For example if you wanted to get the location at time t (world
+        // space units) in terms of indexspace you would do the following
+        // computation:
+        //
+        // Vector pos = cellcorner + celldir * t + Vector(startx, starty, 
startz);
+        //
+        // If you wanted to get how far you are inside a given cell you
+        // could use the following code:
+        //
+        // Vector weights = cellcorner + celldir * t - Vector(ix, iy, iz);
+        Vector cellcorner((orig-_bounds.getMin())*_ihierdiag*cellsize);
+        Vector celldir(dir*_ihierdiag*cellsize);
          
-         HVIsectContext isctx;
-         isctx.total = totals[rayIndex];
-         isctx.alpha = alphas[rayIndex];
-         isctx.dix_dx = dix_dx;
-         isctx.diy_dy = diy_dy;
-         isctx.diz_dz = diz_dz;
-         isctx.transfunct.course_hash = _colorMap->course_hash;
-         isctx.t_inc = t_inc;
-         isctx.t_min = t_min;
-         isctx.t_max = t_max;
-         isctx.t_inc_inv = 1/isctx.t_inc;
-         isctx.ray = ray;
+        HVIsectContext isctx;
+        isctx.total = totals[rayIndex];
+        isctx.alpha = alphas[rayIndex];
+        isctx.dix_dx = dix_dx;
+        isctx.diy_dy = diy_dy;
+        isctx.diz_dz = diz_dz;
+        isctx.transfunct.course_hash = _colorMap->course_hash;
+        isctx.t_inc = t_inc;
+        isctx.t_min = t_min;
+        isctx.t_max = t_max;
+        isctx.t_inc_inv = 1/isctx.t_inc;
+        isctx.ray = ray;
          
-         isect(_depth-1, t_min, dtdx, dtdy, dtdz, next_x, next_y, next_z,
-               ix, iy, iz, 0, 0, 0,
-               cellcorner, celldir,
-               isctx);
+        isect(_depth-1, t_min, dtdx, dtdy, dtdz, next_x, next_y, next_z,
+              ix, iy, iz, 0, 0, 0,
+              cellcorner, celldir,
+              isctx);
          
-         alphas[rayIndex] = isctx.alpha;
-         totals[rayIndex] = isctx.total;
+        alphas[rayIndex] = isctx.alpha;
+        totals[rayIndex] = isctx.total;
       }
       const bool depth = (rays.getDepth() < 
context.scene->getRenderParameters().maxDepth);
       int start = -1;
       for(int i = rays.begin(); i < rays.end(); i++) {
-         if (alphas[i] < RAY_TERMINATION) {
-            if (start < 0)
-               start = i;
+        if (alphas[i] < RAY_TERMINATION) {
+          if (start < 0)
+            start = i;
            
-            const Ray ray = rays.getRay(i);
-            if (lRays1.getHitMaterial(i) == this) //did we hit the outside 
of the volume?
-               lRays1.setRay(i, ray.origin() + ray.direction()*tMaxs[i],
-                             ray.direction());
-            else if (tMaxs[i] == -1) //we weren't supposed to be in the 
volume
-               lRays1.setRay(i, ray.origin()+ray.direction()*(tMins[i]),
-                             ray.direction());
-            else //we hit something else inside the volume
+          const Ray ray = rays.getRay(i);
+          if (lRays1.getHitMaterial(i) == this) //did we hit the outside of 
the volume?
+            lRays1.setRay(i, ray.origin() + ray.direction()*tMaxs[i],
+                          ray.direction());
+          else if (tMaxs[i] == -1) //we weren't supposed to be in the volume
+            lRays1.setRay(i, ray.origin()+ray.direction()*(tMins[i]),
+                          ray.direction());
+          else //we hit something else inside the volume
                //Let's take an epsilon step back so we can hit this when we 
trace a ray.
-               lRays1.setRay(i, 
ray.origin()+ray.direction()*(tMaxs[i]-T_EPSILON*2),
-                             ray.direction());
-         }
-         else {
-            //we don't want to trace the terminated ray.
-            if (start >= 0) {
-               //let's trace these rays
-               lRays1.resize(start, i);
-               context.sample_generator->setupChildPacket(context, rays, 
lRays1);
-               //context.renderer->traceRays(context, lRays1);
-               for(int k = start; k < i; k++) {
-                  Color bgColor(RGB(0,0,0));
-                  if (depth)
-                     bgColor = lRays1.getColor(k);
-                  totals[k] += bgColor*(1.-alphas[k]);
-                  rays.setColor(k, totals[k]);
-               }
-               start = -1;
+            lRays1.setRay(i, 
ray.origin()+ray.direction()*(tMaxs[i]-T_EPSILON*2),
+                          ray.direction());
+        }
+        else {
+          //we don't want to trace the terminated ray.
+          if (start >= 0) {
+            //let's trace these rays
+            lRays1.resize(start, i);
+            context.sample_generator->setupChildPacket(context, rays, 
lRays1);
+            //context.renderer->traceRays(context, lRays1);
+            for(int k = start; k < i; k++) {
+              Color bgColor(RGB(0,0,0));
+              if (depth)
+                bgColor = lRays1.getColor(k);
+              totals[k] += bgColor*(1.-alphas[k]);
+              rays.setColor(k, totals[k]);
             }
-            rays.setColor(i, totals[i]);
-         }
+            start = -1;
+          }
+          rays.setColor(i, totals[i]);
+        }
       }
       if (start >= 0) {
-         //let's trace just these active rays
+        //let's trace just these active rays
         //         lRays1.resize(start, rays.end());
          
-         context.sample_generator->setupChildPacket(context, rays, lRays1);
-         context.renderer->traceRays(context, lRays1);
-         for(int i = start; i < rays.end(); i++) {
-            Color bgColor(RGB(0,0,0));
-            if (depth)
-               bgColor = lRays1.getColor(i);
-            totals[i] += bgColor*(1.-alphas[i]);
-            rays.setColor(i, totals[i]);
-         }
+        context.sample_generator->setupChildPacket(context, rays, lRays1);
+        context.renderer->traceRays(context, lRays1);
+        for(int i = start; i < rays.end(); i++) {
+          Color bgColor(RGB(0,0,0));
+          if (depth)
+            bgColor = lRays1.getColor(i);
+          totals[i] += bgColor*(1.-alphas[i]);
+          rays.setColor(i, totals[i]);
+        }
       }
-   }
+    }
    
-   template<class T>
-   void Volume<T>::computeHistogram(int numBuckets, int* histValues)
-   {
+  template<class T>
+    void Volume<T>::computeHistogram(int numBuckets, int* histValues)
+    {
       float dataMin = _dataMin;
       float dataMax = _dataMax;
       int nx = _data->getNx()-1;
@@ -1110,45 +1111,45 @@
       int nz = _data->getNz()-1;
       float scale = (numBuckets-1)/(dataMax-dataMin);
       for(int i =0; i<numBuckets;i++)
-         histValues[i] = 0;
+        histValues[i] = 0;
       for(int ix=0;ix<nx;ix++){
-         for(int iy=0;iy<ny;iy++){
-            for(int iz=0;iz<nz;iz++){
-               float p000=(*_data)(ix,iy,iz);
-               float p001=(*_data)(ix,iy,iz+1);
-               float p010=(*_data)(ix,iy+1,iz);
-               float p011=(*_data)(ix,iy+1,iz+1);
-               float p100=(*_data)(ix+1,iy,iz);
-               float p101=(*_data)(ix+1,iy,iz+1);
-               float p110=(*_data)(ix+1,iy+1,iz);
-               float p111=(*_data)(ix+1,iy+1,iz+1);
-               float min=std::min(std::min(std::min(p000, p001), 
std::min(p010, p011)), std::min(std::min(p100, p101), std::min(p110, p111)));
-               float max=std::max(std::max(std::max(p000, p001), 
std::max(p010, p011)), std::max(std::max(p100, p101), std::max(p110, p111)));
-               int nmin=(int)((min-dataMin)*scale);
-               int nmax=(int)((max-dataMin)*scale+.999999);
-               if(nmax>=numBuckets)
-                  nmax=numBuckets-1;
-               if(nmin<0)
-                  nmin=0;
-               for(int i=nmin;i<nmax;i++){
-                  histValues[i]++;
-               }
+        for(int iy=0;iy<ny;iy++){
+          for(int iz=0;iz<nz;iz++){
+            float p000=(*_data)(ix,iy,iz);
+            float p001=(*_data)(ix,iy,iz+1);
+            float p010=(*_data)(ix,iy+1,iz);
+            float p011=(*_data)(ix,iy+1,iz+1);
+            float p100=(*_data)(ix+1,iy,iz);
+            float p101=(*_data)(ix+1,iy,iz+1);
+            float p110=(*_data)(ix+1,iy+1,iz);
+            float p111=(*_data)(ix+1,iy+1,iz+1);
+            float min=std::min(std::min(std::min(p000, p001), std::min(p010, 
p011)), std::min(std::min(p100, p101), std::min(p110, p111)));
+            float max=std::max(std::max(std::max(p000, p001), std::max(p010, 
p011)), std::max(std::max(p100, p101), std::max(p110, p111)));
+            int nmin=(int)((min-dataMin)*scale);
+            int nmax=(int)((max-dataMin)*scale+.999999);
+            if(nmax>=numBuckets)
+              nmax=numBuckets-1;
+            if(nmin<0)
+              nmin=0;
+            for(int i=nmin;i<nmax;i++){
+              histValues[i]++;
             }
-         }
+          }
+        }
       }
-   }
+    }
    
-   template<class T>
-   void Volume<T>::attenuateShadows(const RenderContext& context, RayPacket& 
shadowRays) const
-   {
+  template<class T>
+    void Volume<T>::attenuateShadows(const RenderContext& context, 
RayPacket& shadowRays) const
+    {
       
-   }
+    }
    
-   template<class T>
-   float Volume<T>::getValue(int x, int y, int z)
-   {
+  template<class T>
+    float Volume<T>::getValue(int x, int y, int z)
+    {
       return _data(x, y, z);
-   }
+    }
 }//namespace manta
 
 #endif

Modified: trunk/scenes/csafe/python/Configuration.py
==============================================================================
--- trunk/scenes/csafe/python/Configuration.py  (original)
+++ trunk/scenes/csafe/python/Configuration.py  Wed Dec 17 08:46:51 2008
@@ -62,6 +62,8 @@
     f.write( '\n' )
 
     f.write('[Scene Properties]\n')
+    f.write(str(scene.forceDataMin+'\n'))
+    f.write(str(scene.forceDataMax+'\n'))
     f.write(str(scene.duration)+'\n')
     f.write(str(scene.ridx)+'\n')
     f.write(str(scene.radius)+'\n')
@@ -105,6 +107,8 @@
 
     ###read in new values
     lines = f.readlines()
+    currentHistogramIndex = 0
+    currentParticleHistogramIndex = 0
     for i in range(len(lines)):
         ##### Transfer Function####
         if lines[i].find("[Transfer Function]") != -1:
@@ -223,6 +227,12 @@
 
         ##### Scene Properties ####
         elif lines[i].find("[Scene Properties]") != -1:
+            i+=1
+            scene.forceDataMin = float(lines[i].strip())
+            i+=1
+            scene.forceDataMax = float(lines[i].strip())
+            if (scene.forceDataMin != scene.forceDataMax):
+                scene.test.setVolColorMinMax(scene.forceDataMin, 
scene.forceDataMax)
             i+=1
             scene.duration = float(lines[i].strip())
             scene.test.setDuration(scene.duration)

Modified: trunk/scenes/csafe/python/Histogram.py
==============================================================================
--- trunk/scenes/csafe/python/Histogram.py      (original)
+++ trunk/scenes/csafe/python/Histogram.py      Wed Dec 17 08:46:51 2008
@@ -34,6 +34,7 @@
         self.paddingH = 15.0
         wx.Panel.__init__(self, parent, -1, (0, 0) , (width+self.paddingW, 
height+self.paddingH) )
         
+        self.parent = parent
         self.dragging = False
         self.selecting = False
         self.draggingLeft = False
@@ -68,7 +69,6 @@
         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
@@ -215,7 +215,12 @@
         self.numBuckets = nbuckets
         self.width = widthn
         self.height = heightn
-        
+
+    def SetHistoWidth(self, width):
+        print "setting size to: " + str(width)
+        self.width = width
+        self.SetSize( (width + self.paddingW, self.height+self.paddingH))
+        self.Update()
         
     #update dMin/Max, cropMin/Max based on zoomDMin/Max    
     def UpdateDMinMax(self):
@@ -233,6 +238,9 @@
         self.cropDMin = self.cropMin*dWidth + self.dMin # cropped data min
         self.cropDMax = self.cropMax*dWidth + self.dMin # cropped data max
         
+        if (self.parent.group == 1):
+            self.scene.test.setVolClipMinMax(self.dMin, self.dMax, 
self.cropDMin, self.cropDMax)
+        
     def UpdateCropToD(self):
         dWidth = self.dMax - self.dMin
         if (dWidth == 0):
@@ -243,13 +251,13 @@
         
         
     def Update(self):
-
+        print "updating"
         self.lines = []
         width = self.width
         height = self.height
-        
+        print "0.1"
         self.UpdateDMinMax()
-        
+        print "1"
         data = self.data
         
         numBuckets = self.numBuckets
@@ -301,6 +309,7 @@
 
         colorWidth = float(self.colorDMax - self.colorDMin)
         croppedHeightValues = int(width)*[0]
+        print "colors"
         for i in range(0,int(width)):
             # frequency = len( [x for x in data if (x >= start and x <= 
end)] )
             start2 = int(start)
@@ -333,6 +342,7 @@
                 color = self.transferF.GetColor(colorPos)
                 self.lines.append( (color, ( blx + i, bly, blx + i, (bly - 
barHeightNorm*height) ) ) )
         self.Refresh()
+        print "done updating"
        
     def OnPaint(self, evt=None):
         pdc = wx.PaintDC(self)
@@ -449,6 +459,8 @@
         
         self.CreateElements()
         self.SetBackgroundColour(scene.bgColor)
+        #self.Bind(wx.EVT_SIZE, self.OnResize)
+
 
 #    def __init__(self, parent, dataMin, dataMax, width, height, transferF, 
transferFPanel, scene, varIndex, title = "No Name"):
 #        wx.Panel.__init__(self, parent, -1, (0, 0) , (width, height) )
@@ -472,6 +484,23 @@
 #        self.CreateElements()
 #        self.SetBackgroundColour(self.scene.bgColor)
 
+    def SetHistoWidth(self, width):
+        None
+       # self.width = width
+       # self.histogram.SetHistoWidth(width-50)
+       # self.panel.SetSize( (width, 40.0) )
+       # self.SetSize( (width, 40.0) )
+        #self.gbs.AddSpace( (100, 0),1, wx.EXPAND )
+        #self.gbs.Layout()
+        #self.gbs.Fit(self.histogram)
+        #self.gbs.SetSize( (width, 40) )
+        #self.LayoutElements()
+
+    #def OnResize(self, evt):
+       # size = evt.GetSize()
+       # self.SetSize( (size[0], self.height) )
+        
+
     def SetTransferF(self, transferF):
         if (transferF != self.transferF):
             self.transferF = transferF
@@ -510,12 +539,13 @@
         self.box1 = box1 = wx.StaticBoxSizer( box1_title, wx.VERTICAL )
         # grid1 = wx.FlexGridSizer( 2, 2, 0, 0 )
         gbs = wx.GridBagSizer(1,3)
+        #gbs = wx.BoxSizer(wx.HORIZONTAL)
         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, 1, wx.EXPAND|wx.ALIGN_LEFT, 10)
         gbs.Add(self.histogram,(0, 0), (2, 2) )
         if self.scene.histogramBMPLoaded == False:
                 self.scene.bmpVis = 
wx.Bitmap(opj(path+'images/eye.png.8x8'), wx.BITMAP_TYPE_PNG)
@@ -560,10 +590,73 @@
         # 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)
+        vs2.Add( visibilityB, 0, wx.ALIGN_CENTRE|wx.ALL, 0, 10)
         space = (0,0)
         vs2.AddSpacer(space)
-        vs2.Add( colorB, wx.ALIGN_CENTRE|wx.ALL, 0, 10)
+        vs2.Add( colorB, 0, wx.ALIGN_CENTRE|wx.ALL, 0, 10)
+        vs2.AddSpacer(space)
+        vs2.Add( self.rulerB, 0)
+        vs2.AddSpacer(space)
+        vs3 = wx.BoxSizer(wx.VERTICAL)
+        vs3.Add( self.zoomInB, 0)
+        vs3.AddSpacer(space)
+        vs3.Add( self.zoomOutB , 0)
+        vs2.Layout()
+        vs3.Layout()
+        
+        vsH = wx.BoxSizer(wx.HORIZONTAL)
+        vsH.Add(vs2, 0, wx.ALIGN_CENTER,0)
+        vsH.Add(vs3, 0, wx.ALIGN_CENTER,0)  
+        # vs3.Layout()
+        gbs.Add(vsH, (0, 2), (2, 1))
+        #gbs.Add(vsH, 1, wx.ALIGN_RIGHT, 10)
+        # gbs.Add(vs3, (0, 3), (2, 1))
+        
+        
+        gbs.Layout()
+        
+        box1.Add( gbs, 0, wx.ALIGN_CENTRE, 0 )
+        self.box1 = box1
+        vs.Add( box1, 0, wx.ALIGN_CENTRE, 0 )
+        # vs.Add(grid1, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
+        self.SetSizer( vs )
+        vs.Fit( self )
+        gbs.Fit(self.histogram)
+        self.vs = vs
+        self.visible = True
+        self.gbs = gbs
+        self.vsH = vsH
+        self.vs2 = vs2
+        self.vs3 = vs3
+   #     self.SetAutoLayout(True)
+
+    def LayoutElements(self):
+
+        self.vs = vs = wx.BoxSizer( wx.VERTICAL )
+        box1_title = wx.StaticBox( self, -1, self.title + " (" + str( 
self.varIndex ) + ")" )
+
+        box1_title.SetForegroundColour( wx.WHITE ) # Make label readable!
+        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) )
+
+        
+        
+        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( self.visibilityB, wx.ALIGN_CENTRE|wx.ALL, 0, 10)
+        space = (0,0)
+        vs2.AddSpacer(space)
+        vs2.Add( self.colorB, wx.ALIGN_CENTRE|wx.ALL, 0, 10)
         vs2.AddSpacer(space)
         vs2.Add( self.rulerB)
         vs2.AddSpacer(space)
@@ -573,7 +666,7 @@
         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)  
@@ -590,7 +683,13 @@
         # vs.Add(grid1, 0, wx.ALIGN_CENTRE|wx.ALL, 5 )
         self.SetSizer( vs )
         vs.Fit( self )
+        self.vs = vs
         self.visible = True
+        self.gbs = gbs
+        self.vsH = vsH
+        self.vs2 = vs2
+        self.vs3 = vs3
+        self.SetAutoLayout(True)
     
     def OnClickMeasurements(self, evt):
         global measurementsWindow
@@ -604,7 +703,7 @@
         measurementsWindow.Raise()
 
     def SendValues(self, zoomMin, zoomMax, cropMin, cropMax, colorMin, 
colorMax):  # sent from MeasurementsFrame
-        # print "values arrived"
+        print "min, max: " + str(cropMin) + " " + str(cropMax)
         self.histogram.zooms.append( (self.histogram.zoomDMin, 
self.histogram.zoomDMax))
         self.histogram.zoomDMin = zoomMin
         self.histogram.zoomDMax = zoomMax
@@ -634,6 +733,7 @@
                 
self.scene.test.setSphereColorMinMax(self.histogram.varIndex, colorMin, 
colorMax)
         else:
                 self.scene.test.setVolColorMinMax(colorMin, colorMax)
+                self.scene.test.setVolClipMinMax(self.histogram.dMin, 
self.histogram.dMax, cropMin, cropMax)
         
     def OnClickZoomIn(self, evt):
         self.histogram.ZoomIn()
@@ -736,10 +836,10 @@
         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))
-        if (group == 0): # Particles
-            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))
+     #   if (group == 0): # Particles
+        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))
@@ -749,10 +849,10 @@
         gbs.Add(self.zoomText, (1,0))
         gbs.Add(self.zoomMinTcl, (1,1))
         gbs.Add(self.zoomMaxTcl, (1,2))
-        if (group == 0):
-            gbs.Add(self.cropText, (2,0))
-            gbs.Add(self.cropMinTcl, (2,1))
-            gbs.Add(self.cropMaxTcl, (2,2))
+#        if (group == 0):
+        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))
@@ -785,9 +885,8 @@
         zoomMax = self.zoomMaxTcl.GetValue()
         cropMin = 0
         cropMax = 0
-        if self.group == 0:
-                cropMin = self.cropMinTcl.GetValue()
-                cropMax = self.cropMaxTcl.GetValue()
+        cropMin = self.cropMinTcl.GetValue()
+        cropMax = self.cropMaxTcl.GetValue()
         colorMin = self.colorMinTcl.GetValue()
         colorMax = self.colorMaxTcl.GetValue()
         #print "zomMin: " + str(zoomMin)

Modified: trunk/scenes/csafe/python/SceneInfo.py
==============================================================================
--- trunk/scenes/csafe/python/SceneInfo.py      (original)
+++ trunk/scenes/csafe/python/SceneInfo.py      Wed Dec 17 08:46:51 2008
@@ -37,4 +37,7 @@
                self.histogramBuckets = 300
                self.volumeMinBound = [-0.001, -0.101, -0.001]
                self.volumeMaxBound = [0.101, 0.201, 0.101]
+                self.forceDataMin = float(0) #manually set volume data range
+                self.forceDataMax = float(0)
+                self.stepSize = float(0.0125)
 

Modified: trunk/scenes/csafe/python/SceneMenus.py
==============================================================================
--- trunk/scenes/csafe/python/SceneMenus.py     (original)
+++ trunk/scenes/csafe/python/SceneMenus.py     Wed Dec 17 08:46:51 2008
@@ -41,7 +41,6 @@
        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)
@@ -509,8 +508,23 @@
        hSizer8.Add(wx.StaticText(panel, -1, "Number of Rays: "),0,wx.ALL,3)
        hSizer8.Add(self.aoNumTcl,0,wx.ALL,3)
        aoCtrlSizer.Add(hSizer8,0,wx.ALL|wx.ALIGN_CENTER,5)
-       
        sizer.Add(aoCtrlSizer,0,wx.ALL|wx.ALIGN_CENTER, 5)
+
+       
+
+       hSizer9 = wx.BoxSizer(wx.HORIZONTAL)
+       self.volMinTcl = 
wx.TextCtrl(panel,-1,str(scene.forceDataMin),size=(125,-1))
+       self.volMaxTcl = 
wx.TextCtrl(panel,-1,str(scene.forceDataMax),size=(125,-1))
+       hSizer9.Add(wx.StaticText(panel, -1, "Force Volume Min/Max: 
"),0,wx.ALL,3)
+       hSizer9.Add(self.volMinTcl,0,wx.ALL,3)
+       hSizer9.Add(self.volMaxTcl)
+       sizer.Add(hSizer9,0,wx.ALL|wx.ALIGN_CENTER, 5)
+
+       hSizer11 = wx.BoxSizer(wx.HORIZONTAL)
+       self.stepSizeTcl = 
wx.TextCtrl(panel,-1,str(scene.stepSize),size=(125,-1))
+       hSizer11.Add(wx.StaticText(panel, -1, "Step Size: "),0,wx.ALL,3)
+       hSizer11.Add(self.stepSizeTcl,0,wx.ALL,3)
+       sizer.Add(hSizer11,0,wx.ALL|wx.ALIGN_CENTER, 5)
         
 
        self.okButton = wx.Button(panel, wx.ID_OK)
@@ -581,6 +595,12 @@
        self.scene.aoCutoff = float(self.aoCutoffTcl.GetValue())
        self.scene.aoNum = int(float(self.aoNumTcl.GetValue()))
        self.scene.test.setAOVars(self.scene.aoCutoff, self.scene.aoNum)
+        self.scene.forceDataMin = float(self.volMinTcl.GetValue())
+        self.scene.forceDataMax = float(self.volMaxTcl.GetValue())
+        self.scene.stepSize = float(self.stepSizeTcl.GetValue())
+        self.scene.test.setStepSize(float(self.scene.stepSize))
+        if (self.scene.forceDataMin != self.scene.forceDataMax):
+          self.scene.test.setVolColorMinMax(float(self.scene.forceDataMin), 
float(self.scene.forceDataMax))
        print "ridx set to: " + str(self.scene.ridx)
 
     def OnClickOK(self, evt):

Modified: trunk/scenes/csafe/python/csafe_demo.cfg
==============================================================================
--- trunk/scenes/csafe/python/csafe_demo.cfg    (original)
+++ trunk/scenes/csafe/python/csafe_demo.cfg    Wed Dec 17 08:46:51 2008
@@ -270,6 +270,8 @@
 
 
 [Scene Properties]
+300.0
+2100.0
 10.0
 6
 0.001

Modified: trunk/scenes/csafe/python/csafe_scene.py
==============================================================================
--- trunk/scenes/csafe/python/csafe_scene.py    (original)
+++ trunk/scenes/csafe/python/csafe_scene.py    Wed Dec 17 08:46:51 2008
@@ -143,6 +143,7 @@
         self.Bind(wx.EVT_MENU, self.ToggleTooltips,      id=207)
         self.Bind(wx.EVT_MENU, self.ShowHelp,            id=ZOOM_HELP_ID)
         self.Bind(wx.EVT_MENU, self.ShowHelp,            id=COLORMAP_HELP_ID)
+        self.Bind(wx.EVT_SIZE, self.OnResize)
 
         self.SetBackgroundColour(self.scene.bgColor)
 
@@ -321,7 +322,6 @@
         for  i in range(0, len(self.scene.nrrdFiles)):
             self.test.addSphereNrrd(self.scene.nrrdFiles[i])
         #self.test.loadSphereNrrds()
-        #self.test.setVolColorMinMax(300, 1800)
         self.test.reloadData()
 
         #self.test.loadVolNrrds()
@@ -373,7 +373,7 @@
                                                                  
t.colors[i][2], t.colors[i][3])), t.colors[i][4])))
         if (cmap != None):
             cmap.SetColors(slices)
-        self.volCMap.scaleAlphas(0.00125)
+        self.volCMap.scaleAlphas(float(self.scene.stepSize))
         self.scene.test.updateSphereCMap()
 
     def OnClick(self, evt):
@@ -568,11 +568,21 @@
         self.scene.cidx = 4
         self.volCMap.scaleAlphas(0.00125)
 
+    def OnResize(self, evt):
+        try:
+            size = evt.GetSize()
+            self.panel.SetSize(size)
+            for i in range(len(self.histoGroups)):
+                self.histoGroups[i].SetHistoWidth(size[0]-50)
+        except:
+            None
+
     def LayoutWindow(self):
+        size = self.GetSize()
         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_TOP|wx.ALIGN_CENTER, 
5)
+            hvs.Add(self.histoGroups[i], 0,wx.ALIGN_TOP|wx.ALIGN_CENTER, 5)
         hvs.Add(self.tPanel, 0, wx.ALIGN_TOP,5 )
         vs.Add(hvs,0,wx.ALIGN_TOP|wx.ALIGN_CENTER,5)
 

Modified: trunk/scenes/csafe/src/CDGridSpheres.cc
==============================================================================
--- trunk/scenes/csafe/src/CDGridSpheres.cc     (original)
+++ trunk/scenes/csafe/src/CDGridSpheres.cc     Wed Dec 17 08:46:51 2008
@@ -32,108 +32,108 @@
 CDGridSpheres** CDGridSpheres::__grids = new CDGridSpheres*[256];
 
 CDGridSpheres::CDGridSpheres(float* spheres, int nspheres, int nvars, int 
ncells,
-                                    int depth, Real radius, int ridx, 
RGBAColorMap* cmap,
-                                    int cidx, int xindex_) :
-barrier("CDGRidSpheres barrier"), mutex("CDGridSpheres mutex"), 
spheres(spheres), nspheres(nspheres), nvars(nvars),
-radius(radius), ridx(ridx), ncells(ncells), depth(depth),
-cmap(cmap), cidx(cidx), _useAmbientOcclusion(false), xindex(xindex_)
+                             int depth, Real radius, int ridx, RGBAColorMap* 
cmap,
+                             int cidx, int xindex_) :
+  barrier("CDGRidSpheres barrier"), mutex("CDGridSpheres mutex"), 
spheres(spheres), nspheres(nspheres), nvars(nvars),
+  radius(radius), ridx(ridx), ncells(ncells), depth(depth),
+  cmap(cmap), cidx(cidx), _useAmbientOcclusion(false), xindex(xindex_)
 {
   __grids[__numGrids] = this;
   __numGrids++;
   _matl = new Phong(this, this, 10, NULL);
-        cerr<<"Initializing GridSpheres\n";
+  cerr<<"Initializing GridSpheres\n";
 
-        if (radius <= 0) {
-                if (ridx < 0)
-                {
-                        cerr<<"Resetting default radius to 1\n";
-                        radius=1;
-                }
-        }
+  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];
-        }
+  // 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]);
-                }
+  // 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];
-        }
+    data += nvars;
+  }
+  for(int j = 0; j<nvars;j++)
+    {
+      cmin[j] = min[j];
+      cmax[j] = max[j];
+    }
 
-        counts=0;
-        cells=0;
+  counts=0;
+  cells=0;
 
 #ifdef USE_FUNCTION_POINER
-        intersectSphere=0;
+  intersectSphere=0;
 #endif
 }
 
 CDGridSpheres::~CDGridSpheres()
 {
-        delete [] min;
-        delete [] max;
-        delete [] cmin;
-        delete [] cmax;
-        delete [] clipMins;
-        delete [] clipMaxs;
+  delete [] min;
+  delete [] max;
+  delete [] cmin;
+  delete [] cmax;
+  delete [] clipMins;
+  delete [] clipMaxs;
 
-        if (counts)
-                delete[] counts;
+  if (counts)
+    delete[] counts;
 
-        if (cells)
-                delete[] cells;
+  if (cells)
+    delete[] cells;
 
-        if (macrocells)
-                delete [] macrocells;
+  if (macrocells)
+    delete [] macrocells;
 }
 
 void CDGridSpheres::preprocess(const PreprocessContext& context)
 {
   //  context.manta_interface->registerParallelPreRenderCallback(
-        computeBounds(context, bounds);
+  computeBounds(context, bounds);
 
   _matl->preprocess(context);
-        // Preprocess material
-        LitMaterial::preprocess(context);
+  // Preprocess material
+  LitMaterial::preprocess(context);
 
         
-        _ao = new AmbientOcclusion(Color(RGB(1,1,1)), 0.01f, 10);
-        _ao->preprocess(context);
-          
context.manta_interface->addOneShotCallback(MantaInterface::Relative, 0, 
-                Callback::create(this, &CDGridSpheres::update));
-          for (int i = 0; i < __numGrids;i++)
-            __processedGrids[i] = false;
-        }
+  _ao = new AmbientOcclusion(Color(RGB(1,1,1)), 0.01f, 10);
+  _ao->preprocess(context);
+  context.manta_interface->addOneShotCallback(MantaInterface::Relative, 0, 
+                                              Callback::create(this, 
&CDGridSpheres::update));
+  for (int i = 0; i < __numGrids;i++)
+    __processedGrids[i] = false;
+}
 
 
 void CDGridSpheres::updateStatic(int proc, int numProcs)
@@ -156,472 +156,446 @@
   }
 }
 
-        void CDGridSpheres::update(int proc, int numProcs)
-        {
-          //int proc, numProcs;
-          proc = 0; numProcs = 1;
-          //barrier.wait(numProcs);
-  //mutex.lock();
-  // cout << "update numProcs, proc: " << numProcs 
-  //       << " " << proc << endl;
- //mutex.unlock();
-
-          //  cout << "numProcs: " <<         numProcs << endl;
-          //  cout << "context proc: " <<         proc << endl;
-        int procRange = totalcells/numProcs;
-        int procStart = proc*procRange;
-        int procEnd = procStart+procRange;
-        float max_radius;
-        WallClockTimer timer;
-        int* map;
-        size_t totalsize;
-        Real stime;
-        //    if (proc == 0){
-
-
-        // Build grid
-        cerr<<"Building GridSpheres xindex: " << xindex << "\n";
-
-        timer.start();
-
-        cerr<<"  min:  ("<<min[xindex]<<", "<<min[xindex+1]<<", 
"<<min[xindex+2]<<")\n";
-        cerr<<"  max:  ("<<max[xindex]<<", "<<max[xindex+1]<<", 
"<<max[xindex+2]<<")\n";
-
-        // Determine the maximum 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;
-
-        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
-        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);
-                        }
-                }
-        }
+void CDGridSpheres::update(int proc, int numProcs)
+{
+  proc = 0; numProcs = 1;
+
+  int procRange = totalcells/numProcs;
+  int procStart = proc*procRange;
+  int procEnd = procStart+procRange;
+  float max_radius;
+  WallClockTimer timer;
+  int* map;
+  size_t totalsize;
+  Real stime;
+
+
+  // Build grid
+  cerr<<"Building GridSpheres xindex: " << xindex << "\n";
+
+  timer.start();
+  stime=timer.time();
+
+  cerr<<"  min:  ("<<min[xindex]<<", "<<min[xindex+1]<<", 
"<<min[xindex+2]<<")\n";
+  cerr<<"  max:  ("<<max[xindex]<<", "<<max[xindex+1]<<", 
"<<max[xindex+2]<<")\n";
+
+  // Determine the maximum 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;
+
+  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
+  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);
+      }
+    }
+  }
 
-      
-        cerr << "1/6:  Generating map took "<<stime<<" seconds\n";
-        stime=timer.time();
-        // } // if proc == 0
-        // barrier.wait(numProcs);
-        // int* countsTemp = new int[2*totalsize];
-        // bzero(countsTemp, 2*totalsize*sizeof(int));
-
-        procRange = nspheres/numProcs;
-        procStart = proc*procRange;
-        procEnd = procStart+procRange;
-        // mutex.lock();
-        //  cout << "proc, procRange, procStart, procEnd: "
-        //    << proc<< " " << procRange << " " << procStart
-        //    << " " << procEnd << endl;
-        //mutex.unlock();
-        // Compute cell counts
-        float* data=spheres + procStart*nvars;
-        int tc2=totalcells*totalcells;
-        for (int i=procStart; i<procEnd; ++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[xindex], data[xindex+1], data[xindex+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++];
-                                        //mutex.lock();
-                                        //   countsTemp[2*aidx + 1]++;
-                                        counts[2*aidx+1]++;
-                                        //mutex.unlock();
-                                }
-                        }
-                }
+  cerr << "1/6:  Generating map took "<<timer.time() - stime<<" seconds\n";
+  stime=timer.time();
 
-                data += nvars;
-        }
-        //        mutex.lock();
-        //        for(int i = 0; i < 2*totalsize; i++)
-        //          counts[i] += countsTemp[i];
-        //        mutex.unlock();
-        //        barrier.wait(numProcs);
-        //         if (proc == 0) {
-        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;
-        }
+  procRange = nspheres/numProcs;
+  procStart = proc*procRange;
+  procEnd = procStart+procRange;
+  // Compute cell counts
+  float* data=spheres + procStart*nvars;
+  int tc2=totalcells*totalcells;
+  for (int i=procStart; i<procEnd; ++i) {
+    Real ctime=timer.time();
+    if (ctime - stime>5.0) {
+      cerr<<i<<"/"<<nspheres<<'\n';
+      stime=ctime;
+    }
 
-        // 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[xindex], data[xindex+1], data[xindex+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;
-                                }
-                        }
-                }
+    // 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);
+    }
 
-                data += nvars;
+    Vector center(data[xindex], data[xindex+1], data[xindex+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++];
+          //mutex.lock();
+          //   countsTemp[2*aidx + 1]++;
+          counts[2*aidx+1]++;
+          //mutex.unlock();
         }
+      }
+    }
 
-        delete [] map;
+    data += nvars;
+  }
+  cerr<<"    2/6:  Counting cells took "<<timer.time()<<" seconds\n";
+  int total=0;
+  for (size_t i=0; i<totalsize; ++i) {
+    int count=counts[2*i + 1];
+    counts[2*i]=total;
+    total += count;
+  }
 
-        cerr<<"    4/6:  Filling grid took "<<timer.time()<<" seconds\n";
+  // 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;
+    }
 
-        // 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);
-                }
-        }
+    // 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);
+    }
 
-        for (int i=0; i<total; ++i) {
-                if (cells[i]==-1) {
-                        cerr<<"Fatal error:  cells["<<i<<"] == -1\n";
-                        exit(1);
-                }
+    Vector center(data[xindex], data[xindex+1], data[xindex+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;
         }
+      }
+    }
 
-        cerr<<"    5/6:  Verifying grid took "<<timer.time()<<" seconds\n";
+    data += nvars;
+  }
 
-        // 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";
-        }
+  delete [] map;
+
+  cerr<<"    4/6:  Filling grid took "<<timer.time()<<" seconds\n";
+
+  // Verify the grid
+  for (size_t 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);
+    }
+  }
 
-        cerr<<"Done building GridSpheres\n";
+  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
+                                  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[xindex], min[xindex+1], min[xindex+2]) - mr,
-                           Vector(max[xindex], max[xindex+1], max[xindex+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);
+  // 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[xindex], min[xindex+1], min[xindex+2]) - mr,
+             Vector(max[xindex], max[xindex+1], max[xindex+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();
+  Vector bmin=bounds.getMin();
+  Vector bmax=bounds.getMax();
 
-        rays.computeInverseDirections();
-        rays.computeSigns();
+  rays.computeInverseDirections();
+  rays.computeSigns();
 
 #ifdef USE_OPTIMIZED_FCNS
-        // Determine appropriate sphere intersection function for this ray 
packet
-        SphereIntersectFcn intersectSphere = 
&CDGridSpheres::intersectSphereDefault;
+  // 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;
-        }
+  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,
+  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);
+             stop_x, stop_y, stop_z, intersectSphere);
 #else
-                stop_x, stop_y, stop_z);
+    stop_x, stop_y, stop_z);
 #endif // USE_OPTIMIZED_FCNS
-        }
+  }
 }
 
 void CDGridSpheres::computeNormal(const RenderContext& context,
@@ -629,534 +603,524 @@
 {
   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[xindex], data[xindex+1], 
data[xindex+2]);
-
-/*if (ridx>0) {
-     if (data[ridx] <= 0.0)
-      n *= inv_radius;
-    else
-      n.normalize();
-  } else {
-    n *= inv_radius;
-    }*/
-n.normalize();
-    rays.setNormal(i, n);
-  }
+  float* data=spheres + rays.scratchpad<int>(i);
+  Vector n=rays.getHitPosition(i) - Vector(data[xindex], data[xindex+1], 
data[xindex+2]);
+  n.normalize();
+  rays.setNormal(i, n);
+}
 
-  rays.setFlag(RayPacket::HaveUnitNormals);
+rays.setFlag(RayPacket::HaveUnitNormals);
 }
 
 void CDGridSpheres::shade(const RenderContext& context, RayPacket& rays) 
const
 {
-        // Compute ambient light
-        //  ColorArray ambient;
-         // activeLights->getAmbientLight()->computeAmbient(context, rays, 
ambient);
+  // 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);
+  // Shade a bunch of rays that have intersected the same particle
+  //             lambertianShade(context, rays, ambient);
   
-    _matl->shade(context, rays);
+  _matl->shade(context, rays);
 }
 
-void CDGridSpheres::lambertianShade(const RenderContext& context, RayPacket& 
rays,
-                                                                        
ColorArray& totalLight) const
+void CDGridSpheres::lambertianShade(const RenderContext& context, RayPacket& 
rays, ColorArray& totalLight) const
 {
-    // Compute normals
-        rays.computeNormals<false>(context);
+  // Compute normals
+  rays.computeNormals<false>(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());*/
+  // 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());*/
   _matl->shade(context, rays);
-        if (_useAmbientOcclusion)
-        {
-                //ambient occlusion
-            _ao->shade(context, rays);
-            // 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+rays.getColor(i));
-            }
-        }
-        else
-        {
-            // 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];*/
+  if (_useAmbientOcclusion)
+    {
+      //ambient occlusion
+      _ao->shade(context, rays);
+      // 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+rays.getColor(i));
+      }
+    }
+  else
+    {
+      // 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, rays.getColor(i)*diffuse.get(i));
-            }
-        }
+        rays.setColor(i, rays.getColor(i)*diffuse.get(i));
+      }
+    }
 }
 
 void CDGridSpheres::computeHistogram(int index, int numBuckets, int* 
histValues)
 {
-        float dataMin = min[index];
-        float dataMax = max[index];
-        float scale = (numBuckets-1)/(dataMax - dataMin);
-        for(int i = 0; i < numBuckets; i++)
-                histValues[i] = 0;
-        for(int i = 0; i < nspheres; i++)
-        {
-                float val = *(spheres + i*nvars + index);
-                int bucket = int((val-dataMin)*scale);
-                histValues[bucket]++;
-        }
+  float dataMin = min[index];
+  float dataMax = max[index];
+  float scale = (numBuckets-1)/(dataMax - dataMin);
+  for(int i = 0; i < numBuckets; i++)
+    histValues[i] = 0;
+  for(int i = 0; i < nspheres; i++)
+    {
+      float val = *(spheres + i*nvars + index);
+      int bucket = int((val-dataMin)*scale);
+      histValues[bucket]++;
+    }
 }
 
 void CDGridSpheres::computeTexCoords2(const RenderContext& context,
-                                                                          
RayPacket& rays) const
+                                      RayPacket& rays) const
 {
-        rays.computeHitPositions();
-        rays.computeNormals<false>(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.computeHitPositions();
+  rays.computeNormals<false>(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);
+  rays.setFlag(RayPacket::HaveTexture2|RayPacket::HaveTexture3);
 }
 
 void CDGridSpheres::computeTexCoords3(const RenderContext& context,
-                                                                          
RayPacket& rays) const
+                                      RayPacket& rays) const
 {
-        rays.computeHitPositions();
-        rays.computeNormals<false>(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.computeHitPositions();
+  rays.computeNormals<false>(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);
+  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,
+                             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
+                             int stop_x, int stop_y, int stop_z,
+                             SphereIntersectFcn intersectSphere) const
 #else
-int stop_x, int stop_y, int stop_z) const
+  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) {
-                                bool skip = false;
-                                // XXX:  Range checking would go here...  
Ignore for now
-                                for(int j = 0; j < nvars; j++)
-                                {
-                                        if (mcell.min[j] > clipMaxs[j])
-                        { skip = true; break; }
-                                        if (mcell.max[j] < clipMins[j])
-                        { skip = true; break; }
-                                }
-                                if (!skip)
-                               {
-
-                                // 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,
+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) {
+bool skip = false;
+// XXX:  Range checking would go here...  Ignore for now
+for(int j = 0; j < nvars; j++)
+{
+  if (mcell.min[j] > clipMaxs[j])
+    { skip = true; break; }
+  if (mcell.max[j] < clipMins[j])
+    { skip = true; break; }
+}
+ if (!skip)
+   {
+
+     // 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);
+              stop_x, stop_y, stop_z, intersectSphere);
 #else
-                                stop_x, stop_y, stop_z);
+     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) {
-                               bool skip = false;
-                                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])
-                                        {
-                                                skip = true;
-                                                break;
-                                        }
-                                        if (data[k] > clipMaxs[k])
-                                        {
-                                                skip = true;
-                                                break;
-                                        }
-                                }
-                                if(!skip)
-                               {
-                                // 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;
-                                }
+// 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) {
+        bool skip = false;
+        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])
+              {
+                skip = true;
+                break;
+              }
+            if (data[k] > clipMaxs[k])
+              {
+                skip = true;
+                break;
+              }
+          }
+        if(!skip)
+          {
+            // 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[xindex], 
data[xindex+1], data[xindex+2]), radius2);
+            // Intersect the sphere using the appropriately optimized 
function
+            (*this.*intersectSphere)(rays, ray_idx, start + j,               
                                                                 
+                                     Vector(data[xindex], data[xindex+1], 
data[xindex+2]), radius2);
 #else
-                                intersectSphereDefault(rays, ray_idx, start 
+ j,
-                                       Vector(data[xindex], data[xindex+1], 
data[xindex+2]), radius2);
+            intersectSphereDefault(rays, ray_idx, start + j,
+                                   Vector(data[xindex], data[xindex+1], 
data[xindex+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;
-                        }
-                }
-        }
+      // 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
+  const Vector& center, float radius2) const
 {
-        //  if (clip(cells[idx]))
-        //      return;
-        // Rays of constant origin and normalized directions
-        Vector O(rays.getOrigin(ray_idx) - 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];
-                }
-        }
+//  if (clip(cells[idx]))
+//      return;
+// Rays of constant origin and normalized directions
+Vector O(rays.getOrigin(ray_idx) - 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
+  const Vector& center, float radius2) const
 {
-        // if (clip(cells[idx]))
-        //      return;
-        // Rays of constant origin for not normalized directions
-        Vector O(rays.getOrigin(ray_idx) - 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];
-                }
-        }
+  // if (clip(cells[idx]))
+  //      return;
+  // Rays of constant origin for not normalized directions
+  Vector O(rays.getOrigin(ray_idx) - 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
+                                      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];
-                }
-        }
+  // 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
+                                           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];
-                }
-        }
+  // 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
+                                       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);
+  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;
+  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;
-        }
+    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;
-        }
+  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];
-                                }
-                        }
-                }
+  // 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);
-        }
+  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);
+  }
 }
 
 void CDGridSpheres::mapValues(Packet<Color>& results, const RenderContext&, 
RayPacket& rays) const {
@@ -1172,12 +1136,12 @@
 
 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;
+  for(int j = 0; j < nvars; j++)
+    {
+      float v = *(spheres + s + j);
+      if (v < clipMins[j] || v > clipMaxs[j])
+        return true;
+    }
+  return false;
 }
 

Modified: trunk/scenes/csafe/src/CDTest.h
==============================================================================
--- trunk/scenes/csafe/src/CDTest.h     (original)
+++ trunk/scenes/csafe/src/CDTest.h     Wed Dec 17 08:46:51 2008
@@ -103,6 +103,7 @@
       _sphereDMaxs = new float[16];
       _minBound = volumeMinBound;
       _maxBound = volumeMaxBound;
+      _stepSize = 0.0125;
     }
 
   ~CDTest()
@@ -355,7 +356,7 @@
          }
           int xindex = 0;
           std::vector<std::pair<string, string> >& keyValuePairs = 
pnrrd->getKeyValuePairs();
-          for(int i =0; i < keyValuePairs.size(); i++) {
+          for(size_t i =0; i < keyValuePairs.size(); i++) {
             if (keyValuePairs[i].first == "p.x (x) index") {
               stringstream stream(keyValuePairs[i].second);
               stream >> xindex;
@@ -477,7 +478,7 @@
                     min[2], max[0], max[1], max[2]); 
             }
           }
-         Volume<float>* mat = new Volume<float>(grid, _volCMap, BBox(min, 
max), 0.0125, 3, NULL, _forceDataMin, _forceDataMax);
+         Volume<float>* mat = new Volume<float>(grid, _volCMap, BBox(min, 
max), _stepSize, 3, NULL, _forceDataMin, _forceDataMax);
          Cube* vol = new Cube(mat, min, max);
           group->add(vol);
           //#  group->add(vol);
@@ -913,6 +914,19 @@
       _forceDataMax = max;
     }
 
+  //! the clipping range of the volume narrows the range of the colormap
+  /*! 
+    \param actual min
+    \param actual max
+    \param altered min
+    \param altered max
+  */
+  void setVolClipMinMax(float globalMin, float globalMax, float min, float 
max)
+    {
+      if (_volCMap)
+       _volCMap->squish(globalMin, globalMax, min, max);
+    }
+
   //! get the min and max data values used for normalizing color values
   /*!
     \param returns min
@@ -944,6 +958,19 @@
        }
     }
 
+  void setStepSize(float t)
+    {
+      _stepSize = t;
+      for(int i =0;i<int(_vols.size());i++)
+       {
+         if (_vols[i] == NULL)
+           continue;
+          _vols[i]->setStepSize(t);
+        }
+      if (_volCMap)
+        _volCMap->scaleAlphas(t);
+    }
+
   //! sets radius index used for spheredata
   /*!
     \param radius index
@@ -1082,6 +1109,7 @@
   UDAReader uda;
   float* _sphereDMins, *_sphereDMaxs;
   Vector _volPosition, _volSize;
+  float _stepSize;
 };
 
 #endif


  • [Manta] r2355 - in trunk: Model/Materials scenes/csafe/python scenes/csafe/src, brownlee, 12/17/2008

Archive powered by MHonArc 2.6.16.

Top of page