ccApplyTransformationDlg.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577
  1. //##########################################################################
  2. //# #
  3. //# CLOUDCOMPARE #
  4. //# #
  5. //# This program is free software; you can redistribute it and/or modify #
  6. //# it under the terms of the GNU General Public License as published by #
  7. //# the Free Software Foundation; version 2 or later of the License. #
  8. //# #
  9. //# This program is distributed in the hope that it will be useful, #
  10. //# but WITHOUT ANY WARRANTY; without even the implied warranty of #
  11. //# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
  12. //# GNU General Public License for more details. #
  13. //# #
  14. //# COPYRIGHT: EDF R&D / TELECOM ParisTech (ENST-TSI) #
  15. //# #
  16. //##########################################################################
  17. #include "ccApplyTransformationDlg.h"
  18. //Local
  19. #include "ccPersistentSettings.h"
  20. #include "mainwindow.h"
  21. #include "ccUtils.h"
  22. #include "ui_dipDirTransformationDlg.h"
  23. //qCC_db
  24. #include <ccFileUtils.h>
  25. #include <ccNormalVectors.h>
  26. //Qt
  27. #include <QMessageBox>
  28. #include <QSettings>
  29. #include <QFileDialog>
  30. #include <QFileInfo>
  31. #include <QClipboard>
  32. //CCCoreLib
  33. #include <CCConst.h>
  34. static QString s_lastMatrix("1.00000000 0.00000000 0.00000000 0.00000000\n0.00000000 1.00000000 0.00000000 0.00000000\n0.00000000 0.00000000 1.00000000 0.00000000\n0.00000000 0.00000000 0.00000000 1.00000000");
  35. static bool s_inverseMatrix = false;
  36. static bool s_applyToGlobal = false;
  37. static int s_currentFormIndex = 0;
  38. //! Dialog to define a dip / dip dir. transformation
  39. class DipDirTransformationDialog : public QDialog, public Ui::DipDirTransformationDialog
  40. {
  41. Q_OBJECT
  42. public:
  43. DipDirTransformationDialog(QWidget* parent = nullptr) : QDialog(parent) { setupUi(this); }
  44. };
  45. ccApplyTransformationDlg::ccApplyTransformationDlg(QWidget* parent/*=nullptr*/)
  46. : QDialog(parent)
  47. , Ui::ApplyTransformationDialog()
  48. {
  49. setupUi(this);
  50. helpTextEdit->setVisible(false);
  51. //restore last state
  52. matrixTextEdit->setPlainText(s_lastMatrix);
  53. inverseCheckBox->setChecked(s_inverseMatrix);
  54. applyToGlobalCheckBox->setChecked(s_applyToGlobal);
  55. onMatrixTextChange(); //provoke the update of the other forms
  56. tabWidget->setCurrentIndex(s_currentFormIndex);
  57. connect(buttonBox, &QDialogButtonBox::accepted, this, &ccApplyTransformationDlg::checkMatrixValidityAndAccept);
  58. connect(buttonBox, &QDialogButtonBox::clicked, this, &ccApplyTransformationDlg::buttonClicked);
  59. connect(matrixTextEdit, &QPlainTextEdit::textChanged, this, &ccApplyTransformationDlg::onMatrixTextChange);
  60. connect(fromFileToolButton, &QToolButton::clicked, this, &ccApplyTransformationDlg::loadFromASCIIFile);
  61. connect(fromClipboardToolButton, &QToolButton::clicked, this, &ccApplyTransformationDlg::loadFromClipboard);
  62. connect(fromDipDipDirToolButton, &QToolButton::clicked, this, &ccApplyTransformationDlg::initFromDipAndDipDir);
  63. // Axis and angle
  64. connect(rxAxisDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onRotAngleValueChanged);
  65. connect(ryAxisDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onRotAngleValueChanged);
  66. connect(rzAxisDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onRotAngleValueChanged);
  67. connect(rAngleDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onRotAngleValueChanged);
  68. connect(txAxisDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onRotAngleValueChanged);
  69. connect(tyAxisDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onRotAngleValueChanged);
  70. connect(tzAxisDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onRotAngleValueChanged);
  71. connect(scaleDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onRotAngleValueChanged);
  72. connect(setIAxisToolButton, &QToolButton::clicked, [this] {rxAxisDoubleSpinBox->setValue(1.0); ryAxisDoubleSpinBox->setValue(0.0); rzAxisDoubleSpinBox->setValue(0.0); });
  73. connect(setJAxisToolButton, &QToolButton::clicked, [this] {rxAxisDoubleSpinBox->setValue(0.0); ryAxisDoubleSpinBox->setValue(1.0); rzAxisDoubleSpinBox->setValue(0.0); });
  74. connect(setKAxisToolButton, &QToolButton::clicked, [this] {rxAxisDoubleSpinBox->setValue(0.0); ryAxisDoubleSpinBox->setValue(0.0); rzAxisDoubleSpinBox->setValue(1.0); });
  75. connect(pasteAxisToolButton, &QToolButton::clicked, this, &ccApplyTransformationDlg::axisFromClipboard);
  76. connect(pasteTransToolButton, &QToolButton::clicked, this, &ccApplyTransformationDlg::transFromClipboard);
  77. // Euler angles
  78. connect(ePhiDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onEulerValueChanged);
  79. connect(eThetaDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onEulerValueChanged);
  80. connect(ePsiDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onEulerValueChanged);
  81. connect(etxAxisDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onEulerValueChanged);
  82. connect(etyAxisDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onEulerValueChanged);
  83. connect(etzAxisDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onEulerValueChanged);
  84. connect(eScaleDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onEulerValueChanged);
  85. connect(pasteEulerAnglesToolButton, &QToolButton::clicked, this, &ccApplyTransformationDlg::eulerAnglesFromClipboard);
  86. connect(pasteEulerTransToolButton, &QToolButton::clicked, this, &ccApplyTransformationDlg::eulerTransFromClipboard);
  87. // From-->to axes
  88. connect(fromXAxisDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onFromToValueChanged);
  89. connect(fromYAxisDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onFromToValueChanged);
  90. connect(fromZAxisDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onFromToValueChanged);
  91. connect(toXAxisDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onFromToValueChanged);
  92. connect(toYAxisDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onFromToValueChanged);
  93. connect(toZAxisDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onFromToValueChanged);
  94. connect(fromToTxAxisDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onFromToValueChanged);
  95. connect(fromToTyAxisDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onFromToValueChanged);
  96. connect(fromToTzAxisDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onFromToValueChanged);
  97. connect(fromToScaleDoubleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &ccApplyTransformationDlg::onFromToValueChanged);
  98. connect(pasteFromAxisToolButton, &QToolButton::clicked, this, &ccApplyTransformationDlg::fromAxisFromClipboard);
  99. connect(pasteToAxisToolButton, &QToolButton::clicked, this, &ccApplyTransformationDlg::toAxisFromClipboard);
  100. connect(pasteFromToTransToolButton, &QToolButton::clicked, this, &ccApplyTransformationDlg::fromToTransFromClipboard);
  101. connect(setFromAxisIToolButton, &QToolButton::clicked, [this] {fromXAxisDoubleSpinBox->setValue(1.0); fromYAxisDoubleSpinBox->setValue(0.0); fromZAxisDoubleSpinBox->setValue(0.0); });
  102. connect(setFromAxisJToolButton, &QToolButton::clicked, [this] {fromXAxisDoubleSpinBox->setValue(0.0); fromYAxisDoubleSpinBox->setValue(1.0); fromZAxisDoubleSpinBox->setValue(0.0); });
  103. connect(setFromAxisKToolButton, &QToolButton::clicked, [this] {fromXAxisDoubleSpinBox->setValue(0.0); fromYAxisDoubleSpinBox->setValue(0.0); fromZAxisDoubleSpinBox->setValue(1.0); });
  104. connect(setToAxisIToolButton, &QToolButton::clicked, [this] {toXAxisDoubleSpinBox->setValue(1.0); toYAxisDoubleSpinBox->setValue(0.0); toZAxisDoubleSpinBox->setValue(0.0); });
  105. connect(setToAxisJToolButton, &QToolButton::clicked, [this] {toXAxisDoubleSpinBox->setValue(0.0); toYAxisDoubleSpinBox->setValue(1.0); toZAxisDoubleSpinBox->setValue(0.0); });
  106. connect(setToAxisKToolButton, &QToolButton::clicked, [this] {toXAxisDoubleSpinBox->setValue(0.0); toYAxisDoubleSpinBox->setValue(0.0); toZAxisDoubleSpinBox->setValue(1.0); });
  107. }
  108. void ccApplyTransformationDlg::onMatrixTextChange()
  109. {
  110. QString text = matrixTextEdit->toPlainText();
  111. if (text.contains("["))
  112. {
  113. //automatically remove anything between square brackets
  114. static const QRegExp squareBracketsFilter("\\[([^]]+)\\]");
  115. text.replace(squareBracketsFilter, "");
  116. matrixTextEdit->blockSignals(true);
  117. matrixTextEdit->setPlainText(text);
  118. matrixTextEdit->blockSignals(false);
  119. }
  120. bool valid = false;
  121. ccGLMatrixd mat = ccGLMatrixd::FromString(text, valid);
  122. if (valid)
  123. {
  124. updateAll(mat, false, true, true, true); //no need to update the current form
  125. }
  126. }
  127. void ccApplyTransformationDlg::onRotAngleValueChanged(double)
  128. {
  129. double alpha = 0.0;
  130. CCVector3d axis(0.0, 0.0, 1.0);
  131. CCVector3d t(0.0, 0.0, 0.0);
  132. double scale = 1.0;
  133. axis.x = rxAxisDoubleSpinBox->value();
  134. axis.y = ryAxisDoubleSpinBox->value();
  135. axis.z = rzAxisDoubleSpinBox->value();
  136. alpha = CCCoreLib::DegreesToRadians(rAngleDoubleSpinBox->value());
  137. t.x = txAxisDoubleSpinBox->value();
  138. t.y = tyAxisDoubleSpinBox->value();
  139. t.z = tzAxisDoubleSpinBox->value();
  140. scale = scaleDoubleSpinBox->value();
  141. ccGLMatrixd mat;
  142. mat.initFromParameters(alpha, axis, t);
  143. if (scale != 1)
  144. {
  145. mat.scaleRotation(scale);
  146. }
  147. updateAll(mat, true, false, true, true); //no need to update the current form
  148. }
  149. void ccApplyTransformationDlg::onEulerValueChanged(double)
  150. {
  151. double phi = 0.0;
  152. double theta = 0.0;
  153. double psi = 0.0;
  154. CCVector3d t(0.0, 0.0, 0.0);
  155. double scale = 1.0;
  156. phi = CCCoreLib::DegreesToRadians(ePhiDoubleSpinBox->value());
  157. theta = CCCoreLib::DegreesToRadians(eThetaDoubleSpinBox->value());
  158. psi = CCCoreLib::DegreesToRadians(ePsiDoubleSpinBox->value());
  159. t.x = etxAxisDoubleSpinBox->value();
  160. t.y = etyAxisDoubleSpinBox->value();
  161. t.z = etzAxisDoubleSpinBox->value();
  162. scale = eScaleDoubleSpinBox->value();
  163. ccGLMatrixd mat;
  164. mat.initFromParameters(phi, theta, psi, t);
  165. if (scale != 1)
  166. {
  167. mat.scaleRotation(scale);
  168. }
  169. updateAll(mat, true, true, false, true); //no need to update the current form
  170. }
  171. void ccApplyTransformationDlg::onFromToValueChanged(double)
  172. {
  173. CCVector3d fromAxis(0.0, 0.0, 1.0), toAxis(0.0, 0.0, 1.0);
  174. CCVector3d t(0.0, 0.0, 0.0);
  175. double scale = 1.0;
  176. fromAxis.x = fromXAxisDoubleSpinBox->value();
  177. fromAxis.y = fromYAxisDoubleSpinBox->value();
  178. fromAxis.z = fromZAxisDoubleSpinBox->value();
  179. toAxis.x = toXAxisDoubleSpinBox->value();
  180. toAxis.y = toYAxisDoubleSpinBox->value();
  181. toAxis.z = toZAxisDoubleSpinBox->value();
  182. t.x = fromToTxAxisDoubleSpinBox->value();
  183. t.y = fromToTyAxisDoubleSpinBox->value();
  184. t.z = fromToTzAxisDoubleSpinBox->value();
  185. scale = fromToScaleDoubleSpinBox->value();
  186. fromAxis.normalize();
  187. toAxis.normalize();
  188. ccGLMatrixd mat = ccGLMatrixd::FromToRotation(fromAxis, toAxis);
  189. mat.setTranslation(t);
  190. if (scale != 1.0)
  191. {
  192. mat.scaleRotation(scale);
  193. }
  194. updateAll(mat, true, true, true, false); //no need to update the current form
  195. }
  196. void ccApplyTransformationDlg::updateAll( const ccGLMatrixd& mat,
  197. bool textForm/*=true*/,
  198. bool axisAngleForm/*=true*/,
  199. bool eulerForm/*=true*/,
  200. bool fromToForm/*=true*/ )
  201. {
  202. if (textForm)
  203. {
  204. QString matText = mat.toString();
  205. matrixTextEdit->blockSignals(true);
  206. matrixTextEdit->setPlainText(matText);
  207. matrixTextEdit->blockSignals(false);
  208. }
  209. if (axisAngleForm)
  210. {
  211. rxAxisDoubleSpinBox->blockSignals(true);
  212. ryAxisDoubleSpinBox->blockSignals(true);
  213. rzAxisDoubleSpinBox->blockSignals(true);
  214. rAngleDoubleSpinBox->blockSignals(true);
  215. txAxisDoubleSpinBox->blockSignals(true);
  216. tyAxisDoubleSpinBox->blockSignals(true);
  217. tzAxisDoubleSpinBox->blockSignals(true);
  218. scaleDoubleSpinBox ->blockSignals(true);
  219. double alpha = 0.0;
  220. CCVector3d axis(0.0, 0.0, 1.0);
  221. CCVector3d t(0.0, 0.0, 0.0);
  222. double scale = 1.0;
  223. mat.getParameters(alpha, axis, t, &scale);
  224. rxAxisDoubleSpinBox->setValue(axis.x);
  225. ryAxisDoubleSpinBox->setValue(axis.y);
  226. rzAxisDoubleSpinBox->setValue(axis.z);
  227. rAngleDoubleSpinBox->setValue(CCCoreLib::RadiansToDegrees(alpha));
  228. txAxisDoubleSpinBox->setValue(t.x);
  229. tyAxisDoubleSpinBox->setValue(t.y);
  230. tzAxisDoubleSpinBox->setValue(t.z);
  231. scaleDoubleSpinBox ->setValue(scale);
  232. rxAxisDoubleSpinBox->blockSignals(false);
  233. ryAxisDoubleSpinBox->blockSignals(false);
  234. rzAxisDoubleSpinBox->blockSignals(false);
  235. rAngleDoubleSpinBox->blockSignals(false);
  236. txAxisDoubleSpinBox->blockSignals(false);
  237. tyAxisDoubleSpinBox->blockSignals(false);
  238. tzAxisDoubleSpinBox->blockSignals(false);
  239. scaleDoubleSpinBox ->blockSignals(false);
  240. }
  241. if (eulerForm)
  242. {
  243. ePhiDoubleSpinBox ->blockSignals(true);
  244. eThetaDoubleSpinBox ->blockSignals(true);
  245. ePsiDoubleSpinBox ->blockSignals(true);
  246. etxAxisDoubleSpinBox->blockSignals(true);
  247. etyAxisDoubleSpinBox->blockSignals(true);
  248. etzAxisDoubleSpinBox->blockSignals(true);
  249. eScaleDoubleSpinBox ->blockSignals(true);
  250. double phi = 0.0;
  251. double theta = 0.0;
  252. double psi = 0.0;
  253. CCVector3d t(0.0, 0.0, 0.0);
  254. double scale = 1.0;
  255. mat.getParameters(phi, theta, psi, t, &scale);
  256. ePhiDoubleSpinBox ->setValue(CCCoreLib::RadiansToDegrees(phi));
  257. eThetaDoubleSpinBox ->setValue(CCCoreLib::RadiansToDegrees(theta));
  258. ePsiDoubleSpinBox ->setValue(CCCoreLib::RadiansToDegrees(psi));
  259. etxAxisDoubleSpinBox->setValue(t.x);
  260. etyAxisDoubleSpinBox->setValue(t.y);
  261. etzAxisDoubleSpinBox->setValue(t.z);
  262. eScaleDoubleSpinBox ->setValue(scale);
  263. ePhiDoubleSpinBox ->blockSignals(false);
  264. eThetaDoubleSpinBox ->blockSignals(false);
  265. ePsiDoubleSpinBox ->blockSignals(false);
  266. etxAxisDoubleSpinBox->blockSignals(false);
  267. etyAxisDoubleSpinBox->blockSignals(false);
  268. etzAxisDoubleSpinBox->blockSignals(false);
  269. eScaleDoubleSpinBox ->blockSignals(false);
  270. }
  271. if (fromToForm)
  272. {
  273. fromXAxisDoubleSpinBox ->blockSignals(true);
  274. fromYAxisDoubleSpinBox ->blockSignals(true);
  275. fromZAxisDoubleSpinBox ->blockSignals(true);
  276. toXAxisDoubleSpinBox ->blockSignals(true);
  277. toYAxisDoubleSpinBox ->blockSignals(true);
  278. toZAxisDoubleSpinBox ->blockSignals(true);
  279. fromToTxAxisDoubleSpinBox->blockSignals(true);
  280. fromToTyAxisDoubleSpinBox->blockSignals(true);
  281. fromToTzAxisDoubleSpinBox->blockSignals(true);
  282. fromToScaleDoubleSpinBox ->blockSignals(true);
  283. CCVector3d from(0.0, 0.0, 1.0);
  284. CCVector3d to = from;
  285. mat.applyRotation(to);
  286. double scale = mat.getColumnAsVec3D(0).norm();
  287. CCVector3d t = mat.getTranslationAsVec3D();
  288. fromXAxisDoubleSpinBox ->setValue(from.x);
  289. fromYAxisDoubleSpinBox ->setValue(from.y);
  290. fromZAxisDoubleSpinBox ->setValue(from.z);
  291. toXAxisDoubleSpinBox ->setValue(to.x);
  292. toYAxisDoubleSpinBox ->setValue(to.y);
  293. toZAxisDoubleSpinBox ->setValue(to.z);
  294. fromToTxAxisDoubleSpinBox->setValue(t.x);
  295. fromToTyAxisDoubleSpinBox->setValue(t.y);
  296. fromToTzAxisDoubleSpinBox->setValue(t.z);
  297. fromToScaleDoubleSpinBox ->setValue(scale);
  298. fromXAxisDoubleSpinBox ->blockSignals(false);
  299. fromYAxisDoubleSpinBox ->blockSignals(false);
  300. fromZAxisDoubleSpinBox ->blockSignals(false);
  301. toXAxisDoubleSpinBox ->blockSignals(false);
  302. toYAxisDoubleSpinBox ->blockSignals(false);
  303. toZAxisDoubleSpinBox ->blockSignals(false);
  304. fromToTxAxisDoubleSpinBox->blockSignals(false);
  305. fromToTyAxisDoubleSpinBox->blockSignals(false);
  306. fromToTzAxisDoubleSpinBox->blockSignals(false);
  307. fromToScaleDoubleSpinBox ->blockSignals(false);
  308. }
  309. }
  310. ccGLMatrixd ccApplyTransformationDlg::getTransformation(bool& applyToGlobal) const
  311. {
  312. //get current input matrix text
  313. QString matText = matrixTextEdit->toPlainText();
  314. //convert it to a ccGLMatrix
  315. bool valid = false;
  316. ccGLMatrixd mat = ccGLMatrixd::FromString(matText, valid);
  317. assert(valid);
  318. //eventually invert it if necessary
  319. if (inverseCheckBox->isChecked())
  320. {
  321. mat.invert();
  322. }
  323. applyToGlobal = applyToGlobalCheckBox->isChecked();
  324. return mat;
  325. }
  326. void ccApplyTransformationDlg::checkMatrixValidityAndAccept()
  327. {
  328. //get current input matrix text
  329. QString matText = matrixTextEdit->toPlainText();
  330. //convert it to a ccGLMatrix
  331. bool valid = false;
  332. ccGLMatrix mat = ccGLMatrix::FromString(matText, valid);
  333. if (!valid)
  334. {
  335. QMessageBox::warning(this, "Invalid matrix", "Matrix is invalid. Make sure to only use white spaces or tabulations between the 16 elements");
  336. return;
  337. }
  338. accept();
  339. s_lastMatrix = matrixTextEdit->toPlainText();
  340. s_inverseMatrix = inverseCheckBox->isChecked();
  341. s_applyToGlobal = applyToGlobalCheckBox->isChecked();
  342. s_currentFormIndex = tabWidget->currentIndex();
  343. }
  344. void ccApplyTransformationDlg::loadFromASCIIFile()
  345. {
  346. //persistent settings
  347. QSettings settings;
  348. settings.beginGroup(ccPS::LoadFile());
  349. QString currentPath = settings.value(ccPS::CurrentPath(), ccFileUtils::defaultDocPath()).toString();
  350. QString inputFilename = QFileDialog::getOpenFileName(this, "Select input file", currentPath, "*.txt");
  351. if (inputFilename.isEmpty())
  352. return;
  353. ccGLMatrixd mat;
  354. if (mat.fromAsciiFile(inputFilename))
  355. {
  356. matrixTextEdit->setPlainText(mat.toString());
  357. }
  358. else
  359. {
  360. ccLog::Error(QString("Failed to load file '%1'").arg(inputFilename));
  361. }
  362. //save last loading location
  363. settings.setValue(ccPS::CurrentPath(), QFileInfo(inputFilename).absolutePath());
  364. settings.endGroup();
  365. }
  366. void ccApplyTransformationDlg::loadFromClipboard()
  367. {
  368. QClipboard* clipboard = QApplication::clipboard();
  369. if (clipboard)
  370. {
  371. QString clipText = clipboard->text();
  372. if (!clipText.isEmpty())
  373. {
  374. matrixTextEdit->setPlainText(clipText);
  375. }
  376. else
  377. {
  378. ccLog::Warning("[ccApplyTransformationDlg] Clipboard is empty");
  379. }
  380. }
  381. }
  382. void ccApplyTransformationDlg::initFromDipAndDipDir()
  383. {
  384. static double s_dip_deg = 0.0;
  385. static double s_dipDir_deg = 0.0;
  386. static bool s_rotateAboutCenter = false;
  387. DipDirTransformationDialog dddDlg(this);
  388. dddDlg.dipDoubleSpinBox->setValue(s_dip_deg);
  389. dddDlg.dipDirDoubleSpinBox->setValue(s_dipDir_deg);
  390. dddDlg.rotateAboutCenterCheckBox->setChecked(s_rotateAboutCenter);
  391. if (!dddDlg.exec())
  392. {
  393. return;
  394. }
  395. s_dip_deg = dddDlg.dipDoubleSpinBox->value();
  396. s_dipDir_deg = dddDlg.dipDirDoubleSpinBox->value();
  397. s_rotateAboutCenter = dddDlg.rotateAboutCenterCheckBox->isChecked();
  398. //resulting normal vector
  399. CCVector3d Nd = ccNormalVectors::ConvertDipAndDipDirToNormal(s_dip_deg, s_dipDir_deg);
  400. //corresponding rotation (assuming we start from (0, 0, 1))
  401. ccGLMatrixd trans = ccGLMatrixd::FromToRotation(CCVector3d(0.0, 0.0, 1.0), Nd);
  402. if (s_rotateAboutCenter && MainWindow::TheInstance())
  403. {
  404. const ccHObject::Container& selectedEntities = MainWindow::TheInstance()->getSelectedEntities();
  405. ccBBox box;
  406. for (ccHObject* obj : selectedEntities)
  407. {
  408. box += obj->getBB_recursive();
  409. }
  410. if (box.isValid())
  411. {
  412. CCVector3d C = box.getCenter().toDouble();
  413. ccGLMatrixd shiftToCenter;
  414. shiftToCenter.setTranslation(-C);
  415. ccGLMatrixd backToOrigin;
  416. backToOrigin.setTranslation(C);
  417. trans = backToOrigin * trans * shiftToCenter;
  418. }
  419. }
  420. updateAll(trans, true, true, true, true);
  421. }
  422. void ccApplyTransformationDlg::buttonClicked(QAbstractButton* button)
  423. {
  424. if (buttonBox->buttonRole(button) == QDialogButtonBox::ResetRole)
  425. {
  426. updateAll({}, true, true, true, true);
  427. inverseCheckBox->setChecked(false);
  428. }
  429. }
  430. void ccApplyTransformationDlg::axisFromClipboard()
  431. {
  432. CCVector3d vector;
  433. if (ccUtils::GetVectorFromClipboard(vector))
  434. {
  435. rxAxisDoubleSpinBox->setValue(vector.x);
  436. ryAxisDoubleSpinBox->setValue(vector.y);
  437. rzAxisDoubleSpinBox->setValue(vector.z);
  438. }
  439. }
  440. void ccApplyTransformationDlg::transFromClipboard()
  441. {
  442. CCVector3d vector;
  443. if (ccUtils::GetVectorFromClipboard(vector))
  444. {
  445. txAxisDoubleSpinBox->setValue(vector.x);
  446. tyAxisDoubleSpinBox->setValue(vector.y);
  447. tzAxisDoubleSpinBox->setValue(vector.z);
  448. }
  449. }
  450. void ccApplyTransformationDlg::eulerAnglesFromClipboard()
  451. {
  452. CCVector3d vector;
  453. if (ccUtils::GetVectorFromClipboard(vector))
  454. {
  455. ePhiDoubleSpinBox->setValue(vector.x);
  456. eThetaDoubleSpinBox->setValue(vector.y);
  457. ePsiDoubleSpinBox->setValue(vector.z);
  458. }
  459. }
  460. void ccApplyTransformationDlg::eulerTransFromClipboard()
  461. {
  462. CCVector3d vector;
  463. if (ccUtils::GetVectorFromClipboard(vector))
  464. {
  465. etxAxisDoubleSpinBox->setValue(vector.x);
  466. etyAxisDoubleSpinBox->setValue(vector.y);
  467. etzAxisDoubleSpinBox->setValue(vector.z);
  468. }
  469. }
  470. void ccApplyTransformationDlg::fromAxisFromClipboard()
  471. {
  472. CCVector3d vector;
  473. if (ccUtils::GetVectorFromClipboard(vector))
  474. {
  475. fromXAxisDoubleSpinBox->setValue(vector.x);
  476. fromYAxisDoubleSpinBox->setValue(vector.y);
  477. fromZAxisDoubleSpinBox->setValue(vector.z);
  478. }
  479. }
  480. void ccApplyTransformationDlg::toAxisFromClipboard()
  481. {
  482. CCVector3d vector;
  483. if (ccUtils::GetVectorFromClipboard(vector))
  484. {
  485. toXAxisDoubleSpinBox->setValue(vector.x);
  486. toYAxisDoubleSpinBox->setValue(vector.y);
  487. toZAxisDoubleSpinBox->setValue(vector.z);
  488. }
  489. }
  490. void ccApplyTransformationDlg::fromToTransFromClipboard()
  491. {
  492. CCVector3d vector;
  493. if (ccUtils::GetVectorFromClipboard(vector))
  494. {
  495. fromToTxAxisDoubleSpinBox->setValue(vector.x);
  496. fromToTyAxisDoubleSpinBox->setValue(vector.y);
  497. fromToTzAxisDoubleSpinBox->setValue(vector.z);
  498. }
  499. }
  500. #include "ccApplyTransformationDlg.moc"