From d3d6a607b6e28f2dd3f63741b0cf2f119b52e9df Mon Sep 17 00:00:00 2001 From: Ioannis Farmakis Date: Fri, 21 Mar 2025 16:41:45 +0200 Subject: [PATCH] align voxel grid with slope normal vector --- include/qVoxFallDialog.h | 6 ++-- include/qVoxFallTools.h | 39 ++++++++++----------- src/qVoxFallDialog.cpp | 16 ++++++--- src/qVoxFallProcess.cpp | 3 +- src/qVoxFallTools.cpp | 27 --------------- ui/qVoxFallDialog.ui | 75 +++++++++++++++++++++------------------- 6 files changed, 76 insertions(+), 90 deletions(-) diff --git a/include/qVoxFallDialog.h b/include/qVoxFallDialog.h index dd8850f..ff73981 100644 --- a/include/qVoxFallDialog.h +++ b/include/qVoxFallDialog.h @@ -43,6 +43,8 @@ public: //! Returns voxel size double getVoxelSize() const; + //! Returns slope dip + double getDip() const; //! Returns slope azimuth double getAzimuth() const; //! Returns whether a report will be generated @@ -66,8 +68,8 @@ protected: void setMesh1Visibility(bool); void setMesh2Visibility(bool); - //! Automatically estimate the azimuth - void autoComputeAzimuth(); + //! Automatically estimate the dip angle + void autoFitPlane(); protected: //methods diff --git a/include/qVoxFallTools.h b/include/qVoxFallTools.h index 0ef4788..3e0576d 100644 --- a/include/qVoxFallTools.h +++ b/include/qVoxFallTools.h @@ -37,35 +37,34 @@ class qVoxFallTransform { - double az; - float zRot; - public: ccGLMatrix matrix; ccGLMatrix inverse; - qVoxFallTransform(double azimuth) + + qVoxFallTransform(double dip, double azimuth) { - az = azimuth; - zRot = GetRotationAngle(azimuth); + float zRot = azimuth * 3.14159 / 180; + float xRot = (90 - dip) * 3.14159 / 180; - const Vector3Tpl X(std::cos(zRot), std::sin(zRot), 0); - const Vector3Tpl Y(-std::sin(zRot), std::cos(zRot), 0); - const Vector3Tpl Z(0, 0, 1); - const Vector3Tpl Tr(0, 0, 0); - matrix = ccGLMatrix(X, Y, Z, Tr); + ccGLMatrix zRotMatrix; + const Vector3Tpl zX(std::cos(zRot), std::sin(zRot), 0); + const Vector3Tpl zY(-std::sin(zRot), std::cos(zRot), 0); + const Vector3Tpl zZ(0, 0, 1); + const Vector3Tpl zTr(0, 0, 0); + zRotMatrix = ccGLMatrix(zX, zY, zZ, zTr); - const Vector3Tpl rX(std::cos(-zRot), std::sin(-zRot), 0); - const Vector3Tpl rY(-std::sin(-zRot), std::cos(-zRot), 0); - const Vector3Tpl rZ(0, 0, 1); - const Vector3Tpl rTr(0, 0, 0); - inverse = ccGLMatrix(rX, rY, rZ, rTr); + ccGLMatrix xRotMatrix; + const Vector3Tpl xX(1, 0, 0); + const Vector3Tpl xY(0, std::cos(xRot), -std::sin(xRot)); + const Vector3Tpl xZ(0, std::sin(xRot), std::cos(xRot)); + const Vector3Tpl xTr(0, 0, 0); + xRotMatrix = ccGLMatrix(xX, xY, xZ, xTr); + + matrix = zRotMatrix * xRotMatrix; + inverse = matrix.inverse(); } static ccBox* CreateVoxelMesh(CCVector3 V, float voxelSize, int voxelIdx); - -private: - static float GetRotationAngle(double azimuth); - }; diff --git a/src/qVoxFallDialog.cpp b/src/qVoxFallDialog.cpp index fb292ea..16d0a0a 100644 --- a/src/qVoxFallDialog.cpp +++ b/src/qVoxFallDialog.cpp @@ -100,7 +100,7 @@ qVoxFallDialog::qVoxFallDialog(ccMesh* mesh1, ccMesh* mesh2, ccMainAppInterface* connect(browseToolButton, &QAbstractButton::clicked, this, &qVoxFallDialog::browseDestination); - connect(autoAzimuthButton, &QAbstractButton::clicked, this, &qVoxFallDialog::autoComputeAzimuth); + connect(autoFitPlaneButton, &QAbstractButton::clicked, this, &qVoxFallDialog::autoFitPlane); setMeshes(mesh1, mesh2); @@ -170,6 +170,12 @@ double qVoxFallDialog::getVoxelSize() const return voxelSize; } +double qVoxFallDialog::getDip() const +{ + double dip = dipDoubleSpinBox->value(); + return dip; +} + double qVoxFallDialog::getAzimuth() const { double azimuth = azDoubleSpinBox->value(); @@ -257,7 +263,7 @@ void qVoxFallDialog::saveParamsTo(QSettings& settings) settings.setValue("LossGainEnabled", lossCheckBox->isChecked()); } -void qVoxFallDialog::autoComputeAzimuth() +void qVoxFallDialog::autoFitPlane() { //check if there is an already fitted plane and get the dip direction @@ -274,8 +280,9 @@ void qVoxFallDialog::autoComputeAzimuth() PointCoordinateType dipDir = 0.0f; ccNormalVectors::ConvertNormalToDipAndDipDir(N, dip, dipDir); QString dipAndDipDirStr = ccNormalVectors::ConvertDipAndDipDirToString(dip, dipDir); - m_app->dispToConsole("[VoxFall] Azimuth estimation: From existing plane"); + m_app->dispToConsole("[VoxFall] Orientation: From existing plane"); m_app->dispToConsole(QString("\t- %1").arg(dipAndDipDirStr)); + dipDoubleSpinBox->setValue(dip); azDoubleSpinBox->setValue(dipDir); return; } @@ -314,7 +321,7 @@ void qVoxFallDialog::autoComputeAzimuth() if (plane) { - m_app->dispToConsole(tr("[VoxFall] Azimuth estimation: Entity '%1'").arg(m_mesh1->getName())); + m_app->dispToConsole(tr("[VoxFall] Orientation: Fit plane to '%1'").arg(m_mesh1->getName())); m_app->dispToConsole(tr("\t- plane fitting RMS: %1").arg(rms)); //We always consider the normal with a positive 'Z' by default! @@ -328,6 +335,7 @@ void qVoxFallDialog::autoComputeAzimuth() ccNormalVectors::ConvertNormalToDipAndDipDir(N, dip, dipDir); QString dipAndDipDirStr = ccNormalVectors::ConvertDipAndDipDirToString(dip, dipDir); m_app->dispToConsole(QString("\t- %1").arg(dipAndDipDirStr)); + dipDoubleSpinBox->setValue(dip); azDoubleSpinBox->setValue(dipDir); //hack: output the transformation matrix that would make this normal points towards +Z diff --git a/src/qVoxFallProcess.cpp b/src/qVoxFallProcess.cpp index 7dc119b..7830118 100644 --- a/src/qVoxFallProcess.cpp +++ b/src/qVoxFallProcess.cpp @@ -390,6 +390,7 @@ bool qVoxFallProcess::Compute(const qVoxFallDialog& dlg, QString& errorMessage, } //get parameters from dialog + double dip = dlg.getDip(); double azimuth = dlg.getAzimuth(); //max thread count @@ -409,7 +410,7 @@ bool qVoxFallProcess::Compute(const qVoxFallDialog& dlg, QString& errorMessage, auto mesh = mesh1->cloneMesh(); mesh->merge(mesh2, false); - auto transform = qVoxFallTransform(azimuth); + auto transform = qVoxFallTransform(dip, azimuth); mesh->applyGLTransformation_recursive(&transform.matrix); mesh1->applyGLTransformation_recursive(&transform.matrix); diff --git a/src/qVoxFallTools.cpp b/src/qVoxFallTools.cpp index 5d20a99..b994752 100644 --- a/src/qVoxFallTools.cpp +++ b/src/qVoxFallTools.cpp @@ -36,33 +36,6 @@ #include - -float qVoxFallTransform::GetRotationAngle(double azimuth) -{ - if (azimuth > 180) - { - azimuth = azimuth - 180; - } - double azimuthRadians = azimuth * 3.14159 / 180; - - std::vector direction = { sin(azimuthRadians), cos(azimuthRadians) }; - std::vector xyView = { 0, 1 }; - - // compute dot product of unit vectors - double dotProduct = 0; - for (int i = 0; i < direction.size(); i++) - { - direction[i] = direction[i] / sqrt(direction[0] * direction[0] + direction[1] * direction[1]); - xyView[i] = xyView[i] / sqrt(xyView[0] * xyView[0] + xyView[1] * xyView[1]); - dotProduct += direction[i] * xyView[i]; - } - - float zRot = acos(std::max(-1.0, std::min(dotProduct, 1.0))); - - return zRot; -} - - ccBox* qVoxFallTransform::CreateVoxelMesh(CCVector3 V, float voxelSize, int voxelIdx) { CCVector3 dims = { voxelSize, voxelSize, voxelSize }; diff --git a/ui/qVoxFallDialog.ui b/ui/qVoxFallDialog.ui index b4b822d..45b5452 100644 --- a/ui/qVoxFallDialog.ui +++ b/ui/qVoxFallDialog.ui @@ -77,7 +77,7 @@ - Voxel size + Voxel size (m) @@ -97,20 +97,43 @@ - - - - - 0 - 0 - - + + + + + 0 + 0 + + + + Dip (deg) + + + + + + + 0 + + + 0.0 + + + 90.0 + + + 0.0 + + + + + - (Limit of Detection 95%) + Auto - + - + @@ -119,11 +142,11 @@ - Azimuth (deg) + / Dip direction (deg) - + 0 @@ -139,26 +162,6 @@ - - - - - 0 - 0 - - - - (Slope's dip direction) - - - - - - - Auto - - - @@ -181,7 +184,7 @@ - + ... @@ -237,7 +240,7 @@ swapMeshesToolButton voxelSizeDoubleSpinBox azDoubleSpinBox - autoAzimuthButton + autoFitPlaneButton generateReportBox exportCheckBox lossCheckBox