5#include <pxr/base/gf/vec2f.h>
6#include <pxr/base/tf/staticTokens.h>
7#include <pxr/imaging/hd/tokens.h>
25static const pxr::TfToken
st(
"st", pxr::TfToken::Immortal);
42 write_submeshes(mesh);
72 pxr::HdDirtyBits
bits = pxr::HdChangeTracker::Clean;
75 bits |= pxr::HdChangeTracker::DirtyMaterialId | pxr::HdChangeTracker::DirtyDoubleSided;
79 bits |= pxr::HdChangeTracker::DirtyTransform;
82 if (
bits == pxr::HdChangeTracker::Clean) {
86 for (
int i = 0; i < submeshes_.size(); ++i) {
87 scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(submesh_prim_id(i),
bits);
94 return pxr::VtValue();
99 if (key == pxr::HdTokens->
normals) {
100 return pxr::VtValue(submesh(
id).
normals);
103 return pxr::VtValue(submesh(
id).uvs);
105 if (key == pxr::HdTokens->points) {
106 return pxr::VtValue(submesh(
id).vertices);
114 const SubMesh &sm = submesh(
id);
116 return pxr::SdfPath();
123 for (
auto &sm : submeshes_) {
124 if (sm.mat_data && !sm.mat_data->prim_id.IsEmpty()) {
125 paths.
add(sm.mat_data->prim_id);
132 const SubMesh &sm = submesh(
id);
133 return pxr::HdMeshTopology(pxr::PxOsdOpenSubdivTokens->none,
134 pxr::HdTokens->rightHanded,
140 pxr::HdInterpolation interpolation)
const
142 pxr::HdPrimvarDescriptorVector primvars;
143 if (interpolation == pxr::HdInterpolationVertex) {
144 primvars.emplace_back(pxr::HdTokens->points, interpolation, pxr::HdPrimvarRoleTokens->
point);
146 else if (interpolation == pxr::HdInterpolationFaceVarying) {
147 if (!submeshes_[0].
normals.empty()) {
148 primvars.emplace_back(
149 pxr::HdTokens->
normals, interpolation, pxr::HdPrimvarRoleTokens->normal);
151 if (!submeshes_[0].uvs.empty()) {
152 primvars.emplace_back(
153 usdtokens::st, interpolation, pxr::HdPrimvarRoleTokens->textureCoordinate);
161 const SubMesh &sm = submesh(
id);
165 return pxr::HdCullStyle::HdCullStyleNothing;
170 const SubMesh &sm = submesh(
id);
179 for (
int i = 0; i < submeshes_.size(); ++i) {
180 if (submeshes_[i].mat_data == mat_data) {
183 pxr::HdChangeTracker::DirtyDoubleSided | pxr::HdChangeTracker::DirtyCullStyle);
191 pxr::SdfPathVector
ret;
192 for (
int i = 0; i < submeshes_.size(); ++i) {
193 ret.push_back(submesh_prim_id(i));
201 for (
int i = 0; i < submeshes_.size(); ++i) {
209pxr::SdfPath MeshData::submesh_prim_id(
int index)
const
213 return prim_id.AppendElementString(name);
216const MeshData::SubMesh &MeshData::submesh(pxr::SdfPath
const &
id)
const
219 sscanf(
id.GetName().c_str(),
"SM_%d", &index);
220 return submeshes_[index];
231 static_assert(std::is_trivial_v<T>);
237 switch (mesh.normals_domain()) {
251 const bool copy_all_verts,
255 if (copy_all_verts) {
270 dst_data[dst] = src_data[tri_faces[src]];
281 const int3 &tri = corner_tris[src];
282 dst_data[dst * 3 + 0] = src_data[tri[0]];
283 dst_data[dst * 3 + 1] = src_data[tri[1]];
284 dst_data[dst * 3 + 2] = src_data[tri[2]];
302 const bool copy_all_verts = triangles.
size() == corner_tris.
size() &&
303 mesh.verts_no_face().count == 0;
307 if (copy_all_verts) {
312 dst_verts_num = vert_positions.
size();
319 const int3 &tri = corner_tris[src];
324 dst_verts_num =
verts.size();
342 std::fill_n(&dst_normals[dst * 3], 3, src_normals[tri_faces[src]]);
347 const int3 &tri = corner_tris[src];
348 dst_normals[dst * 3 + 0] = src_normals[corner_verts[tri[0]]];
349 dst_normals[dst * 3 + 1] = src_normals[corner_verts[tri[1]]];
350 dst_normals[dst * 3 + 2] = src_normals[corner_verts[tri[2]]];
365void MeshData::write_submeshes(
const Mesh *mesh)
368 submeshes_.reinitialize(mat_count > 0 ? mat_count : 1);
369 for (
const int i : submeshes_.index_range()) {
370 submeshes_[i].mat_index = i;
373 const Span<float3> vert_positions = mesh->vert_positions();
374 const Span<int> corner_verts = mesh->corner_verts();
375 const Span<int3> corner_tris = mesh->corner_tris();
376 const Span<int> tri_faces = mesh->corner_tri_faces();
381 const VArraySpan material_indices = *attributes.
lookup<
int>(
"material_index",
384 if (material_indices.is_empty()) {
399 const int max_index = std::max(mat_count - 1, 0);
403 [&](
const int i) { return std::clamp(material_indices[tri_faces[i]], 0, max_index); },
404 triangles_by_material);
407 for (const int i : range) {
415 triangles_by_material[i],
421 submeshes_.remove_if([](
const SubMesh &submesh) {
return submesh.face_vertex_counts.empty(); });
424void MeshData::update_prims()
426 auto &render_index = scene_delegate_->GetRenderIndex();
428 for (i = 0; i < submeshes_.size(); ++i) {
429 pxr::SdfPath p = submesh_prim_id(i);
430 if (i < submeshes_count_) {
431 render_index.GetChangeTracker().MarkRprimDirty(p, pxr::HdChangeTracker::AllDirty);
435 render_index.InsertRprim(pxr::HdPrimTypeTokens->mesh, scene_delegate_, p);
439 for (; i < submeshes_count_; ++i) {
440 render_index.RemoveRprim(submesh_prim_id(i));
441 ID_LOG(1,
"Remove %d", i);
443 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 struct Object *ob)
struct Material * BKE_object_material_get_eval(struct 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,...)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a point
T * resize(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]
#define ID_LOG(level, msg,...)
#define ID_LOGN(level, msg,...)
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