From 5b13b97f27ef6362b0d63a16c536fb26b224efef Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Tue, 19 Oct 2021 14:22:28 +0100 Subject: [PATCH] Ensure the usage pattern of SpatialSort. --- code/Common/SpatialSort.cpp | 15 ++++++++++++--- include/assimp/SpatialSort.h | 3 +++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/code/Common/SpatialSort.cpp b/code/Common/SpatialSort.cpp index 2bd848164..3ef9f055b 100644 --- a/code/Common/SpatialSort.cpp +++ b/code/Common/SpatialSort.cpp @@ -58,14 +58,16 @@ const aiVector3D PlaneInit(0.8523f, 0.34321f, 0.5736f); // define the reference plane. We choose some arbitrary vector away from all basic axes // in the hope that no model spreads all its vertices along this plane. SpatialSort::SpatialSort(const aiVector3D *pPositions, unsigned int pNumPositions, unsigned int pElementOffset) : - mPlaneNormal(PlaneInit) { + mPlaneNormal(PlaneInit), + mFinalized(false) { mPlaneNormal.Normalize(); Fill(pPositions, pNumPositions, pElementOffset); } // ------------------------------------------------------------------------------------------------ SpatialSort::SpatialSort() : - mPlaneNormal(PlaneInit) { + mPlaneNormal(PlaneInit), + mFinalized(false) { mPlaneNormal.Normalize(); } @@ -80,21 +82,25 @@ void SpatialSort::Fill(const aiVector3D *pPositions, unsigned int pNumPositions, unsigned int pElementOffset, bool pFinalize /*= true */) { mPositions.clear(); + mFinalized = false; Append(pPositions, pNumPositions, pElementOffset, pFinalize); + mFinalized = pFinalize; } // ------------------------------------------------------------------------------------------------ void SpatialSort::Finalize() { std::sort(mPositions.begin(), mPositions.end()); + mFinalized = true; } // ------------------------------------------------------------------------------------------------ void SpatialSort::Append(const aiVector3D *pPositions, unsigned int pNumPositions, unsigned int pElementOffset, bool pFinalize /*= true */) { + ai_assert(!mFinalized && "You cannot add positions to the SpatialSort object after it has been finalized."); // store references to all given positions along with their distance to the reference plane const size_t initial = mPositions.size(); - mPositions.reserve(initial + (pFinalize ? pNumPositions : pNumPositions * 2)); + mPositions.reserve(initial + pNumPositions); for (unsigned int a = 0; a < pNumPositions; a++) { const char *tempPointer = reinterpret_cast(pPositions); const aiVector3D *vec = reinterpret_cast(tempPointer + a * pElementOffset); @@ -114,6 +120,7 @@ void SpatialSort::Append(const aiVector3D *pPositions, unsigned int pNumPosition // Returns an iterator for all positions close to the given position. void SpatialSort::FindPositions(const aiVector3D &pPosition, ai_real pRadius, std::vector &poResults) const { + ai_assert(mFinalized && "The SpatialSort object must be finalized before FindPositions can be called."); const ai_real dist = pPosition * mPlaneNormal; const ai_real minDist = dist - pRadius, maxDist = dist + pRadius; @@ -229,6 +236,7 @@ BinFloat ToBinary(const ai_real &pValue) { // Fills an array with indices of all positions identical to the given position. In opposite to // FindPositions(), not an epsilon is used but a (very low) tolerance of four floating-point units. void SpatialSort::FindIdenticalPositions(const aiVector3D &pPosition, std::vector &poResults) const { + ai_assert(mFinalized && "The SpatialSort object must be finalized before FindIdenticalPositions can be called."); // Epsilons have a huge disadvantage: they are of constant precision, while floating-point // values are of log2 precision. If you apply e=0.01 to 100, the epsilon is rather small, but // if you apply it to 0.001, it is enormous. @@ -297,6 +305,7 @@ void SpatialSort::FindIdenticalPositions(const aiVector3D &pPosition, std::vecto // ------------------------------------------------------------------------------------------------ unsigned int SpatialSort::GenerateMappingTable(std::vector &fill, ai_real pRadius) const { + ai_assert(mFinalized && "The SpatialSort object must be finalized before GenerateMappingTable can be called."); fill.resize(mPositions.size(), UINT_MAX); ai_real dist, maxDist; diff --git a/include/assimp/SpatialSort.h b/include/assimp/SpatialSort.h index 39ebae77b..5db23c86b 100644 --- a/include/assimp/SpatialSort.h +++ b/include/assimp/SpatialSort.h @@ -168,6 +168,9 @@ protected: // all positions, sorted by distance to the sorting plane std::vector mPositions; + + // False until the Finalize method is called. + bool mFinalized; }; } // end of namespace Assimp