diff --git a/include/Delaunay2dMesh.h b/include/Delaunay2dMesh.h index 108defa..dea3b33 100644 --- a/include/Delaunay2dMesh.h +++ b/include/Delaunay2dMesh.h @@ -79,7 +79,6 @@ namespace CCCoreLib //inherited methods (see GenericMesh) unsigned size() const override { return m_numberOfTriangles; } - void forEach(genericTriangleAction action) override; void getBoundingBox(CCVector3& bbMin, CCVector3& bbMax) override; void placeIteratorAtBeginning() override; GenericTriangle* _getNextTriangle() override; diff --git a/include/DgmOctreeReferenceCloud.h b/include/DgmOctreeReferenceCloud.h index 81427a0..1c8c6d7 100644 --- a/include/DgmOctreeReferenceCloud.h +++ b/include/DgmOctreeReferenceCloud.h @@ -23,7 +23,7 @@ namespace CCCoreLib //**** inherited form GenericCloud ****// inline unsigned size() const override { return m_size; } - void forEach(genericPointAction action) override; + void setPointScalarValues(ScalarType value) override; void getBoundingBox(CCVector3& bbMin, CCVector3& bbMax) override; //virtual unsigned char testVisibility(const CCVector3& P) const; //not supported inline void placeIteratorAtBeginning() override { m_globalIterator = 0; } diff --git a/include/GenericCloud.h b/include/GenericCloud.h index c70c555..3c7a1a5 100644 --- a/include/GenericCloud.h +++ b/include/GenericCloud.h @@ -23,21 +23,12 @@ namespace CCCoreLib //! Default destructor virtual ~GenericCloud() = default; - //! Generic function applied to a point (used by foreach) - using genericPointAction = std::function; - //! Returns the number of points /** Virtual method to request the cloud size \return the cloud size **/ virtual unsigned size() const = 0; - //! Fast iteration mechanism - /** Virtual method to apply a function to the whole cloud - \param action the function to apply (see GenericCloud::genericPointAction) - **/ - virtual void forEach(genericPointAction action) = 0; - //! Returns the cloud bounding box /** Virtual method to request the cloud bounding box limits \param bbMin lower bounding-box limits (Xmin,Ymin,Zmin) @@ -88,10 +79,20 @@ namespace CCCoreLib //! Returns true if the scalar field is enabled, false otherwise virtual bool isScalarFieldEnabled() const = 0; + //! Resets all value of the currently enabled scalar field to the same value + /** \param value the value to for to all points + **/ + virtual void setPointScalarValues(ScalarType value) = 0; + //! Sets the ith point associated scalar value + /** \param pointIndex the point index + \param value the value to set + **/ virtual void setPointScalarValue(unsigned pointIndex, ScalarType value) = 0; //! Returns the ith point associated scalar value + /** \param pointIndex the point index + **/ virtual ScalarType getPointScalarValue(unsigned pointIndex) const = 0; }; diff --git a/include/GenericMesh.h b/include/GenericMesh.h index 327a671..7576a89 100644 --- a/include/GenericMesh.h +++ b/include/GenericMesh.h @@ -20,21 +20,12 @@ namespace CCCoreLib //! Default destructor virtual ~GenericMesh() = default; - //! Generic function to apply to a triangle (used by foreach) - using genericTriangleAction = std::function; - //! Returns the number of triangles /** Virtual method to request the mesh size \return the mesh size **/ virtual unsigned size() const = 0; - //! Fast iteration mechanism - /** Virtual method to apply a function to the whole mesh - \param action function to apply (see GenericMesh::genericTriangleAction) - **/ - virtual void forEach(genericTriangleAction action) = 0; - //! Returns the mesh bounding-box /** Virtual method to request the mesh bounding-box limits. It is equivalent to the bounding-box of the cloud composed of the mesh vertexes. diff --git a/include/PointCloudTpl.h b/include/PointCloudTpl.h index c7af351..14c0e1e 100644 --- a/include/PointCloudTpl.h +++ b/include/PointCloudTpl.h @@ -81,39 +81,18 @@ namespace CCCoreLib inline unsigned size() const override { return static_cast(m_points.size()); } - void forEach(GenericCloud::genericPointAction action) override + void setPointScalarValues(ScalarType value) override { - //there's no point of calling forEach if there's no activated scalar field! ScalarField* currentOutScalarFieldArray = getCurrentOutScalarField(); if (!currentOutScalarFieldArray) { + //no activated scalar field! assert(false); return; } - unsigned n = size(); - - if (0 != n) - { - double previousOffset = currentOutScalarFieldArray->getOffset(); - if (n == currentOutScalarFieldArray->size()) - { - // if we are going to change ALL the values, we can also apply the functor on the offset - double firstValue = currentOutScalarFieldArray->getValue(0); - action(m_points.front(), firstValue); - if (ScalarField::ValidValue(firstValue)) - { - currentOutScalarFieldArray->setOffset(firstValue); - } - } - - for (unsigned i = 0; i < n; ++i) - { - ScalarType value = previousOffset + currentOutScalarFieldArray->getLocalValue(i); // warning, the offset has been changed, we can't use getValue anymore - action(m_points[i], value); - currentOutScalarFieldArray->setValue(i, value); - } - } + currentOutScalarFieldArray->resetOffset(); + currentOutScalarFieldArray->fill(value); } void getBoundingBox(CCVector3& bbMin, CCVector3& bbMax) override diff --git a/include/ReferenceCloud.h b/include/ReferenceCloud.h index b347b5e..2240604 100644 --- a/include/ReferenceCloud.h +++ b/include/ReferenceCloud.h @@ -37,7 +37,7 @@ namespace CCCoreLib //**** inherited form GenericCloud ****// inline unsigned size() const override { return static_cast(m_theIndexes.size()); } - void forEach(genericPointAction action) override; + void setPointScalarValues(ScalarType value) override; void getBoundingBox(CCVector3& bbMin, CCVector3& bbMax) override; inline unsigned char testVisibility(const CCVector3& P) const override { assert(m_theAssociatedCloud); return m_theAssociatedCloud->testVisibility(P); } inline void placeIteratorAtBeginning() override { m_globalIterator = 0; } diff --git a/include/ScalarField.h b/include/ScalarField.h index 96ec877..6016013 100644 --- a/include/ScalarField.h +++ b/include/ScalarField.h @@ -70,7 +70,7 @@ namespace CCCoreLib assert(std::isfinite(offset)); m_offsetHasBeenSet = true; - m_offset = offset; + m_offset = (std::abs(offset) < 100.0 ? 0.0 : offset); // don't use a too small offset, as it can cause numerical accuracy issues } //! Resets the offset @@ -111,22 +111,18 @@ namespace CCCoreLib inline ScalarType getMax() const { return m_offset + m_localMaxVal; } //! Fills the array with a particular value - inline void fill(ScalarType fillValue = 0) + inline void fill(ScalarType fillValue = 0, bool autoResetOffset = true) { float fillValueF = 0.0f; if (std::isfinite(fillValue)) { - if (m_offsetHasBeenSet) - { - fillValueF = static_cast(fillValue - m_offset); - } - else + if (!m_offsetHasBeenSet || autoResetOffset) { // if the offset has not been set yet, we use the first finite value by default setOffset(fillValue); - - //fillValueF = 0.0f; // already set } + + fillValueF = static_cast(fillValue - m_offset); } else { @@ -147,6 +143,22 @@ namespace CCCoreLib } } + //! Inverts all values + /** \warning The internal offset will be inverted as well + **/ + inline void invert() + { + if (m_offsetHasBeenSet && std::isfinite(m_offset)) + { + m_offset = -m_offset; + } + + for (float& fValue : *this) + { + fValue = -fValue; + } + } + //! Reserves memory (no exception thrown) CC_CORE_LIB_API bool reserveSafe(std::size_t count); //! Resizes memory (no exception thrown) @@ -171,7 +183,7 @@ namespace CCCoreLib // if the offset has not been set yet, we use the // first finite value as offset by default setOffset(value); - (*this)[index] = 0.0f; + (*this)[index] = static_cast(value - m_offset); } else { @@ -192,7 +204,7 @@ namespace CCCoreLib // if the offset has not been set yet, we use the // first finite value as offset by default setOffset(value); - push_back(0.0f); + push_back(static_cast(value - m_offset)); } else { diff --git a/include/ScalarFieldTools.h b/include/ScalarFieldTools.h index e49b823..b338c33 100644 --- a/include/ScalarFieldTools.h +++ b/include/ScalarFieldTools.h @@ -139,21 +139,6 @@ namespace CCCoreLib KMeanClass kmcc[], GenericProgressCallback* progressCb = nullptr); - //! Sets the distance value associated to a point - /** Generic function that can be used with the GenericCloud::foreach() method. - \param P a 3D point - \param scalarValue its associated scalar value - **/ - static void SetScalarValueToNaN(const CCVector3& P, ScalarType& scalarValue); - - //! Sets the distance value associated to a point to zero - /** Generic function that can be used with the GenericCloud::foreach() method. - \param P a 3D point - \param scalarValue its associated scalar value - **/ - static void SetScalarValueToZero(const CCVector3 &P, ScalarType& scalarValue); - - static void SetScalarValueInverted(const CCVector3 &P, ScalarType& scalarValue); protected: //! "Cellular" function to compute the gradient norms of points inside an octree cell diff --git a/include/SimpleMesh.h b/include/SimpleMesh.h index 1b1918d..b0c7f11 100644 --- a/include/SimpleMesh.h +++ b/include/SimpleMesh.h @@ -34,7 +34,6 @@ namespace CCCoreLib public: //inherited methods - void forEach(genericTriangleAction action) override; void placeIteratorAtBeginning() override; GenericTriangle* _getNextTriangle() override; //temporary GenericTriangle* _getTriangle(unsigned triangleIndex) override; //temporary diff --git a/src/Delaunay2dMesh.cpp b/src/Delaunay2dMesh.cpp index ba5a092..f0b9ec7 100644 --- a/src/Delaunay2dMesh.cpp +++ b/src/Delaunay2dMesh.cpp @@ -318,23 +318,6 @@ bool Delaunay2dMesh::removeTrianglesWithEdgesLongerThan(PointCoordinateType maxE return true; } -void Delaunay2dMesh::forEach(genericTriangleAction action) -{ - if (!m_associatedCloud) - return; - - SimpleTriangle tri; - - const int* _triIndexes = m_triIndexes.data(); - for (unsigned i = 0; i < m_numberOfTriangles; ++i, _triIndexes += 3) - { - tri.A = *m_associatedCloud->getPoint(_triIndexes[0]); - tri.B = *m_associatedCloud->getPoint(_triIndexes[1]); - tri.C = *m_associatedCloud->getPoint(_triIndexes[2]); - action(tri); - } -} - void Delaunay2dMesh::placeIteratorAtBeginning() { m_globalIterator = m_triIndexes.data(); diff --git a/src/DgmOctreeReferenceCloud.cpp b/src/DgmOctreeReferenceCloud.cpp index d02deb5..44d9718 100644 --- a/src/DgmOctreeReferenceCloud.cpp +++ b/src/DgmOctreeReferenceCloud.cpp @@ -63,14 +63,11 @@ void DgmOctreeReferenceCloud::getBoundingBox(CCVector3& bbMin, CCVector3& bbMax) bbMax = m_bbMax; } -void DgmOctreeReferenceCloud::forEach(genericPointAction action) +void DgmOctreeReferenceCloud::setPointScalarValues(ScalarType value) { unsigned count = size(); for (unsigned i = 0; i < count; ++i) { - //we must change from double container to 'ScalarType' one! - ScalarType sqDist = static_cast(m_set->at(i).squareDistd); - action(*m_set->at(i).point, sqDist); - m_set->at(i).squareDistd = static_cast(sqDist); + m_set->at(i).squareDistd = value; } } diff --git a/src/DistanceComputationTools.cpp b/src/DistanceComputationTools.cpp index afa2781..484e529 100644 --- a/src/DistanceComputationTools.cpp +++ b/src/DistanceComputationTools.cpp @@ -173,7 +173,7 @@ int DistanceComputationTools::computeCloud2CloudDistances( GenericIndexedCloudPe } //by default we reset any former value stored in the 'enabled' scalar field - const ScalarType resetValue = maxSearchSquareDistd <= 0 ? NAN_VALUE : params.maxSearchDist; + const ScalarType resetValue = (maxSearchSquareDistd <= 0 ? NAN_VALUE : params.maxSearchDist); if (params.resetFormerDistances) { for (unsigned i = 0; i < comparedCloud->size(); ++i) @@ -1520,18 +1520,18 @@ int DistanceComputationTools::computePoint2MeshDistancesWithOctree( const CCVect bool boundedSearch = (params.maxSearchDist > 0); - PointCloud cloud; - if (!cloud.reserve(1)) + PointCloud pointCloud; + if (!pointCloud.reserve(1)) { return DISTANCE_COMPUTATION_RESULTS::ERROR_OUT_OF_MEMORY; } - cloud.addPoint(P); - if (!cloud.enableScalarField()) + pointCloud.addPoint(P); + if (!pointCloud.enableScalarField()) { return DISTANCE_COMPUTATION_RESULTS::ERROR_OUT_OF_MEMORY; } - cloud.setPointScalarValue(0, NAN_VALUE); - ReferenceCloud Yk(&cloud); + pointCloud.setPointScalarValue(0, NAN_VALUE); + ReferenceCloud Yk(&pointCloud); if (!Yk.reserve(1)) { return DISTANCE_COMPUTATION_RESULTS::ERROR_OUT_OF_MEMORY; @@ -1565,7 +1565,7 @@ int DistanceComputationTools::computePoint2MeshDistancesWithOctree( const CCVect return result; } - distance = cloud.getPointScalarValue(0); + distance = pointCloud.getPointScalarValue(0); return DISTANCE_COMPUTATION_RESULTS::SUCCESS; } @@ -1853,13 +1853,6 @@ int DistanceComputationTools::computeCloud2MeshDistancesWithOctree( const DgmOct #endif // ENABLE_CLOUD2MESH_DIST_MT } -//convert all 'distances' (squared in fact) to their square root -inline void applySqrtToPointDist(const CCVector3 &aPoint, ScalarType& aScalarValue) -{ - if (ScalarField::ValidValue(aScalarValue)) - aScalarValue = sqrt(aScalarValue); -} - int DistanceComputationTools::computeCloud2MeshDistances( GenericIndexedCloudPersist* pointCloud, GenericIndexedMesh* mesh, Cloud2MeshDistancesComputationParams& params, @@ -1992,7 +1985,7 @@ int DistanceComputationTools::computeCloud2MeshDistances( GenericIndexedCloudPer //reset the output distances pointCloud->enableScalarField(); - pointCloud->forEach(ScalarFieldTools::SetScalarValueToNaN); + pointCloud->setPointScalarValues(CCCoreLib::NAN_VALUE); //WE CAN EVENTUALLY COMPUTE THE DISTANCES! int result = computeCloud2MeshDistancesWithOctree(octree, intersection, params, progressCb); @@ -2002,7 +1995,11 @@ int DistanceComputationTools::computeCloud2MeshDistances( GenericIndexedCloudPer !params.signedDistances && !params.useDistanceMap) { - pointCloud->forEach(applySqrtToPointDist); + //convert all squared distances to their root + for (unsigned i = 0; i < pointCloud->size(); ++i) + { + pointCloud->setPointScalarValue(i, sqrt(std::abs(pointCloud->getPointScalarValue(i)))); // std::abs, in case the input value is negative by mistake or because of a numerical accuracy issue + } } if (result < DISTANCE_COMPUTATION_RESULTS::SUCCESS) @@ -2320,7 +2317,7 @@ ScalarType DistanceComputationTools::computePoint2LineSegmentDistSquared(const C return distSq; } -int DistanceComputationTools::computeCloud2ConeEquation(GenericIndexedCloudPersist* cloud, +int DistanceComputationTools::computeCloud2ConeEquation(GenericIndexedCloudPersist* pointCloud, const CCVector3& coneP1, const CCVector3& coneP2, const PointCoordinateType coneR1, @@ -2329,16 +2326,16 @@ int DistanceComputationTools::computeCloud2ConeEquation(GenericIndexedCloudPersi bool outputSolutionType/*=false*/, double* rms/*=nullptr*/) { - if (!cloud) + if (!pointCloud) { return DISTANCE_COMPUTATION_RESULTS::ERROR_NULL_COMPAREDCLOUD; } - unsigned count = cloud->size(); + unsigned count = pointCloud->size(); if (count == 0) { return DISTANCE_COMPUTATION_RESULTS::ERROR_EMPTY_COMPAREDCLOUD; } - if (!cloud->enableScalarField()) + if (!pointCloud->enableScalarField()) { return DISTANCE_COMPUTATION_RESULTS::ERROR_ENABLE_SCALAR_FIELD_FAILURE; } @@ -2360,7 +2357,7 @@ int DistanceComputationTools::computeCloud2ConeEquation(GenericIndexedCloudPersi for (unsigned i = 0; i < count; ++i) { - const CCVector3* P = cloud->getPoint(i); + const CCVector3* P = pointCloud->getPoint(i); CCVector3 n = *P - coneP1; double x = n.dot(coneAxis); double xx = x * x; @@ -2488,11 +2485,11 @@ int DistanceComputationTools::computeCloud2ConeEquation(GenericIndexedCloudPersi } if (signedDistances) { - cloud->setPointScalarValue(i, static_cast(d)); + pointCloud->setPointScalarValue(i, static_cast(d)); } else { - cloud->setPointScalarValue(i, static_cast(std::abs(d))); + pointCloud->setPointScalarValue(i, static_cast(std::abs(d))); } dSumSq += d * d; } @@ -2503,7 +2500,7 @@ int DistanceComputationTools::computeCloud2ConeEquation(GenericIndexedCloudPersi return DISTANCE_COMPUTATION_RESULTS::SUCCESS; } -int DistanceComputationTools::computeCloud2CylinderEquation(GenericIndexedCloudPersist* cloud, +int DistanceComputationTools::computeCloud2CylinderEquation(GenericIndexedCloudPersist* pointCloud, const CCVector3& cylinderP1, const CCVector3& cylinderP2, const PointCoordinateType cylinderRadius, @@ -2511,16 +2508,16 @@ int DistanceComputationTools::computeCloud2CylinderEquation(GenericIndexedCloudP bool outputSolutionType/*=false*/, double* rms/*=nullptr*/) { - if (!cloud) + if (!pointCloud) { return DISTANCE_COMPUTATION_RESULTS::ERROR_NULL_COMPAREDCLOUD; } - unsigned count = cloud->size(); + unsigned count = pointCloud->size(); if (count == 0) { return DISTANCE_COMPUTATION_RESULTS::ERROR_EMPTY_COMPAREDCLOUD; } - if (!cloud->enableScalarField()) + if (!pointCloud->enableScalarField()) { return DISTANCE_COMPUTATION_RESULTS::ERROR_ENABLE_SCALAR_FIELD_FAILURE; } @@ -2535,7 +2532,7 @@ int DistanceComputationTools::computeCloud2CylinderEquation(GenericIndexedCloudP for (unsigned i = 0; i < count; ++i) { - const CCVector3* P = cloud->getPoint(i); + const CCVector3* P = pointCloud->getPoint(i); CCVector3 n = *P - cylinderCenter; double x = std::abs(n.dot(cylinderAxis)); @@ -2602,11 +2599,11 @@ int DistanceComputationTools::computeCloud2CylinderEquation(GenericIndexedCloudP if (signedDistances) { - cloud->setPointScalarValue(i, static_cast(d)); + pointCloud->setPointScalarValue(i, static_cast(d)); } else { - cloud->setPointScalarValue(i, static_cast(std::abs(d))); + pointCloud->setPointScalarValue(i, static_cast(std::abs(d))); } dSumSq += d * d; } @@ -2618,37 +2615,37 @@ int DistanceComputationTools::computeCloud2CylinderEquation(GenericIndexedCloudP return DISTANCE_COMPUTATION_RESULTS::SUCCESS; } -int DistanceComputationTools::computeCloud2SphereEquation( GenericIndexedCloudPersist *cloud, +int DistanceComputationTools::computeCloud2SphereEquation( GenericIndexedCloudPersist* pointCloud, const CCVector3& sphereCenter, const PointCoordinateType sphereRadius, bool signedDistances/*=true*/, double* rms/*=nullptr*/) { - if (!cloud) + if (!pointCloud) { return DISTANCE_COMPUTATION_RESULTS::ERROR_NULL_COMPAREDCLOUD; } - unsigned count = cloud->size(); + unsigned count = pointCloud->size(); if (count == 0) { return DISTANCE_COMPUTATION_RESULTS::ERROR_EMPTY_COMPAREDCLOUD; } - if (!cloud->enableScalarField()) + if (!pointCloud->enableScalarField()) { return DISTANCE_COMPUTATION_RESULTS::ERROR_ENABLE_SCALAR_FIELD_FAILURE; } double dSumSq = 0.0; for (unsigned i = 0; i < count; ++i) { - const CCVector3* P = cloud->getPoint(i); + const CCVector3* P = pointCloud->getPoint(i); double d = (*P - sphereCenter).normd() - sphereRadius; if (signedDistances) { - cloud->setPointScalarValue(i, static_cast(d)); + pointCloud->setPointScalarValue(i, static_cast(d)); } else { - cloud->setPointScalarValue(i, static_cast(std::abs(d))); + pointCloud->setPointScalarValue(i, static_cast(std::abs(d))); } dSumSq += d * d; } @@ -2660,7 +2657,7 @@ int DistanceComputationTools::computeCloud2SphereEquation( GenericIndexedCloudPe return DISTANCE_COMPUTATION_RESULTS::SUCCESS; } -int DistanceComputationTools::computeCloud2DiscEquation(GenericIndexedCloudPersist* cloud, +int DistanceComputationTools::computeCloud2DiscEquation(GenericIndexedCloudPersist* pointCloud, const CCVector3& discCenter, const PointCoordinateType discRadius, const SquareMatrix& rotationTransform, @@ -2671,29 +2668,30 @@ int DistanceComputationTools::computeCloud2DiscEquation(GenericIndexedCloudPersi { return DISTANCE_COMPUTATION_RESULTS::INVALID_INPUT; } - if (!cloud) + if (!pointCloud) { return DISTANCE_COMPUTATION_RESULTS::ERROR_NULL_COMPAREDCLOUD; } - unsigned count = cloud->size(); + unsigned count = pointCloud->size(); if (count == 0) { return DISTANCE_COMPUTATION_RESULTS::ERROR_EMPTY_COMPAREDCLOUD; } - if (!cloud->enableScalarField()) + if (!pointCloud->enableScalarField()) { return DISTANCE_COMPUTATION_RESULTS::ERROR_ENABLE_SCALAR_FIELD_FAILURE; } + const CCVector3d discCenterD = discCenter.toDouble(); CCVector3 normal(0, 0, 1); normal = rotationTransform * normal; double dSumSq = 0.0; for (unsigned i = 0; i < count; ++i) { - const CCVector3* P = cloud->getPoint(i); + CCVector3d P = pointCloud->getPoint(i)->toDouble(); // Project the point onto the plane which contains the disc - ScalarType dPlane = (*P - discCenter).dot(normal); - CCVector3 pProj = *P - normal * dPlane; + ScalarType dPlane = (P - discCenter).dot(normal); + CCVector3d pProj = P - normal.toDouble() * dPlane; ScalarType rProj = (pProj - discCenter).norm(); double d = 0.0; @@ -2704,17 +2702,17 @@ int DistanceComputationTools::computeCloud2DiscEquation(GenericIndexedCloudPersi } else { - CCVector3 pEdge = discCenter + discRadius * (pProj - discCenter) / rProj; // safe as rProj can not be null at this point - d = (*P - pEdge).normd(); // The distance is the distance between the point and the border of the disc - d = (*P - pEdge).dot(normal) > 0 ? d : -d; + CCVector3d pEdge = discCenterD + (discRadius / rProj) * (pProj - discCenterD); // Safe as rProj can not be null at this point + d = (P - pEdge).normd(); // The distance is the distance between the point and the border of the disc + d = (P - pEdge).dot(normal) > 0 ? d : -d; } if (signedDistances) { - cloud->setPointScalarValue(i, static_cast(d)); + pointCloud->setPointScalarValue(i, static_cast(d)); } else { - cloud->setPointScalarValue(i, static_cast(std::abs(d))); + pointCloud->setPointScalarValue(i, static_cast(std::abs(d))); } dSumSq += d * d; } @@ -2726,13 +2724,13 @@ int DistanceComputationTools::computeCloud2DiscEquation(GenericIndexedCloudPersi return DISTANCE_COMPUTATION_RESULTS::SUCCESS; } -int DistanceComputationTools::computeCloud2PlaneEquation( GenericIndexedCloudPersist *cloud, +int DistanceComputationTools::computeCloud2PlaneEquation( GenericIndexedCloudPersist* pointCloud, const PointCoordinateType* planeEquation, bool signedDistances/*=true*/, double* rms/*=nullptr*/) { - assert(cloud && planeEquation); - if (!cloud) + assert(pointCloud && planeEquation); + if (!pointCloud) { return DISTANCE_COMPUTATION_RESULTS::ERROR_NULL_COMPAREDCLOUD; } @@ -2740,12 +2738,12 @@ int DistanceComputationTools::computeCloud2PlaneEquation( GenericIndexedCloudPer { return DISTANCE_COMPUTATION_RESULTS::NULL_PLANE_EQUATION; } - unsigned count = cloud->size(); + unsigned count = pointCloud->size(); if (count == 0) { return DISTANCE_COMPUTATION_RESULTS::ERROR_EMPTY_COMPAREDCLOUD; } - if (!cloud->enableScalarField()) + if (!pointCloud->enableScalarField()) { return DISTANCE_COMPUTATION_RESULTS::ERROR_ENABLE_SCALAR_FIELD_FAILURE; } @@ -2763,15 +2761,15 @@ int DistanceComputationTools::computeCloud2PlaneEquation( GenericIndexedCloudPer double dSumSq = 0.0; for (unsigned i = 0; i < count; ++i) { - const CCVector3* P = cloud->getPoint(i); + const CCVector3* P = pointCloud->getPoint(i); double d = CCVector3::vdotd(P->u, planeEquation) - planeEquation[3]; if (signedDistances) { - cloud->setPointScalarValue(i, static_cast(d)); + pointCloud->setPointScalarValue(i, static_cast(d)); } else { - cloud->setPointScalarValue(i, static_cast(std::abs(d))); + pointCloud->setPointScalarValue(i, static_cast(std::abs(d))); } dSumSq += d * d; } @@ -2783,7 +2781,7 @@ int DistanceComputationTools::computeCloud2PlaneEquation( GenericIndexedCloudPer return DISTANCE_COMPUTATION_RESULTS::SUCCESS; } -int DistanceComputationTools::computeCloud2RectangleEquation( GenericIndexedCloudPersist *cloud, +int DistanceComputationTools::computeCloud2RectangleEquation( GenericIndexedCloudPersist* pointCloud, PointCoordinateType widthX, PointCoordinateType widthY, const SquareMatrix& rotationTransform, @@ -2799,17 +2797,17 @@ int DistanceComputationTools::computeCloud2RectangleEquation( GenericIndexedClou // p0-------------------->p1 //Rect(s,t)=p0 + s*0e + t*e1 //for s,t in {0,1} - assert(cloud); - if (!cloud) + assert(pointCloud); + if (!pointCloud) { return DISTANCE_COMPUTATION_RESULTS::ERROR_NULL_COMPAREDCLOUD; } - unsigned count = cloud->size(); + unsigned count = pointCloud->size(); if (count == 0) { return DISTANCE_COMPUTATION_RESULTS::ERROR_EMPTY_COMPAREDCLOUD; } - if (!cloud->enableScalarField()) + if (!pointCloud->enableScalarField()) { return DISTANCE_COMPUTATION_RESULTS::ERROR_ENABLE_SCALAR_FIELD_FAILURE; } @@ -2835,7 +2833,7 @@ int DistanceComputationTools::computeCloud2RectangleEquation( GenericIndexedClou for (unsigned i = 0; i < count; ++i) { - const CCVector3* pe = cloud->getPoint(i); + const CCVector3* pe = pointCloud->getPoint(i); CCVector3 dist = (*pe - rectangleP0); PointCoordinateType s = e0.dot(dist); if (s > 0) @@ -2870,7 +2868,7 @@ int DistanceComputationTools::computeCloud2RectangleEquation( GenericIndexedClou { d = -d; } - cloud->setPointScalarValue(i, static_cast(d)); + pointCloud->setPointScalarValue(i, static_cast(d)); } if (rms) { @@ -2879,24 +2877,24 @@ int DistanceComputationTools::computeCloud2RectangleEquation( GenericIndexedClou return DISTANCE_COMPUTATION_RESULTS::SUCCESS; } -int DistanceComputationTools::computeCloud2BoxEquation( GenericIndexedCloudPersist* cloud, +int DistanceComputationTools::computeCloud2BoxEquation( GenericIndexedCloudPersist* pointCloud, const CCVector3& boxDimensions, const SquareMatrix& rotationTransform, const CCVector3& boxCenter, bool signedDistances/*=true*/, double* rms/*=nullptr*/) { - assert(cloud); - if (!cloud) + assert(pointCloud); + if (!pointCloud) { return DISTANCE_COMPUTATION_RESULTS::ERROR_NULL_COMPAREDCLOUD; } - unsigned count = cloud->size(); + unsigned count = pointCloud->size(); if (count == 0) { return DISTANCE_COMPUTATION_RESULTS::ERROR_EMPTY_COMPAREDCLOUD; } - if (!cloud->enableScalarField()) + if (!pointCloud->enableScalarField()) { return DISTANCE_COMPUTATION_RESULTS::ERROR_ENABLE_SCALAR_FIELD_FAILURE; } @@ -2915,10 +2913,10 @@ int DistanceComputationTools::computeCloud2BoxEquation( GenericIndexedCloudPersi u = rotationTransform * u; v = rotationTransform * v; w = rotationTransform * w; - PointCoordinateType dSumSq = 0; + double dSumSq = 0; for (unsigned i = 0; i < count; ++i) { - const CCVector3* p = cloud->getPoint(i); + const CCVector3* p = pointCloud->getPoint(i); CCVector3 pointCenterDifference = (*p - boxCenter); CCVector3 p_inBoxCoords(pointCenterDifference.dot(u), pointCenterDifference.dot(v), pointCenterDifference.dot(w)); bool insideBox = (std::abs(p_inBoxCoords.x) <= hu && std::abs(p_inBoxCoords.y) <= hv && std::abs(p_inBoxCoords.z) <= hw); @@ -2987,7 +2985,7 @@ int DistanceComputationTools::computeCloud2BoxEquation( GenericIndexedCloudPersi { d = -d; } - cloud->setPointScalarValue(i, static_cast(d)); + pointCloud->setPointScalarValue(i, static_cast(d)); } if (rms) { @@ -2996,21 +2994,21 @@ int DistanceComputationTools::computeCloud2BoxEquation( GenericIndexedCloudPersi return DISTANCE_COMPUTATION_RESULTS::SUCCESS; } -int DistanceComputationTools::computeCloud2PolylineEquation(GenericIndexedCloudPersist* cloud, +int DistanceComputationTools::computeCloud2PolylineEquation(GenericIndexedCloudPersist* pointCloud, const Polyline* polyline, double* rms/*=nullptr*/) { - if (!cloud) + if (!pointCloud) { assert(false); return DISTANCE_COMPUTATION_RESULTS::ERROR_NULL_COMPAREDCLOUD; } - unsigned count = cloud->size(); + unsigned count = pointCloud->size(); if (count == 0) { return DISTANCE_COMPUTATION_RESULTS::ERROR_EMPTY_COMPAREDCLOUD; } - if (!cloud->enableScalarField()) + if (!pointCloud->enableScalarField()) { return DISTANCE_COMPUTATION_RESULTS::ERROR_ENABLE_SCALAR_FIELD_FAILURE; } @@ -3029,7 +3027,7 @@ int DistanceComputationTools::computeCloud2PolylineEquation(GenericIndexedCloudP for (unsigned i = 0; i < count; ++i) { ScalarType distSq = NAN_VALUE; - const CCVector3* p = cloud->getPoint(i); + const CCVector3* p = pointCloud->getPoint(i); for (unsigned j = 0; j < polyline->size() - 1; j++) { const CCVector3* start = polyline->getPoint(j); @@ -3056,7 +3054,7 @@ int DistanceComputationTools::computeCloud2PolylineEquation(GenericIndexedCloudP } d = sqrt(distSq); dSumSq += distSq; - cloud->setPointScalarValue(i, d); + pointCloud->setPointScalarValue(i, d); } if (rms) @@ -3066,16 +3064,16 @@ int DistanceComputationTools::computeCloud2PolylineEquation(GenericIndexedCloudP return DISTANCE_COMPUTATION_RESULTS::SUCCESS; } -ScalarType DistanceComputationTools::computeCloud2PlaneDistanceRMS( GenericCloud* cloud, +ScalarType DistanceComputationTools::computeCloud2PlaneDistanceRMS( GenericCloud* pointCloud, const PointCoordinateType* planeEquation) { - assert(cloud && planeEquation); - if (!cloud) + assert(pointCloud && planeEquation); + if (!pointCloud) { return 0; } //point count - unsigned count = cloud->size(); + unsigned count = pointCloud->size(); if (count == 0) { return 0; @@ -3092,10 +3090,10 @@ ScalarType DistanceComputationTools::computeCloud2PlaneDistanceRMS( GenericCloud //compute deviations double dSumSq = 0.0; - cloud->placeIteratorAtBeginning(); + pointCloud->placeIteratorAtBeginning(); for (unsigned i = 0; i < count; ++i) { - const CCVector3* P = cloud->getNextPoint(); + const CCVector3* P = pointCloud->getNextPoint(); double d = CCVector3::vdotd(P->u, planeEquation) - planeEquation[3]/*/norm*/; //norm == 1.0 dSumSq += d*d; @@ -3104,19 +3102,19 @@ ScalarType DistanceComputationTools::computeCloud2PlaneDistanceRMS( GenericCloud return static_cast(sqrt(dSumSq / count)); } -ScalarType DistanceComputationTools::ComputeCloud2PlaneRobustMax( GenericCloud* cloud, +ScalarType DistanceComputationTools::ComputeCloud2PlaneRobustMax( GenericCloud* pointCloud, const PointCoordinateType* planeEquation, float percent) { - assert(cloud && planeEquation); + assert(pointCloud && planeEquation); assert(percent < 1.0f); - if (!cloud) + if (!pointCloud) { return 0; } //point count - unsigned count = cloud->size(); + unsigned count = pointCloud->size(); if (count == 0) { return 0; @@ -3137,11 +3135,11 @@ ScalarType DistanceComputationTools::ComputeCloud2PlaneRobustMax( GenericCloud* tail.resize(tailSize); //compute deviations - cloud->placeIteratorAtBeginning(); + pointCloud->placeIteratorAtBeginning(); std::size_t pos = 0; for (unsigned i = 0; i < count; ++i) { - const CCVector3* P = cloud->getNextPoint(); + const CCVector3* P = pointCloud->getNextPoint(); PointCoordinateType d = std::abs(CCVector3::vdot(P->u, planeEquation) - planeEquation[3])/*/norm*/; //norm == 1.0 if (pos < tailSize) @@ -3170,16 +3168,16 @@ ScalarType DistanceComputationTools::ComputeCloud2PlaneRobustMax( GenericCloud* return static_cast(tail.back()); } -ScalarType DistanceComputationTools::ComputeCloud2PlaneMaxDistance( GenericCloud* cloud, +ScalarType DistanceComputationTools::ComputeCloud2PlaneMaxDistance( GenericCloud* pointCloud, const PointCoordinateType* planeEquation) { - assert(cloud && planeEquation); - if (!cloud) + assert(pointCloud && planeEquation); + if (!pointCloud) { return 0; } //point count - unsigned count = cloud->size(); + unsigned count = pointCloud->size(); if (count == 0) { return 0; @@ -3197,10 +3195,10 @@ ScalarType DistanceComputationTools::ComputeCloud2PlaneMaxDistance( GenericCloud //we search the max distance PointCoordinateType maxDist = 0; - cloud->placeIteratorAtBeginning(); + pointCloud->placeIteratorAtBeginning(); for (unsigned i = 0; i < count; ++i) { - const CCVector3* P = cloud->getNextPoint(); + 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); } @@ -3208,46 +3206,49 @@ ScalarType DistanceComputationTools::ComputeCloud2PlaneMaxDistance( GenericCloud return static_cast(maxDist); } -ScalarType DistanceComputationTools::ComputeCloud2PlaneDistance(GenericCloud* cloud, +ScalarType DistanceComputationTools::ComputeCloud2PlaneDistance(GenericCloud* pointCloud, const PointCoordinateType* planeEquation, ERROR_MEASURES measureType) { switch (measureType) { - case RMS: - return DistanceComputationTools::computeCloud2PlaneDistanceRMS(cloud,planeEquation); + case RMS: + return DistanceComputationTools::computeCloud2PlaneDistanceRMS(pointCloud, planeEquation); - case MAX_DIST_68_PERCENT: - return DistanceComputationTools::ComputeCloud2PlaneRobustMax(cloud,planeEquation,0.32f); - case MAX_DIST_95_PERCENT: - return DistanceComputationTools::ComputeCloud2PlaneRobustMax(cloud,planeEquation,0.05f); - case MAX_DIST_99_PERCENT: - return DistanceComputationTools::ComputeCloud2PlaneRobustMax(cloud,planeEquation,0.01f); + case MAX_DIST_68_PERCENT: + return DistanceComputationTools::ComputeCloud2PlaneRobustMax(pointCloud, planeEquation, 0.32f); + case MAX_DIST_95_PERCENT: + return DistanceComputationTools::ComputeCloud2PlaneRobustMax(pointCloud, planeEquation, 0.05f); + case MAX_DIST_99_PERCENT: + return DistanceComputationTools::ComputeCloud2PlaneRobustMax(pointCloud, planeEquation, 0.01f); - case MAX_DIST: - return DistanceComputationTools::ComputeCloud2PlaneMaxDistance(cloud,planeEquation); + case MAX_DIST: + return DistanceComputationTools::ComputeCloud2PlaneMaxDistance(pointCloud, planeEquation); - default: - assert(false); - return -1.0; + default: + assert(false); + return -1.0; } } -bool DistanceComputationTools::computeGeodesicDistances(GenericIndexedCloudPersist* cloud, unsigned seedPointIndex, unsigned char octreeLevel, GenericProgressCallback* progressCb) +bool DistanceComputationTools::computeGeodesicDistances(GenericIndexedCloudPersist* pointCloud, + unsigned seedPointIndex, + unsigned char octreeLevel, + GenericProgressCallback* progressCb) { - assert(cloud); - if (!cloud) + assert(pointCloud); + if (!pointCloud) { return false; } - unsigned n = cloud->size(); + unsigned n = pointCloud->size(); if (n == 0 || seedPointIndex >= n) return false; - cloud->enableScalarField(); - cloud->forEach(ScalarFieldTools::SetScalarValueToNaN); + pointCloud->enableScalarField(); + pointCloud->setPointScalarValues(CCCoreLib::NAN_VALUE); - DgmOctree* octree = new DgmOctree(cloud); + DgmOctree* octree = new DgmOctree(pointCloud); if (octree->build(progressCb) < 1) { delete octree; @@ -3255,7 +3256,7 @@ bool DistanceComputationTools::computeGeodesicDistances(GenericIndexedCloudPersi } FastMarchingForPropagation fm; - if (fm.init(cloud,octree,octreeLevel,true) < 0) + if (fm.init(pointCloud,octree,octreeLevel,true) < 0) { delete octree; return false; @@ -3263,7 +3264,7 @@ bool DistanceComputationTools::computeGeodesicDistances(GenericIndexedCloudPersi //on cherche la cellule de l'octree qui englobe le "seedPoint" Tuple3i cellPos; - octree->getTheCellPosWhichIncludesThePoint(cloud->getPoint(seedPointIndex), cellPos, octreeLevel); + octree->getTheCellPosWhichIncludesThePoint(pointCloud->getPoint(seedPointIndex), cellPos, octreeLevel); fm.setSeedCell(cellPos); bool result = false; diff --git a/src/GeometricalAnalysisTools.cpp b/src/GeometricalAnalysisTools.cpp index 2f4aaa7..f6a4e61 100644 --- a/src/GeometricalAnalysisTools.cpp +++ b/src/GeometricalAnalysisTools.cpp @@ -323,7 +323,7 @@ GeometricalAnalysisTools::ErrorCode GeometricalAnalysisTools::FlagDuplicatePoint } //set all flags to 0 by default - cloud->forEach(ScalarFieldTools::SetScalarValueToZero); + cloud->setPointScalarValues(0); unsigned char level = theOctree->findBestLevelForAGivenNeighbourhoodSizeExtraction(static_cast(minDistanceBetweenPoints)); diff --git a/src/ReferenceCloud.cpp b/src/ReferenceCloud.cpp index b177b52..f0f100f 100644 --- a/src/ReferenceCloud.cpp +++ b/src/ReferenceCloud.cpp @@ -149,17 +149,14 @@ void ReferenceCloud::setPointIndex(unsigned localIndex, unsigned globalIndex) invalidateBoundingBox(); } -void ReferenceCloud::forEach(genericPointAction action) +void ReferenceCloud::setPointScalarValues(ScalarType value) { assert(m_theAssociatedCloud); unsigned count = size(); for (unsigned i = 0; i < count; ++i) { - unsigned index = m_theIndexes[i]; - ScalarType d = m_theAssociatedCloud->getPointScalarValue(index); - action(*m_theAssociatedCloud->getPointPersistentPtr(index), d); - m_theAssociatedCloud->setPointScalarValue(index, d); + m_theAssociatedCloud->setPointScalarValue(m_theIndexes[i], value); } } diff --git a/src/RegistrationTools.cpp b/src/RegistrationTools.cpp index 684cfbc..6ee6f90 100644 --- a/src/RegistrationTools.cpp +++ b/src/RegistrationTools.cpp @@ -361,7 +361,7 @@ ICPRegistrationTools::RESULT_TYPE ICPRegistrationTools::Register( GenericIndexed } //we compute the initial distance between the two clouds (and the CPSet by the way) - //data.cloud->forEach(ScalarFieldTools::SetScalarValueToNaN); //DGM: done automatically in computeCloud2CloudDistances now + //data.cloud->setPointScalarValues(CCCoreLib::NAN_VALUE); //DGM: done automatically in computeCloud2CloudDistances now if (inputModelMesh) { assert(data.CPSetPlain); diff --git a/src/ScalarFieldTools.cpp b/src/ScalarFieldTools.cpp index a562eee..09bb9b8 100644 --- a/src/ScalarFieldTools.cpp +++ b/src/ScalarFieldTools.cpp @@ -16,21 +16,6 @@ using namespace CCCoreLib; static const int AVERAGE_NUMBER_OF_POINTS_FOR_GRADIENT_COMPUTATION = 14; -void ScalarFieldTools::SetScalarValueToNaN(const CCVector3& P, ScalarType& scalarValue) -{ - scalarValue = NAN_VALUE; -} - -void ScalarFieldTools::SetScalarValueToZero(const CCVector3& P, ScalarType& scalarValue) -{ - scalarValue = 0; -} - -void ScalarFieldTools::SetScalarValueInverted(const CCVector3& P, ScalarType& scalarValue) -{ - scalarValue = -scalarValue; -} - int ScalarFieldTools::computeScalarFieldGradient( GenericIndexedCloudPersist* theCloud, PointCoordinateType radius, bool euclideanDistances, diff --git a/src/SimpleMesh.cpp b/src/SimpleMesh.cpp index b873f39..a6b935e 100644 --- a/src/SimpleMesh.cpp +++ b/src/SimpleMesh.cpp @@ -28,19 +28,6 @@ SimpleMesh::~SimpleMesh() } } -void SimpleMesh::forEach(genericTriangleAction action) -{ - SimpleTriangle tri; - - for (VerticesIndexes& ti : triIndexes) - { - theVertices->getPoint(ti.i1, tri.A); - theVertices->getPoint(ti.i2, tri.B); - theVertices->getPoint(ti.i3, tri.C); - action(tri); - } -} - void SimpleMesh::placeIteratorAtBeginning() { globalIterator = 0;