23 ScalarType& scalarValue) {
28 ScalarType& scalarValue) {
33 ScalarType& scalarValue) {
34 scalarValue = -scalarValue;
40 bool euclideanDistances,
41 bool sameInAndOutScalarField ,
51 if (theOctree->
build(progressCb) < 1) {
72 if (sameInAndOutScalarField) {
76 if (!theCloudOctree)
delete theOctree;
80 _theGradientNorms = theGradientNorms;
85 if (!theCloudOctree)
delete theOctree;
92 void* additionalParameters[3] = {
static_cast<void*
>(&euclideanDistances),
93 static_cast<void*
>(&radius),
94 static_cast<void*
>(_theGradientNorms)};
100 true, progressCb,
"Gradient Computation") == 0) {
105 if (!theCloudOctree) {
115 void** additionalParameters,
118 bool euclideanDistances = *
reinterpret_cast<bool*
>(additionalParameters[0]);
122 reinterpret_cast<ScalarField*
>(additionalParameters[2]);
144 DgmOctree::NeighboursSet::iterator it =
146 for (
unsigned j = 0; j < n; ++j, ++it) {
155 for (
unsigned i = 0; i < n; ++i) {
172 unsigned counter = 0;
176 for (
unsigned j = 1; j < k; ++j) {
183 double norm2 = deltaPos.
norm2d();
186 double deltaValue =
static_cast<double>(v2 - v1);
187 if (!euclideanDistances ||
188 deltaValue * deltaValue < 1.01 * norm2) {
201 sum.y += deltaPos.
y * deltaValue;
202 sum.z += deltaPos.
z * deltaValue;
210 gN =
static_cast<ScalarType
>(sum.norm() / counter);
215 if (theGradientNorms) {
237 if (!theCloud)
return false;
239 unsigned n = theCloud->
size();
240 if (n == 0)
return false;
244 theOctree = theCloudOctree;
247 if (theOctree->
build(progressCb) < 1) {
254 unsigned char level =
265 sprintf(infos,
"Level: %i\n", level);
271 void* additionalParameters[2] = {
reinterpret_cast<void*
>(&sigma),
272 reinterpret_cast<void*
>(&sigmaSF)};
278 progressCb,
"Gaussian Filter computation") == 0) {
291 void** additionalParameters,
328 for (
unsigned i = 0; i < n; ++i, ++it) {
337 bool bilateralFilter = (sigmaSF > 0);
339 for (
unsigned i = 0; i < n; ++i)
341 ScalarType queryValue = 0;
342 if (bilateralFilter) {
360 nNSS, radius,
false);
365 double meanValue = 0.0;
367 for (
unsigned j = 0; j < k; ++j, ++it) {
368 double weight = exp(-(it->squareDistd) /
378 if (bilateralFilter) {
379 ScalarType dSF = queryValue - val;
380 weight *= exp(-(dSF * dSF) / sigmaSF2);
383 meanValue += val * weight;
388 i, wSum != 0.0 ?
static_cast<ScalarType
>(meanValue / wSum)
403 if (!firstCloud || !secondCloud)
return;
405 unsigned n1 = firstCloud->
size();
406 if (n1 != secondCloud->
size() || n1 == 0)
return;
408 for (
unsigned i = 0; i < n1; ++i) {
426 unsigned numberOfPoints = theCloud ? theCloud->
size() : 0;
427 if (numberOfPoints == 0)
return;
429 bool firstValidValue =
true;
431 for (
unsigned i = 0; i < numberOfPoints; ++i) {
434 if (!firstValidValue) {
441 firstValidValue =
false;
454 unsigned n = theCloud->
size();
455 for (
unsigned i = 0; i < n; ++i) {
465 unsigned numberOfClasses,
466 std::vector<int>& histo) {
471 if (!theCloud || numberOfClasses == 0) {
475 unsigned pointCount = theCloud->
size();
478 if (numberOfClasses == 1) {
479 histo.push_back(
static_cast<int>(pointCount));
484 histo.resize(numberOfClasses, 0);
485 }
catch (
const std::bad_alloc) {
491 ScalarType minV, maxV;
502 ScalarType invStep = (maxV > minV ? numberOfClasses / (maxV - minV) : 0);
506 int iNumberOfClasses =
static_cast<int>(numberOfClasses);
507 for (
unsigned i = 0; i < pointCount; ++i) {
510 int aimClass =
static_cast<int>((V - minV) * invStep);
511 if (aimClass == iNumberOfClasses)
525 if (!theCloud || K == 0) {
530 unsigned n = theCloud->
size();
531 if (n == 0)
return false;
534 std::vector<ScalarType> theKMeans;
535 std::vector<unsigned char>
537 std::vector<ScalarType>
539 std::vector<ScalarType> theKSums;
540 std::vector<unsigned> theKNums;
541 std::vector<unsigned>
546 belongings.resize(n);
547 minDistsToMean.resize(n);
550 theOldKNums.resize(K);
551 }
catch (
const std::bad_alloc&) {
557 ScalarType minV, maxV;
569 ScalarType step = (maxV - minV) / K;
570 for (
unsigned char j = 0; j < K; ++j) theKMeans[j] = minV + step * j;
574 double initialCMD = 0;
577 bool meansHaveMoved =
false;
580 meansHaveMoved =
false;
583 for (
unsigned i = 0; i < n; ++i) {
584 unsigned char minK = 0;
588 minDistsToMean[i] =
std::abs(theKMeans[minK] - V);
591 for (
unsigned char j = 1; j < K; ++j) {
592 ScalarType distToMean =
std::abs(theKMeans[j] - V);
593 if (distToMean < minDistsToMean[i]) {
594 minDistsToMean[i] = distToMean;
600 belongings[i] = minK;
601 minDistsToMean[i] = V;
606 theOldKNums = theKNums;
607 std::fill(theKSums.begin(), theKSums.end(),
static_cast<ScalarType
>(0));
608 std::fill(theKNums.begin(), theKNums.end(),
static_cast<unsigned>(0));
610 for (
unsigned i = 0; i < n; ++i) {
611 if (minDistsToMean[i] >= 0)
613 theKSums[belongings[i]] += minDistsToMean[i];
614 ++theKNums[belongings[i]];
619 double classMovingDist = 0.0;
621 for (
unsigned char j = 0; j < K; ++j) {
623 (theKNums[j] > 0 ? theKSums[j] / theKNums[j]
626 if (theOldKNums[j] != theKNums[j]) meansHaveMoved =
true;
628 classMovingDist +=
std::abs(theKMeans[j] - newMean);
630 theKMeans[j] = newMean;
635 if (iteration == 1) {
639 sprintf(buffer,
"K=%i", K);
644 initialCMD = classMovingDist;
646 progressCb->
update(
static_cast<float>(
647 (1.0 - classMovingDist / initialCMD) * 100.0));
650 }
while (meansHaveMoved);
653 std::vector<ScalarType> mins, maxs;
655 mins.resize(K, maxV);
656 maxs.resize(K, minV);
657 }
catch (
const std::bad_alloc&) {
664 for (
unsigned i = 0; i < n; ++i) {
667 if (V < mins[belongings[i]])
668 mins[belongings[i]] = V;
669 else if (V > maxs[belongings[i]])
670 maxs[belongings[i]] = V;
677 for (
unsigned char j = 0; j < K; ++j)
678 if (theKNums[j] == 0) mins[j] = maxs[j] = -1.0;
683 for (
unsigned char j = 0; j < K; ++j) {
684 kmcc[j].
mean = theKMeans[j];
690 if (progressCb) progressCb->
stop();
702 double meanValue = 0.0;
705 for (
unsigned i = 0; i < theCloud->
size(); ++i) {
713 return (
count ?
static_cast<ScalarType
>(meanValue /
count) : 0);
724 double meanValue = 0.0;
727 for (
unsigned i = 0; i < theCloud->
size(); ++i) {
730 double Vd =
static_cast<double>(V);
731 meanValue += Vd * Vd;
736 return (
count ?
static_cast<ScalarType
>(meanValue /
count) : 0);
constexpr ScalarType NAN_VALUE
NaN as a ScalarType value.
constexpr double ZERO_TOLERANCE_D
float PointCoordinateType
Type of the coordinates of a (N-D) point.
virtual void release()
Decrease counter and deletes object when 0.
double norm2d() const
Returns vector square norm (forces double precision output)
The octree structure used throughout the library.
void getCellPos(CellCode code, unsigned char level, Tuple3i &cellPos, bool isCodeTruncated) const
unsigned char findBestLevelForAGivenNeighbourhoodSizeExtraction(PointCoordinateType radius) const
int findNeighborsInASphereStartingFromCell(NearestNeighboursSearchStruct &nNSS, double radius, bool sortValues=true) const
Advanced form of the nearest neighbours search algorithm (in a sphere)
const PointCoordinateType & getCellSize(unsigned char level) const
Returns the octree cells length for a given level of subdivision.
void computeCellCenter(CellCode code, unsigned char level, CCVector3 ¢er, bool isCodeTruncated=false) const
unsigned executeFunctionForAllCellsAtLevel(unsigned char level, octreeCellFunc func, void **additionalParameters, bool multiThread=false, GenericProgressCallback *progressCb=nullptr, const char *functionTitle=nullptr, int maxThreadCount=0)
int build(GenericProgressCallback *progressCb=nullptr)
Builds the structure.
unsigned char findBestLevelForAGivenPopulationPerCell(unsigned indicativeNumberOfPointsPerCell) const
virtual bool enableScalarField()=0
Enables the scalar field associated to the cloud.
virtual unsigned size() const =0
Returns the number of points.
virtual ScalarType getPointScalarValue(unsigned pointIndex) const =0
Returns the ith point associated scalar value.
virtual void setPointScalarValue(unsigned pointIndex, ScalarType value)=0
Sets the ith point associated scalar value.
A generic 3D point cloud with index-based and presistent access to points.
A generic 3D point cloud with index-based point access.
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.
virtual bool textCanBeEdited() const
Returns whether the dialog title and info can be updated or not.
virtual void update(float percent)=0
Notifies the algorithm progress.
bool oneStep()
Increments total progress value of a single unit.
void setPointScalarValue(unsigned pointIndex, ScalarType value) override
Sets the ith point associated scalar value.
virtual GenericIndexedCloudPersist * getAssociatedCloud()
Returns the associated (source) cloud.
unsigned size() const override
Returns the number of points.
virtual unsigned getPointGlobalIndex(unsigned localIndex) const
const CCVector3 * getPointPersistentPtr(unsigned index) override
Returns the ith point as a persistent pointer.
const CCVector3 * getPoint(unsigned index) const override
Returns the ith point.
ScalarType getPointScalarValue(unsigned pointIndex) const override
Returns the ith point associated scalar value.
A simple scalar field (to be associated to a point cloud)
void setValue(std::size_t index, ScalarType value)
bool reserveSafe(std::size_t count)
Reserves memory (no exception thrown)
static bool ValidValue(ScalarType value)
Returns whether a scalar value is valid or not.
__host__ __device__ int2 abs(int2 v)
Generic file read and write utility for python interface.
ReferenceCloud * points
Set of points lying inside this cell.
const DgmOctree * parentOctree
Octree to which the cell belongs.
unsigned char level
Cell level of subdivision.
CellCode truncatedCode
Truncated cell code.
A K-mean class position and boundaries.
ScalarType mean
K-mean class mean value.
ScalarType minValue
K-mean class minimum value.
ScalarType maxValue
K-mean class maximum value.