Text archives Help
- 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.