# How to setup an Indexed vtkLookupTable?

**URL:** https://discourse.vtk.org/t/how-to-setup-an-indexed-vtklookuptable/11416
**Category:** Support
**Created:** [May 9, 2023, 1:08pm UTC](https://discourse.vtk.org/t/how-to-setup-an-indexed-vtklookuptable/11416 "2023-05-09T13:08:53Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![Seun](https://discourse.vtk.org/user_avatar/discourse.vtk.org/seun/32/767_2.png) [@Seun](https://discourse.vtk.org/u/Seun)
#### Post date: [May 9, 2023, 1:08pm UTC](https://discourse.vtk.org/t/how-to-setup-an-indexed-vtklookuptable/11416/1 "2023-05-09T13:08:53Z")

</div>

Hello everyone,

I was wondering if someone could point me in the right direction as to how to setup a vtkLooupTable that’s indexed.

My basic idea is

```auto
vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
lut->SetNumberOfTableValues(255);
lut->SetIndexedLookup(true);

// I have a buffer externally created, that holds all 255 [rgba] values.

// I have 255 (RGBA) colours that I iterate over
for(int idx = 0; idx < 255; idx++)
{
   double r = buffer[4 * idx + 0];
   double g = buffer[4 * idx + 1];
   double b = buffer[4 * idx + 2];
   double a = buffer[4 * idx + 3]; // safely assuming all alphas = 1.0
   lut->SetTableValue((vtkIdType)idx, r, g, b, a); 

   std::string annotatedName = "# " + std::to_string(idx);
   lut->SetAnnotation( vtkVariant(idx) , annotatedName );
}

// min, max are values passed to this function.
lut->SetTableRange(min, max);
lut->Build();

return lut;

```

Is this the proper way of creating an indexed lookupTable?

---

<div class="post-metadata">

### Author: ![Paulo\_Carvalho](https://discourse.vtk.org/user_avatar/discourse.vtk.org/paulo_carvalho/32/370_2.png) [@Paulo\_Carvalho](https://discourse.vtk.org/u/Paulo_Carvalho)
#### Post date: [May 9, 2023, 9:31pm UTC](https://discourse.vtk.org/t/how-to-setup-an-indexed-vtklookuptable/11416/2 "2023-05-09T21:31:07Z")

</div>

Hello,

I believe you stumbled upon VTK’s indexed LUT caveat: you can’t skip index numbers, otherwise it misbehaves. At least that is what I found when I tried to create a LUT for categorical variables. In my case, the user can assign random unordered integers to the rock types (e.g. 1 for sandstone; 5 for shale; 2 for basalt; 13 for silt; etc.). Here’s how I build LUTs for discrete, unordered variables:

```cpp
    //determine the greatest categorical code
    //cd -> category definition table (user-defined rock type names, integer codes and RGB colors).
    int maxCatCode = 0;
    for( int i = 0; i < catCount; ++i )
        maxCatCode = std::max<int>( maxCatCode, cd->getCategoryCode(i) );

    //table color indexes must go from 0 to greatest facies code, without skipping values
    size_t tableSize = maxCatCode + 1;
    vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New();
    lut->SetNumberOfTableValues(tableSize);

    //but assign only the codes defined in the category definition
    //which may be less than the total number of entries in the color table
    //this is a requirement by the way VTK's LUT work for categorical color tables
    for(size_t i = 0; i < tableSize; ++i)
    {
        if( cd->codeExists( i ) ){ //category code exists
            double rgb[3];
            QColor color;
            int catIndex = cd->getCategoryIndex( i );
            color = cd->getCustomColor( catIndex );
            rgb[0] = color.redF();
            rgb[1] = color.greenF();
            rgb[2] = color.blueF();
            lut->SetTableValue(i, rgb[0], rgb[1], rgb[2], 1.0);
            lut->SetAnnotation(i, QString::number(i).toStdString() );
        } else { //category code is not defined
            lut->SetTableValue(i, 1.0, 0.0, 1.0, alphaForNotFound); //illegal color codes are rendered as pink transparent.
            lut->SetAnnotation(i, "UNKNOWN CATEGORY" );
        }
    }
    lut->SetNanColor( 1.0, 0.0, 1.0, alphaForNaN ); //unvalued locations are also rendered as pink transparent.
    lut->IndexedLookupOn();
    lut->Build();

    return lut;

```

I hope this helps,

PC

---

<div class="post-metadata">

### Author: ![Paulo\_Carvalho](https://discourse.vtk.org/user_avatar/discourse.vtk.org/paulo_carvalho/32/370_2.png) [@Paulo\_Carvalho](https://discourse.vtk.org/u/Paulo_Carvalho)
#### Post date: [May 9, 2023, 9:40pm UTC](https://discourse.vtk.org/t/how-to-setup-an-indexed-vtklookuptable/11416/3 "2023-05-09T21:40:40Z")

</div>

I use indexed LUTs to render categorical variables like rock type maps/surfaces:

 ![image](https://discourse.vtk.org/uploads/default/original/2X/7/72b7b48877db92c11e47693302ba3387ae5de2ab.jpeg)  
Green = shale; brown = siltstone; yellow = sandstone.

---

<div class="post-metadata">

### Author: ![Seun](https://discourse.vtk.org/user_avatar/discourse.vtk.org/seun/32/767_2.png) [@Seun](https://discourse.vtk.org/u/Seun)
#### Post date: [May 10, 2023, 12:45pm UTC](https://discourse.vtk.org/t/how-to-setup-an-indexed-vtklookuptable/11416/4 "2023-05-10T12:45:19Z")

</div>

Hello Paulo,  
thanks for the detailed response. I’ll try to see if I can address my situation based on your example.  
Indeed, `VTK’s indexed LUT caveat` seems to be my issue, I just couldn’t figure out why it was misbehaving. I’ll try it out again hopefully this time I get it to work. Thanks.

---

<div class="post-metadata">

### Author: ![Seun](https://discourse.vtk.org/user_avatar/discourse.vtk.org/seun/32/767_2.png) [@Seun](https://discourse.vtk.org/u/Seun)
#### Post date: [May 11, 2023, 7:53pm UTC](https://discourse.vtk.org/t/how-to-setup-an-indexed-vtklookuptable/11416/5 "2023-05-11T19:53:47Z")

</div>

Hi Paulo,

I was able to setup an indexed lookup table following your example above, thanks.  
However, I noticed that the generation of my table seems to be slow, do you know what may cause the process to be slow.

---

<div class="post-metadata">

### Author: ![Paulo\_Carvalho](https://discourse.vtk.org/user_avatar/discourse.vtk.org/paulo_carvalho/32/370_2.png) [@Paulo\_Carvalho](https://discourse.vtk.org/u/Paulo_Carvalho)
#### Post date: [May 11, 2023, 10:17pm UTC](https://discourse.vtk.org/t/how-to-setup-an-indexed-vtklookuptable/11416/6 "2023-05-11T22:17:57Z")

</div>

Hi,

How many classes (table size) does it have?

best,

PC

---

<div class="post-metadata">

### Author: ![Paulo\_Carvalho](https://discourse.vtk.org/user_avatar/discourse.vtk.org/paulo_carvalho/32/370_2.png) [@Paulo\_Carvalho](https://discourse.vtk.org/u/Paulo_Carvalho)
#### Post date: [May 11, 2023, 10:19pm UTC](https://discourse.vtk.org/t/how-to-setup-an-indexed-vtklookuptable/11416/7 "2023-05-11T22:19:46Z")

</div>

> [@Seun](#):
>
> my table seems to be slow, do you know what may cause the process to be slow.

How much is slow? One second? One minute?

Anyway, if it is done once, it souldn’t be a nuisance.

cheers,

PC

---

<div class="post-metadata">

### Author: ![Seun](https://discourse.vtk.org/user_avatar/discourse.vtk.org/seun/32/767_2.png) [@Seun](https://discourse.vtk.org/u/Seun)
#### Post date: [May 12, 2023, 12:23pm UTC](https://discourse.vtk.org/t/how-to-setup-an-indexed-vtklookuptable/11416/8 "2023-05-12T12:23:24Z")

</div>

Hi,  
The table size is about 502. Basically I’m using a `.label.txt` file (purportedly derived from ITK SNAP) which really shouldn’t matter but I thought it be worth mentioning. There are 0-based indices all the way to 502 (some indices are missing). so In reality the total number of indices (call it points) is less than 502.

`so just as you example suggested` if I cycle through a total of `502` and `index 2 is missing then the the else branch is executed as in

```auto
lut->SetAnnotation(i, "UNKNOWN CATEGORY" );

```

it’s at least a minute sluggish if not more but I noticed that if I omit

```auto
//lut->IndexedLookupOn()

```

then it’s faster and also behaves as expected. Makes me think do I really even need to flag it as indexed. Uhm?

---

<div class="post-metadata">

### Author: ![Paulo\_Carvalho](https://discourse.vtk.org/user_avatar/discourse.vtk.org/paulo_carvalho/32/370_2.png) [@Paulo\_Carvalho](https://discourse.vtk.org/u/Paulo_Carvalho)
#### Post date: [May 12, 2023, 2:18pm UTC](https://discourse.vtk.org/t/how-to-setup-an-indexed-vtklookuptable/11416/9 "2023-05-12T14:18:03Z")

</div>

G’day,

Well, 502 classes is too much. From an application stand point that does not make any sense. In the Earth sciences, for example, typically we make subsurface models with ~20 classes (e.g. rock types) at maximum. If data from the field contains too many rock types, the geologists normally group them into so-called facies to facilitate numeric modeling. I can’t imagine a possible application for a categorical variable with 502 classes… Why don’t you use a normal LUT?

take care,

PC
