diff --git a/include/DistanceComputationTools.h b/include/DistanceComputationTools.h index 7baea07..b77d240 100644 --- a/include/DistanceComputationTools.h +++ b/include/DistanceComputationTools.h @@ -133,7 +133,8 @@ namespace CCCoreLib \param compOctree the pre-computed octree of the compared cloud (warning: both octrees must have the same cubical bounding-box - it is automatically computed if 0) \param refOctree the pre-computed octree of the reference cloud (warning: both octrees must have the same cubical bounding-box - it is automatically computed if 0) - \return 0 if ok, a negative value otherwise + \return DISTANCE_COMPUTATION_RESULTS::SUCCESS on success, + a negative error code from DISTANCE_COMPUTATION_RESULTS otherwise. **/ static int computeCloud2CloudDistances( GenericIndexedCloudPersist* comparedCloud, GenericIndexedCloudPersist* referenceCloud, @@ -210,7 +211,8 @@ namespace CCCoreLib \param progressCb the client application can get some notification of the process progress through this callback mechanism (see GenericProgressCallback) \param cloudOctree the pre-computed octree of the compared cloud (warning: its bounding box should be equal to the union of both point cloud and mesh bbs and it should be cubical - it is automatically computed if 0) - \return 0 if ok, a negative value otherwise + \return DISTANCE_COMPUTATION_RESULTS::SUCCESS on success, + a negative error code from DISTANCE_COMPUTATION_RESULTS otherwise. **/ static int computeCloud2MeshDistances( GenericIndexedCloudPersist* pointCloud, GenericIndexedMesh* mesh, @@ -224,7 +226,8 @@ namespace CCCoreLib \param intersection a specific structure corresponding the intersection of the mesh with the grid \param params parameters \param progressCb the client method can get some notification of the process progress through this callback mechanism (see GenericProgressCallback) - \return -1 if an error occurred (e.g. not enough memory) and 0 otherwise + \return DISTANCE_COMPUTATION_RESULTS::SUCCESS on success, + a negative error code from DISTANCE_COMPUTATION_RESULTS otherwise. **/ static int computeCloud2MeshDistancesWithOctree(const DgmOctree* octree, const GridAndMeshIntersection& intersection, @@ -240,7 +243,8 @@ namespace CCCoreLib \param distance the output distance \param intersection a specific structure corresponding the intersection of the mesh with the grid \param params parameters - \return -1 if an error occurred (e.g. not enough memory) and 0 otherwise + \return DISTANCE_COMPUTATION_RESULTS::SUCCESS on success, + a negative error code from DISTANCE_COMPUTATION_RESULTS otherwise. **/ static int computePoint2MeshDistancesWithOctree(const CCVector3& P, ScalarType& distance, @@ -262,7 +266,8 @@ namespace CCCoreLib \param compOctree the pre-computed octree of the compared cloud (warning: both octrees must have the same cubical bounding-box - it is automatically computed if 0) \param refOctree the pre-computed octree of the reference cloud (warning: both octrees must have the same cubical bounding-box - it is automatically computed if 0) - \return negative error code or a positive value in case of success + \return DISTANCE_COMPUTATION_RESULTS::SUCCESS on success, + a negative error code from DISTANCE_COMPUTATION_RESULTS otherwise. **/ static int computeApproxCloud2CloudDistance(GenericIndexedCloudPersist* comparedCloud, GenericIndexedCloudPersist* referenceCloud, @@ -333,7 +338,8 @@ namespace CCCoreLib \param[in] outputSolutionType if true the scalar field will be set to which solution was selected (from 1 to 4 or from 7 to 9 - see above) \param[out] rms will be set with the Root Mean Square (RMS) distance between a cloud and a cone (optional) - \return negative error code or a positive value in case of success + \return DISTANCE_COMPUTATION_RESULTS::SUCCESS on success, + a negative error code from DISTANCE_COMPUTATION_RESULTS otherwise. **/ static int computeCloud2ConeEquation( GenericIndexedCloudPersist* cloud, const CCVector3& coneP1, @@ -364,7 +370,8 @@ namespace CCCoreLib \param[in] outputSolutionType if true the scalar field will be set to which solution was selected (from 1 to 4 - see above) \param[out] rms will be set with the Root Mean Square (RMS) distance between a cloud and a cylinder (optional) - \return negative error code or a positive value in case of success + \return DISTANCE_COMPUTATION_RESULTS::SUCCESS on success, + a negative error code from DISTANCE_COMPUTATION_RESULTS otherwise. **/ static int computeCloud2CylinderEquation( GenericIndexedCloudPersist* cloud, const CCVector3& cylinderP1, @@ -381,7 +388,8 @@ namespace CCCoreLib \param[in] signedDistances whether to compute signed or positive distances \param[out] rms will be set with the Root Mean Square (RMS) distance between a cloud and a sphere (optional) - \return negative error code or a positive value in case of success + \return DISTANCE_COMPUTATION_RESULTS::SUCCESS on success, + a negative error code from DISTANCE_COMPUTATION_RESULTS otherwise. **/ static int computeCloud2SphereEquation( GenericIndexedCloudPersist *cloud, const CCVector3& sphereCenter, @@ -397,7 +405,8 @@ namespace CCCoreLib \param[in] signedDistances whether to compute signed or absolute distances \param[out] rms will be set with the Root Mean Square (RMS) distance between a cloud and a disc (optional) - \return negative error code or a positive value in case of success + \return DISTANCE_COMPUTATION_RESULTS::SUCCESS on success, + a negative error code from DISTANCE_COMPUTATION_RESULTS otherwise. **/ static int computeCloud2DiscEquation(GenericIndexedCloudPersist* cloud, const CCVector3& discCenter, @@ -412,7 +421,8 @@ namespace CCCoreLib \param[in] signedDistances whether to compute signed or absolute distances \param[out] rms will be set with the Root Mean Square (RMS) distance between a cloud and a plane (optional) - \return negative error code or a positive value in case of success + \return DISTANCE_COMPUTATION_RESULTS::SUCCESS on success, + a negative error code from DISTANCE_COMPUTATION_RESULTS otherwise. **/ static int computeCloud2PlaneEquation( GenericIndexedCloudPersist* cloud, const PointCoordinateType* planeEquation, @@ -428,7 +438,8 @@ namespace CCCoreLib \param[in] signedDistances whether to compute signed or absolute distances \param[out] rms will be set with the Root Mean Square (RMS) distance between a cloud and a rectangle (optional) - \return negative error code or a positive value in case of success + \return DISTANCE_COMPUTATION_RESULTS::SUCCESS on success, + a negative error code from DISTANCE_COMPUTATION_RESULTS otherwise. **/ static int computeCloud2RectangleEquation( GenericIndexedCloudPersist *cloud, PointCoordinateType widthX, @@ -446,7 +457,8 @@ namespace CCCoreLib \param[in] signedDistances whether to compute signed or positive distances \param[out] rms will be set with the Root Mean Square (RMS) distance between a cloud and a box (optional) - \return negative error code or a positive value in case of success + \return DISTANCE_COMPUTATION_RESULTS::SUCCESS on success, + a negative error code from DISTANCE_COMPUTATION_RESULTS otherwise. **/ static int computeCloud2BoxEquation(GenericIndexedCloudPersist* cloud, const CCVector3& boxDimensions, @@ -460,22 +472,13 @@ namespace CCCoreLib \param[in] polyline the polyline to measure to \param[out] rms will be set with the Root Mean Square (RMS) distance between a cloud and a plane (optional) - \return negative error code or a positive value in case of success + \return DISTANCE_COMPUTATION_RESULTS::SUCCESS on success, + a negative error code from DISTANCE_COMPUTATION_RESULTS otherwise. **/ static int computeCloud2PolylineEquation( GenericIndexedCloudPersist* cloud, const Polyline* polyline, double* rms = nullptr); - //! Error estimators - enum ERROR_MEASURES - { - RMS, /**< Root Mean Square error **/ - MAX_DIST_68_PERCENT, /**< Max distance @ 68% (1 sigma) **/ - MAX_DIST_95_PERCENT, /**< Max distance @ 98% (2 sigmas) **/ - MAX_DIST_99_PERCENT, /**< Max distance @ 99% (3 sigmas) **/ - MAX_DIST, /**< Max distance **/ - }; - //! Error codes returned by the distance computation methods enum DISTANCE_COMPUTATION_RESULTS { @@ -522,24 +525,35 @@ namespace CCCoreLib ERROR_UNKOWN_ERRORMEASURES_TYPE, ERROR_INTERNAL, INVALID_INPUT, - SUCCESS = 1, + SUCCESS = 0, }; - //! Computes the "distance" (see ERROR_MEASURES) between a point cloud and a plane + //! Distance/error measurement type + enum MEASURE_TYPE + { + RMS, /**< Root Mean Square distance **/ + MAX_DIST_68_PERCENT, /**< Max distance @ 68% (1 sigma) **/ + MAX_DIST_95_PERCENT, /**< Max distance @ 98% (2 sigmas) **/ + MAX_DIST_99_PERCENT, /**< Max distance @ 99% (3 sigmas) **/ + MAX_DIST, /**< Max distance **/ + }; + + //! Computes the distance 'measure' (see MEASURE_TYPE) between a point cloud and a plane /** \param cloud a point cloud \param planeEquation plane equation: [a,b,c,d] as 'ax+by+cz=d' \param measureType measure type + \return the distance measure (or NAN_VALUE in case of error) **/ - static ScalarType ComputeCloud2PlaneDistance( GenericCloud* cloud, - const PointCoordinateType* planeEquation, - ERROR_MEASURES measureType); + static ScalarType ComputeCloud2PlaneDistanceMeasure(GenericCloud* cloud, + const PointCoordinateType* planeEquation, + MEASURE_TYPE measureType); //! Computes the maximum distance between a point cloud and a plane /** \warning this method uses the cloud global iterator \param cloud a point cloud \param planeEquation plane equation: [a,b,c,d] as 'ax+by+cz=d' \param percent percentage of lowest values ignored - \return the max distance @ 'percent' % between the point and the plane + \return the max distance @ 'percent' % between the point and the plane (or NAN_VALUE in case of error) **/ static ScalarType ComputeCloud2PlaneRobustMax( GenericCloud* cloud, const PointCoordinateType* planeEquation, diff --git a/include/TrueKdTree.h b/include/TrueKdTree.h index a892c40..c50ec9c 100644 --- a/include/TrueKdTree.h +++ b/include/TrueKdTree.h @@ -130,7 +130,7 @@ namespace CCCoreLib \param progressCb the client application can get some notification of the process progress through this callback mechanism (see GenericProgressCallback) **/ bool build( double maxError, - DistanceComputationTools::ERROR_MEASURES errorMeasure = DistanceComputationTools::RMS, + DistanceComputationTools::MEASURE_TYPE errorMeasure = DistanceComputationTools::RMS, unsigned minPointCountPerCell = 3, unsigned maxPointCountPerCell = 0, GenericProgressCallback* progressCb = nullptr); @@ -142,7 +142,7 @@ namespace CCCoreLib inline double getMaxError() const { return m_maxError; } //! Returns max error estimator used for planarity-based split strategy - inline DistanceComputationTools::ERROR_MEASURES getMaxErrorType() const { return m_errorMeasure; } + inline DistanceComputationTools::MEASURE_TYPE getMaxErrorType() const { return m_errorMeasure; } //! Returns all leaf nodes bool getLeaves(LeafVector& leaves) const; @@ -162,7 +162,7 @@ namespace CCCoreLib double m_maxError; //! Error measurement - DistanceComputationTools::ERROR_MEASURES m_errorMeasure; + DistanceComputationTools::MEASURE_TYPE m_errorMeasure; //! Min number of points per cell (speed-up) /** Can't be < 3 diff --git a/src/DistanceComputationTools.cpp b/src/DistanceComputationTools.cpp index 484e529..cec8a47 100644 --- a/src/DistanceComputationTools.cpp +++ b/src/DistanceComputationTools.cpp @@ -216,25 +216,27 @@ int DistanceComputationTools::computeCloud2CloudDistances( GenericIndexedCloudPe reinterpret_cast(&computeSplitDistances) }; - int result = DISTANCE_COMPUTATION_RESULTS::SUCCESS; - if (!comparedOctree) { return DISTANCE_COMPUTATION_RESULTS::ERROR_NULL_COMPAREDOCTREE; } - result = comparedOctree->executeFunctionForAllCellsAtLevel(params.octreeLevel, - params.localModel == NO_MODEL ? computeCellHausdorffDistance : computeCellHausdorffDistanceWithLocalModel, - additionalParameters, - params.multiThread, - progressCb, - "Cloud-Cloud Distance", - params.maxThreadCount); - if(result == 0) //executeFunctionForAllCellsAtLevel returns zero if error or canceled + int result = comparedOctree->executeFunctionForAllCellsAtLevel(params.octreeLevel, + params.localModel == NO_MODEL ? computeCellHausdorffDistance : computeCellHausdorffDistanceWithLocalModel, + additionalParameters, + params.multiThread, + progressCb, + "Cloud-Cloud Distance", + params.maxThreadCount); + if (result == 0) // executeFunctionForAllCellsAtLevel returns zero if error or canceled { - //something went wrong + // something went wrong result = DISTANCE_COMPUTATION_RESULTS::ERROR_EXECUTE_FUNCTION_FOR_ALL_CELLS_AT_LEVEL_FAILURE; } + else + { + result = DISTANCE_COMPUTATION_RESULTS::SUCCESS; + } if (comparedOctree && !compOctree) @@ -3070,13 +3072,13 @@ ScalarType DistanceComputationTools::computeCloud2PlaneDistanceRMS( GenericCloud assert(pointCloud && planeEquation); if (!pointCloud) { - return 0; + return NAN_VALUE; } //point count unsigned count = pointCloud->size(); if (count == 0) { - return 0; + return NAN_VALUE; } //point to plane distance: d = std::abs(a0*x+a1*y+a2*z-a3) / sqrt(a0^2+a1^2+a2^2) <-- "norm" @@ -3111,19 +3113,19 @@ ScalarType DistanceComputationTools::ComputeCloud2PlaneRobustMax( GenericCloud* if (!pointCloud) { - return 0; + return NAN_VALUE; } //point count unsigned count = pointCloud->size(); if (count == 0) { - return 0; + return NAN_VALUE; } //point to plane distance: d = std::abs(a0*x+a1*y+a2*z-a3) / sqrt(a0^2+a1^2+a2^2) <-- "norm" double norm2 = CCVector3::vnorm2d(planeEquation); //the norm should always be equal to 1.0! - if ( LessThanEpsilon( norm2 ) ) + if (LessThanEpsilon(norm2)) { return NAN_VALUE; } @@ -3139,8 +3141,8 @@ ScalarType DistanceComputationTools::ComputeCloud2PlaneRobustMax( GenericCloud* std::size_t pos = 0; for (unsigned i = 0; i < count; ++i) { - const CCVector3* P = pointCloud->getNextPoint(); - PointCoordinateType d = std::abs(CCVector3::vdot(P->u, planeEquation) - planeEquation[3])/*/norm*/; //norm == 1.0 + const CCVector3* P = pointCloud->getNextPoint(); + PointCoordinateType d = std::abs(CCVector3::vdot(P->u, planeEquation) - planeEquation[3]) /*/norm*/; // norm == 1.0 if (pos < tailSize) { @@ -3154,12 +3156,12 @@ ScalarType DistanceComputationTools::ComputeCloud2PlaneRobustMax( GenericCloud* //search the max element of the tail if (pos > 1) { - std::size_t maxPos = pos - 1; + std::size_t maxPos = pos - 1; std::size_t maxIndex = maxPos; for (std::size_t j = 0; j < maxPos; ++j) if (tail[j] < tail[maxIndex]) maxIndex = j; - //and put it to the back! + // and put it at the back! if (maxPos != maxIndex) std::swap(tail[maxIndex], tail[maxPos]); } @@ -3174,19 +3176,19 @@ ScalarType DistanceComputationTools::ComputeCloud2PlaneMaxDistance( GenericCloud assert(pointCloud && planeEquation); if (!pointCloud) { - return 0; + return NAN_VALUE; } //point count unsigned count = pointCloud->size(); if (count == 0) { - return 0; + return NAN_VALUE; } //point to plane distance: d = std::abs(a0*x+a1*y+a2*z-a3) / sqrt(a0^2+a1^2+a2^2) <-- "norm" double norm2 = CCVector3::vnorm2d(planeEquation); //the norm should always be equal to 1.0! - if ( LessThanEpsilon( norm2 ) ) + if (LessThanEpsilon(norm2)) { return NAN_VALUE; } @@ -3198,17 +3200,17 @@ ScalarType DistanceComputationTools::ComputeCloud2PlaneMaxDistance( GenericCloud pointCloud->placeIteratorAtBeginning(); for (unsigned i = 0; i < count; ++i) { - const CCVector3* P = pointCloud->getNextPoint(); - PointCoordinateType d = std::abs(CCVector3::vdot(P->u,planeEquation) - planeEquation[3])/*/norm*/; //norm == 1.0 - maxDist = std::max(d,maxDist); + const CCVector3* P = pointCloud->getNextPoint(); + PointCoordinateType d = std::abs(CCVector3::vdot(P->u, planeEquation) - planeEquation[3]) /*/norm*/; // norm == 1.0 + maxDist = std::max(d, maxDist); } return static_cast(maxDist); } -ScalarType DistanceComputationTools::ComputeCloud2PlaneDistance(GenericCloud* pointCloud, - const PointCoordinateType* planeEquation, - ERROR_MEASURES measureType) +ScalarType DistanceComputationTools::ComputeCloud2PlaneDistanceMeasure(GenericCloud* pointCloud, + const PointCoordinateType* planeEquation, + MEASURE_TYPE measureType) { switch (measureType) { @@ -3227,7 +3229,7 @@ ScalarType DistanceComputationTools::ComputeCloud2PlaneDistance(GenericCloud* po default: assert(false); - return -1.0; + return NAN_VALUE; } } diff --git a/src/RegistrationTools.cpp b/src/RegistrationTools.cpp index 6ee6f90..79ff8e5 100644 --- a/src/RegistrationTools.cpp +++ b/src/RegistrationTools.cpp @@ -371,7 +371,8 @@ ICPRegistrationTools::RESULT_TYPE ICPRegistrationTools::Register( GenericIndexed c2mDistParams.CPSet = data.CPSetPlain; c2mDistParams.maxThreadCount = params.maxThreadCount; c2mDistParams.robust = params.robustC2MSignedDistances; - if (DistanceComputationTools::computeCloud2MeshDistances(data.cloud, inputModelMesh, c2mDistParams, progressCb) < 0) + if (DistanceComputationTools::computeCloud2MeshDistances(data.cloud, inputModelMesh, c2mDistParams, progressCb) < + DistanceComputationTools::DISTANCE_COMPUTATION_RESULTS::SUCCESS) { //an error occurred during distances computation... return ICP_ERROR_DIST_COMPUTATION; @@ -383,7 +384,8 @@ ICPRegistrationTools::RESULT_TYPE ICPRegistrationTools::Register( GenericIndexed DistanceComputationTools::Cloud2CloudDistancesComputationParams c2cDistParams; c2cDistParams.CPSet = data.CPSetRef; c2cDistParams.maxThreadCount = params.maxThreadCount; - if (DistanceComputationTools::computeCloud2CloudDistances(data.cloud, model.cloud, c2cDistParams, progressCb) < 0) + if (DistanceComputationTools::computeCloud2CloudDistances(data.cloud, model.cloud, c2cDistParams, progressCb) < + DistanceComputationTools::DISTANCE_COMPUTATION_RESULTS::SUCCESS) { //an error occurred during distances computation... return ICP_ERROR_DIST_COMPUTATION; @@ -654,7 +656,7 @@ ICPRegistrationTools::RESULT_TYPE ICPRegistrationTools::Register( GenericIndexed { //retrieve the data point normal const CCVector3* Nd = data.cloud->getNormal(i); - + //retrieve the nearest model point normal CCVector3 Nm; if (inputModelMesh) @@ -939,7 +941,8 @@ ICPRegistrationTools::RESULT_TYPE ICPRegistrationTools::Register( GenericIndexed c2mDistParams.CPSet = data.CPSetPlain; c2mDistParams.maxThreadCount = params.maxThreadCount; c2mDistParams.robust = params.robustC2MSignedDistances; - if (DistanceComputationTools::computeCloud2MeshDistances(data.cloud, inputModelMesh, c2mDistParams) < 0) + if (DistanceComputationTools::computeCloud2MeshDistances(data.cloud, inputModelMesh, c2mDistParams) + < DistanceComputationTools::DISTANCE_COMPUTATION_RESULTS::SUCCESS) { //an error occurred during distances computation... result = ICP_ERROR_REGISTRATION_STEP; @@ -951,7 +954,8 @@ ICPRegistrationTools::RESULT_TYPE ICPRegistrationTools::Register( GenericIndexed DistanceComputationTools::Cloud2CloudDistancesComputationParams c2cDistParams; c2cDistParams.CPSet = data.CPSetRef; c2cDistParams.maxThreadCount = params.maxThreadCount; - if (DistanceComputationTools::computeCloud2CloudDistances(data.cloud, model.cloud, c2cDistParams) < 0) + if (DistanceComputationTools::computeCloud2CloudDistances(data.cloud, model.cloud, c2cDistParams) < + DistanceComputationTools::DISTANCE_COMPUTATION_RESULTS::SUCCESS) { //an error occurred during distances computation... result = ICP_ERROR_REGISTRATION_STEP; @@ -1155,7 +1159,7 @@ bool RegistrationTools::RegistrationProcedure( GenericCloud* P, //data { return false; } - + PointCoordinateType sin_t = static_cast(S / Q); PointCoordinateType cos_t = static_cast(C / Q); PointCoordinateType inv_cos_t = 1 - cos_t; diff --git a/src/TrueKdTree.cpp b/src/TrueKdTree.cpp index f842f4a..07fe3de 100644 --- a/src/TrueKdTree.cpp +++ b/src/TrueKdTree.cpp @@ -62,13 +62,13 @@ static void InitProgress(GenericProgressCallback* progressCb, unsigned totalCoun } } -static inline void UpdateProgress(unsigned increment) +static void UpdateProgress(unsigned increment) { if (s_progressCb) { assert(s_totalProgressCount != 0); s_lastProgressCount += increment; - float fPercent = static_cast(s_lastProgressCount) / s_totalProgressCount * 100.0f; + float fPercent = s_lastProgressCount / (s_totalProgressCount * 100.0f); unsigned uiPercent = static_cast(fPercent); if (uiPercent > s_lastProgress) { @@ -90,23 +90,23 @@ TrueKdTree::BaseNode* TrueKdTree::split(ReferenceCloud* subset) //an error occurred during LS plane computation?! (maybe the (3) points are aligned) //we return an invalid Leaf (so as the above level understands that it's not a memory issue) delete subset; - PointCoordinateType fakePlaneEquation[4] = { 0,0,0,0 }; + PointCoordinateType fakePlaneEquation[4] { 0,0,0,0 }; return new Leaf(nullptr, fakePlaneEquation, static_cast(-1)); } //we always split sets larger than a given size - ScalarType error = -1; + ScalarType error = NAN_VALUE; if (count < m_maxPointCountPerCell || count < 2 * m_minPointCountPerCell) { assert(std::abs(CCVector3(planeEquation).norm2() - 1.0) < 1.0e-6); - error = (count > 3 ? DistanceComputationTools::ComputeCloud2PlaneDistance(subset, planeEquation, m_errorMeasure) : 0); + error = (count > 3 ? DistanceComputationTools::ComputeCloud2PlaneDistanceMeasure(subset, planeEquation, m_errorMeasure) : 0); - //we can't split cells with less than twice the minimum number of points per cell! (and min >= 3 so as to fit a plane) - bool isLeaf = (error <= m_maxError || count < 2 * m_minPointCountPerCell); + // we can't split cells with less than twice the minimum number of points per cell! (and min >= 3 so as to fit a plane) + bool isLeaf = (std::isnan(error) || error <= m_maxError || count < 2 * m_minPointCountPerCell); if (isLeaf) { UpdateProgress(count); - //the Leaf class takes ownership of the subset! + // the Leaf class takes ownership of the subset! return new Leaf(subset, planeEquation, error); } } @@ -165,8 +165,10 @@ TrueKdTree::BaseNode* TrueKdTree::split(ReferenceCloud* subset) else //in fact we can't split this cell! { UpdateProgress(count); - if (error < 0) - error = (count != 3 ? DistanceComputationTools::ComputeCloud2PlaneDistance(subset, planeEquation, m_errorMeasure) : 0); + if (std::isnan(error)) + { + error = (count != 3 ? DistanceComputationTools::ComputeCloud2PlaneDistanceMeasure(subset, planeEquation, m_errorMeasure) : 0); + } //the Leaf class takes ownership of the subset! return new Leaf(subset, planeEquation, error); } @@ -239,7 +241,7 @@ TrueKdTree::BaseNode* TrueKdTree::split(ReferenceCloud* subset) } bool TrueKdTree::build( double maxError, - DistanceComputationTools::ERROR_MEASURES errorMeasure/*=DistanceComputationTools::RMS*/, + DistanceComputationTools::MEASURE_TYPE errorMeasure/*=DistanceComputationTools::RMS*/, unsigned minPointCountPerCell/*=3*/, unsigned maxPointCountPerCell/*=0*/, GenericProgressCallback* progressCb/*=nullptr*/)