ccScalarField.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. #pragma once
  2. //##########################################################################
  3. //# #
  4. //# CLOUDCOMPARE #
  5. //# #
  6. //# This program is free software; you can redistribute it and/or modify #
  7. //# it under the terms of the GNU General Public License as published by #
  8. //# the Free Software Foundation; version 2 or later of the License. #
  9. //# #
  10. //# This program is distributed in the hope that it will be useful, #
  11. //# but WITHOUT ANY WARRANTY; without even the implied warranty of #
  12. //# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
  13. //# GNU General Public License for more details. #
  14. //# #
  15. //# COPYRIGHT: EDF R&D / TELECOM ParisTech (ENST-TSI) #
  16. //# #
  17. //##########################################################################
  18. //CCCoreLib
  19. #include <ScalarField.h>
  20. //qCC_db
  21. #include "ccColorScale.h"
  22. //! A scalar field associated to display-related parameters
  23. /** Extends the CCCoreLib::ScalarField object.
  24. **/
  25. class QCC_DB_LIB_API ccScalarField : public CCCoreLib::ScalarField, public ccSerializableObject
  26. {
  27. public:
  28. //! Default constructor
  29. /** \param name scalar field name
  30. **/
  31. explicit ccScalarField(const std::string& name = std::string());
  32. //! Copy constructor
  33. /** \param sf scalar field to copy
  34. \warning May throw a std::bad_alloc exception
  35. **/
  36. ccScalarField(const ccScalarField& sf);
  37. /*** Scalar values display handling ***/
  38. //! Scalar field range structure
  39. class QCC_DB_LIB_API Range
  40. {
  41. public:
  42. //! Default constructor
  43. Range() : m_min(0), m_start(0), m_stop(0), m_max(0), m_range(1) {}
  44. //getters
  45. inline ScalarType min() const { return m_min; }
  46. inline ScalarType start() const { return m_start; }
  47. inline ScalarType stop() const { return m_stop; }
  48. inline ScalarType max() const { return m_max; }
  49. inline ScalarType range() const { return m_range; }
  50. inline ScalarType maxRange() const { return m_max-m_min; }
  51. //setters
  52. void setBounds(ScalarType minVal, ScalarType maxVal, bool resetStartStop = true)
  53. {
  54. assert(std::isnan(minVal) || std::isnan(maxVal) || minVal <= maxVal);
  55. m_min = minVal; m_max = maxVal;
  56. if (resetStartStop)
  57. {
  58. m_start = m_min;
  59. m_stop = m_max;
  60. }
  61. else
  62. {
  63. m_start = inbound(m_start);
  64. m_stop = inbound(m_stop);
  65. }
  66. updateRange();
  67. }
  68. inline void setStart(ScalarType value) { m_start = inbound(value); if (m_stop < m_start) m_stop = m_start; updateRange(); }
  69. inline void setStop(ScalarType value) { m_stop = inbound(value); if (m_stop < m_start) m_start = m_stop; updateRange(); }
  70. //! Returns the nearest inbound value
  71. inline ScalarType inbound(ScalarType val) const { return (val < m_min ? m_min : (val > m_max ? m_max : val)); }
  72. //! Returns whether a value is inbound or not
  73. inline bool isInbound(ScalarType val) const { return (val >= m_min && val <= m_max); }
  74. //! Returns whether a value is inside range or not
  75. inline bool isInRange(ScalarType val) const { return (val >= m_start && val <= m_stop); }
  76. protected:
  77. //! Updates actual range
  78. inline void updateRange() { m_range = std::max(m_stop - m_start, CCCoreLib::ZERO_TOLERANCE_SCALAR); }
  79. ScalarType m_min; /**< Minimum value **/
  80. ScalarType m_start; /**< Current start value (in [min,max]) **/
  81. ScalarType m_stop; /**< Current stop value (in [min,max]) **/
  82. ScalarType m_max; /**< Minimum value **/
  83. ScalarType m_range; /**< Actual range: start-stop (but can't be ZERO!) **/
  84. };
  85. //! Access to the range of displayed values
  86. /** Values outside of the [start;stop] interval will either be grey
  87. or invisible (see showNaNValuesInGrey).
  88. **/
  89. inline const Range& displayRange() const { return m_displayRange; }
  90. //! Access to the range of saturation values
  91. /** Relative color scales will only be applied to values inside the
  92. [start;stop] interval.
  93. **/
  94. inline const Range& saturationRange() const { return m_logScale ? m_logSaturationRange : m_saturationRange; }
  95. //! Access to the range of log scale saturation values
  96. /** Relative color scales will only be applied to values inside the
  97. [start;stop] interval.
  98. **/
  99. inline const Range& logSaturationRange() const { return m_logSaturationRange; }
  100. //! Sets the minimum displayed value
  101. void setMinDisplayed(ScalarType val);
  102. //! Sets the maximum displayed value
  103. void setMaxDisplayed(ScalarType val);
  104. //! Sets the value at which to start color gradient
  105. void setSaturationStart(ScalarType val);
  106. //! Sets the value at which to stop color gradient
  107. void setSaturationStop(ScalarType val);
  108. //! Returns the color corresponding to a given value (wrt to the current display parameters)
  109. /** Warning: must no be called if the SF is not associated to a color scale!
  110. **/
  111. inline const ccColor::Rgb* getColor(ScalarType value) const
  112. {
  113. assert(m_colorScale);
  114. return m_colorScale->getColorByRelativePos(normalize(value), m_colorRampSteps, m_showNaNValuesInGrey ? &ccColor::lightGreyRGB : nullptr);
  115. }
  116. //! Shortcut to getColor
  117. inline const ccColor::Rgb* getValueColor(unsigned index) const { return getColor(getValue(index)); }
  118. //! Sets whether NaN/out of displayed range values should be displayed in grey or hidden
  119. void showNaNValuesInGrey(bool state);
  120. //! Returns whether NaN values are displayed in grey or hidden
  121. inline bool areNaNValuesShownInGrey() const { return m_showNaNValuesInGrey; }
  122. //! Sets whether 0 should always appear in associated color ramp or not
  123. void alwaysShowZero(bool state);
  124. //! Returns whether 0 should always appear in associated color ramp or not
  125. inline bool isZeroAlwaysShown() const { return m_alwaysShowZero; }
  126. //! Sets whether the color scale should be symmetrical or not
  127. /** For relative color scales only.
  128. **/
  129. void setSymmetricalScale(bool state);
  130. //! Returns whether the color scale s symmetrical or not
  131. /** For relative color scales only.
  132. **/
  133. inline bool symmetricalScale() const { return m_symmetricalScale; }
  134. //! Sets whether scale is logarithmic or not
  135. void setLogScale(bool state);
  136. //! Returns whether scalar field is logarithmic or not
  137. inline bool logScale() const { return m_logScale; }
  138. //inherited
  139. void computeMinAndMax() override;
  140. //! Returns associated color scale
  141. inline const ccColorScale::Shared& getColorScale() const { return m_colorScale; }
  142. //! Sets associated color scale
  143. void setColorScale(ccColorScale::Shared scale);
  144. //! Returns number of color ramp steps
  145. inline unsigned getColorRampSteps() const { return m_colorRampSteps; }
  146. //! Sets number of color ramp steps used for display
  147. void setColorRampSteps(unsigned steps);
  148. //! Simple histogram structure
  149. struct Histogram : std::vector<unsigned>
  150. {
  151. //! Max histogram value
  152. unsigned maxValue = 0;
  153. };
  154. //! Returns associated histogram values (for display)
  155. inline const Histogram& getHistogram() const { return m_histogram; }
  156. //! Returns whether the scalar field in its current configuration MAY have 'hidden' values or not
  157. /** 'Hidden' values are typically NaN values or values outside of the 'displayed' interval
  158. while those values are not displayed in grey (see ccScalarField::showNaNValuesInGrey).
  159. **/
  160. bool mayHaveHiddenValues() const;
  161. //! Sets modification flag state
  162. inline void setModificationFlag(bool state) { m_modified = state; }
  163. //! Returns modification flag state
  164. inline bool getModificationFlag() const { return m_modified; }
  165. //! Imports the parameters from another scalar field
  166. void importParametersFrom(const ccScalarField* sf);
  167. //inherited from ccSerializableObject
  168. inline bool isSerializable() const override { return true; }
  169. bool toFile(QFile& out, short dataVersion) const override;
  170. bool fromFile(QFile& in, short dataVersion, int flags, LoadedIDMap& oldToNewIDMap) override;
  171. short minimumFileVersion() const override;
  172. protected: //methods
  173. //! Default destructor
  174. /** Call release instead
  175. **/
  176. ~ccScalarField() override = default;
  177. //! Updates saturation values
  178. void updateSaturationBounds();
  179. //! Normalizes a scalar value between 0 and 1 (wrt to current parameters)
  180. /** \param val scalar value
  181. \return a number between 0 and 1 if inside displayed range or -1 otherwise
  182. **/
  183. ScalarType normalize(ScalarType val) const;
  184. protected: //members
  185. //! Displayed values range
  186. Range m_displayRange;
  187. //! Saturation values range
  188. /** For color mapping with relative scales.
  189. **/
  190. Range m_saturationRange;
  191. //! saturation values range (log scale mode)
  192. /** For log scale color mapping with relative scales.
  193. **/
  194. Range m_logSaturationRange;
  195. //! Whether NaN values are shown in grey or are hidden
  196. bool m_showNaNValuesInGrey;
  197. //! Whether color scale is symmetrical or not
  198. /** For relative color scales only.
  199. **/
  200. bool m_symmetricalScale;
  201. //! Whether scale is logarithmic or not
  202. bool m_logScale;
  203. //! Whether 0 should always appear in associated color ramp
  204. bool m_alwaysShowZero;
  205. //! Active color ramp (for display)
  206. ccColorScale::Shared m_colorScale;
  207. //! Number of color ramps steps (for display)
  208. unsigned m_colorRampSteps;
  209. //! Associated histogram values (for display)
  210. Histogram m_histogram;
  211. //! Modification flag
  212. /** Any modification to the scalar field values or parameters
  213. will turn this flag on.
  214. **/
  215. bool m_modified;
  216. };