diff --git a/ContextBasedFeature.cpp b/ContextBasedFeature.cpp new file mode 100644 index 0000000..ea4bd08 --- /dev/null +++ b/ContextBasedFeature.cpp @@ -0,0 +1,28 @@ +//########################################################################## +//# # +//# CLOUDCOMPARE PLUGIN: q3DMASC # +//# # +//# 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: Dimitri Lague / CNRS / UEB # +//# # +//########################################################################## + +#include "ContextBasedFeature.h" + +using namespace masc; + +bool ContextBasedFeature::prepare( const CorePoints& corePoints, + QString& error, + CCLib::GenericProgressCallback* progressCb/*=nullptr*/) +{ + //TODO + return false; +} diff --git a/ContextBasedFeature.h b/ContextBasedFeature.h new file mode 100644 index 0000000..029cdf8 --- /dev/null +++ b/ContextBasedFeature.h @@ -0,0 +1,103 @@ +#pragma once + +//########################################################################## +//# # +//# CLOUDCOMPARE PLUGIN: q3DMASC # +//# # +//# 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: Dimitri Lague / CNRS / UEB # +//# # +//########################################################################## + +//Local +#include "FeaturesInterface.h" + +namespace masc +{ + //! Context-based feature + struct ContextBasedFeature : public Feature + { + public: //ContextBasedFeatureType + + enum ContextBasedFeatureType + { + Invalid = 0 + , DZ + , DH + }; + + static QString ToString(ContextBasedFeatureType type) + { + switch (type) + { + case Invalid: + return "Invalid"; + case DZ: + return "DZ"; + case DH: + return "DH"; + default: + assert(false); + break; + } + return "Invalid"; + } + + static inline ContextBasedFeatureType FromString(const QString& token) { return FromUpperString(token.toUpper()); } + static ContextBasedFeatureType FromUpperString(const QString& token) + { + if (token.startsWith("DZ")) + return DZ; + else if (token.startsWith("DH")) + return DH; + + assert(false); + return Invalid; + } + + public: //methods + + //! Default constructor + ContextBasedFeature(ContextBasedFeatureType p_type, + int p_kNN = 0, + double p_scale = std::numeric_limits::quiet_NaN(), + int p_ctxClassLabel = 0) + : type(p_type) + , kNN(p_kNN) + , ctxClassLabel(p_ctxClassLabel) + { + scale = p_scale; + } + + //! Returns the feature type + virtual Type getType() const override { return Type::ContextBasedFeature; } + //! Clones this feature + virtual Feature::Shared clone() const override { return Feature::Shared(new ContextBasedFeature(*this)); } + //! Prepares the feature (compute the scalar field, etc.) + virtual bool prepare(const CorePoints& corePoints, QString& error, CCLib::GenericProgressCallback* progressCb = nullptr) override; + //! Returns the descriptor for this particular feature + virtual QString toString() const override + { + //use the default keyword + number of neighbors + the scale + the context class + return ToString(type) + QString::number(kNN) + "_SC" + QString::number(scale) + "CTX" + QString::number(ctxClassLabel); + } + + //! Neighborhood feature type + /** \warning different from the feature type + **/ + ContextBasedFeatureType type; + + //Number of neighbors + int kNN; + //! Context class (label) + int ctxClassLabel; + }; +} \ No newline at end of file diff --git a/DualCloudFeature.cpp b/DualCloudFeature.cpp new file mode 100644 index 0000000..d1be5b5 --- /dev/null +++ b/DualCloudFeature.cpp @@ -0,0 +1,28 @@ +//########################################################################## +//# # +//# CLOUDCOMPARE PLUGIN: q3DMASC # +//# # +//# 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: Dimitri Lague / CNRS / UEB # +//# # +//########################################################################## + +#include "DualCloudFeature.h" + +using namespace masc; + +bool DualCloudFeature::prepare( const CorePoints& corePoints, + QString& error, + CCLib::GenericProgressCallback* progressCb/*=nullptr*/) +{ + //TODO + return false; +} diff --git a/DualCloudFeature.h b/DualCloudFeature.h new file mode 100644 index 0000000..65655a0 --- /dev/null +++ b/DualCloudFeature.h @@ -0,0 +1,86 @@ +#pragma once + +//########################################################################## +//# # +//# CLOUDCOMPARE PLUGIN: q3DMASC # +//# # +//# 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: Dimitri Lague / CNRS / UEB # +//# # +//########################################################################## + +//Local +#include "FeaturesInterface.h" + +namespace masc +{ + //! Dual-cloud feature + struct DualCloudFeature : public Feature + { + public: //DualCloudFeatureType + + enum DualCloudFeatureType + { + Invalid = 0 + , IDIFF + }; + + static QString ToString(DualCloudFeatureType type) + { + switch (type) + { + case Invalid: + return "Invalid"; + case IDIFF: + return "IDIFF"; + default: + assert(false); + break; + } + return "Invalid"; + } + + static inline DualCloudFeatureType FromString(const QString& token) { return FromUpperString(token.toUpper()); } + static DualCloudFeatureType FromUpperString(const QString& token) + { + if (token == "IDIFF") + return IDIFF; + + assert(false); + return Invalid; + } + + public: //methods + + //! Default constructor + DualCloudFeature(DualCloudFeatureType p_type) + : type(p_type) + {} + + //! Returns the feature type + virtual Type getType() const override { return Type::DualCloudFeature; } + //! Clones this feature + virtual Feature::Shared clone() const override { return Feature::Shared(new DualCloudFeature(*this)); } + //! Prepares the feature (compute the scalar field, etc.) + virtual bool prepare(const CorePoints& corePoints, QString& error, CCLib::GenericProgressCallback* progressCb = nullptr) override; + //! Returns the descriptor for this particular feature + virtual QString toString() const override + { + //use the default keyword + "_SC" + the scale + return ToString(type) + "_SC" + QString::number(scale); + } + + //! Dual-cloud feature type + /** \warning different from the feature type + **/ + DualCloudFeatureType type; + }; +} \ No newline at end of file diff --git a/Features.h b/Features.h deleted file mode 100644 index 0ce73fd..0000000 --- a/Features.h +++ /dev/null @@ -1,510 +0,0 @@ -#pragma once - -//########################################################################## -//# # -//# CLOUDCOMPARE PLUGIN: q3DMASC # -//# # -//# 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: Dimitri Lague / CNRS / UEB # -//# # -//########################################################################## - -//Local -#include "FeaturesInterface.h" -#include "CorePoints.h" -#include "ScalarFieldWrappers.h" - -//Qt -#include -#include - -class ccPointCloud; - -namespace masc -{ - //! Point feature - struct PointFeature : public Feature - { - public: //PointFeatureType - - enum PointFeatureType - { - Invalid = 0 - , Intensity - , X - , Y - , Z - , NbRet - , RetNb - , EchoRat - , R - , G - , B - , NIR - , DipAng - , DipDir - , M3C2 - , PCV - , SF - }; - - static QString ToString(PointFeatureType type) - { - switch (type) - { - case Invalid: - return "Invalid"; - case Intensity: - return "INT"; - case X: - return "X"; - case Y: - return "Y"; - case Z: - return "Z"; - case NbRet: - return "NbRet"; - case RetNb: - return "RetNb"; - case EchoRat: - return "EchoRat"; - case R: - return "R"; - case G: - return "G"; - case B: - return "B"; - case NIR: - return "NIR"; - case DipAng: - return "NormDip"; - case DipDir: - return "NormDipDir"; - case M3C2: - return "M3C2"; - case PCV: - return "PCV"; - case SF: - return "SF#"; - default: - assert(false); - break; - } - return "Invalid"; - } - - static inline PointFeatureType FromString(const QString& token) { return FromUpperString(token.toUpper()); } - static PointFeatureType FromUpperString(const QString& token) - { - if (token == "INT") - return Intensity; - else if (token == "X") - return X; - else if (token == "Y") - return Y; - else if (token == "Z") - return Z; - else if (token == "NBRET") - return NbRet; - else if (token == "RETNB") - return RetNb; - else if (token == "ECHORAT") - return EchoRat; - else if (token == "R") - return R; - else if (token == "G") - return G; - else if (token == "B") - return B; - else if (token == "NIR") - return NIR; - else if (token == "NORMDIP") - return DipAng; - else if (token == "NORMDIPDIR") - return DipDir; - else if (token == "M3C2") - return M3C2; - else if (token == "PCV") - return PCV; - else if (token.startsWith("SF")) - return SF; - - return Invalid; - } - - public: //methods - - //! Default constructor - PointFeature(PointFeatureType p_type) - : type(p_type) - , sourceSFIndex(-1) - { - //auomatically set the right source for specific features - switch (type) - { - case X: - source = DimX; - sourceName = "X"; - break; - case Y: - source = DimY; - sourceName = "Y"; - break; - case Z: - source = DimZ; - sourceName = "Z"; - break; - case R: - source = Red; - sourceName = "Red"; - break; - case G: - source = Green; - sourceName = "Green"; - break; - case B: - source = Blue; - sourceName = "Blue"; - break; - default: - source = ScalarField; - //sourceName --> TBD later - break; - } - } - - //! Returns the feature type - virtual Type getType() const override { return Type::PointFeature; } - //! Clones this feature - virtual Feature::Shared clone() const override { return Feature::Shared(new PointFeature(*this)); } - //! Prepares the feature (compute the scalar field, etc.) - virtual bool prepare(const CorePoints& corePoints, QString& error, CCLib::GenericProgressCallback* progressCb = nullptr) override; - //! Checks the feature definition validity - virtual bool checkValidity(QString &error) const override; - //! Returns the descriptor for this particular feature - virtual QString toString() const override - { - //default keyword otherwise - QString prefix = ToString(type); - - //special case for the 'SF' type - if (type == SF) - { - //'SF#' + sf index - prefix += QString::number(sourceSFIndex); - } - - //Point features always have a scale equal to 0 by definition - return prefix + "_SC0"; - } - - protected: //methods - - //! Returns the 'source' field from a given cloud - QSharedPointer retrieveField(ccPointCloud* cloud, QString& error); - - public: //members - - //! Point feature type - /** \warning different from the feature type - **/ - PointFeatureType type; - - //! Source scalar field index (if the feature source is 'ScalarField') - int sourceSFIndex; - }; - - //! Neighborhood-based feature - struct NeighborhoodFeature : public Feature - { - public: //NeighborhoodFeatureType - - enum NeighborhoodFeatureType - { - Invalid = 0 - , PCA1 - , PCA2 - , SPHER - , LINEA - , PLANA - , DipAng - , DipDir - , ROUGH - , NBPTS - , CURV - , ZRANGE - , Zmax - , Zmin - , ANISO - , FOM - , LINEF - , ORIENF - }; - - static QString ToString(NeighborhoodFeatureType type) - { - switch (type) - { - case Invalid: - return "Invalid"; - case PCA1: - return "PCA1"; - case PCA2: - return "PCA2"; - case SPHER: - return "SPHER"; - case LINEA: - return "LINEA"; - case PLANA: - return "PLANA"; - case DipAng: - return "DipAng"; - case DipDir: - return "DipDir"; - case ROUGH: - return "ROUGH"; - case NBPTS: - return "NBPTS"; - case CURV: - return "CURV"; - case ZRANGE: - return "ZRANGE"; - case Zmax: - return "Zmax"; - case Zmin: - return "Zmin"; - case ANISO: - return "ANISO"; - case FOM: - return "FOM"; - case LINEF: - return "LINEF"; - case ORIENF: - return "ORIENF"; - default: - assert(false); - break; - } - return "Invalid"; - } - - static inline NeighborhoodFeatureType FromString(const QString& token) { return FromUpperString(token.toUpper()); } - static NeighborhoodFeatureType FromUpperString(const QString& token) - { - if (token == "PCA1") - return PCA1; - else if (token == "PCA2") - return PCA2; - else if (token == "SPHER") - return SPHER; - else if (token == "LINEA") - return LINEA; - else if (token == "PLANA") - return PLANA; - else if (token == "DipAng") - return DipAng; - else if (token == "DipDir") - return DipDir; - else if (token == "ROUGH") - return ROUGH; - else if (token == "NBPTS") - return NBPTS; - else if (token == "CURV") - return CURV; - else if (token == "ZRANGE") - return ZRANGE; - else if (token == "Zmax") - return Zmax; - else if (token == "Zmin") - return Zmin; - else if (token == "ANISO") - return ANISO; - else if (token == "FOM") - return FOM; - else if (token == "LINEF") - return LINEF; - else if (token == "ORIENF") - return ORIENF; - - assert(false); - return Invalid; - } - - public: //methods - - //! Default constructor - NeighborhoodFeature(NeighborhoodFeatureType p_type) - : type(p_type) - { - } - - //! Returns the feature type - virtual Type getType() const override { return Type::NeighborhoodFeature; } - //! Clones this feature - virtual Feature::Shared clone() const override { return Feature::Shared(new NeighborhoodFeature(*this)); } - //! Prepares the feature (compute the scalar field, etc.) - virtual bool prepare(const CorePoints& corePoints, QString& error, CCLib::GenericProgressCallback* progressCb = nullptr) override; - //! Returns the descriptor for this particular feature - virtual QString toString() const override - { - //use the default keyword + the scale - return ToString(type) + "_SC" + QString::number(scale); - } - - public: //members - - //! Neighborhood feature type - /** \warning different from the feature type - **/ - NeighborhoodFeatureType type; - }; - - //! Context-based feature - struct ContextBasedFeature : public Feature - { - public: //ContextBasedFeatureType - - enum ContextBasedFeatureType - { - Invalid = 0 - , DZ - , DH - }; - - static QString ToString(ContextBasedFeatureType type) - { - switch (type) - { - case Invalid: - return "Invalid"; - case DZ: - return "DZ"; - case DH: - return "DH"; - default: - assert(false); - break; - } - return "Invalid"; - } - - static inline ContextBasedFeatureType FromString(const QString& token) { return FromUpperString(token.toUpper()); } - static ContextBasedFeatureType FromUpperString(const QString& token) - { - if (token.startsWith("DZ")) - return DZ; - else if (token.startsWith("DH")) - return DH; - - assert(false); - return Invalid; - } - - public: //methods - - //! Default constructor - ContextBasedFeature(ContextBasedFeatureType p_type, - int p_kNN = 0, - double p_scale = std::numeric_limits::quiet_NaN(), - int p_ctxClassLabel = 0) - : type(p_type) - , kNN(p_kNN) - , ctxClassLabel(p_ctxClassLabel) - { - scale = p_scale; - } - - //! Returns the feature type - virtual Type getType() const override { return Type::ContextBasedFeature; } - //! Clones this feature - virtual Feature::Shared clone() const override { return Feature::Shared(new ContextBasedFeature(*this)); } - //! Prepares the feature (compute the scalar field, etc.) - virtual bool prepare(const CorePoints& corePoints, QString& error, CCLib::GenericProgressCallback* progressCb = nullptr) override; - //! Returns the descriptor for this particular feature - virtual QString toString() const override - { - //use the default keyword + number of neighbors + the scale + the context class - return ToString(type) + QString::number(kNN) + "_SC" + QString::number(scale) + "CTX" + QString::number(ctxClassLabel); - } - - //! Neighborhood feature type - /** \warning different from the feature type - **/ - ContextBasedFeatureType type; - - //Number of neighbors - int kNN; - //! Context class (label) - int ctxClassLabel; - }; - - //! Dual-cloud feature - struct DualCloudFeature : public Feature - { - public: //DualCloudFeatureType - - enum DualCloudFeatureType - { - Invalid = 0 - , IDIFF - }; - - static QString ToString(DualCloudFeatureType type) - { - switch (type) - { - case Invalid: - return "Invalid"; - case IDIFF: - return "IDIFF"; - default: - assert(false); - break; - } - return "Invalid"; - } - - static inline DualCloudFeatureType FromString(const QString& token) { return FromUpperString(token.toUpper()); } - static DualCloudFeatureType FromUpperString(const QString& token) - { - if (token == "IDIFF") - return IDIFF; - - assert(false); - return Invalid; - } - - public: //methods - - //! Default constructor - DualCloudFeature(DualCloudFeatureType p_type) - : type(p_type) - {} - - //! Returns the feature type - virtual Type getType() const override { return Type::DualCloudFeature; } - //! Clones this feature - virtual Feature::Shared clone() const override { return Feature::Shared(new DualCloudFeature(*this)); } - //! Prepares the feature (compute the scalar field, etc.) - virtual bool prepare(const CorePoints& corePoints, QString& error, CCLib::GenericProgressCallback* progressCb = nullptr) override; - //! Returns the descriptor for this particular feature - virtual QString toString() const override - { - //use the default keyword + "_SC" + the scale - return ToString(type) + "_SC" + QString::number(scale); - } - - //! Dual-cloud feature type - /** \warning different from the feature type - **/ - DualCloudFeatureType type; - }; -} \ No newline at end of file diff --git a/NeighborhoodFeature.cpp b/NeighborhoodFeature.cpp new file mode 100644 index 0000000..b90deee --- /dev/null +++ b/NeighborhoodFeature.cpp @@ -0,0 +1,28 @@ +//########################################################################## +//# # +//# CLOUDCOMPARE PLUGIN: q3DMASC # +//# # +//# 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: Dimitri Lague / CNRS / UEB # +//# # +//########################################################################## + +#include "NeighborhoodFeature.h" + +using namespace masc; + +bool NeighborhoodFeature::prepare( const CorePoints& corePoints, + QString& error, + CCLib::GenericProgressCallback* progressCb/*=nullptr*/) +{ + //TODO + return false; +} diff --git a/NeighborhoodFeature.h b/NeighborhoodFeature.h new file mode 100644 index 0000000..df9f536 --- /dev/null +++ b/NeighborhoodFeature.h @@ -0,0 +1,169 @@ +#pragma once + +//########################################################################## +//# # +//# CLOUDCOMPARE PLUGIN: q3DMASC # +//# # +//# 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: Dimitri Lague / CNRS / UEB # +//# # +//########################################################################## + +//Local +#include "FeaturesInterface.h" + +namespace masc +{ + //! Neighborhood-based feature + struct NeighborhoodFeature : public Feature + { + public: //NeighborhoodFeatureType + + enum NeighborhoodFeatureType + { + Invalid = 0 + , PCA1 + , PCA2 + , SPHER + , LINEA + , PLANA + , DipAng + , DipDir + , ROUGH + , NBPTS + , CURV + , ZRANGE + , Zmax + , Zmin + , ANISO + , FOM + , LINEF + , ORIENF + }; + + static QString ToString(NeighborhoodFeatureType type) + { + switch (type) + { + case Invalid: + return "Invalid"; + case PCA1: + return "PCA1"; + case PCA2: + return "PCA2"; + case SPHER: + return "SPHER"; + case LINEA: + return "LINEA"; + case PLANA: + return "PLANA"; + case DipAng: + return "DipAng"; + case DipDir: + return "DipDir"; + case ROUGH: + return "ROUGH"; + case NBPTS: + return "NBPTS"; + case CURV: + return "CURV"; + case ZRANGE: + return "ZRANGE"; + case Zmax: + return "Zmax"; + case Zmin: + return "Zmin"; + case ANISO: + return "ANISO"; + case FOM: + return "FOM"; + case LINEF: + return "LINEF"; + case ORIENF: + return "ORIENF"; + default: + assert(false); + break; + } + return "Invalid"; + } + + static inline NeighborhoodFeatureType FromString(const QString& token) { return FromUpperString(token.toUpper()); } + static NeighborhoodFeatureType FromUpperString(const QString& token) + { + if (token == "PCA1") + return PCA1; + else if (token == "PCA2") + return PCA2; + else if (token == "SPHER") + return SPHER; + else if (token == "LINEA") + return LINEA; + else if (token == "PLANA") + return PLANA; + else if (token == "DipAng") + return DipAng; + else if (token == "DipDir") + return DipDir; + else if (token == "ROUGH") + return ROUGH; + else if (token == "NBPTS") + return NBPTS; + else if (token == "CURV") + return CURV; + else if (token == "ZRANGE") + return ZRANGE; + else if (token == "Zmax") + return Zmax; + else if (token == "Zmin") + return Zmin; + else if (token == "ANISO") + return ANISO; + else if (token == "FOM") + return FOM; + else if (token == "LINEF") + return LINEF; + else if (token == "ORIENF") + return ORIENF; + + assert(false); + return Invalid; + } + + public: //methods + + //! Default constructor + NeighborhoodFeature(NeighborhoodFeatureType p_type) + : type(p_type) + { + } + + //! Returns the feature type + virtual Type getType() const override { return Type::NeighborhoodFeature; } + //! Clones this feature + virtual Feature::Shared clone() const override { return Feature::Shared(new NeighborhoodFeature(*this)); } + //! Prepares the feature (compute the scalar field, etc.) + virtual bool prepare(const CorePoints& corePoints, QString& error, CCLib::GenericProgressCallback* progressCb = nullptr) override; + //! Returns the descriptor for this particular feature + virtual QString toString() const override + { + //use the default keyword + the scale + return ToString(type) + "_SC" + QString::number(scale); + } + + public: //members + + //! Neighborhood feature type + /** \warning different from the feature type + **/ + NeighborhoodFeatureType type; + }; +} \ No newline at end of file diff --git a/Features.cpp b/PointFeature.cpp similarity index 97% rename from Features.cpp rename to PointFeature.cpp index e804c66..a4957b5 100644 --- a/Features.cpp +++ b/PointFeature.cpp @@ -15,10 +15,9 @@ //# # //########################################################################## -#include "Features.h" +#include "PointFeature.h" //Local -#include "ScalarFieldWrappers.h" #include "q3DMASCTools.h" //qCC_io @@ -752,26 +751,29 @@ bool PointFeature::prepare( const CorePoints& corePoints, } } -bool NeighborhoodFeature::prepare( const CorePoints& corePoints, - QString& error, - CCLib::GenericProgressCallback* progressCb/*=nullptr*/) +QString PointFeature::toString() const { - //TODO - return false; -} + //default keyword otherwise + QString description = ToString(type); -bool ContextBasedFeature::prepare( const CorePoints& corePoints, - QString& error, - CCLib::GenericProgressCallback* progressCb/*=nullptr*/) -{ - //TODO - return false; -} + //special case for the 'SF' type + if (type == SF) + { + //'SF#' + sf index + description += QString::number(sourceSFIndex); + } -bool DualCloudFeature::prepare( const CorePoints& corePoints, - QString& error, - CCLib::GenericProgressCallback* progressCb/*=nullptr*/) -{ - //TODO - return false; + if (scaled()) + { + description += QString("_SC%1_%2").arg(scale).arg(StatToString(stat)); + } + else + { + description += "_SC0"; + } + + description += "_" + cloud1Label; + + //Point features always have a scale equal to 0 by definition + return description; } diff --git a/PointFeature.h b/PointFeature.h new file mode 100644 index 0000000..898d13b --- /dev/null +++ b/PointFeature.h @@ -0,0 +1,206 @@ +#pragma once + +//########################################################################## +//# # +//# CLOUDCOMPARE PLUGIN: q3DMASC # +//# # +//# 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: Dimitri Lague / CNRS / UEB # +//# # +//########################################################################## + +//Local +#include "FeaturesInterface.h" +#include "ScalarFieldWrappers.h" + +//Qt +#include + +namespace masc +{ + //! Point feature + struct PointFeature : public Feature + { + public: //PointFeatureType + + enum PointFeatureType + { + Invalid = 0 + , Intensity + , X + , Y + , Z + , NbRet + , RetNb + , EchoRat + , R + , G + , B + , NIR + , DipAng + , DipDir + , M3C2 + , PCV + , SF + }; + + static QString ToString(PointFeatureType type) + { + switch (type) + { + case Invalid: + return "Invalid"; + case Intensity: + return "INT"; + case X: + return "X"; + case Y: + return "Y"; + case Z: + return "Z"; + case NbRet: + return "NbRet"; + case RetNb: + return "RetNb"; + case EchoRat: + return "EchoRat"; + case R: + return "R"; + case G: + return "G"; + case B: + return "B"; + case NIR: + return "NIR"; + case DipAng: + return "NormDip"; + case DipDir: + return "NormDipDir"; + case M3C2: + return "M3C2"; + case PCV: + return "PCV"; + case SF: + return "SF#"; + default: + assert(false); + break; + } + return "Invalid"; + } + + static inline PointFeatureType FromString(const QString& token) { return FromUpperString(token.toUpper()); } + static PointFeatureType FromUpperString(const QString& token) + { + if (token == "INT") + return Intensity; + else if (token == "X") + return X; + else if (token == "Y") + return Y; + else if (token == "Z") + return Z; + else if (token == "NBRET") + return NbRet; + else if (token == "RETNB") + return RetNb; + else if (token == "ECHORAT") + return EchoRat; + else if (token == "R") + return R; + else if (token == "G") + return G; + else if (token == "B") + return B; + else if (token == "NIR") + return NIR; + else if (token == "NORMDIP") + return DipAng; + else if (token == "NORMDIPDIR") + return DipDir; + else if (token == "M3C2") + return M3C2; + else if (token == "PCV") + return PCV; + else if (token.startsWith("SF")) + return SF; + + return Invalid; + } + + public: //methods + + //! Default constructor + PointFeature(PointFeatureType p_type) + : type(p_type) + , sourceSFIndex(-1) + { + //auomatically set the right source for specific features + switch (type) + { + case X: + source = DimX; + sourceName = "X"; + break; + case Y: + source = DimY; + sourceName = "Y"; + break; + case Z: + source = DimZ; + sourceName = "Z"; + break; + case R: + source = Red; + sourceName = "Red"; + break; + case G: + source = Green; + sourceName = "Green"; + break; + case B: + source = Blue; + sourceName = "Blue"; + break; + default: + source = ScalarField; + //sourceName --> TBD later + break; + } + } + + //! Returns the feature type + virtual Type getType() const override { return Type::PointFeature; } + //! Clones this feature + virtual Feature::Shared clone() const override { return Feature::Shared(new PointFeature(*this)); } + //! Prepares the feature (compute the scalar field, etc.) + virtual bool prepare(const CorePoints& corePoints, QString& error, CCLib::GenericProgressCallback* progressCb = nullptr) override; + //! Checks the feature definition validity + virtual bool checkValidity(QString &error) const override; + //! Returns the descriptor for this particular feature + virtual QString toString() const override; + + protected: //methods + + //! Returns the 'source' field from a given cloud + QSharedPointer retrieveField(ccPointCloud* cloud, QString& error); + + public: //members + + //! Point feature type + /** \warning different from the feature type + **/ + PointFeatureType type; + + //! Source scalar field index (if the feature source is 'ScalarField') + int sourceSFIndex; + }; +} diff --git a/q3DMASC.cpp b/q3DMASC.cpp index 2022153..f06f061 100644 --- a/q3DMASC.cpp +++ b/q3DMASC.cpp @@ -21,7 +21,6 @@ #include "q3DMASCDisclaimerDialog.h" #include "q3DMASCClassifier.h" #include "q3DMASCTools.h" -#include "Features.h" //qCC_db #include diff --git a/q3DMASCTools.cpp b/q3DMASCTools.cpp index 6e1ec84..3587565 100644 --- a/q3DMASCTools.cpp +++ b/q3DMASCTools.cpp @@ -18,7 +18,10 @@ #include "q3DMASCTools.h" //Local -#include "ScalarFieldWrappers.h" +#include "PointFeature.h" +#include "NeighborhoodFeature.h" +#include "DualCloudFeature.h" +#include "ContextBasedFeature.h" //qCC_io #include @@ -38,6 +41,23 @@ using namespace masc; +bool Tools::SaveFeatureDescriptors(QString filename, const Feature::Set& features) +{ + QFile file(filename); + if (!file.open(QFile::Text | QFile::WriteOnly)) + { + ccLog::Warning(QString("Can't open file '%1' for writing").arg(filename)); + return false; + } + + QTextStream stream(&file); + + //header + stream << "#3DMASC classifier" << endl; + + return true; +} + bool Tools::LoadFile( QString filename, Feature::Set& rawFeatures, std::vector& loadedClouds, diff --git a/q3DMASCTools.h b/q3DMASCTools.h index 4aaa3c5..00a53f7 100644 --- a/q3DMASCTools.h +++ b/q3DMASCTools.h @@ -18,8 +18,7 @@ //########################################################################## //Local -#include "Features.h" -#include "CorePoints.h" +#include "FeaturesInterface.h" //CCLib #include @@ -38,6 +37,8 @@ namespace masc static bool LoadFile(QString filename, Feature::Set& rawFeatures, std::vector& loadedClouds, CorePoints& corePoints); + static bool SaveFeatureDescriptors(QString filename, const Feature::Set& features); + static bool PrepareFeatures(const CorePoints& corePoints, Feature::Set& features, QString& error, CCLib::GenericProgressCallback* progressCb = nullptr); static bool RandomSubset(ccPointCloud* cloud, float ratio, CCLib::ReferenceCloud* inRatioSubset, CCLib::ReferenceCloud* outRatioSubset);