diff --git a/.gitsubprojects b/.gitsubprojects index ded8fe025055c2258258d8cdb569f9cbf5b16d1d..f5aed650a93582beec489f33106061a7765b05ba 100644 --- a/.gitsubprojects +++ b/.gitsubprojects @@ -5,5 +5,5 @@ #git_subproject( Brion https://github.com/BlueBrain/Brion.git 073f356 ) git_subproject( ReTo https://github.com/gmrvvis/ReTo.git 14e08c0 ) git_subproject( prefr https://github.com/gmrvvis/prefr.git 05fbf11 ) -git_subproject( SimIL https://github.com/gmrvvis/SimIL.git 5b557b2 ) +git_subproject( SimIL https://github.com/gmrvvis/SimIL.git 7a1eab6 ) git_subproject( scoop https://github.com/gmrvvis/scoop.git b3326cd ) diff --git a/CMakeLists.txt b/CMakeLists.txt index ef8d4907b8b6e4c707eab5e0a5a106bc7fe6e57b..993fe5264d5e7b09528188eef249fd8eb8988dbe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ cmake_minimum_required( VERSION 3.1 FATAL_ERROR ) # visimpl project and version -project( visimpl VERSION 1.2.0 ) +project( visimpl VERSION 1.2.1 ) set( visimpl_VERSION_ABI 6 ) SET( VISIMPL_LICENSE "GPL") diff --git a/stackviz/MainWindow.cpp b/stackviz/MainWindow.cpp index be6a09ad3c70d4bf2bd582620bc798aeb424f262..72904258f795367c2f17030789d324887e43fb58 100644 --- a/stackviz/MainWindow.cpp +++ b/stackviz/MainWindow.cpp @@ -59,6 +59,8 @@ using namespace stackviz; +constexpr int SLIDER_MAX = 1000; + MainWindow::MainWindow( QWidget* parent_ ) : QMainWindow( parent_ ) , _ui( new Ui::MainWindow ) @@ -86,6 +88,7 @@ MainWindow::MainWindow( QWidget* parent_ ) #endif , m_loader{nullptr} , m_loaderDialog{nullptr} +, m_dataInspector{nullptr} { _ui->setupUi( this ); @@ -101,6 +104,11 @@ MainWindow::MainWindow( QWidget* parent_ ) // Connect about dialog connect( _ui->actionAbout, SIGNAL( triggered( void )), this, SLOT( aboutDialog( void ))); + + // only used for data refresh in case of REST API. Similar one included + // in Summary class, refactor? + m_dataInspector = new DataInspector(""); + m_dataInspector->hide(); } void MainWindow::init( const std::string& @@ -185,7 +193,6 @@ MainWindow::~MainWindow( void ) #endif } - void MainWindow::showStatusBarMessage ( const QString& message ) { _ui->statusbar->showMessage( message ); @@ -334,10 +341,12 @@ void MainWindow::openSubsetEventsFileThroughDialog( void ) void MainWindow::configurePlayer( void ) { _startTimeLabel->setText( - QString::number( static_cast<double>(_player->startTime( )))); + QString::number(_player->startTime(), 'f', 3)); _endTimeLabel->setText( - QString::number( static_cast<double>(_player->endTime( )))); + QString::number(_player->endTime(), 'f', 3)); + + m_dataInspector->setSimPlayer(_player); #ifdef SIMIL_USE_ZEROEQ try @@ -421,7 +430,7 @@ void MainWindow::initPlaybackDock( ) _simSlider = new CustomSlider( Qt::Horizontal ); _simSlider->setMinimum( 0 ); - _simSlider->setMaximum( 1000 ); + _simSlider->setMaximum( SLIDER_MAX ); _simSlider->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ); @@ -475,7 +484,7 @@ void MainWindow::initPlaybackDock( ) this, SLOT( Repeat( ))); connect( _simSlider, SIGNAL( sliderPressed( )), - this, SLOT( PlayAt( ))); + this, SLOT( PlayAtPosition( ))); connect( _goToButton, SIGNAL( clicked( )), this, SLOT( playAtButtonClicked( ))); @@ -507,7 +516,13 @@ void MainWindow::initSummaryWidget( ) _summary, SLOT( fillPlots( bool ))); connect( _summary, SIGNAL( histogramClicked( float )), - this, SLOT( PlayAt( float ))); + this, SLOT( PlayAtPercentage( float ))); + + connect( m_dataInspector, SIGNAL( simDataChanged()), + _summary, SLOT( UpdateHistograms())); + + connect( m_dataInspector, SIGNAL( simDataChanged()), + this, SLOT( onDataUpdated())); #ifdef VISIMPL_USE_ZEROEQ connect( _summary, SIGNAL( histogramClicked( visimpl::HistogramWidget* )), @@ -559,6 +574,8 @@ void MainWindow::Pause( bool notify ) _playButton->setIcon( _playIcon ); _playing = false; + _startTimeLabel->setText(QString::number(_player->currentTime(), 'f', 3)); + if( notify ) { #ifdef VISIMPL_USE_GMRVLEX @@ -575,7 +592,7 @@ void MainWindow::Stop( bool notify ) _player->Stop( ); _playButton->setIcon( _playIcon ); _startTimeLabel->setText( - QString::number( (double)_player ->startTime( ))); + QString::number( _player ->startTime(), 'f', 3)); _playing = false; if( notify ) { @@ -603,38 +620,53 @@ void MainWindow::Repeat( bool notify ) } } -void MainWindow::PlayAt(bool notify) +void MainWindow::PlayAtPosition(bool notify) { if (_player) { - PlayAt(_simSlider->sliderPosition(), notify); + PlayAtPosition(_simSlider->sliderPosition(), notify); } } -void MainWindow::PlayAt(float percentage, bool notify) +void MainWindow::PlayAtPercentage(float percentage, bool notify) { if (_player) { - const int sliderPos = percentage * (_simSlider->maximum() - _simSlider->minimum()) + _simSlider->minimum(); + const auto tBegin = _player->startTime(); + const auto tEnd = _player->endTime(); + const auto timePos = (percentage * (tEnd-tBegin)) + tBegin; - PlayAt(sliderPos, notify); + PlayAtTime(timePos, notify); } } -void MainWindow::PlayAt( int sliderPosition, bool notify ) +void MainWindow::PlayAtPosition( int sliderPosition, bool notify ) { if( _player ) { - const int value = _simSlider->value( ); - const float percentage = static_cast<float>( value - _simSlider->minimum( )) / - ( _simSlider->maximum( ) - _simSlider->minimum( )); - _simSlider->setSliderPosition( sliderPosition ); + PlayAtPercentage( static_cast<float>(sliderPosition) / SLIDER_MAX , notify); + } +} + +void MainWindow::PlayAtTime(float timePos, bool notify) +{ + if(_player) + { + const auto tBegin = _player->startTime(); + const auto tEnd = _player->endTime(); + const auto newTimePos = std::max(tBegin, std::min(tEnd, timePos)); + const auto percentage = (newTimePos - tBegin) / (tEnd - tBegin); + + _simSlider->setSliderPosition( percentage * SLIDER_MAX ); _playButton->setIcon( _pauseIcon ); - _player->PlayAt( percentage ); _playing = true; + _player->PlayAtTime(newTimePos); + + _startTimeLabel->setText(QString::number(_player->currentTime(), 'f', 3)); + if( notify ) { #ifdef VISIMPL_USE_ZEROEQ @@ -643,9 +675,9 @@ void MainWindow::PlayAt( int sliderPosition, bool notify ) // Send event if(_player->zeqEvents()) { - _player ->zeqEvents( )->sendFrame( _simSlider->minimum( ), - _simSlider->maximum( ), - sliderPosition ); + _player ->zeqEvents( )->sendFrame( _player->startTime(), + _player->endTime(), + _player->currentTime() ); } } catch(const std::exception &e) @@ -705,17 +737,18 @@ void MainWindow::GoToEnd( bool notify ) } } -void MainWindow::UpdateSimulationSlider(float percentage) +void MainWindow::UpdateSimulationSlider(float position) { - const double currentTime = percentage * (_player->endTime() - _player->startTime()) + _player->startTime(); - - _startTimeLabel->setText(QString::number(currentTime)); + // NOTE: this method receives the position in time, not percentage. + const auto tBegin = _player->startTime(); + const auto tEnd = _player->endTime(); + const auto newPosition = std::min(tEnd, std::max(tBegin, position)); + const auto isOverflow = newPosition != position; - const int total = _simSlider->maximum() - _simSlider->minimum(); + PlayAtTime( newPosition, isOverflow ); - const int position = percentage * total; - - _simSlider->setSliderPosition(position); + if(isOverflow) + Pause(true); if (_summary) _summary->repaintHistograms(); @@ -730,7 +763,7 @@ void MainWindow::UpdateSimulationSlider(float percentage) void MainWindow::ApplyPlaybackOperation(unsigned int playbackOp) { - auto operation = static_cast<zeroeq::gmrv::PlaybackOperation>(playbackOp); + const auto operation = static_cast<zeroeq::gmrv::PlaybackOperation>(playbackOp); switch (operation) { @@ -809,7 +842,7 @@ void MainWindow::_setZeqUri(const std::string &uri_) { _onSelectionEvent( lexis::data::SelectedIDs::create( data_, size_ ));}); _thread = new std::thread([&]() - { while( _zeqConnection ) _subscriber->receive( 10000 );}); + { while( _zeqConnection ) try { _subscriber->receive( 10000 ); } catch(...) { return; }}); } catch(const std::exception &e) { @@ -854,17 +887,17 @@ void MainWindow::playAtButtonClicked(void) bool ok; const double result = QInputDialog::getDouble(this, tr("Set simulation time to play:"), tr("Simulation time"), static_cast<double>(_player->currentTime()), - static_cast<double>(_player->data()->startTime()), - static_cast<double>(_player->data()->endTime()), 3, &ok, Qt::Popup); + static_cast<double>(_player->startTime()), + static_cast<double>(_player->endTime()), 3, &ok, Qt::Popup); if (ok) { - float percentage = (result - _player->data()->startTime()) / - (_player->data()->endTime() - _player->data()->startTime()); + float percentage = (result - _player->startTime()) / + (_player->endTime() - _player->startTime()); percentage = std::max(0.0f, std::min(1.0f, percentage)); - PlayAt(percentage, true); + PlayAtPercentage(percentage); } } @@ -1078,7 +1111,14 @@ void stackviz::MainWindow::onLoadFinished() _player = new simil::SpikesPlayer(); _player->LoadData(netData, simData); - // NOTE: loader doesn't get destroyed because has a loop for getting data. + // NOTE: loader doesn't get destroyed. +#ifdef SIMIL_WITH_REST_API + auto timer = new QTimer( this ); + connect( timer, SIGNAL( timeout()), + m_dataInspector, SLOT( updateInfo()) ); + + timer->start( 4000 ); +#endif } break; case simil::TDataUndefined: @@ -1133,6 +1173,23 @@ void stackviz::MainWindow::sendZeroEQPlaybackOperation(const unsigned int op) #endif } +void stackviz::MainWindow::onDataUpdated() +{ + const float tBegin = _player->startTime(); + const float tEnd = _player->endTime(); + const float tCurrent = _player->currentTime(); + + if(tEnd > tBegin) + { + _startTimeLabel->setText(QString::number(tCurrent, 'f', 3)); + _endTimeLabel->setText(QString::number(tEnd, 'f', 3)); + + const float percentage = static_cast<float>(tCurrent - tBegin) / (tEnd - tBegin); + _simSlider->setValue( percentage * SLIDER_MAX ); + } + +} + void stackviz::MainWindow::closeLoadingDialog() { if(m_loaderDialog) diff --git a/stackviz/MainWindow.h b/stackviz/MainWindow.h index 83063f363438a2d6fd0d9a828d54e59eaec89a6f..017c82b11ede1ed6277751948d21a099dd37d369 100644 --- a/stackviz/MainWindow.h +++ b/stackviz/MainWindow.h @@ -46,7 +46,6 @@ #endif #include "ui_stackviz.h" - #include "DisplayManagerWidget.h" namespace Ui @@ -56,7 +55,6 @@ namespace Ui namespace stackviz { - class MainWindow : public QMainWindow { @@ -94,9 +92,10 @@ namespace stackviz void Pause( bool notify = true ); void Stop( bool notify = true ); void Repeat( bool notify = true); - void PlayAt( bool notify = true ); - void PlayAt( int, bool notify = true ); - void PlayAt( float, bool notify = true ); + void PlayAtPosition( bool notify = true ); + void PlayAtPosition( int, bool notify = true ); + void PlayAtPercentage( float, bool notify = true ); + void PlayAtTime( float, bool notify = true); void Restart( bool notify = true ); void GoToEnd( bool notify = true ); @@ -122,6 +121,8 @@ namespace stackviz void onLoadFinished(); + void onDataUpdated(); + protected: void configurePlayer( void ); @@ -201,6 +202,7 @@ namespace stackviz std::string m_subsetEventFile; std::shared_ptr<LoaderThread> m_loader; LoadingDialog *m_loaderDialog; + DataInspector * m_dataInspector; }; diff --git a/sumrice/CMakeLists.txt b/sumrice/CMakeLists.txt index d26788146b2a2fca46f6add3100d9472a7128a22..c9f85d6464d296aa75b565289e11635356fbb900 100644 --- a/sumrice/CMakeLists.txt +++ b/sumrice/CMakeLists.txt @@ -21,6 +21,7 @@ set(SUMRICE_PUBLIC_HEADERS CorrelationComputer.h LoaderThread.h LoadingDialog.h + DataInspector.h ) set(SUMRICE_HEADERS @@ -38,6 +39,7 @@ set(SUMRICE_SOURCES CorrelationComputer.cpp LoaderThread.cpp LoadingDialog.cpp + DataInspector.cpp ) set(SUMRICE_LINK_LIBRARIES diff --git a/visimpl/ui/DataInspector.cpp b/sumrice/DataInspector.cpp similarity index 95% rename from visimpl/ui/DataInspector.cpp rename to sumrice/DataInspector.cpp index f6660dbf44447cd2c8991bea5140f447eee73605..d7f7cce9eae4b26724b344051eef226fae9155ce 100644 --- a/visimpl/ui/DataInspector.cpp +++ b/sumrice/DataInspector.cpp @@ -78,7 +78,7 @@ void DataInspector::paintEvent( QPaintEvent* event ) void DataInspector::updateInfo( ) { - if ( _simPlayer != nullptr ) + if ( _simPlayer ) { bool updated = false; if ( _simPlayer->gidsSize( ) != _gidsize ) @@ -88,10 +88,8 @@ void DataInspector::updateInfo( ) _labelGIDs->setText( QString::number( _gidsize ) ); } - simil::SpikesPlayer* spkPlay = - dynamic_cast< simil::SpikesPlayer* >( _simPlayer ); - - if ( spkPlay != nullptr ) + auto spkPlay = dynamic_cast< simil::SpikesPlayer* >( _simPlayer ); + if ( spkPlay ) { if ( spkPlay->spikesSize( ) != _spikesize ) { @@ -104,6 +102,8 @@ void DataInspector::updateInfo( ) } if ( updated ) + { emit simDataChanged( ); + } } } diff --git a/visimpl/ui/DataInspector.h b/sumrice/DataInspector.h similarity index 100% rename from visimpl/ui/DataInspector.h rename to sumrice/DataInspector.h diff --git a/sumrice/Histogram.cpp b/sumrice/Histogram.cpp index 73e424f6ebb169dc4e9f4e603ded126f28141156..290ddb0d908803db1be4999981be69a85edddc89 100644 --- a/sumrice/Histogram.cpp +++ b/sumrice/Histogram.cpp @@ -187,7 +187,8 @@ namespace visimpl if( histogramNumber == T_HIST_FOCUS ) histogram = &_focusHistogram; - std::vector< unsigned int > globalHistogram( histogram->size( ), 0 ); + const unsigned int histogramSize = histogram->size(); + std::vector< unsigned int > globalHistogram( histogramSize, 0 ); float totalTime = _endTime - _startTime ; @@ -232,32 +233,33 @@ namespace visimpl references[ i + 1]->first : _endTime; - int bin; while( spikeIt->first < endTime && spikeIt != _spikes->end( )) { - float perc = + const float percentage = std::max( 0.0f, std::min( 1.0f, ( spikeIt->first - _startTime )* invTotalTime )); - bin = perc * histogram->size( ); + + const unsigned int bin = percentage * (histogramSize - 1); if( !filter || _filteredGIDs.find( spikeIt->second ) != _filteredGIDs.end( )) { ( *histogram )[ bin ]++; } + ( globalHistogram )[ bin ]++; ++spikeIt; } } #endif // VISIMPL_USE_OPENMP - unsigned int cont = 0; + unsigned int count = 0; for( auto bin: *histogram ) { if( bin > histogram->_maxValueHistogramLocal ) { histogram->_maxValueHistogramLocal = bin; } - cont++; + count++; } histogram->_maxValueHistogramGlobal = histogram->_maxValueHistogramLocal; @@ -414,8 +416,7 @@ namespace visimpl void HistogramWidget::bins( unsigned int binsNumber ) { - if( _bins == binsNumber ) - return; + if( _bins == binsNumber ) return; _bins = binsNumber; @@ -430,7 +431,7 @@ namespace visimpl if( _autoCalculateColors ) CalculateColors( T_HIST_MAIN ); - unsigned int focusBins = _bins * _zoomFactor; + const unsigned int focusBins = _bins * _zoomFactor; _focusHistogram.clear( ); _focusHistogram.resize( focusBins, 0 ); @@ -451,9 +452,11 @@ namespace visimpl void HistogramWidget::zoomFactor( float factor ) { + if(_zoomFactor == factor) return; + _zoomFactor = factor; - unsigned int focusBins = _bins * _zoomFactor; + const unsigned int focusBins = _bins * _zoomFactor; _focusHistogram.clear( ); _focusHistogram.resize( focusBins, 0 ); @@ -480,6 +483,8 @@ namespace visimpl void HistogramWidget::colorScaleLocal( TColorScale scale ) { + if(_colorScaleLocal == scale && _scaleFuncLocal) return; + _prevColorScaleLocal = _colorScaleLocal; _colorScaleLocal = scale; @@ -505,6 +510,8 @@ namespace visimpl void HistogramWidget::colorScaleGlobal( TColorScale scale ) { + if(_colorScaleGlobal == scale && _scaleFuncGlobal) return; + _prevColorScaleGlobal = _colorScaleGlobal; _colorScaleGlobal = scale; @@ -546,6 +553,8 @@ namespace visimpl void HistogramWidget::gridLinesNumber( unsigned int linesNumber ) { + if(_gridLinesNumber == linesNumber) return; + _gridLinesNumber = linesNumber; _mainHistogram._gridLines.clear( ); @@ -658,8 +667,7 @@ namespace visimpl unsigned int position = std::max( 0.0f, std::min( 1.0f, percentage)) * _mainHistogram.size( ); - if( position >= _mainHistogram.size( )) - position = _mainHistogram.size( ) - 1; + position = std::min(position, static_cast<unsigned int>(_mainHistogram.size() - 1)); return _mainHistogram[ position ]; } @@ -668,8 +676,7 @@ namespace visimpl { unsigned int position = percentage * _focusHistogram.size( ); - if( position >= _focusHistogram.size( )) - position = _focusHistogram.size( ) - 1; + position = std::min(position, static_cast<unsigned int>(_mainHistogram.size() - 1)); return _focusHistogram[ position ]; } @@ -814,7 +821,7 @@ namespace visimpl void HistogramWidget::paintEvent( QPaintEvent* /*e*/) { QPainter painter( this ); - unsigned int currentHeight = height( ); + const unsigned int currentHeight = height( ); QColor penColor; @@ -927,12 +934,12 @@ namespace visimpl localPosition.setY( std::min( height( ), std::max( 0, localPosition.y( )))); const float percentage = float( localPosition.x( )) / float( width( )); - - int positionX = localPosition.x( ); + const int positionX = localPosition.x( ); int margin = 5; - QString value = QString::number( valueAt( percentage )); - const int valueLength = value.length( ) * 10; + const auto value = valueAt(percentage); + QString valueText = QString::number( value, 'f', 3 ); + const int valueLength = valueText.length( ) * 10; if( width( ) - positionX < valueLength ) margin = -valueLength; @@ -958,14 +965,14 @@ namespace visimpl QPoint position ( positionX + margin, height( ) * 0.75f ); - painter.drawText( position, QString::number( valueAt( percentage ))); + painter.drawText( position, valueText ); if( _paintTimeline ) { position.setY( height( ) * 0.25f ); QString timeText( "t=" ); - timeText.append( QString::number( timeAt( percentage ))); + timeText.append( QString::number( timeAt( percentage ), 'f', 3)); painter.drawText( position, timeText ); } @@ -994,7 +1001,7 @@ namespace visimpl if( _player ) { - int lineX = _player->GetRelativeTime( ) * width( ); + const int lineX = _player->GetRelativeTime( ) * width( ); QLine simMarkerLine( QPoint( lineX, 0), QPoint( lineX, height( ))); @@ -1004,9 +1011,9 @@ namespace visimpl if( _paintTimeline ) { - QString value = QString::number(_player->currentTime( )); + const auto value = QString::number(_player->currentTime( ), 'f', 3); - int valueLength = value.length( ) * _pixelsPerCharacter; + const int valueLength = value.length( ) * _pixelsPerCharacter; if( width( ) - lineX < valueLength ) _pixelMargin = -valueLength; QPoint position ( lineX + _pixelMargin, height( ) * 0.5f ); diff --git a/sumrice/LoaderThread.cpp b/sumrice/LoaderThread.cpp index 8cbe7e0a7604cf727c0b607e38d7995f15322f29..77cc7c31ebf6f64eeb737db2ab0868d1977bd372 100644 --- a/sumrice/LoaderThread.cpp +++ b/sumrice/LoaderThread.cpp @@ -109,11 +109,23 @@ void LoaderThread::run() m_network = m_rest->loadNetwork(m_arg1, m_arg2); m_data = m_rest->loadSimulationData(m_arg1, m_arg2); + unsigned int oldSpikes = 0, oldNetwork = 0; for(int i = 0; i < 5; ++i) { QThread::sleep(1); - emit network(m_network->gidsSize()); - emit spikes(dynamic_cast<simil::SpikeData *>(m_data)->spikes().size()); + const auto newNetwork = m_network->gidsSize(); + if(newNetwork != oldNetwork) + { + oldNetwork = newNetwork; + emit network(newNetwork); + } + + const auto newSpikes = dynamic_cast<simil::SpikeData *>(m_data)->spikes().size(); + if(oldSpikes != newSpikes) + { + oldSpikes = newSpikes; + emit spikes(newSpikes); + } } emit progress(50); #else diff --git a/sumrice/Summary.cpp b/sumrice/Summary.cpp index 149cf3a9597a747d82968c07b7efe7044ff2a7d0..205b8f386a8f8d462579a6b58e05e70c1895dc04 100644 --- a/sumrice/Summary.cpp +++ b/sumrice/Summary.cpp @@ -724,11 +724,13 @@ namespace visimpl void Summary::UpdateHistograms( void ) { - for( auto histogram : _histogramWidgets ) - { - histogram->Spikes(*_spikeReport); - histogram->Update(); - } + auto updateHistogram = [&](HistogramWidget *h) + { + h->Spikes(*_spikeReport); + h->Update(); + h->update(); + }; + std::for_each(_histogramWidgets.begin(), _histogramWidgets.end(), updateHistogram); } void Summary::insertSubset( const Selection& selection ) @@ -1082,8 +1084,10 @@ namespace visimpl bins( binsNumber ); } - void Summary::bins( int bins_ ) + void Summary::bins( unsigned int bins_ ) { + if(_bins == bins_) return; + _bins = bins_; #ifdef VISIMPL_USE_OPENMP @@ -1115,6 +1119,8 @@ namespace visimpl void Summary::zoomFactor( double zoom ) { + if(_zoomFactor == zoom) return; + _zoomFactor = zoom; #ifdef VISIMPL_USE_OPENMP @@ -1126,7 +1132,6 @@ namespace visimpl for( auto histogram : _histogramWidgets ) { #endif - histogram->zoomFactor( _zoomFactor ); histogram->update(); } diff --git a/sumrice/Summary.h b/sumrice/Summary.h index 67bd45de3bf9964f8cae869ba2a47d2e8772297d..5c8bb96f2721dd0c35084471fc557dd476fc51e7 100644 --- a/sumrice/Summary.h +++ b/sumrice/Summary.h @@ -136,7 +136,7 @@ namespace visimpl void generateEventsRep( void ); void clearEvents( void ); - void bins( int bins_ ); + void bins( unsigned int bins_ ); void binsChanged( void ); void zoomFactorChanged( void ); void zoomFactor( double zoom ); diff --git a/visimpl/CMakeLists.txt b/visimpl/CMakeLists.txt index 0d7146df0c62176cf1f5c094ce04e1bc439f3fac..23d07d7ee1e5adc97f1dbc4cedd459aa61bbef2b 100644 --- a/visimpl/CMakeLists.txt +++ b/visimpl/CMakeLists.txt @@ -50,7 +50,6 @@ set(VISIMPL_SOURCES prefr/UpdaterStaticPosition.cpp render/Plane.cpp - ui/DataInspector.cpp ) set(VISIMPL_HEADERS @@ -71,8 +70,6 @@ set(VISIMPL_HEADERS prefr/UpdaterStaticPosition.h render/Plane.h - - ui/DataInspector.h ) include_directories(${CMAKE_CURRENT_BINARY_DIR}) diff --git a/visimpl/DomainManager.cpp b/visimpl/DomainManager.cpp index 97fa8de4cb0b4146496cff509c7df7f8b809265e..0e88bcc10c5da8e8bb2f21e1f1cde075b59cda09 100644 --- a/visimpl/DomainManager.cpp +++ b/visimpl/DomainManager.cpp @@ -469,8 +469,6 @@ namespace visimpl _particleToGID.reserve(count); _gidSource.reserve(count); - std::cout << "Retrieved " << availableParticles.size( ) << std::endl; - _resetBoundingBox( ); auto gidit = _gids.begin( ); diff --git a/visimpl/MainWindow.cpp b/visimpl/MainWindow.cpp index 2adc875837eafa6a04751dd34b430fe817afa45f..1681deb1c43b4bc24ea2f9c215bdde70d9b4b28d 100644 --- a/visimpl/MainWindow.cpp +++ b/visimpl/MainWindow.cpp @@ -99,9 +99,7 @@ namespace visimpl , _simConfigurationDock( nullptr ) , _modeSelectionWidget( nullptr ) , _toolBoxOptions( nullptr ) -#ifdef SIMIL_WITH_REST_API , _objectInspectorGB{nullptr} -#endif , _groupBoxTransferFunction( nullptr ) , _tfWidget( nullptr ) , _selectionManager( nullptr ) @@ -281,9 +279,27 @@ namespace visimpl void MainWindow::configureComponents( void ) { _domainManager = _openGLWidget->domainManager( ); + _selectionManager->setGIDs( _domainManager->gids( ) ); _subsetEvents = _openGLWidget->player( )->data( )->subsetsEvents( ); + + if(_openGLWidget) + { + auto player = _openGLWidget->player(); + if(player) + { + const auto tBegin = player->startTime(); + const auto tEnd = player->endTime(); + const auto tCurrent = player->currentTime(); + + _startTimeLabel->setText(QString::number(tCurrent, 'f', 3)); + _endTimeLabel->setText(QString::number(tEnd, 'f', 3)); + + const auto percentage = (tCurrent - tBegin) / (tEnd - tBegin); + UpdateSimulationSlider(percentage); + } + } } void MainWindow::openBlueConfigThroughDialog( void ) @@ -543,15 +559,14 @@ namespace visimpl connect( _openGLWidget, SIGNAL( updateSlider( float ) ), this, SLOT( UpdateSimulationSlider( float ) ) ); -#ifdef SIMIL_WITH_REST_API _objectInspectorGB->setSimPlayer(_openGLWidget->player( )); _subsetEvents = _openGLWidget->subsetEventsManager( ); -#endif + _startTimeLabel->setText( - QString::number( ( double )_openGLWidget->player( )->startTime( ) ) ); + QString::number(_openGLWidget->player()->startTime(), 'f', 3)); _endTimeLabel->setText( - QString::number( ( double )_openGLWidget->player( )->endTime( ) ) ); + QString::number(_openGLWidget->player()->endTime(), 'f', 3)); _simSlider->setEnabled(true); @@ -649,7 +664,7 @@ namespace visimpl connect( _repeatButton, SIGNAL( clicked( ) ), this, SLOT( Repeat( ) ) ); - connect( _simSlider, SIGNAL( sliderPressed( ) ), this, SLOT( PlayAt( ) ) ); + connect( _simSlider, SIGNAL( sliderPressed( ) ), this, SLOT( PlayAtPosition( ) ) ); connect( _goToButton, SIGNAL( clicked( ) ), this, SLOT( playAtButtonClicked( ) ) ); @@ -662,7 +677,7 @@ namespace visimpl this->addDockWidget(Qt::BottomDockWidgetArea, _simulationDock ); connect( _summary, SIGNAL( histogramClicked( float ) ), this, - SLOT( PlayAt( float ) ) ); + SLOT( PlayAtPercentage( float ) ) ); } void MainWindow::_initSimControlDock( void ) @@ -889,13 +904,11 @@ namespace visimpl layoutContainerSelection->addWidget( selFunctionGB ); layoutContainerSelection->addWidget( gbClippingPlanes ); -#ifdef SIMIL_WITH_REST_API _objectInspectorGB = new DataInspector( "Object inspector" ); _objectInspectorGB->addWidget( new QLabel( "GID:" ), 2, 0, 1, 1 ); _objectInspectorGB->addWidget( _labelGID, 2, 1, 1, 3 ); _objectInspectorGB->addWidget( new QLabel( "Position: " ), 3, 0, 1, 1 ); _objectInspectorGB->addWidget( _labelPosition, 3, 1, 1, 3 ); -#endif QGroupBox* groupBoxGroups = new QGroupBox( "Current visualization groups" ); _groupLayout = new QVBoxLayout( ); @@ -1008,24 +1021,16 @@ namespace visimpl _toolBoxOptions->addItem( containerSelectionTools, tr( "Selection" ) ); -#ifdef SIMIL_WITH_REST_API _toolBoxOptions->addItem( _objectInspectorGB, tr( "Inspector" )); - connect( _objectInspectorGB, SIGNAL( simDataChanged( void )), - _openGLWidget, SLOT( updateData( void ))); - - connect( _objectInspectorGB, SIGNAL( simDataChanged( void )), - _openGLWidget, SLOT( updateData( void ))); + connect( _objectInspectorGB, SIGNAL( simDataChanged()), + _openGLWidget, SLOT( updateData())); - QTimer* timer = new QTimer( this ); - connect( timer, SIGNAL( timeout ( void )), _objectInspectorGB, - SLOT( updateInfo( void ) ) ); + connect( _objectInspectorGB, SIGNAL( simDataChanged()), + _summary, SLOT( UpdateHistograms())); - timer->start( 4000 ); - - connect( _objectInspectorGB, SIGNAL( simDataChanged( void ) ), _summary, - SLOT( UpdateHistograms( void ) ) ); -#endif + connect (_objectInspectorGB, SIGNAL( simDataChanged()), + this, SLOT(configureComponents())); verticalLayout->setAlignment( Qt::AlignTop ); verticalLayout->addWidget( _modeSelectionWidget ); @@ -1148,13 +1153,11 @@ namespace visimpl if ( !_openGLWidget || !_openGLWidget->player( ) ) return; - _startTimeLabel->setText( - QString::number( static_cast<double>(_openGLWidget->currentTime( ) ) ) ); - // TODO UPDATE ENDTIME - - int total = _simSlider->maximum( ) - _simSlider->minimum( ); + _startTimeLabel->setText(QString::number(_openGLWidget->currentTime(), 'f', 3)); + _endTimeLabel->setText(QString::number(_openGLWidget->player()->endTime(), 'f', 3)); - int position = percentage * total; + const int total = _simSlider->maximum( ) - _simSlider->minimum( ); + const int position = (percentage * total) + _simSlider->minimum(); _simSlider->setSliderPosition( position ); @@ -1434,7 +1437,7 @@ namespace visimpl percentage = std::max( 0.0f, std::min( 1.0f, percentage ) ); - PlayAt( percentage, true ); + PlayAtPercentage( percentage, true ); } } @@ -1702,7 +1705,7 @@ namespace visimpl _openGLWidget->Stop( ); _playButton->setIcon( _playIcon ); _startTimeLabel->setText( - QString::number( ( double )_openGLWidget->player( )->startTime( ) ) ); + QString::number(_openGLWidget->player()->startTime(),'f',3)); _openGLWidget->playbackMode( TPlaybackMode::CONTINUOUS ); @@ -1875,6 +1878,8 @@ void MainWindow::clearGroups( void ) { _openGLWidget->Pause( ); _playButton->setIcon( _playIcon ); + _startTimeLabel->setText( + QString::number(_openGLWidget->player()->currentTime(), 'f',3)); if ( notify ) { @@ -1885,7 +1890,7 @@ void MainWindow::clearGroups( void ) } } - void MainWindow::Repeat( bool notify ) + void MainWindow::Repeat( bool notify ) { if ( !_openGLWidget || !_openGLWidget->player( ) ) return; @@ -1905,83 +1910,76 @@ void MainWindow::clearGroups( void ) } } - void MainWindow::requestPlayAt( float percentage ) + void MainWindow::requestPlayAt( float timePos ) { if ( !_openGLWidget || !_openGLWidget->player( ) ) return; - PlayAt( percentage, false ); + const auto tBegin = _openGLWidget->player()->startTime(); + const auto tEnd = _openGLWidget->player()->endTime(); + const auto newPosition = std::min(tEnd, std::max(tBegin, timePos)); + const auto isOverflow = timePos != newPosition; + + PlayAtTime( newPosition, isOverflow ); + + if(isOverflow) + Pause(true); } - void MainWindow::PlayAt( bool notify ) + void MainWindow::PlayAtPosition( bool notify ) { if ( !_openGLWidget || !_openGLWidget->player( ) ) return; - PlayAt( _simSlider->sliderPosition( ), notify ); + PlayAtPosition( _simSlider->sliderPosition( ), notify ); } - void MainWindow::PlayAt( float percentage, bool notify ) + void MainWindow::PlayAtPosition( int sliderPosition, bool notify ) { if ( !_openGLWidget || !_openGLWidget->player( ) ) return; - int sliderPosition = - percentage * ( _simSlider->maximum( ) - _simSlider->minimum( ) ) + - _simSlider->minimum( ); + const int sMin = _simSlider->minimum(); + const int sMax = _simSlider->maximum(); + const float percentage = static_cast<float>(sliderPosition - sMin) * (sMax - sMin); - _simSlider->setSliderPosition( sliderPosition ); - - _playButton->setIcon( _pauseIcon ); + PlayAtPercentage(percentage, notify); + } - _openGLWidget->PlayAt( percentage ); + void MainWindow::PlayAtPercentage( float percentage, bool notify ) + { + if ( !_openGLWidget || !_openGLWidget->player( ) ) + return; - _openGLWidget->playbackMode( TPlaybackMode::CONTINUOUS ); + const auto tBegin = _openGLWidget->player()->startTime(); + const auto tEnd = _openGLWidget->player()->endTime(); + const auto timePos = (percentage * (tEnd - tBegin)) + tBegin; - if ( notify ) - { -#ifdef SIMIL_USE_ZEROEQ - try - { - // Send event - auto eventMgr = _openGLWidget->player( )->zeqEvents( ); - if(eventMgr) - { - eventMgr->sendFrame( _simSlider->minimum( ), _simSlider->maximum( ), sliderPosition ); - } - } - catch(const std::exception &e) - { - std::cerr << "Exception when sending frame. " << e.what() << __FILE__ << ":" << __LINE__ << std::endl; - } - catch(...) - { - std::cerr << "Unknown exception when sending frame. " << __FILE__ << ":" << __LINE__ << std::endl; - } -#endif -#ifdef VISIMPL_USE_GMRVLEX - sendZeroEQPlaybackOperation(zeroeq::gmrv::PLAY); -#endif - } + PlayAtTime(timePos, notify); } - void MainWindow::PlayAt( int sliderPosition, bool notify ) + void MainWindow::PlayAtTime(float timePos, bool notify) { - if ( !_openGLWidget || !_openGLWidget->player( ) ) + if(!_openGLWidget || !_openGLWidget->player()) return; - int value = _simSlider->value( ); - float percentage = - float( value - _simSlider->minimum( ) ) / - float( _simSlider->maximum( ) - _simSlider->minimum( ) ); + const auto tBegin = _openGLWidget->player()->startTime(); + const auto tEnd = _openGLWidget->player()->endTime(); + const auto newPosition = std::max(tBegin, std::min(tEnd, timePos)); + const auto percentage = (newPosition - tBegin) / (tEnd - tBegin); + + const auto sMin = _simSlider->minimum(); + const auto sMax = _simSlider->maximum(); + const int sliderPosition = (percentage * (sMax - sMin)) + sMin; _simSlider->setSliderPosition( sliderPosition ); _playButton->setIcon( _pauseIcon ); - _openGLWidget->PlayAt( percentage ); - + _openGLWidget->PlayAt( newPosition ); _openGLWidget->playbackMode( TPlaybackMode::CONTINUOUS ); + _startTimeLabel->setText( + QString::number(_openGLWidget->player()->currentTime(), 'f',3)); if ( notify ) { @@ -1989,10 +1987,11 @@ void MainWindow::clearGroups( void ) try { // Send event - auto eventMgr = _openGLWidget->player( )->zeqEvents( ); + auto player = _openGLWidget->player(); + auto eventMgr = player->zeqEvents( ); if(eventMgr) { - eventMgr->sendFrame(_simSlider->minimum( ), _simSlider->maximum( ), sliderPosition ); + eventMgr->sendFrame( player->startTime(), player->endTime(), player->currentTime()); } } catch(const std::exception &e) @@ -2005,11 +2004,11 @@ void MainWindow::clearGroups( void ) } #endif #ifdef VISIMPL_USE_GMRVLEX - sendZeroEQPlaybackOperation( zeroeq::gmrv::PLAY); + sendZeroEQPlaybackOperation(zeroeq::gmrv::PLAY); #endif } - } + } void MainWindow::PreviousStep( bool /*notify*/ ) { if ( !_openGLWidget || !_openGLWidget->player( ) ) @@ -2104,10 +2103,30 @@ void MainWindow::clearGroups( void ) _comboAttribSelection->clear(); - if(m_type == simil::TDataType::TBlueConfig) + switch(m_type) { - const QStringList attributes = {"Morphological type", "Functional type"}; - _comboAttribSelection->addItems( attributes ); + case simil::TDataType::TBlueConfig: + { + const QStringList attributes = {"Morphological type", "Functional type"}; + _comboAttribSelection->addItems( attributes ); + } + break; + case simil::TDataType::TREST: + { +#ifdef SIMIL_WITH_REST_API + auto timer = new QTimer( this ); + connect( timer, SIGNAL( timeout()), + _objectInspectorGB, SLOT( updateInfo()) ); + + timer->start( 4000 ); +#endif + } + break; + case simil::TDataType::TCONE: + case simil::TDataType::TCSV: + case simil::TDataType::THDF5: + default: + break; } _openGLWidget->closeLoadingDialog(); diff --git a/visimpl/MainWindow.h b/visimpl/MainWindow.h index d5f6722f766a50348a2d7bc4d26f5a74c0305f43..baee250be5384fd0e8ef635cd3dbe14206273d08 100644 --- a/visimpl/MainWindow.h +++ b/visimpl/MainWindow.h @@ -30,7 +30,6 @@ #include "VisualGroup.h" #include "SelectionManagerWidget.h" #include "SubsetImporter.h" -#include "ui/DataInspector.h" // Qt #include <QMainWindow> @@ -49,7 +48,7 @@ class QToolBox; namespace Ui { -class MainWindow; + class MainWindow; } namespace visimpl @@ -141,9 +140,10 @@ namespace visimpl void Pause( bool notify = true ); void Stop( bool notify = true ); void Repeat( bool notify = true ); - void PlayAt( bool notify = true ); - void PlayAt( float, bool notify = true ); - void PlayAt( int, bool notify = true ); + void PlayAtPosition( bool notify = true ); + void PlayAtPosition( int, bool notify = true ); + void PlayAtPercentage( float, bool notify = true ); + void PlayAtTime( float, bool notify = true); void requestPlayAt( float ); void PreviousStep( bool notify = true ); void NextStep( bool notify = true ); @@ -269,9 +269,7 @@ namespace visimpl QTabWidget* _modeSelectionWidget; QToolBox* _toolBoxOptions; -#ifdef SIMIL_WITH_REST_API DataInspector * _objectInspectorGB; -#endif QGroupBox* _groupBoxTransferFunction; TransferFunctionWidget* _tfWidget; diff --git a/visimpl/OpenGLWidget.cpp b/visimpl/OpenGLWidget.cpp index 91575376b6f82254798ea56f23fd25ee685a181d..d0f2ab141188a6cd1045eff0e0bf3058fc1f2fdd 100644 --- a/visimpl/OpenGLWidget.cpp +++ b/visimpl/OpenGLWidget.cpp @@ -719,8 +719,7 @@ namespace visimpl const unsigned int maxParticles = std::max(100000u, static_cast<unsigned int>( _player->gids( ).size( ))); - _updateData( ); - + _updateData(); _particleSystem = new prefr::ParticleSystem( maxParticles, _camera ); _flagResetParticles = true; @@ -1149,31 +1148,39 @@ namespace visimpl _flagNewData = true; } - void OpenGLWidget::_updateData( void ) + bool OpenGLWidget::_updateData( void ) { const auto &positions = _player->positions(); + // assumed positions doesn't change so if equal the network didn't change. + if(positions.size() == _gidPositions.size()) return false; + _gidPositions.clear(); _gidPositions.reserve(positions.size()); - auto gidit = _player->gids().begin(); - for (const auto &pos : positions) + auto gidit = _player->gids().cbegin(); + auto insertElement = [&](const vmml::Vector3f &v) { - const vec3 position(pos.x() * _scaleFactor.x, - pos.y() * _scaleFactor.y, - pos.z() * _scaleFactor.z); + const vec3 position(v.x() * _scaleFactor.x, + v.y() * _scaleFactor.y, + v.z() * _scaleFactor.z); _gidPositions.insert(std::make_pair(*gidit, position)); ++gidit; - } + }; + std::for_each(positions.cbegin(), positions.cend(), insertElement); + + return true; } void OpenGLWidget::_updateNewData( void ) { - _updateData(); + _flagNewData = false; + + if(!_updateData()) return; + _domainManager->updateData(_player->gids(), _gidPositions ); _focusOn( _domainManager->boundingBox( )); - _flagNewData = false; _flagUpdateRender = true; } @@ -1306,7 +1313,6 @@ namespace visimpl { if( _player->isPlaying( ) || _firstFrame ) { - _particleSystem->update( renderDelta ); _firstFrame = false; } @@ -1975,7 +1981,7 @@ namespace visimpl } } - void OpenGLWidget::PlayAt( float percentage ) + void OpenGLWidget::PlayAt( float timePos ) { if( _player ) { @@ -1984,8 +1990,8 @@ namespace visimpl _backtrace = true; - std::cout << "Play at " << percentage << std::endl; - _player->PlayAt( percentage ); + std::cout << "Play at " << timePos << std::endl; + _player->PlayAtTime(timePos); _particleSystem->run( true ); } } diff --git a/visimpl/OpenGLWidget.h b/visimpl/OpenGLWidget.h index c62c2406d15a8844b6d973e537ca2385fccf6503..633de7ace64163ec632a4959b5a3159bdbd5395f 100644 --- a/visimpl/OpenGLWidget.h +++ b/visimpl/OpenGLWidget.h @@ -208,7 +208,7 @@ namespace visimpl void PlayPause( void ); void Stop( void ); void Repeat( bool repeat ); - void PlayAt( float percentage ); + void PlayAt( float timePos ); void Restart( void ); void PreviousStep( void ); void NextStep( void ); @@ -272,7 +272,7 @@ namespace visimpl void _updateAttributes( void ); void _updateNewData( void ); - void _updateData( void ); + bool _updateData( void ); void _createEventLabels( void ); void _updateEventLabelsVisibility( void ); diff --git a/visimpl/SelectionManagerWidget.cpp b/visimpl/SelectionManagerWidget.cpp index f022f5adbff42abb74d982cffbd87e9b8f6569dd..5793d21c4242b572e629be94ca0fccb27fb751c6 100644 --- a/visimpl/SelectionManagerWidget.cpp +++ b/visimpl/SelectionManagerWidget.cpp @@ -194,13 +194,15 @@ namespace visimpl void SelectionManagerWidget::setGIDs( const TGIDSet& all_, const TGIDUSet& selected_ ) { + if(all_.size() == _gidsAll.size()) return; + _gidsAll.clear( ); _gidsAll.insert( all_.begin( ), all_.end( )); _fillLists( ); + clearSelection(); setSelected( selected_ ); - } const TGIDUSet& SelectionManagerWidget::selected( void ) const