Page MenuHomePhabricator

bug3266.diff

Authored By
xplanes
Jan 29 2010, 3:45 PM
Size
55 KB
Referenced Files
None
Subscribers
None

bug3266.diff

Index: Modules/MitkExt/Rendering/vtkMitkOpenglXRAYVolumeTextureMapper2D.cxx
===================================================================
--- Modules/MitkExt/Rendering/vtkMitkOpenglXRAYVolumeTextureMapper2D.cxx (revision 0)
+++ Modules/MitkExt/Rendering/vtkMitkOpenglXRAYVolumeTextureMapper2D.cxx (revision 0)
@@ -0,0 +1,1236 @@
+/*=========================================================================
+* Copyright (c) 2009,
+* Computational Image and Simulation Technologies in Biomedicine (CISTIB),
+* Universitat Pompeu Fabra (UPF), Barcelona, Spain. All rights reserved.
+* See license.txt file for details.
+=========================================================================*/
+
+#include "vtkMitkOpenglXRAYVolumeTextureMapper2D.h"
+#include "vtkTimerLog.h"
+#include "vtkPlaneCollection.h"
+
+#include "vtkCamera.h"
+#include "vtkDataArray.h"
+#include "vtkVolumeRenderingFactory.h"
+#include "vtkImageData.h"
+#include "vtkLargeInteger.h"
+#include "vtkMatrix4x4.h"
+#include "vtkPointData.h"
+#include "vtkRenderWindow.h"
+#include "vtkRenderer.h"
+#include "vtkTransform.h"
+#include "vtkVolumeProperty.h"
+#include "vtkObjectFactory.h"
+
+#define VTK_PLUS_X_MAJOR_DIRECTION 0
+#define VTK_MINUS_X_MAJOR_DIRECTION 1
+#define VTK_PLUS_Y_MAJOR_DIRECTION 2
+#define VTK_MINUS_Y_MAJOR_DIRECTION 3
+#define VTK_PLUS_Z_MAJOR_DIRECTION 4
+#define VTK_MINUS_Z_MAJOR_DIRECTION 5
+
+
+template <class T>
+void vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume( T *data_ptr,
+ int size[3],
+ int axis,
+ int directionFlag,
+ vtkMitkOpenglXRAYVolumeTextureMapper2D *me )
+{
+ int i, j, k;
+ int kstart, kend, kinc;
+ unsigned char *tptr;
+ T *dptr;
+ unsigned short *nptr;
+ unsigned char *gptr = NULL;
+ float *v, *t;
+ unsigned char *rgbaArray = me->GetRGBAArray();
+ float *gradientOpacityArray;
+ unsigned char *gradientMagnitudes;
+ unsigned short *encodedNormals = NULL;
+ float *redDiffuseShadingTable = NULL;
+ float *greenDiffuseShadingTable = NULL;
+ float *blueDiffuseShadingTable = NULL;
+ float *redSpecularShadingTable = NULL;
+ float *greenSpecularShadingTable = NULL;
+ float *blueSpecularShadingTable = NULL;
+ int shade;
+ float tmpval;
+ int cropping, croppingFlags;
+ double *croppingBounds;
+ int flag[3], tmpFlag, index;
+ int clipLow = 0, clipHigh = 0;
+ vtkRenderWindow *renWin = me->GetRenderWindow();
+ double spacing[3], origin[3];
+ unsigned char zero[4];
+ unsigned char *texture;
+ int textureSize[2];
+ int xTile, yTile, xTotal, yTotal, tile, numTiles;
+ int *zAxis=0, *yAxis=0, *xAxis=0;
+ int loc, inc=0;
+ int saveTextures = me->GetSaveTextures();
+ int textureOffset=0;
+
+ int a0=0, a1=0, a2=0;
+
+ switch ( axis )
+ {
+ case 0:
+ a0 = 1;
+ a1 = 2;
+ a2 = 0;
+ xAxis = &k;
+ yAxis = &i;
+ zAxis = &j;
+ inc = size[0];
+ break;
+ case 1:
+ a0 = 0;
+ a1 = 2;
+ a2 = 1;
+ xAxis = &i;
+ yAxis = &k;
+ zAxis = &j;
+ inc = 1;
+ break;
+ case 2:
+ a0 = 0;
+ a1 = 1;
+ a2 = 2;
+ xAxis = &i;
+ yAxis = &j;
+ zAxis = &k;
+ inc = 1;
+ break;
+ }
+
+ //****patch for x-ray
+ vtkOpenGLExtensionManager *extensions = vtkOpenGLExtensionManager::New();
+
+ int supports_GL_EXT_blend_minmax = extensions->ExtensionSupported(
+ "GL_EXT_blend_minmax" );
+
+ int supports_GL_EXT_blend_color = extensions->ExtensionSupported(
+ "GL_EXT_blend_color" );
+
+ if(supports_GL_EXT_blend_minmax && supports_GL_EXT_blend_color)
+ {
+ extensions->LoadExtension("GL_EXT_blend_minmax");
+ extensions->LoadExtension("GL_EXT_blend_color");
+
+ extensions->SetRenderWindow(renWin);
+
+ glPushAttrib (GL_COLOR_BUFFER_BIT);
+ glBlendFunc (GL_CONSTANT_ALPHA_EXT, GL_ONE);
+ vtkgl::BlendEquation (vtkgl::FUNC_REVERSE_SUBTRACT);
+
+ //now calculate the inverse of the attenuation
+ float in_attenuation = me->GetXRayAttenuation();
+ vtkgl::BlendColorEXT(1.0F, 1.0F, 1.0F,
+ in_attenuation/(static_cast<int>((size[a2]-1) / me->GetInternalSkipFactor())+1));
+
+ glEnable (GL_BLEND);
+ std::cout << "Extensions to handle X-ray loaded" << std::endl;
+ }
+ else
+ {
+ std::cout << "Extensions to handle X-ray rendering are not supported" << std::endl;
+ return;
+ }
+
+
+ int *axisTextureSize = me->GetAxisTextureSize();
+ textureSize[0] = axisTextureSize[a2*3+0];
+ textureSize[1] = axisTextureSize[a2*3+1];
+
+ if ( saveTextures )
+ {
+ texture = me->GetTexture();
+ switch ( axis )
+ {
+ case 0:
+ textureOffset = 0;
+ break;
+ case 1:
+ textureOffset =
+ 4*axisTextureSize[0]*axisTextureSize[1]*axisTextureSize[2];
+ break;
+ case 2:
+ textureOffset =
+ 4*axisTextureSize[0]*axisTextureSize[1]*axisTextureSize[2] +
+ 4*axisTextureSize[3]*axisTextureSize[4]*axisTextureSize[5];
+ break;
+ }
+ }
+ else
+ {
+ // Create space for the texture
+ texture = new unsigned char[4*textureSize[0]*textureSize[1]];
+ textureOffset = 0;
+ }
+
+ // How many tiles are there in X? in Y? total?
+ xTotal = textureSize[0] / size[a0];
+ yTotal = textureSize[1] / size[a1];
+ numTiles = xTotal * yTotal;
+
+ // Create space for the vertices and texture coordinates. You need four vertices
+ // with three components each for each tile, and four texture coordinates with
+ // three components each for each texture coordinate
+ v = new float [12*numTiles];
+ t = new float [ 8*numTiles];
+
+ // Convenient for filling in the empty regions (due to clipping)
+ zero[0] = 0;
+ zero[1] = 0;
+ zero[2] = 0;
+ zero[3] = 0;
+
+ // We need to know the spacing and origin of the data to set up the coordinates
+ // correctly
+ me->GetDataSpacing( spacing );
+ me->GetDataOrigin( origin );
+
+ // What is the first plane, the increment to move to the next plane, and the plane
+ // that is just past the end?
+ if ( directionFlag )
+ {
+ kstart = 0;
+ kend = (static_cast<int>( (size[a2]-1) /
+ me->GetInternalSkipFactor())+1)*me->GetInternalSkipFactor();
+
+ // Offset the slices so that if we take just one it is in the middle
+ kstart += (size[a2]-1-kend+me->GetInternalSkipFactor())/2;
+ kend += (size[a2]-1-kend+me->GetInternalSkipFactor())/2;
+
+ kinc = me->GetInternalSkipFactor();
+ }
+ else
+ {
+ kstart = static_cast<int>((size[a2]-1) /
+ me->GetInternalSkipFactor()) * me->GetInternalSkipFactor();
+ kend = -me->GetInternalSkipFactor();
+
+ // Offset the slices so that if we take just one it is in the middle
+ kend += (size[a2]-1-kstart)/2;
+ kstart += (size[a2]-1-kstart)/2;
+
+ kinc = -me->GetInternalSkipFactor();
+ }
+
+ // Fill in the texture coordinates and most of the vertex information in advance
+ float offset[2];
+ offset[0] = 0.5 / textureSize[0];
+ offset[1] = 0.5 / textureSize[1];
+
+ for ( i = 0; i < numTiles; i++ )
+ {
+ yTile = i / xTotal;
+ xTile = i % xTotal;
+
+ t[i*8 + 0] = size[a0]*xTile/static_cast<float>(textureSize[0]) + offset[0];
+ t[i*8 + 1] = size[a1]*yTile/static_cast<float>(textureSize[1]) + offset[1];
+ t[i*8 + 2] = size[a0]*xTile/static_cast<float>(textureSize[0]) + offset[0];
+ t[i*8 + 3] = size[a1]*(yTile+1)/static_cast<float>(textureSize[1]) - offset[1];
+ t[i*8 + 4] = size[a0]*(xTile+1)/static_cast<float>(textureSize[0]) - offset[0];
+ t[i*8 + 5] = size[a1]*(yTile+1)/static_cast<float>(textureSize[1]) - offset[1];
+ t[i*8 + 6] = size[a0]*(xTile+1)/static_cast<float>(textureSize[0]) - offset[0];
+ t[i*8 + 7] = size[a1]*(yTile )/static_cast<float>(textureSize[1]) + offset[1];
+
+ v[i*12 + a0] = origin[a0];
+ v[i*12 + a1] = origin[a1];
+
+ v[i*12 + 3+a0] = origin[a0];
+ v[i*12 + 3+a1] = spacing[a1] * (size[a1]-1) + origin[a1];
+
+ v[i*12 + 6+a0] = spacing[a0] * (size[a0]-1) + origin[a0];
+ v[i*12 + 6+a1] = spacing[a1] * (size[a1]-1) + origin[a1];
+
+ v[i*12 + 9+a0] = spacing[a0] * (size[a0]-1) + origin[a0];
+ v[i*12 + 9+a1] = origin[a1];
+ }
+
+ tile = 0;
+ for ( k = kstart; k != kend; k+=kinc )
+ {
+ yTile = tile / xTotal;
+ xTile = tile % xTotal;
+
+ for ( j = 0; j < size[a1]; j++ )
+ {
+ i = 0;
+
+ tptr = texture + textureOffset +
+ 4 * ( yTile*size[a1]*textureSize[0]+
+ j*textureSize[0] +
+ xTile*size[a0] );
+
+ loc = (*zAxis)*size[0]*size[1] + (*yAxis)*size[0] + (*xAxis);
+ dptr = data_ptr + loc;
+
+ for ( i = 0; i < size[a0]; i++ )
+ {
+ memcpy( tptr, rgbaArray + (*dptr)*4, 4 );
+ tptr += 4;
+ dptr += inc;
+ }
+ }
+
+
+ if ( renWin->CheckAbortStatus() )
+ {
+ break;
+ }
+
+ v[12*tile + a2] =
+ v[12*tile + 3+a2] =
+ v[12*tile + 6+a2] =
+ v[12*tile + 9+a2] = spacing[a2] * k + origin[a2];
+
+ tile++;
+
+ if ( tile == numTiles || (k+kinc == kend) )
+ {
+ if ( saveTextures )
+ {
+ textureOffset += 4*axisTextureSize[a2*3] * axisTextureSize[a2*3+1];
+ }
+ else
+ {
+ me->RenderQuads( tile, v, t, texture, textureSize, 0);
+ }
+ tile = 0;
+ }
+
+ }
+
+
+ if ( !saveTextures )
+ {
+ delete [] texture;
+ }
+
+ delete [] v;
+ delete [] t;
+
+ //****patch for x-ray
+ glPopAttrib ();
+ extensions->Delete();
+ //****end patch for x-ray
+
+}
+
+vtkCxxRevisionMacro(vtkMitkOpenglXRAYVolumeTextureMapper2D, "$Revision: 1.4 $");
+
+//----------------------------------------------------------------------------
+// Needed when we don't use the vtkStandardNewMacro.
+//vtkInstantiatorNewMacro(vtkMitkOpenglXRAYVolumeTextureMapper2D);
+//----------------------------------------------------------------------------
+
+vtkStandardNewMacro(vtkMitkOpenglXRAYVolumeTextureMapper2D);
+
+vtkMitkOpenglXRAYVolumeTextureMapper2D::vtkMitkOpenglXRAYVolumeTextureMapper2D()
+{
+ this->TargetTextureSize[0] = 512;
+ this->TargetTextureSize[1] = 512;
+ this->MaximumNumberOfPlanes = 0;
+ this->MaximumStorageSize = 0;
+ this->Texture = NULL;
+ this->TextureSize = 0;
+}
+
+vtkMitkOpenglXRAYVolumeTextureMapper2D::~vtkMitkOpenglXRAYVolumeTextureMapper2D()
+{
+ if ( this->Texture )
+ {
+ delete [] this->Texture;
+ }
+}
+
+
+//vtkMitkOpenglXRAYVolumeTextureMapper2D *vtkMitkOpenglXRAYVolumeTextureMapper2D::New()
+//{
+// // First try to create the object from the vtkObjectFactory
+// vtkObject* ret =
+// vtkVolumeRenderingFactory::CreateInstance("vtkMitkOpenglXRAYVolumeTextureMapper2D");
+// return static_cast<vtkMitkOpenglXRAYVolumeTextureMapper2D *>(ret);
+//}
+
+void vtkMitkOpenglXRAYVolumeTextureMapper2D::RenderSavedTexture()
+{
+ int i, k;
+ int kstart, kend, kinc;
+ unsigned char *tptr;
+ float *v, *t;
+ vtkRenderWindow *renWin = this->GetRenderWindow();
+ double spacing[3], origin[3];
+ unsigned char *texture;
+ int textureSize[2];
+ int xTile, yTile, xTotal, yTotal, tile, numTiles;
+ int textureOffset=0;
+ int axis=0, directionFlag=0;
+ int size[3];
+
+ int a0=0, a1=0, a2=0;
+
+ this->GetInput()->GetDimensions( size );
+
+ switch ( this->MajorDirection )
+ {
+ case VTK_PLUS_X_MAJOR_DIRECTION:
+ axis = 0;
+ directionFlag = 1;
+ break;
+ case VTK_MINUS_X_MAJOR_DIRECTION:
+ axis = 0;
+ directionFlag = 0;
+ break;
+ case VTK_PLUS_Y_MAJOR_DIRECTION:
+ axis = 1;
+ directionFlag = 1;
+ break;
+ case VTK_MINUS_Y_MAJOR_DIRECTION:
+ axis = 1;
+ directionFlag = 0;
+ break;
+ case VTK_PLUS_Z_MAJOR_DIRECTION:
+ axis = 2;
+ directionFlag = 1;
+ break;
+ case VTK_MINUS_Z_MAJOR_DIRECTION:
+ axis = 2;
+ directionFlag = 0;
+ break;
+ }
+
+ switch ( axis )
+ {
+ case 0:
+ a0 = 1;
+ a1 = 2;
+ a2 = 0;
+ break;
+ case 1:
+ a0 = 0;
+ a1 = 2;
+ a2 = 1;
+ break;
+ case 2:
+ a0 = 0;
+ a1 = 1;
+ a2 = 2;
+ break;
+ }
+
+
+ //****patch for x-ray
+ vtkOpenGLExtensionManager *extensions = vtkOpenGLExtensionManager::New();
+
+ int supports_GL_EXT_blend_minmax = extensions->ExtensionSupported(
+ "GL_EXT_blend_minmax" );
+
+ int supports_GL_EXT_blend_color = extensions->ExtensionSupported(
+ "GL_EXT_blend_color" );
+
+ if(supports_GL_EXT_blend_minmax && supports_GL_EXT_blend_color)
+ {
+ extensions->LoadExtension("GL_EXT_blend_minmax");
+ extensions->LoadExtension("GL_EXT_blend_color");
+
+ extensions->SetRenderWindow(renWin);
+
+ glPushAttrib (GL_COLOR_BUFFER_BIT);
+ glBlendFunc (GL_CONSTANT_ALPHA_EXT, GL_ONE);
+ vtkgl::BlendEquation(vtkgl::FUNC_REVERSE_SUBTRACT);
+
+ float in_attenuation = GetXRayAttenuation();
+ vtkgl::BlendColorEXT(1.0F, 1.0F, 1.0F,
+ in_attenuation/(static_cast<int>((size[a2]-1) / this->GetInternalSkipFactor())+1));
+
+ glEnable (GL_BLEND);
+ std::cout << "Extensions to handle X-ray loaded" << std::endl;
+ }
+ else
+ {
+ std::cout << "Extensions to handle X-ray rendering are not supported" << std::endl;
+ return;
+ }
+ //****end patch for x-ray
+
+ textureSize[0] = this->AxisTextureSize[a2][0];
+ textureSize[1] = this->AxisTextureSize[a2][1];
+
+ texture = this->Texture;
+ switch ( axis )
+ {
+ case 0:
+ textureOffset = 0;
+ break;
+ case 1:
+ textureOffset =
+ 4*(this->AxisTextureSize[0][0]*
+ this->AxisTextureSize[0][1]*
+ this->AxisTextureSize[0][2]);
+ break;
+ case 2:
+ textureOffset =
+ 4*(this->AxisTextureSize[0][0]*
+ this->AxisTextureSize[0][1]*
+ this->AxisTextureSize[0][2]) +
+ 4*(this->AxisTextureSize[1][0]*
+ this->AxisTextureSize[1][1]*
+ this->AxisTextureSize[1][2]);
+ break;
+ }
+
+ if ( directionFlag == 0 )
+ {
+ textureOffset +=
+ 4*(this->AxisTextureSize[a2][0]*
+ this->AxisTextureSize[a2][1]*
+ (this->AxisTextureSize[a2][2]-1));
+ }
+
+ // How many tiles are there in X? in Y? total?
+ xTotal = textureSize[0] / size[a0];
+ yTotal = textureSize[1] / size[a1];
+ numTiles = xTotal * yTotal;
+
+ // Create space for the vertices and texture coordinates. You need four vertices
+ // with three components each for each tile, and four texture coordinates with
+ // three components each for each texture coordinate
+ v = new float [12*numTiles];
+ t = new float [ 8*numTiles];
+
+ // We need to know the spacing and origin of the data to set up the coordinates
+ // correctly
+ this->GetDataSpacing( spacing );
+ this->GetDataOrigin( origin );
+
+ // What is the first plane, the increment to move to the next plane, and the plane
+ // that is just past the end?
+ if ( directionFlag )
+ {
+ kstart = 0;
+ kend = (static_cast<int>( (size[a2]-1) /
+ this->InternalSkipFactor)+1)*this->InternalSkipFactor;
+
+ // Offset the slices so that if we take just one it is in the middle
+ kstart += (size[a2]-1-kend+this->InternalSkipFactor)/2;
+ kend += (size[a2]-1-kend+this->InternalSkipFactor)/2;
+
+ kinc = this->InternalSkipFactor;
+ }
+ else
+ {
+ kstart = static_cast<int>((size[a2]-1) /
+ this->InternalSkipFactor) * this->InternalSkipFactor;
+ kend = -this->InternalSkipFactor;
+
+ // Offset the slices so that if we take just one it is in the middle
+ kend += (size[a2]-1-kstart)/2;
+ kstart += (size[a2]-1-kstart)/2;
+
+ kinc = -this->InternalSkipFactor;
+ }
+
+ // Fill in the texture coordinates and most of the vertex information in advance
+ float offset[2];
+ offset[0] = 0.5 / textureSize[0];
+ offset[1] = 0.5 / textureSize[1];
+
+ int idx;
+ for ( idx = 0; idx < numTiles; idx++ )
+ {
+ i = ( directionFlag == 1 )?(idx):(numTiles-idx-1);
+
+ yTile = i / xTotal;
+ xTile = i % xTotal;
+
+ t[i*8 + 0] = size[a0]*xTile/static_cast<float>(textureSize[0]) + offset[0];
+ t[i*8 + 1] = size[a1]*yTile/static_cast<float>(textureSize[1]) + offset[1];
+ t[i*8 + 2] = size[a0]*xTile/static_cast<float>(textureSize[0]) + offset[0];
+ t[i*8 + 3] = size[a1]*(yTile+1)/static_cast<float>(textureSize[1]) - offset[1];
+ t[i*8 + 4] = size[a0]*(xTile+1)/static_cast<float>(textureSize[0]) - offset[0];
+ t[i*8 + 5] = size[a1]*(yTile+1)/static_cast<float>(textureSize[1]) - offset[1];
+ t[i*8 + 6] = size[a0]*(xTile+1)/static_cast<float>(textureSize[0]) - offset[0];
+ t[i*8 + 7] = size[a1]*yTile/static_cast<float>(textureSize[1]) + offset[1];
+
+ v[i*12 + a0] = origin[a0];
+ v[i*12 + a1] = origin[a1];
+
+ v[i*12 + 3+a0] = origin[a0];
+ v[i*12 + 3+a1] = spacing[a1] * (size[a1]-1) + origin[a1];
+
+ v[i*12 + 6+a0] = spacing[a0] * (size[a0]-1) + origin[a0];
+ v[i*12 + 6+a1] = spacing[a1] * (size[a1]-1) + origin[a1];
+
+ v[i*12 + 9+a0] = spacing[a0] * (size[a0]-1) + origin[a0];
+ v[i*12 + 9+a1] = origin[a1];
+ }
+
+ if ( directionFlag == 1 )
+ {
+ tile = 0;
+ }
+ else
+ {
+ tile = (((kend - kstart)/kinc)-1)%numTiles;
+ }
+
+ int tileCount = 0;
+
+ for ( k = kstart; k != kend; k+=kinc )
+ {
+ if ( renWin->CheckAbortStatus() )
+ {
+ break;
+ }
+
+ v[12*tile + a2] =
+ v[12*tile + 3+a2] =
+ v[12*tile + 6+a2] =
+ v[12*tile + 9+a2] = spacing[a2] * k + origin[a2];
+
+ tileCount++;
+
+ if ( directionFlag == 1 )
+ {
+ tile++;
+ }
+ else
+ {
+ tile--;
+ }
+
+ if ( (directionFlag == 1 && tile == numTiles ) ||
+ (directionFlag == 0 && tile == -1) || (k+kinc == kend) )
+ {
+ tptr = texture + textureOffset;
+ if ( directionFlag == 1 )
+ {
+ textureOffset +=
+ 4*this->AxisTextureSize[a2][0] * this->AxisTextureSize[a2][1];
+ }
+ else
+ {
+ textureOffset -=
+ 4*this->AxisTextureSize[a2][0] * this->AxisTextureSize[a2][1];
+ }
+
+ this->RenderQuads( tileCount, v, t, tptr, textureSize, !directionFlag );
+ tile = (directionFlag == 1)?(0):(numTiles-1);
+ tileCount = 0;
+ }
+ }
+
+ delete [] v;
+ delete [] t;
+
+ //****patch for x-ray
+ glPopAttrib ();
+ extensions->Delete();
+ //****end patch for x-ray
+}
+
+void vtkMitkOpenglXRAYVolumeTextureMapper2D::GenerateTexturesAndRenderQuads( vtkRenderer *ren, vtkVolume *vol )
+{
+ vtkImageData *input = this->GetInput();
+ int size[3];
+ void *inputPointer;
+ int inputType;
+
+ inputPointer =
+ input->GetPointData()->GetScalars()->GetVoidPointer(0);
+ inputType =
+ input->GetPointData()->GetScalars()->GetDataType();
+
+ input->GetDimensions( size );
+
+ // Do we have a texture already, and nothing has changed? If so
+ // just render it.
+ if ( this->Texture && !this->Shade &&
+ this->GetMTime() < this->TextureMTime &&
+ this->GetInput()->GetMTime() < this->TextureMTime &&
+ vol->GetProperty()->GetMTime() < this->TextureMTime )
+ {
+ this->RenderSavedTexture();
+ return;
+ }
+
+ // Otherwise, we need to generate textures. We can throw away any
+ // saved textures
+ if ( this->Texture )
+ {
+ delete [] this->Texture;
+ this->Texture = NULL;
+ }
+ this->TextureSize = 0;
+
+ // Will all the textures fit in the allotted storage?
+ this->ComputeAxisTextureSize( 0, this->AxisTextureSize[0] );
+ this->ComputeAxisTextureSize( 1, this->AxisTextureSize[1] );
+ this->ComputeAxisTextureSize( 2, this->AxisTextureSize[2] );
+
+ vtkLargeInteger neededSize;
+ vtkLargeInteger tmpInt;
+
+
+ neededSize =
+ this->AxisTextureSize[0][0];
+ neededSize = neededSize *
+ this->AxisTextureSize[0][1] *
+ this->AxisTextureSize[0][2] ;
+
+ tmpInt =
+ this->AxisTextureSize[1][0];
+ tmpInt = tmpInt *
+ this->AxisTextureSize[1][1] *
+ this->AxisTextureSize[1][2];
+ neededSize = neededSize + tmpInt;
+
+ tmpInt =
+ this->AxisTextureSize[2][0];
+ tmpInt = tmpInt *
+ this->AxisTextureSize[2][1] *
+ this->AxisTextureSize[2][2];
+ neededSize = neededSize + tmpInt;
+
+ neededSize *= 4;
+
+ //****patch for x-ray
+ //rebuild the rgbaArray, since mtk transfer function create a mess for that!
+ int sz = vol->GetArraySize();
+ int thr = (int) (sz*GetXRayThreshold());
+ for(int i=0;i<sz;i++)
+ if(i<thr)
+ this->GetRGBAArray()[i] = 0;
+ else
+ this->GetRGBAArray()[i]= i >> 8;
+
+ //****end patch for x-ray
+
+ if ( neededSize.GetLength() > 31 )
+ {
+ this->SaveTextures = 0;
+ }
+ else
+ {
+ this->SaveTextures =
+ ( neededSize.CastToLong() <= this->MaximumStorageSize &&
+ !this->Shade );
+ }
+
+ if ( this->SaveTextures )
+ {
+ this->Texture = new unsigned char [neededSize.CastToLong()];
+ this->TextureSize = neededSize.CastToLong();
+
+ int savedDirection = this->MajorDirection;
+
+ switch ( inputType )
+ {
+ case VTK_UNSIGNED_CHAR:
+ this->InitializeRender( ren, vol, VTK_PLUS_X_MAJOR_DIRECTION );
+ vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume
+ ( static_cast<unsigned char *>(inputPointer), size, 0, 1, this );
+
+ this->InitializeRender( ren, vol, VTK_PLUS_Y_MAJOR_DIRECTION );
+ vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume
+ ( static_cast<unsigned char *>(inputPointer), size, 1, 1, this );
+
+ this->InitializeRender( ren, vol, VTK_PLUS_Z_MAJOR_DIRECTION );
+ vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume
+ ( static_cast<unsigned char *>(inputPointer), size, 2, 1, this );
+ break;
+ case VTK_UNSIGNED_SHORT:
+ this->InitializeRender( ren, vol, VTK_PLUS_X_MAJOR_DIRECTION );
+ vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume
+ ( static_cast<unsigned short *>(inputPointer), size, 0, 1, this );
+
+ this->InitializeRender( ren, vol, VTK_PLUS_Y_MAJOR_DIRECTION );
+ vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume
+ ( static_cast<unsigned short *>(inputPointer), size, 1, 1, this );
+
+ this->InitializeRender( ren, vol, VTK_PLUS_Z_MAJOR_DIRECTION );
+ vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume
+ ( static_cast<unsigned short *>(inputPointer), size, 2, 1, this );
+ break;
+ }
+
+ this->MajorDirection = savedDirection;
+ if ( !ren->GetRenderWindow()->GetAbortRender() )
+ {
+ this->RenderSavedTexture();
+ this->TextureMTime.Modified();
+ }
+ }
+ else
+ {
+
+ switch ( inputType )
+ {
+ case VTK_UNSIGNED_CHAR:
+ switch ( this->MajorDirection )
+ {
+ case VTK_PLUS_X_MAJOR_DIRECTION:
+ vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume
+ ( static_cast<unsigned char *>(inputPointer), size, 0, 1, this );
+ break;
+
+ case VTK_MINUS_X_MAJOR_DIRECTION:
+ vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume
+ ( static_cast<unsigned char *>(inputPointer), size, 0, 0, this );
+ break;
+
+ case VTK_PLUS_Y_MAJOR_DIRECTION:
+ vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume
+ ( static_cast<unsigned char *>(inputPointer), size, 1, 1, this );
+ break;
+
+ case VTK_MINUS_Y_MAJOR_DIRECTION:
+ vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume
+ ( static_cast<unsigned char *>(inputPointer), size, 1, 0, this );
+ break;
+
+ case VTK_PLUS_Z_MAJOR_DIRECTION:
+ vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume
+ ( static_cast<unsigned char *>(inputPointer), size, 2, 1, this );
+ break;
+
+ case VTK_MINUS_Z_MAJOR_DIRECTION:
+ vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume
+ ( static_cast<unsigned char *>(inputPointer), size, 2, 0, this );
+ break;
+ }
+ break;
+ case VTK_UNSIGNED_SHORT:
+ switch ( this->MajorDirection )
+ {
+ case VTK_PLUS_X_MAJOR_DIRECTION:
+ vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume
+ ( static_cast<unsigned short *>(inputPointer), size, 0, 1, this );
+ break;
+
+ case VTK_MINUS_X_MAJOR_DIRECTION:
+ vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume
+ ( static_cast<unsigned short *>(inputPointer), size, 0, 0, this );
+ break;
+
+ case VTK_PLUS_Y_MAJOR_DIRECTION:
+ vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume
+ ( static_cast<unsigned short *>(inputPointer), size, 1, 1, this );
+ break;
+
+ case VTK_MINUS_Y_MAJOR_DIRECTION:
+ vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume
+ ( static_cast<unsigned short *>(inputPointer), size, 1, 0, this );
+ break;
+
+ case VTK_PLUS_Z_MAJOR_DIRECTION:
+ vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume
+ ( static_cast<unsigned short *>(inputPointer), size, 2, 1, this );
+ break;
+
+ case VTK_MINUS_Z_MAJOR_DIRECTION:
+ vtkMitkOpenglXRAYVolumeTextureMapper2D_TraverseVolume
+ ( static_cast<unsigned short *>(inputPointer), size, 2, 0, this );
+ break;
+ }
+ break;
+ default:
+ vtkErrorMacro(
+ "vtkMitkOpenglXRAYVolumeTextureMapper2D only works with unsigned short and unsigned char data.\n" <<
+ "Input type: " << inputType << " given.");
+ }
+ }
+}
+
+void vtkMitkOpenglXRAYVolumeTextureMapper2D::InitializeRender( vtkRenderer *ren,
+ vtkVolume *vol,
+ int majorDirection )
+{
+ if ( majorDirection >= 0)
+ {
+ this->MajorDirection = majorDirection;
+ }
+ else
+ {
+ double vpn[3];
+
+ // Take the vpn, de convert it to volume coordinates, and find the
+ // major direction
+ vtkMatrix4x4 *volMatrix = vtkMatrix4x4::New();
+ volMatrix->DeepCopy( vol->GetMatrix() );
+ vtkTransform *worldToVolumeTransform = vtkTransform::New();
+ worldToVolumeTransform->SetMatrix( volMatrix );
+
+ // Create a transform that will account for the translation of
+ // the scalar data.
+ vtkTransform *volumeTransform = vtkTransform::New();
+
+ volumeTransform->Identity();
+ volumeTransform->Translate(this->GetInput()->GetOrigin());
+
+ // Now concatenate the volume's matrix with this scalar data matrix
+ worldToVolumeTransform->PreMultiply();
+ worldToVolumeTransform->Concatenate( volumeTransform->GetMatrix() );
+ worldToVolumeTransform->Inverse();
+
+ ren->GetActiveCamera()->GetViewPlaneNormal(vpn);
+ worldToVolumeTransform->TransformVector( vpn, vpn );
+
+ volMatrix->Delete();
+ volumeTransform->Delete();
+ worldToVolumeTransform->Delete();
+
+ if ( fabs(vpn[0]) >= fabs(vpn[1]) && fabs(vpn[0]) >= fabs(vpn[2]) )
+ {
+ this->MajorDirection = (vpn[0]<0.0)?
+ (VTK_MINUS_X_MAJOR_DIRECTION):(VTK_PLUS_X_MAJOR_DIRECTION);
+ }
+ else if ( fabs(vpn[1]) >= fabs(vpn[0]) && fabs(vpn[1]) >= fabs(vpn[2]) )
+ {
+ this->MajorDirection = (vpn[1]<0.0)?
+ (VTK_MINUS_Y_MAJOR_DIRECTION):(VTK_PLUS_Y_MAJOR_DIRECTION);
+ }
+ else
+ {
+ this->MajorDirection = (vpn[2]<0.0)?
+ (VTK_MINUS_Z_MAJOR_DIRECTION):(VTK_PLUS_Z_MAJOR_DIRECTION);
+ }
+ }
+
+ // Determine the internal skip factor - if there is a limit on the number
+ // of planes we can have (the MaximumNumberOfPlanes value is greater than
+ // 0) then increase this skip factor until we ensure the maximum condition.
+ this->InternalSkipFactor = 1;
+ if ( this->MaximumNumberOfPlanes > 0 )
+ {
+ int size[3];
+ this->GetInput()->GetDimensions( size );
+ while ( size[this->MajorDirection/2] / static_cast<float>(this->InternalSkipFactor) > static_cast<float>(this->MaximumNumberOfPlanes) )
+ {
+ this->InternalSkipFactor++;
+ }
+ }
+ // Assume that the spacing between samples is 1/2 of the maximum - this
+ // could be computed accurately for parallel (but isn't right now). For
+ // perspective, this spacing changes across the image so no one number will
+ // be accurate. 1/2 the maximum is (1 + sqrt(2)) / 2 = 1.2071
+
+ double *dspacing;
+ dspacing = this->GetInput()->GetSpacing();
+ this->DataSpacing[0] = dspacing[0];
+ this->DataSpacing[1] = dspacing[1];
+ this->DataSpacing[2] = dspacing[2];
+ this->SampleDistance =
+ this->DataSpacing[this->MajorDirection/2]*this->InternalSkipFactor*1.2071;
+ this->vtkVolumeTextureMapper::InitializeRender( ren, vol );
+}
+
+void vtkMitkOpenglXRAYVolumeTextureMapper2D::ComputeAxisTextureSize( int axis, int *textureSize )
+{
+ int targetSize[2];
+ int a0=0, a1=0, a2=0;
+
+ switch ( axis )
+ {
+ case 0:
+ a0 = 1;
+ a1 = 2;
+ a2 = 0;
+ break;
+ case 1:
+ a0 = 0;
+ a1 = 2;
+ a2 = 1;
+ break;
+ case 2:
+ a0 = 0;
+ a1 = 1;
+ a2 = 2;
+ break;
+ }
+
+
+ // How big should the texture be?
+ // Start with the target size
+ targetSize[0] = this->TargetTextureSize[0];
+ targetSize[1] = this->TargetTextureSize[1];
+
+ int size[3];
+ this->GetInput()->GetDimensions( size );
+
+ // Increase the x dimension of the texture if the x dimension of the data
+ // is bigger than it (because these are x by y textures)
+ if ( size[a0] > targetSize[0] )
+ {
+ targetSize[0] = size[a0];
+ }
+
+ // Increase the y dimension of the texture if the y dimension of the data
+ // is bigger than it (because these are x by y textures)
+ if ( size[a1] > targetSize[1] )
+ {
+ targetSize[1] = size[a1];
+ }
+
+ // Make sure the x dimension of the texture is a power of 2
+ textureSize[0] = 32;
+ while( textureSize[0] < targetSize[0] )
+ {
+ textureSize[0] *= 2;
+ }
+
+ // Make sure the y dimension of the texture is a power of 2
+ textureSize[1] = 32;
+ while( textureSize[1] < targetSize[1] )
+ {
+ textureSize[1] *= 2;
+ }
+
+ // Our texture might be too big - shrink it carefully making
+ // sure that it is still big enough in the right dimensions to
+ // handle oddly shaped volumes
+ int volSize = size[0]*size[1]*size[2];
+ int done = (volSize > textureSize[0]*textureSize[1]);
+ int minSize[2];
+
+ // What is the minumum size the texture could be in X (along the X
+ // axis of the volume)?
+ minSize[0] = 32;
+ while ( minSize[0] < size[a0] )
+ {
+ minSize[0] *= 2;
+ }
+
+ // What is the minumum size the texture could be in Y (along the Y
+ // axis of the volume)?
+ minSize[1] = 32;
+ while ( minSize[1] < size[a1] )
+ {
+ minSize[1] *= 2;
+ }
+
+ // Keep reducing the texture size until it is just big enough
+ while (!done)
+ {
+ // Set done to 1. Reset to 0 if we make any changes.
+ done = 1;
+
+ // If the texture is bigger in some dimension that it needs to be
+ // and chopping that dimension in half would still fit the whole
+ // volume, then chop it in half.
+ if ( textureSize[0] > minSize[0] &&
+ ( ((textureSize[0]/2) / size[a0]) *
+ (textureSize[1] / size[a1]) >= size[a2] ) )
+ {
+ textureSize[0] /= 2;
+ done = 0;
+ }
+ if ( textureSize[1] > minSize[1] &&
+ ( (textureSize[0] / size[a0]) *
+ ((textureSize[1]/2) / size[a1]) >= size[a2] ) )
+ {
+ textureSize[1] /= 2;
+ done = 0;
+ }
+ }
+
+ // This is how many texture planes would be necessary if one slice fit on a
+ // texture (taking into account the user defined maximum)
+ textureSize[2] =
+ (size[a2]<this->MaximumNumberOfPlanes||this->MaximumNumberOfPlanes<=0) ?
+ (size[a2]) : (this->MaximumNumberOfPlanes);
+
+ // How many slices can fit on a texture in X and Y?
+ int xTotal = textureSize[0] / size[a0];
+ int yTotal = textureSize[1] / size[a1];
+
+ // The number of textures we need is the number computed above divided by
+ // how many fit on a texture (plus one if they don't fit evenly)
+ textureSize[2] = (textureSize[2] / (xTotal*yTotal)) +
+ ((textureSize[2] % (xTotal*yTotal))!=0);
+}
+
+
+// Print the vtkMitkOpenglXRAYVolumeTextureMapper2D
+void vtkMitkOpenglXRAYVolumeTextureMapper2D::PrintSelf(ostream& os, vtkIndent indent)
+{
+ os << indent << "Target Texture Size: "
+ << this->TargetTextureSize[0] << ", "
+ << this->TargetTextureSize[1] << endl;
+
+ os << indent << "Maximum Number Of Planes: ";
+ if ( this->MaximumNumberOfPlanes > 0 )
+ {
+ os << this->MaximumNumberOfPlanes << endl;
+ }
+ else
+ {
+ os << "<unlimited>" << endl;
+ }
+
+ os << indent << "Maximum Storage Size: "
+ << this->MaximumStorageSize << endl;
+
+ this->Superclass::PrintSelf(os,indent);
+}
+
+
+void vtkMitkOpenglXRAYVolumeTextureMapper2D::Render(vtkRenderer *ren, vtkVolume *vol)
+{
+ vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
+ vtkPlaneCollection *clipPlanes;
+ vtkPlane *plane;
+ int i, numClipPlanes = 0;
+ double planeEquation[4];
+
+ this->Timer->StartTimer();
+
+ // Let the superclass take care of some initialization
+ this->InitializeRender( ren, vol );
+
+ // build transformation
+ vol->GetMatrix(matrix);
+ matrix->Transpose();
+
+ // Use the OpenGL clip planes
+ clipPlanes = this->ClippingPlanes;
+ if ( clipPlanes )
+ {
+ numClipPlanes = clipPlanes->GetNumberOfItems();
+ if (numClipPlanes > 6)
+ {
+ vtkErrorMacro(<< "OpenGL guarantees only 6 additional clipping planes");
+ }
+
+ for (i = 0; i < numClipPlanes; i++)
+ {
+ glEnable((GLenum)(GL_CLIP_PLANE0+i));
+
+ plane = (vtkPlane *)clipPlanes->GetItemAsObject(i);
+
+ planeEquation[0] = plane->GetNormal()[0];
+ planeEquation[1] = plane->GetNormal()[1];
+ planeEquation[2] = plane->GetNormal()[2];
+ planeEquation[3] = -(planeEquation[0]*plane->GetOrigin()[0]+
+ planeEquation[1]*plane->GetOrigin()[1]+
+ planeEquation[2]*plane->GetOrigin()[2]);
+ glClipPlane((GLenum)(GL_CLIP_PLANE0+i),planeEquation);
+ }
+ }
+
+
+ // insert model transformation
+ glMatrixMode( GL_MODELVIEW );
+ glPushMatrix();
+ glMultMatrixd(matrix->Element[0]);
+
+ // Turn lighting off - the polygon textures already have illumination
+ glDisable( GL_LIGHTING );
+
+ // Turn texturing on so that we can draw the textured polygons
+ glEnable( GL_TEXTURE_2D );
+
+#ifdef GL_VERSION_1_1
+ GLuint tempIndex;
+ glGenTextures(1, &tempIndex);
+ glBindTexture(GL_TEXTURE_2D, tempIndex);
+#endif
+
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+
+ glColor3f( 1.0, 1.0, 1.0 );
+
+ this->GenerateTexturesAndRenderQuads( ren, vol );
+
+ // pop transformation matrix
+ glMatrixMode( GL_MODELVIEW );
+ glPopMatrix();
+
+ matrix->Delete();
+
+ glDisable( GL_TEXTURE_2D );
+
+#ifdef GL_VERSION_1_1
+ glFlush();
+ glDeleteTextures(1, &tempIndex);
+#endif
+
+ // Turn lighting back on
+ glEnable( GL_LIGHTING );
+
+ if ( clipPlanes )
+ {
+ for (i = 0; i < numClipPlanes; i++)
+ {
+ glDisable((GLenum)(GL_CLIP_PLANE0+i));
+ }
+ }
+
+ this->Timer->StopTimer();
+
+ this->TimeToDraw = (float)this->Timer->GetElapsedTime();
+
+ // If the timer is not accurate enough, set it to a small
+ // time so that it is not zero
+ if ( this->TimeToDraw == 0.0 )
+ {
+ this->TimeToDraw = 0.0001;
+ }
+}
+
+void vtkMitkOpenglXRAYVolumeTextureMapper2D::RenderQuads( int numQuads,
+ float *v,
+ float *t,
+ unsigned char *texture,
+ int size[2], int reverseFlag )
+{
+#ifdef GL_VERSION_1_1
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, size[0], size[1],
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, texture );
+#else
+ glTexImage2D( GL_TEXTURE_2D, 0, 4, size[0], size[1],
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, texture );
+#endif
+
+ glBegin( GL_QUADS );
+
+ float *tptr, *vptr;
+ int i, j;
+
+ if ( reverseFlag )
+ {
+ for ( i = 0; i < numQuads; i++ )
+ {
+ tptr = t+2*4*(numQuads-i-1);
+ vptr = v+3*4*(numQuads-i-1);
+ for ( j = 0; j < 4; j++ )
+ {
+ glTexCoord2fv( tptr );
+ glVertex3fv( vptr );
+ tptr += 2;
+ vptr += 3;
+ }
+ }
+ }
+ else
+ {
+ tptr = t;
+ vptr = v;
+ for ( i = 0; i < numQuads*4; i++ )
+ {
+ glTexCoord2fv( tptr );
+ glVertex3fv( vptr );
+ tptr += 2;
+ vptr += 3;
+ }
+ }
+
+ glEnd();
+}
+
+
Property changes on: Modules\MitkExt\Rendering\vtkMitkOpenglXRAYVolumeTextureMapper2D.cxx
___________________________________________________________________
Added: svn:eol-style
+ native
Index: Modules/MitkExt/Rendering/vtkMitkOpenglXRAYVolumeTextureMapper2D.h
===================================================================
--- Modules/MitkExt/Rendering/vtkMitkOpenglXRAYVolumeTextureMapper2D.h (revision 0)
+++ Modules/MitkExt/Rendering/vtkMitkOpenglXRAYVolumeTextureMapper2D.h (revision 0)
@@ -0,0 +1,155 @@
+/*=========================================================================
+/*
+* Copyright (c) 2009,
+* Computational Image and Simulation Technologies in Biomedicine (CISTIB),
+* Universitat Pompeu Fabra (UPF), Barcelona, Spain. All rights reserved.
+* See license.txt file for details.
+*/
+
+
+/*=========================================================================*/
+// .NAME vtkMitkOpenglXRAYVolumeTextureMapper2D - class for a volume mapper for XRay Rendering with 2D Textures
+// this class is derived directly by vtkVolumeTexture2D and vtkOpenglVolumeTexture2d
+
+// .SECTION Description
+// vtkMitkOpenglXRAYVolumeTextureMapper2D renders a volume using 2D texture mapping.
+
+
+// .SECTION see also
+// vtkVolumeMapper
+
+#ifndef __vtkMitkOpenglXRAYVolumeTextureMapper2D_h
+#define __vtkMitkOpenglXRAYVolumeTextureMapper2D_h
+
+//****patch for x-ray
+#include "vtkOpenGLExtensionManager.h"
+#include "vtkgl.h" // vtkgl namespace
+#include "ParseOGLExt/headers/glext.h"
+//****end of patch for x-ray
+
+#include "vtkVolumeTextureMapper.h"
+
+#include "mitkCommon.h"
+
+class MITKEXT_CORE_EXPORT vtkMitkOpenglXRAYVolumeTextureMapper2D : public vtkVolumeTextureMapper
+{
+public:
+ vtkTypeRevisionMacro(vtkMitkOpenglXRAYVolumeTextureMapper2D,vtkVolumeTextureMapper);
+ void PrintSelf( ostream& os, vtkIndent indent );
+
+ static vtkMitkOpenglXRAYVolumeTextureMapper2D *New();
+
+ // Description:
+ // Target size in pixels of each size of the texture for downloading. Default is
+ // 512x512 - so a 512x512 texture will be tiled with as many slices of the volume
+ // as possible, then all the quads will be rendered. This can be set to optimize
+ // for a particular architecture. This must be set with numbers that are a power
+ // of two.
+ vtkSetVector2Macro( TargetTextureSize, int );
+ vtkGetVector2Macro( TargetTextureSize, int );
+
+ // Description:
+ // This is the maximum number of planes that will be created for texture mapping
+ // the volume. If the volume has more voxels than this along the viewing direction,
+ // then planes of the volume will be skipped to ensure that this maximum is not
+ // violated. A skip factor is used, and is incremented until the maximum condition
+ // is satisfied.
+ vtkSetMacro( MaximumNumberOfPlanes, int );
+ vtkGetMacro( MaximumNumberOfPlanes, int );
+
+ // Description:
+ // This is the maximum size of saved textures in bytes. If this size is large
+ // enough to hold the RGBA textures for all three directions (XxYxZx3x4 is
+ // the approximate value - it is actually a bit larger due to wasted space in
+ // the textures) then the textures will be saved.
+ vtkSetMacro( MaximumStorageSize, int );
+ vtkGetMacro( MaximumStorageSize, int );
+
+
+ // Description:
+ // Set/Get the xRayAttenuation factor.
+ vtkSetMacro( XRayAttenuation, double );
+ void SetXRayAttenuationDefault()
+ { this->SetXRayAttenuation(1.0); }
+ vtkGetMacro( XRayAttenuation, double );
+
+ // Description:
+ // Set/Get the xRayThreshold factor.
+ vtkSetMacro( XRayThreshold, double );
+ void SetXRayThresholdDefault()
+ { this->SetXRayThreshold(0.5); }
+ vtkGetMacro( XRayThreshold, double );
+
+//BTX
+
+ // Description:
+ // WARNING: INTERNAL METHOD - NOT INTENDED FOR GENERAL USE
+ // DO NOT USE THIS METHOD OUTSIDE OF THE RENDERING PROCESS
+ // Render the volume
+
+ // Description:
+ // WARNING: INTERNAL METHOD - NOT INTENDED FOR GENERAL USE
+ // DO NOT USE THIS METHOD OUTSIDE OF THE RENDERING PROCESS
+ // Render the volume
+
+ virtual void Render(vtkRenderer *ren, vtkVolume *vol);
+
+
+ void RenderQuads( int count, float *v, float *t,
+ unsigned char *texture, int size[2], int reverseFlag);
+
+
+ // Description:
+ // Made public only for access from the templated method. Not a vtkGetMacro
+ // to avoid the PrintSelf defect.
+ int GetInternalSkipFactor() {return this->InternalSkipFactor;};
+
+ int *GetAxisTextureSize() {return &(this->AxisTextureSize[0][0]);};
+
+ int GetSaveTextures() {return this->SaveTextures;};
+
+ unsigned char *GetTexture() {return this->Texture;};
+
+//ETX
+
+
+protected:
+ vtkMitkOpenglXRAYVolumeTextureMapper2D();
+ ~vtkMitkOpenglXRAYVolumeTextureMapper2D();
+
+ void InitializeRender( vtkRenderer *ren, vtkVolume *vol )
+ {this->InitializeRender( ren, vol, -1 );}
+
+ void InitializeRender( vtkRenderer *ren, vtkVolume *vol, int majorDirection );
+
+ void GenerateTexturesAndRenderQuads( vtkRenderer *ren, vtkVolume *vol );
+
+ int MajorDirection;
+ int TargetTextureSize[2];
+
+ int MaximumNumberOfPlanes;
+ int InternalSkipFactor;
+ int MaximumStorageSize;
+
+ double XRayAttenuation;
+ double XRayThreshold;
+
+ unsigned char *Texture;
+ int TextureSize;
+ int SaveTextures;
+ vtkTimeStamp TextureMTime;
+
+ int AxisTextureSize[3][3];
+ void ComputeAxisTextureSize( int axis, int *size );
+
+ void RenderSavedTexture();
+
+private:
+ vtkMitkOpenglXRAYVolumeTextureMapper2D(const vtkMitkOpenglXRAYVolumeTextureMapper2D&); // Not implemented.
+ void operator=(const vtkMitkOpenglXRAYVolumeTextureMapper2D&); // Not implemented.
+};
+
+
+#endif
+
+
Property changes on: Modules\MitkExt\Rendering\vtkMitkOpenglXRAYVolumeTextureMapper2D.h
___________________________________________________________________
Added: svn:eol-style
+ native
Index: Core/Code/DataManagement/mitkTransferFunction.cpp
===================================================================
--- Core/Code/DataManagement/mitkTransferFunction.cpp (revision 21081)
+++ Core/Code/DataManagement/mitkTransferFunction.cpp (working copy)
@@ -32,6 +32,9 @@
m_ScalarOpacityFunction = vtkPiecewiseFunction::New();
m_ColorTransferFunction = vtkColorTransferFunction::New();
m_GradientOpacityFunction = vtkPiecewiseFunction::New();
+
+ m_TF_XR_VRthreshold=0.5; //default threshold
+ m_Mode=-1; //unknown mode
m_ScalarOpacityFunction->Initialize();
m_ScalarOpacityFunction->AddPoint(0,1);
@@ -106,6 +109,16 @@
return true;
}
+void mitk::TransferFunction::SetXRVRThreshold(double thr)
+{
+ if((thr>=0.1)&&(thr<=0.9))
+ m_TF_XR_VRthreshold=thr;
+}
+
+double mitk::TransferFunction::GetXRVRThreshold()
+{
+ return m_TF_XR_VRthreshold;
+}
void TransferFunction::SetScalarOpacityPoints(TransferFunction::ControlPoints points)
{
@@ -300,20 +313,14 @@
m_Max = (int)GetHistogram()->GetBinMax(0, GetHistogram()->Size()-1);
}
-void TransferFunction::SetTransferFunctionMode( int mode )
+int mitk::TransferFunction::GetTransferFunctionMode( )
{
- //Define Transfer Function
- enum TransferFunctionMode{
- TF_CT_DEFAULT,
- TF_CT_BLACK_WHITE,
- TF_CT_THORAX_LARGE,
- TF_CT_THORAX_SMALL,
- TF_CT_BONE,
- TF_CT_BONE_GRADIENT,
- TF_CT_CARDIAC,
- TF_MR_GENERIC
- };
+ return m_Mode;
+}
+void TransferFunction::SetTransferFunctionMode( int mode )
+{
+ m_Mode=mode;
//remove all old points
m_ScalarOpacityFunction->RemoveAllPoints();
m_ColorTransferFunction->RemoveAllPoints();
@@ -550,7 +557,54 @@
m_GradientOpacityFunction->AddPoint( 255, 1);
break;
+
+ case ( TF_MR_MIP ):
+ //Set Opacity
+ m_ScalarOpacityFunction->Initialize();
+ m_ScalarOpacityFunction->AddPoint( 0, 0 );
+ m_ScalarOpacityFunction->AddPoint( 98.3725, 0 );
+ m_ScalarOpacityFunction->AddPoint( 416.637, 1 );
+ m_ScalarOpacityFunction->AddPoint( 2800, 0 );
+
+ //Set Color
+ m_ColorTransferFunction->RemoveAllPoints();
+ m_ColorTransferFunction->AddRGBPoint( 0, 1, 1, 1 );
+ m_ColorTransferFunction->AddRGBPoint( 98.3725, 1, 1, 1 );
+ m_ColorTransferFunction->AddRGBPoint( 416.637, 1, 1, 1 );
+ m_ColorTransferFunction->AddRGBPoint( 2800, 1, 1, 1 );
+
+ //Set Gradient
+ m_GradientOpacityFunction->Initialize();
+ m_GradientOpacityFunction->AddPoint( 0, 1 );
+ m_GradientOpacityFunction->AddPoint( 255, 1 );
+
+ break;
+
+ case (TF_XR_VR):
+ //Set Opacity
+ m_ScalarOpacityFunction->Initialize();
+ m_ScalarOpacityFunction->AddPoint(m_Min,0.0);
+ m_ScalarOpacityFunction->AddPoint(m_Max,1.0);
+
+ double x0;
+ x0= m_Min+(m_TF_XR_VRthreshold* (m_Max-m_Min));
+ m_ScalarOpacityFunction->AddPoint(x0,0.0,0.5, 0);
+ m_ScalarOpacityFunction->AddPoint(x0+1,(x0+1-m_Min)/(m_Max-m_Min), 0.5, 0);
+
+
+ //Set Color
+ m_ColorTransferFunction->RemoveAllPoints();
+ m_ColorTransferFunction->AddRGBPoint(m_Min, 0, 0, 0);
+ m_ColorTransferFunction->AddRGBPoint(m_Max, 1, 1, 1);
+
+ //Set Gradient
+ m_GradientOpacityFunction->Initialize();
+ m_GradientOpacityFunction->AddPoint( 0, 1, 0.5, 0 );
+ m_GradientOpacityFunction->AddPoint( 255, 1, 0.5, 0);
+ std::cout << "TF_XR_VR added" << std::endl;
+ break;
+
default:
Index: Core/Code/DataManagement/mitkTransferFunction.h
===================================================================
--- Core/Code/DataManagement/mitkTransferFunction.h (revision 21081)
+++ Core/Code/DataManagement/mitkTransferFunction.h (working copy)
@@ -55,6 +55,19 @@
typedef std::vector<std::pair<double, double> > ControlPoints;
typedef std::vector<std::pair<double, itk::RGBPixel<double> > > RGBControlPoints;
+
+ enum TransferFunctionMode{
+ TF_CT_DEFAULT,
+ TF_CT_BLACK_WHITE,
+ TF_CT_THORAX_LARGE,
+ TF_CT_THORAX_SMALL,
+ TF_CT_BONE,
+ TF_CT_BONE_GRADIENT,
+ TF_CT_CARDIAC,
+ TF_MR_GENERIC,
+ TF_MR_MIP,
+ TF_XR_VR,
+ };
mitkClassMacro(TransferFunction, itk::DataObject);
@@ -156,7 +169,15 @@
void ClearRGBPoints();
bool operator==(Self& other);
-
+
+ //! Return the current mode
+ int GetTransferFunctionMode( );
+
+ //! Set Threshold for TF_XR_VR mode (thr must be in the [0.1..0.9] range)
+ void SetXRVRThreshold( double thr );
+
+ //! Get Threshold for TF_XR_VR mode (thr is in the [0.1..0.9] range)
+ double GetXRVRThreshold( );
protected:
TransferFunction();
@@ -190,6 +211,9 @@
/** Temporary STL style copy of VTK internal control points */
TransferFunction::RGBControlPoints m_RGBPoints;
+ double m_TF_XR_VRthreshold;
+ int m_Mode; //current mode
+
};
}
Index: Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.cpp
===================================================================
--- Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.cpp (revision 21149)
+++ Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.cpp (working copy)
@@ -56,6 +56,7 @@
#include <vtkImplicitPlaneWidget.h>
#include <vtkAssembly.h>
#include <vtkFixedPointVolumeRayCastMapper.h>
+#include <vtkMitkOpenglXRAYVolumeTextureMapper2D.h>
#include <vtkCubeSource.h>
#include <vtkPolyDataMapper.h>
@@ -179,6 +180,12 @@
m_UnitSpacingImageFilter->SetOutputSpacing( 1.0, 1.0, 1.0 );
CreateDefaultTransferFunctions();
+
+ m_XR_T2DMapper = vtkMitkOpenglXRAYVolumeTextureMapper2D::New();
+ m_ImageCast = vtkImageShiftScale::New();
+ m_ImageCast->SetOutputScalarTypeToUnsignedShort();
+ m_ImageCast->ClampOverflowOn();
+ m_XR_T2DMapper->SetInput( this->m_UnitSpacingImageFilter->GetOutput() );
gpuInitialized=cpuInitialized=false;
@@ -200,6 +207,9 @@
m_BinaryColorTransferFunction->Delete();
m_BinaryOpacityTransferFunction->Delete();
m_BinaryGradientTransferFunction->Delete();
+
+ m_XR_T2DMapper->Delete();
+ m_ImageCast->Delete();
}
vtkProp *mitk::GPUVolumeMapper3D::GetVtkProp(mitk::BaseRenderer *renderer)
@@ -302,6 +312,41 @@
m_MapperGPU->SetSampleDistance(1.0);
}
+ bool isXRayVolumeRendering = false;
+ if ( dynamic_cast<mitk::BoolProperty*>(GetDataTreeNode()->GetProperty("xrayvolumerendering",renderer))!=NULL &&
+ dynamic_cast<mitk::BoolProperty*>(GetDataTreeNode()->GetProperty("xrayvolumerendering",renderer))->GetValue() == true
+ )
+ {
+ isXRayVolumeRendering = true;
+ m_VolumeGPU->SetMapper(m_XR_T2DMapper);
+
+ mitk::DoubleProperty* xRayAttenuationProperty=dynamic_cast<mitk::DoubleProperty*>(GetDataTreeNode()->GetProperty("xrayattenuation",renderer));
+ if(xRayAttenuationProperty==NULL)
+ {
+ xRayAttenuationProperty = mitk::DoubleProperty::New(m_XR_T2DMapper->GetXRayAttenuation());
+ GetDataTreeNode()->SetProperty("xrayattenuation",xRayAttenuationProperty,renderer);
+
+ }
+ mitk::DoubleProperty* xRayTFThresholdProperty=dynamic_cast<mitk::DoubleProperty*>(GetDataTreeNode()->GetProperty("xraythreshold",renderer));
+ if(xRayTFThresholdProperty==NULL)
+ {
+ xRayTFThresholdProperty = mitk::DoubleProperty::New(m_XR_T2DMapper->GetXRayThreshold());
+ GetDataTreeNode()->SetProperty("xraythreshold",xRayTFThresholdProperty,renderer);
+ }
+ m_XR_T2DMapper->SetXRayAttenuation(xRayAttenuationProperty->GetValue());
+ m_XR_T2DMapper->SetXRayThreshold(xRayTFThresholdProperty->GetValue());
+ }
+ else
+ {
+ mitk::BoolProperty* xRayVolProperty=dynamic_cast<mitk::BoolProperty*>(GetDataTreeNode()->GetProperty("xrayvolumerendering",renderer));
+ if(xRayVolProperty==NULL)
+ {
+ xRayVolProperty = mitk::BoolProperty::New(false);
+ GetDataTreeNode()->SetProperty("xrayvolumerendering",xRayVolProperty,renderer);
+ }
+ m_VolumeGPU->SetMapper(m_MapperGPU);
+ }
+
int timestep=0;
ScalarType time = worldgeometry->GetTimeBounds()[0];
if (time> ScalarTypeNumericTraits::NonpositiveMin())
@@ -314,7 +359,13 @@
if(inputData==NULL)
return;
- m_UnitSpacingImageFilter->SetInput( inputData );
+ if(isXRayVolumeRendering)
+ {
+ m_ImageCast->SetInput( inputData );
+ m_UnitSpacingImageFilter->SetInput(m_ImageCast->GetOutput());
+ }
+ else
+ m_UnitSpacingImageFilter->SetInput( inputData );
UpdateTransferFunctions( renderer );
@@ -390,6 +441,41 @@
m_MapperCPU->SetSampleDistance(1.0);
}
+ bool isXRayVolumeRendering =false;
+ if ( dynamic_cast<mitk::BoolProperty*>(GetDataTreeNode()->GetProperty("xrayvolumerendering",renderer))!=NULL &&
+ dynamic_cast<mitk::BoolProperty*>(GetDataTreeNode()->GetProperty("xrayvolumerendering",renderer))->GetValue() == true
+ )
+ {
+ isXRayVolumeRendering = true;
+ m_VolumeCPU->SetMapper(m_XR_T2DMapper);
+
+ mitk::DoubleProperty* xRayAttenuationProperty=dynamic_cast<mitk::DoubleProperty*>(GetDataTreeNode()->GetProperty("xrayattenuation",renderer));
+ if(xRayAttenuationProperty==NULL)
+ {
+ xRayAttenuationProperty = mitk::DoubleProperty::New(m_XR_T2DMapper->GetXRayAttenuation());
+ GetDataTreeNode()->SetProperty("xrayattenuation",xRayAttenuationProperty,renderer);
+
+ }
+ mitk::DoubleProperty* xRayTFThresholdProperty=dynamic_cast<mitk::DoubleProperty*>(GetDataTreeNode()->GetProperty("xraythreshold",renderer));
+ if(xRayTFThresholdProperty==NULL)
+ {
+ xRayTFThresholdProperty = mitk::DoubleProperty::New(m_XR_T2DMapper->GetXRayThreshold());
+ GetDataTreeNode()->SetProperty("xraythreshold",xRayTFThresholdProperty,renderer);
+ }
+ m_XR_T2DMapper->SetXRayAttenuation(xRayAttenuationProperty->GetValue());
+ m_XR_T2DMapper->SetXRayThreshold(xRayTFThresholdProperty->GetValue());
+ }
+ else
+ {
+ mitk::BoolProperty* xRayVolProperty=dynamic_cast<mitk::BoolProperty*>(GetDataTreeNode()->GetProperty("xrayvolumerendering",renderer));
+ if(xRayVolProperty==NULL)
+ {
+ xRayVolProperty = mitk::BoolProperty::New(false);
+ GetDataTreeNode()->SetProperty("xrayvolumerendering",xRayVolProperty,renderer);
+ }
+ m_VolumeCPU->SetMapper(m_MapperCPU);
+ }
+
int timestep=0;
ScalarType time = worldgeometry->GetTimeBounds()[0];
if (time> ScalarTypeNumericTraits::NonpositiveMin())
@@ -402,7 +488,13 @@
if(inputData==NULL)
return;
- m_UnitSpacingImageFilter->SetInput( inputData );
+ if(isXRayVolumeRendering)
+ {
+ m_ImageCast->SetInput( inputData );
+ m_UnitSpacingImageFilter->SetInput(m_ImageCast->GetOutput());
+ }
+ else
+ m_UnitSpacingImageFilter->SetInput( inputData );
UpdateTransferFunctions( renderer );
Index: Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.h
===================================================================
--- Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.h (revision 21149)
+++ Modules/MitkExt/Rendering/mitkGPUVolumeMapper3D.h (working copy)
@@ -49,6 +49,7 @@
class vtkPolyDataMapper;
class vtkActor;
+class vtkMitkOpenglXRAYVolumeTextureMapper2D;
namespace mitk {
@@ -108,7 +109,9 @@
vtkMitkVolumeTextureMapper3D* m_MapperGPU;
vtkFixedPointVolumeRayCastMapper* m_MapperCPU;
-
+ vtkMitkOpenglXRAYVolumeTextureMapper2D* m_XR_T2DMapper;
+ vtkImageShiftScale* m_ImageCast;
+
vtkVolume * m_VolumeGPU;
vtkVolume * m_VolumeCPU;

File Metadata

Mime Type
text/plain
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
427
Default Alt Text
bug3266.diff (55 KB)