VTK  9.0.1
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 
30 namespace vtk
31 {
32 
33 // Pass these to vtk::Range(cds, options):
34 enum 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 
44 VTK_GENERATE_BITFLAG_OPS(vtk::DataObjectTreeOptions)
45 
46 namespace vtk
47 {
48 
49 namespace detail
50 {
51 
52 struct DataObjectTreeRange;
53 struct DataObjectTreeIterator;
54 
57 
59  : public std::iterator<std::forward_iterator_tag, vtkDataObject*, int,
60  DataObjectTreeIteratorReference, DataObjectTreeIteratorReference>
61 {
62 private:
63  using Superclass = std::iterator<std::forward_iterator_tag, vtkDataObject*, int,
67 
68 public:
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 
144 protected:
145  // Note: This takes ownership of iter and manages its lifetime.
146  // Iter should not be used past this point by the caller.
147  DataObjectTreeIterator(SmartIterator&& iter) noexcept : Iterator(std::move(iter)) {}
148 
149  // Note: Iterators constructed using this ctor will be considered
150  // 'end' iterators via a sentinal pattern.
151  DataObjectTreeIterator() noexcept : Iterator{ nullptr } {}
152 
153 private:
154  void CopyState(InternalIterator* source)
155  {
156  if (source)
157  {
158  assert(this->Iterator != nullptr);
159  this->Iterator->SetDataSet(source->GetDataSet());
160  this->Iterator->SetSkipEmptyNodes(source->GetSkipEmptyNodes());
161  this->Iterator->SetVisitOnlyLeaves(source->GetVisitOnlyLeaves());
162  this->Iterator->SetTraverseSubTree(source->GetTraverseSubTree());
163  this->Iterator->InitTraversal();
164  this->AdvanceTo(source->GetCurrentFlatIndex());
165  }
166  }
167 
168  void AdvanceTo(const unsigned int flatIdx)
169  {
170  assert(this->Iterator != nullptr);
171  assert(this->Iterator->GetCurrentFlatIndex() <= flatIdx);
172  while (this->Iterator->GetCurrentFlatIndex() < flatIdx)
173  {
174  this->Increment();
175  }
176  }
177 
178  void Increment()
179  {
180  assert(this->Iterator != nullptr);
181  assert(!this->Iterator->IsDoneWithTraversal());
182  this->Iterator->GoToNextItem();
183  }
184 
185  DataObjectTreeIteratorReference GetData() const
186  {
187  assert(this->Iterator != nullptr);
188  assert(!this->Iterator->IsDoneWithTraversal());
189  return DataObjectTreeIteratorReference{ this->Iterator };
190  }
191 
192  mutable SmartIterator Iterator;
193 };
194 
195 //------------------------------------------------------------------------------
196 // DataObjectTree range proxy.
198 {
199 private:
202 
203 public:
204  using size_type = int;
210 
213  : DataObjectTree(cds)
214  , Options(opts)
215  {
216  assert(this->DataObjectTree);
217  }
218 
219  vtkDataObjectTree* GetDataObjectTree() const noexcept { return this->DataObjectTree; }
220 
221  DataObjectTreeOptions GetOptions() const noexcept { return this->Options; }
222 
223  // This is O(N), since the size requires traversal due to various options.
224  size_type size() const
225  {
226  size_type result = 0;
227  auto iter = this->NewIterator();
228  iter->InitTraversal();
229  while (!iter->IsDoneWithTraversal())
230  {
231  ++result;
232  iter->GoToNextItem();
233  }
234  return result;
235  }
236 
237  iterator begin() const { return DataObjectTreeIterator{ this->NewIterator() }; }
238 
239  iterator end() const { return DataObjectTreeIterator{}; }
240 
241  // Note: These return mutable objects because const vtkObject are unusable.
242  const_iterator cbegin() const { return DataObjectTreeIterator{ this->NewIterator() }; }
243 
244  // Note: These return mutable objects because const vtkObjects are unusable.
246 
247 private:
248  SmartIterator NewIterator() const
249  {
250  using Opts = vtk::DataObjectTreeOptions;
251 
252  auto result = SmartIterator::Take(this->DataObjectTree->NewTreeIterator());
253  result->SetSkipEmptyNodes((this->Options & Opts::SkipEmptyNodes) != Opts::None);
254  result->SetVisitOnlyLeaves((this->Options & Opts::VisitOnlyLeaves) != Opts::None);
255  result->SetTraverseSubTree((this->Options & Opts::TraverseSubTree) != Opts::None);
256  result->InitTraversal();
257  return result;
258  }
259 
260  mutable vtkSmartPointer<vtkDataObjectTree> DataObjectTree;
261  DataObjectTreeOptions Options;
262 };
263 
264 }
265 } // end namespace vtk::detail
266 
267 #endif // __VTK_WRAP__
268 
269 #endif // vtkDataObjectTreeRange_h
270 
271 // 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
Definition: vtkDataObject.h:60
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...
@ reference
Definition: vtkX3D.h:470
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
DataObjectTreeOptions GetOptions() const noexcept
DataObjectTreeRange(vtkDataObjectTree *cds, DataObjectTreeOptions opts=DataObjectTreeOptions::None)
vtkDataObjectTree * GetDataObjectTree() const noexcept
boost::graph_traits< vtkGraph * >::vertex_descriptor source(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)