[vtkusers] Strange rendering with 2-voxel thick volume
Aashish Chaudhary
aashish.chaudhary at kitware.com
Thu Oct 5 15:17:44 EDT 2017
Elvis,
What you said makes sense. I think there might be other places (we have
identified atleast one more) where we are off by one on one axis. If you
can identify some more issues with our fix, ping us and we will sort them
out. Thank you for providing us a edge case and culprit code.
thanks,
On Thu, Oct 5, 2017 at 12:36 PM Elvis Stansvik <elvis.stansvik at orexplore.com>
wrote:
> Det 5 okt. 2017 6:01 em skrev "Aashish Chaudhary" <
> aashish.chaudhary at kitware.com>:
>
> Here is the merge request we are testing:
> https://gitlab.kitware.com/vtk/vtk/merge_requests/3413
>
> It will require probably some more work to ensure correctness at other
> places but this is a start that should fix your problem.
>
>
> Thanks! That's one of the things me and my colleague tried out during our
> session here. It will fix my specific problem, but I think we found that it
> gave ill effects in other cases.
>
> I'll continue the discussion on the MR, I have a testcase I can share when
> I'm home (on the bus atm).
>
> Elvis
>
>
> -Aashish
>
> On Thu, Oct 5, 2017 at 11:48 AM Aashish Chaudhary <
> aashish.chaudhary at kitware.com> wrote:
>
>> No worries...so we just checked the math the cell to point offset matrix
>> seems to be right but the delta seems wrong. Can you change this
>>
>> > delta[0] = this->Extents[1] - this->Extents[0];
>> > delta[1] = this->Extents[3] - this->Extents[2];
>> > delta[2] = this->Extents[5] - this->Extents[4];
>>
>> to this
>>
>> delta[0] = this->Extents[1] - this->Extents[0] + 1;
>> delta[1] = this->Extents[3] - this->Extents[2] + 1;
>> delta[2] = this->Extents[5] - this->Extents[4] + 1;
>>
>> Thanks,
>>
>>
>>
>>
>>
>> On Thu, Oct 5, 2017 at 10:48 AM Elvis Stansvik <
>> elvis.stansvik at orexplore.com> wrote:
>>
>>> 2017-10-05 16:34 GMT+02:00 Aashish Chaudhary <
>>> aashish.chaudhary at kitware.com>:
>>> > Thanks we are looking into it, earlier we moved the math from the
>>> shader to
>>> > a matrix that now we are forming in C++ so at this point we are
>>> looking at
>>> > the equation carefully. But yes, I thought you may have found a bug.
>>>
>>> Thanks for having a look. I suspect my std::max(..) is just a
>>> workaround and not a proper fix.
>>>
>>> Me and a colleague had another look, but I think we were both too
>>> tired to figure out if something was fundamentally wrong with the
>>> equations. Too late in the day :)
>>>
>>> Elvis
>>>
>>> >
>>> > - aashish
>>> >
>>> > On Thu, Oct 5, 2017 at 8:39 AM Elvis Stansvik <
>>> elvis.stansvik at orexplore.com>
>>> > wrote:
>>> >>
>>> >> 2017-10-05 10:38 GMT+02:00 Elvis Stansvik <
>>> elvis.stansvik at orexplore.com>:
>>> >> > 2017-10-04 18:12 GMT+02:00 Aashish Chaudhary
>>> >> > <aashish.chaudhary at kitware.com>:
>>> >> >> Got it, thanks!
>>> >> >
>>> >> > Although I'm not familiar at all with the code, I suspect this is
>>> what
>>> >> > happens with my 200x200x2 volume:
>>> >> >
>>> >> > In void
>>> >> >
>>> vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::ComputeCellToPointMatrix()
>>> >> > {
>>> >> > this->CellToPointMatrix->Identity();
>>> >> > this->AdjustedTexMin[0] = this->AdjustedTexMin[1] =
>>> >> > this->AdjustedTexMin[2] = 0.0f;
>>> >> > this->AdjustedTexMin[3] = 1.0f;
>>> >> > this->AdjustedTexMax[0] = this->AdjustedTexMax[1] =
>>> >> > this->AdjustedTexMax[2] = 1.0f;
>>> >> > this->AdjustedTexMax[3] = 1.0f;
>>> >> >
>>> >> > if (!this->Parent->CellFlag) // point data
>>> >> > {
>>> >> > float delta[3];
>>> >> > delta[0] = this->Extents[1] - this->Extents[0];
>>> >> > delta[1] = this->Extents[3] - this->Extents[2];
>>> >> > delta[2] = this->Extents[5] - this->Extents[4];
>>> >> >
>>> >> > float min[3];
>>> >> > min[0] = 0.5f / delta[0];
>>> >> > min[1] = 0.5f / delta[1];
>>> >> > min[2] = 0.5f / delta[2];
>>> >> >
>>> >> > float range[3]; // max - min
>>> >> > range[0] = (delta[0] - 0.5f) / delta[0] - min[0];
>>> >> > range[1] = (delta[1] - 0.5f) / delta[1] - min[1];
>>> >> > range[2] = (delta[2] - 0.5f) / delta[2] - min[2];
>>> >> >
>>> >> > this->CellToPointMatrix->SetElement(0, 0, range[0]); // Scale
>>> diag
>>> >> > this->CellToPointMatrix->SetElement(1, 1, range[1]);
>>> >> > this->CellToPointMatrix->SetElement(2, 2, range[2]);
>>> >> > this->CellToPointMatrix->SetElement(0, 3, min[0]); // t vector
>>> >> > this->CellToPointMatrix->SetElement(1, 3, min[1]);
>>> >> > this->CellToPointMatrix->SetElement(2, 3, min[2]);
>>> >> >
>>> >> > // Adjust limit coordinates for texture access.
>>> >> > float const zeros[4] = {0.0f, 0.0f, 0.0f, 1.0f}; // GL tex min
>>> >> > float const ones[4] = {1.0f, 1.0f, 1.0f, 1.0f}; // GL tex max
>>> >> > this->CellToPointMatrix->MultiplyPoint(zeros,
>>> this->AdjustedTexMin);
>>> >> > this->CellToPointMatrix->MultiplyPoint(ones,
>>> this->AdjustedTexMax);
>>> >> > }
>>> >> > }
>>> >> >
>>> >> > delta[2] = 1 ==> min[2] = 0.5 ==> range[2] = 0
>>> >> >
>>> >> > So the scale factor in the third dimension will be 0 in
>>> >> > CellToPointMatrix, right? I guess this could be what accounts for
>>> the
>>> >> > strange rendering?
>>> >> >
>>> >> > Could/should this code be updated to take into account when the
>>> extent
>>> >> > delta is just 1, so that volumes 2 data points thick can be
>>> rendered?
>>> >>
>>> >> I've only tested it briefly, but this seems to give the correct
>>> >> rendering even with a 2 point thick input:
>>> >>
>>> >> diff --git
>>> a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx
>>> >> b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx
>>> >> index 8767bd0..88bbcba 100644
>>> >> --- a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx
>>> >> +++ b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx
>>> >> @@ -1495,9 +1495,9 @@ void
>>> >>
>>> vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::ComputeCellToPointMatrix()
>>> >> if (!this->Parent->CellFlag) // point data
>>> >> {
>>> >> float delta[3];
>>> >> - delta[0] = this->Extents[1] - this->Extents[0];
>>> >> - delta[1] = this->Extents[3] - this->Extents[2];
>>> >> - delta[2] = this->Extents[5] - this->Extents[4];
>>> >> + delta[0] = std::max(2, this->Extents[1] - this->Extents[0]);
>>> >> + delta[1] = std::max(2, this->Extents[3] - this->Extents[2]);
>>> >> + delta[2] = std::max(2, this->Extents[5] - this->Extents[4]);
>>> >>
>>> >> float min[3];
>>> >> min[0] = 0.5f / delta[0];
>>> >>
>>> >> This ensures the texture does not collapse into 0 when the extent
>>> >> delta is 1. Would you consider this a correct fix?
>>> >>
>>> >> Elvis
>>> >>
>>> >> >
>>> >> > Elvis
>>> >> >
>>> >> >>
>>> >> >> On Wed, Oct 4, 2017 at 12:07 PM Elvis Stansvik
>>> >> >> <elvis.stansvik at orexplore.com> wrote:
>>> >> >>>
>>> >> >>> 2017-10-04 17:43 GMT+02:00 Aashish Chaudhary
>>> >> >>> <aashish.chaudhary at kitware.com>:
>>> >> >>> > thanks..I just wanted to make sure that we remove that as one
>>> of the
>>> >> >>> > culprit. I am wondering if it is something to do with the
>>> geometry
>>> >> >>> > (bbox) or
>>> >> >>> > something to do with some edge case (calculation that is going
>>> off
>>> >> >>> > because
>>> >> >>> > of very small delta). Although in the past we have tried very
>>> think
>>> >> >>> > volumes
>>> >> >>> >
>>> >> >>> > Is it possible for you to send a sample dataset to us?
>>> >> >>>
>>> >> >>> My test case includes the data used. It's simply a 200x200x2
>>> volume
>>> >> >>> filled with all data points set to 0.01.
>>> >> >>>
>>> >> >>> Elvis
>>> >> >>>
>>> >> >>> >
>>> >> >>> > On Wed, Oct 4, 2017 at 10:09 AM Elvis Stansvik
>>> >> >>> > <elvis.stansvik at orexplore.com> wrote:
>>> >> >>> >>
>>> >> >>> >> Hi Aashish,
>>> >> >>> >>
>>> >> >>> >> 2017-10-04 15:47 GMT+02:00 Aashish Chaudhary
>>> >> >>> >> <aashish.chaudhary at kitware.com>:
>>> >> >>> >> > Please make sure that your sampling distance is less than <
>>> 2.
>>> >> >>> >> > You
>>> >> >>> >> > can
>>> >> >>> >> > set
>>> >> >>> >> > the sampling distance manually in the API.
>>> >> >>> >>
>>> >> >>> >> Hm. I don't think it's related to sampling distance. In the
>>> test
>>> >> >>> >> case
>>> >> >>> >> I'm not setting sampling distance at all, so I think it should
>>> >> >>> >> default
>>> >> >>> >> to 1, and then be automatically adjusted during interaction.
>>> >> >>> >>
>>> >> >>> >> In any case, even if I amend the test case with e.g.:
>>> >> >>> >>
>>> >> >>> >> volumeMapper->AutoAdjustSampleDistancesOff();
>>> >> >>> >> volumeMapper->SetSampleDistance(0.2);
>>> >> >>> >> ...
>>> >> >>> >> volumeMapper2->AutoAdjustSampleDistancesOff();
>>> >> >>> >> volumeMapper2->SetSampleDistance(0.2);
>>> >> >>> >>
>>> >> >>> >> The result is the same.
>>> >> >>> >>
>>> >> >>> >> Elvis
>>> >> >>> >>
>>> >> >>> >> >
>>> >> >>> >> > On Wed, Oct 4, 2017 at 8:23 AM Elvis Stansvik
>>> >> >>> >> > <elvis.stansvik at orexplore.com>
>>> >> >>> >> > wrote:
>>> >> >>> >> >>
>>> >> >>> >> >> Hi all,
>>> >> >>> >> >>
>>> >> >>> >> >> In the test case below, I render one 200x200x2 volume and
>>> one
>>> >> >>> >> >> 200x200x3 volume, both with the same settings.
>>> >> >>> >> >>
>>> >> >>> >> >> The 200x200x3 volume looks as expected (the light gray one
>>> in
>>> >> >>> >> >> the
>>> >> >>> >> >> attached screenshot), while the 200x200x2 one looks strange
>>> (too
>>> >> >>> >> >> dark,
>>> >> >>> >> >> and with some kind of gradient artifact).
>>> >> >>> >> >>
>>> >> >>> >> >> Is there some limitation on rendering a volume that is only
>>> 2
>>> >> >>> >> >> thick
>>> >> >>> >> >> in
>>> >> >>> >> >> one of the dimensions? I can understand why a volume of
>>> >> >>> >> >> thickness 1
>>> >> >>> >> >> can't be rendered properly, since VTK must have values to
>>> >> >>> >> >> interpolate
>>> >> >>> >> >> between, but 2 should be OK right?
>>> >> >>> >> >>
>>> >> >>> >> >> Thanks for any help.
>>> >> >>> >> >>
>>> >> >>> >> >> Elvis
>>> >> >>> >> >>
>>> >> >>> >> >>
>>> >> >>> >> >> main.cpp:
>>> >> >>> >> >>
>>> >> >>> >> >> #include <algorithm>
>>> >> >>> >> >>
>>> >> >>> >> >> #include <vtkColorTransferFunction.h>
>>> >> >>> >> >> #include <vtkGenericOpenGLRenderWindow.h>
>>> >> >>> >> >> #include <vtkGPUVolumeRayCastMapper.h>
>>> >> >>> >> >> #include <vtkImageData.h>
>>> >> >>> >> >> #include <vtkNew.h>
>>> >> >>> >> >> #include <vtkPiecewiseFunction.h>
>>> >> >>> >> >> #include <vtkProperty.h>
>>> >> >>> >> >> #include <vtkRenderer.h>
>>> >> >>> >> >> #include <vtkRenderWindow.h>
>>> >> >>> >> >> #include <vtkRenderWindowInteractor.h>
>>> >> >>> >> >> #include <vtkVolume.h>
>>> >> >>> >> >> #include <vtkVolumeProperty.h>
>>> >> >>> >> >>
>>> >> >>> >> >> int main(int argc, char *argv[])
>>> >> >>> >> >> {
>>> >> >>> >> >> vtkNew<vtkColorTransferFunction> colorFunction;
>>> >> >>> >> >> colorFunction->AddRGBPoint(0.0, 0.0, 0.0, 0.0);
>>> >> >>> >> >> colorFunction->AddRGBPoint(1.0, 0.0, 0.0, 0.0);
>>> >> >>> >> >>
>>> >> >>> >> >> vtkNew<vtkPiecewiseFunction> opacityFunction;
>>> >> >>> >> >> opacityFunction->AddPoint(0.0, 0.0);
>>> >> >>> >> >> opacityFunction->AddPoint(1.0, 1.0);
>>> >> >>> >> >>
>>> >> >>> >> >> // A 200x200x2 volume
>>> >> >>> >> >> vtkNew<vtkImageData> imageData;
>>> >> >>> >> >> imageData->SetExtent(0, 199, 0, 199, 0, 1);
>>> >> >>> >> >> imageData->AllocateScalars(VTK_FLOAT, 1);
>>> >> >>> >> >> std::fill_n(static_cast<float
>>> >> >>> >> >> *>(imageData->GetScalarPointer()),
>>> >> >>> >> >> 200 * 200 * 2, 0.01);
>>> >> >>> >> >>
>>> >> >>> >> >> vtkNew<vtkGPUVolumeRayCastMapper> volumeMapper;
>>> >> >>> >> >> volumeMapper->SetInputData(imageData.Get());
>>> >> >>> >> >>
>>> >> >>> >> >> vtkNew<vtkVolumeProperty> volumeProperty;
>>> >> >>> >> >> volumeProperty->SetScalarOpacity(opacityFunction.Get());
>>> >> >>> >> >> volumeProperty->SetColor(colorFunction.Get());
>>> >> >>> >> >> volumeProperty->ShadeOff();
>>> >> >>> >> >>
>>> >> >>> >> >> vtkNew<vtkVolume> volume;
>>> >> >>> >> >> volume->SetMapper(volumeMapper.Get());
>>> >> >>> >> >> volume->SetProperty(volumeProperty.Get());
>>> >> >>> >> >> volume->SetPosition(120, 0, 0);
>>> >> >>> >> >>
>>> >> >>> >> >> // A 200x200x3 volume
>>> >> >>> >> >> vtkNew<vtkImageData> imageData2;
>>> >> >>> >> >> imageData2->SetExtent(0, 199, 0, 199, 0, 2);
>>> >> >>> >> >> imageData2->AllocateScalars(VTK_FLOAT, 1);
>>> >> >>> >> >> std::fill_n(static_cast<float
>>> >> >>> >> >> *>(imageData2->GetScalarPointer()),
>>> >> >>> >> >> 200 * 200 * 3, 0.01);
>>> >> >>> >> >>
>>> >> >>> >> >> vtkNew<vtkGPUVolumeRayCastMapper> volumeMapper2;
>>> >> >>> >> >> volumeMapper2->SetInputData(imageData2.Get());
>>> >> >>> >> >>
>>> >> >>> >> >> vtkNew<vtkVolumeProperty> volumeProperty2;
>>> >> >>> >> >>
>>> volumeProperty2->SetScalarOpacity(opacityFunction.Get());
>>> >> >>> >> >> volumeProperty2->SetColor(colorFunction.Get());
>>> >> >>> >> >> volumeProperty2->ShadeOff();
>>> >> >>> >> >>
>>> >> >>> >> >> vtkNew<vtkVolume> volume2;
>>> >> >>> >> >> volume2->SetMapper(volumeMapper2.Get());
>>> >> >>> >> >> volume2->SetProperty(volumeProperty2.Get());
>>> >> >>> >> >> volume2->SetPosition(-120, 0, 0);
>>> >> >>> >> >>
>>> >> >>> >> >> vtkNew<vtkRenderer> renderer;
>>> >> >>> >> >> renderer->AddVolume(volume.Get());
>>> >> >>> >> >> renderer->AddVolume(volume2.Get());
>>> >> >>> >> >> renderer->SetBackground(1.0, 1.0, 1.0);
>>> >> >>> >> >>
>>> >> >>> >> >> // Render with "plain" render window / interactor
>>> >> >>> >> >> vtkNew<vtkRenderWindow> window;
>>> >> >>> >> >> window->SetMultiSamples(0);
>>> >> >>> >> >> window->AddRenderer(renderer.Get());
>>> >> >>> >> >>
>>> >> >>> >> >> vtkNew<vtkRenderWindowInteractor> interactor;
>>> >> >>> >> >> interactor->SetRenderWindow(window.Get());
>>> >> >>> >> >> interactor->Start();
>>> >> >>> >> >>
>>> >> >>> >> >> return 0;
>>> >> >>> >> >> }
>>> >> >>> >> >>
>>> >> >>> >> >>
>>> >> >>> >> >> CMakeLists.txt:
>>> >> >>> >> >>
>>> >> >>> >> >> cmake_minimum_required(VERSION 3.1)
>>> >> >>> >> >>
>>> >> >>> >> >> project(TestCase)
>>> >> >>> >> >>
>>> >> >>> >> >> find_package(VTK 8.0 COMPONENTS
>>> >> >>> >> >> vtkCommonCore
>>> >> >>> >> >> vtkCommonDataModel
>>> >> >>> >> >> vtkCommonExecutionModel
>>> >> >>> >> >> vtkCommonMath
>>> >> >>> >> >> vtkFiltersSources
>>> >> >>> >> >> vtkGUISupportQt
>>> >> >>> >> >> vtkInteractionStyle
>>> >> >>> >> >> vtkRenderingCore
>>> >> >>> >> >> vtkRenderingOpenGL2
>>> >> >>> >> >> vtkRenderingVolume
>>> >> >>> >> >> vtkRenderingVolumeOpenGL2
>>> >> >>> >> >> REQUIRED
>>> >> >>> >> >> )
>>> >> >>> >> >>
>>> >> >>> >> >> add_executable(TestCase main.cpp)
>>> >> >>> >> >>
>>> >> >>> >> >> target_link_libraries(TestCase PUBLIC
>>> >> >>> >> >> vtkCommonCore
>>> >> >>> >> >> vtkCommonDataModel
>>> >> >>> >> >> vtkCommonExecutionModel
>>> >> >>> >> >> vtkCommonMath
>>> >> >>> >> >> vtkFiltersSources
>>> >> >>> >> >> vtkInteractionStyle
>>> >> >>> >> >> vtkRenderingCore
>>> >> >>> >> >> vtkRenderingOpenGL2
>>> >> >>> >> >> vtkRenderingVolume
>>> >> >>> >> >> vtkRenderingVolumeOpenGL2
>>> >> >>> >> >> )
>>> >> >>> >> >>
>>> >> >>> >> >> target_include_directories(TestCase PUBLIC
>>> >> >>> >> >> ${VTK_INCLUDE_DIRS}
>>> >> >>> >> >> )
>>> >> >>> >> >>
>>> >> >>> >> >> target_compile_definitions(TestCase PUBLIC
>>> >> >>> >> >> ${VTK_DEFINITIONS}
>>> >> >>> >> >> )
>>> >> >>> >> >>
>>> >> >>> >> >> set_target_properties(TestCase PROPERTIES
>>> >> >>> >> >> CXX_STANDARD 14
>>> >> >>> >> >> CXX_STANDARD_REQUIRED ON
>>> >> >>> >> >> )
>>> >> >>> >> >> _______________________________________________
>>> >> >>> >> >> 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:
>>> >> >>> >> >> http://public.kitware.com/mailman/listinfo/vtkusers
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20171005/241c84ce/attachment-0001.html>
More information about the vtkusers
mailing list