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 
28 namespace vtk
29 {
30 
31 // Pass these to vtk::Range(cds, options):
32 enum 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 
42 VTK_GENERATE_BITFLAG_OPS(vtk::DataObjectTreeOptions)
43 
44 namespace vtk
45 {
46 
47 namespace detail
48 {
49 
50 struct DataObjectTreeRange;
51 struct DataObjectTreeIterator;
52 
55 
57  : public std::iterator<std::forward_iterator_tag, vtkDataObject*, int,
58  DataObjectTreeIteratorReference, DataObjectTreeIteratorReference>
59 {
60 private:
61  using Superclass = std::iterator<std::forward_iterator_tag, vtkDataObject*, int,
62  DataObjectTreeIteratorReference, DataObjectTreeIteratorReference>;
65 
66 public:
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 
79  DataObjectTreeIterator(DataObjectTreeIterator&&) noexcept = default;
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 
142 protected:
143  // Note: This takes ownership of iter and manages its lifetime.
144  // Iter should not be used past this point by the caller.
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 
157 private:
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 {
203 private:
206 
207 public:
208  using size_type = int;
213  using value_type = vtkDataObject*;
214 
216  vtkDataObjectTree* cds, DataObjectTreeOptions opts = DataObjectTreeOptions::None)
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.
228  size_type size() const
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 
251 private:
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
vtkDataObjectTree * GetDataObjectTree() const noexcept
typename Superclass::value_type value_type
provides implementation for most abstract methods in the superclass vtkCompositeDataSet ...
vtk::CompositeDataSetNodeReference< vtkDataObjectTreeIterator, DataObjectTreeIterator > DataObjectTreeIteratorReference
typename Superclass::iterator_category iterator_category
DataObjectTreeIterator operator++(int)
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
DataObjectTreeOptions GetOptions() const noexcept
DataObjectTreeIterator(const DataObjectTreeIterator &o)
This file contains a variety of metaprogramming constructs for working with vtk types.
int IsDoneWithTraversal() override
Test whether the iterator is finished with the traversal.
friend bool operator==(const DataObjectTreeIterator &lhs, const DataObjectTreeIterator &rhs)
friend bool operator!=(const DataObjectTreeIterator &lhs, const DataObjectTreeIterator &rhs)
typename Superclass::pointer pointer
DataObjectTreeRange(vtkDataObjectTree *cds, DataObjectTreeOptions opts=DataObjectTreeOptions::None)
typename Superclass::reference reference
boost::graph_traits< vtkGraph * >::vertex_descriptor source(boost::graph_traits< vtkGraph * >::edge_descriptor e, vtkGraph *)
unsigned int GetCurrentFlatIndex() override
Flat index is an index obtained by traversing the tree in preorder.
vtkSmartPointer< vtkDataArray > GetData(const Ioss::GroupingEntity *entity, const std::string &fieldname, Ioss::Transform *transform=nullptr, Cache *cache=nullptr, const std::string &cachekey=std::string())
Returns a VTK array for a given field (fieldname) on the chosen block (or set) entity.
A reference proxy into a vtkCompositeDataSet, obtained by dereferencing an iterator from the vtk::Ran...
superclass for composite data iterators
typename Superclass::difference_type difference_type
friend void swap(DataObjectTreeIterator &lhs, DataObjectTreeIterator &rhs) noexcept
DataObjectTreeIterator(SmartIterator &&iter) noexcept
general representation of visualization data
Definition: vtkDataObject.h:65