File: TestSimpleIceTCompositePass.cxx

package info (click to toggle)
paraview 5.1.2%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 221,108 kB
  • ctags: 236,092
  • sloc: cpp: 2,416,026; ansic: 190,891; python: 99,856; xml: 81,001; tcl: 46,915; yacc: 5,039; java: 4,413; perl: 3,108; sh: 1,974; lex: 1,926; f90: 748; asm: 471; pascal: 228; makefile: 198; objc: 83; fortran: 31
file content (178 lines) | stat: -rw-r--r-- 7,292 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
// A simple example that demonstrate how to use the vtkIceTCompositePass and
// supporting classes to render a sphere in parallel.
// This only uses the minimal set of functionality and hence does not support
// opacity < 1.0. Refer to TestIceTCompositePass.cxx for a more exhaustive
// example.

#include "vtkActor.h"
#include "vtkCamera.h"
#include "vtkCameraPass.h"
#include "vtkIceTCompositePass.h"
#include "vtkLightsPass.h"
#include "vtkMPIController.h"
#include "vtkOpaquePass.h"
#include "vtkPieceScalars.h"
#include "vtkPolyDataMapper.h"
#include "vtkPSphereSource.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderer.h"
#include "vtkOpenGLRenderer.h"
#include "vtkRenderPassCollection.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSequencePass.h"
#include "vtkSmartPointer.h"
#include "vtkSynchronizedRenderers.h"
#include "vtkSynchronizedRenderWindows.h"
#include "vtkTesting.h"

#include "mpi.h"

int main(int argc, char**argv)
{
  //---------------------------------------------------------------------------
  // Initialize MPI.

  // This is here to avoid false leak messages from vtkDebugLeaks when
  // using mpich. It appears that the root process which spawns all the
  // main processes waits in MPI_Init() and calls exit() when
  // the others are done, causing apparent memory leaks for any objects
  // created before MPI_Init().
  MPI_Init(&argc, &argv);

  vtkSmartPointer<vtkMPIController> controller =
    vtkSmartPointer<vtkMPIController>::New();
  controller->Initialize(&argc, &argv, 1);

  // Get information about the group of processes involved.
  int my_id = controller->GetLocalProcessId();
  int num_procs = controller->GetNumberOfProcesses();
  int retVal = vtkTesting::PASSED;

  // This block ensures that controller is released by all filters before we
  // reach the end to avoid leaks
  if (true)
    {
    //---------------------------------------------------------------------------
    // Create Visualization Pipeline.
    // This code is common to all processes.
    vtkSmartPointer<vtkPSphereSource> sphere = vtkSmartPointer<vtkPSphereSource>::New();
    sphere->SetThetaResolution(50);
    sphere->SetPhiResolution(50);

    // Gives separate colors for each process. Just makes it easier to see how the
    // data is distributed among processes.
    vtkSmartPointer<vtkPieceScalars> piecescalars =
      vtkSmartPointer<vtkPieceScalars>::New();
    piecescalars->SetInputConnection(sphere->GetOutputPort());
    piecescalars->SetScalarModeToCellData();

    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(piecescalars->GetOutputPort());
    mapper->SetScalarModeToUseCellFieldData();
    mapper->SelectColorArray("Piece");
    mapper->SetScalarRange(0, num_procs-1);
    // This sets up the piece-request. This tells vtkPSphereSource to only
    // generate part of the data on this processes.
    mapper->SetPiece(my_id);
    mapper->SetNumberOfPieces(num_procs);

    vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);

    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
    renderer->AddActor(actor);

    vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
    renWin->AddRenderer(renderer);

    // 400x400 windows, +24 in y to avoid gnome menu bar.
    renWin->SetPosition(my_id * 410, 0);
    renWin->SetSize(400, 400);

    //---------------------------------------------------------------------------
    // Setup the render passes. This is just a very small subset of necessary
    // render passes needed to render a opaque sphere.
    vtkSmartPointer<vtkCameraPass> cameraP = vtkSmartPointer<vtkCameraPass>::New();
    vtkSmartPointer<vtkSequencePass> seq = vtkSmartPointer<vtkSequencePass>::New();
    vtkSmartPointer<vtkOpaquePass> opaque = vtkSmartPointer<vtkOpaquePass>::New();
    vtkSmartPointer<vtkLightsPass> lights = vtkSmartPointer<vtkLightsPass>::New();
    vtkSmartPointer<vtkRenderPassCollection> passes =
      vtkSmartPointer<vtkRenderPassCollection>::New();
    passes->AddItem(lights);
    passes->AddItem(opaque);
    seq->SetPasses(passes);

    // Each processes only has part of the data, so each process will render only
    // part of the data. To ensure that root node gets a composited result (or in
    // case of tile-display mode all nodes show part of tile), we use
    // vtkIceTCompositePass.
    vtkSmartPointer<vtkIceTCompositePass> iceTPass =
      vtkSmartPointer<vtkIceTCompositePass>::New();
    iceTPass->SetController(controller);

    // this is the pass IceT is going to use to render the geometry.
    iceTPass->SetRenderPass(seq);

    // insert the iceT pass into the pipeline.
    cameraP->SetDelegatePass(iceTPass);

    vtkOpenGLRenderer *glrenderer = vtkOpenGLRenderer::SafeDownCast(renderer);
    glrenderer->SetPass(cameraP);

    //---------------------------------------------------------------------------
    // In parallel configurations, typically one node acts as the driver i.e. the
    // node where the user interacts with the window e.g. mouse interactions,
    // resizing windows etc. Typically that's the root-node.
    // To ensure that the window parameters get propagated to all processes from
    // the root node, we use the vtkSynchronizedRenderWindows.
    vtkSmartPointer<vtkSynchronizedRenderWindows> syncWindows =
      vtkSmartPointer<vtkSynchronizedRenderWindows>::New();
    syncWindows->SetRenderWindow(renWin);
    syncWindows->SetParallelController(controller);

    // Since there could be multiple render windows that could be synced
    // separately, to identify the windows uniquely among all processes, we need
    // to give each vtkSynchronizedRenderWindows a unique id that's consistent
    // across all the processes.
    syncWindows->SetIdentifier(231);

    // Now we need to ensure that the render is synchronized as well. This is
    // essential to ensure all processes have the same camera orientation etc.
    // This is done using the vtkSynchronizedRenderers class.
    vtkSmartPointer<vtkSynchronizedRenderers> syncRenderers =
      vtkSmartPointer<vtkSynchronizedRenderers>::New();
    syncRenderers->SetRenderer(renderer);
    syncRenderers->SetParallelController(controller);

    //---------------------------------------------------------------------------
    // Now start the event loop on the root node, on the satellites, we start the
    // vtkMultiProcessController::ProcessRMIs() so those processes start listening
    // to commands from the root-node.

    if (my_id==0)
      {
      vtkSmartPointer<vtkRenderWindowInteractor> iren =
        vtkSmartPointer<vtkRenderWindowInteractor>::New();
      iren->SetRenderWindow(renWin);
      renderer->ResetCamera(-0.5, 0.5, -0.5, 0.5, -0.5, 0.5);

      renWin->Render();
      retVal = vtkTesting::Test(argc, argv, renWin, 10);
      if (retVal == vtkRegressionTester::DO_INTERACTOR)
        {
        iren->Start();
        }

      controller->TriggerBreakRMIs();
      controller->Barrier();
      }
    else
      {
      controller->ProcessRMIs();
      controller->Barrier();
      }
    }
  controller->Finalize();
  return !retVal;
}