Commit 9a18b4cc authored by Rusty Blue's avatar Rusty Blue
Browse files

Fix issue of GetBounds() computing the wrong bounds for non-Linear user matrx

A non-trivial last row of a user matrix (or transform) (something other than
[0 0 0 1]) is used correctly by OpenGL, but the GetBounds calculation in
vtkActor (as well as vtkImageActor and vtkVolume) used
this->Transform->TransformPoint() to trasnform the bbox from the mapper.  As
this->Transform is a vtkLinearTransform, the final row of the matrix is ignored
within TransformPoint (actually vtkLinearTransform::InternalTransformPoint(),
which is what is ultimately called).  Instead, we now use
vtkMatrix4x4::MultiplyPoint() to do the transformation.

Note, this change also includes  "cleanup" of several lines before and after
the for loop where we trasnform the points (within GetBounds() fn), replacing
the, with just this->ComputeMatrix().  This is a subset of what was removed,
as it was being called by this->GetMatrix(), but also note that internally
vtkProp3D::ComputeMatrix() does a Push() and Pop() on this->Transform just
as was done in the code that was removed.  There is a potential issue (I'm
looking for an extra set of eyes, or many eyes, to scrutinize) with the
GetOrientation() call (in ComputeMatrix()), which occurs before Push() and
which might screw things up since it results in vtkTransform::InternalUpdate()
which might mess up the Concatentation if doTheLegacyHack == true.  Even if
it is a (potential) problem, moving Push() before GetOrientation() (in
ComputeMatrix()) should (I believe) rectify the potential for a problem,
though I did NOT make that change... yet (waiting for feedback)

Change-Id: I122940f1c2142d4c64502a8a54c44a4e18bdc124
parent 5e2f65e9
......@@ -29,6 +29,7 @@ IF(VTK_USE_DISPLAY)
TestGlyph3DMapperPicking.cxx
TestGPUInfo.cxx
TestGradientBackground.cxx
TestHomogeneousTransformOfActor.cxx
TestInteractorTimers.cxx
TestLabelPlacer.cxx
TestLabelPlacer2D.cxx
......
/*=========================================================================
Program: Visualization Toolkit
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.
=========================================================================*/
#include "vtkTestUtilities.h"
#include "vtkRegressionTestImage.h"
#include "vtkActor.h"
#include "vtkMatrix4x4.h"
#include "vtkPolyDataMapper.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSphereSource.h"
int TestHomogeneousTransformOfActor(int argc, char *argv[])
{
vtkSphereSource *sphere = vtkSphereSource::New();
sphere->SetThetaResolution(10);
sphere->SetPhiResolution(10);
vtkPolyDataMapper *sphereMapper = vtkPolyDataMapper::New();
sphereMapper->SetInputConnection( sphere->GetOutputPort() );
sphere->FastDelete();
vtkActor *sphereActor = vtkActor::New();
sphereActor->SetMapper(sphereMapper);
sphereMapper->FastDelete();
vtkActor *referenceSphereActor = vtkActor::New();
referenceSphereActor->SetMapper(sphereMapper);
referenceSphereActor->SetPosition(6, 0, 0);
// the crux of the test, set w to be not equal to 1
vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
matrix->SetElement(3, 3, 0.25);
sphereActor->SetUserMatrix( matrix );
matrix->FastDelete();
//Create the rendering stuff
vtkRenderer *renderer = vtkRenderer::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
renWin->AddRenderer(renderer);
renderer->FastDelete();
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
renWin->FastDelete();
renderer->AddActor(referenceSphereActor);
referenceSphereActor->Delete();
renderer->AddActor(sphereActor);
sphereActor->Delete();
renderer->SetBackground(0.5,0.5,0.5);
renWin->SetSize(450,450);
renWin->Render();
renderer->ResetCamera();
renWin->Render();
int retVal = vtkRegressionTestImage(renWin);
if ( retVal == vtkRegressionTester::DO_INTERACTOR )
{
iren->Start();
}
iren->Delete();
return !retVal;
}
......@@ -18,16 +18,15 @@
#include "vtkDataArray.h"
#include "vtkGraphicsFactory.h"
#include "vtkImageData.h"
#include "vtkLinearTransform.h"
#include "vtkMapper.h"
#include "vtkMath.h"
#include "vtkMatrix4x4.h"
#include "vtkPointData.h"
#include "vtkPropCollection.h"
#include "vtkProperty.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkTexture.h"
#include "vtkTransform.h"
#include <math.h>
......@@ -354,20 +353,21 @@ double *vtkActor::GetBounds()
bbox[18] = bounds[0]; bbox[19] = bounds[2]; bbox[20] = bounds[4];
bbox[21] = bounds[0]; bbox[22] = bounds[3]; bbox[23] = bounds[4];
// save the old transform
this->Transform->Push();
this->Transform->SetMatrix(this->GetMatrix());
// make sure matrix (transform) is up-to-date
this->ComputeMatrix();
// and transform into actors coordinates
fptr = bbox;
for (n = 0; n < 8; n++)
{
this->Transform->TransformPoint(fptr,fptr);
double homogeneousPt[4] = {fptr[0], fptr[1], fptr[2], 1.0};
this->Matrix->MultiplyPoint(homogeneousPt, homogeneousPt);
fptr[0] = homogeneousPt[0] / homogeneousPt[3];
fptr[1] = homogeneousPt[1] / homogeneousPt[3];
fptr[2] = homogeneousPt[2] / homogeneousPt[3];
fptr += 3;
}
this->Transform->Pop();
// now calc the new bounds
this->Bounds[0] = this->Bounds[2] = this->Bounds[4] = VTK_DOUBLE_MAX;
this->Bounds[1] = this->Bounds[3] = this->Bounds[5] = -VTK_DOUBLE_MAX;
......
......@@ -17,8 +17,8 @@
#include "vtkGraphicsFactory.h"
#include "vtkImageData.h"
#include "vtkMath.h"
#include "vtkMatrix4x4.h"
#include "vtkRenderer.h"
#include "vtkTransform.h"
//----------------------------------------------------------------------------
......@@ -370,20 +370,21 @@ double *vtkImageActor::GetBounds()
bbox[18] = bounds[0]; bbox[19] = bounds[2]; bbox[20] = bounds[4];
bbox[21] = bounds[0]; bbox[22] = bounds[3]; bbox[23] = bounds[4];
// save the old transform
this->Transform->Push();
this->Transform->SetMatrix(this->GetMatrix());
// make sure matrix (transform) is up-to-date
this->ComputeMatrix();
// and transform into actors coordinates
fptr = bbox;
for (n = 0; n < 8; n++)
{
this->Transform->TransformPoint(fptr,fptr);
double homogeneousPt[4] = {fptr[0], fptr[1], fptr[2], 1.0};
this->Matrix->MultiplyPoint(homogeneousPt, homogeneousPt);
fptr[0] = homogeneousPt[0] / homogeneousPt[3];
fptr[1] = homogeneousPt[1] / homogeneousPt[3];
fptr[2] = homogeneousPt[2] / homogeneousPt[3];
fptr += 3;
}
this->Transform->Pop();
// now calc the new bounds
this->Bounds[0] = this->Bounds[2] = this->Bounds[4] = VTK_DOUBLE_MAX;
this->Bounds[1] = this->Bounds[3] = this->Bounds[5] = -VTK_DOUBLE_MAX;
......
......@@ -274,20 +274,21 @@ double *vtkVolume::GetBounds()
bbox[18] = bounds[0]; bbox[19] = bounds[2]; bbox[20] = bounds[4];
bbox[21] = bounds[0]; bbox[22] = bounds[3]; bbox[23] = bounds[4];
// save the old transform
this->Transform->Push();
this->Transform->SetMatrix(this->GetMatrix());
// make sure matrix (transform) is up-to-date
this->ComputeMatrix();
// and transform into actors coordinates
fptr = bbox;
for (n = 0; n < 8; n++)
{
this->Transform->TransformPoint(fptr,fptr);
double homogeneousPt[4] = {fptr[0], fptr[1], fptr[2], 1.0};
this->Matrix->MultiplyPoint(homogeneousPt, homogeneousPt);
fptr[0] = homogeneousPt[0] / homogeneousPt[3];
fptr[1] = homogeneousPt[1] / homogeneousPt[3];
fptr[2] = homogeneousPt[2] / homogeneousPt[3];
fptr += 3;
}
this->Transform->Pop();
// now calc the new bounds
this->Bounds[0] = this->Bounds[2] = this->Bounds[4] = VTK_DOUBLE_MAX;
this->Bounds[1] = this->Bounds[3] = this->Bounds[5] = -VTK_DOUBLE_MAX;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment