VTK  9.2.6
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
28namespace vtk
29{
30
31// Pass these to vtk::Range(cds, options):
32enum class DataObjectTreeOptions : unsigned int
33{
34 None = 0,
35 SkipEmptyNodes = 1 << 1, // Skip null datasets.
36 VisitOnlyLeaves = 1 << 2, // Skip child composite datasets.
37 TraverseSubTree = 1 << 3, // Descend into child composite datasets.
38};
39
40} // end namespace vtk (for bitflag op definition)
41
42VTK_GENERATE_BITFLAG_OPS(vtk::DataObjectTreeOptions)
43
44namespace vtk
45{
46
47namespace detail
48{
49
52
55
57 : public std::iterator<std::forward_iterator_tag, vtkDataObject*, int,
58 DataObjectTreeIteratorReference, DataObjectTreeIteratorReference>
59{
60private:
61 using Superclass = std::iterator<std::forward_iterator_tag, vtkDataObject*, int,
63 using InternalIterator = vtkDataObjectTreeIterator;
64 using SmartIterator = vtkSmartPointer<InternalIterator>;
65
66public:
67 using iterator_category = typename Superclass::iterator_category;
68 using value_type = typename Superclass::value_type;
69 using difference_type = typename Superclass::difference_type;
70 using pointer = typename Superclass::pointer;
71 using reference = typename Superclass::reference;
72
74 : Iterator(o.Iterator ? SmartIterator::Take(o.Iterator->NewInstance()) : nullptr)
75 {
76 this->CopyState(o.Iterator);
77 }
78
80
82 {
83 this->Iterator = o.Iterator ? SmartIterator::Take(o.Iterator->NewInstance()) : nullptr;
84 this->CopyState(o.Iterator);
85 return *this;
86 }
87
89 {
90 this->Increment();
91 return *this;
92 }
93
95 {
96 DataObjectTreeIterator other(*this);
97 this->Increment();
98 return other;
99 }
100
101 reference operator*() const { return this->GetData(); }
102
103 pointer operator->() const { return this->GetData(); }
104
105 friend bool operator==(const DataObjectTreeIterator& lhs, const DataObjectTreeIterator& rhs)
106 {
107 // A null internal iterator means it is an 'end' sentinal.
108 InternalIterator* l = lhs.Iterator;
109 InternalIterator* r = rhs.Iterator;
110
111 if (!r && !l)
112 { // end == end
113 return true;
114 }
115 else if (!r)
116 { // right is end
117 return l->IsDoneWithTraversal() != 0;
118 }
119 else if (!l)
120 { // left is end
121 return r->IsDoneWithTraversal() != 0;
122 }
123 else
124 { // Both iterators are valid, check unique idx:
125 return r->GetCurrentFlatIndex() == l->GetCurrentFlatIndex();
126 }
127 }
128
129 friend bool operator!=(const DataObjectTreeIterator& lhs, const DataObjectTreeIterator& rhs)
130 {
131 return !(lhs == rhs); // let the compiler handle this one =)
132 }
133
134 friend void swap(DataObjectTreeIterator& lhs, DataObjectTreeIterator& rhs) noexcept
135 {
136 using std::swap;
137 swap(lhs.Iterator, rhs.Iterator);
138 }
139
140 friend struct DataObjectTreeRange;
141
142protected:
143 // Note: This takes ownership of iter and manages its lifetime.
144 // Iter should not be used past this point by the caller.
145 DataObjectTreeIterator(SmartIterator&& iter) noexcept
146 : Iterator(std::move(iter))
147 {
148 }
149
150 // Note: Iterators constructed using this ctor will be considered
151 // 'end' iterators via a sentinal pattern.
153 : Iterator{ nullptr }
154 {
155 }
156
157private:
158 void CopyState(InternalIterator* source)
159 {
160 if (source)
161 {
162 assert(this->Iterator != nullptr);
163 this->Iterator->SetDataSet(source->GetDataSet());
164 this->Iterator->SetSkipEmptyNodes(source->GetSkipEmptyNodes());
165 this->Iterator->SetVisitOnlyLeaves(source->GetVisitOnlyLeaves());
166 this->Iterator->SetTraverseSubTree(source->GetTraverseSubTree());
167 this->Iterator->InitTraversal();
168 this->AdvanceTo(source->GetCurrentFlatIndex());
169 }
170 }
171
172 void AdvanceTo(const unsigned int flatIdx)
173 {
174 assert(this->Iterator != nullptr);
175 assert(this->Iterator->GetCurrentFlatIndex() <= flatIdx);
176 while (this->Iterator->GetCurrentFlatIndex() < flatIdx)
177 {
178 this->Increment();
179 }
180 }
181
182 void Increment()
183 {
184 assert(this->Iterator != nullptr);
185 assert(!this->Iterator->IsDoneWithTraversal());
186 this->Iterator->GoToNextItem();
187 }
188
189 DataObjectTreeIteratorReference GetData() const
190 {
191 assert(this->Iterator != nullptr);
192 assert(!this->Iterator->IsDoneWithTraversal());
193 return DataObjectTreeIteratorReference{ this->Iterator };
194 }
195
196 mutable SmartIterator Iterator;
197};
198
199//------------------------------------------------------------------------------
200// DataObjectTree range proxy.
202{
203private:
204 using InternalIterator = vtkDataObjectTreeIterator;
205 using SmartIterator = vtkSmartPointer<InternalIterator>;
206
207public:
208 using size_type = int;
214
217 : DataObjectTree(cds)
218 , Options(opts)
219 {
220 assert(this->DataObjectTree);
221 }
222
223 vtkDataObjectTree* GetDataObjectTree() const noexcept { return this->DataObjectTree; }
224
225 DataObjectTreeOptions GetOptions() const noexcept { return this->Options; }
226
227 // This is O(N), since the size requires traversal due to various options.
229 {
230 size_type result = 0;
231 auto iter = this->NewIterator();
232 iter->InitTraversal();
233 while (!iter->IsDoneWithTraversal())
234 {
235 ++result;
236 iter->GoToNextItem();
237 }
238 return result;
239 }
240
241 iterator begin() const { return DataObjectTreeIterator{ this->NewIterator() }; }
242
243 iterator end() const { return DataObjectTreeIterator{}; }
244
245 // Note: These return mutable objects because const vtkObject are unusable.
246 const_iterator cbegin() const { return DataObjectTreeIterator{ this->NewIterator() }; }
247
248 // Note: These return mutable objects because const vtkObjects are unusable.
250
251private:
252 SmartIterator NewIterator() const
253 {
254 using Opts = vtk::DataObjectTreeOptions;
255
256 auto result = SmartIterator::Take(this->DataObjectTree->NewTreeIterator());
257 result->SetSkipEmptyNodes((this->Options & Opts::SkipEmptyNodes) != Opts::None);
258 result->SetVisitOnlyLeaves((this->Options & Opts::VisitOnlyLeaves) != Opts::None);
259 result->SetTraverseSubTree((this->Options & Opts::TraverseSubTree) != Opts::None);
260 result->InitTraversal();
261 return result;
262 }
263
264 mutable vtkSmartPointer<vtkDataObjectTree> DataObjectTree;
265 DataObjectTreeOptions Options;
266};
267
268}
269} // end namespace vtk::detail
270
271#endif // vtkDataObjectTreeRange_h
272
273// 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,...
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
Hold a reference to a vtkObjectBase instance.
static vtkSmartPointer< InternalIterator > Take(InternalIterator *t)
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(SmartIterator &&iter) noexcept
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)
const DataObjectTreeIteratorReference const_reference
DataObjectTreeIteratorReference reference
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.