From 14649ea6963a83ed13d6a44f9da810ea2c7fcd00 Mon Sep 17 00:00:00 2001 From: Paul Leroy Date: Tue, 26 Mar 2024 17:24:03 +0100 Subject: [PATCH] abort handled properly in eigensolver, ui improvements + ellipsoidDistance implementation Use of Geometric Tools Engine for ellipsoidDistance computation --- CMakeLists.txt | 1 + include/ActionA.h | 1 + include/G3PointDialog.h | 17 ++ include/GrainsAsEllipsoids.h | 25 +- src/ActionA.cpp | 31 ++- src/G3PointDialog.cpp | 18 ++ src/GrainsAsEllipsoids.cpp | 286 +++++++++++-------- ui/qG3PointDialog.ui | 513 ++++++++++++++++++++++------------- 8 files changed, 575 insertions(+), 317 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fc1c9f3..a5a61d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ if ( PLUGIN_G3POINT ) C:/opt/eigen-3.4.0 C:/Users/PaulLeroy/miniconda3/envs/env_4_CloudCompare/include C:/opt/open3d-devel-windows-amd64-0.18.0/include + C:/opt/GeometricTools/GTE ) # Find installed Open3D, which exports Open3D::Open3D diff --git a/include/ActionA.h b/include/ActionA.h index 8cbf563..e2a673b 100644 --- a/include/ActionA.h +++ b/include/ActionA.h @@ -34,6 +34,7 @@ public: void segmentAndClusterAndClean(); void getBorders(); int cluster(); + void fit(); bool processNewStacks(std::vector>& stacks, int pointCount); bool merge(XXb& condition); bool keep(Xb& condition); diff --git a/include/G3PointDialog.h b/include/G3PointDialog.h index 6a70ec5..2f31c5c 100644 --- a/include/G3PointDialog.h +++ b/include/G3PointDialog.h @@ -22,6 +22,14 @@ public: void emitSegmentClusterClean(){emit segmentClusterClean();} void emitGetBorders(){emit getBorders();} + void emitAllClicked(bool state){emit allClicked(state);} + void emitOnlyOneClicked(bool state){emit onlyOneClicked(state);} + void emitOnlyOneChanged(int idx){emit onlyOneChanged(idx);} + void emitFit(){emit fit();} + void emitTransparencyChanged(double transparency){emit transparencyChanged(transparency);} + + void emitSignals(); + double getMaxAngle1(); double getMaxAngle2(); double getMinFlatness(); @@ -34,6 +42,8 @@ public: void enableCluster(bool state); void enableClean(bool state); + void setOnlyOneMax(int idx); + signals: void segment(); void cluster(); @@ -42,6 +52,13 @@ signals: void segmentClusterClean(); void getBorders(); + void allClicked(bool state); + void onlyOneClicked(bool state); + void onlyOneChanged(int idx); + void transparencyChanged(double transparency); + + void fit(); + private: Ui::qG3PointDialog *ui; }; diff --git a/include/GrainsAsEllipsoids.h b/include/GrainsAsEllipsoids.h index 5f8b369..e0967e9 100644 --- a/include/GrainsAsEllipsoids.h +++ b/include/GrainsAsEllipsoids.h @@ -12,10 +12,14 @@ #include #include +#include + class ccPointCloud; -class GrainsAsEllipsoids : public ccHObject +class GrainsAsEllipsoids : public QObject, public ccHObject { + Q_OBJECT + public: typedef Eigen::Array Xb; @@ -54,11 +58,13 @@ public: enum Method{ DIRECT = 0}; + double ellipsoidDistance(const Eigen::ArrayXd& p, int idx); + bool explicitToImplicit(const Eigen::Array3f& center, const Eigen::Array3f& radii, const Eigen::Matrix3f &rotationMatrix, Eigen::ArrayXd& parameters); bool implicitToExplicit(const Eigen::ArrayXd& parameters, Eigen::Array3f& center, Eigen::Array3f& radii, Eigen::Matrix3f& rotationMatrix); - Eigen::ArrayXd directFit(const Eigen::ArrayX3d& xyz); + bool directFit(const Eigen::ArrayX3d& xyz, Eigen::ArrayXd ¶meters); bool fitEllipsoidToGrain(const int grainIndex, Eigen::Array3f& center, Eigen::Array3f& radii, Eigen::Matrix3f& rotationMatrix, const Method& method=DIRECT); @@ -71,6 +77,8 @@ public: void setUniformValueColor(const ccColor::Rgba &color); + void drawEllipsoid(CC_DRAW_CONTEXT &context, int idx); + bool drawEllipsoids(CC_DRAW_CONTEXT &context); bool initProgram(QOpenGLContext* context); @@ -81,6 +89,14 @@ public: // from ccHObject void draw(CC_DRAW_CONTEXT& context); + void setOnlyOne(int i){m_onlyOne = i;} + + void showOnlyOne(bool state){m_showAll =!state;} + + void showAll(bool state); + + void setTransparency(double transparency){m_transparency = transparency;} + ccPointCloud* m_cloud; ccMainAppInterface* m_app; Eigen::ArrayXi m_localMaximumIndexes; @@ -98,6 +114,11 @@ public: std::vector m_center; std::vector m_radii; std::vector m_rotationMatrix; + std::set m_fitNotOK; + double m_transparency = 1.0; + + int m_onlyOne; + bool m_showAll{true}; }; #endif // GRAINSASELLIPSOIDS_H diff --git a/src/ActionA.cpp b/src/ActionA.cpp index c5674a9..18433ee 100644 --- a/src/ActionA.cpp +++ b/src/ActionA.cpp @@ -957,6 +957,27 @@ int G3PointAction::cluster() return 0; } +void G3PointAction::fit() +{ + // plot display grains as ellipsoids + m_grainsAsEllipsoids = new GrainsAsEllipsoids(m_cloud, m_app, m_stacks); + m_grainsAsEllipsoids->setLocalMaximumIndexes(m_localMaximumIndexes); + m_grainColors.reset(new RGBAColorsTableType(getRandomColors(m_localMaximumIndexes.size()))); + m_grainsAsEllipsoids->setGrainColorsTable(*m_grainColors); + m_grainsAsEllipsoids->setName("grains as ellipsoids"); + + // add connections with the dialog + connect(m_dlg, &G3PointDialog::onlyOneClicked, m_grainsAsEllipsoids, &GrainsAsEllipsoids::showOnlyOne); + connect(m_dlg, &G3PointDialog::allClicked, m_grainsAsEllipsoids, &GrainsAsEllipsoids::showAll); + connect(m_dlg, &G3PointDialog::onlyOneChanged, m_grainsAsEllipsoids, &GrainsAsEllipsoids::setOnlyOne); + connect(m_dlg, &G3PointDialog::transparencyChanged, m_grainsAsEllipsoids, &GrainsAsEllipsoids::setTransparency); + + m_dlg->setOnlyOneMax(m_stacks.size()); + m_dlg->emitSignals(); // force to send parameters to m_grainsAsEllipsoids + + m_app->addToDB(m_grainsAsEllipsoids); +} + bool G3PointAction::cleanLabels() { ccLog::Print("[cleanLabels]"); @@ -1640,14 +1661,6 @@ void G3PointAction::segment() m_app->dispToConsole( "[G3Point] initial segmentation: " + QString::number(nLabels) + " labels", ccMainAppInterface::STD_CONSOLE_MESSAGE ); - // plot display grains as ellipsoids - m_grainsAsEllipsoids = new GrainsAsEllipsoids(m_cloud, m_app, m_stacks); - m_grainsAsEllipsoids->setLocalMaximumIndexes(m_localMaximumIndexes); - m_grainColors.reset(new RGBAColorsTableType(getRandomColors(m_localMaximumIndexes.size()))); - m_grainsAsEllipsoids->setGrainColorsTable(*m_grainColors); - m_grainsAsEllipsoids->setName("grains as ellipsoids"); - m_app->addToDB(m_grainsAsEllipsoids); - m_dlg->enableCluster(true); m_dlg->enableClean(true); } @@ -1735,6 +1748,8 @@ void G3PointAction::showDlg() connect(m_dlg, &G3PointDialog::segmentClusterClean, s_g3PointAction, &G3Point::G3PointAction::segmentAndClusterAndClean); connect(m_dlg, &G3PointDialog::getBorders, s_g3PointAction, &G3Point::G3PointAction::getBorders); + connect(m_dlg, &G3PointDialog::fit, s_g3PointAction, &G3Point::G3PointAction::fit); + 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 } diff --git a/src/G3PointDialog.cpp b/src/G3PointDialog.cpp index 9201e66..5056c09 100644 --- a/src/G3PointDialog.cpp +++ b/src/G3PointDialog.cpp @@ -18,6 +18,13 @@ G3PointDialog::G3PointDialog(QString cloudName, QWidget *parent) 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); + + connect(this->ui->radioButtonAll, &QRadioButton::clicked, this, &G3PointDialog::emitAllClicked); + connect(this->ui->radioButtonOnlyOne, &QRadioButton::clicked, this, &::G3PointDialog::emitOnlyOneClicked); + connect(this->ui->spinBoxOnlyOne, qOverload(&QSpinBox::valueChanged), this, &::G3PointDialog::emitOnlyOneChanged); + + connect(this->ui->pushButtonFit, &QPushButton::clicked, this, &G3PointDialog::emitFit); + connect(this->ui->doubleSpinBoxTransparency, qOverload(&QDoubleSpinBox::valueChanged), this, &G3PointDialog::emitTransparencyChanged); } G3PointDialog::~G3PointDialog() @@ -74,3 +81,14 @@ void G3PointDialog::enableClean(bool state) { this->ui->pushButtonClean->setEnabled(state); } + +void G3PointDialog::emitSignals() +{ + emit allClicked(this->ui->radioButtonAll->isChecked()); + emit emitOnlyOneChanged(this->ui->spinBoxOnlyOne->value()); +} + +void G3PointDialog::setOnlyOneMax(int max) +{ + this->ui->spinBoxOnlyOne->setMaximum(max); +} diff --git a/src/GrainsAsEllipsoids.cpp b/src/GrainsAsEllipsoids.cpp index 5e50f81..2a48c2d 100644 --- a/src/GrainsAsEllipsoids.cpp +++ b/src/GrainsAsEllipsoids.cpp @@ -8,7 +8,10 @@ #include #include -std::vector indexes; +// from GeometricTools/GTE +#include +#include +#include GrainsAsEllipsoids::GrainsAsEllipsoids(ccPointCloud *cloud, ccMainAppInterface *app, const std::vector >& stacks) : m_cloud(cloud) @@ -24,18 +27,16 @@ GrainsAsEllipsoids::GrainsAsEllipsoids(ccPointCloud *cloud, ccMainAppInterface * // fit all ellipsoids std::cout << "[GrainsAsEllipsoids::GrainsAsEllipsoids] fit " << stacks.size() << " ellipsoids" << std::endl; - indexes.push_back(268); - indexes.push_back(351); - lockVisibility(false); - for (int idx : indexes) + for (int idx = 0; idx < m_stacks.size(); idx++) { - fitEllipsoidToGrain(idx, m_center[idx], m_radii[idx], m_rotationMatrix[idx]); - std::cout << "grain " << idx << " stack size " << m_stacks[idx].size() << std::endl; - std::cout << "center " << std::endl << m_center[idx] << std::endl; - std::cout << "radii " << std::endl << m_radii[idx] << std::endl; - std::cout << "rotation matrix " << std::endl << m_rotationMatrix[idx] << std::endl; + if (!fitEllipsoidToGrain(idx, m_center[idx], m_radii[idx], m_rotationMatrix[idx])) + { + m_fitNotOK.insert(idx); + ccLog::Warning("[GrainsAsEllipsoids::GrainsAsEllipsoids] fit not possible for grain " + QString::number(idx) + + " of size " + QString::number(m_stacks[idx].size())); + } } } @@ -187,6 +188,67 @@ void GrainsAsEllipsoids::buildInterleavedVertices() // ELLIPSOID FITTING +double GrainsAsEllipsoids::ellipsoidDistance(const Eigen::ArrayXd& p, int idx) +{ + // Compute the mean distance between the points of the grain and the ellipsoid + + // GTE Geometric Tools Engine + + // center + gte::Vector3 center = {m_center[idx](0), m_center[idx](1), m_center[idx](2)}; + + // axis + std::array, 3> axis; + axis[0] = {m_rotationMatrix[idx](0, 0), m_rotationMatrix[idx](1, 0), m_rotationMatrix[idx](2, 0)}; + axis[1] = {m_rotationMatrix[idx](0, 1), m_rotationMatrix[idx](1, 1), m_rotationMatrix[idx](2, 1)}; + axis[2] = {m_rotationMatrix[idx](0, 2), m_rotationMatrix[idx](1, 2), m_rotationMatrix[idx](2, 2)}; + + // extent + gte::Vector3 extent = {m_radii[idx](0), m_radii[idx](1), m_radii[idx](2)}; + + // create the ellipsoid + gte::Ellipsoid3 ellipsoid(center, axis, extent); + + gte::DCPQuery, gte::Ellipsoid3> query; + + std::vector stack = m_stacks[idx]; + double sum_a = 0; // distances with respect to the ellipsoid + double sum_b = 0; // distances with respect to the mean + + //compute gravity center + size_t count = m_cloud->size(); + CCVector3 mean(0, 0, 0); + for (int index : m_stacks[idx]) + { + const CCVector3* P = m_cloud->getPoint(index); + mean.x += P->x; + mean.y += P->y; + mean.z += P->z; + } + mean.x = mean.x / count; + mean.y = mean.y / count; + mean.z = mean.z / count; + + for (int index : stack) + { + const CCVector3 *P = m_cloud->getPoint(index); + gte::Vector3 P_gte = {P->x, P->y, P->z}; + auto result = query(P_gte, ellipsoid); + sum_a = sum_a + pow(result.distance, 2); + + CCVector3 P_minus_min = *P - CCVector3(mean.x, mean.y, mean.z); + sum_b = sum_b + P_minus_min.norm2d(); + } + + double r2 = 1 - sum_a / sum_b; + + // in Matlab + // d = (x-xp).^2 + (y-yp).^2 + (z-zp).^2; + // r2 = 1 - sum((x-xp).^2 + (y-yp).^2 + (z-zp).^2)./sum((x-mean(x)).^2 + (y-mean(y)).^2 + (z-mean(z)).^2); + + return r2; +} + bool GrainsAsEllipsoids::explicitToImplicit(const Eigen::Array3f& center, const Eigen::Array3f& radii, const Eigen::Matrix3f& rotationMatrix, @@ -301,7 +363,7 @@ bool GrainsAsEllipsoids::implicitToExplicit(const Eigen::ArrayXd& parameters, Eigen::EigenSolver eigensolver(s.block(0, 0, 3, 3)); if (eigensolver.info() != Eigen::Success) { - abort(); + return false; } radii = (-s(3, 3) / eigensolver.eigenvalues().array().real()).sqrt().cast(); @@ -310,10 +372,8 @@ bool GrainsAsEllipsoids::implicitToExplicit(const Eigen::ArrayXd& parameters, return true; } -Eigen::ArrayXd GrainsAsEllipsoids::directFit(const Eigen::ArrayX3d& xyz) +bool GrainsAsEllipsoids::directFit(const Eigen::ArrayX3d& xyz, Eigen::ArrayXd& parameters) { - std::cout << "[GrainsAsEllipsoids::directFit]" << std::endl; - Eigen::MatrixXd d(xyz.rows(), 10); d << xyz(Eigen::all, 0).pow(2).matrix() @@ -345,11 +405,13 @@ Eigen::ArrayXd GrainsAsEllipsoids::directFit(const Eigen::ArrayX3d& xyz) Eigen::GeneralizedEigenSolver eigensolver(s, c); if (eigensolver.info() != Eigen::Success) { - abort(); + return false; } Eigen::ArrayXd eigenValues(10); + Eigen::VectorXd eigenValuesAsAMatrix(10); eigenValues = eigensolver.eigenvalues().real(); + eigenValuesAsAMatrix = eigensolver.eigenvalues().real().matrix(); Xb condition = (eigenValues > 0) && (!eigenValues.isInf()); int flt = condition.count(); @@ -381,10 +443,10 @@ Eigen::ArrayXd GrainsAsEllipsoids::directFit(const Eigen::ArrayX3d& xyz) break; case 0: // degenerate case // # single positive eigenvalue becomes near-zero negative eigenvalue due to round-off error - eigenValue = finiteValues.abs().minCoeff(); + eigenValue = eigenValues.abs().minCoeff(); for (k = 0; k < 10; k++) { - if (eigenValues(k) == eigenValue) + if (abs(eigenValues(k)) == eigenValue) { v = eigensolver.eigenvectors()(Eigen::all, k).real(); break; @@ -405,14 +467,14 @@ Eigen::ArrayXd GrainsAsEllipsoids::directFit(const Eigen::ArrayX3d& xyz) break; } - Eigen::ArrayXd p(10); + parameters.resize(10); - p << v(0), v(1), v(2) + parameters << v(0), v(1), v(2) , 2 * v(5), 2 * v(4), 2* v(3) , 2 * v(6), 2 * v(7), 2 * v(8) , v(9); - return p; + return true; } bool GrainsAsEllipsoids::fitEllipsoidToGrain(const int grainIndex, @@ -453,9 +515,15 @@ bool GrainsAsEllipsoids::fitEllipsoidToGrain(const int grainIndex, // The constraint confines the class of ellipsoids to fit to those whose smallest radius is at least half of the // largest radius. - p = directFit(scale * (grainPoints.cast().rowwise() - means)); // Ellipsoid fit + if(!directFit(scale * (grainPoints.cast().rowwise() - means), p)) // Ellipsoid fit + { + return false; + } - implicitToExplicit(p, center, radii, rotationMatrix); // Get the explicit parameters + if (!implicitToExplicit(p, center, radii, rotationMatrix)) // Get the explicit parameters + { + return false; + } break; default: @@ -558,62 +626,27 @@ bool GrainsAsEllipsoids::initProgram(QOpenGLContext* context) return true; } -bool GrainsAsEllipsoids::drawEllipsoids(CC_DRAW_CONTEXT& context) +void GrainsAsEllipsoids::drawEllipsoid(CC_DRAW_CONTEXT& context, int idx) { QOpenGLFunctions_2_1* glFunc = context.glFunctions(); assert(glFunc != nullptr); - CCVector3f color; - - // set uniforms - QVector4D lightPosition(0, 0, 1, 0); - QVector4D lightAmbient(0.3f, 0.3f, 0.3f, 1); // grey - QVector4D lightDiffuse(0.7f, 0.7f, 0.7f, 1); // light grey - QVector4D lightSpecular(1.0f, 1.0f, 1.0f, 1); // RGB white - // QVector4D materialAmbient(0.5f, 0.5f, 0.5f, 1); - QVector4D materialDiffuse(0.7f, 0.7f, 0.7f, 1); - QVector4D materialSpecular(0.4f, 0.4f, 0.4f, 1); - QVector4D materialAmbient(color.x, color.y, color.z, 1); - // QVector4D materialDiffuse(color.r / ccColor::MAX, color.g / ccColor::MAX, color.b / ccColor::MAX, 1); - // QVector4D materialSpecular(color.r / ccColor::MAX, color.g / ccColor::MAX, color.b / ccColor::MAX, 1); - float materialShininess = 16; - - m_program->setUniformValue("lightPosition", lightPosition); - m_program->setUniformValue("lightAmbient", lightAmbient); - m_program->setUniformValue("lightDiffuse", lightDiffuse); - m_program->setUniformValue("lightSpecular", lightSpecular); - m_program->setUniformValue("materialDiffuse", materialDiffuse); - m_program->setUniformValue("materialSpecular", materialSpecular); - m_program->setUniformValue("materialShininess", materialShininess); - - m_program->setAttributeArray("vertexPosition", static_cast(vertices.data()), 3); - m_program->setAttributeArray("vertexNormal", static_cast(normals.data()), 3); - m_program->setAttributeArray("vertexTexCoord", static_cast(texCoords.data()), 2); - - m_program->enableAttributeArray("vertexPosition"); - m_program->enableAttributeArray("vertexNormal"); - m_program->enableAttributeArray("vertexTexCoord"); - - QMatrix4x4 projection; - QMatrix4x4 modelView; - - //generate random colors - std::mt19937 gen(42); // to seed mersenne twister. - std::uniform_real_distribution<> dis(0.5, 1.0); - std::uniform_real_distribution<> dis2(-1., 1.0); - - for (int idx : indexes) + if (!m_fitNotOK.count(idx)) { + QMatrix4x4 projection; + QMatrix4x4 modelView; Eigen::Matrix3f rotation(m_rotationMatrix[idx].transpose()); QMatrix4x4 matrixFromFit(rotation(0, 0), rotation(0, 1), rotation(0, 2), m_center[idx](0), rotation(1, 0), rotation(1, 1), rotation(1, 2), m_center[idx](1), rotation(2, 0), rotation(2, 1), rotation(2, 2), m_center[idx](2), 0, 0, 0, 1); + CCVector3f color; + color = m_grainColors[idx]; glFunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glFunc->glEnable( GL_BLEND ); - m_program->setUniformValue("materialAmbient", color.x, color.y, color.z, 0.5); + glFunc->glEnable(GL_BLEND); + m_program->setUniformValue("materialAmbient", color.x, color.y, color.z, 1.); // prepare translation, rotation and scaling glFunc->glPushMatrix(); // save the current matrix @@ -643,9 +676,61 @@ bool GrainsAsEllipsoids::drawEllipsoids(CC_DRAW_CONTEXT& context) glFunc->glPopMatrix(); } +} - if (false) - { // Matlab 22.36920946, 17.15421478, -11.2193826 +bool GrainsAsEllipsoids::drawEllipsoids(CC_DRAW_CONTEXT& context) +{ + QOpenGLFunctions_2_1* glFunc = context.glFunctions(); + assert(glFunc != nullptr); + + CCVector3f color; + + // set uniforms + QVector4D lightPosition(0, 0, 1, 0); + QVector4D lightAmbient(0.3f, 0.3f, 0.3f, 1); // grey + QVector4D lightDiffuse(0.7f, 0.7f, 0.7f, 1); // light grey + QVector4D lightSpecular(1.0f, 1.0f, 1.0f, 1); // RGB white + // QVector4D materialAmbient(0.5f, 0.5f, 0.5f, 1); + QVector4D materialDiffuse(0.7f, 0.7f, 0.7f, m_transparency); + QVector4D materialSpecular(0.4f, 0.4f, 0.4f, 1); + QVector4D materialAmbient(color.x, color.y, color.z, 1); + // QVector4D materialDiffuse(color.r / ccColor::MAX, color.g / ccColor::MAX, color.b / ccColor::MAX, 1); + // QVector4D materialSpecular(color.r / ccColor::MAX, color.g / ccColor::MAX, color.b / ccColor::MAX, 1); + float materialShininess = 16; + + m_program->setUniformValue("lightPosition", lightPosition); + m_program->setUniformValue("lightAmbient", lightAmbient); + m_program->setUniformValue("lightDiffuse", lightDiffuse); + m_program->setUniformValue("lightSpecular", lightSpecular); + m_program->setUniformValue("materialDiffuse", materialDiffuse); + m_program->setUniformValue("materialSpecular", materialSpecular); + m_program->setUniformValue("materialShininess", materialShininess); + + m_program->setAttributeArray("vertexPosition", static_cast(vertices.data()), 3); + m_program->setAttributeArray("vertexNormal", static_cast(normals.data()), 3); + m_program->setAttributeArray("vertexTexCoord", static_cast(texCoords.data()), 2); + + m_program->enableAttributeArray("vertexPosition"); + m_program->enableAttributeArray("vertexNormal"); + m_program->enableAttributeArray("vertexTexCoord"); + + QMatrix4x4 projection; + QMatrix4x4 modelView; + + if (m_showAll) + { + for (int idx = 0; idx < m_stacks.size(); idx++) + { + drawEllipsoid(context, idx); + } + } + else + { + drawEllipsoid(context, m_onlyOne); + } + + if (false) // Matlab fit of grain 351 + { Eigen::Matrix3f rotation; rotation << -0.1424, -0.8175, -0.5580, -0.9102, -0.1133, 0.3983, @@ -690,44 +775,6 @@ bool GrainsAsEllipsoids::drawEllipsoids(CC_DRAW_CONTEXT& context) glFunc->glPopMatrix(); } -// for (int k = 1; k < m_localMaximumIndexes.size(); k++) -// { -// if (k==indexOfGrainToFit) -// continue; - -// const CCVector3f* center = m_cloud->getPoint(m_localMaximumIndexes[k]); -// CCVector3f color = m_grainColors[k]; -// m_program->setUniformValue("materialAmbient", color.x, color.y, color.z, 1); - -// // prepare translation, rotation and scaling -// glFunc->glPushMatrix(); // save the current matrix -// // translate -// glFunc->glTranslatef(center->x, center->y, center->z); -// // rotate -// glFunc->glRotatef(90, static_cast(dis2(gen)), static_cast(dis2(gen)), static_cast(dis2(gen))); -// // scale -// glFunc->glScalef(static_cast(dis(gen)), static_cast(dis(gen)), static_cast(dis(gen))); -// // get matrices -// glFunc->glGetFloatv(GL_PROJECTION_MATRIX, projection.data()); -// glFunc->glGetFloatv(GL_MODELVIEW_MATRIX, modelView.data()); -// m_program->setUniformValue("modelViewProjectionMatrix", projection * modelView); - -// // draw triangles -// m_program->setUniformValue("drawLines", 0); -// glFunc->glEnable(GL_POLYGON_OFFSET_FILL); -// glFunc->glPolygonOffset(1.0, 1.0f); // move polygon backward -// glFunc->glDrawElements(GL_TRIANGLES, (unsigned int)indices.size(), GL_UNSIGNED_INT, indices.data()); -// glFunc->glDisable(GL_POLYGON_OFFSET_FILL); - -// // draw lines -// m_program->setUniformValue("drawLines", 1); -// glFunc->glDisable(GL_LIGHTING); -// glFunc->glDisable(GL_TEXTURE_2D); -// glFunc->glDrawElements(GL_LINES, (unsigned int)lineIndices.size(), GL_UNSIGNED_INT, lineIndices.data()); - -// glFunc->glPopMatrix(); -// } - m_program->disableAttributeArray("vertexPosition"); m_program->disableAttributeArray("vertexNormal"); m_program->disableAttributeArray("vertexTexCoord"); @@ -756,18 +803,18 @@ void GrainsAsEllipsoids::drawGrains(CC_DRAW_CONTEXT& context) // set uniforms m_program->setUniformValue("modelViewProjectionMatrix", projectionModelView); - // get the coordinates of the local maxima - std::vector semiAxisLengths(m_localMaximumIndexes.size(), CCVector3(1, 1, 1)); - std::vector centers(m_localMaximumIndexes.size()); - - // initialize the vector containing the centers of the grains - for (int index = 0; index < m_localMaximumIndexes.size(); index++) - { - centers[index] = *m_cloud->getPoint(m_localMaximumIndexes[index]); - } - if (false) { + // get the coordinates of the local maxima + std::vector semiAxisLengths(m_localMaximumIndexes.size(), CCVector3(1, 1, 1)); + std::vector centers(m_localMaximumIndexes.size()); + + // initialize the vector containing the centers of the grains + for (int index = 0; index < m_localMaximumIndexes.size(); index++) + { + centers[index] = *m_cloud->getPoint(m_localMaximumIndexes[index]); + } + m_program->setAttributeArray("vertexIn", static_cast(vertices.data()), 3); m_program->setAttributeArray("semiAxisLengths", static_cast(semiAxisLengths.front().u), 3); @@ -801,3 +848,12 @@ void GrainsAsEllipsoids::draw(CC_DRAW_CONTEXT& context) { drawGrains(context); } + +void GrainsAsEllipsoids::showAll(bool state) +{ + m_showAll = state; + ccLog::Warning("[GrainsAsEllipsoids::showAll] changed " + QString::number(m_showAll)); +} + + + diff --git a/ui/qG3PointDialog.ui b/ui/qG3PointDialog.ui index 846d147..8c70bbc 100644 --- a/ui/qG3PointDialog.ui +++ b/ui/qG3PointDialog.ui @@ -6,206 +6,335 @@ 0 0 - 281 - 459 + 303 + 509 Dialog - - - - - - - - - - - - Segment + Cluster - - - - - - - Min points per grain - - - - - - - Point size - - - - - - - Min flatness - - - - - - - Max angle 1 - - - - - - - G3Point - - - true - - - - - - - 1 - - - 3 - - - - - - - Radius factor - - - - - - - 1 - - - 100000 - - - 20 - - - - - - - 1000000000 - - - 50 - - - - - - - 0.600000000000000 - - - - - - - false - - - Clean - - - - - - - false - - - Cluster - - - - - - - 0.100000000000000 - - - 0.100000000000000 - - - - - - - true - - - QAbstractSpinBox::UpDownArrows - - - 360.000000000000000 - - - 60.000000000000000 - - - - - - - steepest slope - - - - - - kNN - - - - - - - Max angle 2 - - - - - - - 10.000000000000000 - - - - - - - Segment + Cluster + Clean - - - - - - - Segment - - - - - - - Get borders + + + 1 + + + Segmentation + + + + + + kNN + + + + + + + 1 + + + 100000 + + + 20 + + + + + + + Radius factor + + + + + + + 0.600000000000000 + + + + + + + Max angle 1 + + + + + + + true + + + QAbstractSpinBox::UpDownArrows + + + 360.000000000000000 + + + 60.000000000000000 + + + + + + + Max angle 2 + + + + + + + 10.000000000000000 + + + + + + + Min points per grain + + + + + + + 1000000000 + + + 50 + + + + + + + Min flatness + + + + + + + 0.100000000000000 + + + 0.100000000000000 + + + + + + + Point size + + + + + + + 1 + + + 3 + + + + + + + Segment + + + + + + + false + + + Cluster + + + + + + + false + + + Clean + + + + + + + Segment + Cluster + + + + + + + Segment + Cluster + Clean + + + + + + + Get borders + + + + + + + G3Point + + + true + + + + + + + steepest slope + + + + + + + - + + + + + + + + Fitting + + + + + + Fit ellipsoids + + + + + + Run + + + + + + + Direct + + + true + + + + + + + + + + Show + + + + + + All + + + true + + + + + + + Only one + + + + + + + + + + Transparency + + + + + + + 1.000000000000000 + + + 0.050000000000000 + + + 1.000000000000000 + + + + + + + Wireframes + + + true + + + + + + + Surfaces + + + true + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + +