mirror of
https://github.com/dgirardeau/q3DMASC.git
synced 2026-08-29 16:40:49 +08:00
215 lines
5.4 KiB
C++
215 lines
5.4 KiB
C++
#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 <QSharedPointer>
|
|
|
|
namespace masc
|
|
{
|
|
//! Point feature
|
|
struct PointFeature : public Feature
|
|
{
|
|
public: //PointFeatureType
|
|
|
|
typedef QSharedPointer<PointFeature> Shared;
|
|
|
|
enum PointFeatureType
|
|
{
|
|
Invalid = 0
|
|
, Intensity
|
|
, X
|
|
, Y
|
|
, Z
|
|
, NbRet
|
|
, RetNb
|
|
, EchoRat
|
|
, R
|
|
, G
|
|
, B
|
|
, NIR
|
|
, Dip
|
|
, 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 Dip:
|
|
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 Dip;
|
|
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)
|
|
, field1(nullptr)
|
|
, field2(nullptr)
|
|
, statSF1(nullptr)
|
|
, statSF2(nullptr)
|
|
{
|
|
//auomatically set the right source for specific features
|
|
switch (type)
|
|
{
|
|
case X:
|
|
source = { Source::DimX, "X" };
|
|
break;
|
|
case Y:
|
|
source = { Source::DimY, "Y" };
|
|
break;
|
|
case Z:
|
|
source = { Source::DimZ, "Z" };
|
|
break;
|
|
case R:
|
|
source = { Source::Red, "Red" };
|
|
break;
|
|
case G:
|
|
source = { Source::Green, "Green" };
|
|
break;
|
|
case B:
|
|
source = { Source::Blue, "Blue" };
|
|
break;
|
|
default:
|
|
source = { Source::ScalarField, QString() }; //source name --> TBD later
|
|
break;
|
|
}
|
|
}
|
|
|
|
//inherited from Feature
|
|
virtual Type getType() const override { return Type::PointFeature; }
|
|
virtual Feature::Shared clone() const override { return Feature::Shared(new PointFeature(*this)); }
|
|
virtual bool prepare(const CorePoints& corePoints, QString& error, CCCoreLib::GenericProgressCallback* progressCb = nullptr, SFCollector* generatedScalarFields = nullptr) override;
|
|
virtual bool finish(const CorePoints& corePoints, QString& error) override;
|
|
virtual bool checkValidity(QString corePointRole, QString &error) const override;
|
|
virtual QString toString() const override;
|
|
|
|
//! Compute the associated 'stat' on a set of points (and with a given field)
|
|
bool computeStat(const CCCoreLib::DgmOctree::NeighboursSet& pointsInNeighbourhood, const IScalarFieldWrapper::Shared& sourceField, double& outputValue) const;
|
|
|
|
protected: //methods
|
|
|
|
//! Returns the 'source' field from a given cloud
|
|
IScalarFieldWrapper::Shared 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;
|
|
|
|
//! First cloud 'source' field
|
|
IScalarFieldWrapper::Shared field1;
|
|
|
|
//! Second cloud 'source' field (if any)
|
|
IScalarFieldWrapper::Shared field2;
|
|
|
|
//! For scaled features
|
|
CCCoreLib::ScalarField *statSF1, *statSF2;
|
|
};
|
|
}
|