| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976 |
- #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) #
- //# #
- //##########################################################################
- #ifdef _MSC_VER
- //To get rid of the warnings about dominant inheritance
- #pragma warning( disable: 4250 )
- #endif
- //CCCoreLib
- #include <PointCloudTpl.h>
- //Local
- #include "ccColorScale.h"
- #include "ccNormalVectors.h"
- #include "ccWaveform.h"
- //Qt
- #include <QGLBuffer>
- class ccScalarField;
- class ccPolyline;
- class ccMesh;
- class QGLBuffer;
- class ccProgressDialog;
- class ccPointCloudLOD;
- /***************************************************
- ccPointCloud
- ***************************************************/
- //! Max number of points per cloud (point cloud will be chunked above this limit)
- #if defined(CC_ENV_32)
- const unsigned CC_MAX_NUMBER_OF_POINTS_PER_CLOUD = 128000000;
- #else //CC_ENV_64 (but maybe CC_ENV_128 one day ;)
- const unsigned CC_MAX_NUMBER_OF_POINTS_PER_CLOUD = 2000000000; //we must keep it below MAX_INT to avoid probable issues ;)
- #endif
- //! A 3D cloud and its associated features (color, normals, scalar fields, etc.)
- /** A point cloud can have multiple features:
- - colors (RGB)
- - normals (compressed)
- - scalar fields
- - an octree structure
- - per-point visibility information (to hide/display subsets of points)
- - other children objects (meshes, calibrated pictures, etc.)
- **/
- class QCC_DB_LIB_API ccPointCloud : public CCCoreLib::PointCloudTpl<ccGenericPointCloud, QString>
- {
- public:
- //! Base class (shortcut)
- using BaseClass = CCCoreLib::PointCloudTpl<ccGenericPointCloud, QString>;
- //! Default constructor
- /** Creates an empty cloud without any feature. Each of them should be
- specifically instantiated/created (once the points have been
- added to this cloud, at least partially).
- \param name cloud name (optional)
- \param uniqueID unique ID (handle with care)
- **/
- ccPointCloud(QString name = QString(), unsigned uniqueID = ccUniqueIDGenerator::InvalidUniqueID) throw();
- //! Default destructor
- ~ccPointCloud() override;
- //! Returns class ID
- CC_CLASS_ENUM getClassID() const override { return CC_TYPES::POINT_CLOUD; }
- public: //clone, copy, etc.
- //! Creates a new point cloud object from a GenericIndexedCloud
- /** "GenericIndexedCloud" is an extension of GenericCloud (from CCCoreLib)
- which provides a const random accessor to points.
- See CClib documentation for more information about GenericIndexedCloud.
- As the GenericIndexedCloud interface is very simple, only points are imported.
- Note: throws an 'int' exception in case of error (see CTOR_ERRORS)
- \param cloud a GenericIndexedCloud structure
- \param sourceCloud cloud from which main parameters will be imported (optional)
- **/
- static ccPointCloud* From(const CCCoreLib::GenericIndexedCloud* cloud, const ccGenericPointCloud* sourceCloud = nullptr);
- //! Creates a new point cloud object from a GenericCloud
- /** "GenericCloud" is a very simple and light interface from CCCoreLib. It is
- meant to give access to points coordinates of any cloud (on the
- condition it implements the GenericCloud interface of course).
- See CClib documentation for more information about GenericClouds.
- As the GenericCloud interface is very simple, only points are imported.
- Note: throws an 'int' exception in case of error (see CTOR_ERRORS)
- \param cloud a GenericCloud structure
- \param sourceCloud cloud from which main parameters will be imported (optional)
- **/
- static ccPointCloud* From(CCCoreLib::GenericCloud* cloud, const ccGenericPointCloud* sourceCloud = nullptr);
- //! Warnings for the partialClone method (bit flags)
- enum CLONE_WARNINGS { WRN_OUT_OF_MEM_FOR_COLORS = 1,
- WRN_OUT_OF_MEM_FOR_NORMALS = 2,
- WRN_OUT_OF_MEM_FOR_SFS = 4,
- WRN_OUT_OF_MEM_FOR_FWF = 8
- };
- //! Creates a new point cloud object from a ReferenceCloud (selection)
- /** "Reference clouds" are a set of indexes referring to a real point cloud.
- See CClib documentation for more information about ReferenceClouds.
- Warning: the ReferenceCloud structure must refer to this cloud.
- \param[in] selection a ReferenceCloud structure (pointing to source)
- \param[out] warnings [optional] to determine if warnings (CTOR_ERRORS) occurred during the duplication process
- \param[in] withChildEntities whether child entities should be transferred as well (see ccHObjectCaster::CloneChildren)
- **/
- ccPointCloud* partialClone(const CCCoreLib::ReferenceCloud* selection, int* warnings = nullptr, bool withChildEntities = true) const;
- //! Clones this entity
- /** All the main features of the entity are cloned, except from the octree and
- the points visibility information.
- \param destCloud [optional] the destination cloud can be provided here
- \param ignoreChildren [optional] whether to ignore the cloud's children or not (in which case they will be cloned as well)
- \return a copy of this entity
- **/
- ccPointCloud* cloneThis(ccPointCloud* destCloud = nullptr, bool ignoreChildren = false);
- //inherited from ccGenericPointCloud
- ccGenericPointCloud* clone(ccGenericPointCloud* destCloud = nullptr, bool ignoreChildren = false) override;
- //! Fuses another 3D entity with this one
- /** All the main features of the given entity are added, except from the octree and
- the points visibility information. Those features are deleted on this cloud.
- **/
- const ccPointCloud& operator +=(ccPointCloud*);
- public: //features deletion/clearing
- //! Clears the entity from all its points and features
- /** Display parameters are also reset to their default values.
- **/
- void clear() override;
- //! Erases the cloud points
- /** Prefer ccPointCloud::clear by default.
- \warning DANGEROUS
- **/
- void unallocatePoints();
- //! Erases the cloud colors
- void unallocateColors();
- //! Erases the cloud normals
- void unallocateNorms();
- //! Notify a modification of color / scalar field display parameters or contents
- inline void colorsHaveChanged() { m_vboManager.updateFlags |= vboSet::UPDATE_COLORS; }
- //! Notify a modification of normals display parameters or contents
- inline void normalsHaveChanged() { m_vboManager.updateFlags |= vboSet::UPDATE_NORMALS; decompressNormals();}
- //! Notify a modification of points display parameters or contents
- inline void pointsHaveChanged() { m_vboManager.updateFlags |= vboSet::UPDATE_POINTS; }
- public: //features allocation/resize
- //! Reserves memory to store the points coordinates
- /** Before adding points to the cloud (with addPoint())
- be sure to reserve the necessary amount of memory
- with this method. If the number of new elements is
- smaller than the actual one, nothing will happen.
- \param _numberOfPoints number of points to reserve the memory for
- \return true if ok, false if there's not enough memory
- **/
- bool reserveThePointsTable(unsigned _numberOfPoints);
- //! Reserves memory to store the RGB colors
- /** Before adding colors to the cloud (with addColor())
- be sure to reserve the necessary amount of memory
- with this method. This method reserves memory for as
- many colors as the number of points in the cloud
- (effectively stored or reserved).
- \return true if ok, false if there's not enough memory
- **/
- bool reserveTheRGBTable();
- //! Resizes the RGB colors array
- /** If possible, the colors array is resized to fit exactly the number
- of points in the cloud (effectively stored or reserved). If the
- new size is inferior to the actual one, the last elements will be
- deleted. Otherwise, the array is filled with zeros (default behavior)
- or "white" colors (is fillWithWhite).
- \warning don't try to "add" any element on a resized array...
- \param fillWithWhite whether to fill new array elements with zeros (false) or white color (true)
- \return true if ok, false if there's not enough memory
- **/
- bool resizeTheRGBTable(bool fillWithWhite = false);
- //! Reserves memory to store the compressed normals
- /** Before adding normals to the cloud (with addNorm())
- be sure to reserve the necessary amount of memory
- with this method. This method reserves memory for as
- many normals as the number of points in the cloud
- (effectively stored or reserved).
- \return true if ok, false if there's not enough memory
- **/
- bool reserveTheNormsTable();
- //! Resizes the compressed normals array
- /** If possible, the normals array is resized to fit exactly the number
- of points in the cloud (effectively stored or reserved). If the
- new size is inferior to the actual one, the last elements will be
- deleted. Otherwise, the array is filled with blank elements.
- \warning don't try to "add" any element on a resized array...
- \return true if ok, false if there's not enough memory
- **/
- bool resizeTheNormsTable();
- //! Reserves memory for all the active features
- /** This method is meant to be called before increasing the cloud
- population. Only the already allocated features will be re-reserved.
- \return true if ok, false if there's not enough memory
- **/
- bool reserve(unsigned numberOfPoints) override;
- //! Resizes all the active features arrays
- /** This method is meant to be called after having increased the cloud
- population (if the final number of inserted point is lower than the
- reserved size). Otherwise, it fills all new elements with blank values.
- \return true if ok, false if there's not enough memory
- **/
- bool resize(unsigned numberOfPoints) override;
- //! Removes unused capacity
- inline void shrinkToFit() { if (size() < capacity()) resize(size()); }
- public: //scalar-fields management
- //! Returns the currently displayed scalar (or 0 if none)
- ccScalarField* getCurrentDisplayedScalarField() const;
- //! Returns the currently displayed scalar field index (or -1 if none)
- int getCurrentDisplayedScalarFieldIndex() const;
- //! Sets the currently displayed scalar field
- /** Warning: this scalar field will automatically be set as the OUTPUT one!
- **/
- void setCurrentDisplayedScalarField(int index);
- //inherited from base class
- void deleteScalarField(int index) override;
- void deleteAllScalarFields() override;
- int addScalarField(const std::string& uniqueName) override;
- //! Returns whether color scale should be displayed or not
- bool sfColorScaleShown() const;
- //! Sets whether color scale should be displayed or not
- void showSFColorsScale(bool state);
- public: //associated (scan) grid structure
- //! Grid structure
- struct QCC_DB_LIB_API Grid : public ccSerializableObject
- {
- //! Shared type
- using Shared = QSharedPointer<Grid>;
- //! Default constructor
- Grid();
- //! Copy constructor
- /** \warning May throw a bad_alloc exception
- **/
- Grid(const Grid& grid) = default;
- //! Inits the grid
- bool init(unsigned rowCount, unsigned colCount, bool withRGB = false);
- //! Sets an index at a given position inside the grid
- void setIndex(unsigned row, unsigned col, int index);
- //! Sets a color at a given position inside the grid
- void setColor(unsigned row, unsigned col, const ccColor::Rgb& rgb);
- //! Updates the min and max valid indexes
- void updateMinAndMaxValidIndexes();
- //! Converts the grid to an RGB image (needs colors)
- QImage toImage() const;
- //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;
- //! Grid width
- unsigned w;
- //! Grid height
- unsigned h;
- //! Number of valid indexes
- unsigned validCount;
- //! Minimum valid index
- unsigned minValidIndex;
- //! Maximum valid index
- unsigned maxValidIndex;
- //! Grid indexes (size: w x h)
- std::vector<int> indexes;
- //! Grid colors (size: w x h, or 0 = no color)
- std::vector<ccColor::Rgb> colors;
- //! Sensor position (expressed relatively to the cloud points)
- ccGLMatrixd sensorPosition;
- };
- //! Returns the number of associated grids
- size_t gridCount() const { return m_grids.size(); }
- //! Returns an associated grid
- inline Grid::Shared& grid(size_t gridIndex) { return m_grids[gridIndex]; }
- //! Returns an associated grid (const version)
- inline const Grid::Shared& grid(size_t gridIndex) const { return m_grids[gridIndex]; }
- //! Adds an associated grid
- inline bool addGrid(Grid::Shared grid) { try{ m_grids.push_back(grid); } catch (const std::bad_alloc&) { return false; } return true; }
- //! Remove all associated grids
- inline void removeGrids() { m_grids.resize(0); }
- //! Meshes a scan grid
- /** \warning The mesh vertices will be this cloud instance!
- **/
- ccMesh* triangulateGrid(const Grid& grid, double minTriangleAngle_deg = 0.0) const;
- public: //normals computation/orientation
- //! Compute the normals with the associated grid structure(s)
- /** Can also orient the normals in the same run.
- **/
- bool computeNormalsWithGrids( double minTriangleAngle_deg = 1.0,
- ccProgressDialog* pDlg = nullptr );
- //! Orient the normals with the associated grid structure(s)
- bool orientNormalsWithGrids( ccProgressDialog* pDlg = nullptr );
- //! Normals are forced to point to O
- bool orientNormalsTowardViewPoint( CCVector3 & VP, ccProgressDialog* pDlg = nullptr);
- //! Compute the normals by approximating the local surface around each point
- bool computeNormalsWithOctree( CCCoreLib::LOCAL_MODEL_TYPES model,
- ccNormalVectors::Orientation preferredOrientation,
- PointCoordinateType defaultRadius,
- ccProgressDialog* pDlg = nullptr );
- //! Orient the normals with a Minimum Spanning Tree
- bool orientNormalsWithMST( unsigned kNN = 6,
- ccProgressDialog* pDlg = nullptr );
- //! Orient normals with Fast Marching
- bool orientNormalsWithFM( unsigned char level,
- ccProgressDialog* pDlg = nullptr);
- //! Toggle the drawing of normals as small lines
- void showNormalsAsLines(bool state);
- //! Are normals drawn as vectors?
- bool normalsAreDrawn() const;
- //! Set the length of the normals
- void setNormalLength(const float& value);
- //! Get the length of the normals
- const float& getNormalLength() {return m_normalLineParameters.length;}
- //! Colors of the normals when they are displayed
- enum NormalLineColors{
- YELLOW,
- RED,
- GREEN,
- BLUE,
- BLACK
- };
- //! Set the color of the normals
- void setNormalLineColor(int colorIdx);
- //! Get the color of the normals
- const int& getNormalLineColor() {return m_normalLineParameters.colorIdx;}
- //! Do the drawing of normals
- void drawNormalsAsLines(CC_DRAW_CONTEXT& context);
- //! Update the decompressed normals which are used by drawNormalsAsLines
- void decompressNormals();
- public: //waveform (e.g. from airborne scanners)
- //! Returns whether the cloud has associated Full WaveForm data
- bool hasFWF() const;
- //! Returns a proxy on a given waveform
- ccWaveformProxy waveformProxy(unsigned index) const;
- //! Waveform descriptors set
- using FWFDescriptorSet = QMap<uint8_t, WaveformDescriptor>;
- //! Waveform data container
- using FWFDataContainer = std::vector<uint8_t>;
- using SharedFWFDataContainer = QSharedPointer<const FWFDataContainer>;
- //! Gives access to the FWF descriptors
- FWFDescriptorSet& fwfDescriptors() { return m_fwfDescriptors; }
- //! Gives access to the FWF descriptors (const version)
- const FWFDescriptorSet& fwfDescriptors() const { return m_fwfDescriptors; }
- //! Gives access to the associated FWF data
- std::vector<ccWaveform>& waveforms() { return m_fwfWaveforms; }
- //! Gives access to the associated FWF data (const version)
- const std::vector<ccWaveform>& waveforms() const { return m_fwfWaveforms; }
- //! Reserves the FWF table
- bool reserveTheFWFTable();
- //! Resizes the FWF table
- bool resizeTheFWFTable();
- //! Gives access to the associated FWF data container
- SharedFWFDataContainer& fwfData() { return m_fwfData; }
- //! Gives access to the associated FWF data container (const version)
- const SharedFWFDataContainer& fwfData() const { return m_fwfData; }
- //! Compresses the associated FWF data container
- /** As the container is shared, the compressed version will be potentially added to the memory
- resulting in a decrease of the available memory...
- **/
- bool compressFWFData();
- //! Computes the maximum amplitude of all associated waveforms
- bool computeFWFAmplitude(double& minVal, double& maxVal, ccProgressDialog* pDlg = nullptr) const;
- //! Clears all associated FWF data
- void clearFWFData();
- public: //other methods
- //! Returns the cloud gravity center
- /** \return gravity center
- **/
- CCVector3 computeGravityCenter();
- //inherited from base class
- void invalidateBoundingBox() override;
- //inherited from ccHObject
- void getDrawingParameters(glDrawParams& params) const override;
- //inherited from ccDrawableObject
- bool hasColors() const override;
- bool hasNormals() const override;
- bool hasScalarFields() const override;
- bool hasDisplayedScalarField() const override;
- void removeFromDisplay(const ccGenericGLDisplay* win) override; //for proper VBO release
- void setDisplay(ccGenericGLDisplay* win) override;
- //inherited from CCCoreLib::GenericCloud
- unsigned char testVisibility(const CCVector3& P) const override;
- //inherited from CCCoreLib::GenericIndexedCloud
- bool normalsAvailable() const override { return hasNormals(); }
- const CCVector3* getNormal(unsigned pointIndex) const override; //equivalent to getPointNormal, but for CCCoreLib
- //inherited from ccGenericPointCloud
- const ccColor::Rgb* geScalarValueColor(ScalarType d) const override;
- const ccColor::Rgb* getPointScalarValueColor(unsigned pointIndex) const override;
- ScalarType getPointDisplayedDistance(unsigned pointIndex) const override;
- const ccColor::Rgba& getPointColor(unsigned pointIndex) const override;
- const CompressedNormType& getPointNormalIndex(unsigned pointIndex) const override;
- const CCVector3& getPointNormal(unsigned pointIndex) const override;
- CCCoreLib::ReferenceCloud* crop(const ccBBox& box, bool inside = true) override;
- void scale(PointCoordinateType fx, PointCoordinateType fy, PointCoordinateType fz, CCVector3 center = CCVector3(0,0,0)) override;
- /** \warning if removeSelectedPoints is true, any attached octree will be deleted, as well as the visibility table. **/
- ccGenericPointCloud* createNewCloudFromVisibilitySelection( bool removeSelectedPoints = false,
- VisibilityTableType* visTable = nullptr,
- std::vector<int>* newIndexesOfRemainingPoints = nullptr,
- bool silent = false,
- CCCoreLib::ReferenceCloud* selection = nullptr) override;
- bool removeVisiblePoints(VisibilityTableType* visTable = nullptr, std::vector<int>* newIndexes = nullptr) override;
- void applyRigidTransformation(const ccGLMatrix& trans) override;
- inline void refreshBB() override { invalidateBoundingBox(); }
- //! Sets whether visibility check is enabled or not (e.g. during distances computation)
- /** See ccPointCloud::testVisibility.
- **/
- inline void enableVisibilityCheck(bool state) { m_visibilityCheckEnabled = state; }
- //! Returns whether the mesh as an associated sensor or not
- bool hasSensor() const;
- //! Comptes the closest point of this cloud relatively to another cloud
- /** The output (reference) clouds will have as many points as this cloud
- (with the indexes pointing on the closest point in the other cloud)
- **/
- QSharedPointer<CCCoreLib::ReferenceCloud> computeCPSet( ccGenericPointCloud& otherCloud,
- CCCoreLib::GenericProgressCallback* progressCb = nullptr,
- unsigned char octreeLevel = 0);
- //! Interpolate colors from another cloud (nearest neighbor only)
- bool interpolateColorsFrom( ccGenericPointCloud* cloud,
- CCCoreLib::GenericProgressCallback* progressCb = nullptr,
- unsigned char octreeLevel = 0);
- //! Sets a particular point color
- /** \warning colors must be enabled.
- **/
- void setPointColor(unsigned pointIndex, const ccColor::Rgba& col);
- //! Sets a particular point color
- /** \warning colors must be enabled.
- **/
- inline void setPointColor(unsigned pointIndex, const ccColor::Rgb& col) { setPointColor(pointIndex, ccColor::Rgba(col, ccColor::MAX)); }
- //! Sets a particular point compressed normal
- /** \warning normals must be enabled.
- **/
- void setPointNormalIndex(unsigned pointIndex, CompressedNormType norm);
- //! Sets a particular point normal (shortcut)
- /** \warning normals must be enabled.
- Normal is automatically compressed before storage.
- **/
- void setPointNormal(unsigned pointIndex, const CCVector3& N);
- //! Pushes a compressed normal vector
- /** \param index compressed normal vector
- **/
- void addNormIndex(CompressedNormType index);
- //! Pushes a normal vector on stack (shortcut)
- /** \param N normal vector
- **/
- void addNorm(const CCVector3& N);
- //! Adds a normal vector to the one at a specific index
- /** The resulting sum is automatically normalized and compressed.
- \param N normal vector to add (size: 3)
- \param index normal index to modify
- **/
- void addNormAtIndex(const PointCoordinateType* N, unsigned index);
- //! Sets the (compressed) normals table
- void setNormsTable(NormsIndexesTableType* norms);
- //! Converts normals to RGB colors
- /** See ccNormalVectors::ConvertNormalToRGB
- \return success
- **/
- bool convertNormalToRGB();
- //! Converts normals to two scalar fields: 'dip' and 'dip direction'
- /** One input scalar field may be empty if the corresponding value is not required
- \param[out] dipSF dip values
- \param[out] dipDirSF dip direction values
- \return success
- **/
- bool convertNormalToDipDirSFs(ccScalarField* dipSF, ccScalarField* dipDirSF);
- //! Pushes an RGBA color on stack
- /** \param C RGBA color
- **/
- void addColor(const ccColor::Rgba& C);
- //! Pushes an RGB color on stack
- /** Will be converted to an RGBA color automatically.
- \param C RGB color
- **/
- inline void addColor(const ccColor::Rgb& C) { addColor(ccColor::Rgba(C, ccColor::MAX)); }
- //! Pushes an RGB color on stack (shortcut)
- /** \param r red component
- \param g green component
- \param b blue component
- \param a alpha component
- **/
- inline void addColor(ColorCompType r, ColorCompType g, ColorCompType b, ColorCompType a = ccColor::MAX) { addColor(ccColor::Rgba(r, g, b, a)); }
- //! Pushes a grey color on stack (shortcut)
- /** Shortcut: color is converted to RGB(g, g, g)
- \param g grey component
- **/
- inline void addGreyColor(ColorCompType g) { addColor(ccColor::Rgba(g, g, g, ccColor::MAX)); }
- //! Converts RGB to grey scale colors
- /** \return success
- **/
- bool convertRGBToGreyScale();
- //! Multiplies all color components of all points by coefficients
- /** If the cloud has no color, all points are considered white and
- the color array is automatically allocated.
- \param r red component
- \param g green component
- \param b blue component
- \param a alpha component
- \return success
- **/
- bool colorize(float r, float g, float b, float a = 1.0f);
- enum RGB_FILTER_TYPES
- {
- NONE,
- BILATERAL,
- GAUSSIAN,
- MEAN,
- MEDIAN
- };
- struct RgbFilterOptions
- {
- bool applyToSFduringRGB = false;
- RGB_FILTER_TYPES filterType = RGB_FILTER_TYPES::NONE;
- unsigned char burntOutColorThreshold = 0;
- bool commandLine = false;
- double sigmaSF = -1;
- double spatialSigma = -1;
- bool blendGrayscale = false;
- unsigned char blendGrayscaleThreshold = 0;
- double blendGrayscalePercent = 0.5;
- };
- //! Applies a spatial Gaussian filter on RGB colors
- /** The "amplitutde" of the Gaussian filter must be specified (sigma).
- As 99% of the Gaussian distribution is between -3*sigma and +3*sigma around the mean value,
- this filter will only look for neighbors within a sphere of radius 3*sigma.
- One can also use the filter as a Bilateral filter. In this case the weights are computed considering the
- difference of the neighbors SF values with the current point SF value (also following a Gaussian distribution).
- Warning: this method assumes the output scalar field is set.
- \param sigma filter variance
- \param sigmaRGB if strictly positive, the variance for the Bilateral filter
- \param applyToSF if true, it will apply filter to the displayed scalar field as well
- \param burntOutColorThreshold if >0 color values which are outside of the [threshold:255-threshold] range will be filtered out
- \param progressCb the client application can get some notification of the process progress through this callback mechanism (see GenericProgressCallback)
- \return success
- **/
- bool applyFilterToRGB( PointCoordinateType sigma,
- PointCoordinateType sigmaSF,
- RgbFilterOptions filterParams,
- CCCoreLib::GenericProgressCallback* progressCb = nullptr);
- //! Assigns color to points proportionally to their 'height'
- /** Height is defined wrt to the specified dimension (heightDim).
- Color array is automatically allocated if necessary.
- \param heightDim ramp dimension (0:X, 1:Y, 2:Z)
- \param colorScale color scale to use
- \return success
- **/
- bool setRGBColorByHeight(unsigned char heightDim, ccColorScale::Shared colorScale);
- //! Assigns color to points by 'banding'
- /** Banding is performed along the specified dimension
- Color array is automatically allocated if necessary.
- \param dim banding dimension (0:X, 1:Y, 2:Z)
- \param freq banding frequency
- \return success
- **/
- bool setRGBColorByBanding(unsigned char dim, double freq);
- //! Converts current scalar field (values & display parameters) to RGB colors
- /** \return success
- **/
- bool convertCurrentScalarFieldToColors(bool mixWithExistingColor = false);
- //! Set a unique color for the whole cloud (shortcut)
- /** Color array is automatically allocated if necessary.
- \param r red component
- \param g green component
- \param b blue component
- \param a alpha component
- \return success
- **/
- inline bool setColor(ColorCompType r, ColorCompType g, ColorCompType b, ColorCompType a = ccColor::MAX) { return setColor(ccColor::Rgba(r, g, b, a)); }
- //! Set a unique color for the whole cloud (RGB version)
- /** Color array is automatically allocated if necessary.
- \param col RGB color
- \return success
- **/
- inline bool setColor(const ccColor::Rgb& col) { return setColor(ccColor::Rgba(col, ccColor::MAX)); }
- //! Set a unique color for the whole cloud (RGBA version)
- /** Color array is automatically allocated if necessary.
- \param col RGBA color
- \return success
- **/
- bool setColor(const ccColor::Rgba& col);
- //! Inverts normals (if any)
- void invertNormals();
- //! Translates cloud
- /** \param T translation vector
- **/
- void translate(const CCVector3& T);
- //! Filters out points whose scalar values falls into an interval
- /** Threshold values should be expressed relatively to the current displayed scalar field.
- \param minVal minimum value
- \param maxVal maximum value
- \param outside whether to select the points inside or outside of the specified interval
- \return resulting cloud (remaining points) or the cloud itself if all points fall inside the input range
- **/
- ccPointCloud* filterPointsByScalarValue(ScalarType minVal, ScalarType maxVal, bool outside = false);
- //! Hides points whose scalar values falls into an interval
- /** Values are taken from the current OUTPUT scalar field.
- \param minVal minimum value (below, points are hidden)
- \param maxVal maximum value (above, points are hidden)
- **/
- void hidePointsByScalarValue(ScalarType minVal, ScalarType maxVal);
- //! Unrolling mode (see ccPointCloud::unroll)
- enum UnrollMode { CYLINDER = 0, CONE_CONICAL = 1, CONE_CYLINDRICAL_FIXED_RADIUS = 2, CONE_CYLINDRICAL_ADAPTIVE_RADIUS = 3 };
- //! Base unrolling parameters
- struct UnrollBaseParams
- {
- PointCoordinateType radius = 0; //!< Unrolling cylinder radius (or cone base radius)
- CCVector3 axisDir; //!< Unrolling cylinder/cone axis direction
- };
- //! Cylinder unrolling parameters
- struct UnrollCylinderParams : public UnrollBaseParams
- {
- CCVector3 center; //!< A point belonging to the cylinder axis
- };
- //! Cone unrolling parameters
- struct UnrollConeParams : public UnrollBaseParams
- {
- CCVector3 apex; //!< Cone apex
- double coneAngle_deg = 0.0; //!< Cone aperture angle (in degrees)
- double spanRatio = 0.5; //!< Conical projection span ratio
- };
- //! Unrolls the cloud and its normals on a cylinder or a cone
- /** This method is redundant with the "developCloudOnCylinder" method of CCCoreLib,
- apart that it can also handle the cloud normals.
- \param mode unrolling mode
- \param params unrolling parameters (must match the unrolling mode)
- \param exportDeviationSF to export the deviations from the ideal shape as a scalar field
- \param startAngle_deg start angle (in degrees) - 0 corresponds to +X (east)
- \param stopAngle_deg stop angle (in degrees)
- \param arbitraryOutputCS whether the output cloud should be exported in an arbitrary coordinate system or not
- \param progressCb for progress notification
- \return the unrolled point cloud
- **/
- ccPointCloud* unroll( UnrollMode mode,
- UnrollBaseParams* params,
- bool exportDeviationSF = false,
- double startAngle_deg = 0.0,
- double stopAngle_deg = 360.0,
- bool arbitraryOutputCS = false,
- CCCoreLib::GenericProgressCallback* progressCb = nullptr) const;
- //! Adds associated SF color ramp info to current GL context
- void addColorRampInfo(CC_DRAW_CONTEXT& context);
- //! Adds an existing scalar field to this cloud
- /** Warning: the cloud takes ownership of it!
- \param sf existing scalar field
- \return index of added scalar field (or -1 if an error occurred)
- **/
- int addScalarField(ccScalarField* sf);
- //! Returns pointer on RGBA colors table
- RGBAColorsTableType* rgbaColors() const { return m_rgbaColors; }
- //! Returns pointer on compressed normals indexes table
- NormsIndexesTableType* normals() const { return m_normals; }
- //! Crops the cloud inside (or outside) a 2D polyline
- /** \warning Always returns a selection (potentially empty) if successful.
- \param poly cropping polyline
- \param orthoDim dimension orthogonal to the plane in which the segmentation should occur (X=0, Y=1, Z=2)
- \param inside whether selected points are inside or outside the polyline
- \return points falling inside (or outside) as a selection
- **/
- CCCoreLib::ReferenceCloud* crop2D(const ccPolyline* poly, unsigned char orthoDim, bool inside = true);
- //! Appends a cloud to this one
- /** Same as the += operator with pointCountBefore == size()
- \param cloud cloud to be added
- \param pointCountBefore the number of points previously contained in this cloud
- \param ignoreChildren whether to copy input cloud's children or not
- \param recomputeMinAndMax whether to compute min and max of scalar fields after append or not
- \return the resulting point cloud
- **/
- const ccPointCloud& append(ccPointCloud* cloud, unsigned pointCountBefore, bool ignoreChildren = false, bool recomputeMinAndMax = true);
- //! Enhances the RGB colors with the current scalar field (assuming it's intensities)
- bool enhanceRGBWithIntensitySF(int sfIdx, bool useCustomIntensityRange = false, double minI = 0.0, double maxI = 1.0);
- //! Exports the specified coordinate dimension(s) to scalar field(s)
- bool exportCoordToSF(bool exportDims[3]);
- //! Sets coordinate(s) from a scalar field
- bool setCoordFromSF(bool importDims[3], CCCoreLib::ScalarField* sf, PointCoordinateType defaultValueForNaN);
- //! Exports the specified normal dimension(s) to scalar field(s)
- bool exportNormalToSF(bool exportDims[3]);
- //! Release VBOs
- void releaseVBOs();
- //! Returns the VBOs size (if any)
- size_t vboSize() const;
- //! Removes the duplicate points and return the corresponding cloud (if any, or the same cloud if there's no duplicate point)
- ccPointCloud* removeDuplicatePoints(double minDistanceBetweenPoints, ccProgressDialog* pDlg = nullptr);
- //! Shift the points of a given quantity along their normals
- bool shiftPointsAlongNormals(PointCoordinateType shift);
- //! Set the path for shaders
- static void SetShaderPath(const QString &path);
- //! Release shaders (if any)
- /** Must be called before the OpenGL context is released.
- **/
- static void ReleaseShaders();
- protected:
- //inherited from ccHObject
- void drawMeOnly(CC_DRAW_CONTEXT& context) override;
- void applyGLTransformation(const ccGLMatrix& trans) override;
- bool toFile_MeOnly(QFile& out, short dataVersion) const override;
- bool fromFile_MeOnly(QFile& in, short dataVersion, int flags, LoadedIDMap& oldToNewIDMap) override;
- short minimumFileVersion_MeOnly() const override;
- void notifyGeometryUpdate() override;
- //inherited from PointCloud
- /** \warning Doesn't handle scan grids!
- **/
- void swapPoints(unsigned firstIndex, unsigned secondIndex) override;
- protected: // variable members
- //! Colors
- RGBAColorsTableType* m_rgbaColors;
- //! Normals (compressed)
- NormsIndexesTableType* m_normals;
- //! Used for drawing normals if needed
- std::vector<CCVector3> m_decompressedNormals;
- //! Specifies whether current scalar field color scale should be displayed or not
- bool m_sfColorScaleDisplayed;
- //! Currently displayed scalar field
- ccScalarField* m_currentDisplayedScalarField;
- //! Currently displayed scalar field index
- int m_currentDisplayedScalarFieldIndex;
- //! Associated grid structure
- std::vector<Grid::Shared> m_grids;
- //! Whether visibility check is available or not (during comparison)
- /** See ccPointCloud::testVisibility
- **/
- bool m_visibilityCheckEnabled;
- protected: // VBO
- //! Init/updates VBOs
- bool updateVBOs(const CC_DRAW_CONTEXT& context, const glDrawParams& glParams);
- class VBO : public QGLBuffer
- {
- public:
- int rgbShift;
- int normalShift;
- //! Inits the VBO
- /** \return the number of allocated bytes (or -1 if an error occurred)
- **/
- int init(int count, bool withColors, bool withNormals, bool* reallocated = nullptr);
- VBO()
- : QGLBuffer(QGLBuffer::VertexBuffer)
- , rgbShift(0)
- , normalShift(0)
- {}
- };
- //! VBO set
- struct vboSet
- {
- //! States of the VBO(s)
- enum STATES { NEW, INITIALIZED, FAILED };
- //! Update flags
- enum UPDATE_FLAGS {
- UPDATE_POINTS = 1,
- UPDATE_COLORS = 2,
- UPDATE_NORMALS = 4,
- UPDATE_ALL = UPDATE_POINTS | UPDATE_COLORS | UPDATE_NORMALS
- };
- vboSet()
- : hasColors(false)
- , colorIsSF(false)
- , sourceSF(nullptr)
- , hasNormals(false)
- , totalMemSizeBytes(0)
- , updateFlags(0)
- , state(NEW)
- {}
- std::vector<VBO*> vbos;
- bool hasColors;
- bool colorIsSF;
- ccScalarField* sourceSF;
- bool hasNormals;
- size_t totalMemSizeBytes;
- int updateFlags;
- //! Current state
- STATES state;
- };
- //! Set of VBOs attached to this cloud
- vboSet m_vboManager;
- //per-block data transfer to the GPU (VBO or standard mode)
- void glChunkVertexPointer(const CC_DRAW_CONTEXT& context, size_t chunkIndex, unsigned decimStep, bool useVBOs);
- void glChunkColorPointer (const CC_DRAW_CONTEXT& context, size_t chunkIndex, unsigned decimStep, bool useVBOs);
- void glChunkSFPointer (const CC_DRAW_CONTEXT& context, size_t chunkIndex, unsigned decimStep, bool useVBOs);
- void glChunkNormalPointer(const CC_DRAW_CONTEXT& context, size_t chunkIndex, unsigned decimStep, bool useVBOs);
- public: //Level of Detail (LOD)
- //! Initializes the LOD structure
- /** \return success
- **/
- bool initLOD();
- //! Clears the LOD structure
- void clearLOD();
- protected: //Level of Detail (LOD)
- //! L.O.D. structure
- ccPointCloudLOD* m_lod;
- protected: //waveform (e.g. from airborne scanners)
- //! General waveform descriptors
- FWFDescriptorSet m_fwfDescriptors;
- //! Per-point waveform accessors
- std::vector<ccWaveform> m_fwfWaveforms;
- //! Waveforms raw data storage
- SharedFWFDataContainer m_fwfData;
- bool m_normalsDrawnAsLines;
- struct NormalLineParameters
- {
- float length = 1.0f;
- ccColor::Rgba color = ccColor::yellow;
- int colorIdx = YELLOW;
- } m_normalLineParameters;
- };
|