Try to fill in the qClassify3DMASCDialog if names are available in the parameter file and clouds exist in the database tree with the same name (case insensitive)

Code cleaning
This commit is contained in:
Paul Leroy
2024-02-16 17:14:54 +01:00
parent 992f5d4c8c
commit 7087b899f4
8 changed files with 100 additions and 70 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ if (PLUGIN_STANDARD_3DMASC)
project( Q3DMASC_PLUGIN )
AddPlugin( NAME ${PROJECT_NAME} )
set(Q3DMASC_PLUGIN_VERSION "1.0")
set(Q3DMASC_PLUGIN_VERSION "1.0+")
include( CMakePolicies NO_POLICY_SCOPE )
+4 -4
View File
@@ -65,14 +65,14 @@
<item row="4" column="0">
<widget class="QLabel" name="cloud2Label">
<property name="text">
<string>PC2</string>
<string>-</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="cloud3Label">
<property name="text">
<string>CTX</string>
<string>-</string>
</property>
</widget>
</item>
@@ -112,14 +112,14 @@
<item row="3" column="0">
<widget class="QLabel" name="cloud1Label">
<property name="text">
<string>PC1</string>
<string>-</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="cloud4Label">
<property name="text">
<string>PCX</string>
<string>-</string>
</property>
</widget>
</item>
+6 -4
View File
@@ -120,7 +120,8 @@ void q3DMASCPlugin::doClassifyAction()
QList<QString> cloudLabels;
QString corePointsLabel;
bool filenamesSpecified = false;
if (!masc::Tools::LoadClassifierCloudLabels(inputFilename, cloudLabels, corePointsLabel, filenamesSpecified))
QMap<QString, QString> labelMapName;
if (!masc::Tools::LoadClassifierCloudLabels(inputFilename, cloudLabels, corePointsLabel, filenamesSpecified, labelMapName))
{
m_app->dispToConsole("Failed to read classifier file (see Console)", ccMainAppInterface::ERR_CONSOLE_MESSAGE);
return;
@@ -138,7 +139,7 @@ void q3DMASCPlugin::doClassifyAction()
//now show a dialog where the user will be able to set the cloud roles
Classify3DMASCDialog classifDlg(m_app);
classifDlg.setCloudRoles(cloudLabels, corePointsLabel);
classifDlg.setCloudRoles(cloudLabels, corePointsLabel, labelMapName);
classifDlg.label_trainOrClassify->setText(corePointsLabel + " will be classified");
classifDlg.classifierFileLineEdit->setText(inputFilename);
classifDlg.testCloudComboBox->hide();
@@ -260,7 +261,8 @@ void q3DMASCPlugin::doTrainAction()
QList<QString> cloudLabels;
QString corePointsLabel;
bool filenamesSpecified = false;
if (!masc::Tools::LoadClassifierCloudLabels(inputFilename, cloudLabels, corePointsLabel, filenamesSpecified))
QMap<QString, QString> rolesAndNames;
if (!masc::Tools::LoadClassifierCloudLabels(inputFilename, cloudLabels, corePointsLabel, filenamesSpecified, rolesAndNames))
{
m_app->dispToConsole("Failed to read classifier file (see Console)", ccMainAppInterface::ERR_CONSOLE_MESSAGE);
return;
@@ -288,7 +290,7 @@ void q3DMASCPlugin::doTrainAction()
//now show a dialog where the user will be able to set the cloud roles
Classify3DMASCDialog classifDlg(m_app, true);
classifDlg.setWindowTitle("3DMASC Train");
classifDlg.setCloudRoles(cloudLabels, corePointsLabel);
classifDlg.setCloudRoles(cloudLabels, corePointsLabel, rolesAndNames);
classifDlg.label_trainOrClassify->setText("The classifier will be trained on " + corePointsLabel);
classifDlg.classifierFileLineEdit->setText(inputFilename);
classifDlg.keepAttributesCheckBox->hide(); // this parameter is set in the trainDlg dialog
+2 -1
View File
@@ -165,7 +165,8 @@ struct Command3DMASCClassif : public ccCommandLineInterface::Command
QList<QString> cloudLabels;
QString corePointsLabel;
bool filenamesSpecified = false;
if (!masc::Tools::LoadClassifierCloudLabels(classifierFilename, cloudLabels, corePointsLabel, filenamesSpecified))
QMap<QString, QString> labelsAndNames;
if (!masc::Tools::LoadClassifierCloudLabels(classifierFilename, cloudLabels, corePointsLabel, filenamesSpecified, labelsAndNames))
{
return cmd.error("Failed to read classifier file");
}
+3 -1
View File
@@ -112,11 +112,12 @@ bool Tools::SaveClassifier( QString filename,
return true;
}
bool Tools::LoadClassifierCloudLabels(QString filename, QList<QString>& labels, QString& corePointsLabel, bool& filenamesSpecified)
bool Tools::LoadClassifierCloudLabels(QString filename, QList<QString>& labels, QString& corePointsLabel, bool& filenamesSpecified, QMap<QString, QString>& labelsAndNames)
{
//just in case
corePointsLabel.clear();
labels.clear();
labelsAndNames.clear();
QFile file(filename);
if (!file.open(QFile::Text | QFile::ReadOnly))
@@ -155,6 +156,7 @@ bool Tools::LoadClassifierCloudLabels(QString filename, QList<QString>& labels,
return false;
}
labels.push_back(label);
labelsAndNames[label] = tokens.back();
if (tokens.size() > 1)
++filenameCount;
+1 -1
View File
@@ -40,7 +40,7 @@ namespace masc
static bool LoadTrainingFile(QString filename, Feature::Set& rawFeatures, std::vector<double>& scales, NamedClouds& loadedClouds, TrainParameters& parameters, CorePoints* corePoints = nullptr, QWidget* parent = nullptr);
static bool LoadClassifierCloudLabels(QString filename, QList<QString>& labels, QString& corePointsLabel, bool& filenamesSpecified);
static bool LoadClassifierCloudLabels(QString filename, QList<QString>& labels, QString& corePointsLabel, bool& filenamesSpecified, QMap<QString, QString>& labelsAndNames);
static bool LoadClassifier(QString filename, NamedClouds& clouds, Feature::Set& rawFeatures, masc::Classifier& classifier, QWidget* parent = nullptr);
+79 -57
View File
@@ -28,10 +28,7 @@
#include <QPushButton>
#include <QComboBox>
#include <QSettings>
//#include <QApplication>
//system
#include <limits>
static ccPointCloud* GetCloudFromCombo(QComboBox* comboBox, ccHObject* dbRoot)
{
@@ -91,6 +88,8 @@ Classify3DMASCDialog::Classify3DMASCDialog(ccMainAppInterface* app, bool trainMo
}
}
testCloudComboBox->addItem("", 0);
//if 3 clouds are loaded, then there's chances that the first one is the global cloud!
cloud1ComboBox->setCurrentIndex(/*cloudCount > 0 ? (cloudCount > 2 ? 1 : 0) : */-1);
connect(cloud1ComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onCloudChanged(int)));
@@ -140,70 +139,109 @@ void Classify3DMASCDialog::writeSettings()
settings.setValue("keepAttributes", keepAttributesCheckBox->isChecked());
}
void Classify3DMASCDialog::setCloudRoles(const QList<QString>& roles, QString corePointsLabel)
void Classify3DMASCDialog::setComboBoxIndex(QMap<QString, QString> rolesAndNames, QLabel* label, QMap<QString, QVariant> namesAndUniqueIds, QComboBox* comboBox)
{
QString name;
if (label != testLabel)
{
name = rolesAndNames[label->text()];
}
else
{
name = rolesAndNames[QString("TEST")]; // this is because the label text of testLabel is 'TEST on (optional)'
}
QMap<QString, QVariant>::iterator it = namesAndUniqueIds.find(name);
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)
{
int index = 0;
for (const QString& role : roles)
{
switch (index)
if (role != "TEST")
{
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;
// cloud1RadioButton->setChecked(true);
break;
case 1:
cloud2Label->setText(role);
if (corePointsLabel == role)
// cloud2RadioButton->setChecked(true);
break;
case 2:
cloud3Label->setText(role);
if (corePointsLabel == role)
// cloud3RadioButton->setChecked(true);
break;
case 3:
cloud4Label->setText(role);
if (corePointsLabel == role)
// cloud4RadioButton->setChecked(true);
break;
default:
//this dialog can't handle more than 3 roles!
break;
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;
}
++index;
}
if (index < 1)
{
// cloud1RadioButton->setEnabled(false);
cloud1ComboBox->setEnabled(false);
}
if (index < 2)
{
// cloud2RadioButton->setEnabled(false);
// cloud2RadioButton->setVisible(false);
cloud2ComboBox->setEnabled(false);
cloud2ComboBox->setVisible(false);
cloud2Label->setVisible(false);
}
if (index < 3)
{
// cloud3RadioButton->setEnabled(false);
// cloud3RadioButton->setVisible(false);
cloud3ComboBox->setEnabled(false);
cloud3ComboBox->setVisible(false);
cloud3Label->setVisible(false);
}
if (index < 4)
{
// cloud4RadioButton->setEnabled(false);
// cloud4RadioButton->setVisible(false);
cloud4ComboBox->setEnabled(false);
cloud4ComboBox->setVisible(false);
cloud4Label->setVisible(false);
}
// 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)
{
if (clouds[i]->isA(CC_TYPES::POINT_CLOUD)) //as filterChildren only test 'isKindOf'
{
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);
}
void Classify3DMASCDialog::getClouds(QMap<QString, ccPointCloud*>& clouds) const
@@ -214,42 +252,26 @@ void Classify3DMASCDialog::getClouds(QMap<QString, ccPointCloud*>& clouds) const
return;
}
// if (cloud1RadioButton->isEnabled())
if (cloud1ComboBox->isEnabled())
{
clouds.insert(cloud1Label->text(), GetCloudFromCombo(cloud1ComboBox, m_app->dbRootObject()));
// if (cloud1RadioButton->isChecked())
// {
// mainCloud = cloud1Label->text();
// }
}
// if (cloud2RadioButton->isEnabled())
if (cloud2ComboBox->isEnabled())
{
clouds.insert(cloud2Label->text(), GetCloudFromCombo(cloud2ComboBox, m_app->dbRootObject()));
// if (cloud2RadioButton->isChecked())
// {
// mainCloud = cloud2Label->text();
// }
}
// if (cloud3RadioButton->isEnabled())
if (cloud3ComboBox->isEnabled())
{
clouds.insert(cloud3Label->text(), GetCloudFromCombo(cloud3ComboBox, m_app->dbRootObject()));
// if (cloud3RadioButton->isChecked())
// {
// mainCloud = cloud3Label->text();
// }
}
// if (cloud4RadioButton->isEnabled())
if (cloud4ComboBox->isEnabled())
{
clouds.insert(cloud4Label->text(), GetCloudFromCombo(cloud4ComboBox, m_app->dbRootObject()));
// if (cloud4RadioButton->isChecked())
// {
// mainCloud = cloud4Label->text();
// }
}
if (testCloudComboBox->currentIndex() >= 0)
{
clouds.insert("TEST", GetCloudFromCombo(testCloudComboBox, m_app->dbRootObject()));
+4 -1
View File
@@ -42,7 +42,10 @@ public:
void writeSettings();
//! Sets the clouds roles
void setCloudRoles(const QList<QString>& roles, QString corePointsLabel);
void setCloudRoles(const QList<QString>& roles, QString &corePointsLabel, const QMap<QString, QString> &rolesAndNames);
//! Preset the combo boxes if possible with the names specified in the parameter file
void setComboBoxIndex(QMap<QString, QString> rolesAndNames, QLabel* label, QMap<QString, QVariant> namesAndUniqueIds, QComboBox* comboBox);
//! Returns the selected point clouds
void getClouds(QMap<QString, ccPointCloud*>& clouds) const;