"Flat index" for vtkDataObjectTree's iterators

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:

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 and then immediately incremented to 1. I only did a cursory inspection of the code though.

Thanks!

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

      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.

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:

    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.

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.

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.