diff --git a/.gitignore b/.gitignore
index b0dbf28e941b0a4a4fde657fe061991c4f70f09b..98c3223e4577c62a918cc997b5218d8a5c71ac73 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,3 +42,4 @@ gmrvlex
prefr
scoop
vmmlib
+HighFive
diff --git a/sumrice/types.h b/sumrice/types.h
index 055e255d8e0f6b45f33714aeb5e8cf38c64dc8d7..60a1fe9cf2c537761550c1e3d5b6668e8a37909a 100644
--- a/sumrice/types.h
+++ b/sumrice/types.h
@@ -37,6 +37,8 @@ namespace visimpl
typedef simil::Spike Spike;
typedef simil::TSpikes TSpikes;
+ typedef std::unordered_map< unsigned int, unsigned int > TUIntUintMap;
+
typedef std::set< uint32_t > TGIDSet;
typedef std::vector< vmml::Vector3f > TPosVect;
diff --git a/visimpl/CMakeLists.txt b/visimpl/CMakeLists.txt
index f8abca0da3fdd050de07a0895572d572a34bc724..3382c372db1dfd2cec6c4f16948255f972980942 100644
--- a/visimpl/CMakeLists.txt
+++ b/visimpl/CMakeLists.txt
@@ -1,6 +1,6 @@
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# ViSimpl
-# 2015-2016 (c) ViSimpl / Universidad Rey Juan Carlos
+# 2015-2019 (c) ViSimpl / Universidad Rey Juan Carlos
# sergio.galindo@urjc.es
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -25,47 +25,51 @@ configure_file(${CMAKE_SOURCE_DIR}/CMake/common/cpp/version.cpp
set(UIDIR ${PROJECT_SOURCE_DIR}/ui)
set(QRCDIR ${PROJECT_SOURCE_DIR}/qrc)
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
+#set(CMAKE_AUTOMOC ON)
+#set(CMAKE_AUTOUIC ON)
set(VISIMPL_SOURCES
${PROJECT_BINARY_DIR}/src/visimpl/version.cpp
CMakeSetup.rc
-
+
visimpl.ui
resources.qrc
-
+
visimpl.cpp
MainWindow.cpp
OpenGLWidget.cpp
-
+
VisualGroup.cpp
DomainManager.cpp
-
+
+ SelectionManagerWidget.cpp
+
prefr/ColorSource.cpp
prefr/ColorOperationModel.cpp
prefr/SourceMultiPosition.cpp
prefr/UpdaterStaticPosition.cpp
-
+
render/Plane.cpp
-
+
)
set(VISIMPL_HEADERS
${PROJECT_BINARY_DIR}/include/visimpl/version.h
OpenGLWidget.h
MainWindow.h
-
+
VisualGroup.h
DomainManager.h
-
+
+ SelectionManagerWidget.h
+
prefr/PrefrShaders.h
prefr/ColorSource.h
prefr/ColorOperationModel.h
prefr/SourceMultiPosition.h
prefr/UpdaterStaticPosition.h
-
+
render/Plane.cpp
)
diff --git a/visimpl/DomainManager.cpp b/visimpl/DomainManager.cpp
index 0882fd05f998e7be7b9bd964a617d1c6645b3d40..44ec85191dc07a8468d7dbf9f83046a767186a1d 100644
--- a/visimpl/DomainManager.cpp
+++ b/visimpl/DomainManager.cpp
@@ -150,6 +150,16 @@ namespace visimpl
_particleSystem->start();
}
+ const tGidPosMap& DomainManager::positions( void ) const
+ {
+ return _gidPositions;
+ }
+
+ const TGIDSet& DomainManager::gids( void ) const
+ {
+ return _gids;
+ }
+
void DomainManager::mode( tVisualMode newMode )
{
clearView( );
diff --git a/visimpl/DomainManager.h b/visimpl/DomainManager.h
index 5f674821fc27a031b8e09bc02c135f2941c11eb0..8d553985eba31bb1587a91c3fcc2e5622891622e 100644
--- a/visimpl/DomainManager.h
+++ b/visimpl/DomainManager.h
@@ -87,6 +87,8 @@ namespace visimpl
const std::vector< VisualGroup* >& groups( void ) const;
const std::vector< VisualGroup* >& attributeGroups( void ) const;
+ const tGidPosMap& positions( void ) const;
+ const TGIDSet& gids( void ) const;
tBoundingBox boundingBox( void ) const;
diff --git a/visimpl/MainWindow.cpp b/visimpl/MainWindow.cpp
index 731774f615eb14d35a051229c439802f6fd3d7a5..0edcf8427f834538bc105a84b27e803ea53f1adb 100644
--- a/visimpl/MainWindow.cpp
+++ b/visimpl/MainWindow.cpp
@@ -88,8 +88,8 @@ namespace visimpl
, _modeSelectionWidget( nullptr )
, _toolBoxOptions( nullptr )
, _groupBoxTransferFunction( nullptr )
- , _tfEditor( nullptr )
, _tfWidget( nullptr )
+ , _selectionManager( nullptr )
, _autoNameGroups( false )
, _groupBoxGroups( nullptr )
, _groupLayout( nullptr )
@@ -115,6 +115,7 @@ namespace visimpl
, _spinBoxClippingWidth( nullptr )
, _spinBoxClippingDist( nullptr )
, _frameClippingColor( nullptr )
+ , _buttonSelectionFromClippingPlanes( nullptr )
{
_ui->setupUi( this );
@@ -163,7 +164,7 @@ namespace visimpl
// Connect about dialog
connect( _ui->actionAbout, SIGNAL( triggered( )),
- this, SLOT( aboutDialog( )));
+ this, SLOT( dialogAbout( )));
connect( _ui->actionHome, SIGNAL( triggered( )),
@@ -249,6 +250,8 @@ namespace visimpl
QStringList attributes = { "Morphological type", "Functional type" };
_comboAttribSelection->addItems( attributes );
+
+ _selectionManager->setGIDs( _domainManager->gids( ));
}
void MainWindow::openBlueConfigThroughDialog( void )
@@ -361,7 +364,7 @@ namespace visimpl
}
- void MainWindow::aboutDialog( void )
+ void MainWindow::dialogAbout( void )
{
QString msj =
@@ -443,6 +446,14 @@ namespace visimpl
QMessageBox::about(this, tr( "About ViSimpl" ), msj );
}
+ void MainWindow::dialogSelectionManagement( void )
+ {
+ if( !_selectionManager )
+ return;
+
+ _selectionManager->show( );
+ }
+
void MainWindow::togglePlaybackDock( void )
{
if( _ui->actionTogglePlaybackDock->isChecked( ))
@@ -620,6 +631,15 @@ namespace visimpl
_tfWidget = new TransferFunctionWidget( );
_tfWidget->setMinimumHeight( 150 );
+ _selectionManager = new SelectionManagerWidget( );
+// _selectionManager->setWindowFlags( Qt::D );
+ _selectionManager->setWindowModality( Qt::WindowModal );
+ _selectionManager->setMinimumHeight( 300 );
+ _selectionManager->setMinimumWidth( 500 );
+
+ connect( _selectionManager, SIGNAL( selectionChanged( void )),
+ this, SLOT( selectionManagerChanged( void )));
+
_deltaTimeBox = new QDoubleSpinBox( );
_deltaTimeBox->setMinimum( 0.00000001 );
_deltaTimeBox->setMaximum( 50 );
@@ -689,6 +709,10 @@ namespace visimpl
_frameClippingColor->setMinimumSize( 20, 20 );
_frameClippingColor->setMaximumSize( 20, 20 );
+ _buttonSelectionFromClippingPlanes = new QPushButton( "To selection");
+ _buttonSelectionFromClippingPlanes->setToolTip( tr( "Create a selection set from elements between planes" ));
+
+
QWidget* topContainer = new QWidget( );
QVBoxLayout* verticalLayout = new QVBoxLayout( );
@@ -743,12 +767,16 @@ namespace visimpl
vcLayout->addWidget( rFunctionGB );
vcContainer->setLayout( vcLayout );
+ QPushButton* buttonSelectionManager = new QPushButton( "..." );
+ buttonSelectionManager->setToolTip( tr( "Show the selection management dialog" ));
+ buttonSelectionManager->setMaximumWidth( 30 );
QGroupBox* selFunctionGB = new QGroupBox( "Current selection");
QHBoxLayout* selLayout = new QHBoxLayout( );
selLayout->setAlignment( Qt::AlignTop );
- selLayout->addWidget( new QLabel( "Selection size: " ));
+ selLayout->addWidget( new QLabel( "Size: " ));
selLayout->addWidget( _selectionSizeLabel );
+ selLayout->addWidget( buttonSelectionManager );
selLayout->addWidget( _addGroupButton );
selLayout->addWidget( _clearSelectionButton );
selFunctionGB->setLayout( selLayout );
@@ -760,8 +788,9 @@ namespace visimpl
QGroupBox* gbClippingPlanes = new QGroupBox( "Clipping planes" );
QGridLayout* layoutClippingPlanes = new QGridLayout( );
gbClippingPlanes->setLayout( layoutClippingPlanes );
- layoutClippingPlanes->addWidget( _checkClipping, 0, 0, 1, 2 );
- layoutClippingPlanes->addWidget( _checkShowPlanes, 0, 2, 1, 2 );
+ layoutClippingPlanes->addWidget( _checkClipping, 0, 0, 1, 1 );
+ layoutClippingPlanes->addWidget( _checkShowPlanes, 0, 1, 1, 2 );
+ layoutClippingPlanes->addWidget( _buttonSelectionFromClippingPlanes, 0, 3, 1, 1 );
layoutClippingPlanes->addWidget( line, 1, 0, 1, 4 );
layoutClippingPlanes->addWidget( _frameClippingColor, 2, 0, 1, 1 );
layoutClippingPlanes->addWidget( _buttonResetPlanes, 2, 1, 1, 1 );
@@ -926,6 +955,9 @@ namespace visimpl
connect( _tfWidget, SIGNAL( previewColor( void )),
this, SLOT( PreviewSimulationSizeFunction( void )));
+ connect( buttonSelectionManager, SIGNAL( clicked( void )),
+ this, SLOT( dialogSelectionManagement( void )));
+
connect( _deltaTimeBox, SIGNAL( valueChanged( double )),
this, SLOT( updateSimDeltaTime( void )));
@@ -952,6 +984,9 @@ namespace visimpl
connect( _checkShowPlanes, SIGNAL( stateChanged( int )),
_openGLWidget, SLOT( paintClippingPlanes( int )));
+ connect( _buttonSelectionFromClippingPlanes, SIGNAL( clicked( void )),
+ this, SLOT( selectionFromPlanes( void )));
+
connect( _buttonResetPlanes, SIGNAL( clicked( void )),
this, SLOT( clippingPlanesReset( void )));
@@ -968,13 +1003,8 @@ namespace visimpl
connect( _frameClippingColor, SIGNAL( clicked( )),
this, SLOT( colorSelectionClicked()));
-
-#ifdef VISIMPL_USE_ZEROEQ
-#ifdef VISIMPL_USE_GMRVLEX
connect( _clearSelectionButton, SIGNAL( clicked( void )),
- this, SLOT( ClearSelection( void )));
-#endif
-#endif
+ this, SLOT( clearSelection( void )));
connect( _addGroupButton, SIGNAL( clicked( void )),
this, SLOT( addGroupFromSelection( )));
@@ -1218,6 +1248,7 @@ namespace visimpl
_spinBoxClippingWidth->setEnabled( active );
_spinBoxClippingDist->setEnabled( active );
_frameClippingColor->setEnabled( active );
+ _buttonSelectionFromClippingPlanes->setEnabled( active );
_openGLWidget->clippingPlanes( active );
@@ -1301,6 +1332,65 @@ namespace visimpl
}
}
+ void MainWindow::selectionFromPlanes( void )
+ {
+ if( !_openGLWidget )
+ return;
+
+ auto ids = _openGLWidget->getPlanesContainedElements( );
+ visimpl::GIDUSet selectedSet( ids.begin( ), ids.end( ));
+
+ if( selectedSet.empty( ))
+ return;
+
+ setSelection( selectedSet, SRC_PLANES );
+
+ }
+
+ void MainWindow::selectionManagerChanged( void )
+ {
+ setSelection( _selectionManager->selected( ), SRC_WIDGET );
+ }
+
+ void MainWindow::_updateSelectionGUI( void )
+ {
+ auto selection = _domainManager->selection( );
+
+ _addGroupButton->setEnabled( true );
+ _clearSelectionButton->setEnabled( true );
+ _selectionSizeLabel->setText( QString::number( selection.size( )));
+ _selectionSizeLabel->update( );
+
+ }
+
+ void MainWindow::setSelection( const GIDUSet& selectedSet,
+ TSelectionSource source_ )
+ {
+ if( source_ == SRC_UNDEFINED )
+ return;
+
+ _domainManager->selection( selectedSet );
+ _openGLWidget->setSelectedGIDs( selectedSet );
+
+ if( source_ != SRC_WIDGET )
+ _selectionManager->setSelected( selectedSet );
+
+ _updateSelectionGUI( );
+ }
+
+ void MainWindow::clearSelection( void )
+ {
+ if( _openGLWidget )
+ {
+ _domainManager->clearSelection( );
+ _openGLWidget->clearSelection( );
+ _selectionManager->clearSelection( );
+
+ _addGroupButton->setEnabled( false );
+ _clearSelectionButton->setEnabled( false );
+ _selectionSizeLabel->setText( "0" );
+ }
+ }
#ifdef VISIMPL_USE_ZEROEQ
@@ -1380,17 +1470,7 @@ namespace visimpl
// pthread_exit( NULL );
//}
- void MainWindow::ClearSelection( void )
- {
- if( _openGLWidget )
- {
- _openGLWidget->clearSelection( );
- _addGroupButton->setEnabled( false );
- _clearSelectionButton->setEnabled( false );
- _selectionSizeLabel->setText( "0" );
- }
- }
void MainWindow::_onSelectionEvent( lexis::data::ConstSelectedIDsPtr selected )
{
@@ -1403,18 +1483,9 @@ namespace visimpl
std::vector< uint32_t > ids = selected->getIdsVector( );
-
-
visimpl::GIDUSet selectedSet( ids.begin( ), ids.end( ));
- if( selectedSet.size( ) == 0 )
- return;
-
- _openGLWidget->setSelectedGIDs( selectedSet );
-
- _addGroupButton->setEnabled( true );
- _clearSelectionButton->setEnabled( true );
- _selectionSizeLabel->setText( QString::number( selectedSet.size( )));
+ setSelection( selectedSet, SRC_EXTERNAL );
}
}
diff --git a/visimpl/MainWindow.h b/visimpl/MainWindow.h
index b2dea1320e30282be2151c8541a05e983cc7c893..7204d804a6ad6e8b2068a008efb63ec8d23a9137 100644
--- a/visimpl/MainWindow.h
+++ b/visimpl/MainWindow.h
@@ -18,6 +18,7 @@
#include <QToolBox>
#include "OpenGLWidget.h"
+#include "SelectionManagerWidget.h"
#include <sumrice/sumrice.h>
@@ -31,6 +32,14 @@ class MainWindow;
namespace visimpl
{
+ enum TSelectionSource
+ {
+ SRC_EXTERNAL = 0,
+ SRC_PLANES,
+ SRC_WIDGET,
+ SRC_UNDEFINED
+ };
+
class MainWindow
: public QMainWindow
{
@@ -63,7 +72,8 @@ namespace visimpl
void openSubsetEventFile( const std::string& fileName,
bool append = false );
- void aboutDialog( void );
+ void dialogAbout( void );
+ void dialogSelectionManagement( void );
void togglePlaybackDock( void );
void toggleSimConfigDock( void );
@@ -125,6 +135,11 @@ namespace visimpl
void colorSelectionClicked( void );
+ void selectionManagerChanged( void );
+ void setSelection( const GIDUSet& selection_, TSelectionSource source_ = SRC_UNDEFINED );
+ void clearSelection( void );
+ void selectionFromPlanes( void );
+
protected:
void _initSimControlDock( void );
@@ -134,6 +149,8 @@ namespace visimpl
void _configurePlayer( void );
void _resetClippingParams( void );
+ void _updateSelectionGUI( void );
+
bool _showDialog( QColor& current, const QString& message = "" );
@@ -147,7 +164,6 @@ namespace visimpl
#endif
- void ClearSelection( void );
protected:
@@ -188,8 +204,8 @@ namespace visimpl
QToolBox* _toolBoxOptions;
QGroupBox* _groupBoxTransferFunction;
- TransferFunctionEditor* _tfEditor;
TransferFunctionWidget* _tfWidget;
+ SelectionManagerWidget* _selectionManager;
bool _autoNameGroups;
QGroupBox* _groupBoxGroups;
@@ -225,6 +241,7 @@ namespace visimpl
QDoubleSpinBox* _spinBoxClippingWidth;
QDoubleSpinBox* _spinBoxClippingDist;
QPushButton* _frameClippingColor;
+ QPushButton* _buttonSelectionFromClippingPlanes;
};
diff --git a/visimpl/OpenGLWidget.cpp b/visimpl/OpenGLWidget.cpp
index 214625a9e57dc798085cfa2c32337c495b6bbb60..ff1440994d715392b8671dc9b59c3534777795b1 100644
--- a/visimpl/OpenGLWidget.cpp
+++ b/visimpl/OpenGLWidget.cpp
@@ -123,6 +123,7 @@ namespace visimpl
, _flagUpdateAttributes( false )
, _flagPickingSingle( false )
, _flagChangeShader( false )
+ , _flagUpdateRender( false )
, _flagModeChange( false )
, _newMode( TMODE_UNDEFINED )
, _flagAttribChange( false )
@@ -594,9 +595,15 @@ namespace visimpl
_camera->position( )[ 1 ],
_camera->position( )[ 2 ] );
- _particleSystem->updateCameraDistances( cameraPosition );
+ if( _player->isPlaying( ) || _lastCameraPosition != cameraPosition || _flagUpdateRender )
+ {
+ _particleSystem->updateCameraDistances( cameraPosition );
+ _lastCameraPosition = cameraPosition;
+
+ _particleSystem->updateRender( );
- _lastCameraPosition = cameraPosition;
+ _flagUpdateRender = false;
+ }
if( _clipping )
{
@@ -604,8 +611,6 @@ namespace visimpl
_clippingPlaneRight->activate( _shaderParticlesCurrent, 1 );
}
-
- _particleSystem->updateRender( );
_particleSystem->render( );
if( _clipping )
@@ -863,6 +868,7 @@ namespace visimpl
_domainManager->mode( _newMode );
_flagModeChange = false;
+ _flagUpdateRender = true;
if( _domainManager->mode( ) == TMODE_ATTRIBUTE )
emit attributeStatsComputed( );
@@ -886,14 +892,13 @@ namespace visimpl
{
_particleSystem->run( false );
- _domainManager->selection( _selectedGIDs );
-
updateCameraBoundingBox( );
_particleSystem->run( true );
_particleSystem->update( 0.0f );
_flagUpdateSelection = false;
+ _flagUpdateRender = true;
}
}
@@ -972,7 +977,6 @@ namespace visimpl
void OpenGLWidget::clearSelection( void )
{
- _domainManager->clearSelection( );
_selectedGIDs.clear( );
_flagUpdateSelection = true;
}
@@ -1133,7 +1137,7 @@ namespace visimpl
_planesCenter = glmToEigen( currentBoundingBox.first + currentBoundingBox.second ) * 0.5f;
- _planeDistance = std::abs( currentBoundingBox.second.x - currentBoundingBox.first.x );
+ _planeDistance = std::abs( currentBoundingBox.second.x - currentBoundingBox.first.x ) + 1;
_planeHeight = std::abs( currentBoundingBox.second.y - currentBoundingBox.first.y );
_planeWidth = std::abs( currentBoundingBox.second.z - currentBoundingBox.first.z );
@@ -1213,23 +1217,23 @@ namespace visimpl
centerLeft = transform( centerLeft, center, _planeRotation );
centerRight = transform( centerRight, center, _planeRotation );
- evec3 leftNormal = ( center - centerLeft ).normalized( );
- evec3 rightNormal = ( center - centerRight ).normalized( );
+ _planeNormalLeft = ( center - centerLeft ).normalized( );
+ _planeNormalRight = ( center - centerRight ).normalized( );
- _clippingPlaneLeft->setEquationByPointAndNormal( centerLeft, leftNormal );
- _clippingPlaneRight->setEquationByPointAndNormal( centerRight, rightNormal );
+ _clippingPlaneLeft->setEquationByPointAndNormal( centerLeft, _planeNormalLeft );
+ _clippingPlaneRight->setEquationByPointAndNormal( centerRight, _planeNormalRight );
- std::cout << "Planes:" << std::endl
- << " Left: "
- << std::endl << vecToStr( transformedPoints[ 0 ])
- << std::endl << vecToStr( transformedPoints[ 1 ])
- << std::endl << vecToStr( transformedPoints[ 2 ])
- << std::endl
- << " Right: "
- << std::endl << vecToStr( transformedPoints[ 3 ])
- << std::endl << vecToStr( transformedPoints[ 4 ])
- << std::endl << vecToStr( transformedPoints[ 5 ])
- << std::endl;
+// std::cout << "Planes:" << std::endl
+// << " Left: "
+// << std::endl << vecToStr( transformedPoints[ 0 ])
+// << std::endl << vecToStr( transformedPoints[ 1 ])
+// << std::endl << vecToStr( transformedPoints[ 2 ])
+// << std::endl
+// << " Right: "
+// << std::endl << vecToStr( transformedPoints[ 3 ])
+// << std::endl << vecToStr( transformedPoints[ 4 ])
+// << std::endl << vecToStr( transformedPoints[ 5 ])
+// << std::endl;
@@ -1353,6 +1357,41 @@ namespace visimpl
_updatePlanes( );
}
+ GIDVec OpenGLWidget::getPlanesContainedElements( void ) const
+ {
+ GIDVec result;
+
+ // Project elements
+ evec3 normal = - _planeNormalLeft;
+ normal.normalize( );
+
+ auto positions = _domainManager->positions( );
+
+ result.reserve( positions.size( ));
+
+ float distance = 0.0f;
+
+ std::cout << "Contained elements: ";
+ for( auto neuronPos : positions )
+ {
+ distance = normal.dot( _planeLeft.points( )[ 0 ] ) -
+ normal.dot( glmToEigen( neuronPos.second ));
+
+ if( distance > 0.0f && distance <= _planeDistance )
+ {
+ result.emplace_back( neuronPos.first );
+// std::cout << " [" << neuronPos.first << ":" << distance << "]";
+ }
+ }
+
+ result.shrink_to_fit( );
+
+ std::cout << " " << result.size( ) << std::endl;
+
+ return result;
+ }
+
+
void OpenGLWidget::mousePressEvent( QMouseEvent* event_ )
{
diff --git a/visimpl/OpenGLWidget.h b/visimpl/OpenGLWidget.h
index ae2ec7dae8f7a90761f30aab305dfb6d80b89867..0dd3c950c426f5049199e858b84880fa7501cc25 100644
--- a/visimpl/OpenGLWidget.h
+++ b/visimpl/OpenGLWidget.h
@@ -201,6 +201,8 @@ namespace visimpl
void changeSimulationDecayValue( float value );
float getSimulationDecayValue( void );
+ GIDVec getPlanesContainedElements( void ) const;
+
protected:
void _resolveFlagsOperations( void );
@@ -314,6 +316,8 @@ namespace visimpl
reto::ClippingPlane* _clippingPlaneLeft;
reto::ClippingPlane* _clippingPlaneRight;
evec3 _planesCenter;
+ evec3 _planeNormalLeft;
+ evec3 _planeNormalRight;
std::vector< Eigen::Vector3f > _planePosLeft;
std::vector< Eigen::Vector3f > _planePosRight;
Eigen::Matrix4f _planeRotation;
@@ -376,6 +380,7 @@ namespace visimpl
bool _flagUpdateAttributes;
bool _flagPickingSingle;
bool _flagChangeShader;
+ bool _flagUpdateRender;
bool _flagModeChange;
tVisualMode _newMode;
diff --git a/visimpl/SelectionManagerWidget.cpp b/visimpl/SelectionManagerWidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8802905336871be55f9a4ccc214fb74984d325af
--- /dev/null
+++ b/visimpl/SelectionManagerWidget.cpp
@@ -0,0 +1,433 @@
+/*
+ * @file SelectionManagerWidget.cpp
+ * @brief
+ * @author Sergio E. Galindo <sergio.galindo@urjc.es>
+ * @date
+ * @remarks Copyright (c) GMRV/URJC. All rights reserved.
+ * Do not distribute without further notice.
+ */
+
+#include "SelectionManagerWidget.h"
+
+#include <QGridLayout>
+#include <QGroupBox>
+#include <QLabel>
+#include <QFileDialog>
+#include <QMessageBox>
+#include <QTextStream>
+#include <QShortcut>
+
+namespace visimpl
+{
+
+ SelectionManagerWidget::SelectionManagerWidget( QWidget* parent_ )
+ : QWidget( parent_ )
+ , _listViewAvailable( nullptr )
+ , _listViewSelected( nullptr )
+ , _modelAvailable( nullptr )
+ , _modelSelected( nullptr )
+ , _buttonAddToSelection( nullptr )
+ , _buttonRemoveFromSelection( nullptr )
+ {
+ init( );
+ }
+
+ SelectionManagerWidget::~SelectionManagerWidget( void )
+ {
+
+ }
+
+ void SelectionManagerWidget::init( void )
+ {
+
+ QVBoxLayout* layoutTop = new QVBoxLayout( );
+
+ this->setLayout( layoutTop );
+
+ _tabWidget = new QTabWidget( );
+ QWidget* containerFoot = new QWidget( );
+ QGridLayout* layoutFoot = new QGridLayout( );
+ containerFoot->setLayout( layoutFoot );
+
+ layoutTop->addWidget( _tabWidget );
+ layoutTop->addWidget( containerFoot );
+
+ _initTabSelection( );
+ _initTabExport( );
+ // Foot
+
+ QPushButton* buttonCancel = new QPushButton( "Cancel" );
+ buttonCancel->setMaximumWidth( 100 );
+ QPushButton* buttonAccept = new QPushButton( "Accept" );
+ buttonAccept->setMaximumWidth( 100 );
+
+ layoutFoot->addWidget( buttonCancel, 0, 0, 1, 1 );
+ layoutFoot->addWidget( buttonAccept, 0, 2, 1, 1 );
+
+ connect( buttonCancel, SIGNAL( clicked( void )),
+ this, SLOT( _buttonCancelClicked( void )));
+ connect( buttonAccept, SIGNAL( clicked( void )),
+ this, SLOT( _buttonAcceptClicked( void )));
+
+ new QShortcut( QKeySequence( Qt::Key_Escape ), this, SLOT( _buttonCancelClicked( )));
+ }
+
+ void SelectionManagerWidget::_initTabSelection( void )
+ {
+
+ QWidget* containerSelection = new QWidget( );
+
+ QGridLayout* layoutSelection = new QGridLayout( );
+ containerSelection->setLayout( layoutSelection );
+
+ _labelAvailable = new QLabel( "Available GIDs: 0" );
+ _labelSelection = new QLabel( "Selected GIDs: 0" );
+
+ layoutSelection->addWidget( _labelAvailable, 0, 0, 1, 1 );
+ layoutSelection->addWidget( _labelSelection, 0, 2, 1, 1 );
+
+ _listViewAvailable = new QListView( );
+ _listViewAvailable->setSelectionMode( QAbstractItemView::ExtendedSelection );
+ _listViewAvailable->setUniformItemSizes( true );
+
+ _listViewSelected = new QListView( );
+ _listViewSelected->setSelectionMode( QAbstractItemView::ExtendedSelection );
+ _listViewSelected->setUniformItemSizes( true );
+
+ _modelAvailable = new QStandardItemModel( );
+ _modelSelected = new QStandardItemModel( );
+
+ _listViewAvailable->setModel( _modelAvailable );
+ _listViewSelected->setModel( _modelSelected );
+
+ _buttonAddToSelection = new QPushButton( "-->" );
+ _buttonAddToSelection->setToolTip( tr( "Add to selected GIDs" ));
+
+ _buttonRemoveFromSelection = new QPushButton( "<--" );
+ _buttonRemoveFromSelection->setToolTip( tr( "Remove from selected GIDs" ));
+
+ layoutSelection->addWidget( _listViewAvailable, 1, 0, 5, 1 );
+ layoutSelection->addWidget( _buttonAddToSelection, 2, 1, 1, 1 );
+ layoutSelection->addWidget( _buttonRemoveFromSelection, 4, 1, 1, 1 );
+ layoutSelection->addWidget( _listViewSelected, 1, 2, 5, 1 );
+
+ connect( _buttonAddToSelection, SIGNAL( clicked( void )),
+ this, SLOT( _addToSelected( void )));
+
+ connect( _buttonRemoveFromSelection, SIGNAL( clicked( void )),
+ this, SLOT( _removeFromSelected( void )));
+
+ _tabWidget->addTab( containerSelection, "Selection" );
+ }
+
+ void SelectionManagerWidget::_initTabExport( void )
+ {
+ QWidget* containerExport = new QWidget( );
+ QGridLayout* layoutExport = new QGridLayout( );
+ containerExport->setLayout( layoutExport );
+
+ _pathExportDefault = QString::fromStdString( std::getenv( "PWD" ));
+ _lineEditFilePath = new QLineEdit( _pathExportDefault.append( "/output.txt"));
+
+ _lineEditPrefix = new QLineEdit( );
+ _lineEditSuffix = new QLineEdit( );
+ _lineEditSeparator = new QLineEdit( );
+
+ _radioNewLine = new QRadioButton( "New line" );
+ _radioSpace = new QRadioButton( "Space" );
+ _radioTab = new QRadioButton( "Tab" );
+ _radioOther = new QRadioButton( "Other:" );
+
+ _buttonBrowse = new QPushButton( "Browse..." );
+ _buttonSave = new QPushButton( "Save" );
+
+ QGroupBox* groupBoxPrefix = new QGroupBox( "Prefix/Suffix" );
+ QGridLayout* layoutPrefix = new QGridLayout( );
+ groupBoxPrefix->setLayout( layoutPrefix );
+ layoutPrefix->addWidget( new QLabel( "Prefix:" ), 0, 0, 1, 1 );
+ layoutPrefix->addWidget( _lineEditPrefix, 0, 1, 1, 1 );
+ layoutPrefix->addWidget( new QLabel( "Suffix:" ), 1, 0, 1, 1 );
+ layoutPrefix->addWidget( _lineEditSuffix, 1, 1, 1, 1 );
+
+ QGroupBox* groupBoxSeparator = new QGroupBox( "Separator" );
+ QGridLayout* layoutSeparator = new QGridLayout( );
+ layoutSeparator->addWidget( _radioNewLine, 0, 0, 1, 2 );
+ layoutSeparator->addWidget( _radioSpace, 1, 0, 1, 2 );
+ layoutSeparator->addWidget( _radioTab, 2, 0, 1, 2 );
+ layoutSeparator->addWidget( _radioOther, 3, 0, 1, 1 );
+ layoutSeparator->addWidget( _lineEditSeparator, 3, 1, 1, 1 );
+
+ _radioNewLine->setChecked( true );
+
+ groupBoxSeparator->setLayout( layoutSeparator );
+
+
+
+ layoutExport->addWidget( new QLabel( "File path:"), 0, 0, 1, 1 );
+ layoutExport->addWidget( _lineEditFilePath, 0, 1, 1, 4 );
+ layoutExport->addWidget( _buttonBrowse, 0, 5, 1, 1 );
+ layoutExport->addWidget( groupBoxPrefix, 1, 0, 4, 2 );
+ layoutExport->addWidget( groupBoxSeparator, 1, 2, 4, 3 );
+ layoutExport->addWidget( _buttonSave, 4, 5, 1, 1 );
+
+
+
+ connect( _buttonBrowse, SIGNAL( clicked( void )),
+ this, SLOT( _buttonBrowseClicked( void )));
+
+ connect( _buttonSave, SIGNAL( clicked( void )),
+ this, SLOT( _buttonSaveClicked( void )));
+
+ _tabWidget->addTab( containerExport, "Export" );
+
+ }
+
+ void SelectionManagerWidget::setGIDs( const TGIDSet& all_,
+ const TGIDUSet& selected_ )
+ {
+ _gidsAll.clear( );
+ _gidsAll.insert( all_.begin( ), all_.end( ));
+
+ _fillLists( );
+
+ setSelected( selected_ );
+
+ }
+
+ const TGIDUSet& SelectionManagerWidget::selected( void ) const
+ {
+ return _gidsSelected;
+ }
+
+ void SelectionManagerWidget::clearSelection( void )
+ {
+ _gidsSelected.clear( );
+ _gidsAvailable = _gidsAll;
+
+ _reloadLists( );
+ }
+
+ void SelectionManagerWidget::setSelected( const TGIDUSet& selected_ )
+ {
+ if( selected_ == _gidsSelected && !_gidsAvailable.empty( ))
+ return;
+
+ _gidsSelected = selected_;
+
+ _gidsAvailable.clear( );
+ for( auto gid : _gidsAll )
+ {
+ if( _gidsSelected.find( gid ) == _gidsSelected.end( ))
+ _gidsAvailable.insert( gid );
+ }
+
+ _reloadLists( );
+ }
+
+ void SelectionManagerWidget::_fillLists( void )
+ {
+ _modelAvailable->clear( );
+ _modelSelected->clear( );
+
+ unsigned int index = 0;
+ GIDVec gids( _gidsAll.size( ));
+ std::copy( _gidsAll.begin( ), _gidsAll.end( ), gids.begin( ));
+ std::sort( gids.begin( ), gids.end( ));
+
+ for( auto gid : gids )
+ {
+ QStandardItem* itemAvailable = new QStandardItem( );
+ QVariant value = QVariant::fromValue( gid );
+
+ itemAvailable->setData( value, Qt::DisplayRole );
+
+ QStandardItem* itemSelected = new QStandardItem( );
+ itemSelected->setData( value, Qt::DisplayRole );
+
+ _modelAvailable->appendRow( itemAvailable );
+ _modelSelected->appendRow( itemSelected );
+
+ _gidIndex.insert( std::make_pair( gid, index ));
+
+ ++index;
+ }
+
+ }
+
+ void SelectionManagerWidget::_reloadLists( void )
+ {
+
+ for( auto gid : _gidsAll )
+ {
+ bool stateSelected = ( _gidsSelected.find( gid ) != _gidsSelected.end( ));
+
+ auto gidIndex = _gidIndex.find( gid );
+ assert( gidIndex != _gidIndex.end( ));
+
+ unsigned int row = gidIndex->second;
+
+ _listViewAvailable->setRowHidden( row, stateSelected );
+ _listViewSelected->setRowHidden( row, !stateSelected );
+ }
+
+ _updateListsLabelNumbers( );
+
+ }
+
+ void SelectionManagerWidget::_updateListsLabelNumbers( void )
+ {
+ _labelAvailable->setText( QString( "Available GIDs: ").append(
+ QString::number( _gidsAvailable.size( ))));
+
+ _labelSelection->setText( QString( "Selected GIDs: ").append(
+ QString::number( _gidsSelected.size( ))));
+ }
+
+ void SelectionManagerWidget::_addToSelected( void )
+ {
+
+ auto selectedIndices =
+ _listViewAvailable->selectionModel( )->selectedIndexes( );
+
+ if( selectedIndices.size( ) <= 0 )
+ return;
+
+ for( auto index : selectedIndices )
+ {
+ if( index.row( ) < 0 )
+ continue;
+
+ auto item = _modelAvailable->itemFromIndex( index );
+
+ bool ok;
+ unsigned int gid = item->data( Qt::DisplayRole ).toUInt( &ok );
+
+ _gidsAvailable.erase( gid );
+ _gidsSelected.insert( gid );
+
+ auto gidIndex = _gidIndex.find( gid );
+ assert( gidIndex != _gidIndex.end( ));
+
+
+
+ _listViewAvailable->setRowHidden( gidIndex->second, true );
+ _listViewSelected->setRowHidden( gidIndex->second, false );
+
+ }
+
+ _listViewAvailable->selectionModel( )->clearSelection( );
+
+ _updateListsLabelNumbers( );
+ }
+
+ void SelectionManagerWidget::_removeFromSelected( void )
+ {
+
+ auto selectedIndices =
+ _listViewSelected->selectionModel( )->selectedIndexes( );
+
+ for( auto index : selectedIndices )
+ {
+ if( index.row( ) < 0 )
+ continue;
+
+ auto item = _modelSelected->itemFromIndex( index );
+ unsigned int gid = item->data( Qt::DisplayRole ).toUInt( );
+
+ _gidsSelected.erase( gid );
+ _gidsAvailable.insert( gid );
+
+ auto gidIndex = _gidIndex.find( gid );
+ assert( gidIndex != _gidIndex.end( ));
+
+ _listViewAvailable->setRowHidden( gidIndex->second, false );
+ _listViewSelected->setRowHidden( gidIndex->second, true );
+
+ }
+
+ _listViewSelected->selectionModel( )->clearSelection( );
+
+ _updateListsLabelNumbers( );
+ }
+
+ void SelectionManagerWidget::_saveToFile( const QString& filePath,
+ const QString& separator,
+ const QString& prefix,
+ const QString& suffix )
+ {
+ QFile file;
+
+ if( file.exists( filePath ))
+ {
+
+ QMessageBox msgBox( this );
+ msgBox.setText( "The selected file already exists." );
+ msgBox.setInformativeText( "Do you want to overwrite?" );
+ msgBox.setStandardButtons( QMessageBox::Save | QMessageBox::Cancel );
+ msgBox.setDefaultButton( QMessageBox::Save );
+ int ret = msgBox.exec( );
+
+ if((( QMessageBox::StandardButton ) ret ) == QMessageBox::Cancel )
+ return;
+ }
+
+ file.setFileName( filePath );
+ file.open( QFile::WriteOnly | QFile::Truncate );
+ QTextStream outStream( &file );
+
+ GIDVec gids( _gidsSelected.size( ));
+ std::copy( _gidsSelected.begin( ), _gidsSelected.end( ), gids.begin( ));
+ std::sort( gids.begin( ), gids.end( ));
+
+ for( auto gid : gids )
+ {
+ outStream << prefix << gid << suffix << separator;
+ }
+
+ file.close( );
+
+ QMessageBox::information( this, QString( "Save successful" ), QString( "Selection saved to file." ));
+
+ }
+
+ void SelectionManagerWidget::_buttonAcceptClicked( void )
+ {
+ this->close( );
+
+ emit selectionChanged( );
+ }
+
+ void SelectionManagerWidget::_buttonCancelClicked( void )
+ {
+ this->close( );
+ }
+
+ void SelectionManagerWidget::_buttonBrowseClicked( void )
+ {
+ QString path = QFileDialog::getSaveFileName(
+ this, tr( "Save to file" ), _lineEditFilePath->text( ),
+ tr( "Text files (.txt);;All files (*)" ),
+ nullptr, QFileDialog::DontUseNativeDialog );
+
+ if( !path.isEmpty( ))
+ _lineEditFilePath->setText( path );
+ }
+
+ void SelectionManagerWidget::_buttonSaveClicked( void )
+ {
+ QString separator;
+ if( _radioNewLine->isChecked( ))
+ separator = "\n";
+ else if( _radioSpace->isChecked( ))
+ separator = " ";
+ else if( _radioTab->isChecked( ))
+ separator = "\t";
+ else
+ separator = _lineEditSeparator->text( );
+
+ _saveToFile( _lineEditFilePath->text( ), separator,
+ _lineEditPrefix->text( ), _lineEditSuffix->text( ));
+
+ }
+
+}
diff --git a/visimpl/SelectionManagerWidget.h b/visimpl/SelectionManagerWidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..d713d0ad7b4f72b444387e6565262f25e373ace9
--- /dev/null
+++ b/visimpl/SelectionManagerWidget.h
@@ -0,0 +1,130 @@
+/*
+ * @file SelectionManagerWidget.h
+ * @brief
+ * @author Sergio E. Galindo <sergio.galindo@urjc.es>
+ * @date
+ * @remarks Copyright (c) GMRV/URJC. All rights reserved.
+ * Do not distribute without further notice.
+ */
+
+#ifndef SELECTIONMANAGERWIDGET_H_
+#define SELECTIONMANAGERWIDGET_H_
+
+#include <QListView>
+#include <QStandardItemModel>
+#include <QPushButton>
+#include <QLineEdit>
+#include <QRadioButton>
+
+#include <unordered_set>
+
+#include "types.h"
+
+namespace visimpl
+{
+
+ class SelectionManagerWidget : public QWidget
+ {
+ Q_OBJECT;
+
+ public:
+
+ enum TSeparator
+ {
+ TSEP_NEWLINE = 0,
+ TSEP_SPACE,
+ TSEP_TAB,
+ TSEP_OTHER
+ };
+
+ SelectionManagerWidget( QWidget* parent = 0 );
+ ~SelectionManagerWidget( void );
+
+ void init( void );
+
+ void setGIDs( const TGIDSet& all_,
+ const TGIDUSet& selected_ = { });
+
+ void setSelected( const TGIDUSet& selected_ );
+ const TGIDUSet& selected( void ) const;
+
+ void clearSelection( void );
+
+ signals:
+
+ void selectionChanged( void );
+
+ protected slots:
+
+ void _addToSelected( void );
+ void _removeFromSelected( void );
+
+ void _buttonBrowseClicked( void );
+ void _buttonSaveClicked( void );
+
+ void _buttonCancelClicked( void );
+ void _buttonAcceptClicked( void );
+
+
+ protected:
+
+ void _initTabSelection( void );
+ void _initTabExport( void );
+
+ void _fillLists( void );
+ void _reloadLists( void );
+
+ void _updateListsLabelNumbers( void );
+
+ void _saveToFile( const QString& filePath,
+ const QString& separator = "\n",
+ const QString& prefix = "",
+ const QString& suffix = "" );
+
+
+ TGIDUSet _gidsAll;
+ TGIDUSet _gidsSelected;
+ TGIDUSet _gidsAvailable;
+
+ QTabWidget* _tabWidget;
+
+ // Selection tab
+
+ QListView* _listViewAvailable;
+ QListView* _listViewSelected;
+
+ QStandardItemModel* _modelAvailable;
+ QStandardItemModel* _modelSelected;
+
+ QPushButton* _buttonAddToSelection;
+ QPushButton* _buttonRemoveFromSelection;
+
+ QLabel* _labelAvailable;
+ QLabel* _labelSelection;
+
+ TUIntUintMap _gidIndex;
+
+ // Export tab
+
+ QLineEdit* _lineEditFilePath;
+ QLineEdit* _lineEditPrefix;
+ QLineEdit* _lineEditSuffix;
+ QLineEdit* _lineEditSeparator;
+
+ QRadioButton* _radioNewLine;
+ QRadioButton* _radioSpace;
+ QRadioButton* _radioTab;
+ QRadioButton* _radioOther;
+
+ QPushButton* _buttonBrowse;
+ QPushButton* _buttonSave;
+
+ QString _pathExportDefault;
+
+ };
+
+}
+
+
+
+#endif /* SELECTIONMANAGERWIDGET_H_ */
diff --git a/visimpl/render/Plane.cpp b/visimpl/render/Plane.cpp
index 905ae93ff309ccb1c02f3bed9e8f1509d7f1cd7d..a9d43a217204f31c76d9a6cdc395aaf8c790aef0 100644
--- a/visimpl/render/Plane.cpp
+++ b/visimpl/render/Plane.cpp
@@ -80,6 +80,11 @@ namespace visimpl
glBindVertexArray( 0 );
}
+ const std::vector< evec3 >& Plane::points( void ) const
+ {
+ return _points;
+ }
+
void Plane::render( reto::ShaderProgram* program_ )
{
assert( _camera );
diff --git a/visimpl/render/Plane.h b/visimpl/render/Plane.h
index 2c017adf6aa9dffcfcf28839023c2689fd56cda2..a3e2698bebae3d63f4c58dcbc75130e903b9e31d 100644
--- a/visimpl/render/Plane.h
+++ b/visimpl/render/Plane.h
@@ -23,6 +23,8 @@ namespace visimpl
void points( evec3 first, evec3 second, evec3 third, evec3 fourth );
+ const std::vector< evec3 >& points( void ) const;
+
void init( reto::Camera* camera );
void render( reto::ShaderProgram* program_ );