Przeglądaj źródła

Ensure the usage pattern of SpatialSort.

Malcolm Tyrrell 3 lat temu
rodzic
commit
5b13b97f27
2 zmienionych plików z 15 dodań i 3 usunięć
  1. 12 3
      code/Common/SpatialSort.cpp
  2. 3 0
      include/assimp/SpatialSort.h

+ 12 - 3
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<const char *>(pPositions);
         const aiVector3D *vec = reinterpret_cast<const aiVector3D *>(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<unsigned int> &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<unsigned int> &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<unsigned int> &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;
 

+ 3 - 0
include/assimp/SpatialSort.h

@@ -168,6 +168,9 @@ protected:
 
     // all positions, sorted by distance to the sorting plane
     std::vector<Entry> mPositions;
+
+    // False until the Finalize method is called.
+    bool mFinalized;
 };
 
 } // end of namespace Assimp