# demystifiying color discretization

**URL:** https://discourse.vtk.org/t/demystifiying-color-discretization/117
**Category:** Support
**Created:** [January 24, 2019, 2:06pm UTC](https://discourse.vtk.org/t/demystifiying-color-discretization/117 "2019-01-24T14:06:32Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![embeddedmz](https://discourse.vtk.org/user_avatar/discourse.vtk.org/embeddedmz/32/12_2.png) [@embeddedmz](https://discourse.vtk.org/u/embeddedmz)
#### Post date: [January 24, 2019, 2:06pm UTC](https://discourse.vtk.org/t/demystifiying-color-discretization/117/1 "2019-01-24T14:06:33Z")

</div>

Hi,

In the past, I had a slow rendering problem. At the time, the problem was color management with ‘vtkColorTransferFunction’.

I solved the problem by using a ‘vtkLookupTable’ along with the ‘vtkColorTransferFunction’, example :

```
// I add control points to the vtkColorTransferFunction
for (const auto& pt : ctrlPts)
{
    m_transferFunction->AddRGBPoint(pt[0], pt[1], pt[2], pt[3]);
}

/* I build the lut */
m_lookupTable->SetNumberOfTableValues(m_lookupTableSize); // e.g. m_lookupTableSize == 256
m_lookupTable->SetRange(minRange, maxRange); // the range of data retrieved from a vtkImageData
m_lookupTable->Build();

double rgb[3];
for (size_t i = 0; i < m_lookupTableSize; ++i)
{
    m_transferFunction->GetColor(static_cast<double>(i) / m_lookupTableSize, rgb);
    m_lookupTable->SetTableValue(i, rgb[0], rgb[1], rgb[2]);
    // in the VTK examples, there is a memory bug, do not feed rgb a ptr to SetTableValue
} 

```

Recently, I encountered a class named vtkDiscretizableColorTransferFunction, that is also wrapped in ParaView under the name vtkPVDiscretizableColorTransferFunction.

I thought this last is doing what I am doing in the code I posted above, but when I tested it, it was slow as hell, just like ‘vtkColorTransferFunction’.

Strangely, in Paraview (with a 256 LUT sized table for example), rendering didn’t seem slow, may be I am using it wrong. Example :

> ```
> vtkNew<vtkDiscretizableColorTransferFunction> discretTF;
> discretTF->DiscretizeOn();
> discretTF->SetNumberOfValues(256);
> discretTF->IndexedLookupOff();
> discretTF->AddRGBPoint(0, 0.23137254902, 0.298039215686, 0.752941176471);
> discretTF->AddRGBPoint(0.5, 0.865, 0.865, 0.865);
> discretTF->AddRGBPoint(1, 0.705882352941, 0.0156862745098, 0.149019607843);
> discretTF->Build();
> 
> ```

When I render a vtkImageData with the code above, it’s as slow as using vtkColorTransferFunction (not discretized I guess).

My questions are :

- If we want discretized colors (to provide the fastest rendering), what’s the best strategy ?
- Why vtkDiscretizableColorTransferFunction (or even vtkPVDiscretizableColorTransferFunction, I took the class from ParaView and it has the same slow rendering time as vtkDiscretizableColorTransferFunction) is slow ?

Thanks.

---

<div class="post-metadata">

### Author: ![lassoan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lassoan/32/50_2.png) [@lassoan](https://discourse.vtk.org/u/lassoan)
#### Post date: [January 24, 2019, 2:45pm UTC](https://discourse.vtk.org/t/demystifiying-color-discretization/117/2 "2019-01-24T14:45:14Z")

</div>

Can you run the code using a profiler to see where most of the time is spent?

If you use Visual Studio then you can use the built-in profiler. You can also simply run VerySleepy profiler and attach it to the running process. To get line numbers and realistic performance, set VTK build mode to “RelWithDebInfo”.

---

<div class="post-metadata">

### Author: ![embeddedmz](https://discourse.vtk.org/user_avatar/discourse.vtk.org/embeddedmz/32/12_2.png) [@embeddedmz](https://discourse.vtk.org/u/embeddedmz)
#### Post date: [January 24, 2019, 3:07pm UTC](https://discourse.vtk.org/t/demystifiying-color-discretization/117/3 "2019-01-24T15:07:48Z")

</div>

I’m working under Linux CentOS. I’m using a simple C++ program to read data and measure rendering times (the Render() instruction).

If I use non discretized colors (a vtkColorTransferFunction as a transfer function fed to vtkImageMapToColors - 3D rendering - or even a 2D vtkChartHistogram2D) or a vtkDiscretizableColorTransferFunction, the rendering time is 9 - 10 second (in total for many vtkImageData(s))

Whereas with a vtkLookupTable (and a vtkColorTransferFunction to fill the LUT), the rendering time is 3 seconds.

I can’t test under Visual Studio, for now. I don’t know how to profile a code under Linux.

In ParaView, I don’t know how vtkPVDiscretizableColorTransferFunction is being used as there’s many layers between the class and the GUI. But it renders fast the result (when Discretize checkbox is checked).

---

<div class="post-metadata">

### Author: ![lassoan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lassoan/32/50_2.png) [@lassoan](https://discourse.vtk.org/u/lassoan)
#### Post date: [January 24, 2019, 3:18pm UTC](https://discourse.vtk.org/t/demystifiying-color-discretization/117/4 "2019-01-24T15:18:03Z")

</div>

> [@embeddedmz](#):
>
> how to profile a code under Linux

It is a skill that is worth learning. You should be able to find lots of tutorials on the web.

---

<div class="post-metadata">

### Author: ![embeddedmz](https://discourse.vtk.org/user_avatar/discourse.vtk.org/embeddedmz/32/12_2.png) [@embeddedmz](https://discourse.vtk.org/u/embeddedmz)
#### Post date: [January 24, 2019, 3:20pm UTC](https://discourse.vtk.org/t/demystifiying-color-discretization/117/5 "2019-01-24T15:20:37Z")

</div>

OK, I will profile it when I find free time.

---

<div class="post-metadata">

### Author: ![embeddedmz](https://discourse.vtk.org/user_avatar/discourse.vtk.org/embeddedmz/32/12_2.png) [@embeddedmz](https://discourse.vtk.org/u/embeddedmz)
#### Post date: [January 24, 2019, 5:08pm UTC](https://discourse.vtk.org/t/demystifiying-color-discretization/117/6 "2019-01-24T17:08:15Z")

</div>

I profiled the application using valgrind and I noticed that vtkDiscretizableColorTransferFunction’s “Build”, “MTime” and “GetColor” methods are being called many times (for my example respectively 174 097 665, 174 097 664 and 174 097 663). And as this class uses vtkLookupTable, there’s 3 methods that are called also 174 million times…

That’s strange as in my code “Build” is called only one time with the first vtkImageData I render (to retrieve the data range from this last and use it when adding RGB points) :

```
        static bool s_bLUTInit = false;
        if (!s_bLUTInit)
        {
            double range[2];
            imgData->GetPointData()->GetArray(0)->GetRange(range);

            discretTF->DiscretizeOn();
            discretTF->SetNumberOfValues(256);
            discretTF->IndexedLookupOff();
            const double scale = range[1] - range[0];
            discretTF->AddRGBPoint(0* scale + range[0], 0.23137254902, 0.298039215686, 0.752941176471);
            discretTF->AddRGBPoint(0.5* scale + range[0], 0.865, 0.865, 0.865);
            discretTF->AddRGBPoint(1* scale + range[0], 0.705882352941, 0.0156862745098, 0.149019607843);
            discretTF->Build();
            chart->SetTransferFunction(discretTF.Get());

            s_bLUTInit = true;
        } 

```

And to refresh the chart (e.g. a vtkChartHistogram2D), I just call

> chart-\>SetInputData(imgData);  
> chart-\>RecalculateBounds();  
> pRenderWindow-\>Render();

The code above is called in a loop, where I retrieve from a reader a vtkImageData.

To sum up, with the first code I posted, I don’t have a slow rendering (vtkLookupTable + vtkColorTransferFunction), but when using vtkDiscretizableColorTransferFunction the rendering is very slow as each time when I change the vtkImageData fed to the vtkChartHistogram2D (or even a vtkImageActor + vtkImageMapToColors), the vtkDiscretizableColorTransferFunction is rebuilt again and again.

How to prevent that constant rebuilding ? why I don’t have this issue when using vtkLookupTable (first code) ?

---

<div class="post-metadata">

### Author: ![lassoan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lassoan/32/50_2.png) [@lassoan](https://discourse.vtk.org/u/lassoan)
#### Post date: [January 24, 2019, 5:10pm UTC](https://discourse.vtk.org/t/demystifiying-color-discretization/117/7 "2019-01-24T17:10:54Z")

</div>

You can put a breakpoint in Build method and see why it is called (you can step back in the stack trace to see what method called it and why).

---

<div class="post-metadata">

### Author: ![embeddedmz](https://discourse.vtk.org/user_avatar/discourse.vtk.org/embeddedmz/32/12_2.png) [@embeddedmz](https://discourse.vtk.org/u/embeddedmz)
#### Post date: [January 24, 2019, 5:15pm UTC](https://discourse.vtk.org/t/demystifiying-color-discretization/117/8 "2019-01-24T17:15:22Z")

</div>

The build method is called, but as BuildTime \> GetMTime() it returns immediately. So the problem is elsewhere.

---

<div class="post-metadata">

### Author: ![embeddedmz](https://discourse.vtk.org/user_avatar/discourse.vtk.org/embeddedmz/32/12_2.png) [@embeddedmz](https://discourse.vtk.org/u/embeddedmz)
#### Post date: [January 24, 2019, 5:32pm UTC](https://discourse.vtk.org/t/demystifiying-color-discretization/117/9 "2019-01-24T17:32:34Z")

</div>

I noticed that with vtkDiscretizable…, the method used to map values is GetColor, this last use MapValue(v) many times 174 millions times etc… callstack :

```
 1 vtkLookupTable::MapValue vtkLookupTable.cxx 707 0x7fc651a2984d 
2 vtkLookupTable::GetColor vtkLookupTable.cxx 352 0x7fc651a1012d 
3 vtkColorTransferFunctionMapData<char> vtkColorTransferFunction.cxx 1364 0x7fc65560c4bd 
4 vtkColorTransferFunction::MapScalarsThroughTable2 vtkColorTransferFunction.cxx 1706 0x7fc6555fb254 
5 vtkPlotHistogram2D::GenerateHistogram vtkPlotHistogram2D.cxx 265 0x484480       
6 vtkPlotHistogram2D::Update vtkPlotHistogram2D.cxx 44 0x48355e       
7 vtkChartHistogram2D::Update vtkChartHistogram2D.cxx 58 0x7fc65a886f74 
8 vtkChartXY::Paint vtkChartXY.cxx 385 0x7fc65a8957bd 
9 PaintItems vtkContextScenePrivate.h 89 0x7fc65a60e3fd 
10 vtkContextScene::Paint vtkContextScene.cxx 125 0x7fc65a60e3fd 
11 vtkContextActor::RenderOverlay vtkContextActor.cxx 220 0x7fc65a6088ee 
12 vtkOpenGLContextActor::RenderOverlay vtkOpenGLContextActor.cxx 73 0x7fc660903eb9 
13 vtkOpenGLRenderer::UpdateGeometry vtkOpenGLRenderer.cxx 262 0x7fc65be14f2f 
14 vtkOpenGLRenderer::DeviceRender vtkOpenGLRenderer.cxx 166 0x7fc65be14330 
15 vtkRenderer::Render vtkRenderer.cxx 338 0x7fc65569f644 
16 vtkRendererCollection::Render vtkRendererCollection.cxx 51 0x7fc65569d77a 
17 vtkRenderWindow::DoStereoRender vtkRenderWindow.cxx 768 0x7fc6556af1a5 
18 vtkRenderWindow::DoFDRender vtkRenderWindow.cxx 737 0x7fc6556afdb7 
19 vtkRenderWindow::DoAARender vtkRenderWindow.cxx 616 0x7fc6556af9be 
20 vtkRenderWindow::Render vtkRenderWindow.cxx 432 0x7fc6556b0db3 
... <More>                                                                                             

```

Whereas with the solution I made, it’s the vtkLookupTable::MapScalarsThroughTable2 that is used, and is only called 137 times. callstack :

```
1 vtkLookupTable::MapScalarsThroughTable2 vtkLookupTable.cxx 1142 0x7f9e8564d943 
2 vtkPlotHistogram2D::GenerateHistogram vtkPlotHistogram2D.cxx 265 0x48427e       
3 vtkPlotHistogram2D::Update vtkPlotHistogram2D.cxx 44 0x48335c       
4 vtkChartHistogram2D::Update vtkChartHistogram2D.cxx 58 0x7f9e8e4a9f74 
5 vtkChartXY::Paint vtkChartXY.cxx 385 0x7f9e8e4b87bd 
6 PaintItems vtkContextScenePrivate.h 89 0x7f9e8e2313fd 
7 vtkContextScene::Paint vtkContextScene.cxx 125 0x7f9e8e2313fd 
8 vtkContextActor::RenderOverlay vtkContextActor.cxx 220 0x7f9e8e22b8ee 
9 vtkOpenGLContextActor::RenderOverlay vtkOpenGLContextActor.cxx 73 0x7f9e94526eb9 
10 vtkOpenGLRenderer::UpdateGeometry vtkOpenGLRenderer.cxx 262 0x7f9e8fa37f2f 
11 vtkOpenGLRenderer::DeviceRender vtkOpenGLRenderer.cxx 166 0x7f9e8fa37330 
12 vtkRenderer::Render vtkRenderer.cxx 338 0x7f9e892c2644 
13 vtkRendererCollection::Render vtkRendererCollection.cxx 51 0x7f9e892c077a 
14 vtkRenderWindow::DoStereoRender vtkRenderWindow.cxx 768 0x7f9e892d21a5 
15 vtkRenderWindow::DoFDRender vtkRenderWindow.cxx 737 0x7f9e892d2db7 
16 vtkRenderWindow::DoAARender vtkRenderWindow.cxx 616 0x7f9e892d29be 
17 vtkRenderWindow::Render vtkRenderWindow.cxx 432 0x7f9e892d3db3 
18 vtkXOpenGLRenderWindow::Render vtkXOpenGLRenderWindow.cxx 1856 0x7f9e8fae9ce1 
19 main main.cpp 642 0x466c21
```

---

<div class="post-metadata">

### Author: ![embeddedmz](https://discourse.vtk.org/user_avatar/discourse.vtk.org/embeddedmz/32/12_2.png) [@embeddedmz](https://discourse.vtk.org/u/embeddedmz)
#### Post date: [January 24, 2019, 5:42pm UTC](https://discourse.vtk.org/t/demystifiying-color-discretization/117/10 "2019-01-24T17:42:20Z")

</div>

I am not sure maybe ParaView is using effectively a vtkLookupTable under the hood. But the question remains, the vtkDiscretizable… is named discretizable but in fact, it doesn’t provide that feature as it’s slow… If someone can demystify to me this crazy stuff, that would be great !

---

<div class="post-metadata">

### Author: ![embeddedmz](https://discourse.vtk.org/user_avatar/discourse.vtk.org/embeddedmz/32/12_2.png) [@embeddedmz](https://discourse.vtk.org/u/embeddedmz)
#### Post date: [March 12, 2019, 12:07pm UTC](https://discourse.vtk.org/t/demystifiying-color-discretization/117/11 "2019-03-12T12:07:24Z")

</div>

Up (I really want to clarify the subject)…

---

<div class="post-metadata">

### Author: ![embeddedmz](https://discourse.vtk.org/user_avatar/discourse.vtk.org/embeddedmz/32/12_2.png) [@embeddedmz](https://discourse.vtk.org/u/embeddedmz)
#### Post date: [March 14, 2019, 2:57pm UTC](https://discourse.vtk.org/t/demystifiying-color-discretization/117/12 "2019-03-14T14:57:18Z")

</div>

I found the answer : in the older versions of VTK, MapScalarsThroughTable2 is not overriden for vtkDiscretizableColorTransferFunction, thus it uses the vtkColorTransferFunction version. it must be overriden to use the MapScalarsThroughTable2 of its member LookupTable (vtkLookupTable) when `Discretize` mode is enabled.
