vtkParallelRenderManager.cxx 63.2 KB
Newer Older
1 2 3 4 5
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkParallelRenderManager.cxx

6
  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 8 9
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

Charles Law's avatar
Charles Law committed
10 11 12 13 14 15
  Copyright 2003 Sandia Corporation. Under the terms of Contract
  DE-AC04-94AL85000, there is a non-exclusive license for use of this work by
  or on behalf of the U.S. Government. Redistribution and use in source and
  binary forms, with or without modification, are permitted provided that this
  Notice and any statement of authorship are reproduced on all copies.

16 17
     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
18 19 20 21 22 23 24
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkParallelRenderManager.h"

#include "vtkActorCollection.h"
#include "vtkActor.h"
25
#include "vtkCallbackCommand.h"
26
#include "vtkCamera.h"
Ken Martin's avatar
Ken Martin committed
27
#include "vtkDoubleArray.h"
28 29
#include "vtkLightCollection.h"
#include "vtkLight.h"
Ken Martin's avatar
Ken Martin committed
30
#include "vtkMath.h"
31 32 33 34 35
#include "vtkMultiProcessController.h"
#include "vtkMultiProcessStream.h" // needed for vtkMultiProcessStream.
#include "vtkPolyDataMapper.h"
#include "vtkRendererCollection.h"
#include "vtkRenderer.h"
Ken Martin's avatar
Ken Martin committed
36 37
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
38
#include "vtkTimerLog.h"
Ken Martin's avatar
Ken Martin committed
39
#include "vtkUnsignedCharArray.h"
40 41 42

static void AbortRenderCheck(vtkObject *caller, unsigned long vtkNotUsed(event),
                 void *clientData, void *);
43 44 45


static void GenericStartRender(vtkObject *caller, unsigned long vtkNotUsed(event),
46
            void *clientData, void *);
47
static void GenericEndRender(vtkObject *caller, unsigned long vtkNotUsed(event),
48 49 50 51 52 53 54 55 56 57 58
            void *clientData, void *);
/*
static void ResetCamera(vtkObject *caller,
                        unsigned long vtkNotUsed(event),
                        void *clientData, void *);
static void ResetCameraClippingRange(vtkObject *caller,
                                     unsigned long vtkNotUsed(event),
                                     void *clientData, void *);
*/
static void RenderRMI(void *arg, void *, int, int);
static void ComputeVisiblePropBoundsRMI(void *arg, void *, int, int);
59
bool vtkParallelRenderManager::DefaultRenderEventPropagation = true;
60

61

Mathieu Malaterre's avatar
Mathieu Malaterre committed
62
//----------------------------------------------------------------------------
63 64 65
vtkParallelRenderManager::vtkParallelRenderManager()
{
  this->RenderWindow = NULL;
Ken Martin's avatar
Ken Martin committed
66
  this->ObservingRenderWindow = 0;
Berk Geveci's avatar
Berk Geveci committed
67
  this->ObservingAbort = 0;
68

69 70
  this->Controller = NULL;
  this->SetController(vtkMultiProcessController::GetGlobalController());
71 72
  this->RootProcessId = 0;

73 74 75
  this->Renderers = vtkRendererCollection::New();
  this->SyncRenderWindowRenderers = 1;

76 77 78 79 80 81 82 83 84 85 86 87 88 89
  this->Lock = 0;

  this->ImageReductionFactor = 1;
  this->MaxImageReductionFactor = 16;
  this->AutoImageReductionFactor = 0;
  this->AverageTimePerPixel = 0.0;

  this->RenderTime = 0.0;
  this->ImageProcessingTime = 0.0;

  this->ParallelRendering = 1;
  this->WriteBackImages = 1;
  this->MagnifyImages = 1;
  this->MagnifyImageMethod = vtkParallelRenderManager::NEAREST;
90 91
  this->RenderEventPropagation =
    vtkParallelRenderManager::DefaultRenderEventPropagation? 1 : 0;
92 93 94 95
  this->UseCompositing = 1;

  this->FullImage = vtkUnsignedCharArray::New();
  this->ReducedImage = vtkUnsignedCharArray::New();
Ken Martin's avatar
Ken Martin committed
96 97 98
  this->FullImageUpToDate = 0;
  this->ReducedImageUpToDate = 0;
  this->RenderWindowImageUpToDate = 0;
Ken Martin's avatar
Ken Martin committed
99 100
  this->FullImageSize[0] = 0;
  this->FullImageSize[1] = 0;
101

102 103 104
  this->ReducedImageSize[0] = 0;
  this->ReducedImageSize[1] = 0;

105
  this->ForceRenderWindowSize = 0;
106 107
  this->ForcedRenderWindowSize[0] = 0;
  this->ForcedRenderWindowSize[1] = 0;
108

Ken Martin's avatar
Ken Martin committed
109
  this->Viewports = vtkDoubleArray::New();
110 111
  this->Viewports->SetNumberOfComponents(4);

112 113
  this->UseRGBA = 1;

114
  this->AddedRMIs = 0;
115 116
  this->RenderRMIId = 0;
  this->BoundsRMIId = 0;
117
  this->Timer = vtkTimerLog::New();
118

119
  this->UseBackBuffer = 1;
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
120
  this->SynchronizeTileProperties = 1;
121 122
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
123
//----------------------------------------------------------------------------
124 125 126
vtkParallelRenderManager::~vtkParallelRenderManager()
{
  this->SetRenderWindow(NULL);
127
  if (this->Controller && this->AddedRMIs)
128
  {
129 130
    this->Controller->RemoveRMI(this->RenderRMIId);
    this->Controller->RemoveRMI(this->BoundsRMIId);
131
    this->AddedRMIs = 0;
132
  }
133
  this->SetController(NULL);
134 135 136 137 138
  if (this->FullImage) this->FullImage->Delete();
  if (this->ReducedImage) this->ReducedImage->Delete();
  if (this->Viewports) this->Viewports->Delete();
  if (this->Timer) this->Timer->Delete();
  if (this->Renderers) this->Renderers->Delete();
139 140
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
141
//----------------------------------------------------------------------------
142 143 144 145 146 147 148 149 150 151
void vtkParallelRenderManager::PrintSelf(ostream &os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);

  os << indent << "ParallelRendering: "
     << (this->ParallelRendering ? "on" : "off") << endl;
  os << indent << "RenderEventPropagation: "
     << (this->RenderEventPropagation ? "on" : "off") << endl;
  os << indent << "UseCompositing: "
     << (this->UseCompositing ? "on" : "off") << endl;
152 153
  os << indent << "SyncRenderWindowRenderers: "
     << (this->SyncRenderWindowRenderers ? "on" : "off") << endl;
154

155
  os << indent << "ObservingRenderWindow: "
156 157 158 159 160 161 162 163 164 165 166
     << (this->ObservingRenderWindow ? "yes" : "no") << endl;
  os << indent << "Locked: " << (this->Lock ? "yes" : "no") << endl;

  os << indent << "ImageReductionFactor: "
     << this->ImageReductionFactor << endl;
  os << indent << "MaxImageReductionFactor: "
     << this->MaxImageReductionFactor << endl;
  os << indent << "AutoImageReductionFactor: "
     << (this->AutoImageReductionFactor ? "on" : "off") << endl;

  if (this->MagnifyImageMethod == vtkParallelRenderManager::LINEAR)
167
  {
168
    os << indent << "MagnifyImageMethod: LINEAR\n";
169
  }
170
  else if (this->MagnifyImageMethod == vtkParallelRenderManager::NEAREST)
171
  {
172
    os << indent << "MagnifyImageMethod: NEAREST\n";
173
  }
174 175 176 177 178 179 180 181 182 183 184 185 186 187

  os << indent << "WriteBackImages: "
     << (this->WriteBackImages ? "on" : "off") << endl;
  os << indent << "MagnifyImages: "
     << (this->MagnifyImages ? "on" : "off") << endl;

  os << indent << "FullImageSize: ("
     << this->FullImageSize[0] << ", " << this->FullImageSize[1] << ")" << endl;
  os << indent << "ReducedImageSize: ("
     << this->ReducedImageSize[0] << ", "
     << this->ReducedImageSize[1] << ")" << endl;

  os << indent << "RenderWindow: " << this->RenderWindow << endl;
  os << indent << "Controller: " << this->Controller << endl;
188
  os << indent << "Renderers: " << this->Renderers << endl;
189 190
  os << indent << "RootProcessId: " << this->RootProcessId << endl;

191 192
  os << indent << "Last render time: " << this->RenderTime << endl;

193
  os << indent << "Last image processing time: "
194
     << this->ImageProcessingTime << endl;
195
  os << indent << "UseRGBA: " << this->UseRGBA << endl;
196
  os << indent << "SynchronizeTileProperties: "
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
197
    << this->SynchronizeTileProperties << endl;
198 199 200

  os << indent << "FullImage: ";
  if (this->FullImage)
201
  {
202
    this->FullImage->PrintSelf(os, indent.GetNextIndent());;
203
  }
204
  else
205
  {
206
    os << "(none)" << endl;
207
  }
Berk Geveci's avatar
Berk Geveci committed
208

209 210
  os << indent << "ForcedRenderWindowSize: "
     << this->ForcedRenderWindowSize[0] << " "
Berk Geveci's avatar
Berk Geveci committed
211 212 213 214 215
     << this->ForcedRenderWindowSize[1] << endl;

  os << indent << "ForceRenderWindowSize: "
     << this->ForceRenderWindowSize
     << endl;
216 217 218 219

  os << indent << "UseBackBuffer: "
     << (this->UseBackBuffer ? "on" : "off") << endl;

220 221
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
222
//----------------------------------------------------------------------------
223 224 225 226 227 228 229
vtkRenderWindow *vtkParallelRenderManager::MakeRenderWindow()
{
  vtkDebugMacro("MakeRenderWindow");

  return vtkRenderWindow::New();
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
230
//----------------------------------------------------------------------------
231 232 233 234 235 236 237
vtkRenderer *vtkParallelRenderManager::MakeRenderer()
{
  vtkDebugMacro("MakeRenderer");

  return vtkRenderer::New();
}

238 239 240 241
//----------------------------------------------------------------------------
void vtkParallelRenderManager::AddRenderWindowEventHandlers()
{
  if (this->RenderWindow && !this->ObservingRenderWindow)
242
  {
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
    vtkCallbackCommand *cbc = vtkCallbackCommand::New();
    cbc->SetCallback(::GenericStartRender);
    cbc->SetClientData((void*)this);
    // renWin will delete the cbc when the observer is removed.
    this->StartRenderTag
      = this->RenderWindow->AddObserver(vtkCommand::StartEvent,cbc);
    cbc->Delete();

    cbc = vtkCallbackCommand::New();
    cbc->SetCallback(::GenericEndRender);
    cbc->SetClientData((void*)this);
    // renWin will delete the cbc when the observer is removed.
    this->EndRenderTag
      = this->RenderWindow->AddObserver(vtkCommand::EndEvent,cbc);
    cbc->Delete();
    this->ObservingRenderWindow = 1;
259
  }
260 261 262 263 264 265
}

//----------------------------------------------------------------------------
void vtkParallelRenderManager::RemoveRenderWindowEventHandlers()
{
  if (this->RenderWindow && this->ObservingRenderWindow)
266
  {
267 268 269 270 271
    this->RenderWindow->RemoveObserver(this->StartRenderTag);
    this->RenderWindow->RemoveObserver(this->EndRenderTag);
    this->StartRenderTag = 0;
    this->EndRenderTag = 0;
    this->ObservingRenderWindow = 0;
272
  }
273 274
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
275
//----------------------------------------------------------------------------
276 277 278 279
void vtkParallelRenderManager::SetRenderWindow(vtkRenderWindow *renWin)
{
  vtkDebugMacro("SetRenderWindow");
  if (this->RenderWindow == renWin)
280
  {
281
    return;
282
  }
283 284

  if (this->RenderWindow)
285
  {
286
    // Remove all of the observers.
Berk Geveci's avatar
Berk Geveci committed
287
    if (this->ObservingAbort)
288
    {
Berk Geveci's avatar
Berk Geveci committed
289
      this->RenderWindow->RemoveObserver(this->AbortRenderCheckTag);
290
      this->AbortRenderCheckTag = 0;
Berk Geveci's avatar
Berk Geveci committed
291
      this->ObservingAbort = 0;
292
    }
293 294
    this->RemoveRenderWindowEventHandlers();
  }
295

296 297
  vtkSetObjectBodyMacro(RenderWindow, vtkRenderWindow, renWin);

298
  if (this->RenderWindow)
299
  {
300 301 302 303 304 305 306 307 308 309
    vtkCallbackCommand *cbc;

    // In case a subclass wants to raise aborts.
    cbc = vtkCallbackCommand::New();
    cbc->SetCallback(::AbortRenderCheck);
    cbc->SetClientData((void*)this);
    // renWin will delete the cbc when the observer is removed.
    this->AbortRenderCheckTag = renWin->AddObserver(vtkCommand::AbortCheckEvent,
      cbc);
    cbc->Delete();
Berk Geveci's avatar
Berk Geveci committed
310
    this->ObservingAbort = 1;
311

312
    this->AddRenderWindowEventHandlers();
313
  }
314 315
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
316
//----------------------------------------------------------------------------
317 318
void vtkParallelRenderManager::SetController(vtkMultiProcessController *controller)
{
Mathieu Malaterre's avatar
Mathieu Malaterre committed
319 320
  //Regular vtkSetObjectMacro:
  vtkSetObjectBodyMacro(Controller,vtkMultiProcessController,controller)
321 322
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
323
//----------------------------------------------------------------------------
324 325 326 327 328 329 330 331 332 333 334 335 336
void vtkParallelRenderManager::InitializePieces()
{
  vtkDebugMacro("InitializePieces");

  vtkRendererCollection *rens;
  vtkRenderer *ren;
  vtkActorCollection *actors;
  vtkActor *actor;
  vtkMapper *mapper;
  vtkPolyDataMapper *pdMapper;
  int piece, numPieces;

  if ((this->RenderWindow == NULL) || (this->Controller == NULL))
337
  {
338 339
    vtkWarningMacro("Called InitializePieces before setting RenderWindow or Controller");
    return;
340
  }
341 342 343
  piece = this->Controller->GetLocalProcessId();
  numPieces = this->Controller->GetNumberOfProcesses();

344
  rens = this->GetRenderers();
Ken Martin's avatar
Ken Martin committed
345 346 347
  vtkCollectionSimpleIterator rsit;
  rens->InitTraversal(rsit);
  while ( (ren = rens->GetNextRenderer(rsit)) )
348
  {
349
    actors = ren->GetActors();
Ken Martin's avatar
Ken Martin committed
350 351 352
    vtkCollectionSimpleIterator ait;
    actors->InitTraversal(ait);
    while ( (actor = actors->GetNextActor(ait)) )
353
    {
354 355 356
      mapper = actor->GetMapper();
      pdMapper = vtkPolyDataMapper::SafeDownCast(mapper);
      if (pdMapper)
357
      {
358 359 360 361
        pdMapper->SetPiece(piece);
        pdMapper->SetNumberOfPieces(numPieces);
      }
    }
362
  }
363 364
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
365
//----------------------------------------------------------------------------
366 367 368 369 370
void vtkParallelRenderManager::InitializeOffScreen()
{
  vtkDebugMacro("InitializeOffScreen");

  if ((this->RenderWindow == NULL) || (this->Controller == NULL))
371
  {
372 373
    vtkWarningMacro("Called InitializeOffScreen before setting RenderWindow or Controller");
    return;
374
  }
375 376 377

  if ( (this->Controller->GetLocalProcessId() != this->RootProcessId) ||
       !this->WriteBackImages )
378
  {
379
    this->RenderWindow->OffScreenRenderingOn();
380
  }
381
  else
382
  {
383
    this->RenderWindow->OffScreenRenderingOff();
384
  }
385 386
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
387
//----------------------------------------------------------------------------
388 389 390 391 392
void vtkParallelRenderManager::StartInteractor()
{
  vtkDebugMacro("StartInteractor");

  if ((this->Controller == NULL) || (this->RenderWindow == NULL))
393
  {
394 395
    vtkErrorMacro("Must set Controller and RenderWindow before starting interactor.");
    return;
396
  }
397 398

  if (this->Controller->GetLocalProcessId() == this->RootProcessId)
399
  {
400 401
    vtkRenderWindowInteractor *inter = this->RenderWindow->GetInteractor();
    if (!inter)
402
    {
403
      vtkErrorMacro("Render window does not have an interactor.");
404
    }
405
    else
406
    {
407 408
      inter->Initialize();
      inter->Start();
409
    }
410 411
    //By the time we reach here, the interaction is finished.
    this->StopServices();
412
  }
413
  else
414
  {
415
    this->StartServices();
416
  }
417 418
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
419
//----------------------------------------------------------------------------
420
void vtkParallelRenderManager::StartServices()
421
{
422
  vtkDebugMacro("StartServices");
423

424
  if (!this->Controller)
425
  {
426 427
    vtkErrorMacro("Must set Controller before starting service");
    return;
428
  }
429
  if (this->Controller->GetLocalProcessId() == this->RootProcessId)
430
  {
431
    vtkWarningMacro("Starting service on root process (probably not what you wanted to do)");
432
  }
433 434 435 436 437

  this->InitializeRMIs();
  this->Controller->ProcessRMIs();
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
438
//----------------------------------------------------------------------------
439 440 441 442 443
void vtkParallelRenderManager::StopServices()
{
  vtkDebugMacro("StopServices");

  if (!this->Controller)
444
  {
445 446
    vtkErrorMacro("Must set Controller before stopping service");
    return;
447
  }
448
  if (this->Controller->GetLocalProcessId() != this->RootProcessId)
449
  {
450 451
    vtkErrorMacro("Can only stop services on root node");
    return;
452
  }
453

454 455
  this->Controller->TriggerRMIOnAllChildren(
    vtkMultiProcessController::BREAK_RMI_TAG);
456 457
}

458 459 460 461
//----------------------------------------------------------------------------
void vtkParallelRenderManager::GenericStartRenderCallback()
{
  if (!this->Controller)
462
  {
463
    return;
464
  }
465 466

  if (this->Controller->GetLocalProcessId() == this->RootProcessId)
467
  {
468
    this->StartRender();
469
  }
470
  else // LocalProcessId != RootProcessId
471
  {
472
    this->SatelliteStartRender();
473
  }
474 475 476 477 478 479
}

//----------------------------------------------------------------------------
void vtkParallelRenderManager::GenericEndRenderCallback()
{
  if (!this->Controller)
480
  {
481
    return;
482
  }
483 484

  if (this->Controller->GetLocalProcessId() == this->RootProcessId)
485
  {
486
    this->EndRender();
487
  }
488
  else // LocalProcessId != RootProcessId
489
  {
490
    this->SatelliteEndRender();
491
  }
492 493
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
494
//----------------------------------------------------------------------------
495 496
void vtkParallelRenderManager::StartRender()
{
497 498 499
  vtkParallelRenderManager::RenderWindowInfo winInfo;
  vtkParallelRenderManager::RendererInfo renInfo;
  vtkParallelRenderManager::LightInfo lightInfo;
500 501 502 503

  vtkDebugMacro("StartRender");

  if ((this->Controller == NULL) || (this->Lock))
504
  {
505
    return;
506
  }
Ken Martin's avatar
Ken Martin committed
507
  this->Lock = 1;
508

Ken Martin's avatar
Ken Martin committed
509 510 511
  this->FullImageUpToDate = 0;
  this->ReducedImageUpToDate = 0;
  this->RenderWindowImageUpToDate = 0;
512 513

  if (this->FullImage->GetPointer(0) == this->ReducedImage->GetPointer(0))
514
  {
515 516 517
    // "Un-share" pointer for full/reduced images in case we need separate
    // arrays this run.
    this->ReducedImage->Initialize();
518
  }
519 520

  if (!this->ParallelRendering)
521
  {
Ken Martin's avatar
Ken Martin committed
522
    this->Lock = 0;
523
    return;
524
  }
525 526 527

  this->InvokeEvent(vtkCommand::StartEvent, NULL);

528 529
  this->ImageProcessingTime = 0;

530 531 532 533
  // Used to time the total render (without compositing).
  this->Timer->StartTimer();

  if (this->AutoImageReductionFactor)
534
  {
535 536
    this->SetImageReductionFactorForUpdateRate(
      this->RenderWindow->GetDesiredUpdateRate());
537
  }
538 539

  // Make adjustments for window size.
540 541
  int *tilesize;
  if (this->ForceRenderWindowSize)
542
  {
543
    tilesize = this->ForcedRenderWindowSize;
544
  }
545
  else
546
  {
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
547
    tilesize = this->RenderWindow->GetActualSize();
548
  }
549
  int size[2];
550
  size[0] = tilesize[0];
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
551
  size[1] = tilesize[1];
552
  if ((size[0] == 0) || (size[1] == 0))
553
  {
554 555 556 557
    // It helps to have a real window size.
    vtkDebugMacro("Resetting window size to 300x300");
    size[0] = size[1] = 300;
    this->RenderWindow->SetSize(size[0], size[1]);
558
  }
559 560
  this->FullImageSize[0] = size[0];
  this->FullImageSize[1] = size[1];
561

562 563
  //Round up.
  this->ReducedImageSize[0] =
564
    (int)((size[0]+this->ImageReductionFactor-1)/this->ImageReductionFactor);
565
  this->ReducedImageSize[1] =
566
    (int)((size[1]+this->ImageReductionFactor-1)/this->ImageReductionFactor);
567 568

  // Collect and distribute information about current state of RenderWindow
569
  vtkRendererCollection *rens = this->GetRenderers();
570 571 572 573 574 575 576 577 578 579
  winInfo.FullSize[0] = this->FullImageSize[0];
  winInfo.FullSize[1] = this->FullImageSize[1];
  winInfo.ReducedSize[0] = this->ReducedImageSize[0];
  winInfo.ReducedSize[1] = this->ReducedImageSize[1];
  winInfo.NumberOfRenderers = rens->GetNumberOfItems();
  winInfo.ImageReductionFactor = this->ImageReductionFactor;
  winInfo.UseCompositing = this->UseCompositing;
  winInfo.DesiredUpdateRate = this->RenderWindow->GetDesiredUpdateRate();
  this->RenderWindow->GetTileScale(winInfo.TileScale);
  this->RenderWindow->GetTileViewport(winInfo.TileViewport);
580 581

  if (this->RenderEventPropagation)
582
  {
583 584
    this->Controller->TriggerRMIOnAllChildren(
      vtkParallelRenderManager::RENDER_RMI_TAG);
585
  }
586

587 588 589 590
  // Gather information about the window to send.
  vtkMultiProcessStream stream;
  winInfo.Save(stream);
  this->CollectWindowInformation(stream);
591 592

  if (this->ImageReductionFactor > 1)
593
  {
594
    this->Viewports->SetNumberOfTuples(rens->GetNumberOfItems());
595
  }
596 597

  vtkCollectionSimpleIterator cookie;
598
  vtkRenderer *ren;
599 600 601 602
  int i;

  for (rens->InitTraversal(cookie), i = 0;
       (ren = rens->GetNextRenderer(cookie)) != NULL; i++)
603
  {
604
    ren->GetViewport(renInfo.Viewport);
605 606 607

    // Adjust Renderer viewports to get reduced size image.
    if (this->ImageReductionFactor > 1)
608
    {
609
      this->Viewports->SetTuple(i, renInfo.Viewport);
610
      if (this->ImageReduceRenderer(ren))
611
      {
612 613 614 615 616
        renInfo.Viewport[0] /= this->ImageReductionFactor;
        renInfo.Viewport[1] /= this->ImageReductionFactor;
        renInfo.Viewport[2] /= this->ImageReductionFactor;
        renInfo.Viewport[3] /= this->ImageReductionFactor;
        ren->SetViewport(renInfo.Viewport);
617
      }
618
    }
619

620
    int hasActiveCamera=ren->IsActiveCameraCreated();
621
    vtkCamera *cam = ren->GetActiveCamera();
622
    if(!hasActiveCamera)
623
    {
624
      this->ResetCamera(ren);
625
    }
626 627 628 629 630 631
    cam->GetPosition(renInfo.CameraPosition);
    cam->GetFocalPoint(renInfo.CameraFocalPoint);
    cam->GetViewUp(renInfo.CameraViewUp);
    cam->GetClippingRange(renInfo.CameraClippingRange);
    renInfo.CameraViewAngle = cam->GetViewAngle();
    cam->GetWindowCenter(renInfo.WindowCenter);
632

633
    ren->GetBackground(renInfo.Background);
634 635
    ren->GetBackground2(renInfo.Background2);
    renInfo.GradientBackground=ren->GetGradientBackground();
Amy Squillacote's avatar
Amy Squillacote committed
636
    if (cam->GetParallelProjection())
637
    {
638
      renInfo.ParallelScale = cam->GetParallelScale();
639
    }
Amy Squillacote's avatar
Amy Squillacote committed
640
    else
641
    {
642
      renInfo.ParallelScale = 0.0;
643
    }
644
    renInfo.Draw = ren->GetDraw();
645
    vtkLightCollection *lc = ren->GetLights();
646 647
    renInfo.NumberOfLights = lc->GetNumberOfItems();
    renInfo.Save(stream);
648 649

    vtkLight *light;
Ken Martin's avatar
Ken Martin committed
650 651
    vtkCollectionSimpleIterator lsit;
    for (lc->InitTraversal(lsit); (light = lc->GetNextLight(lsit)); )
652
    {
653 654 655
      lightInfo.Type = (double)(light->GetLightType());
      light->GetPosition(lightInfo.Position);
      light->GetFocalPoint(lightInfo.FocalPoint);
656
      lightInfo.Save(stream);
657
    }
658 659
    this->CollectRendererInformation(ren, stream);
  }
660 661

  if (!this->Controller->Broadcast(stream, this->Controller->GetLocalProcessId()))
662
  {
663
    return;
664
  }
665 666 667 668 669

  // Backwards compatibility stuff.
  this->SendWindowInformation();
  rens->InitTraversal(cookie);
  while ((ren = rens->GetNextRenderer(cookie)) != NULL)
670
  {
671
    this->SendRendererInformation(ren);
672
  }
673

674 675 676
  this->PreRenderProcessing();
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
677
//----------------------------------------------------------------------------
678 679 680
void vtkParallelRenderManager::EndRender()
{
  if (!this->ParallelRendering)
681
  {
682
    return;
683
  }
684 685

  this->Timer->StopTimer();
686
  this->RenderTime = this->Timer->GetElapsedTime() - this->ImageProcessingTime;
687

688 689 690 691 692 693 694 695
  // Just because we are not doing compositing does not mean a subclass
  // does not need to do post render processing.
//   if (!this->UseCompositing)
//     {
//     this->Lock = 0;
//     return;
//     }

696
  if (this->CheckForAbortComposite())
697
  {
698 699
    this->Lock = 0;
    return;
700
  }
701

702 703 704 705
  this->PostRenderProcessing();

  // Restore renderer viewports, if necessary.
  if (this->ImageReductionFactor > 1)
706
  {
707 708
    vtkRendererCollection *rens = this->GetRenderers();
    vtkCollectionSimpleIterator cookie;
709
    vtkRenderer *ren;
710 711 712
    int i;
    for (rens->InitTraversal(cookie), i = 0;
         (ren = rens->GetNextRenderer(cookie)) != NULL; i++)
713
    {
714
      ren->SetViewport(this->Viewports->GetPointer(4*i));
715
    }
716
  }
717 718 719 720 721 722 723 724

  this->WriteFullImage();

  this->InvokeEvent(vtkCommand::EndEvent, NULL);

  this->Lock = 0;
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
725
//----------------------------------------------------------------------------
726 727
void vtkParallelRenderManager::SatelliteEndRender()
{
728
  if (this->CheckForAbortComposite())
729
  {
730
    return;
731
  }
732 733 734 735 736 737 738
// It's a mistake to check ParallelRendering on the Satellites.
// The Root node decides if the render calls are to be propagated to the
// satellites...the satellites always reply to the Root nodes requests.
//  if (!this->ParallelRendering)
//    {
//    return;
//    }
739 740 741 742 743 744
  // Just because we are not doing compositing does not mean a subclass
  // does not need to do post render processing.
//   if (!this->UseCompositing)
//     {
//     return;
//     }
745 746 747 748 749 750 751 752

  this->PostRenderProcessing();

  this->WriteFullImage();

  this->InvokeEvent(vtkCommand::EndEvent, NULL);
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
753
//----------------------------------------------------------------------------
754 755 756 757 758
void vtkParallelRenderManager::RenderRMI()
{
  this->RenderWindow->Render();
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
759
//----------------------------------------------------------------------------
760 761 762 763
void vtkParallelRenderManager::ResetCamera(vtkRenderer *ren)
{
  vtkDebugMacro("ResetCamera");

Ken Martin's avatar
Ken Martin committed
764
  double bounds[6];
765 766

  if (this->Lock)
767
  {
768 769 770 771 772
    // Can't query other processes in the middle of a render.
    // Just grab local value instead.
    this->LocalComputeVisiblePropBounds(ren, bounds);
    ren->ResetCamera(bounds);
    return;
773
  }
774

Ken Martin's avatar
Ken Martin committed
775
  this->Lock = 1;
776 777 778

  this->ComputeVisiblePropBounds(ren, bounds);
  // Keep from setting camera from some outrageous value.
Ken Martin's avatar
Ken Martin committed
779
  if (!vtkMath::AreBoundsInitialized(bounds))
780
  {
781 782
    // See if the not pickable values are better.
    ren->ComputeVisiblePropBounds(bounds);
Ken Martin's avatar
Ken Martin committed
783
    if (!vtkMath::AreBoundsInitialized(bounds))
784
    {
785 786 787
      this->Lock = 0;
      return;
    }
788
  }
789
  ren->ResetCamera(bounds);
790

791 792 793
  this->Lock = 0;
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
794
//----------------------------------------------------------------------------
795 796 797 798
void vtkParallelRenderManager::ResetCameraClippingRange(vtkRenderer *ren)
{
  vtkDebugMacro("ResetCameraClippingRange");

Ken Martin's avatar
Ken Martin committed
799
  double bounds[6];
800 801

  if (this->Lock)
802
  {
803 804 805 806 807
    // Can't query other processes in the middle of a render.
    // Just grab local value instead.
    this->LocalComputeVisiblePropBounds(ren, bounds);
    ren->ResetCameraClippingRange(bounds);
    return;
808
  }
809 810

  this->Lock = 1;
811

812 813 814 815 816 817
  this->ComputeVisiblePropBounds(ren, bounds);
  ren->ResetCameraClippingRange(bounds);

  this->Lock = 0;
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
818
//----------------------------------------------------------------------------
819
void vtkParallelRenderManager::ComputeVisiblePropBoundsRMI(int renderId)
820 821 822 823
{
  vtkDebugMacro("ComputeVisiblePropBoundsRMI");
  int i;

824
  vtkRendererCollection *rens = this->GetRenderers();
825
  vtkRenderer *ren = NULL;
Ken Martin's avatar
Ken Martin committed
826 827
  vtkCollectionSimpleIterator rsit;
  rens->InitTraversal(rsit);
828
  for (i = 0; i <= renderId; i++)
829
  {
Ken Martin's avatar
Ken Martin committed
830
    ren = rens->GetNextRenderer(rsit);
831
  }
832 833

  if (ren == NULL)
834
  {
835 836 837
    vtkWarningMacro("Client requested invalid renderer in "
            "ComputeVisiblePropBoundsRMI\n"
            "Defaulting to first renderer");
Ken Martin's avatar
Ken Martin committed
838
    ren = rens->GetFirstRenderer();
839
  }
840

Ken Martin's avatar
Ken Martin committed
841
  double bounds[6];
842 843 844 845 846 847
  this->LocalComputeVisiblePropBounds(ren, bounds);

  this->Controller->Send(bounds, 6, this->RootProcessId,
                         vtkParallelRenderManager::BOUNDS_TAG);
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
848
//----------------------------------------------------------------------------
849
void vtkParallelRenderManager::LocalComputeVisiblePropBounds(vtkRenderer *ren,
Ken Martin's avatar
Ken Martin committed
850
                                                             double bounds[6])
851 852 853 854 855
{
  ren->ComputeVisiblePropBounds(bounds);
}


Mathieu Malaterre's avatar
Mathieu Malaterre committed
856
//----------------------------------------------------------------------------
857
void vtkParallelRenderManager::ComputeVisiblePropBounds(vtkRenderer *ren,
Ken Martin's avatar
Ken Martin committed
858
                                                        double bounds[6])
859
{
860
  vtkDebugMacro(<< "ComputeVisiblePropBounds");
861 862

  if (!this->ParallelRendering)
863
  {
864 865
    ren->ComputeVisiblePropBounds(bounds);
    return;
866
  }
867 868

  if (this->Controller)
869
  {
870
    if (this->Controller->GetLocalProcessId() != this->RootProcessId)
871
    {
872 873
      vtkErrorMacro("ComputeVisiblePropBounds/ResetCamera can only be called on root process");
      return;
874
    }
875

876
    vtkRendererCollection *rens = this->GetRenderers();
Ken Martin's avatar
Ken Martin committed
877 878
    vtkCollectionSimpleIterator rsit;
    rens->InitTraversal(rsit);
879
    int renderId = 0;
Ken Martin's avatar
Ken Martin committed
880
    while (1)
881
    {
Ken Martin's avatar
Ken Martin committed
882
      vtkRenderer *myren = rens->GetNextRenderer(rsit);
883
      if (myren == NULL)
884
      {
885 886 887
        vtkWarningMacro("ComputeVisiblePropBounds called with unregistered renderer " << ren << "\nDefaulting to first renderer.");
        renderId = 0;
        break;
888
      }
889
      if (myren == ren)
890
      {
891 892 893
        //Found correct renderer.
        break;
      }
894 895
      renderId++;
    }
896 897 898 899

    //Invoke RMI's on servers to perform their own ComputeVisiblePropBounds.
    int numProcs = this->Controller->GetNumberOfProcesses();
    int id;
900 901
    this->Controller->TriggerRMIOnAllChildren(&renderId, sizeof(int),
      vtkParallelRenderManager::COMPUTE_VISIBLE_PROP_BOUNDS_RMI_TAG);
902

903 904 905 906
    //Now that all the RMI's have been invoked, we can safely query our
    //local bounds even if an Update requires a parallel operation.

    this->LocalComputeVisiblePropBounds(ren, bounds);
907

908 909
    //Collect all the bounds.
    for (id = 0; id < numProcs; id++)
910
    {
Ken Martin's avatar
Ken Martin committed
911
      double tmp[6];
912 913

      if (id == this->RootProcessId)
914
      {
915
        continue;
916
      }
917 918

      this->Controller->Receive(tmp, 6, id, vtkParallelRenderManager::BOUNDS_TAG);
919

920
      if (tmp[0] < bounds[0])
921
      {
922
        bounds[0] = tmp[0];
923
      }
924
      if (tmp[1] > bounds[1])
Kitware Robot's avatar