26 QString&
error)
const {
33 error =
"invalid feature type";
38 error =
"one cloud is required to compute context-based features";
44 error = QString(
"Context cloud (%1) has no classification field")
49 error = QString(
"Context cloud (%1) has an invalid classification "
56 error = QString(
"invalid kNN value for a scale-less context-based "
67 QString& errorMessage,
73 errorMessage =
"internal error (no input core points)";
80 errorMessage =
"internal error (no contextual cloud)";
90 if (!classifSF || classifSF->size() <
cloud1->
size()) {
100 QString resultSFName =
103 resultSFName +=
"@" + QString::number(
scale);
105 resultSFName +=
"@kNN=" + QString::number(
kNN);
115 errorMessage = QString(
"[ContextBasedFeature::prepare] Failed to "
116 "prepare scalar %1 @ scale %2")
128 QString logMessage =
"Computing " + typeStr +
" on cloud " +
130 QString::number(pointCount) +
" points)" +
131 " with context cloud " +
cloud1Label +
" (class " +
135 const ScalarType fClass =
static_cast<ScalarType
>(
ctxClassLabel);
136 unsigned classCount = 0;
137 for (
unsigned i = 0; i < classifSF->size(); ++i) {
138 if (classifSF->
getValue(i) == fClass) ++classCount;
141 if (classCount >=
static_cast<unsigned>(
kNN)) {
143 if (!classCloud.
reserve(classCount)) {
144 errorMessage =
"Not enough memory";
148 for (
unsigned i = 0; i < classifSF->size(); ++i) {
149 if (classifSF->
getValue(i) == fClass) {
155 CVLog::Print(QString(
"Computing octree of class %1 (%2 points)")
161 "[ContextBasedFeature::prepare] Failed to compute "
162 "octree (not enough memory?)";
168 classOctree->findBestLevelForAGivenPopulationPerCell(
170 CVLog::Print(QString(
"[Initial octree level] level = %1")
175 progressCb->
setInfo(qPrintable(logMessage));
181 double meanNeighborhoodSize = 0;
182 int tenth = pointCount / 10;
183 bool cancelled =
false;
186 #pragma omp parallel for num_threads(std::max(1, omp_get_max_threads() - 2))
189 for (
int i = 0; i < static_cast<int>(pointCount); ++i) {
193 double maxSquareDist = 0;
197 int neighborhoodSize = 0;
198 if (classOctree->findPointNeighbourhood(
200 maxSquareDist, 0, &neighborhoodSize) >=
201 static_cast<unsigned>(
kNN)) {
203 for (
int k = 0; k <
kNN; ++k) {
209 s =
static_cast<ScalarType
>(P->
z -
213 s =
static_cast<ScalarType
>(
214 sqrt(pow(P->
x - sumQ.
x /
kNN, 2.0) +
215 pow(P->
y - sumQ.
y /
kNN, 2.0)));
220 if (i && (i % tenth) == 0) {
221 double density = meanNeighborhoodSize / tenth;
227 while (density > 2.9) {
233 "neighborhood size: %1 --> new "
235 .arg(meanNeighborhoodSize / tenth)
237 meanNeighborhoodSize = 0;
239 meanNeighborhoodSize += neighborhoodSize;
251 "[ContextBasedFeature] Process cancelled";
272 QString(
"Cloud %1 has less than %2 points of class %3")
287 ScalarType& outputValue)
const {
288 const ScalarType fClass =
static_cast<ScalarType
>(
ctxClassLabel);
291 unsigned validCount = 0;
299 if (validCount == 0) {
307 static_cast<ScalarType
>(queryPoint.
z - sumQ.
z / validCount);
310 outputValue =
static_cast<ScalarType
>(
311 sqrt(pow(queryPoint.
x - sumQ.
x / validCount, 2.0) +
312 pow(queryPoint.
y - sumQ.
y / validCount, 2.0)));
327 error =
"internal error (no input core points)";
341 corePoints.cloud->setCurrentDisplayedScalarField(sfIndex);
355 if (
kNN != 1) str += QString::number(
kNN);
358 str +=
"_SC" + QString::number(
scale);
constexpr ScalarType NAN_VALUE
NaN as a ScalarType value.
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
static bool Print(const char *format,...)
Prints out a formatted message in console.
static Vector3Tpl fromArray(const int a[3])
Constructor from an int array.
virtual ccOctree::Shared computeOctree(cloudViewer::GenericProgressCallback *progressCb=nullptr, bool autoAddChild=true)
Computes the cloud octree.
QSharedPointer< ccOctree > Shared
Shared pointer.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
bool reserve(unsigned numberOfPoints) override
Reserves memory for all the active features.
static const int MAX_OCTREE_LEVEL
Max octree subdivision level.
std::vector< PointDescriptor > NeighboursSet
A set of neighbours.
virtual unsigned size() const =0
Returns the number of points.
virtual const CCVector3 * getPoint(unsigned index) const =0
Returns the ith point.
virtual void stop()=0
Notifies the fact that the process has ended.
virtual void setInfo(const char *infoStr)=0
Notifies some information about the ongoing process.
virtual void setMethodTitle(const char *methodTitle)=0
Notifies the algorithm title.
bool oneStep()
Increments total progress value of a single unit.
int getScalarFieldIndexByName(const char *name) const
Returns the index of a scalar field represented by its name.
void setCurrentOutScalarField(int index)
Sets the OUTPUT scalar field.
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
unsigned size() const override
ScalarType getPointScalarValue(unsigned pointIndex) const override
const CCVector3 * getPoint(unsigned index) const override
A very simple point cloud (no point duplication)
const CCVector3 * getPoint(unsigned index) const override
Returns the ith point.
A simple scalar field (to be associated to a point cloud)
virtual void computeMinAndMax()
Determines the min and max values.
ScalarType & getValue(std::size_t index)
void setValue(std::size_t index, ScalarType value)
const char * getName() const
Returns scalar field name.
static void error(char *msg)
Structure used during nearest neighbour search.
virtual QString toString() const override
Returns the formatted description.
cloudViewer::ScalarField * sf
The computed scalar.
virtual bool prepare(const CorePoints &corePoints, QString &error, cloudViewer::GenericProgressCallback *progressCb=nullptr, SFCollector *generatedScalarFields=nullptr) override
Prepares the feature (compute the scalar field, etc.)
bool computeValue(cloudViewer::DgmOctree::NeighboursSet &pointsInNeighbourhood, const CCVector3 &queryPoint, ScalarType &outputValue) const
Compute the feature value on a set of points.
virtual bool finish(const CorePoints &corePoints, QString &error) override
Finishes the feature preparation (update the scalar field, etc.)
static QString ToString(ContextBasedFeatureType type)
ContextBasedFeatureType type
Neighborhood feature type.
int ctxClassLabel
Context class (label)
virtual bool checkValidity(QString corePointRole, QString &error) const override
Checks the feature definition validity.
static bool CheckSFExistence(ccPointCloud *cloud, const char *resultSFName)
virtual bool checkValidity(QString corePointRole, QString &error) const
Checks the feature definition validity.
bool scaled() const
Returns whether the feature has an associated scale.
double scale
Scale (diameter)
static cloudViewer::ScalarField * PrepareSF(ccPointCloud *cloud, const char *resultSFName, SFCollector *generatedScalarFields, SFCollector::Behavior behavior)
bool sf1WasAlreadyExisting