18 #include "milxQtAnimateModel.h" 22 #include <vtkWindowToImageFilter.h> 23 #include <vtkFFMPEGWriter.h> 24 #include <vtkCamera.h> 26 milxQtAnimateModel::milxQtAnimateModel(QWidget *theParent,
bool contextSystem) :
milxQtModel(theParent, contextSystem)
32 m_rotationInterval = 5;
41 milxQtAnimateModel::~milxQtAnimateModel()
48 const int n = meshes->GetNumberOfItems();
53 printInfo(
"Extracting IDs");
57 QDialog *casePossibilities =
new QDialog(
this);
58 QComboBox *integerValues =
new QComboBox(
this);
59 QPushButton *okButton =
new QPushButton(
this);
60 okButton->setText(
"Ok");
61 QLabel *lblMessage =
new QLabel(
this);
62 lblMessage->setText(
"Choose Case ID from possibilities.");
63 QFormLayout *formLayout =
new QFormLayout(
this);
64 formLayout->addRow(lblMessage);
65 formLayout->addRow(tr(
"&Select Case ID from first file: "), integerValues);
66 formLayout->addRow(okButton);
67 casePossibilities->setLayout(formLayout);
69 connect(okButton, SIGNAL(clicked(
bool)), casePossibilities, SLOT(accept()));
71 meshes->InitTraversal();
76 for(
int j = 0; j < n; j ++)
78 QFileInfo fi(filenames[j]);
79 QRegExp rx(
"(\\d+)", Qt::CaseSensitive, QRegExp::RegExp2);
84 while ((pos = rx.indexIn(fi.baseName(), pos)) != -1)
87 pos += rx.matchedLength();
93 if(list.size() > 1 && idIndex < 0)
95 printInfo(
"Please choose Case ID from possibilities for first file.");
96 for(
int k = 0; k < list.size(); k ++)
97 integerValues->addItem(list[k]);
99 casePossibilities->exec();
101 index = integerValues->currentIndex();
103 else if(list.size() > 0 && idIndex < list.size() && idIndex > 0)
107 else if(list.size() > 0 && idIndex < list.size() && idIndex < 0)
113 printError(
"Index provided for expected case IDs is incorrect. Ignoring operation.");
120 printDebug(
"Frame Index to be used: " + QString::number(index));
122 caseID = list[index].toInt();
124 m_caseIDs.append(caseID);
126 qApp->processEvents();
130 qDebug() <<
"IDs: " << m_caseIDs << endl;
132 printInfo(
"Starting Animation Loop");
133 connect(&timer, SIGNAL(timeout()),
this, SLOT(updateAnimation()));
134 timer.start(m_interval);
147 menu->addAction(currAct);
149 foreach(QMenu *currMenu, menusToAdd)
151 menu->addMenu(currMenu);
153 menu->addSeparator()->setText(
"Animation");
154 menu->addAction(startAct);
155 menu->addAction(pauseAct);
156 menu->addAction(rotationAct);
157 menu->addAction(intervalAct);
158 menu->addAction(rotationIntervalAct);
159 menu->addAction(movieAct);
160 menu->addSeparator()->setText(tr(
"Display"));
181 menu->addSeparator()->setText(tr(
"Properties"));
184 menu->addSeparator();
191 void milxQtAnimateModel::reset()
194 m_meshes->InitTraversal();
202 const int n = m_meshes->GetNumberOfItems();
210 if(rotationAct->isChecked())
211 srcCamera->Azimuth(m_rotationInterval);
213 printDebug(
"Animating frame " + QString::number(m_currentID) +
" of " + QString::number(n));
216 vtkSmartPointer<vtkPolyData> mesh = m_meshes->GetNextItem();
219 qApp->processEvents();
222 void milxQtAnimateModel::startAnimation()
229 void milxQtAnimateModel::pauseAnimation()
239 void milxQtAnimateModel::interval(
int newInterval)
245 newInterval = QInputDialog::getInt(
this, tr(
"Please Provide the delay between frames"),
246 tr(
"Interval:"), m_interval, 0, 1000000, 1, &ok);
251 if(ok && newInterval > 0)
253 m_interval = newInterval;
254 timer.start(m_interval);
258 void milxQtAnimateModel::intervalRotation(
int newInterval)
264 newInterval = QInputDialog::getDouble(
this, tr(
"Please Provide the angle increment"),
265 tr(
"Angle:"), 5, 0, 360, 2, &ok);
270 if(ok && newInterval > 0)
271 m_rotationInterval = newInterval;
279 if(filename.isEmpty())
281 QSettings settings(
"Shekhar Chandra",
"milxQt");
282 QString path = settings.value(
"recentPath").toString();
283 QFileDialog *fileSaver =
new QFileDialog(
this);
284 filename = fileSaver->getSaveFileName(
this,
285 tr(
"Select File Name to Save"),
287 tr(
"Movie Files (*.avi)"));
290 if(!filename.isEmpty())
292 const int n = m_meshes->GetNumberOfItems();
293 const int frameRate = 1000.0/m_interval;
298 frames =
static_cast<int>( QInputDialog::getInt(
this, tr(
"Please Provide the total frames to write"),
299 tr(
"Frames:"), n, 0, 8192, 1, &ok) );
307 vtkWindowToImageFilter *windowToImage = vtkWindowToImageFilter::New();
308 windowToImage->SetInput(milxQtRenderWindow::GetRenderWindow());
309 linkProgressEventOf(windowToImage);
311 vtkSmartPointer<vtkFFMPEGWriter> writer = vtkSmartPointer<vtkFFMPEGWriter>::New();
312 writer->SetFileName(filename.toStdString().c_str());
313 writer->SetInputConnection(windowToImage->GetOutputPort());
314 writer->SetRate(frameRate);
315 linkProgressEventOf(writer);
321 printDebug(
"Movie Write Begin");
322 for(
int j = 0; j < frames; j ++)
324 printDebug(
"Loading Frame " + QString::number(j));
328 vtkPolyData *mesh = m_meshes->GetNextItem();
333 qApp->processEvents();
335 windowToImage->Update();
337 printDebug(
"Writing Frame " + QString::number(j));
338 writer->SetInputConnection(windowToImage->GetOutputPort());
341 printDebug(
"Prep next Frame ");
342 windowToImage->Delete();
343 windowToImage = vtkWindowToImageFilter::New();
344 windowToImage->SetInput(milxQtRenderWindow::GetRenderWindow());
345 linkProgressEventOf(windowToImage);
346 windowToImage->Update();
348 if(rotationAct->isChecked())
349 srcCamera->Azimuth(m_rotationInterval);
350 printDebug(
"Finish Loop");
352 printDebug(
"Movie Written Successfully");
354 printDebug(
"Movie File Closed Sucessfully");
355 windowToImage->Delete();
360 printInfo(
"Movie Operation Completed");
363 timer.start(m_interval);
366 void milxQtAnimateModel::createActions()
368 contextMenu =
new QMenu(
this);
369 contextMenu->setTitle(QApplication::translate(
"MainWindow",
"Animation", 0, QApplication::UnicodeUTF8));
371 startAct =
new QAction(
this);
372 startAct->setText(QApplication::translate(
"Model",
"Start/Restart", 0, QApplication::UnicodeUTF8));
373 startAct->setShortcut(tr(
"Alt+s"));
374 pauseAct =
new QAction(
this);
375 pauseAct->setText(QApplication::translate(
"Model",
"Pause/Unpause", 0, QApplication::UnicodeUTF8));
376 pauseAct->setShortcut(tr(
"Alt+p"));
377 intervalAct =
new QAction(
this);
378 intervalAct->setText(QApplication::translate(
"Model",
"Change Interval", 0, QApplication::UnicodeUTF8));
379 intervalAct->setShortcut(tr(
"Alt+i"));
380 rotationIntervalAct =
new QAction(
this);
381 rotationIntervalAct->setText(QApplication::translate(
"Model",
"Change Rotation Interval", 0, QApplication::UnicodeUTF8));
382 rotationIntervalAct->setShortcut(tr(
"Shift+Alt+r"));
383 rotationAct =
new QAction(
this);
384 rotationAct->setText(QApplication::translate(
"Model",
"Rotate View", 0, QApplication::UnicodeUTF8));
385 rotationAct->setShortcut(tr(
"Alt+r"));
386 rotationAct->setCheckable(
true);
387 rotationAct->setChecked(
false);
388 movieAct =
new QAction(
this);
389 movieAct->setText(QApplication::translate(
"Model",
"Record as Movie", 0, QApplication::UnicodeUTF8));
390 movieAct->setShortcut(tr(
"Alt+m"));
393 void milxQtAnimateModel::createConnections()
396 connect(startAct, SIGNAL(triggered()),
this, SLOT(startAnimation()));
397 connect(pauseAct, SIGNAL(triggered()),
this, SLOT(pauseAnimation()));
398 connect(intervalAct, SIGNAL(triggered()),
this, SLOT(interval()));
399 connect(rotationIntervalAct, SIGNAL(triggered()),
this, SLOT(intervalRotation()));
400 connect(movieAct, SIGNAL(triggered()),
this, SLOT(movie()));
405 void milxQtAnimateModel::contextMenuEvent(QContextMenuEvent *currentEvent)
407 createMenu(contextMenu);
409 contextMenu->exec(currentEvent->globalPos());
QAction * scaleAct
Action for the scale bar of the display.
QAction * normalsAct
Action for showing the normals of a model.
QAction * outlineAct
show outline action
QAction * saveViewFileAct
Save camera view to file.
QMenu * viewMenu
Context Menu.
void setName(const QString filename)
Set the name of the data.
QAction * pointsAct
Show points.
QAction * viewZY
Change view to zy-plane (Coronal)
void createConnections()
Create the connections for context menu etc.
QAction * surfaceAct
Show surface.
void SetInputCollection(vtkPolyDataCollection *meshes, QStringList &filenames, const int idIndex=-1)
Animate the collection provided.
QAction * wireframeAct
Show wireframe.
void SetInput(vtkSmartPointer< vtkPolyData > mesh)
Assigns the mesh provided to the class, preparing for display. Call generateModel() and then show() t...
QString prefix
Prefix of the data.
QAction * centroidAct
show centroid action
This class represents the MILX Qt Model/Mesh Display object using VTK.
void OffScreenRenderingOn()
Enable off-screen rendering, which is faster for large datasets in some instances.
void OffScreenRenderingOff()
Disable off-screen rendering, which is faster for large datasets in some instances.
void refresh()
Refresh the display of the model.
QAction * colourAct
Action for changing colours of a model.
QAction * cubeAxesAct
show cube axes action
QAction * refreshAct
Action for refreshing the display.
void enableActionBasedOnView()
Enables the view actions corresponding to current view set.
QMenu * arraysMenu()
Return the arrays menu with the milxQtModel class ordering. This is for the benefit of derived class ...
QAction * resetAct
Action for refreshing the display.
QMenu * colourMapMenu
Colour map menu.
QAction * saveViewAct
Save camera view.
QAction * viewXY
Change view to xy-plane (Axial)
QList< QAction * > actionsToAdd
Context actions to add.
void movie(QString filename="", int frames=0)
QAction * viewZX
Change view to zx-plane (Sagittal)
QMenu * showMenu
Camera Menu.
virtual void createMenu(QMenu *menu)
Create the menu for the data in this object. Used for context menu and file menus.
QAction * interpAct
Action for changing the interpolation of a model.
QMenu * windowPropertiesMenu
Context Menu.
vtkRenderer * GetRenderer()
Returns the VTK Renderer object.
QAction * loadViewAct
Load camera view.
QAction * loadViewFileAct
Load camera view to file.