[vtkusers] Setting vtkCamera to custom modelview & volume rendering

Bud Bundy budric at gmail.com
Tue Aug 30 11:24:48 EDT 2016


Hi Aashish,

I compiled VTK revision dbae27c5ee61cb7507d893001ae8d93a580f9e72 of the 
master branch and still the same problem with volume rendering. 
Rectangles render fine.

The worldToCamera transform applied through SetModelTransformMatrix() 
seems to deform the volume for volume rendering - yet it does not deform 
the rectangle geometry.  Does this behavior seem right or should I file 
a bug report? I'm a new user so it's entirely possible this is intended 
behavior, but to me at a glance and reading API documentaiton it doesn't 
seem right. Yet another screenshot attached.

Thanks.


On 08/29/2016 03:43 PM, Aashish Chaudhary wrote:
> Hi Bud,
>
> There was a bug that was fixed recently. Can you try the latest master 
> and see if it is fixed? If it is, you can always cherry-pick that 
> commit to 6.3 branch.
>
> - Aashish
>
> On Mon, Aug 29, 2016 at 1:46 PM Bud Bundy <budric at gmail.com 
> <mailto:budric at gmail.com>> wrote:
>
>     Sorry to bump my own thread but I still can't get this to work. 
>     For 2 identical cameras in terms of position and projection
>     transform, after adjusting the lights (or not) I get 2 different
>     renderings.
>
>     The only difference is I apply worldToCamera transform by setting
>     camera1->SetModelTransformMatrix(worldToCamera); whereas for
>     camera2 I transform the vtkVolume.  In my understanding these
>     should be identical in terms of positioning something in camera
>     coordinate system.  But the rendering is different (sample
>     attached as volume_vtk_7.0.0.jpg).
>
>     Weirdly enough if I render a cube instead of the volume, it works
>     with VTK 7.0.0 (attached actor_vtk_7.0.0.jpg). Same transform,
>     both cameras work.  However, then same code rendering the cube
>     doesn't work with 6.3.0 (attached actor_vtk_6.3.0.jpg).  Not that
>     I need to use 6.3.0.  But I'm just at my wits end on what to try.
>
>     Can someone please have a look at my code and tell me how to get
>     camera1 to render properly?  Thank you
>
>
>     #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>
>
>     #include <vtkLightCollection.h>
>     #include <vtkLight.h>
>     #include <vtkTransform.h>
>     #include <iostream>
>
>     const double objectToWorld[16] = {
>         0.976,    0,    0,        -249.511,
>         0, -0.976,    0,        249.224,
>         0,    0, -2,            -1251.5,
>         0,    0,    0,            1 };
>
>     const double worldToCamera[16] = {
>         -0.965924, 0.00168586, 0.258819,    372.757,
>         0.258819, -0.000451724, 0.965926,    1382.12,
>         0.00174533, 0.999998, 0,            16.3087,
>         0, 0, 0,                            1};
>
>     vtkSmartPointer<vtkActor> generateRectangle()
>     {
>         vtkSmartPointer<vtkCubeSource> cubeSource =
>     vtkSmartPointer<vtkCubeSource>::New();
>
>         vtkSmartPointer<vtkPolyDataMapper> mapper =
>     vtkSmartPointer<vtkPolyDataMapper>::New();
>     mapper->SetInputConnection(cubeSource->GetOutputPort());
>
>         vtkSmartPointer<vtkActor> actor =
>     vtkSmartPointer<vtkActor>::New();
>         actor->SetMapper(mapper);
>         actor->SetScale(512, 512, 160);
>         actor->SetPosition(256, 256, 80);
>         vtkSmartPointer<vtkTransform> userTransform =
>     vtkSmartPointer<vtkTransform>::New();
>         userTransform->SetMatrix(objectToWorld);
>         actor->SetUserTransform(userTransform);
>         return actor;
>
>
>     }
>
>     vtkSmartPointer<vtkVolume> generateVolume()
>     {
>         // Create a spherical implicit function.
>         vtkSmartPointer<vtkSphere> sphere =
>     vtkSmartPointer<vtkSphere>::New();
>
>         sphere->SetRadius(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);
>
>         volume->SetScale(512, 512, 160);
>         volume->SetPosition(256, 256, 80);
>
>         vtkSmartPointer<vtkTransform> userTransform =
>     vtkSmartPointer<vtkTransform>::New();
>         userTransform->SetMatrix(objectToWorld);
>         volume->SetUserTransform(userTransform);
>         return volume;
>
>
>     }
>
>     void assertArrayEquals(const double * a, const double * b, size_t
>     elements)
>     {
>         for (size_t i = 0; i < elements; ++i)
>         {
>             assert(a[i] - b[i] <= std::numeric_limits<double>::epsilon());
>         }
>     }
>
>     void assertVtkMatrixEquals(const vtkMatrix4x4 * a, const
>     vtkMatrix4x4 * b)
>     {
>         for (size_t i = 0; i < 4; ++i)
>         {
>             for (size_t j = 0; j < 4; ++j)
>             {
>                 assert(fabs(a->GetElement(i, j) - b->GetElement(i, j))
>     < std::numeric_limits<double>::epsilon());
>
>
>             }
>         }
>     }
>
>     int main()
>     {
>         // camera1
>         vtkSmartPointer<vtkCamera> camera1 =
>     vtkSmartPointer<vtkCamera>::New();
>         camera1->SetPosition(0, 0, 1000);
>         camera1->SetFocalPoint(0, 0, 0);
>
>         camera1->SetViewUp(0, 1, 0);
>
>
>         camera1->SetClippingRange(0.1, 5000);
>         camera1->SetViewAngle(60);
>
>         camera1->SetModelTransformMatrix(worldToCamera);
>
>
>
>         //camera 2
>         vtkSmartPointer<vtkCamera> camera2 =
>     vtkSmartPointer<vtkCamera>::New();
>
>         camera2->SetPosition(0, 0, 1000);
>         camera2->SetFocalPoint(0, 0, 0);
>         camera2->SetViewUp(0, 1, 0);
>         camera2->SetClippingRange(0.1, 5000);
>         camera2->SetViewAngle(60);
>
>
>
>         // renderer1 using camera1
>         vtkSmartPointer<vtkRenderer> renderer1 =
>     vtkSmartPointer<vtkRenderer>::New();
>         renderer1->SetViewport(0, 0, 0.5, 1);
>
>         renderer1->SetActiveCamera(camera1);
>         //renderer1->AddVolume(generateVolume());
>         renderer1->AddActor(generateRectangle());
>
>
>
>         // renderer2 using camera2
>         vtkSmartPointer<vtkRenderer> renderer2 =
>     vtkSmartPointer<vtkRenderer>::New();
>         renderer2->SetViewport(0.5, 0, 1, 1);
>
>         vtkSmartPointer<vtkVolume> volume2 = generateVolume();
>         vtkSmartPointer<vtkActor> rectangle2 = generateRectangle();
>         vtkSmartPointer<vtkTransform> objectToCameraTransform =
>     vtkSmartPointer<vtkTransform>::New();
>         // Generate transform (worldToCamera * objectToWorld) and
>     apply it to the model
>         objectToCameraTransform->SetMatrix(objectToWorld);
>         objectToCameraTransform->PostMultiply();
>     objectToCameraTransform->Concatenate(worldToCamera);
>         objectToCameraTransform->Update();
>         volume2->SetUserTransform(objectToCameraTransform);
>     rectangle2->SetUserTransform(objectToCameraTransform);
>         renderer2->SetActiveCamera(camera2);
>         //renderer2->AddVolume(volume2);
>         renderer2->AddActor(rectangle2);
>
>
>
>         // 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);
>
>         // Attempt to Adjust lights
>         renderWindow->Render();
>         vtkLight * modifiedLight = dynamic_cast<vtkLight
>     *>(renderer1->GetLights()->GetItemAsObject(0));
>         modifiedLight->SetLightTypeToHeadlight();
>     modifiedLight->SetPosition(camera1->GetPosition());
>     modifiedLight->SetFocalPoint(camera1->GetFocalPoint());
>         // Above Doesn't work, Ok let's try this as well
>         renderer1->UpdateLightsGeometryToFollowCamera();
>
>         // Sanity check
>         assertArrayEquals(camera1->GetPosition(),        
>     camera2->GetPosition(), 3);
>         assertArrayEquals(camera1->GetFocalPoint(),        
>     camera2->GetFocalPoint(), 3);
>     assertVtkMatrixEquals(camera1->GetProjectionTransformMatrix(renderer1),
>     camera2->GetProjectionTransformMatrix(renderer2));
>
>
>         vtkSmartPointer<vtkLightCollection> lightCollection1 =
>     renderer1->GetLights();
>         vtkSmartPointer<vtkLightCollection> lightCollection2 =
>     renderer2->GetLights();
>         assert(lightCollection1->GetNumberOfItems() ==
>     lightCollection2->GetNumberOfItems());
>         lightCollection1->InitTraversal();
>         lightCollection2->InitTraversal();
>         vtkSmartPointer<vtkLight> light1 =
>     lightCollection1->GetNextItem();
>         vtkSmartPointer<vtkLight> light2 =
>     lightCollection2->GetNextItem();
>         assertArrayEquals(light1->GetPosition(),    
>     light2->GetPosition(), 3);
>     assertArrayEquals(light1->GetTransformedPosition(),    
>     light2->GetTransformedPosition(), 3);
>         assertArrayEquals(light1->GetFocalPoint(),        
>     light2->GetFocalPoint(), 3);
>     assertArrayEquals(light1->GetTransformedFocalPoint(),
>     light1->GetTransformedFocalPoint(), 3);
>         assertArrayEquals(light1->GetAmbientColor(),    
>     light2->GetAmbientColor(), 3);
>         assertArrayEquals(light1->GetSpecularColor(),        
>     light2->GetSpecularColor(), 3);
>         assertArrayEquals(light1->GetDiffuseColor(),    
>     light2->GetDiffuseColor(), 3);
>
>         renderWindow->Render();
>         renderWindowInteractor->Start();
>
>         return EXIT_SUCCESS;
>     }
>
>
>     On 08/05/2016 03:10 PM, Bud Bundy wrote:
>>
>>     Thanks,
>>
>>     The light positions were indeed different, but making them the
>>     same didn't fix it for me.  Perhaps my fix is wrong?
>>
>>     void assertArrayEquals(const double * a, const double * b, size_t
>>     elements)
>>     {
>>         for (size_t i = 0; i < elements; ++i)
>>         {
>>             assert(a[i] - b[i] <=
>>     std::numeric_limits<double>::epsilon());
>>         }
>>     }
>>
>>         //previous int main() code ...
>>
>>         //setting lights before first call to Render() crashes
>>     program, also describedh
>>     http://www.vtk.org/Wiki/VTK/Examples/Cxx/Lighting/Light
>>
>>         renderWindow->Render();
>>
>>         renderer2->RemoveAllLights();
>>         vtkSmartPointer<vtkLight> newLight =
>>     vtkSmartPointer<vtkLight>::New();
>>         newLight->SetPosition(0, 0, 1000);
>>         renderer2->AddLight(newLight);
>>
>>         //assert lighting is the same
>>         vtkSmartPointer<vtkLightCollection> lightCollection1 =
>>     renderer1->GetLights();
>>         vtkSmartPointer<vtkLightCollection> lightCollection2 =
>>     renderer2->GetLights();
>>         assert(lightCollection1->GetNumberOfItems() ==
>>     lightCollection2->GetNumberOfItems());
>>         lightCollection1->InitTraversal();
>>         lightCollection2->InitTraversal();
>>         vtkSmartPointer<vtkLight> light1 =
>>     lightCollection1->GetNextItem();
>>         vtkSmartPointer<vtkLight> light2 =
>>     lightCollection2->GetNextItem();
>>         assertArrayEquals(light1->GetPosition(),
>>     light2->GetPosition(), 3);
>>     assertArrayEquals(light1->GetTransformedPosition(),
>>     light2->GetTransformedPosition(), 3);
>>         assertArrayEquals(light1->GetFocalPoint(),
>>     light2->GetFocalPoint(), 3);
>>     assertArrayEquals(light1->GetTransformedFocalPoint(),
>>     light1->GetTransformedFocalPoint(), 3);
>>         assertArrayEquals(light1->GetAmbientColor(),
>>     light2->GetAmbientColor(), 3);
>>         assertArrayEquals(light1->GetSpecularColor(),
>>     light2->GetSpecularColor(), 3);
>>         assertArrayEquals(light1->GetDiffuseColor(),
>>     light2->GetDiffuseColor(), 3);
>>
>>         renderWindow->Render();
>>
>>         renderWindowInteractor->Start();
>>
>>
>>     On 08/05/16 14:10, David E DeMarle wrote:
>>>
>>>     I was just doing a very similar thing and noticed that light
>>>     positions are only updated with the set origin, focal point and
>>>     up. I ended up computing those for my intended matrix and
>>>     lighting then worked as expected.
>>>
>>>
>>>     On Aug 5, 2016 1:12 PM, "Bud Bundy" <budric at gmail.com
>>>     <mailto:budric at gmail.com>> wrote:
>>>
>>>         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.
>>>
>>>
>>>         _______________________________________________
>>>         Powered by www.kitware.com <http://www.kitware.com>
>>>
>>>         Visit other Kitware open-source projects at
>>>         http://www.kitware.com/opensource/opensource.html
>>>
>>>         Please keep messages on-topic and check the VTK FAQ at:
>>>         http://www.vtk.org/Wiki/VTK_FAQ
>>>
>>>         Search the list archives at:
>>>         http://markmail.org/search/?q=vtkusers
>>>
>>>         Follow this link to subscribe/unsubscribe:
>>>         http://public.kitware.com/mailman/listinfo/vtkusers
>>>
>>
>
>     _______________________________________________
>     Powered by www.kitware.com <http://www.kitware.com>
>
>     Visit other Kitware open-source projects at
>     http://www.kitware.com/opensource/opensource.html
>
>     Please keep messages on-topic and check the VTK FAQ at:
>     http://www.vtk.org/Wiki/VTK_FAQ
>
>     Search the list archives at: http://markmail.org/search/?q=vtkusers
>
>     Follow this link to subscribe/unsubscribe:
>     http://public.kitware.com/mailman/listinfo/vtkusers
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20160830/976d658e/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: volume_vtk_7.1.0.jpg
Type: image/jpeg
Size: 29992 bytes
Desc: not available
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20160830/976d658e/attachment-0001.jpg>


More information about the vtkusers mailing list