[vtkusers] vtkSmartVolumeMapper doesn't properly handle input changes

Marc Ruiz Altisent marc.ruiz+vtk at gmail.com
Tue May 29 13:33:40 EDT 2018


Done: https://gitlab.kitware.com/vtk/vtk/issues/17328

Thanks

Missatge de David E DeMarle <dave.demarle at kitware.com> del dia dt., 29 de
maig 2018 a les 18:18:

> Yes please do file a bug report on gitlab issue tracker.
>
> Thanks
>
>
> David E DeMarle
> Kitware, Inc.
> Principal Engineer
> 21 Corporate Drive
> Clifton Park, NY 12065-8662
> Phone: 518-881-4909
>
> On Mon, May 28, 2018 at 7:55 AM, Marc Ruiz Altisent <
> marc.ruiz+vtk at gmail.com> wrote:
>
>> Should I create a new issue for this in the bug tracker?
>>
>> Missatge de Marc Ruiz Altisent <marc.ruiz+vtk at gmail.com> del dia dc., 23
>> de maig 2018 a les 19:29:
>>
>>> Hi everyone,
>>>
>>> I have found an issue with vtkSmartVolumeMapper. If you create several
>>> vtkImageData objects, set one of them as the input of the mapper and
>>> render, then you won't be able to render one of the others at a later time:
>>> if you set one of the others as input the mapper will keep rendering the
>>> first one.
>>>
>>> The issue is in the method vtkSmartVolumeMapper::ConnectMapperInput. It
>>> doesn't pass the original input to its internal mapper, but a shallow copy
>>> of it. The first time it will always perform the shallow copy, but
>>> afterwards it will only do it if the new input has been modified after
>>> creating the previous shallow copy, which is not always the case (e.g. if
>>> you create all the data before the first render).
>>>
>>> Possible workarounds are to call Modified() on the input data when
>>> setting a new one or to create a new mapper each time.
>>>
>>> Below is a sample program (adapted from a couple of examples) to proof
>>> the issue. Pressing 1 or 2 alternates between 2 datasets but only the first
>>> one is always rendered. Uncommenting the 2 Modified() calls makes it work
>>> as expected.
>>>
>>> #include <vtkSmartPointer.h>
>>> #include <vtkSphere.h>
>>> #include <vtkBox.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 <vtkInteractorStyleTrackballCamera.h>
>>> #include <vtkObjectFactory.h>
>>>
>>> // Define interaction style
>>> class KeyPressInteractorStyle : public vtkInteractorStyleTrackballCamera
>>> {
>>>   public:
>>>     static KeyPressInteractorStyle* New();
>>>     vtkTypeMacro(KeyPressInteractorStyle,
>>> vtkInteractorStyleTrackballCamera);
>>>
>>>     virtual void OnKeyPress()
>>>     {
>>>       // Get the keypress
>>>       vtkRenderWindowInteractor *rwi = this->Interactor;
>>>       std::string key = rwi->GetKeySym();
>>>
>>>       if(key == "1")
>>>       {
>>>         mapper->SetInputData(imageData1);
>>>         //imageData1->Modified();
>>>         rwi->Render();
>>>       }
>>>       else if(key == "2")
>>>       {
>>>         mapper->SetInputData(imageData2);
>>>         //imageData2->Modified();
>>>         rwi->Render();
>>>       }
>>>
>>>       // Forward events
>>>       vtkInteractorStyleTrackballCamera::OnKeyPress();
>>>     }
>>>     vtkSmartPointer<vtkVolumeMapper> mapper;
>>>     vtkSmartPointer<vtkImageData> imageData1, imageData2;
>>> };
>>> vtkStandardNewMacro(KeyPressInteractorStyle);
>>>
>>> static void CreateImageData(vtkImageData* im, bool);
>>>
>>> int main(int argc, char *argv[])
>>> {
>>>   vtkSmartPointer<vtkImageData> imageData =
>>>     vtkSmartPointer<vtkImageData>::New();
>>>   vtkSmartPointer<vtkImageData> imageData2 =
>>>     vtkSmartPointer<vtkImageData>::New();
>>>
>>>   CreateImageData(imageData, true);
>>>   CreateImageData(imageData2, false);
>>>
>>>   vtkSmartPointer<vtkRenderWindow> renWin =
>>>     vtkSmartPointer<vtkRenderWindow>::New();
>>>   vtkSmartPointer<vtkRenderer> ren1 =
>>>     vtkSmartPointer<vtkRenderer>::New();
>>>   ren1->SetBackground(0.1,0.4,0.2);
>>>
>>>   renWin->AddRenderer(ren1);
>>>
>>>   renWin->SetSize(301,300); // intentional odd and NPOT  width/height
>>>
>>>   vtkSmartPointer<vtkRenderWindowInteractor> iren =
>>>     vtkSmartPointer<vtkRenderWindowInteractor>::New();
>>>   iren->SetRenderWindow(renWin);
>>>
>>>   vtkSmartPointer<KeyPressInteractorStyle> style =
>>>     vtkSmartPointer<KeyPressInteractorStyle>::New();
>>>   iren->SetInteractorStyle(style);
>>>   style->SetCurrentRenderer(ren1);
>>>
>>>   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);
>>>
>>>   style->mapper = volumeMapper;
>>>   style->imageData1 = imageData;
>>>   style->imageData2 = imageData2;
>>>
>>>   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);
>>>   ren1->AddViewProp(volume);
>>>   ren1->ResetCamera();
>>>
>>>   // Render composite. In default mode. For coverage.
>>>   renWin->Render();
>>>
>>>   iren->Start();
>>>
>>>   return EXIT_SUCCESS;
>>> }
>>>
>>> void CreateImageData(vtkImageData* imageData, bool spherical)
>>> {
>>>   vtkSmartPointer<vtkImplicitFunction> implicitFunction;
>>>
>>>   if (spherical)
>>>   {
>>>     vtkSmartPointer<vtkSphere> sphere =
>>>       vtkSmartPointer<vtkSphere>::New();
>>>     sphere->SetRadius(0.1);
>>>     sphere->SetCenter(0.0,0.0,0.0);
>>>     implicitFunction = sphere;
>>>   }
>>>   else
>>>   {
>>>     vtkSmartPointer<vtkBox> box =
>>>       vtkSmartPointer<vtkBox>::New();
>>>     box->SetBounds(-0.1, 0.1, -0.1, 0.1, -0.1, 0.1);
>>>     implicitFunction = box;
>>>   }
>>>
>>>   vtkSmartPointer<vtkSampleFunction> sampleFunction =
>>>     vtkSmartPointer<vtkSampleFunction>::New();
>>>   sampleFunction->SetImplicitFunction(implicitFunction);
>>>   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());
>>> }
>>>
>>
>> _______________________________________________
>> Powered by 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:
>> https://vtk.org/mailman/listinfo/vtkusers
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://public.kitware.com/pipermail/vtkusers/attachments/20180529/0fd83bd8/attachment.html>


More information about the vtkusers mailing list