WIP: Hydra: Per-vertex color attributes #114585

Draft
Vasyl Pidhirskyi wants to merge 5 commits from Vasyl-Pidhirskyi/blender:per-vertex-color into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
2 changed files with 31 additions and 3 deletions

View File

@ -6,12 +6,13 @@
#include <pxr/base/tf/staticTokens.h>
#include <pxr/imaging/hd/tokens.h>
#include "BLI_string.h"
#include "BKE_attribute.h"
#include "BKE_attribute.hh"
#include "BKE_material.h"
#include "BKE_mesh.hh"
#include "BKE_mesh_runtime.hh"
#include "BLI_color.hh"
#include "BLI_string.h"
#include "hydra_scene_delegate.h"
#include "mesh.h"
@ -102,6 +103,12 @@ pxr::VtValue MeshData::get_data(pxr::SdfPath const &id, pxr::TfToken const &key)
if (key == pxr::HdTokens->points) {
return pxr::VtValue(submesh(id).vertices);
}
if (key == pxr::HdTokens->displayColor) {
return pxr::VtValue(submesh(id).vertex_color);
}
if (key == pxr::HdTokens->displayOpacity) {
return pxr::VtValue(submesh(id).vertex_opacity);
}
return get_data(key);
}
@ -139,6 +146,12 @@ pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors(
pxr::HdPrimvarDescriptorVector primvars;
if (interpolation == pxr::HdInterpolationVertex) {
primvars.emplace_back(pxr::HdTokens->points, interpolation, pxr::HdPrimvarRoleTokens->point);
if (!submeshes_[0].vertex_color.empty()) {
primvars.emplace_back(
pxr::HdTokens->displayColor, interpolation, pxr::HdPrimvarRoleTokens->color);
primvars.emplace_back(
pxr::HdTokens->displayOpacity, interpolation, pxr::HdPrimvarRoleTokens->color);
}
}
else if (interpolation == pxr::HdInterpolationFaceVarying) {
if (!submeshes_[0].normals.empty()) {
@ -273,11 +286,24 @@ void MeshData::write_submeshes(const Mesh *mesh)
const Span<float3> positions = mesh->vert_positions();
MutableSpan(vertices.data(), vertices.size()).copy_from(positions.cast<pxr::GfVec3f>());
VArraySpan<ColorGeometry4f> vertex_color;
if (mat_count == 0) {
vertex_color = *mesh->attributes().lookup<ColorGeometry4f>(mesh->default_color_attribute,
ATTR_DOMAIN_POINT);
}
if (submeshes_.size() == 1) {
submeshes_[0].vertices = std::move(vertices);
if (!vertex_color.is_empty()) {
for (auto &color : vertex_color) {
submeshes_[0].vertex_color.push_back(pxr::GfVec3f(color.r, color.g, color.b));
submeshes_[0].vertex_opacity.push_back(color.a);
}
}
}
else {
/* Optimizing submeshes: getting only used vertices, rearranged indices */
/* Optimizing submeshes: getting only used vertices, rearranged indices.
* NOTE: vertex_color and vertex_opacity are empty, because mat_count > 0 */
for (SubMesh &sm : submeshes_) {
Vector<int> index_map(vertices.size(), 0);
for (int &face_vertex_index : sm.face_vertex_indices) {

View File

@ -19,6 +19,8 @@ namespace blender::io::hydra {
class MeshData : public ObjectData {
struct SubMesh {
pxr::VtVec3fArray vertices;
pxr::VtVec3fArray vertex_color;
pxr::VtFloatArray vertex_opacity;
pxr::VtIntArray face_vertex_counts;
pxr::VtIntArray face_vertex_indices;
pxr::VtVec3fArray normals;