From a58db939ff87e7f124bd3f60e0b7e2c81d906bf4 Mon Sep 17 00:00:00 2001 From: Daniel Girardeau-Montaut Date: Wed, 12 Jan 2022 23:16:40 +0100 Subject: [PATCH] Add optional parameter to the ComputeCharacteristic method to pass a 'up direction' to compute signed roughness --- include/GeometricalAnalysisTools.h | 2 ++ include/Neighbourhood.h | 8 +++++--- src/GeometricalAnalysisTools.cpp | 9 ++++++--- src/Neighbourhood.cpp | 16 ++++++++++++++-- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/include/GeometricalAnalysisTools.h b/include/GeometricalAnalysisTools.h index cfe753a..7b0a2ab 100644 --- a/include/GeometricalAnalysisTools.h +++ b/include/GeometricalAnalysisTools.h @@ -48,6 +48,7 @@ namespace CCCoreLib \param subOption feature / curvature type / local density computation algorithm or nothing (0) \param cloud cloud to compute the characteristic on \param kernelRadius neighbouring sphere radius + \param roughnessUpDir up direction to compute signed roughness values (optional) \param progressCb client application can get some notification of the process progress through this callback mechanism (see GenericProgressCallback) \param inputOctree if not set as input, octree will be automatically computed. \return succes @@ -56,6 +57,7 @@ namespace CCCoreLib int subOption, GenericIndexedCloudPersist* cloud, PointCoordinateType kernelRadius, + CCVector3* roughnessUpDir = nullptr, GenericProgressCallback* progressCb = nullptr, DgmOctree* inputOctree = nullptr); diff --git a/include/Neighbourhood.h b/include/Neighbourhood.h index 1c0b5cf..235e07f 100644 --- a/include/Neighbourhood.h +++ b/include/Neighbourhood.h @@ -194,11 +194,13 @@ namespace CCCoreLib **/ ScalarType computeMomentOrder1(const CCVector3& P); - //! Computes the roughness of a set of point (by fitting a 2D plane) - /** \return roughness value at a given position P + //! Computes the roughness of a point (by fitting a 2D plane on its neighbors) + /** \param P point for which to compute the roughness value + \param roughnessUpDir up direction to compute a signed roughness value (optional) + \return roughness value at a given position P \warning The point P shouldn't be in the set of points **/ - ScalarType computeRoughness(const CCVector3& P); + ScalarType computeRoughness(const CCVector3& P, CCVector3* roughnessUpDir = nullptr); //! Computes the curvature of a set of point (by fitting a 2.5D quadric) /** \return curvature value at a given position P or CCCoreLib::NAN_VALUE if the computation failed diff --git a/src/GeometricalAnalysisTools.cpp b/src/GeometricalAnalysisTools.cpp index a6b3573..ec16f32 100644 --- a/src/GeometricalAnalysisTools.cpp +++ b/src/GeometricalAnalysisTools.cpp @@ -26,6 +26,7 @@ GeometricalAnalysisTools::ErrorCode GeometricalAnalysisTools::ComputeCharactersi int subOption, GenericIndexedCloudPersist* cloud, PointCoordinateType kernelRadius, + CCVector3* roughnessUpDir/*=nullptr*/, GenericProgressCallback* progressCb/*=nullptr*/, DgmOctree* inputOctree/*=nullptr*/) { @@ -104,7 +105,8 @@ GeometricalAnalysisTools::ErrorCode GeometricalAnalysisTools::ComputeCharactersi { static_cast(&c), static_cast(&subOption), - static_cast(&kernelRadius) + static_cast(&kernelRadius), + static_cast(roughnessUpDir) }; ErrorCode result = NoError; @@ -165,12 +167,13 @@ GeometricalAnalysisTools::ErrorCode GeometricalAnalysisTools::ComputeCharactersi bool GeometricalAnalysisTools::ComputeGeomCharacteristicAtLevel(const DgmOctree::octreeCell& cell, void** additionalParameters, - NormalizedProgress* nProgress/*=0*/) + NormalizedProgress* nProgress/*=nullptr*/) { //parameters GeomCharacteristic c = *static_cast(additionalParameters[0]); int subOption = *static_cast(additionalParameters[1]); PointCoordinateType radius = *static_cast(additionalParameters[2]); + CCVector3* roughnessUpDir = static_cast(additionalParameters[3]); //structure for nearest neighbors search DgmOctree::NearestNeighboursSphericalSearchStruct nNSS; @@ -257,7 +260,7 @@ bool GeometricalAnalysisTools::ComputeGeomCharacteristicAtLevel(const DgmOctree: DgmOctreeReferenceCloud neighboursCloud(&nNSS.pointsInNeighbourhood, neighborCount - 1); //we don't take the query point into account! Neighbourhood Z(&neighboursCloud); - value = Z.computeRoughness(nNSS.queryPoint); + value = Z.computeRoughness(nNSS.queryPoint, roughnessUpDir); //swap the points back to their original position (DGM: not necessary in this case) //if (localIndex+1 < neighborCount) diff --git a/src/Neighbourhood.cpp b/src/Neighbourhood.cpp index 24a9042..5cbeb29 100644 --- a/src/Neighbourhood.cpp +++ b/src/Neighbourhood.cpp @@ -901,12 +901,24 @@ double Neighbourhood::computeFeature(GeomFeature feature) return value; } -ScalarType Neighbourhood::computeRoughness(const CCVector3& P) +ScalarType Neighbourhood::computeRoughness(const CCVector3& P, CCVector3* roughnessUpDir/*=nullptr*/) { const PointCoordinateType* lsPlane = getLSPlane(); if (lsPlane) { - return std::abs(DistanceComputationTools::computePoint2PlaneDistance(&P, lsPlane)); + ScalarType distToPlane = DistanceComputationTools::computePoint2PlaneDistance(&P, lsPlane); + if (roughnessUpDir) + { + if (CCVector3::vdot(lsPlane, roughnessUpDir->u) < 0) + { + distToPlane = -distToPlane; + } + } + else + { + distToPlane = std::abs(distToPlane); + } + return distToPlane; } else {