Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
VTK
VTK
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 580
    • Issues 580
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge Requests 163
    • Merge Requests 163
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Incidents
    • Environments
  • Analytics
    • Analytics
    • CI / CD
    • Repository
    • Value Stream
  • Snippets
    • Snippets
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • VTK
  • VTKVTK
  • Issues
  • #17140

Closed
Open
Opened Oct 05, 2017 by B.B.@Budric

vtkCamera::SetModelTransformMatrix, SetUserViewTransform or SetUserTransform produce incorrect volume rendering

Hi,

Using vtkCamera::SetModelTransformMatrix or SetUserViewTransform or SetUserTransform does not render the volume correctly - the result appears inappropriately sheared. I have sample code based on SmartVolumeMapper example with a simple translation applied to vtkVolume, and a modelview transform I want to apply to vtkCamera. I've attached screenshots of the issues - first is the default rendering, second image is renering after using interactor to reset view and rotate with mouse.

The issue is with 8.0.1, OpenGL2 rendering backend.

I was discussing same issue against 6.3 a while ago on the user mailing lists: http://markmail.org/message/xy7r5dtyzrfmaxrl

#include <vtkVersion.h>
#include <vtkSmartPointer.h>
#include <vtkSphere.h>
#include <vtkSampleFunction.h>
#include <vtkSmartVolumeMapper.h>
#include <vtkColorTransferFunction.h>
#include <vtkPiecewiseFunction.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkVolumeProperty.h>
#include <vtkCamera.h>
#include <vtkImageShiftScale.h>
#include <vtkImageData.h>
#include <vtkPointData.h>
#include <vtkDataArray.h>
#include <vtkTransform.h>

static void CreateImageData(vtkImageData* im);

int main(int argc, char *argv[])
{
	vtkSmartPointer<vtkImageData> imageData =
		vtkSmartPointer<vtkImageData>::New();
	CreateImageData(imageData);	

	vtkSmartPointer<vtkRenderWindow> renWin =
		vtkSmartPointer<vtkRenderWindow>::New();
	vtkSmartPointer<vtkRenderer> ren1 =
		vtkSmartPointer<vtkRenderer>::New();
	ren1->SetBackground(0.1, 0.4, 0.2);

	/*
	Setup camera
	*/
	vtkSmartPointer<vtkTransform> volumeUserTransform = vtkSmartPointer<vtkTransform>::New();
	volumeUserTransform->Translate(2, 2, 0);
	vtkSmartPointer<vtkTransform> cameraModelviewTransform = vtkSmartPointer<vtkTransform>::New();
	cameraModelviewTransform->Translate(-2, -2, -10);		

	vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();				
	camera->SetModelTransformMatrix(cameraModelviewTransform->GetMatrix());	
	//camera->SetUserViewTransform(cameraModelviewTransform);					//<-- Broken but differently broken rendering from SetModelTransformMatrix
	//camera->SetUserTransform(cameraModelviewTransform);						//<-- Nothing rendered at all
	ren1->SetActiveCamera(camera);

	renWin->AddRenderer(ren1);
	renWin->SetSize(512, 512);

	vtkSmartPointer<vtkRenderWindowInteractor> iren =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	iren->SetRenderWindow(renWin);

	renWin->Render(); // make sure we have an OpenGL context.

	vtkSmartPointer<vtkSmartVolumeMapper> volumeMapper =
		vtkSmartPointer<vtkSmartVolumeMapper>::New();
	volumeMapper->SetBlendModeToComposite(); // composite first
	volumeMapper->SetInputData(imageData);
	vtkSmartPointer<vtkVolumeProperty> volumeProperty =
		vtkSmartPointer<vtkVolumeProperty>::New();
	volumeProperty->ShadeOff();
	volumeProperty->SetInterpolationType(VTK_LINEAR_INTERPOLATION);

	vtkSmartPointer<vtkPiecewiseFunction> compositeOpacity =
		vtkSmartPointer<vtkPiecewiseFunction>::New();
	compositeOpacity->AddPoint(0.0, 0.0);
	compositeOpacity->AddPoint(80.0, 1.0);
	compositeOpacity->AddPoint(80.1, 0.0);
	compositeOpacity->AddPoint(255.0, 0.0);
	volumeProperty->SetScalarOpacity(compositeOpacity); // composite first.

	vtkSmartPointer<vtkColorTransferFunction> color =
		vtkSmartPointer<vtkColorTransferFunction>::New();
	color->AddRGBPoint(0.0, 0.0, 0.0, 1.0);
	color->AddRGBPoint(40.0, 1.0, 0.0, 0.0);
	color->AddRGBPoint(255.0, 1.0, 1.0, 1.0);
	volumeProperty->SetColor(color);

	vtkSmartPointer<vtkVolume> volume =
		vtkSmartPointer<vtkVolume>::New();
	volume->SetMapper(volumeMapper);
	volume->SetProperty(volumeProperty);
	volume->SetUserTransform(volumeUserTransform);
	ren1->AddViewProp(volume);

	// Render composite. In default mode. For coverage.
	renWin->Render();
	iren->Start();

	return EXIT_SUCCESS;
}

void CreateImageData(vtkImageData* imageData)
{
	// Create a spherical implicit function.
	vtkSmartPointer<vtkSphere> sphere =
		vtkSmartPointer<vtkSphere>::New();
	sphere->SetRadius(0.1);
	sphere->SetCenter(0.0, 0.0, 0.0);

	vtkSmartPointer<vtkSampleFunction> sampleFunction =
		vtkSmartPointer<vtkSampleFunction>::New();
	sampleFunction->SetImplicitFunction(sphere);
	sampleFunction->SetOutputScalarTypeToDouble();
	sampleFunction->SetSampleDimensions(127, 127, 127); // intentional NPOT dimensions.
	sampleFunction->SetModelBounds(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
	sampleFunction->SetCapping(false);
	sampleFunction->SetComputeNormals(false);
	sampleFunction->SetScalarArrayName("values");
	sampleFunction->Update();

	vtkDataArray* a = sampleFunction->GetOutput()->GetPointData()->GetScalars("values");
	double range[2];
	a->GetRange(range);

	vtkSmartPointer<vtkImageShiftScale> t =
		vtkSmartPointer<vtkImageShiftScale>::New();
	t->SetInputConnection(sampleFunction->GetOutputPort());

	t->SetShift(-range[0]);
	double magnitude = range[1] - range[0];
	if (magnitude == 0.0)
	{
		magnitude = 1.0;
	}
	t->SetScale(255.0 / magnitude);
	t->SetOutputScalarTypeToUnsignedChar();

	t->Update();

	imageData->ShallowCopy(t->GetOutput());
}

error1 error2

Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking
None
Due date
None
Reference: vtk/vtk#17140