5#include <pxr/base/gf/vec2f.h>
6#include <pxr/base/tf/staticTokens.h>
7#include <pxr/imaging/hd/tokens.h>
24static const pxr::TfToken
st(
"st", pxr::TfToken::Immortal);
41 write_submeshes(mesh);
71 pxr::HdDirtyBits
bits = pxr::HdChangeTracker::Clean;
74 bits |= pxr::HdChangeTracker::DirtyMaterialId | pxr::HdChangeTracker::DirtyDoubleSided;
78 bits |= pxr::HdChangeTracker::DirtyTransform;
81 if (
bits == pxr::HdChangeTracker::Clean) {
85 for (
int i = 0;
i < submeshes_.size(); ++
i) {
93 return pxr::VtValue();
98 if (key == pxr::HdTokens->
normals) {
99 return pxr::VtValue(submesh(
id).
normals);
102 return pxr::VtValue(submesh(
id).uvs);
104 if (key == pxr::HdTokens->points) {
105 return pxr::VtValue(submesh(
id).vertices);
113 const SubMesh &sm = submesh(
id);
115 return pxr::SdfPath();
122 for (
const auto &sm : submeshes_) {
123 if (sm.mat_data && !sm.mat_data->prim_id.IsEmpty()) {
124 paths.
add(sm.mat_data->prim_id);
131 const SubMesh &sm = submesh(
id);
132 return pxr::HdMeshTopology(pxr::PxOsdOpenSubdivTokens->none,
133 pxr::HdTokens->rightHanded,
139 pxr::HdInterpolation interpolation)
const
141 pxr::HdPrimvarDescriptorVector primvars;
142 if (interpolation == pxr::HdInterpolationVertex) {
143 primvars.emplace_back(pxr::HdTokens->points, interpolation, pxr::HdPrimvarRoleTokens->point);
145 else if (interpolation == pxr::HdInterpolationFaceVarying) {
146 if (!submeshes_[0].
normals.empty()) {
147 primvars.emplace_back(
148 pxr::HdTokens->
normals, interpolation, pxr::HdPrimvarRoleTokens->normal);
150 if (!submeshes_[0].uvs.empty()) {
151 primvars.emplace_back(
152 usdtokens::st, interpolation, pxr::HdPrimvarRoleTokens->textureCoordinate);
160 const SubMesh &sm = submesh(
id);
164 return pxr::HdCullStyle::HdCullStyleNothing;
169 const SubMesh &sm = submesh(
id);
178 for (
int i = 0;
i < submeshes_.size(); ++
i) {
179 if (submeshes_[
i].mat_data == mat_data) {
182 pxr::HdChangeTracker::DirtyDoubleSided | pxr::HdChangeTracker::DirtyCullStyle);
190 pxr::SdfPathVector
ret;
191 for (
int i = 0;
i < submeshes_.size(); ++
i) {
192 ret.push_back(submesh_prim_id(
i));
200 for (
int i = 0;
i < submeshes_.size(); ++
i) {
208pxr::SdfPath MeshData::submesh_prim_id(
int index)
const
215const MeshData::SubMesh &MeshData::submesh(pxr::SdfPath
const &
id)
const
218 sscanf(
id.GetName().c_str(),
"SM_%d", &index);
219 return submeshes_[index];
230 static_assert(std::is_trivial_v<T>);
236 switch (mesh.normals_domain()) {
250 const bool copy_all_verts,
254 if (copy_all_verts) {
269 dst_data[dst] = src_data[tri_faces[src]];
280 const int3 &tri = corner_tris[src];
281 dst_data[dst * 3 + 0] = src_data[tri[0]];
282 dst_data[dst * 3 + 1] = src_data[tri[1]];
283 dst_data[dst * 3 + 2] = src_data[tri[2]];
301 const bool copy_all_verts = triangles.
size() == corner_tris.
size() &&
302 mesh.verts_no_face().count == 0;
306 if (copy_all_verts) {
311 dst_verts_num = vert_positions.
size();
318 const int3 &tri = corner_tris[src];
323 dst_verts_num =
verts.size();
341 std::fill_n(&dst_normals[dst * 3], 3, src_normals[tri_faces[src]]);
346 const int3 &tri = corner_tris[src];
347 dst_normals[dst * 3 + 0] = src_normals[corner_verts[tri[0]]];
348 dst_normals[dst * 3 + 1] = src_normals[corner_verts[tri[1]]];
349 dst_normals[dst * 3 + 2] = src_normals[corner_verts[tri[2]]];
364void MeshData::write_submeshes(
const Mesh *mesh)
367 submeshes_.reinitialize(mat_count > 0 ? mat_count : 1);
368 for (
const int i : submeshes_.index_range()) {
369 submeshes_[
i].mat_index =
i;
372 const Span<float3> vert_positions = mesh->vert_positions();
373 const Span<int> corner_verts = mesh->corner_verts();
374 const Span<int3> corner_tris = mesh->corner_tris();
375 const Span<int> tri_faces = mesh->corner_tri_faces();
380 const VArraySpan material_indices = *attributes.
lookup<
int>(
"material_index",
383 if (material_indices.is_empty()) {
398 const int max_index = std::max(mat_count - 1, 0);
402 [&](
const int i) { return std::clamp(material_indices[tri_faces[i]], 0, max_index); },
403 triangles_by_material);
406 for (const int i : range) {
414 triangles_by_material[i],
420 submeshes_.remove_if([](
const SubMesh &submesh) {
return submesh.face_vertex_counts.empty(); });
423void MeshData::update_prims()
425 auto &render_index = scene_delegate_->GetRenderIndex();
427 for (
i = 0;
i < submeshes_.size(); ++
i) {
428 pxr::SdfPath p = submesh_prim_id(
i);
429 if (
i < submeshes_count_) {
430 render_index.GetChangeTracker().MarkRprimDirty(p, pxr::HdChangeTracker::AllDirty);
434 render_index.InsertRprim(pxr::HdPrimTypeTokens->mesh, scene_delegate_, p);
438 for (;
i < submeshes_count_; ++
i) {
439 render_index.RemoveRprim(submesh_prim_id(
i));
442 submeshes_count_ = submeshes_.size();
CustomData interface, see also DNA_customdata_types.h.
const char * CustomData_get_active_layer_name(const CustomData *data, eCustomDataType type)
General operations, lookup, etc. for materials.
int BKE_object_material_count_eval(const Object *ob)
Material * BKE_object_material_get_eval(Object *ob, short act)
void BKE_object_to_mesh_clear(Object *object)
Mesh * BKE_object_to_mesh(Depsgraph *depsgraph, Object *object, bool preserve_all_data_layers)
#define BLI_assert_unreachable()
#define SNPRINTF(dst, format,...)
T * resize(const size_t newsize)
static void from_groups(const IndexMask &universe, IndexMaskMemory &memory, Fn &&get_group_index, MutableSpan< IndexMask > r_masks)
constexpr MutableSpan< NewT > cast() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
GAttributeReader lookup(const StringRef attribute_id) const
void foreach_index_optimized(Fn &&fn) const
void foreach_index(Fn &&fn) const
HydraSceneDelegate * scene_delegate_
pxr::HdCullStyle cull_style() const
pxr::HdMeshTopology topology(pxr::SdfPath const &id) const
void write_materials() override
pxr::VtValue get_data(pxr::TfToken const &key) const override
pxr::SdfPathVector submesh_paths() const
pxr::HdCullStyle cull_style(pxr::SdfPath const &id) const
void update_double_sided(MaterialData *mat_data)
void available_materials(Set< pxr::SdfPath > &paths) const override
pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const
bool double_sided(pxr::SdfPath const &id) const
MeshData(HydraSceneDelegate *scene_delegate, const Object *object, pxr::SdfPath const &prim_id)
virtual pxr::SdfPath material_id() const
MaterialData * get_or_create_material(const Material *mat)
virtual void write_transform()
ObjectData(HydraSceneDelegate *scene_delegate, const Object *object, pxr::SdfPath const &prim_id)
static float normals[][3]
void copy(const GVArray &src, GMutableSpan dst, int64_t grain_size=4096)
void gather(const GVArray &src, const IndexMask &indices, GMutableSpan dst, int64_t grain_size=4096)
void vert_tris_from_corner_tris(Span< int > corner_verts, Span< int3 > corner_tris, MutableSpan< int3 > vert_tris)
static const pxr::TfToken st("st", pxr::TfToken::Immortal)
static std::pair< bke::MeshNormalDomain, Span< float3 > > get_mesh_normals(const Mesh &mesh)
static void resize_uninitialized(pxr::VtArray< T > &array, const int new_size)
void gather_vert_data(const Span< int > verts, const bool copy_all_verts, const Span< T > src_data, MutableSpan< T > dst_data)
static void copy_submesh(const Mesh &mesh, const Span< float3 > vert_positions, const Span< int > corner_verts, const Span< int3 > corner_tris, const Span< int > tri_faces, const std::pair< bke::MeshNormalDomain, Span< float3 > > normals, const Span< float2 > uv_map, const IndexMask &triangles, MeshData::SubMesh &sm)
void gather_face_data(const Span< int > tri_faces, const IndexMask &triangles, const Span< T > src_data, MutableSpan< T > dst_data)
void gather_corner_data(const Span< int3 > corner_tris, const IndexMask &triangles, const Span< T > src_data, MutableSpan< T > dst_data)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
VecBase< float, 2 > float2
VecBase< int32_t, 3 > int3
VecBase< float, 3 > float3
pxr::VtVec3fArray normals
pxr::VtVec3fArray vertices
pxr::VtIntArray face_vertex_counts
pxr::VtIntArray face_vertex_indices