Commit c02b744a authored by David Gobbi's avatar David Gobbi Committed by Kitware Robot
Browse files

Merge topic 'reslice-mapper-faster'

158d5346 ENH: Add timestamp check on quality adjustment.
118cf7e4 ENH: Consolidate ResliceMapper OpenGL code into SliceMapper.
a8976cc0 BUG: Need to propagate AllocatedRenderTime to children.
parents c19b7b96 158d5346
......@@ -253,7 +253,6 @@ SET( KitOpenGL_SRCS
vtkOpenGLGlyph3DMapper.cxx
vtkOpenGLHardwareSupport.cxx
vtkOpenGLImageMapper.cxx
vtkOpenGLImageResliceMapper.cxx
vtkOpenGLImageSliceMapper.cxx
vtkOpenGLLight.cxx
vtkOpenGLLightingPainter.cxx
......@@ -714,7 +713,6 @@ IF (VTK_USE_MANGLED_MESA)
vtkMesaCoincidentTopologyResolutionPainter.cxx
vtkMesaDisplayListPainter.cxx
vtkMesaImageMapper.cxx
vtkMesaImageResliceMapper.cxx
vtkMesaImageSliceMapper.cxx
vtkMesaLight.cxx
vtkMesaLightingPainter.cxx
......
......@@ -27,7 +27,6 @@
#include "vtkOpenGLCoincidentTopologyResolutionPainter.h"
#include "vtkOpenGLDisplayListPainter.h"
#include "vtkOpenGLGlyph3DMapper.h"
#include "vtkOpenGLImageResliceMapper.h"
#include "vtkOpenGLImageSliceMapper.h"
#include "vtkOpenGLLight.h"
#include "vtkOpenGLLightingPainter.h"
......@@ -82,7 +81,6 @@
#include "vtkMesaClipPlanesPainter.h"
#include "vtkMesaCoincidentTopologyResolutionPainter.h"
#include "vtkMesaDisplayListPainter.h"
#include "vtkMesaImageResliceMapper.h"
#include "vtkMesaImageSliceMapper.h"
#include "vtkMesaLight.h"
#include "vtkMesaLightingPainter.h"
......@@ -304,16 +302,6 @@ vtkObject* vtkGraphicsFactory::CreateInstance(const char* vtkclassname )
#endif
return vtkOpenGLCamera::New();
}
if(strcmp(vtkclassname, "vtkImageResliceMapper") == 0)
{
#if defined(VTK_USE_MANGLED_MESA)
if ( vtkGraphicsFactory::UseMesaClasses )
{
return vtkMesaImageResliceMapper::New();
}
#endif
return vtkOpenGLImageResliceMapper::New();
}
if(strcmp(vtkclassname, "vtkImageSliceMapper") == 0)
{
#if defined(VTK_USE_MANGLED_MESA)
......
......@@ -284,10 +284,6 @@ vtkMatrix4x4 *vtkImageMapper3D::GetDataToWorldMatrix()
this->DataToWorldMatrix->DeepCopy(mat);
}
}
else
{
this->DataToWorldMatrix->Identity();
}
return this->DataToWorldMatrix;
}
......@@ -295,7 +291,7 @@ vtkMatrix4x4 *vtkImageMapper3D::GetDataToWorldMatrix()
//----------------------------------------------------------------------------
// Subdivide the image until the pieces fit into texture memory
void vtkImageMapper3D::RecursiveRenderTexturedPolygon(
vtkRenderer *ren, vtkProp3D *prop, vtkImageProperty *property,
vtkRenderer *ren, vtkImageProperty *property,
vtkImageData *input, int extent[6], bool recursive)
{
int xdim, ydim;
......@@ -311,7 +307,7 @@ void vtkImageMapper3D::RecursiveRenderTexturedPolygon(
{
// We can fit it - render
this->RenderTexturedPolygon(
ren, prop, property, input, extent, recursive);
ren, property, input, extent, recursive);
}
// If the texture does not fit, then subdivide and render
......@@ -341,19 +337,18 @@ void vtkImageMapper3D::RecursiveRenderTexturedPolygon(
subExtent[idx*2] = extent[idx*2];
subExtent[idx*2 + 1] = extent[idx*2] + tsize - 1;
this->RecursiveRenderTexturedPolygon(
ren, prop, property, input, subExtent, true);
ren, property, input, subExtent, true);
subExtent[idx*2] = subExtent[idx*2] + tsize;
subExtent[idx*2 + 1] = extent[idx*2 + 1];
this->RecursiveRenderTexturedPolygon(
ren, prop, property, input, subExtent, true);
ren, property, input, subExtent, true);
}
}
//----------------------------------------------------------------------------
void vtkImageMapper3D::RenderTexturedPolygon(
vtkRenderer *, vtkProp3D *, vtkImageProperty *,
vtkImageData *, int [6], bool)
vtkRenderer *, vtkImageProperty *, vtkImageData *, int [6], bool)
{
// implemented in subclasses
}
......@@ -965,9 +960,6 @@ unsigned char *vtkImageMapper3D::MakeTextureData(
this->ComputeTextureSize(
extent, xdim, ydim, imageSize, textureSize);
// will be set if the extent represents contiguous memory
bool contiguous = false;
// number of components
int numComp = input->GetNumberOfScalarComponents();
int scalarType = input->GetScalarType();
......@@ -1031,7 +1023,6 @@ unsigned char *vtkImageMapper3D::MakeTextureData(
(xdim == 0 && ydim == 2 && dataExtent[2] == dataExtent[3] &&
extent[0] == dataExtent[0] && extent[1] == dataExtent[1]) )
{
contiguous = true;
// if contiguous and correct data type, use data as-is
if (inputIsColors && reuseData)
{
......
......@@ -31,6 +31,7 @@
class vtkRenderer;
class vtkProp3D;
class vtkPoints;
class vtkMatrix4x4;
class vtkLookupTable;
class vtkScalarsToColors;
......@@ -175,7 +176,7 @@ protected:
// Description:
// Called by RecursiveRenderTexturedPolygon, overriden by subclasses.
virtual void RenderTexturedPolygon(
vtkRenderer *ren, vtkProp3D *prop, vtkImageProperty *property,
vtkRenderer *ren, vtkImageProperty *property,
vtkImageData *image, int extent[6], bool recursive);
// Description:
......@@ -183,7 +184,7 @@ protected:
// as many times as necessary if the texture must be broken up into
// pieces that are small enough for the GPU to render
virtual void RecursiveRenderTexturedPolygon(
vtkRenderer *ren, vtkProp3D *prop, vtkImageProperty *property,
vtkRenderer *ren, vtkImageProperty *property,
vtkImageData *image, int extent[6], bool recursive);
// Description:
......
......@@ -14,6 +14,7 @@
=========================================================================*/
#include "vtkImageResliceMapper.h"
#include "vtkImageSliceMapper.h"
#include "vtkRenderer.h"
#include "vtkCamera.h"
#include "vtkImageSlice.h"
......@@ -21,6 +22,7 @@
#include "vtkImageProperty.h"
#include "vtkLookupTable.h"
#include "vtkMath.h"
#include "vtkPoints.h"
#include "vtkMatrix4x4.h"
#include "vtkAbstractTransform.h"
#include "vtkPlane.h"
......@@ -29,23 +31,14 @@
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkImageResliceToColors.h"
#include "vtkGraphicsFactory.h"
#include "vtkObjectFactory.h"
//----------------------------------------------------------------------------
// Needed when we don't use the vtkStandardNewMacro.
vtkInstantiatorNewMacro(vtkImageResliceMapper);
//----------------------------------------------------------------------------
vtkImageResliceMapper* vtkImageResliceMapper::New()
{
// First try to create the object from the vtkObjectFactory
vtkObject* ret = vtkGraphicsFactory::CreateInstance("vtkImageResliceMapper");
return static_cast<vtkImageResliceMapper *>(ret);
}
vtkStandardNewMacro(vtkImageResliceMapper);
//----------------------------------------------------------------------------
vtkImageResliceMapper::vtkImageResliceMapper()
{
this->SliceMapper = vtkImageSliceMapper::New();
this->ImageReslice = vtkImageResliceToColors::New();
this->ResliceMatrix = vtkMatrix4x4::New();
this->WorldToDataMatrix = vtkMatrix4x4::New();
......@@ -59,6 +52,10 @@ vtkImageResliceMapper::vtkImageResliceMapper()
//----------------------------------------------------------------------------
vtkImageResliceMapper::~vtkImageResliceMapper()
{
if (this->SliceMapper)
{
this->SliceMapper->Delete();
}
if (this->ImageReslice)
{
this->ImageReslice->Delete();
......@@ -102,9 +99,9 @@ void vtkImageResliceMapper::SetSlicePlane(vtkPlane *plane)
}
//----------------------------------------------------------------------------
void vtkImageResliceMapper::ReleaseGraphicsResources(vtkWindow *)
void vtkImageResliceMapper::ReleaseGraphicsResources(vtkWindow *win)
{
// see OpenGL subclass for implementation
this->SliceMapper->ReleaseGraphicsResources(win);
}
//----------------------------------------------------------------------------
......@@ -123,7 +120,8 @@ void vtkImageResliceMapper::Render(vtkRenderer *ren, vtkImageSlice *prop)
int *isize = this->GetInput()->GetDimensions();
int maxisize = (isize[0] > isize[1] ? isize[0] : isize[1]);
maxisize = (isize[2] > maxisize ? isize[2] : maxisize);
if (maxisize <= maxrsize && maxisize <= 1024)
if (maxisize <= maxrsize && maxisize <= 1024 &&
prop->GetRedrawMTime() > this->SliceMapper->LoadTime)
{
this->InternalResampleToScreenPixels =
(prop->GetAllocatedRenderTime() >= 1.0);
......@@ -144,6 +142,36 @@ void vtkImageResliceMapper::Render(vtkRenderer *ren, vtkImageSlice *prop)
// update anything related to the image coloring
this->UpdateColorInformation(property);
// perform the reslicing
this->ImageReslice->SetInput(this->GetInput());
this->ImageReslice->UpdateWholeExtent();
// apply checkerboard pattern (should have timestamps)
if (property && property->GetCheckerboard())
{
this->CheckerboardImage(this->ImageReslice->GetOutput(),
ren->GetActiveCamera(), property);
}
// everything else is delegated
this->SliceMapper->SetInput(this->ImageReslice->GetOutput());
this->SliceMapper->GetDataToWorldMatrix()->DeepCopy(
this->SliceToWorldMatrix);
this->SliceMapper->SetSliceFacesCamera(this->SliceFacesCamera);
this->SliceMapper->SetExactPixelMatch(this->InternalResampleToScreenPixels);
this->SliceMapper->SetBorder( (this->Border ||
this->InternalResampleToScreenPixels) );
this->SliceMapper->SetPassColorData(true);
this->SliceMapper->SetDisplayExtent(this->ImageReslice->GetOutputExtent());
// render pass info for members of vtkImageStack
this->SliceMapper->MatteEnable = this->MatteEnable;
this->SliceMapper->ColorEnable = this->ColorEnable;
this->SliceMapper->DepthEnable = this->DepthEnable;
// let vtkImageSliceMapper do the rest of the work
this->SliceMapper->Render(ren, prop);
}
//----------------------------------------------------------------------------
......@@ -591,24 +619,27 @@ void vtkImageResliceMapper::UpdateResliceInformation(vtkRenderer *ren)
double ymin = VTK_DOUBLE_MAX;
double ymax = -VTK_DOUBLE_MAX;
for (int k = 0; k < this->NCoords; k++)
vtkPoints *points = this->SliceMapper->GetPoints();
vtkIdType n = points->GetNumberOfPoints();
if (n == 0)
{
if (this->Coords[3*k + 0] < xmin)
{
xmin = this->Coords[3*k + 0];
}
if (this->Coords[3*k + 0] > xmax)
{
xmax = this->Coords[3*k + 0];
}
if (this->Coords[3*k + 1] < ymin)
{
ymin = this->Coords[3*k + 1];
}
if (this->Coords[3*k + 1] > ymax)
{
ymax = this->Coords[3*k + 1];
}
double inputOrigin[3];
this->GetInput()->GetOrigin(inputOrigin);
xmin = inputOrigin[0];
xmax = inputOrigin[0];
ymin = inputOrigin[1];
ymax = inputOrigin[1];
}
for (vtkIdType k = 0; k < n; k++)
{
double point[3];
points->GetPoint(k, point);
xmin = ((xmin < point[0]) ? xmin : point[0]);
xmax = ((xmax > point[0]) ? xmax : point[0]);
ymin = ((ymin < point[1]) ? ymin : point[1]);
ymax = ((ymax > point[1]) ? ymax : point[1]);
}
double tol = 7.62939453125e-06;
......@@ -911,8 +942,7 @@ void vtkImageResliceMapper::UpdatePolygonCoords(vtkRenderer *ren)
"6 points, please report a bug!");
}
double *coords = this->Coords;
this->NCoords = n;
double coords[18];
if (n > 0)
{
......@@ -947,36 +977,20 @@ void vtkImageResliceMapper::UpdatePolygonCoords(vtkRenderer *ren)
coords[kk3+2] = z;
}
}
}
//----------------------------------------------------------------------------
// Compute the texture coordinates for the cut polygon
void vtkImageResliceMapper::ComputeTCoords(
vtkImageData *input, const int extent[6], int ncoords,
const double *coords, double *tcoords)
{
// info about the texture, based on the provided extent
int xdim, ydim;
int imageSize[2];
int textureSize[2];
// compute image size and texture size from extent
this->ComputeTextureSize(
extent, xdim, ydim, imageSize, textureSize);
// now get the info about the image
double *spacing = input->GetSpacing();
double *origin = input->GetOrigin();
vtkPoints *points = this->SliceMapper->GetPoints();
if (!points)
{
points = vtkPoints::New();
points->SetDataTypeToDouble();
this->SliceMapper->SetPoints(points);
points->Delete();
}
// compute the texture coords
for (int k = 0; k < ncoords; k++)
points->SetNumberOfPoints(n);
for (int k = 0; k < n; k++)
{
int k2 = k*2;
int k3 = k*3;
tcoords[k2] = ((coords[k3] - origin[0] + 0.5*spacing[0])/
(textureSize[0]*spacing[0]));
tcoords[k2+1] = ((coords[k3+1] - origin[1] + 0.5*spacing[1])/
(textureSize[1]*spacing[1]));
points->SetPoint(k, &coords[3*k]);
}
}
......@@ -1063,4 +1077,5 @@ void vtkImageResliceMapper::ReportReferences(vtkGarbageCollector* collector)
// These filters share our input and are therefore involved in a
// reference loop.
vtkGarbageCollectorReport(collector, this->ImageReslice, "ImageReslice");
vtkGarbageCollectorReport(collector, this->SliceMapper, "SliceMapper");
}
......@@ -28,6 +28,7 @@
#include "vtkImageMapper3D.h"
class vtkImageSliceMapper;
class vtkRenderer;
class vtkCamera;
class vtkLookupTable;
......@@ -132,16 +133,12 @@ protected:
// Make a polygon by cutting the data bounds with a plane.
void UpdatePolygonCoords(vtkRenderer *ren);
// Description:
// Compute the texcoords for the image poly.
void ComputeTCoords(
vtkImageData *input, const int extent[6], int ncoords,
const double *coords, double *tcoords);
// Description:
// Garbage collection for reference loops.
void ReportReferences(vtkGarbageCollector*);
vtkImageSliceMapper *SliceMapper;
int AutoAdjustImageQuality; // LOD-style behavior
int ResampleToScreenPixels; // Use software interpolation only
int InternalResampleToScreenPixels; // Use software interpolation only
......@@ -151,7 +148,6 @@ protected:
vtkMatrix4x4 *SliceToWorldMatrix; // Slice to World transform matrix
double Coords[18];
double TCoords[12];
int NCoords;
private:
......
......@@ -14,6 +14,7 @@
=========================================================================*/
#include "vtkImageSliceMapper.h"
#include "vtkPoints.h"
#include "vtkMath.h"
#include "vtkMatrix4x4.h"
#include "vtkPlane.h"
......@@ -27,6 +28,8 @@
#include "vtkInformationVector.h"
#include "vtkStreamingDemandDrivenPipeline.h"
vtkCxxSetObjectMacro(vtkImageSliceMapper, Points, vtkPoints);
//----------------------------------------------------------------------------
// Needed when we don't use the vtkStandardNewMacro.
vtkInstantiatorNewMacro(vtkImageSliceMapper);
......@@ -57,6 +60,10 @@ vtkImageSliceMapper::vtkImageSliceMapper()
this->CroppingRegion[4] = 0;
this->CroppingRegion[5] = 0;
this->Points = NULL;
this->ExactPixelMatch = false;
this->PassColorData = false;
// streaming misbehaves if there is no output port
this->SetNumberOfOutputPorts(1);
}
......@@ -64,6 +71,10 @@ vtkImageSliceMapper::vtkImageSliceMapper()
//----------------------------------------------------------------------------
vtkImageSliceMapper::~vtkImageSliceMapper()
{
if (this->Points)
{
this->Points->Delete();
}
}
//----------------------------------------------------------------------------
......@@ -228,6 +239,7 @@ void vtkImageSliceMapper::PrintSelf(ostream& os, vtkIndent indent)
<< this->CroppingRegion[0] << " " << this->CroppingRegion[1] << " "
<< this->CroppingRegion[2] << " " << this->CroppingRegion[3] << " "
<< this->CroppingRegion[4] << " " << this->CroppingRegion[5] << "\n";
os << indent << "Points: " << this->Points << "\n";
}
//----------------------------------------------------------------------------
......
......@@ -30,6 +30,7 @@
#include "vtkImageMapper3D.h"
class vtkCamera;
class vtkPoints;
class VTK_RENDERING_EXPORT vtkImageSliceMapper : public vtkImageMapper3D
{
......@@ -110,6 +111,35 @@ protected:
vtkImageSliceMapper();
~vtkImageSliceMapper();
// Description:
// Set points that describe a polygon on which the slice will
// be rendered.
void SetPoints(vtkPoints *points);
vtkPoints *GetPoints() { return this->Points; }
// Description:
// Force linear interpolation. Internal method, for when this
// mapper is used as a helper class.
void SetExactPixelMatch(int v) {
this->ExactPixelMatch = (v != 0); }
// Description:
// Pass color data. Internal method, for when this mapper is
// used as a helper class.
void SetPassColorData(int v) {
this->PassColorData = (v != 0); }
// Description:
// Set the display extent. Internal method, for when this mapper
// is used as a helper class.
void SetDisplayExtent(int extent[6]) {
this->DisplayExtent[0] = extent[0];
this->DisplayExtent[1] = extent[1];
this->DisplayExtent[2] = extent[2];
this->DisplayExtent[3] = extent[3];
this->DisplayExtent[4] = extent[4];
this->DisplayExtent[5] = extent[5]; }
// Description:
// Get the camera orientation as a simple integer [0,1,2,3,4,5]
// that indicates one of the six major directions. The integers
......@@ -127,9 +157,10 @@ protected:
// Description:
// Do a checkerboard pattern to the alpha of an RGBA image
void CheckerboardImage(
unsigned char *data, int xsize, int ysize,
const double imageSpacing[3], vtkImageProperty *property);
unsigned char *data, int xsize, int ysize,
const double imageSpacing[3], vtkImageProperty *property);
vtkTimeStamp LoadTime;
int SliceNumber;
int SliceNumberMinValue;
int SliceNumberMaxValue;
......@@ -137,10 +168,15 @@ protected:
int Cropping;
int CroppingRegion[6];
int DisplayExtent[6];
int ExactPixelMatch;
int PassColorData;
vtkPoints *Points;
private:
vtkImageSliceMapper(const vtkImageSliceMapper&); // Not implemented.
void operator=(const vtkImageSliceMapper&); // Not implemented.
friend class vtkImageResliceMapper;
};
#endif
......@@ -280,12 +280,15 @@ int vtkImageStack::RenderOpaqueGeometry(vtkViewport* viewport)
int rendered = 0;
vtkImageSlice *image = 0;
vtkCollectionSimpleIterator pit;
vtkIdType n = this->Images->GetNumberOfItems();
double renderTime = this->AllocatedRenderTime/(n + (n == 0));
if (this->Images->GetNumberOfItems() == 1)
if (n == 1)
{
// no multi-pass if only one image
this->Images->InitTraversal(pit);
image = this->Images->GetNextImage(pit);
image->SetAllocatedRenderTime(renderTime, viewport);
return image->RenderOpaqueGeometry(viewport);
}
......@@ -294,6 +297,7 @@ int vtkImageStack::RenderOpaqueGeometry(vtkViewport* viewport)
this->Images->InitTraversal(pit);
while ( (image = this->Images->GetNextImage(pit)) != 0)
{
image->SetAllocatedRenderTime(renderTime, viewport);
image->SetStackedImagePass(pass);
rendered |= image->RenderOpaqueGeometry(viewport);
image->SetStackedImagePass(-1);
......@@ -321,11 +325,14 @@ int vtkImageStack::RenderTranslucentPolygonalGeometry(vtkViewport* viewport)
int rendered = 0;
vtkImageSlice *image = 0;
vtkCollectionSimpleIterator pit;
vtkIdType n = this->Images->GetNumberOfItems();
double renderTime = this->AllocatedRenderTime/(n + (n == 0));
if (this->Images->GetNumberOfItems() == 1)
if (n == 1)
{
// no multi-pass if only one image
this->Images->InitTraversal(pit);
image->SetAllocatedRenderTime(renderTime, viewport);
image = this->Images->GetNextImage(pit);
return image->RenderTranslucentPolygonalGeometry(viewport);
}
......@@ -335,6 +342,7 @@ int vtkImageStack::RenderTranslucentPolygonalGeometry(vtkViewport* viewport)
this->Images->InitTraversal(pit);
while ( (image = this->Images->GetNextImage(pit)) != 0)
{
image->SetAllocatedRenderTime(renderTime, viewport);
image->SetStackedImagePass(pass);
rendered |= image->RenderTranslucentPolygonalGeometry(viewport);
image->SetStackedImagePass(-1);
......@@ -362,11 +370,14 @@ int vtkImageStack::RenderOverlay(vtkViewport* viewport)
int rendered = 0;
vtkImageSlice *image = 0;
vtkCollectionSimpleIterator pit;
vtkIdType n = this->Images->GetNumberOfItems();
double renderTime = this->AllocatedRenderTime/(n + (n == 0));
if (this->Images->GetNumberOfItems() == 1)
if (n == 1)
{
// no multi-pass if only one image
this->Images->InitTraversal(pit);
image->SetAllocatedRenderTime(renderTime, viewport);
image = this->Images->GetNextImage(pit);
return image->RenderOverlay(viewport);
}
......@@ -376,6 +387,7 @@ int vtkImageStack::RenderOverlay(vtkViewport* viewport)
this->Images->InitTraversal(pit);
while ( (image = this->Images->GetNextImage(pit)) != 0)
{
image->SetAllocatedRenderTime(renderTime, viewport);
image->SetStackedImagePass(pass);
rendered |= image->RenderOverlay(viewport);
image->SetStackedImagePass(-1);
......
/*=========================================================================
Program: Visualization Toolkit
Module: vtkMesaImageResliceMapper.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// This keeps the New method from being defined in included cxx file.
#define VTK_IMPLEMENT_MESA_CXX
#include "MangleMesaInclude/gl_mangle.h"
#include "MangleMesaInclude/gl.h"
#include <math.h>
#include "vtkToolkits.h"
#include "vtkMesaImageResliceMapper.h"
#include "vtkMesaCamera.h"
#include "vtkMesaRenderer.h"
#include "vtkMesaRenderWindow.h"
// make sure this file is included before the #define takes place
// so we don't get two vtkMesaImageResliceMapper classes defined.
#include "vtkOpenGLImageResliceMapper.h"
#include "vtkMesaImageResliceMapper.h"