diff --git a/source/blender/io/usd/hydra/mesh.cc b/source/blender/io/usd/hydra/mesh.cc index 1351c6aa1bbe..a0d210535f55 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,33 @@ 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_) { + 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; + } } } } 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;