Ensure the usage pattern of SpatialSort.

pull/4130/head
Malcolm Tyrrell 2021-10-19 14:22:28 +01:00
parent a83db61289
commit 5b13b97f27
2 changed files with 15 additions and 3 deletions

View File

@ -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;

View File

@ -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