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