ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
sfEditDlg.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include "sfEditDlg.h"
9 
10 #include "ui_sfEditDlg.h"
11 
12 // LOCAL
13 #include "ecvHistogramWindow.h"
14 
15 // CV_CORE_LIB
16 #include <CVConst.h>
17 
18 // CV_DB_LIB
19 #include <ecvScalarField.h>
20 
21 // system
22 #include <assert.h>
23 
24 #include <cmath>
25 
27 const int SPIN_BOX_STEPS = 1000;
28 
29 sfEditDlg::sfEditDlg(QWidget* parent /*=0*/)
30  : QWidget(parent),
31  m_associatedSF(nullptr),
32  m_associatedSFHisto(nullptr),
33  m_ui(new Ui::SFEditDlg) {
34  m_ui->setupUi(this);
35 
36  // histogram window
37  {
39  QHBoxLayout* hboxLayout = new QHBoxLayout(m_ui->histoFrame);
40  hboxLayout->addWidget(m_associatedSFHisto);
41  hboxLayout->setContentsMargins(0, 0, 0, 0);
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 
50  connect(m_ui->minValSpinBox,
51  static_cast<void (QDoubleSpinBox::*)(double)>(
52  &QDoubleSpinBox::valueChanged),
54  connect(m_ui->maxValSpinBox,
55  static_cast<void (QDoubleSpinBox::*)(double)>(
56  &QDoubleSpinBox::valueChanged),
58  connect(m_ui->minSatSpinBox,
59  static_cast<void (QDoubleSpinBox::*)(double)>(
60  &QDoubleSpinBox::valueChanged),
62  connect(m_ui->maxSatSpinBox,
63  static_cast<void (QDoubleSpinBox::*)(double)>(
64  &QDoubleSpinBox::valueChanged),
66 
75 
76  // checkboxes
77  connect(m_ui->nanInGreyCheckBox, &QCheckBox::toggled, this,
79  connect(m_ui->alwaysShow0CheckBox, &QCheckBox::toggled, this,
81  connect(m_ui->symmetricalScaleCheckBox, &QCheckBox::toggled, this,
83  connect(m_ui->logScaleCheckBox, &QCheckBox::toggled, this,
85 
86  show();
87 }
88 
90 
92  m_associatedSF = sf;
93  if (!sf) {
94  assert(false);
95  setEnabled(false);
96  m_ui->histoFrame->setVisible(false);
97  return;
98  }
99 
100  // options (checkboxes)
101  {
102  bool nanValuesInGrey = sf->areNaNValuesShownInGrey();
103  bool alwaysShowZero = sf->isZeroAlwaysShown();
104  bool symmetricalScale = sf->symmetricalScale();
105  bool logScale = sf->logScale();
106  bool absoluteScale =
107  sf->getColorScale() && !sf->getColorScale()->isRelative();
108 
109  m_ui->nanInGreyCheckBox->blockSignals(true);
110  m_ui->nanInGreyCheckBox->setChecked(nanValuesInGrey);
111  m_ui->nanInGreyCheckBox->blockSignals(false);
112 
113  m_ui->alwaysShow0CheckBox->blockSignals(true);
114  m_ui->alwaysShow0CheckBox->setChecked(alwaysShowZero);
115  m_ui->alwaysShow0CheckBox->setEnabled(!logScale);
116  m_ui->alwaysShow0CheckBox->blockSignals(false);
117 
118  m_ui->symmetricalScaleCheckBox->blockSignals(true);
119  m_ui->symmetricalScaleCheckBox->setChecked(symmetricalScale);
120  m_ui->symmetricalScaleCheckBox->setEnabled(!absoluteScale && !logScale);
121  m_ui->symmetricalScaleCheckBox->blockSignals(false);
122 
123  m_ui->logScaleCheckBox->blockSignals(true);
124  m_ui->logScaleCheckBox->setChecked(logScale);
125  m_ui->logScaleCheckBox->blockSignals(false);
126 
127  if (logScale)
128  m_ui->satLabel->setText("log sat.");
129  else if (symmetricalScale)
130  m_ui->satLabel->setText("abs. sat.");
131  else
132  m_ui->satLabel->setText("saturation");
133  }
134 
135  // displayed and saturation values
136  {
137  const ccScalarField::Range& displayRange = sf->displayRange();
138  const ccScalarField::Range& saturationRange = sf->saturationRange();
139 
140  // special case: no need to actiate this widget for flat scalar field
141  //(worse, divisions by zero may occur!)
142  bool flatSF = (displayRange.maxRange() == 0);
143  m_ui->slidersFrame->setEnabled(!flatSF);
144 
145  // show histogram
146  m_ui->histoFrame->setVisible(true);
147  {
148  const ccScalarField::Histogram& histogram =
150  unsigned classNumber = static_cast<unsigned>(histogram.size());
151  if (classNumber == 0) classNumber = 128;
152  m_associatedSFHisto->fromSF(m_associatedSF, classNumber, false);
153  }
154 
155  /*** spinboxes ***/
156 
157  m_ui->minValSpinBox->blockSignals(true);
158  m_ui->minSatSpinBox->blockSignals(true);
159  m_ui->maxSatSpinBox->blockSignals(true);
160  m_ui->maxValSpinBox->blockSignals(true);
161 
162  if (!flatSF) {
163  // Minimum displayed value
164  m_ui->minValSpinBox->setRange(displayRange.min(),
165  displayRange.stop());
166  m_ui->minValSpinBox->setSingleStep(displayRange.maxRange() /
168  m_ui->minValSpinBox->setValue(displayRange.start());
169 
170  // Minimum color saturation value
171  m_ui->minSatSpinBox->setRange(saturationRange.min(),
172  saturationRange.stop());
173  m_ui->minSatSpinBox->setSingleStep(saturationRange.maxRange() /
175  m_ui->minSatSpinBox->setValue(saturationRange.start());
176 
177  // Maximum color saturation value slider
178  m_ui->maxSatSpinBox->setRange(saturationRange.start(),
179  saturationRange.max());
180  m_ui->maxSatSpinBox->setSingleStep(saturationRange.maxRange() /
182  m_ui->maxSatSpinBox->setValue(saturationRange.stop());
183 
184  // Maximum displayed value slider
185  m_ui->maxValSpinBox->setRange(displayRange.start(),
186  displayRange.max());
187  m_ui->maxValSpinBox->setSingleStep(displayRange.maxRange() /
189  m_ui->maxValSpinBox->setValue(displayRange.stop());
190  } else {
191  // unique value
192  double uniqueVal = displayRange.min();
193  m_ui->minValSpinBox->setRange(uniqueVal, uniqueVal);
194  m_ui->minSatSpinBox->setRange(uniqueVal, uniqueVal);
195  m_ui->maxSatSpinBox->setRange(uniqueVal, uniqueVal);
196  m_ui->maxValSpinBox->setRange(uniqueVal, uniqueVal);
197  }
198 
199  m_ui->minValSpinBox->blockSignals(false);
200  m_ui->minSatSpinBox->blockSignals(false);
201  m_ui->maxSatSpinBox->blockSignals(false);
202  m_ui->maxValSpinBox->blockSignals(false);
203  }
204 }
205 
206 void sfEditDlg::minValSBChanged(double val) {
207  if (!m_associatedSF) return;
208 
210 
211  emit entitySFHasChanged();
212 
213  QApplication::processEvents();
214 }
215 
216 void sfEditDlg::maxValSBChanged(double val) {
217  if (!m_associatedSF) return;
218 
220 
221  emit entitySFHasChanged();
222 
223  QApplication::processEvents();
224 }
225 
226 void sfEditDlg::minSatSBChanged(double val) {
227  if (!m_associatedSF) return;
228 
230 
231  emit entitySFHasChanged();
232 
233  QApplication::processEvents();
234 }
235 
236 void sfEditDlg::maxSatSBChanged(double val) {
237  if (!m_associatedSF) return;
238 
240 
241  emit entitySFHasChanged();
242 
243  QApplication::processEvents();
244 }
245 
247  if (!m_associatedSF) return;
248 
249  m_ui->minValSpinBox->blockSignals(true);
250  m_ui->minValSpinBox->setValue(val);
251  m_ui->minValSpinBox->blockSignals(false);
252 
253  emit entitySFHasChanged();
254 
255  QApplication::processEvents();
256 }
257 
259  if (!m_associatedSF) return;
260 
261  m_ui->maxValSpinBox->blockSignals(true);
262  m_ui->maxValSpinBox->setValue(val);
263  m_ui->maxValSpinBox->blockSignals(false);
264 
265  emit entitySFHasChanged();
266 
267  QApplication::processEvents();
268 }
269 
271  if (!m_associatedSF) return;
272 
273  m_ui->minSatSpinBox->blockSignals(true);
274  m_ui->minSatSpinBox->setValue(val);
275  m_ui->minSatSpinBox->blockSignals(false);
276 
277  emit entitySFHasChanged();
278 
279  QApplication::processEvents();
280 }
281 
283  if (!m_associatedSF) return;
284 
285  m_ui->maxSatSpinBox->blockSignals(true);
286  m_ui->maxSatSpinBox->setValue(val);
287  m_ui->maxSatSpinBox->blockSignals(false);
288 
289  emit entitySFHasChanged();
290 
291  QApplication::processEvents();
292 }
293 
294 void sfEditDlg::nanInGrayChanged(bool state) {
295  if (!m_associatedSF) return;
296 
297  if (m_associatedSF->areNaNValuesShownInGrey() != state) {
299  emit entitySFHasChanged();
300 
301  // m_associatedSFHisto->refreshBars();
302  }
303 }
304 
306  if (!m_associatedSF) return;
307 
308  if (m_associatedSF->isZeroAlwaysShown() != state) {
310  emit entitySFHasChanged();
311 
312  // m_associatedSFHisto->refreshBars();
313  }
314 }
315 
317  if (!m_associatedSF) return;
318 
319  if (m_associatedSF->symmetricalScale() != state) {
321  fillDialogWith(m_associatedSF); // the saturation sliders may need to
322  // be updated!
323  emit entitySFHasChanged();
324 
325  // Saturation might change!
327  // m_associatedSFHisto->refreshBars();
328  }
329 }
330 
331 void sfEditDlg::logScaleChanged(bool state) {
332  if (!m_associatedSF) return;
333 
334  if (m_associatedSF->logScale() != state) {
335  m_associatedSF->setLogScale(state);
337  m_associatedSF); // the saturation sliders + the symmetrical
338  // scale checkbox may need to be updated!
339  emit entitySFHasChanged();
340 
341  // Saturation might change!
343  // m_associatedSFHisto->refreshBars();
344  }
345 }
Histogram widget.
void setMinDispValue(double)
void sfMaxSatValChanged(double)
void sfMinSatValChanged(double)
void refresh()
Updates the display.
void fromSF(ccScalarField *sf, unsigned initialNumberOfClasses=0, bool numberOfClassesCanBeChanged=true, bool showNaNValuesInGrey=true)
Computes histogram from a scalar field.
void sfMinDispValChanged(double)
void setSFInteractionMode(SFInteractionModes modes)
Enables SF interaction mode.
void sfMaxDispValChanged(double)
void setMaxDispValue(double)
Scalar field range structure.
ScalarType stop() const
ScalarType min() const
ScalarType maxRange() const
ScalarType max() const
ScalarType start() const
A scalar field associated to display-related parameters.
const ccColorScale::Shared & getColorScale() const
Returns associated color scale.
bool logScale() const
Returns whether scalar field is logarithmic or not.
void alwaysShowZero(bool state)
Sets whether 0 should always appear in associated color ramp or not.
void setLogScale(bool state)
Sets whether scale is logarithmic or not.
void setSymmetricalScale(bool state)
Sets whether the color scale should be symmetrical or not.
const Range & saturationRange() const
Access to the range of saturation values.
const Histogram & getHistogram() const
Returns associated histogram values (for display)
void showNaNValuesInGrey(bool state)
const Range & displayRange() const
Access to the range of displayed values.
bool symmetricalScale() const
Returns whether the color scale s symmetrical or not.
bool areNaNValuesShownInGrey() const
Returns whether NaN values are displayed in gray or hidden.
bool isZeroAlwaysShown() const
Returns whether 0 should always appear in associated color ramp or not.
ccScalarField * m_associatedSF
Associated scalar field.
Definition: sfEditDlg.h:62
void minSatHistoChanged(double)
Definition: sfEditDlg.cpp:270
void minValSBChanged(double)
Definition: sfEditDlg.cpp:206
sfEditDlg(QWidget *parent=0)
Default constructor.
Definition: sfEditDlg.cpp:29
Ui::SFEditDlg * m_ui
Definition: sfEditDlg.h:66
void maxValHistoChanged(double)
Definition: sfEditDlg.cpp:258
void alwaysShow0Changed(bool)
Definition: sfEditDlg.cpp:305
ccHistogramWindow * m_associatedSFHisto
Associated scalar field histogram.
Definition: sfEditDlg.h:64
void logScaleChanged(bool)
Definition: sfEditDlg.cpp:331
void minSatSBChanged(double)
Definition: sfEditDlg.cpp:226
void entitySFHasChanged()
Signal emitted when the SF display parameters have changed.
void maxValSBChanged(double)
Definition: sfEditDlg.cpp:216
void maxSatSBChanged(double)
Definition: sfEditDlg.cpp:236
void minValHistoChanged(double)
Definition: sfEditDlg.cpp:246
void maxSatHistoChanged(double)
Definition: sfEditDlg.cpp:282
void fillDialogWith(ccScalarField *sf)
Updates dialog with a given scalar field.
Definition: sfEditDlg.cpp:91
void symmetricalScaleChanged(bool)
Definition: sfEditDlg.cpp:316
void nanInGrayChanged(bool)
Definition: sfEditDlg.cpp:294
const int SPIN_BOX_STEPS
Default number of steps for spin-boxes.
Definition: sfEditDlg.cpp:27
Simple histogram structure.