[vtkusers] Setting vtkCamera to custom modelview & volume rendering

Bud Bundy budric at gmail.com
Fri Aug 5 13:12:09 EDT 2016


Hi,

I need to setup the camera to an arbitrary modelview matrix I have in 
memory.  I managed to get some code working such that 
GetModelViewTransformMatrix() returns the modelview I have/want. However 
the volume rendering is sometimes blank, and I don't understand why 
because the volume is in front of the camera.  I managed to boil down 
the problem to the following code below. camera1 and camera2 have the 
same modelview transform, however the rendering look very different 
(I've attached a screen shot) - though not blank it's a lot dimmer.

The code is loosely based on: 
http://www.vtk.org/Wiki/VTK/Examples/Cxx/VolumeRendering/SmartVolumeMapper

I'm using VTK 7.0

#include <vtkActor.h>
#include <vtkSmartPointer.h>
#include <vtkCubeSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCamera.h>
#include <vtkSphere.h>
#include <vtkSampleFunction.h>
#include <vtkImageShiftScale.h>
#include <vtkImageData.h>
#include <vtkPointData.h>
#include <vtkSmartVolumeMapper.h>
#include <vtkPiecewiseFunction.h>
#include <vtkVolumeProperty.h>
#include <vtkColorTransferFunction.h>
#include <vtkCommand.h>
#include <vtkMatrix4x4.h>

vtkSmartPointer<vtkVolume> generateVolume()
{
     // 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->SetOutputScalarTypeToFloat();
     sampleFunction->SetSampleDimensions(64, 64, 20);
     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();

     vtkSmartPointer<vtkImageData> imageData = 
vtkSmartPointer<vtkImageData>::New();
     imageData->ShallowCopy(t->GetOutput());

     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);

     vtkSmartPointer<vtkMatrix4x4> volumeScaleTransform = 
vtkSmartPointer<vtkMatrix4x4>::New();
     volumeScaleTransform->Identity();
     volumeScaleTransform->SetElement(0, 0, 512);
     volumeScaleTransform->SetElement(1, 1, 512);
     volumeScaleTransform->SetElement(2, 2, 160);
     volume->SetUserMatrix(volumeScaleTransform);
     return volume;
}

int main()
{
     // camera1
     vtkSmartPointer<vtkCamera> camera1 = 
vtkSmartPointer<vtkCamera>::New();
     camera1->SetPosition(0, 0, 1000);
     camera1->SetFocalPoint(0, 0, 0);
     camera1->SetClippingRange(0.1, 5000);
     camera1->SetViewAngle(60);

     //camera 2
     vtkSmartPointer<vtkCamera> camera2 = 
vtkSmartPointer<vtkCamera>::New();
     camera2->SetPosition(0, 0, 0);            //I do not want any 
additional translation that comes with default (0,0,1) setting.
     camera2->SetFocalPoint(0, 0, -1);       //setting this to (0,0,0) 
causes whole modelview matrix to be 0, regardless of what 
SetModelTransformMatrix() sets
     camera2->SetViewAngle(60);
     camera2->SetClippingRange(0.1, 5000);
     double modelViewTransform[16] = { 1, 0, 0, 0,
         0, 1, 0, 0,
         0, 0, 1, -1000,
         0, 0, 0, 1 };
     camera2->SetModelTransformMatrix(modelViewTransform);

     // renderer1 using camera1
     vtkSmartPointer<vtkRenderer> renderer1 = 
vtkSmartPointer<vtkRenderer>::New();
     renderer1->SetViewport(0, 0, 0.5, 1);
     renderer1->AddVolume(generateVolume());
     renderer1->SetActiveCamera(camera1);

     // renderer2 using camera2
     vtkSmartPointer<vtkRenderer> renderer2 = 
vtkSmartPointer<vtkRenderer>::New();
     renderer2->SetViewport(0.5, 0, 1, 1);
     renderer2->AddVolume(generateVolume());
     renderer2->SetActiveCamera(camera2);

     // assert model view matrices are the same
     vtkSmartPointer<vtkMatrix4x4> vtkModelViewMatrix1 = 
renderer1->GetActiveCamera()->GetModelViewTransformMatrix();
     vtkSmartPointer<vtkMatrix4x4> vtkModelViewMatrix2 = 
renderer2->GetActiveCamera()->GetModelViewTransformMatrix();
     for (int i = 0; i < 4; ++i)
         for (int j = 0; j < 4; ++j)
             assert(vtkModelViewMatrix1->GetElement(i, j) == 
vtkModelViewMatrix2->GetElement(i, j));

     // window and interactor
     vtkSmartPointer<vtkRenderWindow> renderWindow = 
vtkSmartPointer<vtkRenderWindow>::New();
     renderWindow->SetSize(1024, 512);
     renderWindow->AddRenderer(renderer1);
     renderWindow->AddRenderer(renderer2);
     vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = 
vtkSmartPointer<vtkRenderWindowInteractor>::New();
     renderWindowInteractor->SetRenderWindow(renderWindow);

     renderWindow->Render();
     renderWindowInteractor->Start();

     return EXIT_SUCCESS;
}


Thank you very much.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: camera_problem.jpg
Type: image/jpeg
Size: 23175 bytes
Desc: not available
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20160805/d3e6c4d2/attachment.jpg>


More information about the vtkusers mailing list