| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- //##########################################################################
- //# #
- //# CLOUDCOMPARE #
- //# #
- //# 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: SAGE INGENIERIE #
- //# #
- //##########################################################################
- #include "ccPlaneEditDlg.h"
- //local
- #include "mainwindow.h"
- //common
- #include <ccPickingHub.h>
- //qCC_db
- #include <ccPlane.h>
- #include <ccNormalVectors.h>
- //Qt
- #include <QDoubleValidator>
- //semi-persistent parameters
- static double s_dip = 0;
- static double s_dipDir = 0;
- static double s_width = 10.0;
- static double s_height = 10.0;
- static bool s_upward = true;
- static CCVector3d s_center(0, 0, 0);
- ccPlaneEditDlg::ccPlaneEditDlg(ccPickingHub* pickingHub, QWidget* parent)
- : QDialog(parent)
- , Ui::PlaneEditDlg()
- , m_pickingWin(nullptr)
- , m_associatedPlane(nullptr)
- , m_pickingHub(pickingHub)
- {
- assert(pickingHub);
- setModal(false);
- setupUi(this);
- //restore semi-persistent parameters
- dipDoubleSpinBox->setValue(s_dip);
- dipDirDoubleSpinBox->setValue(s_dipDir);
- upwardCheckBox->setChecked(s_upward);
- onDipDirChanged(0); //0 = fake argument
- wDoubleSpinBox->setValue(s_width);
- hDoubleSpinBox->setValue(s_height);
- cxAxisDoubleSpinBox->setValue(s_center.x);
- cyAxisDoubleSpinBox->setValue(s_center.y);
- czAxisDoubleSpinBox->setValue(s_center.z);
- connect(pickCenterToolButton, &QCheckBox::toggled, this, &ccPlaneEditDlg::pickPointAsCenter);
- connect(upwardCheckBox, &QCheckBox::toggled, this, &ccPlaneEditDlg::onDipDirModified);
- connect(dipDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccPlaneEditDlg::onDipDirChanged);
- connect(dipDirDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccPlaneEditDlg::onDipDirChanged);
- connect(nxDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccPlaneEditDlg::onNormalChanged);
- connect(nyDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccPlaneEditDlg::onNormalChanged);
- connect(nzDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccPlaneEditDlg::onNormalChanged);
- connect(buttonBox, &QDialogButtonBox::accepted, this, &ccPlaneEditDlg::saveParamsAndAccept);
- connect(buttonBox, &QDialogButtonBox::rejected, this, &ccPlaneEditDlg::deleteLater);
- //auto disable picking mode on quit
- connect(this, &QDialog::finished, [&]()
- {
- if (pickCenterToolButton->isChecked()) pickCenterToolButton->setChecked(false); }
- );
- }
- ccPlaneEditDlg::~ccPlaneEditDlg()
- {
- assert(!pickCenterToolButton->isChecked());
- }
- void ccPlaneEditDlg::saveParamsAndAccept()
- {
- //save semi-persistent parameters
- if (!m_associatedPlane)
- {
- s_dip = dipDoubleSpinBox->value();
- s_dipDir = dipDirDoubleSpinBox->value();
- s_upward = upwardCheckBox->isChecked();
- s_width = wDoubleSpinBox->value();
- s_height = hDoubleSpinBox->value();
- s_center.x = cxAxisDoubleSpinBox->value();
- s_center.y = cyAxisDoubleSpinBox->value();
- s_center.z = czAxisDoubleSpinBox->value();
- }
- //edition mode
- if (m_associatedPlane)
- {
- updatePlane(m_associatedPlane);
- if (MainWindow::TheInstance())
- MainWindow::TheInstance()->updatePropertiesView();
- m_associatedPlane->redrawDisplay();
- }
- else //creation
- {
- PointCoordinateType width = static_cast<PointCoordinateType>(wDoubleSpinBox->value());
- PointCoordinateType height = static_cast<PointCoordinateType>(hDoubleSpinBox->value());
- ccPlane* plane = new ccPlane(width, height);
- updatePlane(plane);
- if (m_pickingWin)
- {
- plane->setDisplay(m_pickingWin);
- }
- if (MainWindow::TheInstance())
- {
- MainWindow::TheInstance()->addToDB(plane);
- }
- else
- {
- delete plane;
- plane = nullptr;
- }
- }
- accept();
- deleteLater();
- }
- void ccPlaneEditDlg::onDipDirModified(bool)
- {
- onDipDirChanged(0); //0 = fake argument
- }
- void ccPlaneEditDlg::onDipDirChanged(double)
- {
- double dip = dipDoubleSpinBox->value();
- double dipDir = dipDirDoubleSpinBox->value();
- bool upward = upwardCheckBox->isChecked();
- CCVector3 Nd = ccNormalVectors::ConvertDipAndDipDirToNormal(static_cast<PointCoordinateType>(dip), static_cast<PointCoordinateType>(dipDir), upward);
- nxDoubleSpinBox->blockSignals(true);
- nyDoubleSpinBox->blockSignals(true);
- nzDoubleSpinBox->blockSignals(true);
-
- nxDoubleSpinBox->setValue(Nd.x);
- nyDoubleSpinBox->setValue(Nd.y);
- nzDoubleSpinBox->setValue(Nd.z);
-
- nxDoubleSpinBox->blockSignals(false);
- nyDoubleSpinBox->blockSignals(false);
- nzDoubleSpinBox->blockSignals(false);
- }
- void ccPlaneEditDlg::onNormalChanged(double)
- {
- CCVector3 Nd;
- Nd.x = nxDoubleSpinBox->value();
- Nd.y = nyDoubleSpinBox->value();
- Nd.z = nzDoubleSpinBox->value();
- Nd.normalize();
- PointCoordinateType dip = 0;
- PointCoordinateType dipDir = 0;
- ccNormalVectors::ConvertNormalToDipAndDipDir(Nd, dip, dipDir);
- dipDoubleSpinBox->blockSignals(true);
- dipDirDoubleSpinBox->blockSignals(true);
- upwardCheckBox->blockSignals(true);
-
- dipDoubleSpinBox->setValue(dip);
- dipDirDoubleSpinBox->setValue(dipDir);
- upwardCheckBox->setChecked(Nd.z >= 0);
-
- dipDoubleSpinBox->blockSignals(false);
- dipDirDoubleSpinBox->blockSignals(false);
- upwardCheckBox->blockSignals(false);
- }
- void ccPlaneEditDlg::pickPointAsCenter(bool state)
- {
- if (!m_pickingHub)
- {
- return;
- }
- if (state)
- {
- if (!m_pickingHub->addListener(this, true))
- {
- ccLog::Error("Can't start the picking process (another tool is using it)");
- state = false;
- }
- }
- else
- {
- m_pickingHub->removeListener(this);
- }
- pickCenterToolButton->blockSignals(true);
- pickCenterToolButton->setChecked(state);
- pickCenterToolButton->blockSignals(false);
- }
- void ccPlaneEditDlg::onItemPicked(const PickedItem& pi)
- {
- if (!pi.entity)
- {
- return;
- }
- m_pickingWin = m_pickingHub->activeWindow();
- cxAxisDoubleSpinBox->setValue(pi.P3D.x);
- cyAxisDoubleSpinBox->setValue(pi.P3D.y);
- czAxisDoubleSpinBox->setValue(pi.P3D.z);
- pickCenterToolButton->setChecked(false);
- }
- void ccPlaneEditDlg::initWithPlane(ccPlane* plane)
- {
- m_associatedPlane = plane;
- if (!plane)
- {
- assert(false);
- return;
- }
-
- CCVector3 N = plane->getNormal();
- //init the dialog
- nxDoubleSpinBox->blockSignals(true);
- nyDoubleSpinBox->blockSignals(true);
- nzDoubleSpinBox->blockSignals(true);
- nxDoubleSpinBox->setValue(N.x);
- nyDoubleSpinBox->setValue(N.y);
- nzDoubleSpinBox->setValue(N.z);
- nxDoubleSpinBox->blockSignals(false);
- nyDoubleSpinBox->blockSignals(false);
- nzDoubleSpinBox->blockSignals(false);
- onNormalChanged(0);
- //PointCoordinateType dip = 0, dipDir = 0;
- //ccNormalVectors::ConvertNormalToDipAndDipDir(N, dip, dipDir);
- //dipDoubleSpinBox->setValue(dip);
- //dipDirDoubleSpinBox->setValue(dipDir);
- //upwardCheckBox->setChecked(N.z >= 0);
- wDoubleSpinBox->setValue(plane->getXWidth());
- hDoubleSpinBox->setValue(plane->getYWidth());
-
- CCVector3 C = plane->getCenter();
- cxAxisDoubleSpinBox->setValue(C.x);
- cyAxisDoubleSpinBox->setValue(C.y);
- czAxisDoubleSpinBox->setValue(C.z);
- }
- void ccPlaneEditDlg::updatePlane(ccPlane* plane)
- {
- if (!plane)
- {
- assert(false);
- return;
- }
-
- double dip = dipDoubleSpinBox->value();
- double dipDir = dipDirDoubleSpinBox->value();
- bool upward = upwardCheckBox->isChecked();
- PointCoordinateType width = static_cast<PointCoordinateType>(wDoubleSpinBox->value());
- PointCoordinateType height = static_cast<PointCoordinateType>(hDoubleSpinBox->value());
- CCVector3 Nd = ccNormalVectors::ConvertDipAndDipDirToNormal(static_cast<PointCoordinateType>(dip), static_cast<PointCoordinateType>(dipDir), upward);
- CCVector3 Cd { static_cast<PointCoordinateType>(cxAxisDoubleSpinBox->value()),
- static_cast<PointCoordinateType>(cyAxisDoubleSpinBox->value()),
- static_cast<PointCoordinateType>(czAxisDoubleSpinBox->value()) };
-
- CCVector3 N = plane->getNormal();
- CCVector3 C = plane->getCenter();
- //shall we transform (translate and / or rotate) the plane?
- ccGLMatrix trans;
- bool needToApplyRot = (std::abs(N.dot(Nd) - CCCoreLib::PC_ONE) > std::numeric_limits<PointCoordinateType>::epsilon());
- bool needToApplyTrans = (needToApplyRot || ((C - Cd).norm2d() != 0));
- if (needToApplyTrans)
- {
- trans.setTranslation(-C);
- }
- if (needToApplyRot)
- {
- ccGLMatrix rotation;
- //special case: plane parallel to XY
- if (std::abs(N.z) > CCCoreLib::PC_ONE - std::numeric_limits<PointCoordinateType>::epsilon())
- {
- ccGLMatrix rotX; rotX.initFromParameters( CCCoreLib::DegreesToRadians( -dip ), CCVector3(1, 0, 0), CCVector3(0, 0, 0) ); //plunge
- ccGLMatrix rotZ; rotZ.initFromParameters( CCCoreLib::DegreesToRadians( dipDir ), CCVector3(0, 0, -1), CCVector3(0, 0, 0) );
- rotation = rotZ * rotX;
- }
- else //general case
- {
- rotation = ccGLMatrix::FromToRotation(N, Nd);
- }
- trans = rotation * trans;
- }
- if (needToApplyTrans)
- {
- trans.setTranslation(trans.getTranslationAsVec3D() + Cd);
- }
- if (needToApplyRot || needToApplyTrans)
- {
- plane->applyGLTransformation_recursive(&trans);
- ccLog::Print("[Plane edit] Applied transformation matrix:");
- ccLog::Print(trans.toString(12, ' ')); //full precision
- }
- if ( plane->getXWidth() != width
- || plane->getYWidth() != height)
- {
- plane->setXWidth(width, false);
- plane->setYWidth(height, true);
- }
- }
|