Implement custom integer->string conversion for hashing

Converts to hexadecimal, reversed order which is faster.
This commit is contained in:
tamasmeszaros 2021-06-15 10:43:57 +02:00
parent 72df789077
commit a5529aff1e

View File

@ -145,12 +145,45 @@ void SLAPrint::Steps::hollow_model(SLAPrintObject &po)
struct FaceHash {
// A 64 bit number's max hex digits
static constexpr size_t MAX_NUM_CHARS = 16;
// A hash is created for each triangle to be identifiable. The hash uses
// only the triangle's geometric traits, not the index in a particular mesh.
std::unordered_set<std::string> facehash;
static std::string facekey(const Vec3i &face,
const std::vector<Vec3f> &vertices)
// Returns the string in reverse, but that is ok for hashing
static std::array<char, MAX_NUM_CHARS + 1> to_chars(int64_t val)
{
std::array<char, MAX_NUM_CHARS + 1> ret;
static const constexpr char * Conv = "0123456789abcdef";
auto ptr = ret.begin();
auto uval = static_cast<uint64_t>(std::abs(val));
while (uval) {
*ptr = Conv[uval & 0xf];
++ptr;
uval = uval >> 4;
}
if (val < 0) { *ptr = '-'; ++ptr; }
*ptr = '\0'; // C style string ending
return ret;
}
static std::string hash(const Vec<3, int64_t> &v)
{
std::string ret;
ret.reserve(3 * MAX_NUM_CHARS);
for (auto val : v)
ret += to_chars(val).data();
return ret;
}
static std::string facekey(const Vec3i &face, const std::vector<Vec3f> &vertices)
{
// Scale to integer to avoid floating points
std::array<Vec<3, int64_t>, 3> pts = {
@ -166,15 +199,13 @@ struct FaceHash {
Vec<3, int64_t> c = a.cross(b) + (pts[0] + pts[1] + pts[2]) / 3;
// Return a concatenated string representation of the coordinates
return float_to_string_decimal_point(c(0)) + float_to_string_decimal_point(c(1)) + float_to_string_decimal_point(c(2));
return hash(c);
}
FaceHash(const indexed_triangle_set &its)
FaceHash (const indexed_triangle_set &its): facehash(its.indices.size())
{
for (const Vec3i &face : its.indices) {
std::string keystr = facekey(face, its.vertices);
facehash.insert(keystr);
}
for (const Vec3i &face : its.indices)
facehash.insert(facekey(face, its.vertices));
}
bool find(const std::string &key)