[vtkusers] Strange rendering with 2-voxel thick volume
Elvis Stansvik
elvis.stansvik at orexplore.com
Thu Oct 5 08:39:39 EDT 2017
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
More information about the vtkusers
mailing list