Bug Summary

File:OMEdit/OMEditLIB/Animation/AbstractAnimationWindow.cpp
Warning:line 316, column 7
Potential leak of memory pointed to by 'widget'

Annotated Source Code

[?] Use j/k keys for keyboard navigation

1/*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-CurrentYear, Open Source Modelica Consortium (OSMC),
5 * c/o Linköpings universitet, Department of Computer and Information Science,
6 * SE-58183 Linköping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR
11 * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2.
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE
13 * OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
14 *
15 * The OpenModelica software and the Open Source Modelica
16 * Consortium (OSMC) Public License (OSMC-PL) are obtained
17 * from OSMC, either from the above address,
18 * from the URLs: http://www.ida.liu.se/projects/OpenModelica or
19 * http://www.openmodelica.org, and in the OpenModelica distribution.
20 * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html.
21 *
22 * This program is distributed WITHOUT ANY WARRANTY; without
23 * even the implied warranty of MERCHANTABILITY or FITNESS
24 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
25 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
26 *
27 * See the full OSMC Public License conditions for more details.
28 *
29 */
30/*
31 * @author Volker Waurich <volker.waurich@tu-dresden.de>
32 */
33
34#include <osg/MatrixTransform>
35#include <osg/Vec3>
36#include <osgDB/ReadFile>
37
38#include "AbstractAnimationWindow.h"
39#include "Modeling/MessagesWidget.h"
40#include "Options/OptionsDialog.h"
41#include "Modeling/MessagesWidget.h"
42#include "Plotting/PlotWindowContainer.h"
43#include "ViewerWidget.h"
44#include "Visualizer.h"
45#include "VisualizerMAT.h"
46#include "VisualizerCSV.h"
47
48/*!
49 * \class AbstractAnimationWindow
50 * \brief Abstract animation class defines a QMainWindow for animation.
51 */
52/*!
53 * \brief AbstractAnimationWindow::AbstractAnimationWindow
54 * \param pParent
55 */
56AbstractAnimationWindow::AbstractAnimationWindow(QWidget *pParent)
57 : QMainWindow(pParent),
58// osgViewer::CompositeViewer(),
59 mPathName(""),
60 mFileName(""),
61 mpVisualizer(nullptr),
62 mpViewerWidget(nullptr),
63 mpAnimationToolBar(new QToolBar(QString("Animation Toolbar"),this)),
64 mpAnimationParameterDockerWidget(new QDockWidget(QString("Parameter Settings"),this)),
65 mpAnimationChooseFileAction(nullptr),
66 mpAnimationInitializeAction(nullptr),
67 mpAnimationPlayAction(nullptr),
68 mpAnimationPauseAction(nullptr),
69 mpAnimationRepeatAction(nullptr),
70 mpAnimationSlider(nullptr),
71 mpAnimationTimeLabel(nullptr),
72 mpTimeTextBox(nullptr),
73 mpAnimationSpeedLabel(nullptr),
74 mpSpeedComboBox(nullptr),
75 mpPerspectiveDropDownBox(nullptr),
76 mpRotateCameraLeftAction(nullptr),
77 mpRotateCameraRightAction(nullptr),
78 mCameraInitialized(false),
79 mSliderRange(1000)
80{
81 // to distinguish this widget as a subwindow among the plotwindows
82 setObjectName(QString("animationWindow"));
83 //the viewer widget
84 mpViewerWidget = new ViewerWidget(this);
85 // we need to set the minimum height so that visualization window is still shown when we cascade windows.
86 mpViewerWidget->setMinimumHeight(100);
87 // toolbar icon size
88 int toolbarIconSize = OptionsDialog::instance()->getGeneralSettingsPage()->getToolbarIconSizeSpinBox()->value();
89 mpAnimationToolBar->setIconSize(QSize(toolbarIconSize, toolbarIconSize));
90 addToolBar(Qt::TopToolBarArea, mpAnimationToolBar);
91 addDockWidget(Qt::RightDockWidgetArea, mpAnimationParameterDockerWidget);
92
93 // Viewer layout
94 QGridLayout *pGridLayout = new QGridLayout;
95 pGridLayout->setContentsMargins(0, 0, 0, 0);
96 pGridLayout->addWidget(mpViewerWidget);
97 // add the viewer to the frame for boxed rectangle around it.
98 QFrame *pCentralWidgetFrame = new QFrame;
99 pCentralWidgetFrame->setFrameStyle(QFrame::StyledPanel);
100 pCentralWidgetFrame->setLayout(pGridLayout);
101 setCentralWidget(pCentralWidgetFrame);
102}
103
104/*!
105 * \brief AbstractAnimationWindow::openAnimationFile
106 * \param fileName
107 */
108void AbstractAnimationWindow::openAnimationFile(QString fileName, bool stashCamera)
109{
110 std::string file = fileName.toStdString();
111 if (file.compare("")) {
4
Assuming the condition is true
5
Taking true branch
112 std::size_t pos = file.find_last_of("/\\");
113 mPathName = file.substr(0, pos + 1);
114 mFileName = file.substr(pos + 1, file.length());
115 //std::cout<<"file "<<mFileName<<" path "<<mPathName<<std::endl;
116 if (loadVisualization()) {
6
Taking true branch
117 // start the widgets
118 mpAnimationInitializeAction->setEnabled(true);
119 mpAnimationPlayAction->setEnabled(true);
120 mpAnimationPauseAction->setEnabled(true);
121 mpAnimationRepeatAction->setEnabled(true);
122 mpAnimationSlider->setEnabled(true);
123 bool state = mpAnimationSlider->blockSignals(true);
124 mpAnimationSlider->setValue(0);
125 mpAnimationSlider->blockSignals(state);
126 mpSpeedComboBox->setEnabled(true);
127 mpTimeTextBox->setEnabled(true);
128 mpTimeTextBox->setText(QString::number(mpVisualizer->getTimeManager()->getStartTime()));
129 /* Only use isometric view as default for csv file type.
130 * Otherwise use side view as default which suits better for Modelica models.
131 */
132 if (isCSV(mFileName)) {
7
Taking false branch
133 mpPerspectiveDropDownBox->setCurrentIndex(0);
134 cameraPositionIsometric();
135 } else {
136 mpPerspectiveDropDownBox->setCurrentIndex(1);
137 cameraPositionSide();
138 }
139 if (isFMU(mFileName)) {
8
Taking true branch
140 initInteractiveControlPanel();
9
Calling 'AbstractAnimationWindow::initInteractiveControlPanel'
141 }
142
143 if(stashCamera && !mCameraInitialized) { // mCameraInitialized is used to make sure the view is never stashed
144 mCameraInitialized = true; // before the camera is initialized the first time
145 stashView();
146 }
147 }
148 }
149}
150
151void AbstractAnimationWindow::createActions()
152{
153 // actions and widgets for the toolbar
154 int toolbarIconSize = OptionsDialog::instance()->getGeneralSettingsPage()->getToolbarIconSizeSpinBox()->value();
155 // choose file action
156 mpAnimationChooseFileAction = new QAction(QIcon(":/Resources/icons/open.svg"), Helper::animationChooseFile, this);
157 mpAnimationChooseFileAction->setStatusTip(Helper::animationChooseFileTip);
158 connect(mpAnimationChooseFileAction, SIGNAL(triggered())"2""triggered()",this, SLOT(chooseAnimationFileSlotFunction())"1""chooseAnimationFileSlotFunction()");
159 // initialize action
160 mpAnimationInitializeAction = new QAction(QIcon(":/Resources/icons/initialize.svg"), Helper::animationInitialize, this);
161 mpAnimationInitializeAction->setStatusTip(Helper::animationInitializeTip);
162 mpAnimationInitializeAction->setEnabled(false);
163 connect(mpAnimationInitializeAction, SIGNAL(triggered())"2""triggered()",this, SLOT(initSlotFunction())"1""initSlotFunction()");
164 // animation play action
165 mpAnimationPlayAction = new QAction(QIcon(":/Resources/icons/play_animation.svg"), Helper::animationPlay, this);
166 mpAnimationPlayAction->setStatusTip(Helper::animationPlayTip);
167 mpAnimationPlayAction->setEnabled(false);
168 connect(mpAnimationPlayAction, SIGNAL(triggered())"2""triggered()",this, SLOT(playSlotFunction())"1""playSlotFunction()");
169 // animation pause action
170 mpAnimationPauseAction = new QAction(QIcon(":/Resources/icons/pause.svg"), Helper::animationPause, this);
171 mpAnimationPauseAction->setStatusTip(Helper::animationPauseTip);
172 mpAnimationPauseAction->setEnabled(false);
173 connect(mpAnimationPauseAction, SIGNAL(triggered())"2""triggered()",this, SLOT(pauseSlotFunction())"1""pauseSlotFunction()");
174 // animation repeat action
175 mpAnimationRepeatAction = new QAction(QIcon(":/Resources/icons/refresh.svg"), Helper::animationRepeat, this);
176 mpAnimationRepeatAction->setStatusTip(Helper::animationRepeatTip);
177 mpAnimationRepeatAction->setEnabled(false);
178 mpAnimationRepeatAction->setCheckable(true);
179 connect(mpAnimationRepeatAction, SIGNAL(triggered(bool))"2""triggered(bool)",this, SLOT(repeatSlotFunciton(bool))"1""repeatSlotFunciton(bool)");
180 // animation slide
181 mpAnimationSlider = new QSlider(Qt::Horizontal);
182 mpAnimationSlider->setMinimum(0);
183 mpAnimationSlider->setMaximum(mSliderRange);
184 mpAnimationSlider->setSliderPosition(0);
185 mpAnimationSlider->setEnabled(false);
186 connect(mpAnimationSlider, SIGNAL(valueChanged(int))"2""valueChanged(int)",this, SLOT(sliderSetTimeSlotFunction(int))"1""sliderSetTimeSlotFunction(int)");
187 // animation time
188 QDoubleValidator *pDoubleValidator = new QDoubleValidator(this);
189 pDoubleValidator->setBottom(0);
190 mpAnimationTimeLabel = new Label;
191 mpAnimationTimeLabel->setText(tr("Time [s]:"));
192 mpTimeTextBox = new QLineEdit("0.0");
193 mpTimeTextBox->setMaximumSize(QSize(toolbarIconSize*2, toolbarIconSize));
194 mpTimeTextBox->setEnabled(false);
195 mpTimeTextBox->setValidator(pDoubleValidator);
196 connect(mpTimeTextBox, SIGNAL(returnPressed())"2""returnPressed()",this, SLOT(jumpToTimeSlotFunction())"1""jumpToTimeSlotFunction()");
197 // animation speed
198 mpAnimationSpeedLabel = new Label;
199 mpAnimationSpeedLabel->setText(tr("Speed:"));
200 mpSpeedComboBox = new QComboBox;
201 mpSpeedComboBox->setEditable(true);
202 mpSpeedComboBox->addItems(Helper::speedOptions.split(","));
203 mpSpeedComboBox->setCurrentIndex(3);
204 mpSpeedComboBox->setMaximumSize(QSize(toolbarIconSize*2, toolbarIconSize));
205 mpSpeedComboBox->setEnabled(false);
206 mpSpeedComboBox->setValidator(pDoubleValidator);
207 mpSpeedComboBox->setCompleter(0);
208 connect(mpSpeedComboBox, SIGNAL(currentIndexChanged(int))"2""currentIndexChanged(int)",this, SLOT(setSpeedSlotFunction())"1""setSpeedSlotFunction()");
209 connect(mpSpeedComboBox->lineEdit(), SIGNAL(textChanged(QString))"2""textChanged(QString)",this, SLOT(setSpeedSlotFunction())"1""setSpeedSlotFunction()");
210 // perspective drop down
211 mpPerspectiveDropDownBox = new QComboBox;
212 mpPerspectiveDropDownBox->addItem(QIcon(":/Resources/icons/perspective0.svg"), QString("Isometric"));
213 mpPerspectiveDropDownBox->addItem(QIcon(":/Resources/icons/perspective1.svg"),QString("Side"));
214 mpPerspectiveDropDownBox->addItem(QIcon(":/Resources/icons/perspective2.svg"),QString("Front"));
215 mpPerspectiveDropDownBox->addItem(QIcon(":/Resources/icons/perspective3.svg"),QString("Top"));
216 connect(mpPerspectiveDropDownBox, SIGNAL(activated(int))"2""activated(int)", this, SLOT(setPerspective(int))"1""setPerspective(int)");
217 // rotate camera left action
218 mpRotateCameraLeftAction = new QAction(QIcon(":/Resources/icons/rotateCameraLeft.svg"), tr("Rotate Left"), this);
219 mpRotateCameraLeftAction->setStatusTip(tr("Rotates the camera left"));
220 connect(mpRotateCameraLeftAction, SIGNAL(triggered())"2""triggered()", this, SLOT(rotateCameraLeft())"1""rotateCameraLeft()");
221 // rotate camera right action
222 mpRotateCameraRightAction = new QAction(QIcon(":/Resources/icons/rotateCameraRight.svg"), tr("Rotate Right"), this);
223 mpRotateCameraRightAction->setStatusTip(tr("Rotates the camera right"));
224 connect(mpRotateCameraRightAction, SIGNAL(triggered())"2""triggered()", this, SLOT(rotateCameraRight())"1""rotateCameraRight()");
225 //interactive control action
226 mpInteractiveControlAction = mpAnimationParameterDockerWidget->toggleViewAction();
227 mpInteractiveControlAction->setIcon(QIcon(":/Resources/icons/control-panel.svg"));
228 mpInteractiveControlAction->setText(tr("interactive control"));
229 mpInteractiveControlAction->setStatusTip(tr("Opens the interactive control panel"));
230 mpInteractiveControlAction->setEnabled(false);
231 mpAnimationParameterDockerWidget->hide();
232}
233
234/*!
235 * \brief AbstractAnimationWindow::updateControlPanelValues
236 */
237void AbstractAnimationWindow::updateControlPanelValues()
238{
239 if (getVisualizer()) {
240 VisualizerFMU* FMUvis = dynamic_cast<VisualizerFMU*>(mpVisualizer);
241 for (int stateIdx = 0; stateIdx < mSpinBoxVector.size(); stateIdx++) {
242 mStateLabels.at(stateIdx)->setText(QString::number(FMUvis->getFMU()->getFMUData()->_states[stateIdx]));
243 }
244 }
245}
246
247/*!
248 * \brief AbstractAnimationWindow::initInteractiveControlPanel
249 */
250void AbstractAnimationWindow::initInteractiveControlPanel()
251{
252 if (getVisualizer()) {
10
Taking true branch
253 VisualizerFMU* FMUvis = dynamic_cast<VisualizerFMU*>(mpVisualizer);
254 QWidget *widget = new QWidget(this);
11
Memory is allocated
255 mSpinBoxVector.clear();
256 mStateLabels.clear();
257
258 if (FMUvis->getFMU()->getFMUData()->_stateNames.size()==FMUvis->getFMU()->getFMUData()->_nStates){
12
Taking false branch
259 //widgets for the states
260 QVBoxLayout *layout = new QVBoxLayout();
261 layout->setSpacing(2);
262
263 layout->addWidget(new QLabel(QString("<b>modify state variables</b>"),this));
264 for (unsigned int stateIdx = 0; stateIdx < FMUvis->getFMU()->getFMUData()->_nStates; stateIdx++)
265 {
266 DoubleSpinBoxIndexed* spinBox = new DoubleSpinBoxIndexed(this, stateIdx);
267 spinBox->setValue(FMUvis->getFMU()->getFMUData()->_states[stateIdx]);
268 spinBox->setMaximum(DBL_MAX1.7976931348623157e+308);
269 spinBox->setMinimum(-DBL_MAX1.7976931348623157e+308);
270 spinBox->setSingleStep(0.1);
271 mSpinBoxVector.push_back(spinBox);
272
273 QLabel* stateLabel = new QLabel(QString::number(FMUvis->getFMU()->getFMUData()->_states[stateIdx]), this);
274 stateLabel->setMargin(0);
275 mStateLabels.push_back(stateLabel);
276
277 QWidget* stateValWidget = new QWidget();
278 QHBoxLayout *stateInfoLayout = new QHBoxLayout();
279 stateInfoLayout->setMargin(0);
280 stateInfoLayout->addWidget(stateLabel);
281 stateInfoLayout->addWidget(spinBox);
282 stateValWidget->setLayout(stateInfoLayout);
283
284 layout->addSpacing(12);
285 layout->addWidget(new QLabel(QString::fromStdString(FMUvis->getFMU()->getFMUData()->_stateNames.at(stateIdx)),this));
286 layout->addWidget(stateValWidget);
287 connect(mSpinBoxVector.at(stateIdx), SIGNAL(valueChangedFrom(double, int))"2""valueChangedFrom(double, int)", this, SLOT(setStateSolveSystem(double, int))"1""setStateSolveSystem(double, int)");
288 }
289
290 //widgets for the inputs
291 //layout->addWidget(new QLabel(QString("<b>modify inputs</b>"),this));
292 /*
293 for (int inputIdx = 0; inputIdx < 0; inputIdx++) {
294 std::string name = "some input";
295 layout->addWidget(new QLabel(QString::fromStdString("inputName"),this));
296 QWidget* valWidget = new QWidget();
297 QHBoxLayout *valueLayout = new QHBoxLayout();
298 valueLayout->addWidget(new QLabel(QString::fromStdString("min"),this));
299 valueLayout->addWidget(new QLabel(QString::fromStdString("value"),this));
300 valueLayout->addWidget(new QLabel(QString::fromStdString("max"),this));
301 valWidget->setLayout(valueLayout);
302 layout->addWidget(valWidget);
303 layout->addWidget(new QSlider(Qt::Horizontal, this));
304 }
305 QPushButton* updateButton = new QPushButton(QIcon(":/Resources/icons/update.svg"), "&update system",this);
306 layout->addWidget(updateButton);
307 connect(updateButton, SIGNAL(released()), this, SLOT(setStatesSolveSystem()));
308 */
309
310 layout->setSizeConstraint(QLayout::SetMinimumSize);
311 widget->setLayout(layout);
312 QScrollArea *scrollArea = new QScrollArea(this);
313 scrollArea->setWidget(widget);
314 mpAnimationParameterDockerWidget->setWidget(scrollArea);
315 } else {
316 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica, tr("Information about states could not be determined."),
13
Potential leak of memory pointed to by 'widget'
317 Helper::scriptingKind, Helper::errorLevel));
318 mpAnimationParameterDockerWidget->hide();
319
320 }
321 } else {
322 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica, tr("Interactive Control needs an FMU ME 2.0"),
323 Helper::scriptingKind, Helper::errorLevel));
324 mpAnimationParameterDockerWidget->hide();
325 }
326}
327
328/*!
329 * \brief AbstractAnimationWindow::setStateSolveSystem
330 * \param val The new value
331 * \param idx The state that belongs to the value
332 */
333void AbstractAnimationWindow::setStateSolveSystem(double val, int idx)
334{
335 if (idx>=0) {
336 VisualizerFMU* FMUvis = dynamic_cast<VisualizerFMU*>(mpVisualizer);
337 if (FMUvis) {
338 FMUvis->getFMU()->getFMUData()->_states[idx] = val;
339 }
340 FMUvis->updateSystem();
341 mpViewerWidget->update();
342 }
343}
344
345
346/*!
347 * \brief AbstractAnimationWindow::clearView
348 */
349void AbstractAnimationWindow::clearView()
350{
351 if (mpViewerWidget) {
352 mpViewerWidget->getSceneView()->setSceneData(0);
353 popView();
354 mpViewerWidget->update();
355 }
356}
357
358void AbstractAnimationWindow::stashView()
359{
360 if(!mCameraInitialized) return;
361 mStashedViewMatrix = mpViewerWidget->getSceneView()->getCameraManipulator()->getMatrix();
362}
363
364void AbstractAnimationWindow::popView()
365{
366 if(!mCameraInitialized) return;
367 mpViewerWidget->getSceneView()->getCameraManipulator()->setByMatrix(mStashedViewMatrix);
368 mpViewerWidget->update();
369}
370
371/*!
372 * \brief AbstractAnimationWindow::loadVisualization
373 * loads the data and the xml scene description
374 * \return
375 */
376bool AbstractAnimationWindow::loadVisualization()
377{
378 VisType visType = VisType::NONE;
379 // Get visualization type.
380 if (isFMU(mFileName)) {
381 visType = VisType::FMU;
382 } else if (isMAT(mFileName)) {
383 visType = VisType::MAT;
384 } else if (isCSV(mFileName)) {
385 visType = VisType::CSV;
386 } else {
387 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica, tr("Unknown visualization type."),
388 Helper::scriptingKind, Helper::errorLevel));
389 return false;
390 }
391 //load the XML File, build osgTree, get initial values for the shapes
392 bool xmlExists = checkForXMLFile(mFileName, mPathName);
393 if (!xmlExists) {
394 QString msg = tr("Could not find the visual XML file %1.").arg(QString(assembleXMLFileName(mFileName, mPathName).c_str()));
395 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica, msg, Helper::scriptingKind,
396 Helper::errorLevel));
397 return false;
398 } else {
399 //init visualizer
400 if (visType == VisType::MAT) {
401 mpVisualizer = new VisualizerMAT(mFileName, mPathName);
402 } else if (visType == VisType::CSV) {
403 mpVisualizer = new VisualizerCSV(mFileName, mPathName);
404 } else if (visType == VisType::FMU) {
405 mpVisualizer = new VisualizerFMU(mFileName, mPathName);
406 } else {
407 QString msg = tr("Could not init %1 %2.").arg(QString(mPathName.c_str())).arg(QString(mFileName.c_str()));
408 MessagesWidget::instance()->addGUIMessage(MessageItem(MessageItem::Modelica, msg, Helper::scriptingKind,
409 Helper::errorLevel));
410 return false;
411 }
412 connect(mpVisualizer->getTimeManager()->getUpdateSceneTimer(), SIGNAL(timeout())"2""timeout()", SLOT(updateScene())"1""updateScene()");
413 mpVisualizer->initData();
414 mpVisualizer->setUpScene();
415 mpVisualizer->initVisualization();
416 //add scene for the chosen visualization
417 mpViewerWidget->getSceneView()->setSceneData(mpVisualizer->getOMVisScene()->getScene().getRootNode());
418 }
419 //add window title
420 setWindowTitle(QString::fromStdString(mFileName));
421 //open settings dialog for FMU simulation
422 if (visType == VisType::FMU) {
423 openFMUSettingsDialog(dynamic_cast<VisualizerFMU*>(mpVisualizer));
424 mpInteractiveControlAction->setEnabled(true);
425 initInteractiveControlPanel();
426 }
427 else {
428 mpInteractiveControlAction->setEnabled(false);
429 mpAnimationParameterDockerWidget->hide();
430 }
431
432 return true;
433}
434
435/*!
436 * \brief AbstractAnimationWindow::resetCamera
437 * resets the camera position
438 */
439void AbstractAnimationWindow::resetCamera()
440{
441 mpViewerWidget->getSceneView()->home();
442 mpViewerWidget->update();
443}
444
445/*!
446 * \brief AbstractAnimationWindow::cameraPositionIsometric
447 * sets the camera position to isometric view
448 */
449void AbstractAnimationWindow::cameraPositionIsometric()
450{
451 double d = computeDistanceToOrigin();
452 osg::Matrixd mat = osg::Matrixd(0.7071, 0, -0.7071, 0,
453 -0.409, 0.816, -0.409, 0,
454 0.57735, 0.57735, 0.57735, 0,
455 0.57735*d, 0.57735*d, 0.57735*d, 1);
456 mpViewerWidget->getSceneView()->getCameraManipulator()->setByMatrix(mat);
457 mpViewerWidget->update();
458}
459
460/*!
461 * \brief AbstractAnimationWindow::cameraPositionSide
462 * sets the camera position to Side
463 */
464void AbstractAnimationWindow::cameraPositionSide()
465{
466 double d = computeDistanceToOrigin();
467 osg::Matrixd mat = osg::Matrixd(1, 0, 0, 0,
468 0, 1, 0, 0,
469 0, 0, 1, 0,
470 0, 0, d, 1);
471 mpViewerWidget->getSceneView()->getCameraManipulator()->setByMatrix(mat);
472 mpViewerWidget->update();
473}
474
475/*!
476 * \brief AbstractAnimationWindow::cameraPositionFront
477 * sets the camera position to Front
478 */
479void AbstractAnimationWindow::cameraPositionFront()
480{
481 double d = computeDistanceToOrigin();
482 osg::Matrixd mat = osg::Matrixd(0, 0, 1, 0,
483 1, 0, 0, 0,
484 0, 1, 0, 0,
485 0, d, 0, 1);
486 mpViewerWidget->getSceneView()->getCameraManipulator()->setByMatrix(mat);
487 mpViewerWidget->update();
488}
489
490/*!
491 * \brief AbstractAnimationWindow::cameraPositionTop
492 * sets the camera position to Top
493 */
494void AbstractAnimationWindow::cameraPositionTop()
495{
496 double d = computeDistanceToOrigin();
497 osg::Matrixd mat = osg::Matrixd( 0, 0,-1, 0,
498 0, 1, 0, 0,
499 1, 0, 0, 0,
500 d, 0, 0, 1);
501 mpViewerWidget->getSceneView()->getCameraManipulator()->setByMatrix(mat);
502 mpViewerWidget->update();
503}
504
505/*!
506 * \brief AbstractAnimationWindow::computeDistanceToOrigin
507 * computes distance to origin using pythagoras theorem
508 */
509double AbstractAnimationWindow::computeDistanceToOrigin()
510{
511 osg::ref_ptr<osgGA::CameraManipulator> manipulator = mpViewerWidget->getSceneView()->getCameraManipulator();
512 osg::Matrixd mat = manipulator->getMatrix();
513 //assemble
514
515 //Compute distance to center using pythagoras theorem
516 double d = sqrt(abs(mat(3,0))*abs(mat(3,0))+
517 abs(mat(3,1))*abs(mat(3,1))+
518 abs(mat(3,2))*abs(mat(3,2)));
519
520 //If d is very small (~0), set it to 1 as default
521 if(d < 1e-10) {
522 d=1;
523 }
524
525 return d;
526}
527
528/*!
529 * \brief AbstractAnimationWindow::openFMUSettingsDialog
530 * Opens a dialog to set the settings for the FMU visualization
531 * \param pVisualizerFMU
532 */
533void AbstractAnimationWindow::openFMUSettingsDialog(VisualizerFMU* pVisualizerFMU)
534{
535 FMUSettingsDialog *pFMUSettingsDialog = new FMUSettingsDialog(this, pVisualizerFMU);
536 pFMUSettingsDialog->exec();
537}
538
539/*!
540 * \brief AbstractAnimationWindow::updateSceneFunction
541 * updates the visualization objects
542 */
543void AbstractAnimationWindow::updateScene()
544{
545 if (!(mpVisualizer == NULL__null)) {
546 //set time label
547 if (!mpVisualizer->getTimeManager()->isPaused()) {
548 mpTimeTextBox->setText(QString::number(mpVisualizer->getTimeManager()->getVisTime()));
549 // set time slider
550 if (mpVisualizer->getVisType() != VisType::FMU) {
551 int time = mpVisualizer->getTimeManager()->getTimeFraction();
552 bool state = mpAnimationSlider->blockSignals(true);
553 mpAnimationSlider->setValue(time);
554 mpAnimationSlider->blockSignals(state);
555 }
556 }
557
558 //update the scene
559 mpVisualizer->sceneUpdate();
560 mpViewerWidget->update();
561
562 updateControlPanelValues();
563 }
564}
565
566/*!
567 * \brief AbstractAnimationWindow::animationFileSlotFunction
568 * opens a file dialog to chooes an animation
569 */
570void AbstractAnimationWindow::chooseAnimationFileSlotFunction()
571{
572 QString fileName = StringHandler::getOpenFileName(this, QString("%1 - %2").arg(Helper::applicationName).arg(Helper::chooseFile),
573 NULL__null, Helper::visualizationFileTypes, NULL__null);
574 if (fileName.isEmpty()) {
1
Assuming the condition is false
2
Taking false branch
575 return;
576 }
577 openAnimationFile(fileName);
3
Calling 'AbstractAnimationWindow::openAnimationFile'
578}
579
580/*!
581 * \brief AbstractAnimationWindow::initSlotFunction
582 * slot function for the init button
583 */
584void AbstractAnimationWindow::initSlotFunction()
585{
586 mpVisualizer->initVisualization();
587 bool state = mpAnimationSlider->blockSignals(true);
588 mpAnimationSlider->setValue(0);
589 mpAnimationSlider->blockSignals(state);
590 mpTimeTextBox->setText(QString::number(mpVisualizer->getTimeManager()->getVisTime()));
591 mpViewerWidget->update();
592 updateControlPanelValues();
593}
594
595/*!
596 * \brief AbstractAnimationWindow::playSlotFunction
597 * slot function for the play button
598 */
599void AbstractAnimationWindow::playSlotFunction()
600{
601 mpVisualizer->getTimeManager()->setPause(false);
602}
603
604/*!
605 * \brief AbstractAnimationWindow::pauseSlotFunction
606 * slot function for the pause button
607 */
608void AbstractAnimationWindow::pauseSlotFunction()
609{
610 mpVisualizer->getTimeManager()->setPause(true);
611}
612
613/*!
614 * \brief AbstractAnimationWindow::repeatSlotFunciton
615 * Slot function for the repeat button
616 * \param checked
617 */
618void AbstractAnimationWindow::repeatSlotFunciton(bool checked)
619{
620 mpVisualizer->getTimeManager()->setRepeat(checked);
621}
622
623/*!
624 * \brief AbstractAnimationWindow::sliderSetTimeSlotFunction
625 * slot function for the time slider to jump to the adjusted point of time
626 */
627void AbstractAnimationWindow::sliderSetTimeSlotFunction(int value)
628{
629 float time = (mpVisualizer->getTimeManager()->getEndTime()
630 - mpVisualizer->getTimeManager()->getStartTime())
631 * (float) (value / (float)mSliderRange);
632 mpVisualizer->getTimeManager()->setVisTime(time);
633 mpTimeTextBox->setText(QString::number(mpVisualizer->getTimeManager()->getVisTime()));
634 mpVisualizer->updateScene(time);
635 mpViewerWidget->update();
636}
637
638/*!
639 * \brief AbstractAnimationWindow::jumpToTimeSlotFunction
640 * slot function to jump to the user input point of time
641 */
642void AbstractAnimationWindow::jumpToTimeSlotFunction()
643{
644 QString str = mpTimeTextBox->text();
645 bool isFloat = true;
646 double start = mpVisualizer->getTimeManager()->getStartTime();
647 double end = mpVisualizer->getTimeManager()->getEndTime();
648 double value = str.toFloat(&isFloat);
649 if (isFloat && value >= 0.0) {
650 if (value < start) {
651 value = start;
652 } else if (value > end) {
653 value = end;
654 }
655 mpVisualizer->getTimeManager()->setVisTime(value);
656 bool state = mpAnimationSlider->blockSignals(true);
657 mpAnimationSlider->setValue(mpVisualizer->getTimeManager()->getTimeFraction());
658 mpAnimationSlider->blockSignals(state);
659 mpVisualizer->updateScene(value);
660 mpViewerWidget->update();
661 }
662}
663
664/*!
665 * \brief AbstractAnimationWindow::setSpeedUpSlotFunction
666 * slot function to set the user input speed up
667 */
668void AbstractAnimationWindow::setSpeedSlotFunction()
669{
670 QString str = mpSpeedComboBox->lineEdit()->text();
671 bool isFloat = true;
672 double value = str.toFloat(&isFloat);
673 if (isFloat && value > 0.0) {
674 mpVisualizer->getTimeManager()->setSpeedUp(value);
675 mpViewerWidget->update();
676 }
677}
678
679/*!
680 * \brief AbstractAnimationWindow::setPerspective
681 * gets the identifier for the chosen perspective and calls the functions
682 */
683void AbstractAnimationWindow::setPerspective(int value)
684{
685 switch(value) {
686 case 0:
687 cameraPositionIsometric();
688 break;
689 case 1:
690 cameraPositionSide();
691 break;
692 case 2:
693 cameraPositionTop();
694 break;
695 case 3:
696 cameraPositionFront();
697 break;
698 }
699}
700
701/*!
702 * \brief AbstractAnimationWindow::rotateCameraLeft
703 * rotates the camera 90 degress left about the line of sight
704 */
705void AbstractAnimationWindow::rotateCameraLeft()
706{
707 osg::ref_ptr<osgGA::CameraManipulator> manipulator = mpViewerWidget->getSceneView()->getCameraManipulator();
708 osg::Matrixd mat = manipulator->getMatrix();
709 osg::Camera *pCamera = mpViewerWidget->getSceneView()->getCamera();
710
711 osg::Vec3d eye, center, up;
712 pCamera->getViewMatrixAsLookAt(eye, center, up);
713 osg::Vec3d rotationAxis = center-eye;
714
715 osg::Matrixd rotMatrix;
716 rotMatrix.makeRotate(3.1415/2.0, rotationAxis);
717
718 mpViewerWidget->getSceneView()->getCameraManipulator()->setByMatrix(mat*rotMatrix);
719 mpViewerWidget->update();
720}
721
722/*!
723 * \brief AbstractAnimationWindow::rotateCameraRight
724 * rotates the camera 90 degress right about the line of sight
725 */
726void AbstractAnimationWindow::rotateCameraRight()
727{
728 osg::ref_ptr<osgGA::CameraManipulator> manipulator = mpViewerWidget->getSceneView()->getCameraManipulator();
729 osg::Matrixd mat = manipulator->getMatrix();
730 osg::Camera *pCamera = mpViewerWidget->getSceneView()->getCamera();
731
732 osg::Vec3d eye, center, up;
733 pCamera->getViewMatrixAsLookAt(eye, center, up);
734 osg::Vec3d rotationAxis = center-eye;
735
736 osg::Matrixd rotMatrix;
737 rotMatrix.makeRotate(-3.1415/2.0, rotationAxis);
738
739 mpViewerWidget->getSceneView()->getCameraManipulator()->setByMatrix(mat*rotMatrix);
740 mpViewerWidget->update();
741}
742
743/*!
744 * \brief DoubleSpinBoxIndexed::DoubleSpinBoxIndexed
745 */
746DoubleSpinBoxIndexed::DoubleSpinBoxIndexed(QWidget *pParent, int idx)
747 : QDoubleSpinBox(pParent)
748{
749 mStateIdx = idx;
750 connect( this, SIGNAL(valueChanged(double))"2""valueChanged(double)",
751 this, SLOT(slotForwardValueChanged(double))"1""slotForwardValueChanged(double)");
752}
753
754/*!
755 * \brief DoubleSpinBoxIndexed::slotForwardValueChanged
756 * \param val
757 */
758void DoubleSpinBoxIndexed::slotForwardValueChanged(double val)
759{
760 emit valueChangedFrom(val, mStateIdx);
761}
762