| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- #pragma once
- //##########################################################################
- //# #
- //# CLOUDCOMPARE #
- //# #
- //# This program is free software; you can redistribute it and/or modify #
- //# it under the terms of the GNU General Public License as published by #
- //# the Free Software Foundation; version 2 or later of the License. #
- //# #
- //# This program is distributed in the hope that it will be useful, #
- //# but WITHOUT ANY WARRANTY; without even the implied warranty of #
- //# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
- //# GNU General Public License for more details. #
- //# #
- //# COPYRIGHT: EDF R&D / TELECOM ParisTech (ENST-TSI) #
- //# #
- //##########################################################################
- //CCCoreLib
- #include <ScalarField.h>
- //qCC_db
- #include "ccColorScale.h"
- //! A scalar field associated to display-related parameters
- /** Extends the CCCoreLib::ScalarField object.
- **/
- class QCC_DB_LIB_API ccScalarField : public CCCoreLib::ScalarField, public ccSerializableObject
- {
- public:
- //! Default constructor
- /** \param name scalar field name
- **/
- explicit ccScalarField(const std::string& name = std::string());
- //! Copy constructor
- /** \param sf scalar field to copy
- \warning May throw a std::bad_alloc exception
- **/
- ccScalarField(const ccScalarField& sf);
- /*** Scalar values display handling ***/
- //! Scalar field range structure
- class QCC_DB_LIB_API Range
- {
- public:
- //! Default constructor
- Range() : m_min(0), m_start(0), m_stop(0), m_max(0), m_range(1) {}
- //getters
- inline ScalarType min() const { return m_min; }
- inline ScalarType start() const { return m_start; }
- inline ScalarType stop() const { return m_stop; }
- inline ScalarType max() const { return m_max; }
- inline ScalarType range() const { return m_range; }
- inline ScalarType maxRange() const { return m_max-m_min; }
- //setters
- void setBounds(ScalarType minVal, ScalarType maxVal, bool resetStartStop = true)
- {
- assert(std::isnan(minVal) || std::isnan(maxVal) || minVal <= maxVal);
- m_min = minVal; m_max = maxVal;
- if (resetStartStop)
- {
- m_start = m_min;
- m_stop = m_max;
- }
- else
- {
- m_start = inbound(m_start);
- m_stop = inbound(m_stop);
- }
- updateRange();
- }
- inline void setStart(ScalarType value) { m_start = inbound(value); if (m_stop < m_start) m_stop = m_start; updateRange(); }
- inline void setStop(ScalarType value) { m_stop = inbound(value); if (m_stop < m_start) m_start = m_stop; updateRange(); }
-
- //! Returns the nearest inbound value
- inline ScalarType inbound(ScalarType val) const { return (val < m_min ? m_min : (val > m_max ? m_max : val)); }
- //! Returns whether a value is inbound or not
- inline bool isInbound(ScalarType val) const { return (val >= m_min && val <= m_max); }
- //! Returns whether a value is inside range or not
- inline bool isInRange(ScalarType val) const { return (val >= m_start && val <= m_stop); }
- protected:
- //! Updates actual range
- inline void updateRange() { m_range = std::max(m_stop - m_start, CCCoreLib::ZERO_TOLERANCE_SCALAR); }
- ScalarType m_min; /**< Minimum value **/
- ScalarType m_start; /**< Current start value (in [min,max]) **/
- ScalarType m_stop; /**< Current stop value (in [min,max]) **/
- ScalarType m_max; /**< Minimum value **/
- ScalarType m_range; /**< Actual range: start-stop (but can't be ZERO!) **/
- };
- //! Access to the range of displayed values
- /** Values outside of the [start;stop] interval will either be grey
- or invisible (see showNaNValuesInGrey).
- **/
- inline const Range& displayRange() const { return m_displayRange; }
- //! Access to the range of saturation values
- /** Relative color scales will only be applied to values inside the
- [start;stop] interval.
- **/
- inline const Range& saturationRange() const { return m_logScale ? m_logSaturationRange : m_saturationRange; }
- //! Access to the range of log scale saturation values
- /** Relative color scales will only be applied to values inside the
- [start;stop] interval.
- **/
- inline const Range& logSaturationRange() const { return m_logSaturationRange; }
- //! Sets the minimum displayed value
- void setMinDisplayed(ScalarType val);
- //! Sets the maximum displayed value
- void setMaxDisplayed(ScalarType val);
- //! Sets the value at which to start color gradient
- void setSaturationStart(ScalarType val);
- //! Sets the value at which to stop color gradient
- void setSaturationStop(ScalarType val);
- //! Returns the color corresponding to a given value (wrt to the current display parameters)
- /** Warning: must no be called if the SF is not associated to a color scale!
- **/
- inline const ccColor::Rgb* getColor(ScalarType value) const
- {
- assert(m_colorScale);
- return m_colorScale->getColorByRelativePos(normalize(value), m_colorRampSteps, m_showNaNValuesInGrey ? &ccColor::lightGreyRGB : nullptr);
- }
- //! Shortcut to getColor
- inline const ccColor::Rgb* getValueColor(unsigned index) const { return getColor(getValue(index)); }
- //! Sets whether NaN/out of displayed range values should be displayed in grey or hidden
- void showNaNValuesInGrey(bool state);
- //! Returns whether NaN values are displayed in grey or hidden
- inline bool areNaNValuesShownInGrey() const { return m_showNaNValuesInGrey; }
- //! Sets whether 0 should always appear in associated color ramp or not
- void alwaysShowZero(bool state);
- //! Returns whether 0 should always appear in associated color ramp or not
- inline bool isZeroAlwaysShown() const { return m_alwaysShowZero; }
- //! Sets whether the color scale should be symmetrical or not
- /** For relative color scales only.
- **/
- void setSymmetricalScale(bool state);
- //! Returns whether the color scale s symmetrical or not
- /** For relative color scales only.
- **/
- inline bool symmetricalScale() const { return m_symmetricalScale; }
- //! Sets whether scale is logarithmic or not
- void setLogScale(bool state);
- //! Returns whether scalar field is logarithmic or not
- inline bool logScale() const { return m_logScale; }
- //inherited
- void computeMinAndMax() override;
- //! Returns associated color scale
- inline const ccColorScale::Shared& getColorScale() const { return m_colorScale; }
- //! Sets associated color scale
- void setColorScale(ccColorScale::Shared scale);
- //! Returns number of color ramp steps
- inline unsigned getColorRampSteps() const { return m_colorRampSteps; }
- //! Sets number of color ramp steps used for display
- void setColorRampSteps(unsigned steps);
- //! Simple histogram structure
- struct Histogram : std::vector<unsigned>
- {
- //! Max histogram value
- unsigned maxValue = 0;
- };
- //! Returns associated histogram values (for display)
- inline const Histogram& getHistogram() const { return m_histogram; }
- //! Returns whether the scalar field in its current configuration MAY have 'hidden' values or not
- /** 'Hidden' values are typically NaN values or values outside of the 'displayed' interval
- while those values are not displayed in grey (see ccScalarField::showNaNValuesInGrey).
- **/
- bool mayHaveHiddenValues() const;
- //! Sets modification flag state
- inline void setModificationFlag(bool state) { m_modified = state; }
- //! Returns modification flag state
- inline bool getModificationFlag() const { return m_modified; }
- //! Imports the parameters from another scalar field
- void importParametersFrom(const ccScalarField* sf);
- //inherited from ccSerializableObject
- inline bool isSerializable() const override { return true; }
- bool toFile(QFile& out, short dataVersion) const override;
- bool fromFile(QFile& in, short dataVersion, int flags, LoadedIDMap& oldToNewIDMap) override;
- short minimumFileVersion() const override;
- protected: //methods
- //! Default destructor
- /** Call release instead
- **/
- ~ccScalarField() override = default;
- //! Updates saturation values
- void updateSaturationBounds();
- //! Normalizes a scalar value between 0 and 1 (wrt to current parameters)
- /** \param val scalar value
- \return a number between 0 and 1 if inside displayed range or -1 otherwise
- **/
- ScalarType normalize(ScalarType val) const;
- protected: //members
- //! Displayed values range
- Range m_displayRange;
- //! Saturation values range
- /** For color mapping with relative scales.
- **/
- Range m_saturationRange;
- //! saturation values range (log scale mode)
- /** For log scale color mapping with relative scales.
- **/
- Range m_logSaturationRange;
- //! Whether NaN values are shown in grey or are hidden
- bool m_showNaNValuesInGrey;
- //! Whether color scale is symmetrical or not
- /** For relative color scales only.
- **/
- bool m_symmetricalScale;
- //! Whether scale is logarithmic or not
- bool m_logScale;
- //! Whether 0 should always appear in associated color ramp
- bool m_alwaysShowZero;
- //! Active color ramp (for display)
- ccColorScale::Shared m_colorScale;
-
- //! Number of color ramps steps (for display)
- unsigned m_colorRampSteps;
- //! Associated histogram values (for display)
- Histogram m_histogram;
- //! Modification flag
- /** Any modification to the scalar field values or parameters
- will turn this flag on.
- **/
- bool m_modified;
- };
|