diff options
-rw-r--r-- | source/blender/alembic/intern/abc_customdata.cc | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/source/blender/alembic/intern/abc_customdata.cc b/source/blender/alembic/intern/abc_customdata.cc index b98d82f0c7d..8ab9f1118f4 100644 --- a/source/blender/alembic/intern/abc_customdata.cc +++ b/source/blender/alembic/intern/abc_customdata.cc @@ -26,6 +26,7 @@ #include <Alembic/AbcGeom/All.h> #include <algorithm> +#include <unordered_map> extern "C" { #include "DNA_customdata_types.h" @@ -51,6 +52,27 @@ using Alembic::Abc::V2fArraySample; using Alembic::AbcGeom::OV2fGeomParam; using Alembic::AbcGeom::OC4fGeomParam; + +static inline uint64_t uv_to_hash_key(Imath::V2f v) +{ + /* Convert -0.0f to 0.0f, so bitwise comparison works. */ + if (v.x == 0.0f) { + v.x = 0.0f; + } + if (v.y == 0.0f) { + v.y = 0.0f; + } + + /* Pack floats in 64bit. */ + union { + float xy[2]; + uint64_t key; + } tmp; + tmp.xy[0] = v.x; + tmp.xy[1] = v.y; + return tmp.key; +} + static void get_uvs(const CDStreamConfig &config, std::vector<Imath::V2f> &uvs, std::vector<uint32_t> &uvidx, @@ -84,6 +106,9 @@ static void get_uvs(const CDStreamConfig &config, } } else { + std::unordered_map<uint64_t, int> idx_map; + int idx_count = 0; + for (int i = 0; i < num_poly; ++i) { MPoly ¤t_poly = polygons[i]; MLoopUV *loopuvpoly = mloopuv_array + current_poly.loopstart + current_poly.totloop; @@ -91,15 +116,15 @@ static void get_uvs(const CDStreamConfig &config, for (int j = 0; j < current_poly.totloop; ++j) { loopuvpoly--; Imath::V2f uv(loopuvpoly->uv[0], loopuvpoly->uv[1]); - - std::vector<Imath::V2f>::iterator it = std::find(uvs.begin(), uvs.end(), uv); - - if (it == uvs.end()) { - uvidx.push_back(uvs.size()); + uint64_t k = uv_to_hash_key(uv); + std::unordered_map<uint64_t, int>::iterator it = idx_map.find(k); + if (it == idx_map.end()) { + idx_map[k] = idx_count; uvs.push_back(uv); + uvidx.push_back(idx_count++); } else { - uvidx.push_back(std::distance(uvs.begin(), it)); + uvidx.push_back(it->second); } } } |