2018-11-04 23:31:48 +01:00
//##########################################################################
//# #
//# CLOUDCOMPARE PLUGIN: qCANUPO #
//# #
//# This program is free software; you can redistribute it and/or modify #
//# it under the terms of the GNU General Public License as published by #
//# the Free Software Foundation; version 2 or later of the License. #
//# #
//# This program is distributed in the hope that it will be useful, #
//# but WITHOUT ANY WARRANTY; without even the implied warranty of #
//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
//# GNU General Public License for more details. #
//# #
//# COPYRIGHT: UNIVERSITE EUROPEENNE DE BRETAGNE #
//# #
//##########################################################################
# include "qClassify3DMASCDialog.h"
//qCC_plugins
2020-06-04 00:32:27 +02:00
# include <ccMainAppInterface.h>
2018-11-04 23:31:48 +01:00
//qCC_db
# include <ccPointCloud.h>
//Qt
# include <QMainWindow>
# include <QPushButton>
# include <QComboBox>
2023-03-27 22:52:23 +02:00
# include <QSettings>
2018-11-04 23:31:48 +01:00
static ccPointCloud * GetCloudFromCombo ( QComboBox * comboBox , ccHObject * dbRoot )
{
assert ( comboBox & & dbRoot ) ;
if ( ! comboBox | | ! dbRoot )
{
assert ( false ) ;
return 0 ;
}
//return the cloud currently selected in the combox box
int index = comboBox - > currentIndex ( ) ;
if ( index < 0 )
{
assert ( false ) ;
return 0 ;
}
unsigned uniqueID = comboBox - > itemData ( index ) . toUInt ( ) ;
ccHObject * item = dbRoot - > find ( uniqueID ) ;
if ( ! item | | ! item - > isA ( CC_TYPES : : POINT_CLOUD ) )
{
assert ( false ) ;
return 0 ;
}
return static_cast < ccPointCloud * > ( item ) ;
}
2019-01-21 00:10:47 +01:00
Classify3DMASCDialog : : Classify3DMASCDialog ( ccMainAppInterface * app , bool trainMode /*=false*/ )
2018-11-04 23:31:48 +01:00
: QDialog ( app ? app - > getMainWindow ( ) : 0 )
, Ui : : Classify3DMASCDialog ( )
, m_app ( app )
{
setupUi ( this ) ;
if ( m_app )
{
//add list of clouds to the combo-boxes
ccHObject : : Container clouds ;
if ( m_app - > dbRootObject ( ) )
{
2024-02-20 08:57:19 +01:00
m_app - > dbRootObject ( ) - > filterChildren ( clouds , true , CC_TYPES : : POINT_CLOUD , true ) ;
2018-11-04 23:31:48 +01:00
}
unsigned cloudCount = 0 ;
for ( size_t i = 0 ; i < clouds . size ( ) ; + + i )
{
2024-02-20 08:57:19 +01:00
QString name = clouds [ i ] - > getName ( ) + QString ( " [%1] " ) . arg ( clouds [ i ] - > getUniqueID ( ) ) ;
QVariant uniqueID ( clouds [ i ] - > getUniqueID ( ) ) ;
cloud1ComboBox - > addItem ( name , uniqueID ) ;
cloud2ComboBox - > addItem ( name , uniqueID ) ;
cloud3ComboBox - > addItem ( name , uniqueID ) ;
cloud4ComboBox - > addItem ( name , uniqueID ) ;
testCloudComboBox - > addItem ( name , uniqueID ) ;
+ + cloudCount ;
2018-11-04 23:31:48 +01:00
}
2024-02-16 17:14:54 +01:00
testCloudComboBox - > addItem ( " " , 0 ) ;
2024-02-19 10:57:05 +01:00
//if 3 clouds are loaded, then there's chances that the first one is the global cloud!
2019-03-26 14:28:27 +01:00
cloud1ComboBox - > setCurrentIndex ( /*cloudCount > 0 ? (cloudCount > 2 ? 1 : 0) : */ - 1 ) ;
connect ( cloud1ComboBox , SIGNAL ( currentIndexChanged ( int ) ) , this , SLOT ( onCloudChanged ( int ) ) ) ;
cloud2ComboBox - > setCurrentIndex ( /*cloudCount > 1 ? (cloudCount > 2 ? 2 : 1) : */ - 1 ) ;
connect ( cloud2ComboBox , SIGNAL ( currentIndexChanged ( int ) ) , this , SLOT ( onCloudChanged ( int ) ) ) ;
cloud3ComboBox - > setCurrentIndex ( /*cloudCount > 2 ? 0 : */ - 1 ) ;
connect ( cloud3ComboBox , SIGNAL ( currentIndexChanged ( int ) ) , this , SLOT ( onCloudChanged ( int ) ) ) ;
2019-03-29 13:40:57 +01:00
cloud4ComboBox - > setCurrentIndex ( /*cloudCount > 3 ? 0 : */ - 1 ) ;
connect ( cloud4ComboBox , SIGNAL ( currentIndexChanged ( int ) ) , this , SLOT ( onCloudChanged ( int ) ) ) ;
2019-03-25 18:45:28 +01:00
testCloudComboBox - > setCurrentIndex ( - 1 ) ;
2018-11-04 23:31:48 +01:00
if ( cloudCount = = 0 & & app )
{
2019-01-21 00:10:47 +01:00
app - > dispToConsole ( QString ( " You need at least 1 loaded cloud to " ) + ( trainMode ? " train a classifier " : " classify it... " ) , ccMainAppInterface : : ERR_CONSOLE_MESSAGE ) ;
2018-11-04 23:31:48 +01:00
}
}
2019-01-21 00:10:47 +01:00
if ( trainMode )
{
label - > setText ( tr ( " Trainer file " ) ) ;
warningLabel - > setVisible ( false ) ;
2022-10-17 17:33:15 +02:00
warningLabel - > setText ( " Assign each role to the right cloud, and select the cloud on which to train the classifier " ) ;
2019-01-21 00:10:47 +01:00
}
2018-11-04 23:31:48 +01:00
onCloudChanged ( 0 ) ;
2023-06-01 09:54:11 +02:00
readSettings ( ) ;
}
Classify3DMASCDialog : : ~ Classify3DMASCDialog ( )
{
writeSettings ( ) ;
2018-11-04 23:31:48 +01:00
}
2023-03-27 22:52:23 +02:00
void Classify3DMASCDialog : : readSettings ( )
{
QSettings settings ;
settings . beginGroup ( " 3DMASC " ) ;
bool keepAttributes = settings . value ( " keepAttributes " , false ) . toBool ( ) ;
this - > keepAttributesCheckBox - > setChecked ( keepAttributes ) ;
}
void Classify3DMASCDialog : : writeSettings ( )
{
QSettings settings ;
settings . beginGroup ( " 3DMASC " ) ;
settings . setValue ( " keepAttributes " , keepAttributesCheckBox - > isChecked ( ) ) ;
}
2024-02-20 08:57:19 +01:00
void Classify3DMASCDialog : : setComboBoxIndex ( const QMap < QString , QString > & rolesAndNames , QLabel * label , const QMap < QString , QVariant > & namesAndUniqueIds , QComboBox * comboBox )
2024-02-16 17:14:54 +01:00
{
2024-02-20 08:57:19 +01:00
QString name = label = = testLabel ? QString ( " TEST " ) : label - > text ( ) ; // testLabel is specific, the role is always TEST
2024-02-16 17:14:54 +01:00
2024-02-20 08:57:19 +01:00
QMap < QString , QVariant > : : const_iterator it ( namesAndUniqueIds . find ( name ) ) ;
2024-02-16 17:14:54 +01:00
if ( it ! = namesAndUniqueIds . end ( ) )
{
int index = comboBox - > findData ( it . value ( ) ) ;
if ( index ! = - 1 )
{
comboBox - > setCurrentIndex ( index ) ;
}
}
}
void Classify3DMASCDialog : : setCloudRoles ( const QList < QString > & roles , QString & corePointsLabel , const QMap < QString , QString > & rolesAndNames )
2018-11-04 23:31:48 +01:00
{
int index = 0 ;
for ( const QString & role : roles )
{
2024-02-16 17:14:54 +01:00
if ( role ! = " TEST " )
2018-11-04 23:31:48 +01:00
{
2024-02-16 17:14:54 +01:00
switch ( index )
{
case 0 :
cloud1Label - > setText ( role ) ;
if ( corePointsLabel . isEmpty ( ) ) // if "core_points:" is not in the parameter file, the corePointsLabel is the first encountered role
{
corePointsLabel = role ;
}
break ;
case 1 :
cloud2Label - > setText ( role ) ;
break ;
case 2 :
cloud3Label - > setText ( role ) ;
break ;
case 3 :
cloud4Label - > setText ( role ) ;
break ;
default :
//this dialog can't handle more than 3 roles!
break ;
}
+ + index ;
2018-11-04 23:31:48 +01:00
}
2018-11-05 00:11:27 +01:00
}
if ( index < 1 )
{
cloud1ComboBox - > setEnabled ( false ) ;
}
if ( index < 2 )
{
2022-10-27 09:19:52 +02:00
cloud2ComboBox - > setEnabled ( false ) ;
2018-11-05 00:11:27 +01:00
cloud2ComboBox - > setVisible ( false ) ;
2022-10-17 09:28:14 +02:00
cloud2Label - > setVisible ( false ) ;
2018-11-05 00:11:27 +01:00
}
if ( index < 3 )
{
2022-10-27 09:19:52 +02:00
cloud3ComboBox - > setEnabled ( false ) ;
2018-11-05 00:11:27 +01:00
cloud3ComboBox - > setVisible ( false ) ;
2022-10-17 09:28:14 +02:00
cloud3Label - > setVisible ( false ) ;
2018-11-04 23:31:48 +01:00
}
2019-03-29 13:40:57 +01:00
if ( index < 4 )
{
2022-10-27 09:19:52 +02:00
cloud4ComboBox - > setEnabled ( false ) ;
2019-03-29 13:40:57 +01:00
cloud4ComboBox - > setVisible ( false ) ;
2022-10-17 09:28:14 +02:00
cloud4Label - > setVisible ( false ) ;
2019-03-29 13:40:57 +01:00
}
2024-02-16 17:14:54 +01:00
// now we will try to preset the combo boxes depending on the names which are in the parameter file
QMap < QString , QVariant > namesAndUniqueIds ;
// build a map 'name : uniqueId' of the available clouds in the database tree (duplicate names are not handled, simply keep the first occurrence)
ccHObject : : Container clouds ;
if ( m_app - > dbRootObject ( ) )
{
m_app - > dbRootObject ( ) - > filterChildren ( clouds , true , CC_TYPES : : POINT_CLOUD ) ;
}
for ( size_t i = 0 ; i < clouds . size ( ) ; + + i )
{
2024-02-20 08:57:19 +01:00
if ( clouds [ i ] - > isA ( CC_TYPES : : POINT_CLOUD ) ) //as filterChildren only tests 'isKindOf'
2024-02-16 17:14:54 +01:00
{
QVariant uniqueID ( clouds [ i ] - > getUniqueID ( ) ) ;
namesAndUniqueIds [ clouds [ i ] - > getName ( ) . toUpper ( ) ] = uniqueID ;
}
}
// preset the combo boxes if possible
setComboBoxIndex ( rolesAndNames , cloud1Label , namesAndUniqueIds , cloud1ComboBox ) ;
setComboBoxIndex ( rolesAndNames , cloud2Label , namesAndUniqueIds , cloud2ComboBox ) ;
setComboBoxIndex ( rolesAndNames , cloud3Label , namesAndUniqueIds , cloud3ComboBox ) ;
setComboBoxIndex ( rolesAndNames , cloud4Label , namesAndUniqueIds , cloud4ComboBox ) ;
setComboBoxIndex ( rolesAndNames , testLabel , namesAndUniqueIds , testCloudComboBox ) ;
2018-11-04 23:31:48 +01:00
}
2022-10-27 09:19:52 +02:00
void Classify3DMASCDialog : : getClouds ( QMap < QString , ccPointCloud * > & clouds ) const
2018-11-04 23:31:48 +01:00
{
if ( ! m_app )
{
assert ( false ) ;
return ;
}
2022-10-25 16:47:19 +02:00
if ( cloud1ComboBox - > isEnabled ( ) )
2018-11-04 23:31:48 +01:00
{
2022-10-17 09:28:14 +02:00
clouds . insert ( cloud1Label - > text ( ) , GetCloudFromCombo ( cloud1ComboBox , m_app - > dbRootObject ( ) ) ) ;
2018-11-04 23:31:48 +01:00
}
2024-02-16 17:14:54 +01:00
2022-10-27 09:19:52 +02:00
if ( cloud2ComboBox - > isEnabled ( ) )
2018-11-04 23:31:48 +01:00
{
2022-10-17 09:28:14 +02:00
clouds . insert ( cloud2Label - > text ( ) , GetCloudFromCombo ( cloud2ComboBox , m_app - > dbRootObject ( ) ) ) ;
2018-11-04 23:31:48 +01:00
}
2024-02-16 17:14:54 +01:00
2022-10-27 09:19:52 +02:00
if ( cloud3ComboBox - > isEnabled ( ) )
2018-11-04 23:31:48 +01:00
{
2022-10-17 09:28:14 +02:00
clouds . insert ( cloud3Label - > text ( ) , GetCloudFromCombo ( cloud3ComboBox , m_app - > dbRootObject ( ) ) ) ;
2018-11-04 23:31:48 +01:00
}
2024-02-16 17:14:54 +01:00
2022-10-27 09:19:52 +02:00
if ( cloud4ComboBox - > isEnabled ( ) )
2019-03-29 13:40:57 +01:00
{
2022-10-17 09:28:14 +02:00
clouds . insert ( cloud4Label - > text ( ) , GetCloudFromCombo ( cloud4ComboBox , m_app - > dbRootObject ( ) ) ) ;
2019-03-29 13:40:57 +01:00
}
2024-02-16 17:14:54 +01:00
2019-03-25 18:45:28 +01:00
if ( testCloudComboBox - > currentIndex ( ) > = 0 )
{
clouds . insert ( " TEST " , GetCloudFromCombo ( testCloudComboBox , m_app - > dbRootObject ( ) ) ) ;
}
2018-11-04 23:31:48 +01:00
}
void Classify3DMASCDialog : : onCloudChanged ( int dummy )
{
2022-10-25 16:47:19 +02:00
if ( ! cloud1ComboBox - > isEnabled ( ) )
2018-11-04 23:31:48 +01:00
{
//this means that no role has been defined yet
buttonBox - > button ( QDialogButtonBox : : Ok ) - > setEnabled ( false ) ;
return ;
}
buttonBox - > button ( QDialogButtonBox : : Ok ) - > setEnabled ( cloud1ComboBox - > currentIndex ( ) > = 0 ) ;
}