vtkPVDataDeliveryManager.cxx 29.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*=========================================================================

  Program:   ParaView
  Module:    $RCSfile$

  Copyright (c) Kitware, Inc.
  All rights reserved.
  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
15
#include "vtkPVDataDeliveryManager.h"
16 17

#include "vtkAlgorithmOutput.h"
18
#include "vtkDataObject.h"
19 20
#include "vtkExtentTranslator.h"
#include "vtkKdTreeManager.h"
21
#include "vtkMPIMoveData.h"
22 23 24 25 26
#include "vtkMultiProcessController.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkOrderedCompositeDistributor.h"
#include "vtkPKdTree.h"
27
#include "vtkPVDataRepresentation.h"
28
#include "vtkPVRenderView.h"
29
#include "vtkPVStreamingMacros.h"
30 31
#include "vtkPVTrivialProducer.h"
#include "vtkSmartPointer.h"
32
#include "vtkStreamingDemandDrivenPipeline.h"
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
33
#include "vtkTimerLog.h"
34
#include "vtkWeakPointer.h"
35 36

#include <assert.h>
37 38 39 40 41 42 43
#include <map>
#include <queue>
#include <utility>

//*****************************************************************************
class vtkPVDataDeliveryManager::vtkInternals
{
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
  friend class vtkItem;
  std::map<int, vtkSmartPointer<vtkDataObject> > EmptyDataObjectTypes;

  // This helps us avoid creating new instances of various data object types to use as
  // empty datasets. Instead, we build a map and keep reusing objects.
  vtkDataObject* GetEmptyDataObject(vtkDataObject* ref)
  {
    if (ref)
    {
      auto iter = this->EmptyDataObjectTypes.find(ref->GetDataObjectType());
      if (iter != this->EmptyDataObjectTypes.end())
      {
        return iter->second;
      }
      else
      {
        vtkSmartPointer<vtkDataObject> clone;
        clone.TakeReference(ref->NewInstance());
        this->EmptyDataObjectTypes[ref->GetDataObjectType()] = clone;
        return clone;
      }
    }
    return nullptr;
  }

69 70
public:
  class vtkPriorityQueueItem
Kitware Robot's avatar
Kitware Robot committed
71
  {
72 73 74 75 76 77 78
  public:
    unsigned int RepresentationId;
    unsigned int BlockId;
    unsigned int Level;
    unsigned int Index;
    double Priority;

Kitware Robot's avatar
Kitware Robot committed
79 80 81 82 83 84
    vtkPriorityQueueItem()
      : RepresentationId(0)
      , BlockId(0)
      , Level(0)
      , Index(0)
      , Priority(0)
85 86 87
    {
    }

Kitware Robot's avatar
Kitware Robot committed
88 89
    bool operator<(const vtkPriorityQueueItem& other) const
    {
90
      return this->Priority < other.Priority;
Kitware Robot's avatar
Kitware Robot committed
91 92
    }
  };
93 94 95 96

  typedef std::priority_queue<vtkPriorityQueueItem> PriorityQueueType;
  PriorityQueueType PriorityQueue;

97
  class vtkOrderedCompositingInfo
Kitware Robot's avatar
Kitware Robot committed
98
  {
99 100 101 102 103
  public:
    vtkSmartPointer<vtkExtentTranslator> Translator;
    double Origin[3];
    double Spacing[3];
    int WholeExtent[6];
Kitware Robot's avatar
Kitware Robot committed
104
  };
105

106
  class vtkItem
Kitware Robot's avatar
Kitware Robot committed
107
  {
108
    vtkSmartPointer<vtkPVTrivialProducer> Producer;
109 110

    // Data object produced by the representation.
111
    vtkWeakPointer<vtkDataObject> DataObject;
112 113 114 115 116 117 118 119

    // Data object available after delivery to the "rendering" node.
    vtkSmartPointer<vtkDataObject> DeliveredDataObject;

    // Data object after re-distributing when using ordered compositing, for
    // example.
    vtkSmartPointer<vtkDataObject> RedistributedDataObject;

120 121 122
    // Data object for a streamed piece.
    vtkSmartPointer<vtkDataObject> StreamedPiece;

123 124
    vtkMTimeType TimeStamp;
    vtkMTimeType ActualMemorySize;
Kitware Robot's avatar
Kitware Robot committed
125

126
  public:
127
    vtkOrderedCompositingInfo OrderedCompositingInfo;
128

129 130 131
    bool CloneDataToAllNodes;
    bool DeliverToClientAndRenderingProcesses;
    bool GatherBeforeDeliveringToClient;
132 133
    bool Redistributable;
    bool Streamable;
134
    int RedistributionMode;
135

Kitware Robot's avatar
Kitware Robot committed
136 137 138 139 140 141 142 143 144
    vtkItem()
      : Producer(vtkSmartPointer<vtkPVTrivialProducer>::New())
      , TimeStamp(0)
      , ActualMemorySize(0)
      , CloneDataToAllNodes(false)
      , DeliverToClientAndRenderingProcesses(false)
      , GatherBeforeDeliveringToClient(false)
      , Redistributable(false)
      , Streamable(false)
145
      , RedistributionMode(vtkOrderedCompositeDistributor::SPLIT_BOUNDARY_CELLS)
Kitware Robot's avatar
Kitware Robot committed
146 147
    {
    }
148

149
    void SetDataObject(vtkDataObject* data, vtkInternals* helper)
Kitware Robot's avatar
Kitware Robot committed
150
    {
151
      this->DataObject = data;
152 153
      this->DeliveredDataObject = nullptr;
      this->RedistributedDataObject = nullptr;
Kitware Robot's avatar
Kitware Robot committed
154
      this->ActualMemorySize = data ? data->GetActualMemorySize() : 0;
155 156 157 158 159 160 161 162 163 164 165
      // This method gets called when data is entirely changed. That means that any
      // data we may have delivered or redistributed would also be obsolete.
      // Hence we reset the `Producer` as well. This avoids #2160.

      // explanation for using a clone: typically, the Producer is connected by the
      // representation to a rendering pipeline e.g. the mapper. As that could be the
      // case, we need to ensure the producer's input is cleaned too. Setting simply nullptr
      // could confuse the mapper and hence we setup a data object of the same type as the data.
      // we could simply set the data too, but that can lead to other confusion as the mapper should
      // never directly see the representation's data.
      this->Producer->SetOutput(helper->GetEmptyDataObject(data));
166

Kitware Robot's avatar
Kitware Robot committed
167 168
      vtkTimeStamp ts;
      ts.Modified();
169
      this->TimeStamp = ts;
Kitware Robot's avatar
Kitware Robot committed
170
    }
171

Kitware Robot's avatar
Kitware Robot committed
172
    void SetActualMemorySize(unsigned long size) { this->ActualMemorySize = size; }
173
    unsigned long GetActualMemorySize() const { return this->ActualMemorySize; }
174

Kitware Robot's avatar
Kitware Robot committed
175
    void SetDeliveredDataObject(vtkDataObject* data) { this->DeliveredDataObject = data; }
176

Kitware Robot's avatar
Kitware Robot committed
177
    void SetRedistributedDataObject(vtkDataObject* data) { this->RedistributedDataObject = data; }
178

Kitware Robot's avatar
Kitware Robot committed
179
    vtkDataObject* GetDeliveredDataObject() { return this->DeliveredDataObject.GetPointer(); }
180 181

    vtkDataObject* GetRedistributedDataObject()
Kitware Robot's avatar
Kitware Robot committed
182
    {
183
      return this->RedistributedDataObject.GetPointer();
Kitware Robot's avatar
Kitware Robot committed
184
    }
185 186

    vtkPVTrivialProducer* GetProducer(bool use_redistributed_data)
Kitware Robot's avatar
Kitware Robot committed
187
    {
188
      if (use_redistributed_data && this->Redistributable)
Kitware Robot's avatar
Kitware Robot committed
189
      {
190
        this->Producer->SetOutput(this->RedistributedDataObject);
Kitware Robot's avatar
Kitware Robot committed
191
      }
192
      else
Kitware Robot's avatar
Kitware Robot committed
193
      {
194
        this->Producer->SetOutput(this->DeliveredDataObject);
195
      }
Kitware Robot's avatar
Kitware Robot committed
196 197
      return this->Producer.GetPointer();
    }
198

Kitware Robot's avatar
Kitware Robot committed
199
    vtkDataObject* GetDataObject() const { return this->DataObject.GetPointer(); }
200
    vtkMTimeType GetTimeStamp() const { return this->TimeStamp; }
Kitware Robot's avatar
Kitware Robot committed
201 202 203
    void SetNextStreamedPiece(vtkDataObject* data) { this->StreamedPiece = data; }
    vtkDataObject* GetStreamedPiece() { return this->StreamedPiece; }
  };
204

205 206 207
  // First is repr unique id, second is the input port.
  typedef std::pair<unsigned int, int> ReprPortType;
  typedef std::map<ReprPortType, std::pair<vtkItem, vtkItem> > ItemsMapType;
208

209 210 211 212
  // Keep track of representation and its uid.
  typedef std::map<unsigned int, vtkWeakPointer<vtkPVDataRepresentation> > RepresentationsMapType;

  vtkItem* GetItem(unsigned int index, bool use_second, int port, bool create_if_needed = false)
Kitware Robot's avatar
Kitware Robot committed
213
  {
214 215 216
    ReprPortType key(index, port);
    ItemsMapType::iterator items = this->ItemsMap.find(key);
    if (items != this->ItemsMap.end())
Kitware Robot's avatar
Kitware Robot committed
217
    {
218
      return use_second ? &(items->second.second) : &(items->second.first);
219
    }
220 221 222 223 224
    else if (create_if_needed)
    {
      std::pair<vtkItem, vtkItem>& itemsPair = this->ItemsMap[key];
      return use_second ? &(itemsPair.second) : &(itemsPair.first);
    }
Kitware Robot's avatar
Kitware Robot committed
225 226
    return NULL;
  }
227

228 229
  vtkItem* GetItem(
    vtkPVDataRepresentation* repr, bool use_second, int port, bool create_if_needed = false)
Kitware Robot's avatar
Kitware Robot committed
230
  {
231
    return this->GetItem(repr->GetUniqueIdentifier(), use_second, port, create_if_needed);
Kitware Robot's avatar
Kitware Robot committed
232
  }
233 234

  unsigned long GetVisibleDataSize(bool use_second_if_available)
Kitware Robot's avatar
Kitware Robot committed
235
  {
236 237 238
    unsigned long size = 0;
    ItemsMapType::iterator iter;
    for (iter = this->ItemsMap.begin(); iter != this->ItemsMap.end(); ++iter)
Kitware Robot's avatar
Kitware Robot committed
239
    {
240 241 242 243 244 245 246
      const ReprPortType& key = iter->first;
      if (!this->IsRepresentationVisible(key.first))
      {
        // skip hidden representations.
        continue;
      }

247
      if (use_second_if_available && iter->second.second.GetDataObject())
Kitware Robot's avatar
Kitware Robot committed
248
      {
249
        size += iter->second.second.GetActualMemorySize();
Kitware Robot's avatar
Kitware Robot committed
250
      }
251
      else
Kitware Robot's avatar
Kitware Robot committed
252
      {
253
        size += iter->second.first.GetActualMemorySize();
254 255
      }
    }
Kitware Robot's avatar
Kitware Robot committed
256 257
    return size;
  }
258

259 260 261 262 263 264 265
  bool IsRepresentationVisible(unsigned int id) const
  {
    RepresentationsMapType::const_iterator riter = this->RepresentationsMap.find(id);
    return (riter != this->RepresentationsMap.end() && riter->second.GetPointer() != NULL &&
      riter->second->GetVisibility());
  }

266
  ItemsMapType ItemsMap;
267
  RepresentationsMapType RepresentationsMap;
268
};
269

270 271 272
//*****************************************************************************

vtkStandardNewMacro(vtkPVDataDeliveryManager);
273
//----------------------------------------------------------------------------
274
vtkPVDataDeliveryManager::vtkPVDataDeliveryManager()
275 276 277 278 279
  : Internals(new vtkInternals())
{
}

//----------------------------------------------------------------------------
280
vtkPVDataDeliveryManager::~vtkPVDataDeliveryManager()
281 282 283 284 285
{
  delete this->Internals;
  this->Internals = 0;
}

286
//----------------------------------------------------------------------------
287
void vtkPVDataDeliveryManager::SetRenderView(vtkPVRenderView* view)
288
{
289
  this->RenderView = view;
290 291
}

292
//----------------------------------------------------------------------------
293
vtkPVRenderView* vtkPVDataDeliveryManager::GetRenderView()
294
{
295
  return this->RenderView;
296 297
}

Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
298
//----------------------------------------------------------------------------
299
unsigned long vtkPVDataDeliveryManager::GetVisibleDataSize(bool low_res)
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
300 301 302
{
  return this->Internals->GetVisibleDataSize(low_res);
}
303 304

//----------------------------------------------------------------------------
305
void vtkPVDataDeliveryManager::RegisterRepresentation(vtkPVDataRepresentation* repr)
306
{
Kitware Robot's avatar
Kitware Robot committed
307
  assert("A representation must have a valid UniqueIdentifier" && repr->GetUniqueIdentifier());
308
  this->Internals->RepresentationsMap[repr->GetUniqueIdentifier()] = repr;
309 310 311
}

//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
312
void vtkPVDataDeliveryManager::UnRegisterRepresentation(vtkPVDataRepresentation* repr)
313
{
314 315
  unsigned int rid = repr->GetUniqueIdentifier();
  this->Internals->RepresentationsMap.erase(rid);
316

317 318
  vtkInternals::ItemsMapType::iterator iter = this->Internals->ItemsMap.begin();
  while (iter != this->Internals->ItemsMap.end())
319
  {
320 321 322 323 324 325 326 327 328 329 330
    const vtkInternals::ReprPortType& key = iter->first;
    if (key.first == rid)
    {
      vtkInternals::ItemsMapType::iterator toerase = iter;
      ++iter;
      this->Internals->ItemsMap.erase(toerase);
    }
    else
    {
      ++iter;
    }
331
  }
332 333 334
}

//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
335
vtkPVDataRepresentation* vtkPVDataDeliveryManager::GetRepresentation(unsigned int index)
336
{
337 338 339
  vtkInternals::RepresentationsMapType::const_iterator iter =
    this->Internals->RepresentationsMap.find(index);
  return iter != this->Internals->RepresentationsMap.end() ? iter->second.GetPointer() : NULL;
340 341
}

342
//----------------------------------------------------------------------------
343
void vtkPVDataDeliveryManager::SetDeliverToAllProcesses(
344
  vtkPVDataRepresentation* repr, bool mode, bool low_res, int port)
345
{
346 347
  vtkInternals::vtkItem* item =
    this->Internals->GetItem(repr, low_res, port, /*create_if_needed=*/true);
348
  if (item)
Kitware Robot's avatar
Kitware Robot committed
349
  {
350
    item->CloneDataToAllNodes = mode;
Kitware Robot's avatar
Kitware Robot committed
351
  }
352
  else
Kitware Robot's avatar
Kitware Robot committed
353
  {
354
    vtkErrorMacro("Invalid argument.");
Kitware Robot's avatar
Kitware Robot committed
355
  }
356 357 358 359
}

//----------------------------------------------------------------------------
void vtkPVDataDeliveryManager::SetDeliverToClientAndRenderingProcesses(
360 361
  vtkPVDataRepresentation* repr, bool deliver_to_client, bool gather_before_delivery, bool low_res,
  int port)
362
{
363 364
  vtkInternals::vtkItem* item =
    this->Internals->GetItem(repr, low_res, port, /*create_if_needed=*/true);
365
  if (item)
Kitware Robot's avatar
Kitware Robot committed
366
  {
367 368
    item->DeliverToClientAndRenderingProcesses = deliver_to_client;
    item->GatherBeforeDeliveringToClient = gather_before_delivery;
Kitware Robot's avatar
Kitware Robot committed
369
  }
370
  else
Kitware Robot's avatar
Kitware Robot committed
371
  {
372
    vtkErrorMacro("Invalid argument.");
Kitware Robot's avatar
Kitware Robot committed
373
  }
374 375
}

376
//----------------------------------------------------------------------------
377
void vtkPVDataDeliveryManager::MarkAsRedistributable(
378
  vtkPVDataRepresentation* repr, bool value /*=true*/, int port)
379
{
380 381
  vtkInternals::vtkItem* item = this->Internals->GetItem(repr, false, port, true);
  vtkInternals::vtkItem* low_item = this->Internals->GetItem(repr, true, port, true);
382
  if (item)
Kitware Robot's avatar
Kitware Robot committed
383
  {
384 385
    item->Redistributable = value;
    low_item->Redistributable = value;
Kitware Robot's avatar
Kitware Robot committed
386
  }
387
  else
Kitware Robot's avatar
Kitware Robot committed
388
  {
389
    vtkErrorMacro("Invalid argument.");
Kitware Robot's avatar
Kitware Robot committed
390
  }
391
}
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
392

393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424
//----------------------------------------------------------------------------
void vtkPVDataDeliveryManager::SetRedistributionMode(
  vtkPVDataRepresentation* repr, int mode, int port)
{
  vtkInternals::vtkItem* item = this->Internals->GetItem(repr, false, port, true);
  vtkInternals::vtkItem* low_item = this->Internals->GetItem(repr, true, port, true);
  if (item)
  {
    item->RedistributionMode = mode;
    low_item->RedistributionMode = mode;
  }
  else
  {
    vtkErrorMacro("Invalid argument.");
  }
}

//----------------------------------------------------------------------------
void vtkPVDataDeliveryManager::SetRedistributionModeToSplitBoundaryCells(
  vtkPVDataRepresentation* repr, int port)
{
  this->SetRedistributionMode(repr, vtkOrderedCompositeDistributor::SPLIT_BOUNDARY_CELLS, port);
}

//----------------------------------------------------------------------------
void vtkPVDataDeliveryManager::SetRedistributionModeToDuplicateBoundaryCells(
  vtkPVDataRepresentation* repr, int port)
{
  this->SetRedistributionMode(
    repr, vtkOrderedCompositeDistributor::ASSIGN_TO_ALL_INTERSECTING_REGIONS, port);
}

425
//----------------------------------------------------------------------------
426
void vtkPVDataDeliveryManager::SetStreamable(vtkPVDataRepresentation* repr, bool val, int port)
427
{
428 429
  vtkInternals::vtkItem* item = this->Internals->GetItem(repr, false, port, true);
  vtkInternals::vtkItem* low_item = this->Internals->GetItem(repr, true, port, true);
430
  if (item)
Kitware Robot's avatar
Kitware Robot committed
431
  {
432 433
    item->Streamable = val;
    low_item->Streamable = val;
Kitware Robot's avatar
Kitware Robot committed
434
  }
435
  else
Kitware Robot's avatar
Kitware Robot committed
436
  {
437
    vtkErrorMacro("Invalid argument.");
Kitware Robot's avatar
Kitware Robot committed
438
  }
439 440
}

441
//----------------------------------------------------------------------------
442 443
void vtkPVDataDeliveryManager::SetPiece(vtkPVDataRepresentation* repr, vtkDataObject* data,
  bool low_res, unsigned long trueSize, int port)
444
{
445 446
  vtkInternals::vtkItem* item =
    this->Internals->GetItem(repr, low_res, port, /*create_if_needed=*/true);
447
  if (item)
Kitware Robot's avatar
Kitware Robot committed
448
  {
449
    vtkMTimeType data_time = 0;
450
    if (data && (data->GetMTime() > data_time))
Kitware Robot's avatar
Kitware Robot committed
451
    {
452
      data_time = data->GetMTime();
Kitware Robot's avatar
Kitware Robot committed
453
    }
454 455 456 457
    if (repr && repr->GetPipelineDataTime() > data_time)
    {
      data_time = repr->GetPipelineDataTime();
    }
Kitware Robot's avatar
Kitware Robot committed
458 459
    if (data_time > item->GetTimeStamp() || item->GetDataObject() != data)
    {
460
      item->SetDataObject(data, this->Internals);
Kitware Robot's avatar
Kitware Robot committed
461
    }
462
    if (trueSize > 0)
Kitware Robot's avatar
Kitware Robot committed
463
    {
464
      item->SetActualMemorySize(trueSize);
465
    }
Kitware Robot's avatar
Kitware Robot committed
466
  }
467
  else
Kitware Robot's avatar
Kitware Robot committed
468
  {
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
469
    vtkErrorMacro("Invalid argument.");
Kitware Robot's avatar
Kitware Robot committed
470
  }
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
471 472 473
}

//----------------------------------------------------------------------------
474
vtkAlgorithmOutput* vtkPVDataDeliveryManager::GetProducer(
475
  vtkPVDataRepresentation* repr, bool low_res, int port)
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
476
{
477
  vtkInternals::vtkItem* item = this->Internals->GetItem(repr, low_res, port);
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
478
  if (!item)
Kitware Robot's avatar
Kitware Robot committed
479
  {
480
    vtkErrorMacro("Invalid arguments.");
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
481
    return NULL;
Kitware Robot's avatar
Kitware Robot committed
482
  }
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
483

Kitware Robot's avatar
Kitware Robot committed
484
  return item->GetProducer(this->RenderView->GetUseOrderedCompositing())->GetOutputPort(0);
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
485 486 487
}

//----------------------------------------------------------------------------
488 489
void vtkPVDataDeliveryManager::SetPiece(
  unsigned int id, vtkDataObject* data, bool low_res, int port)
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
490
{
491
  vtkInternals::vtkItem* item = this->Internals->GetItem(id, low_res, port, true);
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
492
  if (item)
Kitware Robot's avatar
Kitware Robot committed
493
  {
494
    item->SetDataObject(data, this->Internals);
Kitware Robot's avatar
Kitware Robot committed
495
  }
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
496
  else
Kitware Robot's avatar
Kitware Robot committed
497
  {
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
498
    vtkErrorMacro("Invalid argument.");
Kitware Robot's avatar
Kitware Robot committed
499
  }
500 501
}

502
//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
503 504
void vtkPVDataDeliveryManager::SetOrderedCompositingInformation(vtkPVDataRepresentation* repr,
  vtkExtentTranslator* translator, const int whole_extents[6], const double origin[3],
505
  const double spacing[3], int port)
506
{
507
  vtkInternals::vtkItem* item = this->Internals->GetItem(repr, false, port, true);
508
  if (item)
Kitware Robot's avatar
Kitware Robot committed
509
  {
510 511
    vtkInternals::vtkOrderedCompositingInfo info;
    info.Translator = translator;
Kitware Robot's avatar
Kitware Robot committed
512 513 514
    memcpy(info.WholeExtent, whole_extents, sizeof(int) * 6);
    memcpy(info.Origin, origin, sizeof(double) * 3);
    memcpy(info.Spacing, spacing, sizeof(double) * 3);
515 516

    item->OrderedCompositingInfo = info;
Kitware Robot's avatar
Kitware Robot committed
517
  }
518
  else
Kitware Robot's avatar
Kitware Robot committed
519
  {
520
    vtkErrorMacro("Invalid argument.");
Kitware Robot's avatar
Kitware Robot committed
521
  }
522 523
}

524
//----------------------------------------------------------------------------
525
vtkAlgorithmOutput* vtkPVDataDeliveryManager::GetProducer(unsigned int id, bool low_res, int port)
526
{
527
  vtkInternals::vtkItem* item = this->Internals->GetItem(id, low_res, port);
528
  if (!item)
Kitware Robot's avatar
Kitware Robot committed
529
  {
530 531
    vtkErrorMacro("Invalid arguments.");
    return NULL;
Kitware Robot's avatar
Kitware Robot committed
532
  }
533

Kitware Robot's avatar
Kitware Robot committed
534
  return item->GetProducer(this->RenderView->GetUseOrderedCompositing())->GetOutputPort(0);
535 536
}

537
//----------------------------------------------------------------------------
538
bool vtkPVDataDeliveryManager::NeedsDelivery(
539
  vtkMTimeType timestamp, std::vector<unsigned int>& keys_to_deliver, bool use_low)
540 541
{
  vtkInternals::ItemsMapType::iterator iter;
Kitware Robot's avatar
Kitware Robot committed
542 543
  for (iter = this->Internals->ItemsMap.begin(); iter != this->Internals->ItemsMap.end(); ++iter)
  {
544
    if (this->Internals->IsRepresentationVisible(iter->first.first))
Kitware Robot's avatar
Kitware Robot committed
545
    {
546 547 548 549 550 551 552
      vtkInternals::vtkItem& item = use_low ? iter->second.second : iter->second.first;
      if (item.GetTimeStamp() > timestamp)
      {
        // FIXME: convert keys_to_deliver to a vector of pairs.
        keys_to_deliver.push_back(iter->first.first);
        keys_to_deliver.push_back(static_cast<unsigned int>(iter->first.second));
      }
553
    }
Kitware Robot's avatar
Kitware Robot committed
554
  }
555 556 557 558
  return keys_to_deliver.size() > 0;
}

//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
559
void vtkPVDataDeliveryManager::Deliver(int use_lod, unsigned int size, unsigned int* values)
560 561

{
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
562 563 564 565 566 567 568 569 570 571 572 573
  // This method gets called on all processes with the list of representations
  // to "deliver". We check with the view what mode we're operating in and
  // decide where the data needs to be delivered.
  //
  // Representations can provide overrides, e.g. though the view says data is
  // merely "pass-through", some representation says we need to clone the data
  // everywhere. That makes it critical that this method is called on all
  // processes at the same time to avoid deadlocks and other complications.
  //
  // This method will be implemented in "view-specific" subclasses since how the
  // data is delivered is very view specific.

574 575
  assert(size % 2 == 0);

Kitware Robot's avatar
Kitware Robot committed
576
  vtkTimerLog::MarkStartEvent(use_lod ? "LowRes Data Migration" : "FullRes Data Migration");
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
577

Kitware Robot's avatar
Kitware Robot committed
578 579 580
  bool using_remote_rendering = use_lod
    ? this->RenderView->GetUseDistributedRenderingForInteractiveRender()
    : this->RenderView->GetUseDistributedRenderingForStillRender();
581
  int mode = this->RenderView->GetDataDistributionMode(using_remote_rendering);
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
582

583
  for (unsigned int cc = 0; cc < size; cc += 2)
Kitware Robot's avatar
Kitware Robot committed
584
  {
585
    int port = static_cast<int>(values[cc + 1]);
586

587 588 589
    vtkInternals::vtkItem* item = this->Internals->GetItem(values[cc], use_lod != 0, port);
    vtkDataObject* data = item ? item->GetDataObject() : NULL;
    if (!data)
590
    {
591 592
      // ideally, we want to sync this info between all ranks some other rank
      // doesn't deadlock (esp. in collaboration mode).
593 594
      continue;
    }
595

596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616
    //    if (data != NULL && data->IsA("vtkUniformGridAMR"))
    //      {
    //      // we are dealing with AMR datasets.
    //      // We assume for now we're not running in render-server mode. We can
    //      // ensure that at some point in future.
    //      // So we are either in pass-through or collect mode.

    //      // FIXME: check that the mode flags are "suitable" for AMR.
    //      }

    vtkNew<vtkMPIMoveData> dataMover;
    dataMover->InitializeForCommunicationForParaView();
    dataMover->SetOutputDataType(data ? data->GetDataObjectType() : VTK_POLY_DATA);
    dataMover->SetMoveMode(mode);
    if (item->CloneDataToAllNodes)
    {
      dataMover->SetMoveModeToClone();
    }
    else if (item->DeliverToClientAndRenderingProcesses)
    {
      if (mode == vtkMPIMoveData::PASS_THROUGH)
Kitware Robot's avatar
Kitware Robot committed
617
      {
618
        dataMover->SetMoveMode(vtkMPIMoveData::COLLECT_AND_PASS_THROUGH);
Kitware Robot's avatar
Kitware Robot committed
619
      }
620
      else
Kitware Robot's avatar
Kitware Robot committed
621
      {
622 623
        // nothing to do, since the data is going to be delivered to the client
        // anyways.
624
      }
625 626 627 628
      dataMover->SetSkipDataServerGatherToZero(item->GatherBeforeDeliveringToClient == false);
    }
    dataMover->SetInputData(data);
    dataMover->Update();
629
    if (dataMover->GetOutputGeneratedOnProcess())
630 631
    {
      item->SetDeliveredDataObject(dataMover->GetOutputDataObject(0));
632
    }
Kitware Robot's avatar
Kitware Robot committed
633
  }
634

Kitware Robot's avatar
Kitware Robot committed
635
  vtkTimerLog::MarkEndEvent(use_lod ? "LowRes Data Migration" : "FullRes Data Migration");
636
}
637

638
//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
639
void vtkPVDataDeliveryManager::RedistributeDataForOrderedCompositing(bool use_lod)
640 641
{
  if (this->RenderView->GetUpdateTimeStamp() > this->RedistributionTimeStamp)
Kitware Robot's avatar
Kitware Robot committed
642
  {
643 644 645 646
    vtkTimerLog::MarkStartEvent("Regenerate Kd-Tree");
    // need to re-generate the kd-tree.
    this->RedistributionTimeStamp.Modified();

647
    vtkNew<vtkKdTreeManager> cutsGenerator;
648
    vtkInternals::ItemsMapType::iterator iter;
Kitware Robot's avatar
Kitware Robot committed
649 650 651
    for (iter = this->Internals->ItemsMap.begin(); iter != this->Internals->ItemsMap.end(); ++iter)
    {
      vtkInternals::vtkItem& item = iter->second.first;
652
      if (this->Internals->IsRepresentationVisible(iter->first.first))
653
      {
654
        if (item.OrderedCompositingInfo.Translator)
Kitware Robot's avatar
Kitware Robot committed
655
        {
656 657
          // implies that the representation is providing us with means to
          // override how the ordered compositing happens.
Kitware Robot's avatar
Kitware Robot committed
658 659 660 661
          const vtkInternals::vtkOrderedCompositingInfo& info = item.OrderedCompositingInfo;
          cutsGenerator->SetStructuredDataInformation(
            info.Translator, info.WholeExtent, info.Origin, info.Spacing);
        }
662
        else if (item.Redistributable)
Kitware Robot's avatar
Kitware Robot committed
663
        {
664
          cutsGenerator->AddDataObject(item.GetDeliveredDataObject());
665 666
        }
      }
Kitware Robot's avatar
Kitware Robot committed
667
    }
668 669
    cutsGenerator->GenerateKdTree();
    this->KdTree = cutsGenerator->GetKdTree();
670
    vtkTimerLog::MarkEndEvent("Regenerate Kd-Tree");
Kitware Robot's avatar
Kitware Robot committed
671
  }
672 673

  if (this->KdTree == NULL)
Kitware Robot's avatar
Kitware Robot committed
674
  {
675
    return;
Kitware Robot's avatar
Kitware Robot committed
676
  }
677

678 679
  vtkTimerLog::MarkStartEvent("Redistributing Data for Ordered Compositing");
  vtkInternals::ItemsMapType::iterator iter;
Kitware Robot's avatar
Kitware Robot committed
680 681
  for (iter = this->Internals->ItemsMap.begin(); iter != this->Internals->ItemsMap.end(); ++iter)
  {
682 683 684 685 686
    if (!this->Internals->IsRepresentationVisible(iter->first.first))
    {
      // skip hidden representations;
      continue;
    }
687

688 689
    vtkInternals::vtkItem& item = use_lod ? iter->second.second : iter->second.first;
    if (!item.Redistributable ||
690 691
      // delivered object can be null in case we're updating lod and the
      // representation doeesn't have any LOD data.
692
      item.GetDeliveredDataObject() == NULL)
Kitware Robot's avatar
Kitware Robot committed
693
    {
694
      continue;
Kitware Robot's avatar
Kitware Robot committed
695
    }
696

697 698 699
    if (item.GetRedistributedDataObject() &&

      // input-data didn't change
Kitware Robot's avatar
Kitware Robot committed
700
      (item.GetDeliveredDataObject()->GetMTime() < item.GetRedistributedDataObject()->GetMTime()) &&
701 702

      // kd-tree didn't change
Kitware Robot's avatar
Kitware Robot committed
703 704
      (item.GetRedistributedDataObject()->GetMTime() > this->KdTree->GetMTime()))
    {
705 706
      // skip redistribution.
      continue;
Kitware Robot's avatar
Kitware Robot committed
707
    }
708

709 710
    // release old memory (not necessarily, but try).
    item.SetRedistributedDataObject(NULL);
711

712 713 714 715 716
    vtkNew<vtkOrderedCompositeDistributor> redistributor;
    redistributor->SetController(vtkMultiProcessController::GetGlobalController());
    redistributor->SetInputData(item.GetDeliveredDataObject());
    redistributor->SetPKdTree(this->KdTree);
    redistributor->SetPassThrough(0);
717
    redistributor->SetBoundaryMode(item.RedistributionMode);
718 719
    redistributor->Update();
    item.SetRedistributedDataObject(redistributor->GetOutputDataObject(0));
Kitware Robot's avatar
Kitware Robot committed
720
  }
721
  vtkTimerLog::MarkEndEvent("Redistributing Data for Ordered Compositing");
722 723
}

724
//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
725
void vtkPVDataDeliveryManager::ClearRedistributedData(bool use_lod)
726 727 728 729 730 731
{
  // It seems like we should be able to set each item's RedistributedDataObject
  // to NULL in this loop but that doesn't work. For now we're leaving this as
  // is to make sure we don't break functionality but this should be revisited
  // later.
  vtkInternals::ItemsMapType::iterator iter;
Kitware Robot's avatar
Kitware Robot committed
732 733
  for (iter = this->Internals->ItemsMap.begin(); iter != this->Internals->ItemsMap.end(); ++iter)
  {
734 735 736 737
    if (!this->Internals->IsRepresentationVisible(iter->first.first))
    {
      continue;
    }
Kitware Robot's avatar
Kitware Robot committed
738
    vtkInternals::vtkItem& item = use_lod ? iter->second.second : iter->second.first;
739
    if (!item.Redistributable ||
740 741 742
      // delivered object can be null in case we're updating lod and the
      // representation doeesn't have any LOD data.
      item.GetDeliveredDataObject() == NULL)
Kitware Robot's avatar
Kitware Robot committed
743
    {
744 745
      continue;
    }
Kitware Robot's avatar
Kitware Robot committed
746 747
    item.SetRedistributedDataObject(item.GetDeliveredDataObject());
  }
748 749
}

750
//----------------------------------------------------------------------------
751
vtkPKdTree* vtkPVDataDeliveryManager::GetKdTree()
752 753 754
{
  return this->KdTree;
}
755 756

//----------------------------------------------------------------------------
757
void vtkPVDataDeliveryManager::SetNextStreamedPiece(
758
  vtkPVDataRepresentation* repr, vtkDataObject* data, int port)
759
{
760
  vtkInternals::vtkItem* item = this->Internals->GetItem(repr,
761
    /*low_res=*/false, port, true);
762
  if (item == NULL)
Kitware Robot's avatar
Kitware Robot committed
763
  {
764 765
    vtkErrorMacro("Invalid argument.");
    return;
Kitware Robot's avatar
Kitware Robot committed
766 767
  }

768 769 770 771
  // For now, I am going to keep things simple. Piece is delivered to the
  // representation separately. That's it.
  item->SetNextStreamedPiece(data);
}
772

773
//----------------------------------------------------------------------------
774 775
vtkDataObject* vtkPVDataDeliveryManager::GetCurrentStreamedPiece(
  vtkPVDataRepresentation* repr, int port)
776
{
777 778
  vtkInternals::vtkItem* item = this->Internals->GetItem(repr,
    /*low_res=*/false, port);
779
  if (item == NULL)
Kitware Robot's avatar
Kitware Robot committed
780
  {
781 782
    vtkErrorMacro("Invalid argument.");
    return NULL;
Kitware Robot's avatar
Kitware Robot committed
783
  }
784 785
  return item->GetStreamedPiece();
}
786

787 788 789 790 791
//----------------------------------------------------------------------------
void vtkPVDataDeliveryManager::ClearStreamedPieces()
{
  // I am not too sure if I want to do this. Right now I am thinking once a
  // piece is delivered, the delivery manager should no longer bother about it.
792
  vtkInternals::ItemsMapType::iterator iter;
Kitware Robot's avatar
Kitware Robot committed
793 794
  for (iter = this->Internals->ItemsMap.begin(); iter != this->Internals->ItemsMap.end(); ++iter)
  {
795
    vtkInternals::vtkItem& item = iter->second.first;
796
    item.SetNextStreamedPiece(NULL);
Kitware Robot's avatar
Kitware Robot committed
797
  }
798 799 800
}

//----------------------------------------------------------------------------