Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2018-12-07 02:02:56 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2018-12-07 02:19:53 +0300
commit27e77d4f9c16b8b6c67d9275b9bc373357f713b0 (patch)
tree4cce0ba4d81cc49d4daabaf405ddffff195bb276 /source/blender/alembic
parentcccc40db51a0b73d396952be65ef351a7c68ed4f (diff)
Fix Alembic indexed UVs being merged for different vertices.
Other software uses this to define UV islands, so we can't just merge any UVs with the same coordinate. They have to share a vertex too. Contributed by Maxime Robinot, with changes by me. Differential Revision: https://developer.blender.org/D4006
Diffstat (limited to 'source/blender/alembic')
-rw-r--r--source/blender/alembic/intern/abc_customdata.cc69
1 files changed, 30 insertions, 39 deletions
diff --git a/source/blender/alembic/intern/abc_customdata.cc b/source/blender/alembic/intern/abc_customdata.cc
index 424475dc61b..96685b6ac3a 100644
--- a/source/blender/alembic/intern/abc_customdata.cc
+++ b/source/blender/alembic/intern/abc_customdata.cc
@@ -52,29 +52,6 @@ using Alembic::Abc::V2fArraySample;
using Alembic::AbcGeom::OV2fGeomParam;
using Alembic::AbcGeom::OC4fGeomParam;
-
-typedef std::unordered_map<uint64_t, int> uv_index_map;
-
-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,
@@ -88,45 +65,59 @@ static void get_uvs(const CDStreamConfig &config,
const int num_poly = config.totpoly;
MPoly *polygons = config.mpoly;
+ MLoop *mloop = config.mloop;
if (!config.pack_uvs) {
int cnt = 0;
uvidx.resize(config.totloop);
uvs.resize(config.totloop);
+ /* Iterate in reverse order to match exported polygons. */
for (int i = 0; i < num_poly; ++i) {
MPoly &current_poly = polygons[i];
- MLoopUV *loopuvpoly = mloopuv_array + current_poly.loopstart + current_poly.totloop;
+ MLoopUV *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop;
for (int j = 0; j < current_poly.totloop; ++j, ++cnt) {
- --loopuvpoly;
+ --loopuv;
uvidx[cnt] = cnt;
- uvs[cnt][0] = loopuvpoly->uv[0];
- uvs[cnt][1] = loopuvpoly->uv[1];
+ uvs[cnt][0] = loopuv->uv[0];
+ uvs[cnt][1] = loopuv->uv[1];
}
}
}
else {
- uv_index_map idx_map;
+ /* Mapping for indexed UVs, deduplicating UV coordinates at vertices. */
+ std::vector<std::vector<uint32_t>> idx_map(config.totvert);
int idx_count = 0;
for (int i = 0; i < num_poly; ++i) {
MPoly &current_poly = polygons[i];
- MLoopUV *loopuvpoly = mloopuv_array + current_poly.loopstart + current_poly.totloop;
+ MLoop *looppoly = mloop + current_poly.loopstart + current_poly.totloop;
+ MLoopUV *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop;
for (int j = 0; j < current_poly.totloop; ++j) {
- loopuvpoly--;
- Imath::V2f uv(loopuvpoly->uv[0], loopuvpoly->uv[1]);
- uint64_t k = uv_to_hash_key(uv);
- uv_index_map::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++);
+ --looppoly;
+ --loopuv;
+
+ Imath::V2f uv(loopuv->uv[0], loopuv->uv[1]);
+ bool found_same = false;
+
+ /* Find UV already in uvs array. */
+ for (uint32_t uv_idx : idx_map[looppoly->v]) {
+ if (uvs[uv_idx] == uv) {
+ found_same = true;
+ uvidx.push_back(uv_idx);
+ break;
+ }
}
- else {
- uvidx.push_back(it->second);
+
+ /* UV doesn't exists for this vertex, add it. */
+ if (!found_same) {
+ uint32_t uv_idx = idx_count++;
+ idx_map[looppoly->v].push_back(uv_idx);
+ uvidx.push_back(uv_idx);
+ uvs.push_back(uv);
}
}
}