| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- //##########################################################################
- //# #
- //# 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) #
- //# #
- //##########################################################################
- #ifndef CC_NORMAL_VECTORS_HEADER
- #define CC_NORMAL_VECTORS_HEADER
- //Local
- #include "ccGenericPointCloud.h"
- //System
- #include <vector>
- //! Compressed normal vectors handler
- class QCC_DB_LIB_API ccNormalVectors
- {
- public:
- //! Returns unique instance
- static ccNormalVectors* GetUniqueInstance();
- //! Releases unique instance
- /** Call to this method is now optional.
- **/
- static void ReleaseUniqueInstance();
- //! Returns the number of compressed normal vectors
- static inline unsigned GetNumberOfVectors() { return static_cast<unsigned>(GetUniqueInstance()->m_theNormalVectors.size()); }
- //! Static access to ccNormalVectors::getNormal
- static inline const CCVector3& GetNormal(unsigned normIndex) { return GetUniqueInstance()->getNormal(normIndex); }
- //! Returns the precomputed normal corresponding to a given compressed index
- inline const CCVector3& getNormal(unsigned normIndex) const { return m_theNormalVectors[normIndex]; }
- //! Returns the compressed index corresponding to a normal vector
- static CompressedNormType GetNormIndex(const PointCoordinateType N[]);
- //! Returns the compressed index corresponding to a normal vector (shortcut)
- static inline CompressedNormType GetNormIndex(const CCVector3& N) { return GetNormIndex(N.u); }
- //! 'Default' orientations
- enum Orientation {
- PLUS_X = 0, //!< N.x always positive
- MINUS_X = 1, //!< N.x always negative
- PLUS_Y = 2, //!< N.y always positive
- MINUS_Y = 3, //!< N.y always negative
- PLUS_Z = 4, //!< N.z always positive
- MINUS_Z = 5, //!< N.z always negative
- PLUS_BARYCENTER = 6, //!< Normals always opposite to the cloud barycenter
- MINUS_BARYCENTER = 7, //!< Normals always towards the cloud barycenter
- PLUS_ORIGIN = 8, //!< Normals always opposite to the origin
- MINUS_ORIGIN = 9, //!< Normals always towards the origin
- PREVIOUS = 10, //!< Re-use previous normal (if any)
- PLUS_SENSOR_ORIGIN = 11, //!< Normals opposite to the associated sensor origin (if any, and if multiple, the first one will be used)
- MINUS_SENSOR_ORIGIN = 12, //!< Normals towards the associated sensor origin (if any, and if multiple, the first one will be used)
- UNDEFINED = 255 //!< Undefined (no orientation is required)
- };
- //! Computes normal at each point of a given cloud
- /** \param cloud point cloud on which to process the normals.
- \param theNormsCodes array in which the normals indexes are stored
- \param localModel which kind of model to use for the computation (LS = plane, QUADRIC = quadratic Height Function, TRI = triangulation)
- \param localRadius local neighborhood radius (not necessary for TRI)
- \param preferredOrientation specifies a preferred orientation for normals (optional)
- \param progressCb progress notification (optional)
- \param inputOctree inputOctree input cloud octree (optional).
- \return success
- **/
- static bool ComputeCloudNormals(ccGenericPointCloud* cloud,
- NormsIndexesTableType& theNormsCodes,
- CCCoreLib::LOCAL_MODEL_TYPES localModel,
- PointCoordinateType localRadius,
- Orientation preferredOrientation = UNDEFINED,
- CCCoreLib::GenericProgressCallback* progressCb = nullptr,
- CCCoreLib::DgmOctree* inputOctree = nullptr);
- //! Updates normals orientation based on a preferred orientation
- /** \param theCloud point cloud on which to process the normals.
- \param theNormsCodes array in which the normals indexes are stored
- \param preferredOrientation specifies a preferred orientation for normals
- \return success
- **/
- static bool UpdateNormalOrientations( ccGenericPointCloud* theCloud,
- NormsIndexesTableType& theNormsCodes,
- Orientation preferredOrientation);
- //! Converts a normal vector to geological 'strike & dip' parameters (N[dip]°E - [strike]°)
- /** \param[in] N normal (should be normalized!)
- \param[out] strike_deg strike value (in degrees)
- \param[out] dip_deg dip value (in degrees)
- **/
- static void ConvertNormalToStrikeAndDip(const CCVector3& N, PointCoordinateType& strike_deg, PointCoordinateType& dip_deg);
- //! Converts a normal vector to geological 'dip direction & dip' parameters (float version)
- /** See http://en.wikipedia.org/wiki/Strike_and_dip
- The dip direction is the azimuth of the direction (in [0,360[).
- The dip is always in [0,90].
- \param[in] N normal (should be normalized!)
- \param[out] dip_deg value (in degrees)
- \param[out] dipDir_deg dip direction value (in degrees)
- **/
- static void ConvertNormalToDipAndDipDir(const CCVector3f& N, float& dip_deg, float& dipDir_deg);
- //! Converts a normal vector to geological 'dip direction & dip' parameters (double version)
- /** See http://en.wikipedia.org/wiki/Strike_and_dip
- The dip direction is the azimuth of the direction (in [0,360[).
- The dip is always in [0,90].
- \param[in] N normal (should be normalized!)
- \param[out] dip_deg value (in degrees)
- \param[out] dipDir_deg dip direction value (in degrees)
- **/
- static void ConvertNormalToDipAndDipDir(const CCVector3d& N, double& dip_deg, double& dipDir_deg);
- //! Converts a couple of geological 'dip direction & dip' parameters to a unit normal vector (float version)
- /** \param[in] dip_deg value (in degrees)
- \param[in] dipDir_deg dip direction value(in degrees)
- \param[in] upward whether the output normal vector should point towards Z+ (true) or Z- (false)
- \return unit normal vector
- **/
- static CCVector3f ConvertDipAndDipDirToNormal(float dip_deg, float dipDir_deg, bool upward = true);
- //! Converts a couple of geological 'dip direction & dip' parameters to a unit normal vector (double version)
- /** \param[in] dip_deg value (in degrees)
- \param[in] dipDir_deg dip direction value(in degrees)
- \param[in] upward whether the output normal vector should point towards Z+ (true) or Z- (false)
- \return unit normal vector
- **/
- static CCVector3d ConvertDipAndDipDirToNormal(double dip_deg, double dipDir_deg, bool upward = true);
- //! Converts geological 'strike & dip' parameters (N[dip]°E - [strike]°) to a string
- /** \param[in] strike_deg strike value (in degrees)
- \param[in] dip_deg dip value (in degrees)
- \return formatted string "N[strike]°E - [dip]°"
- **/
- static QString ConvertStrikeAndDipToString(double& strike_deg, double& dip_deg);
- //! Converts geological 'dip direction & dip' parameters to a string
- /** \param[in] dip_deg dip angle value (in degrees)
- \param[in] dipDir_deg dip direction value (in degrees)
- \return formatted string "Dip direction: [dipDir]° - Dip angle: [dip]°"
- **/
- static QString ConvertDipAndDipDirToString(PointCoordinateType dip_deg, PointCoordinateType dipDir_deg);
- //! Converts a normal vector to HSV color space
- /** Uses 'strike & dip' parameters (H=strike, S=dip, V=constant)
- \param[in] N normal (should be normalized!)
- \param[out] H hue [0;360[
- \param[out] S saturation [0;1]
- \param[out] V value [0;1]
- **/
- static void ConvertNormalToHSV(const CCVector3& N, float& H, float& S, float& V);
- //! Converts a normal vector to RGB color space
- /** Uses 'ConvertNormalToHSV' then converts HSV to RGB.
- \param[in] N normal (should be normalized!)
- \return RGB value (components between 0 and MAX_COLOR_COMP)
- **/
- static ccColor::Rgb ConvertNormalToRGB(const CCVector3& N);
- public:
- //! Default destructor
- virtual ~ccNormalVectors() = default;
- //! Allocates normal HSV colors array
- /** Mandatory for HSV color related methods (getNormalHSVColor, etc.)
- **/
- bool enableNormalHSVColorsArray();
- //! Returns the HSV color equivalent to a given compressed normal index
- const ccColor::Rgb& getNormalHSVColor(unsigned index) const;
- //! Returns the HSV color array
- inline const std::vector<ccColor::Rgb>& getNormalHSVColorArray() const { return m_theNormalHSVColors; }
- //! Helper: computes the normal (with best LS fit)
- static bool ComputeNormalWithLS(CCCoreLib::GenericIndexedCloudPersist* pointAndNeighbors, CCVector3& N);
- //! Helper: computes the normal (with Delaunay 2.5D)
- /** The normal is computed at the first point (assuming the others are its neighbors).
- **/
- static bool ComputeNormalWithTri(CCCoreLib::GenericIndexedCloudPersist* pointAndNeighbors, CCVector3& N);
- //! Helper: computes the normal (with Delaunay 2.5D)
- /** The normal is computed at the first point (assuming the others are its neighbors).
- **/
- static bool ComputeNormalWithQuadric(CCCoreLib::GenericIndexedCloudPersist* points, const CCVector3& P, CCVector3& N);
- protected:
- //! Default constructor
- /** Shouldn't be called directly. Use 'GetUniqueInstance' instead.
- **/
- ccNormalVectors();
- //! Inits internal structures
- bool init();
- //! Compressed normal vectors
- std::vector<CCVector3> m_theNormalVectors;
- //! 'HSV' colors corresponding to each compressed normal index
- /** In fact, HSV color has already been converted to RGB here for faster display.
- **/
- std::vector<ccColor::Rgb> m_theNormalHSVColors;
- //! Cellular method for octree-based normal computation
- static bool ComputeNormsAtLevelWithQuadric(const CCCoreLib::DgmOctree::octreeCell& cell, void** additionalParameters, CCCoreLib::NormalizedProgress* nProgress = nullptr);
- //! Cellular method for octree-based normal computation
- static bool ComputeNormsAtLevelWithLS(const CCCoreLib::DgmOctree::octreeCell& cell, void** additionalParameters, CCCoreLib::NormalizedProgress* nProgress = nullptr);
- //! Cellular method for octree-based normal computation
- static bool ComputeNormsAtLevelWithTri(const CCCoreLib::DgmOctree::octreeCell& cell, void** additionalParameters, CCCoreLib::NormalizedProgress* nProgress = nullptr);
- };
- #endif //CC_NORMAL_VECTORS_HEADER
|