VTK  9.7.1
TestMotionFXCFGReaderCommon.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-License-Identifier: BSD-3-Clause
3 #ifndef TestMotionFXCFGReaderCommon_h
4 #define TestMotionFXCFGReaderCommon_h
5 
6 #include <vtkActor.h>
7 #include <vtkCallbackCommand.h>
9 #include <vtkInformation.h>
10 #include <vtkMotionFXCFGReader.h>
11 #include <vtkNew.h>
12 #include <vtkRenderWindow.h>
14 #include <vtkRenderer.h>
15 #include <vtkSmartPointer.h>
17 #include <vtkTestUtilities.h>
18 #include <vtkTesting.h>
19 
20 #include <algorithm>
21 #include <cassert>
22 #include <iostream>
23 #include <vector>
24 
25 namespace impl
26 {
27 
28 struct ClientData
29 {
33  std::vector<double> TimeSteps;
35 
36  void GoToNext()
37  {
38  std::cout << "Go to next" << std::endl;
39  this->CurrentIndex =
40  std::min(static_cast<int>(this->TimeSteps.size()) - 1, this->CurrentIndex + 1);
41  this->Render();
42  }
43 
44  void GoToPrev()
45  {
46  std::cout << "Go to prev" << std::endl;
47  this->CurrentIndex = std::max(0, this->CurrentIndex - 1);
48  this->Render();
49  }
50 
51  void Play()
52  {
53  std::cout << "Playing";
54  for (size_t cc = 0; cc < this->TimeSteps.size(); ++cc)
55  {
56  std::cout << ".";
57  std::cout.flush();
58  this->CurrentIndex = static_cast<int>(cc);
59  this->Render();
60  }
61  std::cout << std::endl;
62  }
63 
64  void Render()
65  {
66  assert(
67  this->CurrentIndex >= 0 && this->CurrentIndex < static_cast<int>(this->TimeSteps.size()));
68  this->Reader->UpdateTimeStep(this->TimeSteps[this->CurrentIndex]);
69  this->Mapper->SetInputDataObject(this->Reader->GetOutputDataObject(0));
70  this->Window->Render();
71  }
72 };
73 
74 static void CharEventCallback(vtkObject* caller, unsigned long, void* clientdata, void*)
75 {
76  ClientData& data = *reinterpret_cast<ClientData*>(clientdata);
77  auto iren = vtkRenderWindowInteractor::SafeDownCast(caller);
78  switch (iren->GetKeyCode())
79  {
80  case 'x':
81  case 'X':
82  data.GoToNext();
83  break;
84 
85  case 'z':
86  case 'Z':
87  data.GoToPrev();
88  break;
89 
90  case 'c':
91  case 'C':
92  data.Play();
93  break;
94  }
95 }
96 
97 template <typename InitializationCallback>
98 int Test(int argc, char* argv[], const char* dfile, const InitializationCallback& initCallback)
99 {
101  char* fname = vtkTestUtilities::ExpandDataFileName(argc, argv, dfile);
102  reader->SetFileName(fname);
103  delete[] fname;
104 
105  reader->SetTimeResolution(100);
106  reader->UpdateInformation();
107 
109  vtkInformation* outInfo = reader->GetOutputInformation(0);
110  const int numTimeSteps = outInfo->Length(SDDP::TIME_STEPS());
111 
112  if (numTimeSteps != 100)
113  {
114  std::cerr << "ERROR: missing timesteps. Potential issue reading the CFG file." << std::endl;
115  return EXIT_FAILURE;
116  }
117 
119 
120  vtkNew<vtkRenderer> renderer;
121  renWin->AddRenderer(renderer);
122 
124  iren->SetRenderWindow(renWin);
125 
127  mapper->SetInputConnection(reader->GetOutputPort());
128 
129  vtkNew<vtkActor> actor;
130  actor->SetMapper(mapper);
131  renderer->AddActor(actor);
132 
133  initCallback(renWin, renderer, reader);
134 
135  std::vector<double> ts(numTimeSteps);
136  outInfo->Get(SDDP::TIME_STEPS(), ts.data());
137 
138  // for baseline comparison, we'll jump to the middle of the
139  // time sequence and do a capture.
140  reader->UpdateTimeStep(ts[numTimeSteps / 2]);
141  mapper->SetInputDataObject(reader->GetOutputDataObject(0));
142  renWin->Render();
143 
144  const int retVal = vtkTesting::Test(argc, argv, renWin, 10);
145  if (retVal == vtkTesting::DO_INTERACTOR)
146  {
148  data.Window = renWin;
149  data.Reader = reader;
150  data.Mapper = mapper;
151  data.TimeSteps = ts;
152  data.CurrentIndex = numTimeSteps / 2;
153 
155  observer->SetClientData(&data);
156  observer->SetCallback(&CharEventCallback);
157  iren->AddObserver(vtkCommand::CharEvent, observer);
158 
159  std::cout << "Entering interactive mode......" << std::endl
160  << "Supported operations:" << std::endl
161  << " 'z' or 'Z' : go to next time step" << std::endl
162  << " 'x' or 'X' : go to previous time step" << std::endl
163  << " 'c' or 'C' : play animation from start to end" << std::endl
164  << " 'q' or 'Q' : quit" << std::endl;
165  iren->Start();
166  return EXIT_SUCCESS;
167  }
168  else if (retVal == vtkTesting::NOT_RUN)
169  {
170  return VTK_SKIP_RETURN_CODE;
171  }
172  else if (retVal == vtkTesting::PASSED)
173  {
174  return EXIT_SUCCESS;
175  }
176 
177  return EXIT_FAILURE;
178 }
179 }
180 
181 #endif
void AddActor(vtkProp *p)
Add/Remove different types of props to the renderer.
std::vector< double > TimeSteps
virtual void SetClientData(void *cd)
Methods to set and get client and callback information, and the callback function.
virtual void SetTimeResolution(int)
Get/Set the time resolution for timesteps produced by the reader.
abstract base class for most VTK objects
Definition: vtkObject.h:52
vtkAlgorithmOutput * GetOutputPort(int index)
Get a proxy object corresponding to the given output port of this algorithm.
static vtkRenderWindowInteractor * SafeDownCast(vtkObjectBase *o)
Store vtkAlgorithm input/output information.
static void CharEventCallback(vtkObject *caller, unsigned long, void *clientdata, void *)
vtkSmartPointer< vtkMotionFXCFGReader > Reader
void SetRenderWindow(vtkRenderWindow *aren)
Set/Get the rendering window being controlled by this object.
vtkDataObject * GetOutputDataObject(int port)
Get the data object that will contain the algorithm output for the given port.
virtual void AddRenderer(vtkRenderer *)
Add a renderer to the list of renderers.
unsigned long AddObserver(unsigned long event, vtkCommand *, float priority=0.0f)
Allow people to add/remove/invoke observers (callbacks) to any VTK object.
void Render() override
Ask each renderer owned by this RenderWindow to render its image and synchronize this process...
virtual void SetInputDataObject(int port, vtkDataObject *data)
Sets the data-object as an input on the given port index.
void SetFileName(const char *fname)
Get/Set the filename.
virtual void Start()
Start the event loop.
vtkSmartPointer< vtkRenderWindow > Window
int Get(vtkInformationIntegerKey *key)
Get/Set an integer-valued entry.
int Test(int argc, char *argv[], const char *dfile, const InitializationCallback &initCallback)
virtual void SetInputConnection(int port, vtkAlgorithmOutput *input)
Set the connection for the given input port index.
virtual int UpdateTimeStep(double time, int piece=-1, int numPieces=1, int ghostLevels=0, const int extents[6]=nullptr)
Convenience method to update an algorithm after passing requests to its first output port...
vtkSmartPointer< vtkCompositePolyDataMapper > Mapper
int Length(vtkInformationIntegerVectorKey *key)
Get/Set an integer-vector-valued entry.
virtual bool UpdateInformation()
Bring the algorithm's information up-to-date.
Allocate and hold a VTK object.
virtual void SetMapper(vtkMapper *)
This is the method that is used to connect an actor to the end of a visualization pipeline...
Executive supporting partial updates.
vtkInformation * GetOutputInformation(int port)
Return the information object that is associated with a particular output port.
#define max(a, b)
virtual void SetCallback(void(*f)(vtkObject *caller, unsigned long eid, void *clientdata, void *calldata))