BUG: Removed all iteratorless traverse of shared collections
Collections have convenience functions for traversing it without the need for creating an iterator, using InitTraversal() and GetNextItemAsObject(). These functions use an internal iterator stored in the collection.
Problem:
When a collection is traversed using the internal iterator by multiple functions at the same time, the behavior will be incorrect.
For collections that can be accessed by multiple objects, it is almost impossible to make sure that only one function will use the internal iterator at a time. Therefore, shared collections must be traversed using external iterators.
For example, this error caused a bug in View Controllers module: it only showed the first slice view controller (while there were three). The problem was that View Controllers module iterated through the nodes using the internal iterator and internally a method was called that asked for a list of nodes by classname, which used the same internal iterator.
Solution:
- Made vtkMRMLScene's InitTraversal, GetNextNode, and GetNextNodeByClass methods deprecated (they are still functional, but log a warning when they are called).
- Replaced all instances of shared collection traversal with internal iterator.
- Added vtkMRMLScene::GetFirstNodeByClass convenience function and modified functions that used InitTraversal/GetNextNodeByClass or GetNthNodeByClass(0, ...) to use this function.