VTK  9.1.0
vtkDataObjectTreeRange.h
Go to the documentation of this file.
1/*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkDataObjectTreeRange.h
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14=========================================================================*/
15
16#ifndef vtkDataObjectTreeRange_h
17#define vtkDataObjectTreeRange_h
18
20#include "vtkDataObjectTree.h"
22#include "vtkMeta.h"
23#include "vtkRange.h"
24#include "vtkSmartPointer.h"
25
26#include <cassert>
27
28#ifndef __VTK_WRAP__
29
30namespace vtk
31{
32
33// Pass these to vtk::Range(cds, options):
34enum class DataObjectTreeOptions : unsigned int
35{
36 None = 0,
37 SkipEmptyNodes = 1 << 1, // Skip null datasets.
38 VisitOnlyLeaves = 1 << 2, // Skip child composite datasets.
39 TraverseSubTree = 1 << 3, // Descend into child composite datasets.
40};
41
42} // end namespace vtk (for bitflag op definition)
43
44VTK_GENERATE_BITFLAG_OPS(vtk::DataObjectTreeOptions)
45
46namespace vtk
47{
48
49namespace detail
50{
51
52struct DataObjectTreeRange;
53struct DataObjectTreeIterator;
54
57
59 : public std::iterator<std::forward_iterator_tag, vtkDataObject*, int,
60 DataObjectTreeIteratorReference, DataObjectTreeIteratorReference>
61{
62private:
63 using Superclass = std::iterator<std::forward_iterator_tag, vtkDataObject*, int,
67
68public:
69 using iterator_category = typename Superclass::iterator_category;
70 using value_type = typename Superclass::value_type;
71 using difference_type = typename Superclass::difference_type;
72 using pointer = typename Superclass::pointer;
73 using reference = typename Superclass::reference;
74
76 : Iterator(o.Iterator ? SmartIterator::Take(o.Iterator->NewInstance()) : nullptr)
77 {
78 this->CopyState(o.Iterator);
79 }
80
82
84 {
85 this->Iterator = o.Iterator ? SmartIterator::Take(o.Iterator->NewInstance()) : nullptr;
86 this->CopyState(o.Iterator);
87 return *this;
88 }
89
91 {
92 this->Increment();
93 return *this;
94 }
95
97 {
98 DataObjectTreeIterator other(*this);
99 this->Increment();
100 return other;
101 }
102
103 reference operator*() const { return this->GetData(); }
104
105 pointer operator->() const { return this->GetData(); }
106
107 friend bool operator==(const DataObjectTreeIterator& lhs, const DataObjectTreeIterator& rhs)
108 {
109 // A null internal iterator means it is an 'end' sentinal.
110 InternalIterator* l = lhs.Iterator;
111 InternalIterator* r = rhs.Iterator;
112
113 if (!r && !l)
114 { // end == end
115 return true;
116 }
117 else if (!r)
118 { // right is end
119 return l->IsDoneWithTraversal() != 0;
120 }
121 else if (!l)
122 { // left is end
123 return r->IsDoneWithTraversal() != 0;
124 }
125 else
126 { // Both iterators are valid, check unique idx:
127 return r->GetCurrentFlatIndex() == l->GetCurrentFlatIndex();
128 }
129 }
130
131 friend bool operator!=(const DataObjectTreeIterator& lhs, const DataObjectTreeIterator& rhs)
132 {
133 return !(lhs == rhs); // let the compiler handle this one =)
134 }
135
136 friend void swap(DataObjectTreeIterator& lhs, DataObjectTreeIterator& rhs) noexcept
137 {
138 using std::swap;
139 swap(lhs.Iterator, rhs.Iterator);
140 }
141
142 friend struct DataObjectTreeRange;
143
144protected:
145 // Note: This takes ownership of iter and manages its lifetime.
146 // Iter should not be used past this point by the caller.
148 : Iterator(std::move(iter))
149 {
150 }
151
152 // Note: Iterators constructed using this ctor will be considered
153 // 'end' iterators via a sentinal pattern.
155 : Iterator{ nullptr }
156 {
157 }
158
159private:
160 void CopyState(InternalIterator* source)
161 {
162 if (source)
163 {
164 assert(this->Iterator != nullptr);
165 this->Iterator->SetDataSet(source->GetDataSet());
166 this->Iterator->SetSkipEmptyNodes(source->GetSkipEmptyNodes());
167 this->Iterator->SetVisitOnlyLeaves(source->GetVisitOnlyLeaves());
168 this->Iterator->SetTraverseSubTree(source->GetTraverseSubTree());
169 this->Iterator->InitTraversal();
170 this->AdvanceTo(source->GetCurrentFlatIndex());
171 }
172 }
173
174 void AdvanceTo(const unsigned int flatIdx)
175 {
176 assert(this->Iterator != nullptr);
177 assert(this->Iterator->GetCurrentFlatIndex() <= flatIdx);
178 while (this->Iterator->GetCurrentFlatIndex() < flatIdx)
179 {
180 this->Increment();
181 }
182 }
183
184 void Increment()
185 {
186 assert(this->Iterator != nullptr);
187 assert(!this->Iterator->IsDoneWithTraversal());
188 this->Iterator->GoToNextItem();
189 }
190
191 DataObjectTreeIteratorReference GetData() const
192 {
193 assert(this->Iterator != nullptr);
194 assert(!this->Iterator->IsDoneWithTraversal());
195 return DataObjectTreeIteratorReference{ this->Iterator };
196 }
197
198 mutable SmartIterator Iterator;
199};
200
201//------------------------------------------------------------------------------
202// DataObjectTree range proxy.
204{
205private:
208
209public:
210 using size_type = int;
216
219 : DataObjectTree(cds)
220 , Options(opts)
221 {
222 assert(this->DataObjectTree);
223 }
224
225 vtkDataObjectTree* GetDataObjectTree() const noexcept { return this->DataObjectTree; }
226
227 DataObjectTreeOptions GetOptions() const noexcept { return this->Options; }
228
229 // This is O(N), since the size requires traversal due to various options.
231 {
232 size_type result = 0;
233 auto iter = this->NewIterator();
234 iter->InitTraversal();
235 while (!iter->IsDoneWithTraversal())
236 {
237 ++result;
238 iter->GoToNextItem();
239 }
240 return result;
241 }
242
243 iterator begin() const { return DataObjectTreeIterator{ this->NewIterator() }; }
244
245 iterator end() const { return DataObjectTreeIterator{}; }
246
247 // Note: These return mutable objects because const vtkObject are unusable.
248 const_iterator cbegin() const { return DataObjectTreeIterator{ this->NewIterator() }; }
249
250 // Note: These return mutable objects because const vtkObjects are unusable.
252
253private:
254 SmartIterator NewIterator() const
255 {
256 using Opts = vtk::DataObjectTreeOptions;
257
258 auto result = SmartIterator::Take(this->DataObjectTree->NewTreeIterator());
259 result->SetSkipEmptyNodes((this->Options & Opts::SkipEmptyNodes) != Opts::None);
260 result->SetVisitOnlyLeaves((this->Options & Opts::VisitOnlyLeaves) != Opts::None);
261 result->SetTraverseSubTree((this->Options & Opts::TraverseSubTree) != Opts::None);
262 result->InitTraversal();
263 return result;
264 }
265
266 mutable vtkSmartPointer<vtkDataObjectTree> DataObjectTree;
267 DataObjectTreeOptions Options;
268};
269
270}
271} // end namespace vtk::detail
272
273#endif // __VTK_WRAP__
274
275#endif // vtkDataObjectTreeRange_h
276
277// VTK-HeaderTest-Exclude: vtkDataObjectTreeRange.h
virtual void SetDataSet(vtkCompositeDataSet *ds)
Set the composite dataset this iterator is iterating over.
virtual void InitTraversal()
Begin iterating over the composite dataset structure.
virtual void SetSkipEmptyNodes(vtkTypeBool)
If SkipEmptyNodes is true, then nullptr datasets will be skipped.
superclass for composite data iterators
int IsDoneWithTraversal() override
Test whether the iterator is finished with the traversal.
virtual void SetTraverseSubTree(vtkTypeBool)
If TraverseSubTree is set to true, the iterator will visit the entire tree structure,...
void GoToNextItem() override
Move the iterator to the next item in the collection.
unsigned int GetCurrentFlatIndex() override
Flat index is an index obtained by traversing the tree in preorder.
virtual void SetVisitOnlyLeaves(vtkTypeBool)
If VisitOnlyLeaves is true, the iterator will only visit nodes (sub-datasets) that are not composite.
provides implementation for most abstract methods in the superclass vtkCompositeDataSet
virtual vtkDataObjectTreeIterator * NewTreeIterator()
Return a new iterator (the iterator has to be deleted by user).
general representation of visualization data
static vtkSmartPointer< InternalIterator > Take(InternalIterator *t)
Transfer ownership of one reference to the given VTK object to a new smart pointer.
A reference proxy into a vtkCompositeDataSet, obtained by dereferencing an iterator from the vtk::Ran...
vtk::CompositeDataSetNodeReference< vtkDataObjectTreeIterator, DataObjectTreeIterator > DataObjectTreeIteratorReference
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
typename Superclass::value_type value_type
DataObjectTreeIterator(const DataObjectTreeIterator &o)
DataObjectTreeIterator(DataObjectTreeIterator &&) noexcept=default
DataObjectTreeIterator operator++(int)
DataObjectTreeIterator(SmartIterator &&iter) noexcept
typename Superclass::pointer pointer
typename Superclass::reference reference
friend bool operator!=(const DataObjectTreeIterator &lhs, const DataObjectTreeIterator &rhs)
typename Superclass::iterator_category iterator_category
friend bool operator==(const DataObjectTreeIterator &lhs, const DataObjectTreeIterator &rhs)
friend void swap(DataObjectTreeIterator &lhs, DataObjectTreeIterator &rhs) noexcept
typename Superclass::difference_type difference_type
vtkDataObjectTree * GetDataObjectTree() const noexcept
DataObjectTreeOptions GetOptions() const noexcept
DataObjectTreeRange(vtkDataObjectTree *cds, DataObjectTreeOptions opts=DataObjectTreeOptions::None)
boost::graph_traits< vtkGraph * >::vertex_descriptor source(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)
This file contains a variety of metaprogramming constructs for working with vtk types.