vtkPVDataDeliveryManagerInternals.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: ParaView
4  Module: vtkPVDataDeliveryManagerInternals.h
5 
6  Copyright (c) Kitware, Inc.
7  All rights reserved.
8  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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 #ifndef vtkPVDataDeliveryManagerInternals_h
16 #define vtkPVDataDeliveryManagerInternals_h
17 #ifndef __WRAP__
18 
19 #include "vtkDataObject.h" // for vtkDataObject
20 #include "vtkInformation.h" // for vtkInformation
21 #include "vtkNew.h" // for vtkNew
23 #include "vtkPVDataRepresentation.h" // for vtkPVDataRepresentation
24 #include "vtkPVTrivialProducer.h" // for vtkPVTrivialProducer
25 #include "vtkSmartPointer.h" // for vtkSmartPointer
26 #include "vtkWeakPointer.h" // for vtkWeakPointer
27 
28 #include <cassert> // for assert
29 #include <map> // for std::map
30 #include <numeric> // for std::accumulate
31 #include <utility> // for std::pair
32 
34 {
35  friend class vtkItem;
36  std::map<int, vtkSmartPointer<vtkDataObject>> EmptyDataObjectTypes;
37 
38  // This helps us avoid creating new instances of various data object types to use as
39  // empty datasets. Instead, we build a map and keep reusing objects.
40  vtkDataObject* GetEmptyDataObject(vtkDataObject* ref)
41  {
42  if (ref)
43  {
44  auto iter = this->EmptyDataObjectTypes.find(ref->GetDataObjectType());
45  if (iter != this->EmptyDataObjectTypes.end())
46  {
47  return iter->second;
48  }
49  else
50  {
52  clone.TakeReference(ref->NewInstance());
53  this->EmptyDataObjectTypes[ref->GetDataObjectType()] = clone;
54  return clone;
55  }
56  }
57  return nullptr;
58  }
59 
60 public:
62  {
63  // Data object produced by the representation.
65 
66  // Data object available after delivery to the "rendering" node.
67  std::map<int, vtkSmartPointer<vtkDataObject>> DeliveredDataObjects;
68 
69  // Some useful meta-data.
72 
73  // Arbitrary meta-data container.
75  };
76 
77  class vtkItem
78  {
80 
81  // Store of data generated by the representation for rendering.
82  // The store keeps data at various stages of the pipeline along with
83  // relevant cache, as appropriate.
84  std::map<double, vtkRepresentedData> Data;
85 
87 
88  public:
89  vtkItem() = default;
90 
91  void ClearCache() { this->Data.clear(); }
92 
93  void SetDataObject(vtkDataObject* data, vtkInternals* helper, double cacheKey)
94  {
95  auto& store = this->Data[cacheKey];
96  if (data)
97  {
98  store.DataObject.TakeReference(data->NewInstance());
99  store.DataObject->ShallowCopy(data);
100  }
101  else
102  {
103  store.DataObject = nullptr;
104  }
105 
106  store.DeliveredDataObjects.clear();
107  store.ActualMemorySize = data ? data->GetActualMemorySize() : 0;
108  // This method gets called when data is entirely changed. That means that any
109  // data we may have delivered or redistributed would also be obsolete.
110  // Hence we reset the `Producer` as well. This avoids #2160.
111 
112  // explanation for using a clone: typically, the Producer is connected by the
113  // representation to a rendering pipeline e.g. the mapper. As that could be the
114  // case, we need to ensure the producer's input is cleaned too. Setting simply nullptr
115  // could confuse the mapper and hence we setup a data object of the same type as the data.
116  // we could simply set the data too, but that can lead to other confusion as the mapper should
117  // never directly see the representation's data.
118  this->Producer->SetOutput(helper->GetEmptyDataObject(data));
119 
120  vtkTimeStamp ts;
121  ts.Modified();
122  store.TimeStamp = ts;
123  this->TimeStamp = ts;
124  }
125 
126  void SetActualMemorySize(unsigned long size, double cacheKey)
127  {
128  auto& store = this->Data[cacheKey];
129  store.ActualMemorySize = size;
130  }
131 
132  unsigned long GetActualMemorySize(double cacheKey) const
133  {
134  auto iter = this->Data.find(cacheKey);
135  return iter != this->Data.end() ? iter->second.ActualMemorySize : 0;
136  }
137 
138  vtkDataObject* GetDeliveredDataObject(int dataKey, double cacheKey) const
139  {
140  try
141  {
142  const auto& store = this->Data.at(cacheKey);
143  return store.DeliveredDataObjects.at(dataKey);
144  }
145  catch (std::out_of_range&)
146  {
147  return nullptr;
148  }
149  }
150 
151  void SetDeliveredDataObject(int dataKey, double cacheKey, vtkDataObject* data)
152  {
153  auto& store = this->Data[cacheKey];
154  store.DeliveredDataObjects[dataKey] = data;
155  }
156 
157  vtkPVTrivialProducer* GetProducer(int dataKey, double cacheKey)
158  {
159  vtkDataObject* prev = this->Producer->GetOutputDataObject(0);
160  vtkDataObject* cur = this->GetDeliveredDataObject(dataKey, cacheKey);
161  this->Producer->SetOutput(cur);
162  if (cur != prev && cur != nullptr)
163  {
164  // this is only needed to overcome a bug in the mapper where they are
165  // using input's mtime incorrectly.
166  cur->Modified();
167  }
168  return this->Producer.GetPointer();
169  }
170 
171  vtkDataObject* GetDataObject(double cacheKey) const
172  {
173  auto iter = this->Data.find(cacheKey);
174  return iter != this->Data.end() ? iter->second.DataObject.GetPointer() : nullptr;
175  }
176 
177  vtkMTimeType GetTimeStamp(double cacheKey) const
178  {
179  auto iter = this->Data.find(cacheKey);
180  return iter != this->Data.end() ? iter->second.TimeStamp : vtkMTimeType{ 0 };
181  }
182 
184  {
185  auto& store = this->Data[cacheKey];
186  if (store.Information == nullptr)
187  {
188  store.Information = vtkSmartPointer<vtkInformation>::New();
189  }
190  return store.Information;
191  }
192 
193  vtkMTimeType GetTimeStamp() const { return this->TimeStamp; }
194  vtkMTimeType GetDeliveryTimeStamp(int dataKey, double cacheKey) const
195  {
196  if (auto dobj = this->GetDeliveredDataObject(dataKey, cacheKey))
197  {
198  return dobj->GetMTime();
199  }
200  return vtkMTimeType{ 0 };
201  }
202  };
203 
204  // First is repr unique id, second is the input port.
205  typedef std::pair<unsigned int, int> ReprPortType;
206  typedef std::map<ReprPortType, std::pair<vtkItem, vtkItem>> ItemsMapType;
207 
208  // Keep track of representation and its uid.
209  typedef std::map<unsigned int, vtkWeakPointer<vtkPVDataRepresentation>> RepresentationsMapType;
210 
211  vtkItem* GetItem(unsigned int index, bool use_second, int port, bool create_if_needed = false)
212  {
213  ReprPortType key(index, port);
214  ItemsMapType::iterator items = this->ItemsMap.find(key);
215  if (items != this->ItemsMap.end())
216  {
217  return use_second ? &(items->second.second) : &(items->second.first);
218  }
219  else if (create_if_needed)
220  {
221  std::pair<vtkItem, vtkItem>& itemsPair = this->ItemsMap[key];
222  return use_second ? &(itemsPair.second) : &(itemsPair.first);
223  }
224  return nullptr;
225  }
226 
228  vtkPVDataRepresentation* repr, bool use_second, int port, bool create_if_needed = false)
229  {
230  return this->GetItem(repr->GetUniqueIdentifier(), use_second, port, create_if_needed);
231  }
232 
234  {
235  const auto id = repr->GetUniqueIdentifier();
236  return std::accumulate(this->ItemsMap.begin(), this->ItemsMap.end(), 0,
237  [&id](int sum, const ItemsMapType::value_type& item_pair) {
238  return sum + (item_pair.first.first == id ? 1 : 0);
239  });
240  }
241 
242  unsigned long GetVisibleDataSize(bool use_second_if_available, vtkPVDataDeliveryManager* dmgr)
243  {
244  unsigned long size = 0;
245  ItemsMapType::iterator iter;
246  for (iter = this->ItemsMap.begin(); iter != this->ItemsMap.end(); ++iter)
247  {
248  const ReprPortType& key = iter->first;
249  if (!this->IsRepresentationVisible(key.first))
250  {
251  // skip hidden representations.
252  continue;
253  }
254 
255  auto repr = this->RepresentationsMap[key.first];
256  assert(repr != nullptr);
257  const double cacheKey = dmgr->GetCacheKey(repr);
258 
259  if (use_second_if_available && iter->second.second.GetDataObject(cacheKey))
260  {
261  size += iter->second.second.GetActualMemorySize(cacheKey);
262  }
263  else
264  {
265  size += iter->second.first.GetActualMemorySize(cacheKey);
266  }
267  }
268  return size;
269  }
270 
271  bool IsRepresentationVisible(unsigned int id) const
272  {
273  RepresentationsMapType::const_iterator riter = this->RepresentationsMap.find(id);
274  return (riter != this->RepresentationsMap.end() && riter->second.GetPointer() != nullptr &&
275  riter->second->GetVisibility());
276  }
277 
279  void ClearCache(unsigned int id)
280  {
281  for (auto& ipair : this->ItemsMap)
282  {
283  if (ipair.first.first == id)
284  {
285  ipair.second.first.ClearCache();
286  ipair.second.second.ClearCache();
287  }
288  }
289  }
290 
291  ItemsMapType ItemsMap;
292  RepresentationsMapType RepresentationsMap;
293 };
294 
295 #endif // __WRAP__
296 #endif
297 // VTK-HeaderTest-Exclude: vtkPVDataDeliveryManagerInternals.h
manager for data-delivery.
void SetDataObject(vtkDataObject *data, vtkInternals *helper, double cacheKey)
std::map< ReprPortType, std::pair< vtkItem, vtkItem > > ItemsMapType
void SetOutput(vtkDataObject *output) override
Set the data object that is "produced" by this producer.
vtkItem * GetItem(vtkPVDataRepresentation *repr, bool use_second, int port, bool create_if_needed=false)
unsigned long GetVisibleDataSize(bool use_second_if_available, vtkPVDataDeliveryManager *dmgr)
vtkPVDataRepresentation adds some ParaView specific API to data representations.
vtkPVTrivialProducer * GetProducer(int dataKey, double cacheKey)
void Modified()
double GetCacheKey(vtkPVDataRepresentation *repr) const
void SetActualMemorySize(unsigned long size, double cacheKey)
vtkDataObject * GetOutputDataObject(int port)
static vtkSmartPointer< T > New()
vtkTypeUInt64 vtkMTimeType
unsigned int GetUniqueIdentifier()
Return 0 if the Initialize() method was not called otherwise a unique ID that will be shared across t...
vtkDataObject * NewInstance() const
specialized subclass of vtkTrivialProducer that preserves the information about the whole extent of t...
std::map< unsigned int, vtkWeakPointer< vtkPVDataRepresentation > > RepresentationsMapType
void SetDeliveredDataObject(int dataKey, double cacheKey, vtkDataObject *data)
virtual void Modified()
size
virtual unsigned long GetActualMemorySize()
void TakeReference(vtkDataObject *t)
T * GetPointer() const
vtkDataObject * GetDeliveredDataObject(int dataKey, double cacheKey) const
virtual int GetDataObjectType()
vtkItem * GetItem(unsigned int index, bool use_second, int port, bool create_if_needed=false)
key
vtkMTimeType GetDeliveryTimeStamp(int dataKey, double cacheKey) const
std::map< int, vtkSmartPointer< vtkDataObject > > DeliveredDataObjects