Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F444
bug3266.diff
Public
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Authored By
xplanes
Jan 29 2010, 3:45 PM
2010-01-29 15:45:32 (UTC+1)
Size
55 KB
Referenced Files
None
Subscribers
None
bug3266.diff
View Options
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
Details
Attached
Mime Type
text/plain
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
427
Default Alt Text
bug3266.diff (55 KB)
Attached To
Mode
T3266: XRay rendering
Attached
Detach File
Event Timeline
xplanes
added a comment.
Jan 29 2010, 3:45 PM
2010-01-29 15:45:32 (UTC+1)
Comment Actions
Unified patch
Log In to Comment