# "Flat index" for vtkDataObjectTree's iterators

**URL:** https://discourse.vtk.org/t/flat-index-for-vtkdataobjecttrees-iterators/7313
**Category:** Development
**Created:** [December 2, 2021, 12:43pm UTC](https://discourse.vtk.org/t/flat-index-for-vtkdataobjecttrees-iterators/7313 "2021-12-02T12:43:03Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![tigarmo](https://discourse.vtk.org/user_avatar/discourse.vtk.org/tigarmo/32/1797_2.png) [@tigarmo](https://discourse.vtk.org/u/tigarmo)
#### Post date: [December 2, 2021, 12:43pm UTC](https://discourse.vtk.org/t/flat-index-for-vtkdataobjecttrees-iterators/7313/1 "2021-12-02T12:43:04Z")

</div>

Hi everyone,

It’s my understanding that for composite objects the “flat index” refers to the “subdata” inside the composite, and that this index is 0-based as usual. Therefore, it looks like there might be a bug with vtkDataObjectTree’s iterator:

```python
from vtkmodules.vtkCommonDataModel import vtkMultiBlockDataSet
from vtkmodules.vtkFiltersSources import vtkSphereSource

def main():
    root = vtkMultiBlockDataSet()

    leaf1 = vtkSphereSource()
    leaf1.SetCenter(0, 0, 0)
    leaf1.Update()
    root.SetBlock(0, leaf1.GetOutput())

    assert root.GetNumberOfBlocks() == 1
    # This next assertion fails, because GetCurrentFlatIndex() is returning 1
    assert root.NewIterator().GetCurrentFlatIndex() == 0

if __name__ == ' __main__':
    main()

```

This is using VTK 9.1.0 from conda-forge on Windows. It looks like maybe the iterator’s flat index is being [initialized to 0](https://gitlab.kitware.com/SeunOdutola/vtk/-/blob/ArrowSourceCentralize/Common/DataModel/vtkDataObjectTreeIterator.cxx#L290) and then immediately incremented to 1. I only did a cursory inspection of the code though.

Thanks!

---

<div class="post-metadata">

### Author: ![utkarshayachit](https://discourse.vtk.org/user_avatar/discourse.vtk.org/utkarshayachit/32/379_2.png) [@utkarshayachit](https://discourse.vtk.org/u/utkarshayachit)
#### Post date: [December 2, 2021, 1:02pm UTC](https://discourse.vtk.org/t/flat-index-for-vtkdataobjecttrees-iterators/7313/2 "2021-12-02T13:02:07Z")

</div>

It’s the index of the node in pre-order traversal of the tree. For example:

```auto
      A
    / \
  B C
 / \ /|\
D E F G H

```

For this tree, the pre-order traversal yeilds `A, B, D, E, C, F, G, H`, and their indices are `0, 1, 2,...` correspondingly.

Since 0 identifies the root note, the and the iterator skips the root node hence it simply skips index 0.

---

<div class="post-metadata">

### Author: ![tigarmo](https://discourse.vtk.org/user_avatar/discourse.vtk.org/tigarmo/32/1797_2.png) [@tigarmo](https://discourse.vtk.org/u/tigarmo)
#### Post date: [December 2, 2021, 1:46pm UTC](https://discourse.vtk.org/t/flat-index-for-vtkdataobjecttrees-iterators/7313/3 "2021-12-02T13:46:17Z")

</div>

Hi, thanks for the quick reply. What you say makes sense from the point of view of the tree, but then it sort of looks to me like the API is a bit inconsistent. Unless I’m misunderstanding the purpose of the flat index, I would expect this to work:

```python
    assert root.GetNumberOfBlocks() == 1
    first = root.NewIterator().GetCurrentFlatIndex()
    assert root.GetBlock(first) is not None

```

… but since the index is effectively “1-based” the call does indeed return `None`.

For a bit more context, I found this issue when writing some picking code that uses the flat index to identify the subdata that was picked. So it looks like I should check whether the picked prop was an instance of `vtkDataObjectTree` and then subtract 1 from the returned index.

---

<div class="post-metadata">

### Author: ![utkarshayachit](https://discourse.vtk.org/user_avatar/discourse.vtk.org/utkarshayachit/32/379_2.png) [@utkarshayachit](https://discourse.vtk.org/u/utkarshayachit)
#### Post date: [December 2, 2021, 1:59pm UTC](https://discourse.vtk.org/t/flat-index-for-vtkdataobjecttrees-iterators/7313/4 "2021-12-02T13:59:23Z")

</div>

`GetBlock` doesn’t use the flat index, but simply an index for the immediate children of the `vtkMutliBlockDataSet`. Thus, in my example tree, `GetBlock(0)` on `A` will return a `vtkMultiBlockDataSet` for node `B`; and `GetBlock(1)` returns `vtkMutiBlockDataSet` for block `C`.

---

<div class="post-metadata">

### Author: ![tigarmo](https://discourse.vtk.org/user_avatar/discourse.vtk.org/tigarmo/32/1797_2.png) [@tigarmo](https://discourse.vtk.org/u/tigarmo)
#### Post date: [December 2, 2021, 7:01pm UTC](https://discourse.vtk.org/t/flat-index-for-vtkdataobjecttrees-iterators/7313/5 "2021-12-02T19:01:19Z")

</div>

> `GetBlock` doesn’t use the flat index

Thanks, I think that’s the bit I was missing. Do you know of a way that I can use this flat index to retrieve the “subitem”? The docs for `vtkCompositeDataIterator::GetCurrentFlatIndex()` seem to indicate this purpose:

> Flat index is an index to identify the data in a composite data structure.

I suppose I could iterate again on the composite structure until I found the “matching” iterator, but that seems like a roundabout way of doing this.

Thanks again for the help.
