VTK  9.3.0
vtkDataObjectTreeRange.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-License-Identifier: BSD-3-Clause
3 
4 #ifndef vtkDataObjectTreeRange_h
5 #define vtkDataObjectTreeRange_h
6 
8 #include "vtkDataObjectTree.h"
10 #include "vtkMeta.h"
11 #include "vtkRange.h"
12 #include "vtkSmartPointer.h"
13 
14 #include <cassert>
15 
16 namespace vtk
17 {
18 VTK_ABI_NAMESPACE_BEGIN
19 
20 // Pass these to vtk::Range(cds, options):
21 enum class DataObjectTreeOptions : unsigned int
22 {
23  None = 0,
24  SkipEmptyNodes = 1 << 1, // Skip null datasets.
25  VisitOnlyLeaves = 1 << 2, // Skip child composite datasets.
26  TraverseSubTree = 1 << 3, // Descend into child composite datasets.
27 };
28 
29 VTK_ABI_NAMESPACE_END
30 } // end namespace vtk (for bitflag op definition)
31 
32 VTK_ABI_NAMESPACE_BEGIN
33 VTK_GENERATE_BITFLAG_OPS(vtk::DataObjectTreeOptions)
34 VTK_ABI_NAMESPACE_END
35 
36 namespace vtk
37 {
38 namespace detail
39 {
40 VTK_ABI_NAMESPACE_BEGIN
41 
42 struct DataObjectTreeRange;
43 struct DataObjectTreeIterator;
44 
47 
49 {
50 private:
53 
54 public:
55  using iterator_category = std::forward_iterator_tag;
57  using difference_type = int;
60 
62  : Iterator(o.Iterator ? SmartIterator::Take(o.Iterator->NewInstance()) : nullptr)
63  {
64  this->CopyState(o.Iterator);
65  }
66 
68 
70  {
71  this->Iterator = o.Iterator ? SmartIterator::Take(o.Iterator->NewInstance()) : nullptr;
72  this->CopyState(o.Iterator);
73  return *this;
74  }
75 
77  {
78  this->Increment();
79  return *this;
80  }
81 
83  {
84  DataObjectTreeIterator other(*this);
85  this->Increment();
86  return other;
87  }
88 
89  reference operator*() const { return this->GetData(); }
90 
91  pointer operator->() const { return this->GetData(); }
92 
93  friend bool operator==(const DataObjectTreeIterator& lhs, const DataObjectTreeIterator& rhs)
94  {
95  // A null internal iterator means it is an 'end' sentinal.
96  InternalIterator* l = lhs.Iterator;
97  InternalIterator* r = rhs.Iterator;
98 
99  if (!r && !l)
100  { // end == end
101  return true;
102  }
103  else if (!r)
104  { // right is end
105  return l->IsDoneWithTraversal() != 0;
106  }
107  else if (!l)
108  { // left is end
109  return r->IsDoneWithTraversal() != 0;
110  }
111  else
112  { // Both iterators are valid, check unique idx:
113  return r->GetCurrentFlatIndex() == l->GetCurrentFlatIndex();
114  }
115  }
116 
117  friend bool operator!=(const DataObjectTreeIterator& lhs, const DataObjectTreeIterator& rhs)
118  {
119  return !(lhs == rhs); // let the compiler handle this one =)
120  }
121 
122  friend void swap(DataObjectTreeIterator& lhs, DataObjectTreeIterator& rhs) noexcept
123  {
124  using std::swap;
125  swap(lhs.Iterator, rhs.Iterator);
126  }
127 
128  friend struct DataObjectTreeRange;
129 
130 protected:
131  // Note: This takes ownership of iter and manages its lifetime.
132  // Iter should not be used past this point by the caller.
134  : Iterator(std::move(iter))
135  {
136  }
137 
138  // Note: Iterators constructed using this ctor will be considered
139  // 'end' iterators via a sentinal pattern.
141  : Iterator{ nullptr }
142  {
143  }
144 
145 private:
146  void CopyState(InternalIterator* source)
147  {
148  if (source)
149  {
150  assert(this->Iterator != nullptr);
151  this->Iterator->SetDataSet(source->GetDataSet());
152  this->Iterator->SetSkipEmptyNodes(source->GetSkipEmptyNodes());
153  this->Iterator->SetVisitOnlyLeaves(source->GetVisitOnlyLeaves());
154  this->Iterator->SetTraverseSubTree(source->GetTraverseSubTree());
155  this->Iterator->InitTraversal();
156  this->AdvanceTo(source->GetCurrentFlatIndex());
157  }
158  }
159 
160  void AdvanceTo(const unsigned int flatIdx)
161  {
162  assert(this->Iterator != nullptr);
163  assert(this->Iterator->GetCurrentFlatIndex() <= flatIdx);
164  while (this->Iterator->GetCurrentFlatIndex() < flatIdx)
165  {
166  this->Increment();
167  }
168  }
169 
170  void Increment()
171  {
172  assert(this->Iterator != nullptr);
173  assert(!this->Iterator->IsDoneWithTraversal());
174  this->Iterator->GoToNextItem();
175  }
176 
178  {
179  assert(this->Iterator != nullptr);
180  assert(!this->Iterator->IsDoneWithTraversal());
181  return DataObjectTreeIteratorReference{ this->Iterator };
182  }
183 
184  mutable SmartIterator Iterator;
185 };
186 
187 //------------------------------------------------------------------------------
188 // DataObjectTree range proxy.
190 {
191 private:
194 
195 public:
196  using size_type = int;
202 
205  : DataObjectTree(cds)
206  , Options(opts)
207  {
208  assert(this->DataObjectTree);
209  }
210 
211  vtkDataObjectTree* GetDataObjectTree() const noexcept { return this->DataObjectTree; }
212 
213  DataObjectTreeOptions GetOptions() const noexcept { return this->Options; }
214 
215  // This is O(N), since the size requires traversal due to various options.
216  size_type size() const
217  {
218  size_type result = 0;
219  auto iter = this->NewIterator();
220  iter->InitTraversal();
221  while (!iter->IsDoneWithTraversal())
222  {
223  ++result;
224  iter->GoToNextItem();
225  }
226  return result;
227  }
228 
229  iterator begin() const { return DataObjectTreeIterator{ this->NewIterator() }; }
230 
231  iterator end() const { return DataObjectTreeIterator{}; }
232 
233  // Note: These return mutable objects because const vtkObject are unusable.
234  const_iterator cbegin() const { return DataObjectTreeIterator{ this->NewIterator() }; }
235 
236  // Note: These return mutable objects because const vtkObjects are unusable.
238 
239 private:
240  SmartIterator NewIterator() const
241  {
242  using Opts = vtk::DataObjectTreeOptions;
243 
244  auto result = SmartIterator::Take(this->DataObjectTree->NewTreeIterator());
245  result->SetSkipEmptyNodes((this->Options & Opts::SkipEmptyNodes) != Opts::None);
246  result->SetVisitOnlyLeaves((this->Options & Opts::VisitOnlyLeaves) != Opts::None);
247  result->SetTraverseSubTree((this->Options & Opts::TraverseSubTree) != Opts::None);
248  result->InitTraversal();
249  return result;
250  }
251 
252  mutable vtkSmartPointer<vtkDataObjectTree> DataObjectTree;
253  DataObjectTreeOptions Options;
254 };
255 
256 VTK_ABI_NAMESPACE_END
257 }
258 } // end namespace vtk::detail
259 
260 #endif // vtkDataObjectTreeRange_h
261 
262 // 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:55
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...
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.
vtk::CompositeDataSetNodeReference< vtkDataObjectTreeIterator, DataObjectTreeIterator > DataObjectTreeIteratorReference
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
DataObjectTreeIterator(const DataObjectTreeIterator &o)
DataObjectTreeIterator(DataObjectTreeIterator &&) noexcept=default
DataObjectTreeIterator operator++(int)
DataObjectTreeIterator(SmartIterator &&iter) noexcept
friend bool operator!=(const DataObjectTreeIterator &lhs, const DataObjectTreeIterator &rhs)
std::forward_iterator_tag iterator_category
friend bool operator==(const DataObjectTreeIterator &lhs, const DataObjectTreeIterator &rhs)
friend void swap(DataObjectTreeIterator &lhs, DataObjectTreeIterator &rhs) noexcept
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 *)
This file contains a variety of metaprogramming constructs for working with vtk types.