From b55675a6dc25b8aaf5e0656de891adca74ce4ed4 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Wed, 2 Aug 2023 03:05:23 +0300 Subject: [PATCH 1/2] Optimized SubMesh to hold only used vertices --- source/blender/io/usd/hydra/mesh.cc | 53 +++++++++++++++++++++-------- source/blender/io/usd/hydra/mesh.h | 2 +- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/source/blender/io/usd/hydra/mesh.cc b/source/blender/io/usd/hydra/mesh.cc index 1351c6aa1bbe..6d282d8f0712 100644 --- a/source/blender/io/usd/hydra/mesh.cc +++ b/source/blender/io/usd/hydra/mesh.cc @@ -82,9 +82,6 @@ void MeshData::update() pxr::VtValue MeshData::get_data(pxr::TfToken const &key) const { - if (key == pxr::HdTokens->points) { - return pxr::VtValue(vertices_); - } return pxr::VtValue(); } @@ -93,9 +90,13 @@ pxr::VtValue MeshData::get_data(pxr::SdfPath const &id, pxr::TfToken const &key) if (key == pxr::HdTokens->normals) { return pxr::VtValue(submesh(id).normals); } - else if (key == pxr::tokens_->st) { + if (key == pxr::tokens_->st) { return pxr::VtValue(submesh(id).uvs); } + if (key == pxr::HdTokens->points) { + return pxr::VtValue(submesh(id).vertices); + } + return get_data(key); } @@ -131,9 +132,7 @@ pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors( { pxr::HdPrimvarDescriptorVector primvars; if (interpolation == pxr::HdInterpolationVertex) { - if (!vertices_.empty()) { - primvars.emplace_back(pxr::HdTokens->points, interpolation, pxr::HdPrimvarRoleTokens->point); - } + primvars.emplace_back(pxr::HdTokens->points, interpolation, pxr::HdPrimvarRoleTokens->point); } else if (interpolation == pxr::HdInterpolationFaceVarying) { if (!submeshes_[0].normals.empty()) { @@ -214,7 +213,6 @@ const MeshData::SubMesh &MeshData::submesh(pxr::SdfPath const &id) const void MeshData::write_submeshes(Mesh *mesh) { submeshes_.clear(); - vertices_.clear(); /* Insert base submeshes */ int mat_count = BKE_object_material_count_eval((Object *)id); @@ -267,12 +265,39 @@ void MeshData::write_submeshes(Mesh *mesh) } } - if (!submeshes_.empty()) { - /* vertices */ - vertices_.reserve(mesh->totvert); - blender::Span verts = mesh->vert_positions(); - for (blender::float3 v : verts) { - vertices_.push_back(pxr::GfVec3f(v.x, v.y, v.z)); + if (submeshes_.empty()) { + return; + } + + /* vertices */ + blender::Span verts = mesh->vert_positions(); + pxr::VtVec3fArray vertices(mesh->totvert); + int i = 0; + for (blender::float3 v : verts) { + vertices[i++] = pxr::GfVec3f(v.x, v.y, v.z); + } + + if (submeshes_.size() == 1) { + submeshes_[0].vertices = std::move(vertices); + } + else { + /* Optimizing submeshes: getting only used vertices, rearranged indices */ + for (SubMesh &sm : submeshes_) { + Map index_map; + for (int i : sm.face_vertex_indices) { + index_map.add(i, 0); + } + i = 0; + for (int &v : index_map.values()) { + v = i++; + } + sm.vertices.resize(index_map.size()); + for (auto it : index_map.items()) { + sm.vertices[it.value] = vertices[it.key]; + } + for (int &v : sm.face_vertex_indices) { + v = index_map.lookup(v); + } } } } diff --git a/source/blender/io/usd/hydra/mesh.h b/source/blender/io/usd/hydra/mesh.h index d6985d9b1ce4..48398af0dd6e 100644 --- a/source/blender/io/usd/hydra/mesh.h +++ b/source/blender/io/usd/hydra/mesh.h @@ -17,6 +17,7 @@ namespace blender::io::hydra { class MeshData : public ObjectData { struct SubMesh { + pxr::VtVec3fArray vertices; pxr::VtIntArray face_vertex_counts; pxr::VtIntArray face_vertex_indices; pxr::VtVec3fArray normals; @@ -26,7 +27,6 @@ class MeshData : public ObjectData { }; private: - pxr::VtVec3fArray vertices_; std::vector submeshes_; int submeshes_count_ = 0; -- 2.30.2 From a4222724715b5ac42293da652ed1dc692c77f180 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Wed, 2 Aug 2023 15:16:47 +0300 Subject: [PATCH 2/2] Improved SubMesh optimization algorithm --- source/blender/io/usd/hydra/mesh.cc | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/source/blender/io/usd/hydra/mesh.cc b/source/blender/io/usd/hydra/mesh.cc index 6d282d8f0712..a0d210535f55 100644 --- a/source/blender/io/usd/hydra/mesh.cc +++ b/source/blender/io/usd/hydra/mesh.cc @@ -283,20 +283,14 @@ void MeshData::write_submeshes(Mesh *mesh) else { /* Optimizing submeshes: getting only used vertices, rearranged indices */ for (SubMesh &sm : submeshes_) { - Map index_map; - for (int i : sm.face_vertex_indices) { - index_map.add(i, 0); - } - i = 0; - for (int &v : index_map.values()) { - v = i++; - } - sm.vertices.resize(index_map.size()); - for (auto it : index_map.items()) { - sm.vertices[it.value] = vertices[it.key]; - } - for (int &v : sm.face_vertex_indices) { - v = index_map.lookup(v); + Vector index_map(vertices.size(), 0); + for (int &face_vertex_index : sm.face_vertex_indices) { + const int v = face_vertex_index; + if (index_map[v] == 0) { + sm.vertices.push_back(vertices[v]); + index_map[v] = sm.vertices.size(); + } + face_vertex_index = index_map[v] - 1; } } } -- 2.30.2