forked from blender/blender
Optimized SubMesh to hold only used vertices #84
@ -82,9 +82,6 @@ void MeshData::update()
|
|||||||
|
|
||||||
pxr::VtValue MeshData::get_data(pxr::TfToken const &key) const
|
pxr::VtValue MeshData::get_data(pxr::TfToken const &key) const
|
||||||
{
|
{
|
||||||
if (key == pxr::HdTokens->points) {
|
|
||||||
return pxr::VtValue(vertices_);
|
|
||||||
}
|
|
||||||
return pxr::VtValue();
|
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) {
|
if (key == pxr::HdTokens->normals) {
|
||||||
return pxr::VtValue(submesh(id).normals);
|
return pxr::VtValue(submesh(id).normals);
|
||||||
}
|
}
|
||||||
else if (key == pxr::tokens_->st) {
|
if (key == pxr::tokens_->st) {
|
||||||
return pxr::VtValue(submesh(id).uvs);
|
return pxr::VtValue(submesh(id).uvs);
|
||||||
}
|
}
|
||||||
|
if (key == pxr::HdTokens->points) {
|
||||||
|
return pxr::VtValue(submesh(id).vertices);
|
||||||
|
}
|
||||||
|
|
||||||
return get_data(key);
|
return get_data(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,10 +132,8 @@ pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors(
|
|||||||
{
|
{
|
||||||
pxr::HdPrimvarDescriptorVector primvars;
|
pxr::HdPrimvarDescriptorVector primvars;
|
||||||
if (interpolation == pxr::HdInterpolationVertex) {
|
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) {
|
else if (interpolation == pxr::HdInterpolationFaceVarying) {
|
||||||
if (!submeshes_[0].normals.empty()) {
|
if (!submeshes_[0].normals.empty()) {
|
||||||
primvars.emplace_back(
|
primvars.emplace_back(
|
||||||
@ -214,7 +213,6 @@ const MeshData::SubMesh &MeshData::submesh(pxr::SdfPath const &id) const
|
|||||||
void MeshData::write_submeshes(Mesh *mesh)
|
void MeshData::write_submeshes(Mesh *mesh)
|
||||||
{
|
{
|
||||||
submeshes_.clear();
|
submeshes_.clear();
|
||||||
vertices_.clear();
|
|
||||||
|
|
||||||
/* Insert base submeshes */
|
/* Insert base submeshes */
|
||||||
int mat_count = BKE_object_material_count_eval((Object *)id);
|
int mat_count = BKE_object_material_count_eval((Object *)id);
|
||||||
@ -267,12 +265,33 @@ void MeshData::write_submeshes(Mesh *mesh)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!submeshes_.empty()) {
|
if (submeshes_.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* vertices */
|
/* vertices */
|
||||||
vertices_.reserve(mesh->totvert);
|
|
||||||
blender::Span<blender::float3> verts = mesh->vert_positions();
|
blender::Span<blender::float3> verts = mesh->vert_positions();
|
||||||
|
pxr::VtVec3fArray vertices(mesh->totvert);
|
||||||
|
int i = 0;
|
||||||
for (blender::float3 v : verts) {
|
for (blender::float3 v : verts) {
|
||||||
vertices_.push_back(pxr::GfVec3f(v.x, v.y, v.z));
|
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<int> 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ namespace blender::io::hydra {
|
|||||||
|
|
||||||
class MeshData : public ObjectData {
|
class MeshData : public ObjectData {
|
||||||
struct SubMesh {
|
struct SubMesh {
|
||||||
|
pxr::VtVec3fArray vertices;
|
||||||
pxr::VtIntArray face_vertex_counts;
|
pxr::VtIntArray face_vertex_counts;
|
||||||
pxr::VtIntArray face_vertex_indices;
|
pxr::VtIntArray face_vertex_indices;
|
||||||
pxr::VtVec3fArray normals;
|
pxr::VtVec3fArray normals;
|
||||||
@ -26,7 +27,6 @@ class MeshData : public ObjectData {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
pxr::VtVec3fArray vertices_;
|
|
||||||
std::vector<SubMesh> submeshes_;
|
std::vector<SubMesh> submeshes_;
|
||||||
int submeshes_count_ = 0;
|
int submeshes_count_ = 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user
I would guess something like this is more efficient, instead of multiple loops and hash maps.
You are right, your algorithm is more efficient and faster, thank you.