diff --git a/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastIndependentComponentMIP.png.md5 b/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastIndependentComponentMIP.png.md5 new file mode 100644 index 00000000000..b58a4e3ac60 --- /dev/null +++ b/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastIndependentComponentMIP.png.md5 @@ -0,0 +1 @@ +c5c09772ee4f6e5e18bdb3d41657cb70 diff --git a/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastIndependentComponentMinIP.png.md5 b/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastIndependentComponentMinIP.png.md5 new file mode 100644 index 00000000000..4d6e7ed94b7 --- /dev/null +++ b/Rendering/Volume/Testing/Data/Baseline/TestGPURayCastIndependentComponentMinIP.png.md5 @@ -0,0 +1 @@ +787ac19c55b11c28cb0249fee76acc8d diff --git a/Rendering/Volume/Testing/Python/CMakeLists.txt b/Rendering/Volume/Testing/Python/CMakeLists.txt index 46425cd7b5d..7df895162f9 100644 --- a/Rendering/Volume/Testing/Python/CMakeLists.txt +++ b/Rendering/Volume/Testing/Python/CMakeLists.txt @@ -12,6 +12,8 @@ set (GenericVolumePythonTests VolumePickerCrop.py VolumePicker.py,NO_RT TestGPURayCastIndependentComponent.py,NO_RT + TestGPURayCastIndependentComponentMIP.py,NO_RT +TestGPURayCastIndependentComponentMinIP.py,NO_RT ) # These tests are only built when the rendering backend is OpenGL diff --git a/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponentMIP.py b/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponentMIP.py new file mode 100755 index 00000000000..fe528a7410e --- /dev/null +++ b/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponentMIP.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +''' +========================================================================= + + Program: Visualization Toolkit + Module: TestGPURayCastIndependentComponentMIP.py + + Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen + All rights reserved. + See Copyright.txt or http://www.kitware.com/Copyright.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notice for more information. + +========================================================================= +''' + +import sys +import vtk +import vtk.test.Testing +from vtk.util.misc import vtkGetDataRoot +VTK_DATA_ROOT = vtkGetDataRoot() + +''' + Prevent .pyc files from being created. + Stops the vtk source being polluted + by .pyc files. +''' +sys.dont_write_bytecode = True + +class TestGPURayCastIndependentComponentMIP(vtk.test.Testing.vtkTest): + + def test(self): + dataRoot = vtkGetDataRoot() + reader = vtk.vtkXMLImageDataReader() + reader.SetFileName("" + str(dataRoot) + "/Data/vase_4comp.vti") + + volume = vtk.vtkVolume() + #mapper = vtk.vtkFixedPointVolumeRayCastMapper() + mapper = vtk.vtkGPUVolumeRayCastMapper() + mapper.SetBlendModeToMaximumIntensity(); + mapper.SetSampleDistance(0.1) + mapper.SetAutoAdjustSampleDistances(0) + ren = vtk.vtkRenderer() + renWin = vtk.vtkRenderWindow() + iRen = vtk.vtkRenderWindowInteractor() + + # Set connections + mapper.SetInputConnection(reader.GetOutputPort()); + volume.SetMapper(mapper) + ren.AddViewProp(volume) + renWin.AddRenderer(ren) + iRen.SetRenderWindow(renWin) + + # Define opacity transfer function and color functions + opacityFunc1 = vtk.vtkPiecewiseFunction() + opacityFunc1.AddPoint(0.0, 0.0); + opacityFunc1.AddPoint(60.0, 0.1); + opacityFunc1.AddPoint(255.0, 0.0); + + opacityFunc2 = vtk.vtkPiecewiseFunction() + opacityFunc2.AddPoint(0.0, 0.0); + opacityFunc2.AddPoint(60.0, 0.0); + opacityFunc2.AddPoint(120.0, 0.1); + opacityFunc1.AddPoint(255.0, 0.0); + + opacityFunc3 = vtk.vtkPiecewiseFunction() + opacityFunc3.AddPoint(0.0, 0.0); + opacityFunc3.AddPoint(120.0, 0.0); + opacityFunc3.AddPoint(180.0, 0.1); + opacityFunc3.AddPoint(255.0, 0.0); + + opacityFunc4 = vtk.vtkPiecewiseFunction() + opacityFunc4.AddPoint(0.0, 0.0); + opacityFunc4.AddPoint(180.0, 0.0); + opacityFunc4.AddPoint(255.0, 0.1); + + # Color transfer functions + color1 = vtk.vtkColorTransferFunction() + color1.AddRGBPoint(0.0, 1.0, 0.0, 0.0); + color1.AddRGBPoint(60.0, 1.0, 0.0, 0.0); + + color2 = vtk.vtkColorTransferFunction() + color2.AddRGBPoint(60.0, 0.0, 0.0, 1.0); + color2.AddRGBPoint(120.0, 0.0, 0.0, 1.0); + + color3 = vtk.vtkColorTransferFunction() + color3.AddRGBPoint(120.0, 0.0, 1.0, 0.0); + color3.AddRGBPoint(180.0, 0.0, 1.0, 0.0); + + color4 = vtk.vtkColorTransferFunction() + color4.AddRGBPoint(180.0, 0.0, 0.0, 0.0); + color4.AddRGBPoint(239.0, 0.0, 0.0, 0.0); + + # Now set the opacity and the color + volumeProperty = volume.GetProperty() + volumeProperty.SetIndependentComponents(1) + volumeProperty.SetScalarOpacity(0, opacityFunc1) + volumeProperty.SetScalarOpacity(1, opacityFunc2) + volumeProperty.SetScalarOpacity(2, opacityFunc3) + volumeProperty.SetScalarOpacity(3, opacityFunc4) + volumeProperty.SetColor(0, color1) + volumeProperty.SetColor(1, color2) + volumeProperty.SetColor(2, color3) + volumeProperty.SetColor(3, color4) + + iRen.Initialize(); + ren.SetBackground(0.1,0.4,0.2) + ren.ResetCamera() + renWin.Render() + + img_file = "TestGPURayCastIndependentComponentMIP.png" + vtk.test.Testing.compareImage( + iRen.GetRenderWindow(), vtk.test.Testing.getAbsImagePath(img_file), threshold=10) + vtk.test.Testing.interact() + #iRen.Start() + +if __name__ == "__main__": + vtk.test.Testing.main([(TestGPURayCastIndependentComponentMIP, 'test')]) diff --git a/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponentMinIP.py b/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponentMinIP.py new file mode 100755 index 00000000000..1b93fba2262 --- /dev/null +++ b/Rendering/Volume/Testing/Python/TestGPURayCastIndependentComponentMinIP.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +''' +========================================================================= + + Program: Visualization Toolkit + Module: TestGPURayCastIndependentComponentMinIP.py + + Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen + All rights reserved. + See Copyright.txt or http://www.kitware.com/Copyright.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notice for more information. + +========================================================================= +''' + +import sys +import vtk +import vtk.test.Testing +from vtk.util.misc import vtkGetDataRoot +VTK_DATA_ROOT = vtkGetDataRoot() + +''' + Prevent .pyc files from being created. + Stops the vtk source being polluted + by .pyc files. +''' +sys.dont_write_bytecode = True + +class TestGPURayCastIndependentComponentMinIP(vtk.test.Testing.vtkTest): + + def test(self): + dataRoot = vtkGetDataRoot() + reader = vtk.vtkXMLImageDataReader() + reader.SetFileName("" + str(dataRoot) + "/Data/vase_4comp.vti") + + volume = vtk.vtkVolume() + #mapper = vtk.vtkFixedPointVolumeRayCastMapper() + mapper = vtk.vtkGPUVolumeRayCastMapper() + mapper.SetBlendModeToMinimumIntensity(); + mapper.SetSampleDistance(0.1) + mapper.SetAutoAdjustSampleDistances(0) + ren = vtk.vtkRenderer() + renWin = vtk.vtkRenderWindow() + iRen = vtk.vtkRenderWindowInteractor() + + # Set connections + mapper.SetInputConnection(reader.GetOutputPort()); + volume.SetMapper(mapper) + ren.AddViewProp(volume) + renWin.AddRenderer(ren) + iRen.SetRenderWindow(renWin) + + # Define opacity transfer function and color functions + opacityFunc1 = vtk.vtkPiecewiseFunction() + opacityFunc1.AddPoint(0.0, 0.0); + opacityFunc1.AddPoint(60.0, 0.1); + opacityFunc1.AddPoint(255.0, 0.0); + + opacityFunc2 = vtk.vtkPiecewiseFunction() + opacityFunc2.AddPoint(0.0, 0.1); + opacityFunc2.AddPoint(60.0, 0.0); + opacityFunc2.AddPoint(120.0, 0.0); + opacityFunc1.AddPoint(255.0, 0.0); + + opacityFunc3 = vtk.vtkPiecewiseFunction() + opacityFunc3.AddPoint(0.0, 0.0); + opacityFunc3.AddPoint(120.0, 0.1); + opacityFunc3.AddPoint(180.0, 0.0); + opacityFunc3.AddPoint(255.0, 0.0); + + opacityFunc4 = vtk.vtkPiecewiseFunction() + opacityFunc4.AddPoint(0.0, 0.0); + opacityFunc4.AddPoint(180.0, 0.1); + opacityFunc4.AddPoint(255.0, 0.0); + + # Color transfer functions + color1 = vtk.vtkColorTransferFunction() + color1.AddRGBPoint(0.0, 1.0, 0.0, 0.0); + color1.AddRGBPoint(60.0, 1.0, 0.0, 0.0); + + color2 = vtk.vtkColorTransferFunction() + color2.AddRGBPoint(60.0, 0.0, 0.0, 1.0); + color2.AddRGBPoint(120.0, 0.0, 0.0, 1.0); + + color3 = vtk.vtkColorTransferFunction() + color3.AddRGBPoint(120.0, 0.0, 1.0, 0.0); + color3.AddRGBPoint(180.0, 0.0, 1.0, 0.0); + + color4 = vtk.vtkColorTransferFunction() + color4.AddRGBPoint(180.0, 0.0, 0.0, 0.0); + color4.AddRGBPoint(239.0, 0.0, 0.0, 0.0); + + # Now set the opacity and the color + volumeProperty = volume.GetProperty() + volumeProperty.SetIndependentComponents(1) + volumeProperty.SetScalarOpacity(0, opacityFunc1) + volumeProperty.SetScalarOpacity(1, opacityFunc2) + volumeProperty.SetScalarOpacity(2, opacityFunc3) + volumeProperty.SetScalarOpacity(3, opacityFunc4) + volumeProperty.SetColor(0, color1) + volumeProperty.SetColor(1, color2) + volumeProperty.SetColor(2, color3) + volumeProperty.SetColor(3, color4) + + iRen.Initialize(); + ren.SetBackground(0.1,0.4,0.2) + ren.ResetCamera() + renWin.Render() + + img_file = "TestGPURayCastIndependentComponentMinIP.png" + vtk.test.Testing.compareImage( + iRen.GetRenderWindow(), vtk.test.Testing.getAbsImagePath(img_file), threshold=10) + vtk.test.Testing.interact() + #iRen.Start() + +if __name__ == "__main__": + vtk.test.Testing.main([(TestGPURayCastIndependentComponentMinIP, 'test')]) diff --git a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h index 3fcdd521e0f..ca26352d5e2 100644 --- a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h +++ b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h @@ -196,7 +196,7 @@ namespace vtkvolume if (noOfComponents > 1 && independentComponents) { shaderStr += std::string("\ - uniform vec4 in_componentWeight;"); + \nuniform vec4 in_componentWeight;"); } return shaderStr; @@ -747,6 +747,7 @@ namespace vtkvolume { return std::string("\ \n // We get data between 0.0 - 1.0 range\ + \n bool l_firstValue = true;\ \n vec4 l_maxValue = vec4(0.0);" ); } @@ -754,6 +755,7 @@ namespace vtkvolume { return std::string("\ \n //We get data between 0.0 - 1.0 range\ + \n bool l_firstValue = true;\ \n vec4 l_minValue = vec4(1.0);" ); } @@ -790,9 +792,14 @@ namespace vtkvolume { shaderStr += std::string("\ \n vec4 scalar = texture3D(in_volume, g_dataPos);\ - \n if (l_maxValue.w < scalar.w)\ + \n if (l_maxValue.w < scalar.w || l_firstValue)\ \n {\ \n l_maxValue = scalar;\ + \n }\ + \n\ + \n if (l_firstValue)\ + \n {\ + \n l_firstValue = false;\ \n }" ); } @@ -800,9 +807,14 @@ namespace vtkvolume { shaderStr += std::string("\ \n vec4 scalar = texture3D(in_volume, g_dataPos);\ - \n if (l_maxValue.w < scalar.x)\ + \n if (l_maxValue.w < scalar.x || l_firstValue)\ \n {\ \n l_maxValue.w = scalar.x;\ + \n }\ + \n\ + \n if (l_firstValue)\ + \n {\ + \n l_firstValue = false;\ \n }" ); } @@ -813,9 +825,14 @@ namespace vtkvolume { shaderStr += std::string("\ \n vec4 scalar = texture3D(in_volume, g_dataPos);\ - \n if (l_minValue.w > scalar.w)\ + \n if (l_minValue.w > scalar.w || l_firstValue)\ \n {\ \n l_minValue = scalar;\ + \n }\ + \n\ + \n if (l_firstValue)\ + \n {\ + \n l_firstValue = false;\ \n }" ); } @@ -823,9 +840,14 @@ namespace vtkvolume { shaderStr += std::string("\ \n vec4 scalar = texture3D(in_volume, g_dataPos);\ - \n if (l_minValue.w > scalar.x)\ + \n if (l_minValue.w > scalar.x || l_firstValue)\ \n {\ \n l_minValue.w = scalar.x;\ + \n }\ + \n\ + \n if (l_firstValue)\ + \n {\ + \n l_firstValue = false;\ \n }" ); } @@ -921,18 +943,16 @@ namespace vtkvolume if (noOfComponents > 1 && independentComponents) { return std::string("\ - \n for (int i = 0; i < in_noOfComponents; ++i)\ - \n {\ - \n vec4 g_srcColor = vec4(0);\ - \n for (int i = 0; i < in_noOfComponents; ++i)\ - \n {\ - \n vec4 tmp = vec4(computeColor(l_maxValue, i);\ - \n g_srcColor[0] += tmp[0] * tmp[3] * in_componentWeight[i];\ - \n g_srcColor[1] += tmp[1] * tmp[3] * in_componentWeight[i];\ - \n g_srcColor[2] += tmp[2] * tmp[3] * in_componentWeight[i];\ - \n g_srcColor[2] += tmp[3] * tmp[3] * in_componentWeight[i];\ - \n }\ - \n }" + \n vec4 g_srcColor = vec4(0);\ + \n for (int i = 0; i < in_noOfComponents; ++i)\ + \n {\ + \n vec4 tmp = computeColor(l_maxValue, i);\ + \n g_srcColor[0] += tmp[0] * tmp[3] * in_componentWeight[i];\ + \n g_srcColor[1] += tmp[1] * tmp[3] * in_componentWeight[i];\ + \n g_srcColor[2] += tmp[2] * tmp[3] * in_componentWeight[i];\ + \n g_srcColor[3] += tmp[3] * in_componentWeight[i];\ + \n }\ + \n g_fragColor = g_srcColor;" ); } else @@ -950,18 +970,16 @@ namespace vtkvolume if (noOfComponents > 1 && independentComponents) { return std::string("\ - \n for (int i = 0; i < in_noOfComponents; ++i)\ - \n {\ - \n vec4 g_srcColor = vec4(0);\ - \n for (int i = 0; i < in_noOfComponents; ++i)\ - \n {\ - \n vec4 tmp = vec4(computeColor(l_maxValue, i);\ - \n g_srcColor[0] += tmp[0] * tmp[3] * in_componentWeight[i];\ - \n g_srcColor[1] += tmp[1] * tmp[3] * in_componentWeight[i];\ - \n g_srcColor[2] += tmp[2] * tmp[3] * in_componentWeight[i];\ - \n g_srcColor[2] += tmp[3] * tmp[3] * in_componentWeight[i];\ - \n }\ - \n }" + \n vec4 g_srcColor = vec4(0);\ + \n for (int i = 0; i < in_noOfComponents; ++i)\ + \n {\ + \n vec4 tmp = computeColor(l_minValue, i);\ + \n g_srcColor[0] += tmp[0] * tmp[3] * in_componentWeight[i];\ + \n g_srcColor[1] += tmp[1] * tmp[3] * in_componentWeight[i];\ + \n g_srcColor[2] += tmp[2] * tmp[3] * in_componentWeight[i];\ + \n g_srcColor[2] += tmp[3] * tmp[3] * in_componentWeight[i];\ + \n }\ + \n g_fragColor = g_srcColor;" ); } else