<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">2017-02-12 17:56 GMT+01:00 Elvis Stansvik <span dir="ltr"><<a href="mailto:elvis.stansvik@orexplore.com" target="_blank">elvis.stansvik@orexplore.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="">2017-02-12 17:31 GMT+01:00 David Gobbi <span dir="ltr"><<a href="mailto:david.gobbi@gmail.com" target="_blank">david.gobbi@gmail.com</a>></span>:<br></span><span class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Elvis,<div><br></div><div>Here is something you can do as a check: set the sample distance for the ray casting to a very small value, so that it takes around 1000 steps for the ray to traverse the volume from front to back.  The thickness of your volume is 29*0.006 = 0.174, so you can try a sample spacing of 1.74e-04:</div><div><br></div><div>mapper->AutoAdjustSampleDistan<wbr>cesOff();</div><div>mapper->SetSampleDistance(1.74<wbr>e-04);</div><div><br></div><div>If the two volumes look the same when you use a small sample distance, then the difference you were seeing was probably just due to discretization.</div></div></blockquote><div><br></div></span><div>That indeed did the trick, thanks David!<span class="HOEnZb"><font color="#888888"><br></font></span></div></div></div></div></blockquote><div><br></div><div>And to clarify: The small difference I was seeing when I had the sample distance left to auto-adjusted isn't really a problem for my application. I was just surprised there was still a small difference even when both volumes were rendered with the same opacity unit distance, and I wanted to find the explanation for it. The discretization error coming into play makes sense.<br><br></div><div>Elvis<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><span class="HOEnZb"><font color="#888888"><br></font></span></div><span class="HOEnZb"><font color="#888888"><div>Elvis<br> <br></div></font></span><div><div class="h5"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><span class="m_4335941606091367686HOEnZb"><font color="#888888"><div><br></div><div> - David</div></font></span><div><div class="m_4335941606091367686h5"><div><br></div><div><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Feb 9, 2017 at 6:45 AM, Elvis Stansvik <span dir="ltr"><<a href="mailto:elvis.stansvik@orexplore.com" target="_blank">elvis.stansvik@orexplore.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div>Hi all,<br><br>The following example shows a 30x30x30 volume rendered, and next to it a downscaled version of it (but using an identical opacity/transfer function). Notice how in the result (attached), the downscaled version is less opaque. This is despite me using<br><br>    SetScalarOpacityUnitDistance(i<wbr>mage->GetSpacing()[0])<br><br></div>to set the scalar opacity unit distance to the spacing of the respective image. I would thought calling SetScalarOpacityUnitDistance like this would ensure both volumes look the same (apart from resolution).<br><br></div>How can I make both volumes look the same opacity-wise when using the same transfer functions?<br><br></div>Thanks in advance,<br></div>Elvis<br><br></div>main.cpp:<br><br><br>#include <algorithm><br><br>#include <vtkCamera.h><br>#include <vtkColorTransferFunction.h><br>#include <vtkGPUVolumeRayCastMapper.h><br>#include <vtkImageData.h><br>#include <vtkImageResize.h><br>#include <vtkPiecewiseFunction.h><br>#include <vtkRenderer.h><br>#include <vtkRenderWindow.h><br>#include <vtkRenderWindowInteractor.h><br>#include <vtkSmartPointer.h><br>#include <vtkVolume.h><br>#include <vtkVolumeProperty.h><br><br>// Create a volume from the given image<br>vtkSmartPointer<vtkVolume> createVolume(vtkSmartPointer<v<wbr>tkImageData> image) {<br>    auto color = vtkSmartPointer<vtkColorTransf<wbr>erFunction>::New();<br>    color->AddRGBPoint(0.0, 1.0, 0.0, 0.0);<br>    color->AddRGBPoint(1.0, 1.0, 0.0, 0.0);<br><br>    auto opacity = vtkSmartPointer<vtkPiecewiseFu<wbr>nction>::New();<br>    opacity->AddPoint(0.0, 0.1);<br>    opacity->AddPoint(1.0, 0.1);<br><br>    auto property = vtkSmartPointer<vtkVolumePrope<wbr>rty>::New();<br>    property->SetColor(color);<br>    property->SetScalarOpacity(opa<wbr>city);<br>    property->SetInterpolationType<wbr>ToLinear();<br>    property->ShadeOff();<br>    property->SetScalarOpacityUnit<wbr>Distance(image->GetSpacing()[0<wbr>]);<br><br>    auto mapper = vtkSmartPointer<vtkGPUVolumeRa<wbr>yCastMapper>::New();<br>    mapper->SetInputData(image);<br><br>    auto volume = vtkSmartPointer<vtkVolume>::Ne<wbr>w();<br>    volume->SetMapper(mapper);<br>    volume->SetProperty(property);<br><br>    return volume;<br>}<br><br>int main(int argc, char *argv[]) {<br><br>    // Create a 30x30x30 volume<br>    auto image = vtkSmartPointer<vtkImageData>:<wbr>:New();<br>    image->SetDimensions(30, 30, 30);<br>    image->SetSpacing(0.006, 0.006, 0.006);<br>    image->AllocateScalars(VTK_FLO<wbr>AT, 1);<br><br>    auto imagePtr = static_cast<float *>(image->GetScalarPointer());<br>    std::fill_n(imagePtr, 30 * 30 * 30, 1.0);<br><br>    auto volume = createVolume(image);<br><br>    // Create a smaller (10x10x10) version<br>    auto resize = vtkSmartPointer<vtkImageResize<wbr>>::New();<br>    resize->SetInputData(image);<br>    resize->SetOutputDimensions(10<wbr>, 10, 10);<br>    resize->Update();<br><br>    auto smallVolume = createVolume(resize->GetOutput<wbr>());<br>    smallVolume->SetPosition(0.2, 0, 0);<br><br>    // Render the two volumes<br>    auto renderer = vtkSmartPointer<vtkRenderer>::<wbr>New();<br>    renderer->SetBackground(1.0, 1.0, 1.0);<br>    renderer->AddVolume(volume);<br>    renderer->AddVolume(smallVolum<wbr>e);<br>    renderer->ResetCamera();<br><br>    auto camera = renderer->GetActiveCamera();<br>    camera->SetParallelProjection(<wbr>1);<br><br>    auto window = vtkSmartPointer<vtkRenderWindo<wbr>w>::New();<br>    window->AddRenderer(renderer);<br>    window->SetSize(800, 400);<br><br>    auto interactor = vtkSmartPointer<vtkRenderWindo<wbr>wInteractor>::New();<br>    interactor->SetRenderWindow(wi<wbr>ndow);<br>    interactor->Start();<br><br>    return 0;<br>}<br><br><br></div>CMakeLists.txt:<br><br><br>cmake_minimum_required(VERSION 3.1)<br> <br>project(TestCase)<br> <br>set(CMAKE_CXX_STANDARD 11)<br>set(CMAKE_CXX_STANDARD_REQUIRE<wbr>D ON)<br><br>find_package(VTK COMPONENTS<br>    vtkCommonCore<br>    vtkCommonDataModel<br>    vtkCommonExecutionModel<br>    vtkInteractionStyle<br>    vtkImagingCore<br>    vtkRenderingCore<br>    vtkRenderingOpenGL2<br>    vtkRenderingVolume<br>    vtkRenderingVolumeOpenGL2<br>)<br><br>add_executable(TestCase main.cpp)<br> <br>target_link_libraries(TestCase PUBLIC<br>    vtkCommonCore<br>    vtkCommonDataModel<br>    vtkCommonExecutionModel<br>    vtkImagingCore<br>    vtkInteractionStyle<br>    vtkRenderingCore<br>    vtkRenderingOpenGL2<br>    vtkRenderingVolume<br>    vtkRenderingVolumeOpenGL2<br>)<br><br>target_include_directories(Tes<wbr>tCase PUBLIC<br>    ${VTK_INCLUDE_DIRS}<br>)<br><br><br>target_compile_definitions(Tes<wbr>tCase PUBLIC<br>    ${VTK_DEFINITIONS}<br>)</div></blockquote></div><br></div></div></div></div></div>
</blockquote></div></div></div><br></div></div>
</blockquote></div><br></div></div>