clean function in progress, code cleaning
This commit is contained in:
+16
-6
@@ -20,6 +20,7 @@ class G3PointAction : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
typedef Eigen::Array<bool, Eigen::Dynamic, Eigen::Dynamic> XXb;
|
||||
typedef Eigen::Array<bool, Eigen::Dynamic, Eigen::Dynamic> Xb;
|
||||
|
||||
public:
|
||||
explicit G3PointAction(ccPointCloud *cloud, ccMainAppInterface *app=nullptr);
|
||||
@@ -27,8 +28,14 @@ public:
|
||||
static void createAction(ccMainAppInterface *appInterface);
|
||||
static void GetG3PointAction(ccPointCloud *cloud, ccMainAppInterface *app=nullptr);
|
||||
void segment();
|
||||
void segmentCluster();
|
||||
void segmentAndCluster();
|
||||
void segmentAndClusterAndClean();
|
||||
void getBorders();
|
||||
int cluster();
|
||||
bool processNewStacks(std::vector<std::vector<int>>& stacks);
|
||||
bool merge(XXb& condition);
|
||||
bool keepLabels(Xb& condition);
|
||||
bool cleanLabels();
|
||||
void clean();
|
||||
|
||||
private:
|
||||
@@ -36,11 +43,11 @@ private:
|
||||
void add_to_stack(int index, const Eigen::ArrayXi& n_donors, const Eigen::ArrayXXi& donors, std::vector<int>& stack);
|
||||
int segment_labels(bool useParallelStrategy=true);
|
||||
double angle_rot_2_vec_mat(const Eigen::Vector3d &a, const Eigen::Vector3d &b);
|
||||
Eigen::ArrayXXd compute_mean_angle();
|
||||
bool export_local_maxima_as_cloud();
|
||||
bool update_local_maximum_indexes();
|
||||
bool update_labels_and_colors();
|
||||
bool check_stacks(const std::vector<std::vector<int>>& stacks, int count);
|
||||
Eigen::ArrayXXd computeMeanAngle();
|
||||
bool exportLocalMaximaAsCloud();
|
||||
bool updateLocalMaximumIndexes();
|
||||
bool updateLabelsAndColors();
|
||||
bool checkStacks(const std::vector<std::vector<int>>& stacks, int count);
|
||||
int segment_labels_steepest_slope(bool useParallelStrategy=true);
|
||||
void add_to_stack_braun_willett(int index, const Eigen::ArrayXi& delta, const Eigen::ArrayXi &Di, std::vector<int>& stack, int local_maximum);
|
||||
int segment_labels_braun_willett(bool useParallelStrategy=true);
|
||||
@@ -58,6 +65,9 @@ private:
|
||||
int m_kNN = 20;
|
||||
double m_radiusFactor = 0.6;
|
||||
double m_maxAngle1 = 60;
|
||||
double m_maxAngle2 = 10;
|
||||
int m_nMin = 50;
|
||||
double m_minFlatness = 0.1;
|
||||
|
||||
ccPointCloud* m_cloud;
|
||||
ccMainAppInterface *m_app;
|
||||
|
||||
@@ -14,20 +14,33 @@ class G3PointDialog : public QDialog
|
||||
public:
|
||||
explicit G3PointDialog(QString cloudName, QWidget *parent = nullptr);
|
||||
~G3PointDialog();
|
||||
|
||||
void emitSegment(){emit segment();}
|
||||
void emitCluster(){emit cluster();}
|
||||
void emitSegmentCluster(){emit segmentCluster();}
|
||||
void emitClean(){emit clean();}
|
||||
void emitSegmentClusterClean(){emit segmentClusterClean();}
|
||||
void emitGetBorders(){emit getBorders();}
|
||||
|
||||
double getMaxAngle1();
|
||||
double getMaxAngle2();
|
||||
double getMinFlatness();
|
||||
int getNMin();
|
||||
int getkNN();
|
||||
int getPointSize();
|
||||
double getRadiusFactor();
|
||||
|
||||
bool isSteepestSlope();
|
||||
void enableCluster(bool state);
|
||||
void enableClean(bool state);
|
||||
|
||||
signals:
|
||||
void segment();
|
||||
void cluster();
|
||||
void segmentCluster();
|
||||
void clean();
|
||||
void segmentClusterClean();
|
||||
void getBorders();
|
||||
|
||||
private:
|
||||
Ui::qG3PointDialog *ui;
|
||||
|
||||
+291
-30
@@ -15,6 +15,7 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QThreadPool>
|
||||
#include <QtConcurrent>
|
||||
#include <QApplication>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
@@ -333,7 +334,7 @@ double G3PointAction::angle_rot_2_vec_mat(const Eigen::Vector3d& a, const Eigen:
|
||||
return angle;
|
||||
}
|
||||
|
||||
Eigen::ArrayXXd G3PointAction::compute_mean_angle()
|
||||
Eigen::ArrayXXd G3PointAction::computeMeanAngle()
|
||||
{
|
||||
// Find the indexborder nodes (no donor and many other labels in the neighbourhood)
|
||||
Eigen::ArrayXXi duplicated_labels(m_cloud->size(), m_kNN);
|
||||
@@ -419,7 +420,7 @@ Eigen::ArrayXXd G3PointAction::compute_mean_angle()
|
||||
return Aangle;
|
||||
}
|
||||
|
||||
bool G3PointAction::export_local_maxima_as_cloud()
|
||||
bool G3PointAction::exportLocalMaximaAsCloud()
|
||||
{
|
||||
// create cloud
|
||||
QString cloudName = m_cloud->getName() + "_g3point";
|
||||
@@ -444,11 +445,12 @@ bool G3PointAction::export_local_maxima_as_cloud()
|
||||
cloud->showColors(true);
|
||||
cloud->setPointSize(m_dlg->getPointSize());
|
||||
|
||||
int nbChildrenn = m_cloud->getParent()->getChildrenNumber();
|
||||
ccHObject* parent = m_cloud->getParent();
|
||||
int nbChildren = parent->getChildrenNumber();
|
||||
std::vector<ccHObject *> toDelete;
|
||||
for (int k = 0; k < nbChildrenn; k++)
|
||||
for (int k = 0; k < nbChildren; k++)
|
||||
{
|
||||
auto child = m_cloud->getParent()->getChild(k);
|
||||
auto child = parent->getChild(k);
|
||||
|
||||
if (child->getName() == cloudName)
|
||||
{
|
||||
@@ -457,16 +459,16 @@ bool G3PointAction::export_local_maxima_as_cloud()
|
||||
}
|
||||
for (auto& child : toDelete)
|
||||
{
|
||||
delete child;
|
||||
parent->removeChild(child);
|
||||
}
|
||||
|
||||
m_cloud->getParent()->addChild(cloud, ccHObject::DP_PARENT_OF_OTHER, 0);
|
||||
parent->addChild(cloud, ccHObject::DP_PARENT_OF_OTHER, 0);
|
||||
m_app->addToDB(cloud);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool G3PointAction::update_local_maximum_indexes()
|
||||
bool G3PointAction::updateLocalMaximumIndexes()
|
||||
{
|
||||
size_t nlabels = m_stacks.size();
|
||||
|
||||
@@ -487,12 +489,18 @@ bool G3PointAction::update_local_maximum_indexes()
|
||||
localMaximumIndexes(k) = stack[maxIndex];
|
||||
}
|
||||
|
||||
if ((localMaximumIndexes == -1).any())
|
||||
{
|
||||
ccLog::Error("[G3PointAction::updateLocalMaximumIndexes] CANCEL value error in the indexes of the local maximima");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_localMaximumIndexes = localMaximumIndexes;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool G3PointAction::update_labels_and_colors()
|
||||
bool G3PointAction::updateLabelsAndColors()
|
||||
{
|
||||
std::cout << "[G3PointAction::update_labels_and_colors]" << std::endl;
|
||||
|
||||
@@ -508,7 +516,7 @@ bool G3PointAction::update_labels_and_colors()
|
||||
}
|
||||
CCCoreLib::ScalarField* g3point_label = m_cloud->getScalarField(sfIdx);
|
||||
|
||||
RGBAColorsTableType randomColors = getRandomColors(m_localMaximumIndexes.size());
|
||||
RGBAColorsTableType randomColors = getRandomColors(m_stacks.size());
|
||||
|
||||
if (!m_cloud->resizeTheRGBTable(false))
|
||||
{
|
||||
@@ -516,7 +524,7 @@ bool G3PointAction::update_labels_and_colors()
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int k = 0; k < m_localMaximumIndexes.size(); k++)
|
||||
for (int k = 0; k < m_stacks.size(); k++)
|
||||
{
|
||||
const std::vector<int>& stack = m_stacks[k];
|
||||
// labels
|
||||
@@ -553,7 +561,7 @@ bool G3PointAction::update_labels_and_colors()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool G3PointAction::check_stacks(const std::vector<std::vector<int>>& stacks, int count)
|
||||
bool G3PointAction::checkStacks(const std::vector<std::vector<int>>& stacks, int count)
|
||||
{
|
||||
std::set<int> indexes;
|
||||
bool ret = true;
|
||||
@@ -579,8 +587,8 @@ bool G3PointAction::check_stacks(const std::vector<std::vector<int>>& stacks, in
|
||||
ccLog::Error("[G3PointAction::check_stacks] number of duplicates " + QString::number(errorCount));
|
||||
}
|
||||
|
||||
// the number of points in the staxks shall be the number of point in the point cloud
|
||||
if(indexes.size() != m_cloud->size())
|
||||
// the number of points in the stacks shall be the number of point in m_labels
|
||||
if(indexes.size() != m_labels.size())
|
||||
{
|
||||
ccLog::Warning("[G3PointAction::check_stacks] size of indexes " + QString::number(indexes.size()) + ", point count " + QString::number(m_cloud->size()));
|
||||
ret = false;
|
||||
@@ -593,6 +601,7 @@ int G3PointAction::cluster()
|
||||
{
|
||||
ccLog::Print("[cluster_labels]");
|
||||
size_t nlabels = m_stacks.size();
|
||||
|
||||
m_maxAngle1 = m_dlg->getMaxAngle1();
|
||||
m_radiusFactor = m_dlg->getRadiusFactor();
|
||||
|
||||
@@ -654,7 +663,7 @@ int G3PointAction::cluster()
|
||||
k++;
|
||||
}
|
||||
|
||||
Eigen::ArrayXXd A = compute_mean_angle();
|
||||
Eigen::ArrayXXd A = computeMeanAngle();
|
||||
|
||||
// merge labels if sinks are
|
||||
// => close to each other (Dist == 1)
|
||||
@@ -668,22 +677,23 @@ int G3PointAction::cluster()
|
||||
std::cout << "\n\nA" << std::endl;
|
||||
std::cout << A.block(0, 0, 10, 10) << std::endl;
|
||||
|
||||
if (!check_stacks(m_stacks, m_cloud->size()))
|
||||
if (!checkStacks(m_stacks, m_cloud->size()))
|
||||
{
|
||||
ccLog::Error("m_stacks is not valid");
|
||||
}
|
||||
|
||||
std::vector<std::vector<int>> newStacks;
|
||||
Eigen::ArrayXi newLabels = Eigen::ArrayXi::Ones(m_labels.size()) * (-1);
|
||||
int countNewLabels = 0;
|
||||
|
||||
// create the condition matrix and for ce the symmetry of the matrix
|
||||
// create the condition matrix and force the symmetry of the matrix
|
||||
XXb condition = (Dist < 1) || (Nneigh < 1) || (A > m_maxAngle1) || (A != A);
|
||||
XXb symmetrical_condition = (condition == condition.transpose()).select(condition, true);
|
||||
condition = symmetrical_condition;
|
||||
|
||||
std::cout << "\n\nsymmetrical_condition" << std::endl;
|
||||
std::cout << symmetrical_condition.block(0, 0, 20, 20) << std::endl;
|
||||
|
||||
std::vector<std::vector<int>> newStacks;
|
||||
Eigen::ArrayXi newLabels = Eigen::ArrayXi::Ones(m_labels.size()) * (-1);
|
||||
int countNewLabels = 0;
|
||||
|
||||
for (int label = 0; label < nlabels; label++)
|
||||
{
|
||||
|
||||
@@ -703,7 +713,7 @@ int G3PointAction::cluster()
|
||||
}
|
||||
|
||||
// shall we merge otherLabel with label?
|
||||
if (!symmetrical_condition(label, otherLabel))
|
||||
if (!condition(label, otherLabel))
|
||||
// if ((Dist(label, otherLabel) == 1)
|
||||
// && (Nneigh(label, otherLabel) == 1)
|
||||
// && (A(label, otherLabel) <= m_maxAngle1)
|
||||
@@ -768,25 +778,257 @@ int G3PointAction::cluster()
|
||||
std::cout << m_stacks[k].size() << " " << newStacks[k].size() << std::endl;
|
||||
}
|
||||
|
||||
if (!check_stacks(newStacks, m_cloud->size()))
|
||||
if (!checkStacks(newStacks, m_cloud->size()))
|
||||
{
|
||||
ccLog::Error("newStacks is not valid");
|
||||
}
|
||||
|
||||
m_stacks = newStacks;
|
||||
|
||||
update_local_maximum_indexes();
|
||||
updateLocalMaximumIndexes();
|
||||
|
||||
update_labels_and_colors();
|
||||
updateLabelsAndColors();
|
||||
|
||||
exportLocalMaximaAsCloud();
|
||||
|
||||
std::cout << "(b) m_stacks.size() " << m_stacks.size() << std::endl;
|
||||
std::cout << "(b) m_labels.size() " << m_labels.size() << std::endl;
|
||||
|
||||
export_local_maxima_as_cloud();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool G3PointAction::processNewStacks(std::vector<std::vector<int>>& stacks)
|
||||
{
|
||||
if (!checkStacks(stacks, m_cloud->size()))
|
||||
{
|
||||
ccLog::Error("[G3PointAction::merge] newStacks is not valid");
|
||||
return false;
|
||||
}
|
||||
|
||||
ccLog::Print("[G3PointAction::processNewStacks] keep " + QString::number(stacks.size())
|
||||
+ "/" + QString::number(m_stacks.size()) + " labels ("
|
||||
+ QString::number(m_stacks.size() - stacks.size()) + " removed)");
|
||||
QApplication::processEvents();
|
||||
|
||||
// new stacks are valid, set the class attribute
|
||||
m_stacks = stacks;
|
||||
|
||||
updateLocalMaximumIndexes();
|
||||
|
||||
updateLabelsAndColors();
|
||||
|
||||
exportLocalMaximaAsCloud();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool G3PointAction::merge(XXb& condition)
|
||||
{
|
||||
std::vector<std::vector<int>> newStacks;
|
||||
Eigen::ArrayXi newLabels = Eigen::ArrayXi::Ones(m_labels.size()) * (-1);
|
||||
int countNewLabels = 0;
|
||||
size_t nlabels = m_stacks.size();
|
||||
|
||||
if (condition.rows() != m_stacks.size()) // check that condition is validd
|
||||
{
|
||||
ccLog::Error("[G3PointAction::merge] the shape of the condition (" + QString::number(condition.rows())
|
||||
+ ", " + QString::number(condition.cols())
|
||||
+ ") is not coherent with the stacks size " + QString::number(m_stacks.size()));
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int label = 0; label < nlabels; label++)
|
||||
{
|
||||
|
||||
if (newLabels(label) == -1) // the label has not already been merged
|
||||
{
|
||||
newLabels(label) = countNewLabels;
|
||||
newStacks.push_back(m_stacks[label]); // initialize a newStack with the stack of the current label
|
||||
countNewLabels++;
|
||||
}
|
||||
|
||||
for (int otherLabel = 0; otherLabel < nlabels; otherLabel++)
|
||||
{
|
||||
|
||||
if (otherLabel == label)
|
||||
{
|
||||
continue; // do not try to merge a label with itself
|
||||
}
|
||||
|
||||
// shall we merge otherLabel with label?
|
||||
if (!condition(label, otherLabel))
|
||||
{
|
||||
|
||||
std::vector<int>& labelStack = newStacks[newLabels(label)];
|
||||
|
||||
if (newLabels(otherLabel) != -1) // the other label has already been merged
|
||||
{
|
||||
std::vector<int>& otherLabelStack = newStacks[newLabels(otherLabel)];
|
||||
if (newLabels(label) > newLabels(otherLabel)) // merge label in otherLabel
|
||||
{
|
||||
// add the label stack to the otherLabel stack
|
||||
otherLabelStack.insert(otherLabelStack.end(), labelStack.begin(), labelStack.end()); // add the stack to the label stack
|
||||
// empty the label stack
|
||||
labelStack.clear();
|
||||
// update the label
|
||||
newLabels(label) = newLabels(otherLabel);
|
||||
}
|
||||
if (newLabels(label) < newLabels(otherLabel)) // merge otherLabel in label
|
||||
{
|
||||
// add the otherLabel stack to the label stack
|
||||
labelStack.insert(labelStack.end(), otherLabelStack.begin(), otherLabelStack.end()); // add the stack to the label stack
|
||||
// empty the otherLabel stack
|
||||
otherLabelStack.clear();
|
||||
// update the otherLabel
|
||||
newLabels(otherLabel) = newLabels(label);
|
||||
}
|
||||
}
|
||||
else // merge otherLabel and label
|
||||
{
|
||||
std::vector<int>& otherLabelStack = m_stacks[otherLabel];
|
||||
// add the otherLabel stack to the label stack
|
||||
labelStack.insert(labelStack.end(), otherLabelStack.begin(), otherLabelStack.end()); // add the stack to the label stack
|
||||
// update the otherLabel
|
||||
newLabels(otherLabel) = newLabels(label);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove empty stacks
|
||||
std::vector<std::vector<int>> newStacksWithoutEmpty;
|
||||
for (auto& stack : newStacks)
|
||||
{
|
||||
if (!stack.empty())
|
||||
{
|
||||
newStacksWithoutEmpty.push_back(stack);
|
||||
}
|
||||
}
|
||||
|
||||
newStacks = newStacksWithoutEmpty;
|
||||
|
||||
processNewStacks(newStacks);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool G3PointAction::keepLabels(Xb& condition)
|
||||
{
|
||||
std::vector<std::vector<int>> newStacks;
|
||||
size_t pointCount = 0;
|
||||
|
||||
// the first stack will contain the removed points
|
||||
newStacks.push_back(std::vector<int>());
|
||||
|
||||
for (int index = 0; index < condition.size(); index++)
|
||||
{
|
||||
std::vector<int>& stack = m_stacks[index];
|
||||
if (condition(index)) // if the condition is met, we keep the stack
|
||||
{
|
||||
newStacks.push_back(stack);
|
||||
pointCount = pointCount + stack.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
// add the stack to the default stack
|
||||
newStacks[0].insert(newStacks[0].end(), stack.begin(), stack.end());
|
||||
}
|
||||
}
|
||||
|
||||
if (!processNewStacks(newStacks))
|
||||
{
|
||||
ccLog::Error("[G3PointAction::keepLabels] processing newStacks failed");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool G3PointAction::cleanLabels()
|
||||
{
|
||||
ccLog::Print("[cleanLabels]");
|
||||
|
||||
m_maxAngle2 = m_dlg->getMaxAngle2();
|
||||
m_nMin = m_dlg->getNMin();
|
||||
m_minFlatness = m_dlg->getMinFlatness();
|
||||
size_t nGrains = m_stacks.size();
|
||||
|
||||
// merge points considering the normals at the border
|
||||
{
|
||||
ccLog::Print("[cleanLabels] merge points considering the normals at the border");
|
||||
Eigen::ArrayXXd A = computeMeanAngle();
|
||||
XXb condition = (A > m_maxAngle2) || (A != A) || (Eigen::MatrixXi::Identity(nGrains, nGrains).array() == 1); // add true on the diagonal (important for the if hereafter)
|
||||
XXb symmetrical_condition = (condition == condition.transpose()).select(condition, true);
|
||||
if (condition.all())
|
||||
{
|
||||
ccLog::Print("[cleanLabels] nothing to merge, continue");
|
||||
}
|
||||
else
|
||||
{
|
||||
ccLog::Print("[cleanLabels] condition.count() " + QString::number(condition.count()) + " condition.size() " + QString::number(condition.size()));
|
||||
merge(condition);
|
||||
}
|
||||
|
||||
QApplication::processEvents();
|
||||
}
|
||||
|
||||
//remove small labels
|
||||
{
|
||||
ccLog::Print("[cleanLabels] remove small labels");
|
||||
Eigen::ArrayXi stackSize(m_stacks.size());
|
||||
for (size_t k = 0; k < m_stacks.size(); k++)
|
||||
{
|
||||
stackSize(k) = m_stacks[k].size();
|
||||
}
|
||||
Xb condition = (stackSize > m_nMin);
|
||||
size_t numberOfGrainsToKeep = condition.count();
|
||||
if (numberOfGrainsToKeep == m_stacks.size())
|
||||
{
|
||||
ccLog::Print("[cleanLabels] all grains are larger than " + QString::number(m_nMin) + " points, nothing to remove");
|
||||
}
|
||||
else if (numberOfGrainsToKeep)
|
||||
{
|
||||
keepLabels(condition);
|
||||
}
|
||||
else
|
||||
{
|
||||
ccLog::Error("[cleanLabels] CANCEL: no remaining grain after removing those with less than " + QString::number(m_nMin) + " points");
|
||||
return false;
|
||||
}
|
||||
QApplication::processEvents();
|
||||
}
|
||||
|
||||
// remove flattish labels
|
||||
// {
|
||||
// ccLog::Print("[cleanLabels] remove flattish labels");
|
||||
// Eigen::ArrayX3d s(m_stacks.size(), 3);
|
||||
// for (size_t k = 0; k < m_stacks.size(); k++)
|
||||
// {
|
||||
// std::vector<int>& stack = m_stacks[k];
|
||||
// // get the points of the label
|
||||
// size_t nPoints = stack.size();
|
||||
// Eigen::MatrixX3d points(nPoints, 3);
|
||||
// for (int index = 0; index < nPoints; index++)
|
||||
// {
|
||||
// const CCVector3* point = m_cloud->getPoint(stack[index]);
|
||||
// points(index, 0) = point->x;
|
||||
// points(index, 1) = point->y;
|
||||
// points(index, 2) = point->z;
|
||||
// }
|
||||
// // compute the centroid of the label
|
||||
// Eigen::RowVector3d centroid = points.colwise().mean();
|
||||
// points.rowwise() -= centroid;
|
||||
// // SVD decomposition A = U S V∗
|
||||
// s(k, Eigen::all) = points.jacobiSvd().singularValues();
|
||||
// // filtering condition: (l2 / l0 > min_flatness) or (l1 / l0 > 2 * min_flatness)
|
||||
// Xb condition = (s(Eigen::all, 2) / s(Eigen::all, 0) > m_minFlatness)
|
||||
// || (s(Eigen::all, 1) / s(Eigen::all, 0) > 2. * m_minFlatness);
|
||||
// keepLabels(condition);
|
||||
// }
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void G3PointAction::add_to_stack_braun_willett(int index, const Eigen::ArrayXi& delta, const Eigen::ArrayXi& Di, std::vector<int>& stack, int local_maximum)
|
||||
{
|
||||
stack.push_back(index);
|
||||
@@ -1368,20 +1610,35 @@ void G3PointAction::segment()
|
||||
// Perform initial segmentation
|
||||
int nLabels = segment_labels_braun_willett();
|
||||
|
||||
export_local_maxima_as_cloud();
|
||||
exportLocalMaximaAsCloud();
|
||||
|
||||
m_app->dispToConsole( "[G3Point] initial segmentation: " + QString::number(nLabels) + " labels", ccMainAppInterface::STD_CONSOLE_MESSAGE );
|
||||
|
||||
m_dlg->enableCluster(true);
|
||||
m_dlg->enableClean(true);
|
||||
}
|
||||
|
||||
void G3PointAction::segmentCluster()
|
||||
void G3PointAction::segmentAndCluster()
|
||||
{
|
||||
segment();
|
||||
|
||||
cluster();
|
||||
}
|
||||
|
||||
void G3PointAction::segmentAndClusterAndClean()
|
||||
{
|
||||
segment();
|
||||
|
||||
cluster();
|
||||
|
||||
cleanLabels();
|
||||
}
|
||||
|
||||
void G3PointAction::getBorders()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void G3PointAction::init()
|
||||
{
|
||||
m_kNN = m_dlg->getkNN();
|
||||
@@ -1406,7 +1663,11 @@ void G3PointAction::showDlg()
|
||||
|
||||
connect(m_dlg, &G3PointDialog::segment, s_g3PointAction, &G3Point::G3PointAction::segment);
|
||||
connect(m_dlg, &G3PointDialog::cluster, s_g3PointAction, &G3Point::G3PointAction::cluster);
|
||||
connect(m_dlg, &G3PointDialog::segmentCluster, s_g3PointAction, &G3Point::G3PointAction::segmentCluster);
|
||||
connect(m_dlg, &G3PointDialog::segmentCluster, s_g3PointAction, &G3Point::G3PointAction::segmentAndCluster);
|
||||
connect(m_dlg, &G3PointDialog::clean, s_g3PointAction, &G3Point::G3PointAction::cleanLabels);
|
||||
connect(m_dlg, &G3PointDialog::segmentClusterClean, s_g3PointAction, &G3Point::G3PointAction::segmentAndClusterAndClean);
|
||||
connect(m_dlg, &G3PointDialog::getBorders, s_g3PointAction, &G3Point::G3PointAction::getBorders);
|
||||
|
||||
connect(m_dlg, &QDialog::finished, s_g3PointAction, &G3Point::G3PointAction::clean);
|
||||
connect(m_dlg, &QDialog::finished, s_g3PointAction, &G3Point::G3PointAction::resetDlg); // dialog is defined with Qt::WA_DeleteOnClose
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@ G3PointDialog::G3PointDialog(QString cloudName, QWidget *parent)
|
||||
connect(this->ui->pushButtonSegment, &QPushButton::clicked, this, &G3PointDialog::emitSegment);
|
||||
connect(this->ui->pushButtonCluster, &QPushButton::clicked, this, &G3PointDialog::emitCluster);
|
||||
connect(this->ui->pushButtonSegmentCluster, &QPushButton::clicked, this, &G3PointDialog::emitSegmentCluster);
|
||||
connect(this->ui->pushButtonClean, &QPushButton::clicked, this, &G3PointDialog::emitClean);
|
||||
connect(this->ui->pushButtonSegmentClusterClean, &QPushButton::clicked, this, &G3PointDialog::emitSegmentClusterClean);
|
||||
connect(this->ui->pushButtonGetBorders, &QPushButton::clicked, this, &G3PointDialog::emitGetBorders);
|
||||
}
|
||||
|
||||
G3PointDialog::~G3PointDialog()
|
||||
@@ -27,6 +30,21 @@ double G3PointDialog::getMaxAngle1()
|
||||
return this->ui->doubleSpinBoxMaxAngle1->value();
|
||||
}
|
||||
|
||||
double G3PointDialog::getMaxAngle2()
|
||||
{
|
||||
return this->ui->doubleSpinBoxMaxAngle2->value();
|
||||
}
|
||||
|
||||
double G3PointDialog::getMinFlatness()
|
||||
{
|
||||
return this->ui->doubleSpinBoxMinFlatness->value();
|
||||
}
|
||||
|
||||
int G3PointDialog::getNMin()
|
||||
{
|
||||
return this->ui->spinBoxNMin->value();
|
||||
}
|
||||
|
||||
int G3PointDialog::getkNN()
|
||||
{
|
||||
return this->ui->spinBoxkNN->value();
|
||||
@@ -51,3 +69,8 @@ void G3PointDialog::enableCluster(bool state)
|
||||
{
|
||||
this->ui->pushButtonCluster->setEnabled(state);
|
||||
}
|
||||
|
||||
void G3PointDialog::enableClean(bool state)
|
||||
{
|
||||
this->ui->pushButtonClean->setEnabled(state);
|
||||
}
|
||||
|
||||
+130
-58
@@ -6,14 +6,83 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>199</width>
|
||||
<height>276</height>
|
||||
<width>281</width>
|
||||
<height>459</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="16" column="0" colspan="2">
|
||||
<widget class="QLabel" name="labelCloud">
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<widget class="QPushButton" name="pushButtonSegmentCluster">
|
||||
<property name="text">
|
||||
<string>Segment + Cluster</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Min points per grain</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Point size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Min flatness</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Max angle 1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="0">
|
||||
<widget class="QRadioButton" name="radioButtonG3Point">
|
||||
<property name="text">
|
||||
<string>G3Point</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxPointSize">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>3</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Radius factor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxkNN">
|
||||
<property name="minimum">
|
||||
@@ -27,34 +96,34 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxPointSize">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
<item row="4" column="1">
|
||||
<widget class="QSpinBox" name="spinBoxNMin">
|
||||
<property name="maximum">
|
||||
<number>1000000000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>3</number>
|
||||
<number>50</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QRadioButton" name="radioButtonG3Point">
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxRadiusFactor">
|
||||
<property name="value">
|
||||
<double>0.600000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QPushButton" name="pushButtonClean">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>G3Point</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
<string>Clean</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Max angle 1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<item row="9" column="1">
|
||||
<widget class="QPushButton" name="pushButtonCluster">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
@@ -64,17 +133,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>kNN</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QPushButton" name="pushButtonSegment">
|
||||
<property name="text">
|
||||
<string>Segment</string>
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxMinFlatness">
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -94,45 +159,52 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QPushButton" name="pushButtonSegmentCluster">
|
||||
<property name="text">
|
||||
<string>Segment + Cluster</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="2">
|
||||
<widget class="QLabel" name="labelCloud">
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<item row="15" column="1">
|
||||
<widget class="QRadioButton" name="radioButtonSteepestSlope">
|
||||
<property name="text">
|
||||
<string>steepest slope</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>kNN</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Point size</string>
|
||||
<string>Max angle 2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Radius factor</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxRadiusFactor">
|
||||
<item row="3" column="1">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxMaxAngle2">
|
||||
<property name="value">
|
||||
<double>0.600000000000000</double>
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<widget class="QPushButton" name="pushButtonSegmentClusterClean">
|
||||
<property name="text">
|
||||
<string>Segment + Cluster + Clean</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QPushButton" name="pushButtonSegment">
|
||||
<property name="text">
|
||||
<string>Segment</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1">
|
||||
<widget class="QPushButton" name="pushButtonGetBorders">
|
||||
<property name="text">
|
||||
<string>Get borders</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
Reference in New Issue
Block a user