sfEditDlg.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  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 "sfEditDlg.h"
  18. #include "ui_sfEditDlg.h"
  19. //Local
  20. #include "ccHistogramWindow.h"
  21. //qCC_db
  22. #include <ccScalarField.h>
  23. //CCCoreLib
  24. #include <CCConst.h>
  25. //system
  26. #include <cassert>
  27. #include <cmath>
  28. //! Default number of steps for spin-boxes
  29. const int SPIN_BOX_STEPS = 1000;
  30. sfEditDlg::sfEditDlg(QWidget* parent/*=nullptr*/)
  31. : QWidget(parent)
  32. , m_associatedSF(nullptr)
  33. , m_associatedSFHisto(nullptr)
  34. , m_ui( new Ui::SFEditDlg )
  35. {
  36. m_ui->setupUi(this);
  37. //histogram window
  38. {
  39. m_associatedSFHisto = new ccHistogramWindow;
  40. QHBoxLayout* hboxLayout = new QHBoxLayout(m_ui->histoFrame);
  41. hboxLayout->addWidget(m_associatedSFHisto);
  42. hboxLayout->setContentsMargins(0, 0, 0, 0);
  43. m_associatedSFHisto->setSFInteractionMode(ccHistogramWindow::SFInteractionMode::All);
  44. m_associatedSFHisto->xAxis->setTickLabels(false);
  45. m_associatedSFHisto->xAxis->ticker()->setTickCount(6);
  46. m_associatedSFHisto->yAxis->setTickLabels(false);
  47. m_associatedSFHisto->yAxis->ticker()->setTickCount(3);
  48. }
  49. connect(m_ui->minValSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &sfEditDlg::minValSBChanged);
  50. connect(m_ui->maxValSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &sfEditDlg::maxValSBChanged);
  51. connect(m_ui->minSatSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &sfEditDlg::minSatSBChanged);
  52. connect(m_ui->maxSatSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &sfEditDlg::maxSatSBChanged);
  53. connect(m_associatedSFHisto, &ccHistogramWindow::sfMinDispValChanged, this, &sfEditDlg::minValHistoChanged);
  54. connect(m_associatedSFHisto, &ccHistogramWindow::sfMaxDispValChanged, this, &sfEditDlg::maxValHistoChanged);
  55. connect(m_associatedSFHisto, &ccHistogramWindow::sfMinSatValChanged, this, &sfEditDlg::minSatHistoChanged);
  56. connect(m_associatedSFHisto, &ccHistogramWindow::sfMaxSatValChanged, this, &sfEditDlg::maxSatHistoChanged);
  57. //checkboxes
  58. connect(m_ui->nanInGreyCheckBox, &QCheckBox::toggled, this, &sfEditDlg::nanInGrayChanged);
  59. connect(m_ui->alwaysShow0CheckBox, &QCheckBox::toggled, this, &sfEditDlg::alwaysShow0Changed);
  60. connect(m_ui->symmetricalScaleCheckBox, &QCheckBox::toggled, this, &sfEditDlg::symmetricalScaleChanged);
  61. connect(m_ui->logScaleCheckBox, &QCheckBox::toggled, this, &sfEditDlg::logScaleChanged);
  62. show();
  63. }
  64. sfEditDlg::~sfEditDlg()
  65. {
  66. delete m_ui;
  67. }
  68. void sfEditDlg::fillDialogWith(ccScalarField* sf)
  69. {
  70. m_associatedSF = sf;
  71. if (!sf)
  72. {
  73. assert(false);
  74. setEnabled(false);
  75. m_ui->histoFrame->setVisible(false);
  76. return;
  77. }
  78. //options (checkboxes)
  79. {
  80. bool nanValuesInGrey = sf->areNaNValuesShownInGrey();
  81. bool alwaysShowZero = sf->isZeroAlwaysShown();
  82. bool symmetricalScale = sf->symmetricalScale();
  83. bool logScale = sf->logScale();
  84. bool absoluteScale = sf->getColorScale() && !sf->getColorScale()->isRelative();
  85. m_ui->nanInGreyCheckBox->blockSignals(true);
  86. m_ui->nanInGreyCheckBox->setChecked(nanValuesInGrey);
  87. m_ui->nanInGreyCheckBox->blockSignals(false);
  88. m_ui->alwaysShow0CheckBox->blockSignals(true);
  89. m_ui->alwaysShow0CheckBox->setChecked(alwaysShowZero);
  90. m_ui->alwaysShow0CheckBox->setEnabled(!logScale);
  91. m_ui->alwaysShow0CheckBox->blockSignals(false);
  92. m_ui->symmetricalScaleCheckBox->blockSignals(true);
  93. m_ui->symmetricalScaleCheckBox->setChecked(symmetricalScale);
  94. m_ui->symmetricalScaleCheckBox->setEnabled(!absoluteScale && !logScale);
  95. m_ui->symmetricalScaleCheckBox->blockSignals(false);
  96. m_ui->logScaleCheckBox->blockSignals(true);
  97. m_ui->logScaleCheckBox->setChecked(logScale);
  98. m_ui->logScaleCheckBox->blockSignals(false);
  99. if (logScale)
  100. m_ui->satLabel->setText("log sat.");
  101. else if (symmetricalScale)
  102. m_ui->satLabel->setText("abs. sat.");
  103. else
  104. m_ui->satLabel->setText("saturation");
  105. }
  106. //displayed and saturation values
  107. {
  108. const ccScalarField::Range& displayRange = sf->displayRange();
  109. const ccScalarField::Range& saturationRange = sf->saturationRange();
  110. //special case: no need to actiate this widget for flat scalar field
  111. //(worse, divisions by zero may occur!)
  112. bool flatSF = (displayRange.maxRange() == 0);
  113. m_ui->slidersFrame->setEnabled(!flatSF);
  114. //show histogram
  115. m_ui->histoFrame->setVisible(true);
  116. {
  117. const ccScalarField::Histogram& histogram = m_associatedSF->getHistogram();
  118. unsigned classNumber = static_cast<unsigned>(histogram.size());
  119. if (classNumber == 0)
  120. classNumber = 128;
  121. m_associatedSFHisto->fromSF(m_associatedSF, classNumber, false);
  122. }
  123. /*** spinboxes ***/
  124. m_ui->minValSpinBox->blockSignals(true);
  125. m_ui->minSatSpinBox->blockSignals(true);
  126. m_ui->maxSatSpinBox->blockSignals(true);
  127. m_ui->maxValSpinBox->blockSignals(true);
  128. if (!flatSF)
  129. {
  130. //Minimum displayed value
  131. m_ui->minValSpinBox->setRange(displayRange.min(), displayRange.stop());
  132. m_ui->minValSpinBox->setSingleStep(displayRange.maxRange() / SPIN_BOX_STEPS);
  133. m_ui->minValSpinBox->setValue(displayRange.start());
  134. //Minimum color saturation value
  135. m_ui->minSatSpinBox->setRange(saturationRange.min(), saturationRange.stop());
  136. m_ui->minSatSpinBox->setSingleStep(saturationRange.maxRange() / SPIN_BOX_STEPS);
  137. m_ui->minSatSpinBox->setValue(saturationRange.start());
  138. // Maximum color saturation value slider
  139. m_ui->maxSatSpinBox->setRange(saturationRange.start(), saturationRange.max());
  140. m_ui->maxSatSpinBox->setSingleStep(saturationRange.maxRange() / SPIN_BOX_STEPS);
  141. m_ui->maxSatSpinBox->setValue(saturationRange.stop());
  142. // Maximum displayed value slider
  143. m_ui->maxValSpinBox->setRange(displayRange.start(), displayRange.max());
  144. m_ui->maxValSpinBox->setSingleStep(displayRange.maxRange() / SPIN_BOX_STEPS);
  145. m_ui->maxValSpinBox->setValue(displayRange.stop());
  146. }
  147. else
  148. {
  149. //unique value
  150. double uniqueVal = displayRange.min();
  151. m_ui->minValSpinBox->setRange(uniqueVal, uniqueVal);
  152. m_ui->minSatSpinBox->setRange(uniqueVal, uniqueVal);
  153. m_ui->maxSatSpinBox->setRange(uniqueVal, uniqueVal);
  154. m_ui->maxValSpinBox->setRange(uniqueVal, uniqueVal);
  155. }
  156. m_ui->minValSpinBox->blockSignals(false);
  157. m_ui->minSatSpinBox->blockSignals(false);
  158. m_ui->maxSatSpinBox->blockSignals(false);
  159. m_ui->maxValSpinBox->blockSignals(false);
  160. }
  161. }
  162. void sfEditDlg::minValSBChanged(double val)
  163. {
  164. if (!m_associatedSF)
  165. return;
  166. m_associatedSFHisto->setMinDispValue(val);
  167. Q_EMIT entitySFHasChanged();
  168. QApplication::processEvents();
  169. }
  170. void sfEditDlg::maxValSBChanged(double val)
  171. {
  172. if (!m_associatedSF)
  173. return;
  174. m_associatedSFHisto->setMaxDispValue(val);
  175. Q_EMIT entitySFHasChanged();
  176. QApplication::processEvents();
  177. }
  178. void sfEditDlg::minSatSBChanged(double val)
  179. {
  180. if (!m_associatedSF)
  181. return;
  182. m_associatedSFHisto->setMinSatValue(val);
  183. Q_EMIT entitySFHasChanged();
  184. QApplication::processEvents();
  185. }
  186. void sfEditDlg::maxSatSBChanged(double val)
  187. {
  188. if (!m_associatedSF)
  189. return;
  190. m_associatedSFHisto->setMaxSatValue(val);
  191. Q_EMIT entitySFHasChanged();
  192. QApplication::processEvents();
  193. }
  194. void sfEditDlg::minValHistoChanged(double val)
  195. {
  196. if (!m_associatedSF)
  197. return;
  198. m_ui->minValSpinBox->blockSignals(true);
  199. m_ui->minValSpinBox->setValue(val);
  200. m_ui->minValSpinBox->blockSignals(false);
  201. Q_EMIT entitySFHasChanged();
  202. QApplication::processEvents();
  203. }
  204. void sfEditDlg::maxValHistoChanged(double val)
  205. {
  206. if (!m_associatedSF)
  207. return;
  208. m_ui->maxValSpinBox->blockSignals(true);
  209. m_ui->maxValSpinBox->setValue(val);
  210. m_ui->maxValSpinBox->blockSignals(false);
  211. Q_EMIT entitySFHasChanged();
  212. QApplication::processEvents();
  213. }
  214. void sfEditDlg::minSatHistoChanged(double val)
  215. {
  216. if (!m_associatedSF)
  217. return;
  218. m_ui->minSatSpinBox->blockSignals(true);
  219. m_ui->minSatSpinBox->setValue(val);
  220. m_ui->minSatSpinBox->blockSignals(false);
  221. Q_EMIT entitySFHasChanged();
  222. QApplication::processEvents();
  223. }
  224. void sfEditDlg::maxSatHistoChanged(double val)
  225. {
  226. if (!m_associatedSF)
  227. return;
  228. m_ui->maxSatSpinBox->blockSignals(true);
  229. m_ui->maxSatSpinBox->setValue(val);
  230. m_ui->maxSatSpinBox->blockSignals(false);
  231. Q_EMIT entitySFHasChanged();
  232. QApplication::processEvents();
  233. }
  234. void sfEditDlg::nanInGrayChanged(bool state)
  235. {
  236. if (!m_associatedSF)
  237. return;
  238. if (m_associatedSF->areNaNValuesShownInGrey() != state)
  239. {
  240. m_associatedSF->showNaNValuesInGrey(state);
  241. Q_EMIT entitySFHasChanged();
  242. //m_associatedSFHisto->refreshBars();
  243. }
  244. }
  245. void sfEditDlg::alwaysShow0Changed(bool state)
  246. {
  247. if (!m_associatedSF)
  248. return;
  249. if (m_associatedSF->isZeroAlwaysShown() != state)
  250. {
  251. m_associatedSF->alwaysShowZero(state);
  252. Q_EMIT entitySFHasChanged();
  253. //m_associatedSFHisto->refreshBars();
  254. }
  255. }
  256. void sfEditDlg::symmetricalScaleChanged(bool state)
  257. {
  258. if (!m_associatedSF)
  259. return;
  260. if (m_associatedSF->symmetricalScale() != state)
  261. {
  262. m_associatedSF->setSymmetricalScale(state);
  263. fillDialogWith(m_associatedSF); //the saturation sliders may need to be updated!
  264. Q_EMIT entitySFHasChanged();
  265. //Saturation might change!
  266. m_associatedSFHisto->refresh();
  267. //m_associatedSFHisto->refreshBars();
  268. }
  269. }
  270. void sfEditDlg::logScaleChanged(bool state)
  271. {
  272. if (!m_associatedSF)
  273. return;
  274. if (m_associatedSF->logScale() != state)
  275. {
  276. m_associatedSF->setLogScale(state);
  277. fillDialogWith(m_associatedSF); //the saturation sliders + the symmetrical scale checkbox may need to be updated!
  278. Q_EMIT entitySFHasChanged();
  279. //Saturation might change!
  280. m_associatedSFHisto->refresh();
  281. //m_associatedSFHisto->refreshBars();
  282. }
  283. }