ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
ecvScalarField.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 "ecvScalarField.h"
9 
10 // Local
11 #include "ecvColorScalesManager.h"
12 
13 // cloudViewer
14 #include <CVConst.h>
15 
16 // system
17 #include <algorithm>
18 
19 using namespace cloudViewer;
20 
22 const unsigned MAX_HISTOGRAM_SIZE = 512;
23 
25  : ScalarField(name),
26  m_showNaNValuesInGrey(true),
27  m_symmetricalScale(false),
28  m_logScale(false),
29  m_alwaysShowZero(false),
30  m_colorScale(nullptr),
31  m_colorRampSteps(0),
32  m_modified(true),
33  m_globalShift(0) {
37 }
38 
40  : ScalarField(sf),
41  m_displayRange(sf.m_displayRange),
42  m_saturationRange(sf.m_saturationRange),
43  m_logSaturationRange(sf.m_logSaturationRange),
44  m_showNaNValuesInGrey(sf.m_showNaNValuesInGrey),
45  m_symmetricalScale(sf.m_symmetricalScale),
46  m_logScale(sf.m_logScale),
47  m_alwaysShowZero(sf.m_alwaysShowZero),
48  m_colorScale(sf.m_colorScale),
49  m_colorRampSteps(sf.m_colorRampSteps),
50  m_histogram(sf.m_histogram),
51  m_modified(sf.m_modified),
52  m_globalShift(sf.m_globalShift) {
54 }
55 
56 ScalarType ccScalarField::normalize(ScalarType d) const {
58  d)) // NaN values are also rejected by 'isInRange'!
59  {
60  return static_cast<ScalarType>(-1);
61  }
62 
63  // most probable path first!
64  if (!m_logScale) {
65  if (!m_symmetricalScale) {
66  if (d <= m_saturationRange.start())
67  return 0;
68  else if (d >= m_saturationRange.stop())
69  return static_cast<ScalarType>(1);
71  } else // symmetric scale
72  {
73  if (fabs(d) <= m_saturationRange.start())
74  return static_cast<ScalarType>(0.5);
75 
76  if (d >= 0) {
77  if (d >= m_saturationRange.stop())
78  return static_cast<ScalarType>(1);
79  return (static_cast<ScalarType>(1) +
80  (d - m_saturationRange.start()) /
82  2;
83  } else {
84  if (d <= -m_saturationRange.stop()) return 0;
85  return (static_cast<ScalarType>(1) +
86  (d + m_saturationRange.start()) /
88  2;
89  }
90  }
91  } else // log scale
92  {
93  ScalarType dLog = log10(std::max(static_cast<ScalarType>(fabs(d)),
95  if (dLog <= m_logSaturationRange.start())
96  return 0;
97  else if (dLog >= m_logSaturationRange.stop())
98  return static_cast<ScalarType>(1);
99  return (dLog - m_logSaturationRange.start()) /
101  }
102 
103  // can't get here normally!
104  assert(false);
105  return static_cast<ScalarType>(-1);
106 }
107 
109  if (m_colorScale != scale) {
110  bool wasAbsolute = (m_colorScale && !m_colorScale->isRelative());
111  bool isAbsolute = (scale && !scale->isRelative());
112 
113  m_colorScale = scale;
114 
115  if (isAbsolute) m_symmetricalScale = false;
116 
117  if (isAbsolute || wasAbsolute != isAbsolute) updateSaturationBounds();
118 
119  m_modified = true;
120  }
121 }
122 
124  if (m_symmetricalScale != state) {
125  m_symmetricalScale = state;
127 
128  m_modified = true;
129  }
130 }
131 
132 void ccScalarField::setLogScale(bool state) {
133  if (m_logScale != state) {
134  m_logScale = state;
135  if (m_logScale && m_minVal < 0) {
137  "[ccScalarField] Scalar field contains negative values! "
138  "Log scale will only consider absolute values...");
139  }
140 
141  m_modified = true;
142  }
143 }
144 
146  ScalarField::computeMinAndMax();
147 
149 
150  // update histogram
151  {
152  if (m_displayRange.maxRange() == 0 || currentSize() == 0) {
153  // can't build histogram of a flat field
154  m_histogram.clear();
155  } else {
156  unsigned count = currentSize();
157  unsigned numberOfClasses = static_cast<unsigned>(
158  ceil(sqrt(static_cast<double>(count))));
159  numberOfClasses = std::max<unsigned>(
160  std::min<unsigned>(numberOfClasses, MAX_HISTOGRAM_SIZE), 4);
161 
162  m_histogram.maxValue = 0;
163 
164  // reserve memory
165  try {
166  m_histogram.resize(numberOfClasses);
167  } catch (const std::bad_alloc&) {
169  "[ccScalarField::computeMinAndMax] Failed to update "
170  "associated histogram!");
171  m_histogram.clear();
172  }
173 
174  if (!m_histogram.empty()) {
175  std::fill(m_histogram.begin(), m_histogram.end(), 0);
176 
177  // compute histogram
178  {
179  ScalarType step = static_cast<ScalarType>(numberOfClasses) /
181  for (unsigned i = 0; i < count; ++i) {
182  const ScalarType& val = getValue(i);
183 
184  unsigned bin = static_cast<unsigned>(
185  floor((val - m_displayRange.min()) * step));
186  ++m_histogram[std::min(bin, numberOfClasses - 1)];
187  }
188  }
189 
190  // update 'maxValue'
191  m_histogram.maxValue = *std::max_element(m_histogram.begin(),
192  m_histogram.end());
193  }
194  }
195  }
196 
197  m_modified = true;
198 
200 }
201 
203  if (!m_colorScale ||
204  m_colorScale->isRelative()) // Relative scale (default)
205  {
206  ScalarType minAbsVal =
207  (m_maxVal < 0 ? std::min(-m_maxVal, -m_minVal)
208  : std::max<ScalarType>(m_minVal, 0));
209  ScalarType maxAbsVal = std::max(fabs(m_minVal), fabs(m_maxVal));
210 
211  if (m_symmetricalScale) {
212  m_saturationRange.setBounds(minAbsVal, maxAbsVal);
213  } else {
215  }
216 
217  // log scale (we always update it even if m_logScale is not enabled!)
218  // if (m_logScale)
219  {
220  ScalarType minSatLog =
221  log10(std::max(minAbsVal, ZERO_TOLERANCE_SCALAR));
222  ScalarType maxSatLog =
223  log10(std::max(maxAbsVal, ZERO_TOLERANCE_SCALAR));
224  m_logSaturationRange.setBounds(minSatLog, maxSatLog);
225  }
226  } else // absolute scale
227  {
228  // DGM: same formulas as for the 'relative scale' case but we use the
229  // boundaries defined by the scale itself instead of the current SF
230  // boundaries...
231  double minVal = 0, maxVal = 0;
232  m_colorScale->getAbsoluteBoundaries(minVal, maxVal);
233 
234  m_saturationRange.setBounds(static_cast<ScalarType>(minVal),
235  static_cast<ScalarType>(maxVal));
236 
237  // log scale (we always update it even if m_logScale is not enabled!)
238  // if (m_logScale)
239  {
240  ScalarType minAbsVal = static_cast<ScalarType>(
241  maxVal < 0 ? std::min(-maxVal, -minVal)
242  : std::max(minVal, 0.0));
243  ScalarType maxAbsVal = static_cast<ScalarType>(
244  std::max(fabs(minVal), fabs(maxVal)));
245  ScalarType minSatLog =
246  log10(std::max(minAbsVal, ZERO_TOLERANCE_SCALAR));
247  ScalarType maxSatLog =
248  log10(std::max(maxAbsVal, ZERO_TOLERANCE_SCALAR));
249  m_logSaturationRange.setBounds(minSatLog, maxSatLog);
250  }
251  }
252 
253  m_modified = true;
254 }
255 
256 void ccScalarField::setMinDisplayed(ScalarType val) {
258  m_modified = true;
259 }
260 
261 void ccScalarField::setMaxDisplayed(ScalarType val) {
262  m_displayRange.setStop(val);
263  m_modified = true;
264 }
265 
266 void ccScalarField::setSaturationStart(ScalarType val) {
267  if (m_logScale) {
268  m_logSaturationRange.setStart(val/*log10(std::max(val, static_cast<ScalarType>(ZERO_TOLERANCE_F)))*/);
269  } else {
271  }
272  m_modified = true;
273 }
274 
275 void ccScalarField::setSaturationStop(ScalarType val) {
276  if (m_logScale) {
277  m_logSaturationRange.setStop(val/*log10(std::max(val, static_cast<ScalarType>(ZERO_TOLERANCE_F)))*/);
278  } else {
280  }
281  m_modified = true;
282 }
283 
284 void ccScalarField::setColorRampSteps(unsigned steps) {
285  if (steps > ccColorScale::MAX_STEPS)
287  else if (steps < ccColorScale::MIN_STEPS)
289  else
290  m_colorRampSteps = steps;
291 
292  m_modified = true;
293 }
294 
295 bool ccScalarField::toFile(QFile& out, short dataVersion) const {
296  assert(out.isOpen() && (out.openMode() & QIODevice::WriteOnly));
297 
298  if (dataVersion < 20) {
299  assert(false);
300  return false;
301  }
302 
303  // name (dataVersion>=20)
304  if (out.write(m_name, 256) < 0) return WriteError();
305 
306  // data (dataVersion>=20)
307  if (!ccSerializationHelper::GenericArrayToFile<ScalarType, 1, ScalarType>(
308  *this, out))
309  return WriteError();
310 
311  // displayed values & saturation boundaries (dataVersion>=20)
312  double dValue = (double)m_displayRange.start();
313  if (out.write((const char*)&dValue, sizeof(double)) < 0)
314  return WriteError();
315  dValue = (double)m_displayRange.stop();
316  if (out.write((const char*)&dValue, sizeof(double)) < 0)
317  return WriteError();
318  dValue = (double)m_saturationRange.start();
319  if (out.write((const char*)&dValue, sizeof(double)) < 0)
320  return WriteError();
321  dValue = (double)m_saturationRange.stop();
322  if (out.write((const char*)&dValue, sizeof(double)) < 0)
323  return WriteError();
324  dValue = (double)m_logSaturationRange.start();
325  if (out.write((const char*)&dValue, sizeof(double)) < 0)
326  return WriteError();
327  dValue = (double)m_logSaturationRange.stop();
328  if (out.write((const char*)&dValue, sizeof(double)) < 0)
329  return WriteError();
330 
331  //'logarithmic scale' state (dataVersion>=20)
332  if (out.write((const char*)&m_logScale, sizeof(bool)) < 0)
333  return WriteError();
334 
335  //'symmetrical scale' state (dataVersion>=27)
336  if (dataVersion >= 27) {
337  if (out.write((const char*)&m_symmetricalScale, sizeof(bool)) < 0)
338  return WriteError();
339 
340  //'NaN values in grey' state (dataVersion>=27)
341  if (out.write((const char*)&m_showNaNValuesInGrey, sizeof(bool)) < 0)
342  return WriteError();
343 
344  //'always show 0' state (dataVersion>=27)
345  if (out.write((const char*)&m_alwaysShowZero, sizeof(bool)) < 0)
346  return WriteError();
347 
348  // color scale (dataVersion>=27)
349  {
350  bool hasColorScale = (m_colorScale != nullptr);
351  if (out.write((const char*)&hasColorScale, sizeof(bool)) < 0)
352  return WriteError();
353 
354  if (m_colorScale)
355  if (!m_colorScale->toFile(out, dataVersion))
356  return WriteError();
357  }
358  }
359 
360  // color ramp steps (dataVersion>=20)
361  uint32_t colorRampSteps = (uint32_t)m_colorRampSteps;
362  if (out.write((const char*)&colorRampSteps, 4) < 0) return WriteError();
363 
364  // global shift (dataVersion>=42)
365  if (dataVersion >= 42) {
366  if (out.write((const char*)&m_globalShift, sizeof(double)) < 0)
367  return WriteError();
368  }
369 
370  return true;
371 }
372 
374  // we need version 42 to save a non-zero global shift
375  short minVersion = (getGlobalShift() != 0.0 ? 42 : 27);
376 
377  if (strlen(m_name) > 255) {
378  // we need version 52 to save a name longer than 255 characters
379  minVersion = std::max(minVersion, static_cast<short>(52));
380  }
381 
382  if (m_colorScale) {
383  // we need a certain version to save the color scale depending on its
384  // contents
385  minVersion = std::max(minVersion, m_colorScale->minimumFileVersion());
386  }
387  return minVersion;
388 }
389 
390 bool ccScalarField::fromFile(QFile& in,
391  short dataVersion,
392  int flags,
393  LoadedIDMap& oldToNewIDMap) {
394  assert(in.isOpen() && (in.openMode() & QIODevice::ReadOnly));
395 
396  if (dataVersion < 20) return CorruptError();
397 
398  // name (dataVersion >= 20)
399  if (in.read(m_name, 256) < 0) return ReadError();
400 
401  //'strictly positive' state (20 <= dataVersion < 26)
402  bool onlyPositiveValues = false;
403  if (dataVersion < 26) {
404  if (in.read((char*)&onlyPositiveValues, sizeof(bool)) < 0)
405  return ReadError();
406  }
407 
408  // data (dataVersion >= 20)
409  bool result = false;
410  {
411  QString sfDescription = "SF " + QString(m_name);
412  double baseOffset = 0.0;
413  bool fileScalarIsFloat =
415  if (fileScalarIsFloat) // file is 'float'
416  {
418  ScalarType>(
419  *this, in, dataVersion, sfDescription);
420  } else // file is 'double'
421  {
422  // we load it as float, but apply an automatic offset (based on the
423  // first element) to not lose information/accuracy
425  ScalarType, 1, ScalarType, double>(
426  *this, in, dataVersion, sfDescription, &baseOffset);
427  }
428  }
429  if (!result) {
430  return false;
431  }
432 
433  // convert former 'hidden/NaN' values for non strictly positive SFs
434  // (dataVersion < 26)
435  if (dataVersion < 26) {
436  const ScalarType FORMER_BIG_VALUE =
437  static_cast<ScalarType>(sqrt(3.4e38f) - 1.0f);
438 
439  for (unsigned i = 0; i < currentSize(); ++i) {
440  ScalarType& val = getValue(i);
441  // convert former 'HIDDEN_VALUE' and 'BIG_VALUE' to 'NAN_VALUE'
442  if ((onlyPositiveValues && val < 0) ||
443  (!onlyPositiveValues && val >= FORMER_BIG_VALUE)) {
444  val = NAN_VALUE;
445  }
446  }
447  }
448 
450 
451  // displayed values & saturation boundaries (dataVersion>=20)
452  double minDisplayed = 0;
453  if (in.read((char*)&minDisplayed, sizeof(double)) < 0) return ReadError();
454  double maxDisplayed = 0;
455  if (in.read((char*)&maxDisplayed, sizeof(double)) < 0) return ReadError();
456  double minSaturation = 0;
457  if (in.read((char*)&minSaturation, sizeof(double)) < 0) return ReadError();
458  double maxSaturation = 0;
459  if (in.read((char*)&maxSaturation, sizeof(double)) < 0) return ReadError();
460  double minLogSaturation = 0;
461  if (in.read((char*)&minLogSaturation, sizeof(double)) < 0)
462  return ReadError();
463  double maxLogSaturation = 0;
464  if (in.read((char*)&maxLogSaturation, sizeof(double)) < 0)
465  return ReadError();
466 
467  if (dataVersion < 27) {
468  //'absolute saturation' state (27>dataVersion>=20)
469  bool absSaturation = false;
470  if (in.read((char*)&absSaturation, sizeof(bool)) < 0)
471  return ReadError();
472  // quite equivalent to 'symmetrical mode' now...
473  m_symmetricalScale = absSaturation;
474  }
475 
476  //'logarithmic scale' state (dataVersion>=20)
477  if (in.read((char*)&m_logScale, sizeof(bool)) < 0) {
478  return ReadError();
479  }
480 
481  if (dataVersion < 27) {
482  bool autoBoundaries = false;
483  //'automatic boundaries update' state (dataVersion>=20)
484  if (in.read((char*)&autoBoundaries, sizeof(bool)) < 0) {
485  return ReadError();
486  }
487  // warn the user that this option is deprecated
488  if (!autoBoundaries) {
490  "[ccScalarField] Former 'released' boundaries are "
491  "deprecated!");
493  "[ccScalarField] You'll have to create the corresponding "
494  "'absolute' color scale (see the Color Scale Manager) and "
495  "replace the file.");
496  }
497  }
498 
499  // new attributes
500  if (dataVersion >= 27) {
501  //'symmetrical scale' state (27<=dataVersion)
502  if (in.read((char*)&m_symmetricalScale, sizeof(bool)) < 0)
503  return ReadError();
504 
505  //'NaN values in grey' state (dataVersion>=27)
506  if (in.read((char*)&m_showNaNValuesInGrey, sizeof(bool)) < 0)
507  return ReadError();
508 
509  //'always show 0' state (27<=dataVersion)
510  if (in.read((char*)&m_alwaysShowZero, sizeof(bool)) < 0)
511  return ReadError();
512  }
513 
514  // color scale
515  {
516  ccColorScalesManager* colorScalesManager =
518  if (!colorScalesManager) {
520  "[ccScalarField::fromFile] Failed to access color scales "
521  "manager?!");
522  assert(false);
523  }
524 
525  // old versions
526  if (dataVersion < 27) {
527  uint32_t activeColorScale = 0;
528  if (in.read((char*)&activeColorScale, 4) < 0) return ReadError();
529 
530  // Retrieve equivalent default scale
531  ccColorScalesManager::DEFAULT_SCALES activeColorScaleType =
533  switch (activeColorScale) {
535  activeColorScaleType = ccColorScalesManager::BGYR;
536  break;
538  activeColorScaleType = ccColorScalesManager::GREY;
539  break;
541  activeColorScaleType = ccColorScalesManager::BWR;
542  break;
544  activeColorScaleType = ccColorScalesManager::RY;
545  break;
547  activeColorScaleType = ccColorScalesManager::RW;
548  break;
549  default:
551  "[ccScalarField::fromFile] Color scale is no more "
552  "supported!");
553  break;
554  }
555  m_colorScale =
556  ccColorScalesManager::GetDefaultScale(activeColorScaleType);
557  } else //(dataVersion>=27)
558  {
559  bool hasColorScale = false;
560  if (in.read((char*)&hasColorScale, sizeof(bool)) < 0)
561  return ReadError();
562 
563  if (hasColorScale) {
564  ccColorScale::Shared colorScale = ccColorScale::Create("temp");
565  if (!colorScale->fromFile(in, dataVersion, flags,
566  oldToNewIDMap))
567  return ReadError();
568  m_colorScale = colorScale;
569 
570  if (colorScalesManager) {
571  ccColorScale::Shared existingColorScale =
572  colorScalesManager->getScale(colorScale->getUuid());
573  if (!existingColorScale) {
574  colorScalesManager->addScale(colorScale);
575  } else // same UUID?
576  {
577  // FIXME: we should look if the color scale is exactly
578  // the same!
579  m_colorScale = existingColorScale;
580  }
581  }
582  }
583  }
584 
585  // A scalar field must have a color scale!
586  if (!m_colorScale)
588 
589  // color ramp steps (dataVersion>=20)
590  uint32_t colorRampSteps = 0;
591  if (in.read((char*)&colorRampSteps, 4) < 0) return ReadError();
592  setColorRampSteps(static_cast<unsigned>(colorRampSteps));
593  }
594 
595  if (dataVersion >= 42) {
596  // global shift (dataVersion>=42)
597  if (in.read((char*)&m_globalShift, sizeof(double)) < 0)
598  return ReadError();
599  }
600 
601  // update values
603  m_displayRange.setStart((ScalarType)minDisplayed);
604  m_displayRange.setStop((ScalarType)maxDisplayed);
605  m_saturationRange.setStart((ScalarType)minSaturation);
606  m_saturationRange.setStop((ScalarType)maxSaturation);
607  m_logSaturationRange.setStart((ScalarType)minLogSaturation);
608  m_logSaturationRange.setStop((ScalarType)maxLogSaturation);
609 
610  m_modified = true;
611 
612  return true;
613 }
614 
616  bool hiddenPoints = (!areNaNValuesShownInGrey() &&
619 
620  return hiddenPoints;
621 }
622 
624  m_showNaNValuesInGrey = state;
625  m_modified = true;
626 }
627 
629  m_alwaysShowZero = state;
630  m_modified = true;
631 }
632 
634  if (!sf) {
635  assert(false);
636  return;
637  }
638 
642  setLogScale(sf->logScale());
649 }
constexpr ScalarType ZERO_TOLERANCE_SCALAR
Definition: CVConst.h:57
constexpr ScalarType NAN_VALUE
NaN as a ScalarType value.
Definition: CVConst.h:76
std::string name
int count
core::Tensor result
Definition: VtkUtils.cpp:76
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
Definition: CVLog.cpp:133
static const unsigned DEFAULT_STEPS
Default number of steps for display.
static const unsigned MIN_STEPS
Minimum number of steps.
Definition: ecvColorScale.h:99
QSharedPointer< ccColorScale > Shared
Shared pointer type.
Definition: ecvColorScale.h:74
static ccColorScale::Shared Create(const QString &name)
Creates a new color scale (with auto-generated unique id)
static const unsigned MAX_STEPS
Maximum number of steps (internal representation)
Color scales manager/container.
ccColorScale::Shared getScale(QString UUID) const
Returns a color scale based on its UUID.
void addScale(ccColorScale::Shared scale)
Adds a new color scale.
static ccColorScale::Shared GetDefaultScale(DEFAULT_SCALES scale=BGYR)
Returns a pre-defined color scale (static shortcut)
DEFAULT_SCALES
Pre-defined color scales (all relative - i.e. expand to actual SF)
static ccColorScalesManager * GetUniqueInstance()
Returns unique instance.
void setStop(ScalarType value)
ScalarType stop() const
ScalarType min() const
ScalarType maxRange() const
bool isInRange(ScalarType val) const
Returns whether a value is inside range or not.
ScalarType max() const
void setBounds(ScalarType minVal, ScalarType maxVal, bool resetStartStop=true)
void setStart(ScalarType value)
ScalarType range() const
ScalarType start() const
A scalar field associated to display-related parameters.
const ccColorScale::Shared & getColorScale() const
Returns associated color scale.
Range m_logSaturationRange
saturation values range (log scale mode)
void setSaturationStop(ScalarType val)
Sets the value at which to stop color gradient.
void setColorRampSteps(unsigned steps)
Sets number of color ramp steps used for display.
double m_globalShift
Global shift.
short minimumFileVersion() const override
Returns the minimum file version required to save this instance.
void setMinDisplayed(ScalarType val)
Sets the minimum displayed value.
bool m_showNaNValuesInGrey
Whether NaN values are shown in grey or are hidden.
void updateSaturationBounds()
Updates saturation values.
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.
unsigned getColorRampSteps() const
Returns number of color ramp steps.
Range m_displayRange
Displayed values range.
void setLogScale(bool state)
Sets whether scale is logarithmic or not.
void setColorScale(ccColorScale::Shared scale)
Sets associated color scale.
bool toFile(QFile &out, short dataVersion) const override
Saves data to binary stream.
double getGlobalShift() const
Returns the global shift (if any)
Histogram m_histogram
Associated histogram values (for display)
void setSymmetricalScale(bool state)
Sets whether the color scale should be symmetrical or not.
bool fromFile(QFile &in, short dataVersion, int flags, LoadedIDMap &oldToNewIDMap) override
Loads data from binary stream.
unsigned m_colorRampSteps
Number of color ramps steps (for display)
bool m_alwaysShowZero
Whether 0 should always appear in associated color ramp.
const Range & saturationRange() const
Access to the range of saturation values.
ScalarType normalize(ScalarType val) const
Normalizes a scalar value between 0 and 1 (wrt to current parameters)
bool m_symmetricalScale
Whether color scale is symmetrical or not.
void showNaNValuesInGrey(bool state)
const Range & displayRange() const
Access to the range of displayed values.
bool m_logScale
Whether scale is logarithmic or not.
void computeMinAndMax() override
Determines the min and max values.
bool symmetricalScale() const
Returns whether the color scale s symmetrical or not.
void importParametersFrom(const ccScalarField *sf)
Imports the parameters from another scalar field.
bool m_modified
Modification flag.
bool mayHaveHiddenValues() const
void setSaturationStart(ScalarType val)
Sets the value at which to start color gradient.
void setMaxDisplayed(ScalarType val)
Sets the maximum displayed value.
Range m_saturationRange
Saturation values range.
ccScalarField(const char *name=nullptr)
Default constructor.
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.
ccColorScale::Shared m_colorScale
Active color ramp (for display)
static bool CorruptError()
Sends a custom error message (corrupted file) and returns 'false'.
QMultiMap< unsigned, unsigned > LoadedIDMap
Map of loaded unique IDs (old ID --> new ID)
static bool ReadError()
Sends a custom error message (read error) and returns 'false'.
static bool WriteError()
Sends a custom error message (write error) and returns 'false'.
static bool GenericArrayFromFile(std::vector< Type > &data, QFile &in, short dataVersion, const QString &verboseDescription)
Helper: loads a vector structure from file.
static bool GenericArrayFromTypedFile(std::vector< Type > &data, QFile &in, short dataVersion, const QString &verboseDescription, FileComponentType *_autoOffset=nullptr)
A simple scalar field (to be associated to a point cloud)
Definition: ScalarField.h:25
ScalarType & getValue(std::size_t index)
Definition: ScalarField.h:92
char m_name[256]
Scalar field name.
Definition: ScalarField.h:115
ScalarType m_maxVal
Maximum value.
Definition: ScalarField.h:120
unsigned currentSize() const
Definition: ScalarField.h:100
ScalarType m_minVal
Minimum value.
Definition: ScalarField.h:118
const unsigned MAX_HISTOGRAM_SIZE
Default number of classes for associated histogram.
MiniVec< float, N > floor(const MiniVec< float, N > &a)
Definition: MiniVec.h:75
MiniVec< float, N > ceil(const MiniVec< float, N > &a)
Definition: MiniVec.h:89
Generic file read and write utility for python interface.
unsigned maxValue
Max histogram value.