From 9510f62faa6a7378a5d391cae57dfa138f4ea64d Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Tue, 16 May 2023 21:20:27 +0300 Subject: [PATCH 01/10] Support multimaterials on one mesh. Initial --- .../render/hydra/scene_delegate/mesh.cc | 20 ++++++++++++++++--- .../render/hydra/scene_delegate/mesh.h | 9 ++++++++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index 0bae621a101b..1903f8020a74 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -38,7 +38,6 @@ void MeshData::init() BKE_object_to_mesh_clear(object); } - write_material(); write_transform(); } @@ -73,7 +72,7 @@ void MeshData::update() } else { if (id->recalc & ID_RECALC_SHADING) { - write_material(); + write_material(nullptr); bits |= pxr::HdChangeTracker::DirtyMaterialId | pxr::HdChangeTracker::DirtyDoubleSided; } if (id->recalc & ID_RECALC_TRANSFORM) { @@ -189,6 +188,7 @@ void MeshData::write_mesh(Mesh *mesh) vertices_.clear(); normals_.clear(); uvs_.clear(); + face_material_indices_.clear(); BKE_mesh_calc_normals_split(mesh); int tris_len = BKE_mesh_runtime_looptri_len(mesh); @@ -219,9 +219,10 @@ void MeshData::write_mesh(Mesh *mesh) write_normals(mesh); write_uv_maps(mesh); + write_material(mesh); } -void MeshData::write_material() +void MeshData::write_material(Mesh *mesh) { Object *object = (Object *)id; Material *mat = nullptr; @@ -233,6 +234,7 @@ void MeshData::write_material() mat_data_ = nullptr; return; } + pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat); mat_data_ = scene_delegate_->material_data(p_id); if (!mat_data_) { @@ -241,6 +243,18 @@ void MeshData::write_material() mat_data_->init(); mat_data_->insert(); } + + if (mesh) { + face_material_indices_.clear(); + const int *material_indices = BKE_mesh_material_indices(mesh); + const int *looptri_polys = BKE_mesh_runtime_looptri_polys_ensure(mesh); + int poly_ind; + blender::Span loopTris = mesh->looptris(); + for (size_t i = 0; i < loopTris.size(); ++i) { + poly_ind = looptri_polys[i]; + face_material_indices_.push_back(material_indices[poly_ind]); + } + } } void MeshData::write_uv_maps(Mesh *mesh) diff --git a/source/blender/render/hydra/scene_delegate/mesh.h b/source/blender/render/hydra/scene_delegate/mesh.h index e9a66dd7bdcb..4737d77471ec 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.h +++ b/source/blender/render/hydra/scene_delegate/mesh.h @@ -14,6 +14,12 @@ namespace blender::render::hydra { class MeshData : public ObjectData { + struct MaterialMesh { + pxr::VtIntArray face_vertex_counts; + pxr::VtIntArray face_vertex_indices; + MaterialData *mat_data = nullptr; + }; + public: MeshData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id); @@ -35,7 +41,7 @@ class MeshData : public ObjectData { private: void write_mesh(Mesh *mesh); - void write_material(); + void write_material(Mesh *mesh); void write_uv_maps(Mesh *mesh); void write_normals(Mesh *mesh); @@ -45,6 +51,7 @@ class MeshData : public ObjectData { pxr::VtVec2fArray uvs_; pxr::VtVec3fArray normals_; + pxr::VtIntArray face_material_indices_; MaterialData *mat_data_ = nullptr; }; -- 2.30.2 From ca20ec82a620c972f2dd1d45e1f4729c1e587225 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 18 May 2023 11:17:50 +0300 Subject: [PATCH 02/10] Implemented writing material_meshes --- .../render/hydra/scene_delegate/mesh.cc | 125 +++++++++--------- .../render/hydra/scene_delegate/mesh.h | 7 +- 2 files changed, 64 insertions(+), 68 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index 1903f8020a74..356b505fffd3 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -43,9 +43,9 @@ void MeshData::init() void MeshData::insert() { - if (face_vertex_counts_.empty()) { - return; - } + //if (face_vertex_counts_.empty()) { + // return; + //} ID_LOG(2, ""); scene_delegate_->GetRenderIndex().InsertRprim( @@ -72,7 +72,7 @@ void MeshData::update() } else { if (id->recalc & ID_RECALC_SHADING) { - write_material(nullptr); + write_material(); bits |= pxr::HdChangeTracker::DirtyMaterialId | pxr::HdChangeTracker::DirtyDoubleSided; } if (id->recalc & ID_RECALC_TRANSFORM) { @@ -90,11 +90,11 @@ void MeshData::update() return; } - if (face_vertex_counts_.empty()) { - /* Remove prim without faces */ - remove(); - return; - } + //if (face_vertex_counts_.empty()) { + // /* Remove prim without faces */ + // remove(); + // return; + //} ID_LOG(2, ""); scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(prim_id, bits); } @@ -127,10 +127,11 @@ bool MeshData::update_visibility() pxr::HdMeshTopology MeshData::mesh_topology() const { + const MaterialMesh &m = material_meshes_[0]; return pxr::HdMeshTopology(pxr::PxOsdOpenSubdivTokens->none, pxr::HdTokens->rightHanded, - face_vertex_counts_, - face_vertex_indices_); + m.face_vertex_counts, + m.face_vertex_indices); } pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors( @@ -158,23 +159,27 @@ pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors( pxr::SdfPath MeshData::material_id() const { - if (!mat_data_) { + const MaterialMesh &m = material_meshes_[0]; + if (!m.mat_data) { return pxr::SdfPath(); } - return mat_data_->prim_id; + return m.mat_data->prim_id; } bool MeshData::double_sided() const { - if (mat_data_) { - return mat_data_->double_sided; + const MaterialMesh &m = material_meshes_[0]; + if (m.mat_data) { + return m.mat_data->double_sided; } return true; } void MeshData::update_double_sided(MaterialData *mat_data) { - if (mat_data_ == mat_data) { + MaterialMesh &m = material_meshes_[0]; + + if (m.mat_data == mat_data) { ID_LOG(2, ""); scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty( prim_id, pxr::HdChangeTracker::DirtyDoubleSided); @@ -183,12 +188,9 @@ void MeshData::update_double_sided(MaterialData *mat_data) void MeshData::write_mesh(Mesh *mesh) { - face_vertex_counts_.clear(); - face_vertex_indices_.clear(); vertices_.clear(); normals_.clear(); uvs_.clear(); - face_material_indices_.clear(); BKE_mesh_calc_normals_split(mesh); int tris_len = BKE_mesh_runtime_looptri_len(mesh); @@ -196,20 +198,6 @@ void MeshData::write_mesh(Mesh *mesh) return; } - blender::Span loopTris = mesh->looptris(); - - /* face_vertex_counts */ - face_vertex_counts_ = pxr::VtIntArray(tris_len, 3); - - /* face_vertex_indices */ - blender::Span corner_verts = mesh->corner_verts(); - face_vertex_indices_.reserve(loopTris.size() * 3); - for (MLoopTri lt : loopTris) { - face_vertex_indices_.push_back(corner_verts[lt.tri[0]]); - face_vertex_indices_.push_back(corner_verts[lt.tri[1]]); - face_vertex_indices_.push_back(corner_verts[lt.tri[2]]); - } - /* vertices */ vertices_.reserve(mesh->totvert); blender::Span verts = mesh->vert_positions(); @@ -217,42 +205,53 @@ void MeshData::write_mesh(Mesh *mesh) vertices_.push_back(pxr::GfVec3f(v.x, v.y, v.z)); } + /* material meshes */ + material_meshes_.clear(); + int mat_count = BKE_object_material_count_eval((Object *)id); + for (int i = 0; i < std::max(mat_count, 1); ++i) { + material_meshes_.push_back(MaterialMesh()); + } + + const int *material_indices = BKE_mesh_material_indices(mesh); + const int *looptri_polys = BKE_mesh_runtime_looptri_polys_ensure(mesh); + blender::Span corner_verts = mesh->corner_verts(); + blender::Span looptris = mesh->looptris(); + for (size_t i = 0; i < looptris.size(); ++i) { + int mat_ind = material_indices ? material_indices[looptri_polys[i]] : 0; + + const MLoopTri < = looptris[i]; + MaterialMesh &m = material_meshes_[mat_ind]; + m.face_vertex_counts.push_back(3); + m.face_vertex_indices.push_back(corner_verts[lt.tri[0]]); + m.face_vertex_indices.push_back(corner_verts[lt.tri[1]]); + m.face_vertex_indices.push_back(corner_verts[lt.tri[2]]); + } + write_normals(mesh); write_uv_maps(mesh); - write_material(mesh); + write_material(); } -void MeshData::write_material(Mesh *mesh) +void MeshData::write_material() { Object *object = (Object *)id; - Material *mat = nullptr; - if (BKE_object_material_count_eval(object) > 0) { - mat = BKE_object_material_get_eval(object, object->actcol); - } - - if (!mat) { - mat_data_ = nullptr; - return; - } - - pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat); - mat_data_ = scene_delegate_->material_data(p_id); - if (!mat_data_) { - scene_delegate_->materials_[p_id] = std::make_unique(scene_delegate_, mat, p_id); - mat_data_ = scene_delegate_->material_data(p_id); - mat_data_->init(); - mat_data_->insert(); - } - - if (mesh) { - face_material_indices_.clear(); - const int *material_indices = BKE_mesh_material_indices(mesh); - const int *looptri_polys = BKE_mesh_runtime_looptri_polys_ensure(mesh); - int poly_ind; - blender::Span loopTris = mesh->looptris(); - for (size_t i = 0; i < loopTris.size(); ++i) { - poly_ind = looptri_polys[i]; - face_material_indices_.push_back(material_indices[poly_ind]); + for (int i = 0; i < material_meshes_.size(); ++i) { + MaterialMesh &m = material_meshes_[i]; + if (m.face_vertex_counts.empty()) { + continue; + } + Material *mat = BKE_object_material_get_eval(object, i); + if (!mat) { + m.mat_data = nullptr; + continue; + } + pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat); + m.mat_data = scene_delegate_->material_data(p_id); + if (!m.mat_data) { + scene_delegate_->materials_[p_id] = std::make_unique(scene_delegate_, mat, p_id); + m.mat_data = scene_delegate_->material_data(p_id); + m.mat_data->init(); + m.mat_data->insert(); } } } diff --git a/source/blender/render/hydra/scene_delegate/mesh.h b/source/blender/render/hydra/scene_delegate/mesh.h index 4737d77471ec..63f5d65df905 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.h +++ b/source/blender/render/hydra/scene_delegate/mesh.h @@ -41,18 +41,15 @@ class MeshData : public ObjectData { private: void write_mesh(Mesh *mesh); - void write_material(Mesh *mesh); + void write_material(); void write_uv_maps(Mesh *mesh); void write_normals(Mesh *mesh); - pxr::VtIntArray face_vertex_counts_; - pxr::VtIntArray face_vertex_indices_; pxr::VtVec3fArray vertices_; pxr::VtVec2fArray uvs_; pxr::VtVec3fArray normals_; - pxr::VtIntArray face_material_indices_; - MaterialData *mat_data_ = nullptr; + std::vector material_meshes_; }; } // namespace blender::render::hydra -- 2.30.2 From fc4da28bb945237eaaac9386778cb746b2424608 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 19 May 2023 01:13:09 +0300 Subject: [PATCH 03/10] Renamed MaterialMesh -> SubMesh. Preparations for inserting submeshes --- .../scene_delegate/blender_scene_delegate.cc | 14 ++---- .../render/hydra/scene_delegate/instancer.cc | 5 +- .../render/hydra/scene_delegate/mesh.cc | 46 +++++++++++++------ .../render/hydra/scene_delegate/mesh.h | 12 +++-- 4 files changed, 46 insertions(+), 31 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc index 7cc48f1e2b47..94204f444469 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -26,7 +26,7 @@ pxr::HdMeshTopology BlenderSceneDelegate::GetMeshTopology(pxr::SdfPath const &id { CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText()); MeshData *m_data = mesh_data(id); - return m_data->mesh_topology(); + return m_data->mesh_topology(id); } pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id) @@ -96,7 +96,7 @@ pxr::HdPrimvarDescriptorVector BlenderSceneDelegate::GetPrimvarDescriptors( pxr::SdfPath BlenderSceneDelegate::GetMaterialId(pxr::SdfPath const &rprim_id) { CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", rprim_id.GetText()); - return mesh_data(rprim_id)->material_id(); + return mesh_data(rprim_id)->material_id(rprim_id); } pxr::VtValue BlenderSceneDelegate::GetMaterialResource(pxr::SdfPath const &id) @@ -125,7 +125,7 @@ bool BlenderSceneDelegate::GetVisible(pxr::SdfPath const &id) bool BlenderSceneDelegate::GetDoubleSided(pxr::SdfPath const &id) { CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText()); - return mesh_data(id)->double_sided(); + return mesh_data(id)->double_sided(id); } pxr::HdCullStyle BlenderSceneDelegate::GetCullStyle(pxr::SdfPath const &id) @@ -510,12 +510,8 @@ void BlenderSceneDelegate::remove_unused_objects() std::set available_materials; for (auto &it : objects_) { MeshData *m_data = dynamic_cast(it.second.get()); - if (!m_data) { - continue; - } - pxr::SdfPath mat_id = m_data->material_id(); - if (!mat_id.IsEmpty()) { - available_materials.insert(mat_id); + if (m_data) { + m_data->available_materials(available_materials); } } for (auto &it : instancers_) { diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index e10cd9972574..8ddde9fdfcc5 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -214,10 +214,7 @@ void InstancerData::check_remove(std::set &available_objects) void InstancerData::available_materials(std::set &paths) const { for (auto &it : mesh_instances_) { - pxr::SdfPath mat_id = ((MeshData *)it.second.data.get())->material_id(); - if (!mat_id.IsEmpty()) { - paths.insert(mat_id); - } + ((MeshData *)it.second.data.get())->available_materials(paths); } } diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index 356b505fffd3..98c1a7fd2946 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -125,9 +125,9 @@ bool MeshData::update_visibility() return ret; } -pxr::HdMeshTopology MeshData::mesh_topology() const +pxr::HdMeshTopology MeshData::mesh_topology(pxr::SdfPath const &id) const { - const MaterialMesh &m = material_meshes_[0]; + const SubMesh &m = sub_meshes_[0]; return pxr::HdMeshTopology(pxr::PxOsdOpenSubdivTokens->none, pxr::HdTokens->rightHanded, m.face_vertex_counts, @@ -157,18 +157,18 @@ pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors( return primvars; } -pxr::SdfPath MeshData::material_id() const +pxr::SdfPath MeshData::material_id(pxr::SdfPath const &id) const { - const MaterialMesh &m = material_meshes_[0]; + const SubMesh &m = sub_meshes_[0]; if (!m.mat_data) { return pxr::SdfPath(); } return m.mat_data->prim_id; } -bool MeshData::double_sided() const +bool MeshData::double_sided(pxr::SdfPath const &id) const { - const MaterialMesh &m = material_meshes_[0]; + const SubMesh &m = sub_meshes_[0]; if (m.mat_data) { return m.mat_data->double_sided; } @@ -177,7 +177,7 @@ bool MeshData::double_sided() const void MeshData::update_double_sided(MaterialData *mat_data) { - MaterialMesh &m = material_meshes_[0]; + SubMesh &m = sub_meshes_[0]; if (m.mat_data == mat_data) { ID_LOG(2, ""); @@ -186,6 +186,15 @@ void MeshData::update_double_sided(MaterialData *mat_data) } } +void MeshData::available_materials(std::set &paths) const +{ + for (auto &m : sub_meshes_) { + if (m.mat_data && !m.mat_data->prim_id.IsEmpty()) { + paths.insert(m.mat_data->prim_id); + } + } +} + void MeshData::write_mesh(Mesh *mesh) { vertices_.clear(); @@ -206,10 +215,12 @@ void MeshData::write_mesh(Mesh *mesh) } /* material meshes */ - material_meshes_.clear(); + sub_meshes_.clear(); int mat_count = BKE_object_material_count_eval((Object *)id); for (int i = 0; i < std::max(mat_count, 1); ++i) { - material_meshes_.push_back(MaterialMesh()); + SubMesh m; + m.mat_index = i; + sub_meshes_.push_back(m); } const int *material_indices = BKE_mesh_material_indices(mesh); @@ -220,13 +231,22 @@ void MeshData::write_mesh(Mesh *mesh) int mat_ind = material_indices ? material_indices[looptri_polys[i]] : 0; const MLoopTri < = looptris[i]; - MaterialMesh &m = material_meshes_[mat_ind]; + SubMesh &m = sub_meshes_[mat_ind]; m.face_vertex_counts.push_back(3); m.face_vertex_indices.push_back(corner_verts[lt.tri[0]]); m.face_vertex_indices.push_back(corner_verts[lt.tri[1]]); m.face_vertex_indices.push_back(corner_verts[lt.tri[2]]); } + for (auto it = sub_meshes_.begin(); it != sub_meshes_.end();) { + if (it->face_vertex_counts.empty()) { + it = sub_meshes_.erase(it); + } + else { + ++it; + } + } + write_normals(mesh); write_uv_maps(mesh); write_material(); @@ -235,12 +255,12 @@ void MeshData::write_mesh(Mesh *mesh) void MeshData::write_material() { Object *object = (Object *)id; - for (int i = 0; i < material_meshes_.size(); ++i) { - MaterialMesh &m = material_meshes_[i]; + for (int i = 0; i < sub_meshes_.size(); ++i) { + SubMesh &m = sub_meshes_[i]; if (m.face_vertex_counts.empty()) { continue; } - Material *mat = BKE_object_material_get_eval(object, i); + Material *mat = BKE_object_material_get_eval(object, m.mat_index); if (!mat) { m.mat_data = nullptr; continue; diff --git a/source/blender/render/hydra/scene_delegate/mesh.h b/source/blender/render/hydra/scene_delegate/mesh.h index 63f5d65df905..f2a22386747e 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.h +++ b/source/blender/render/hydra/scene_delegate/mesh.h @@ -14,9 +14,10 @@ namespace blender::render::hydra { class MeshData : public ObjectData { - struct MaterialMesh { + struct SubMesh { pxr::VtIntArray face_vertex_counts; pxr::VtIntArray face_vertex_indices; + int mat_index = 0; MaterialData *mat_data = nullptr; }; @@ -31,11 +32,12 @@ class MeshData : public ObjectData { pxr::VtValue get_data(pxr::TfToken const &key) const override; bool update_visibility() override; - pxr::HdMeshTopology mesh_topology() const; + pxr::HdMeshTopology mesh_topology(pxr::SdfPath const &id) const; pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const; - pxr::SdfPath material_id() const; - bool double_sided() const; + pxr::SdfPath material_id(pxr::SdfPath const &id) const; + bool double_sided(pxr::SdfPath const &id) const; void update_double_sided(MaterialData *mat_data); + void available_materials(std::set &paths) const; pxr::HdCullStyle cull_style = pxr::HdCullStyleBackUnlessDoubleSided; @@ -49,7 +51,7 @@ class MeshData : public ObjectData { pxr::VtVec2fArray uvs_; pxr::VtVec3fArray normals_; - std::vector material_meshes_; + std::vector sub_meshes_; }; } // namespace blender::render::hydra -- 2.30.2 From 3e5ca6bc3722fe1246d90209f8cec64b9393b95e Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 19 May 2023 04:13:25 +0300 Subject: [PATCH 04/10] Adjusted MeshData code --- .../scene_delegate/blender_scene_delegate.cc | 13 +- .../render/hydra/scene_delegate/instancer.cc | 6 +- .../render/hydra/scene_delegate/mesh.cc | 222 ++++++++++-------- .../render/hydra/scene_delegate/mesh.h | 8 +- 4 files changed, 142 insertions(+), 107 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc index 94204f444469..ec01c9eb53e5 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -376,8 +376,8 @@ void BlenderSceneDelegate::check_updates() DEGIDIterData data = {0}; data.graph = depsgraph; data.only_updated = true; - ITER_BEGIN ( - DEG_iterator_ids_begin, DEG_iterator_ids_next, DEG_iterator_ids_end, &data, ID *, id) { + ITER_BEGIN (DEG_iterator_ids_begin, DEG_iterator_ids_next, DEG_iterator_ids_end, &data, ID *, id) + { CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, @@ -451,7 +451,8 @@ void BlenderSceneDelegate::add_new_objects() DEG_iterator_objects_end, &data, Object *, - object) { + object) + { update_objects(object); update_instancers(object); @@ -476,7 +477,8 @@ void BlenderSceneDelegate::remove_unused_objects() DEG_iterator_objects_end, &data, Object *, - object) { + object) + { if (ObjectData::is_supported(object)) { available_objects.insert(object_prim_id(object).GetName()); } @@ -550,7 +552,8 @@ void BlenderSceneDelegate::update_visibility() DEG_iterator_objects_end, &data, Object *, - object) { + object) + { if (!object_data(object_prim_id(object))) { update_objects(object); diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index 8ddde9fdfcc5..4a0f9faaf7b1 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -66,7 +66,8 @@ void InstancerData::update() Object *object = (Object *)id; if (id->recalc & ID_RECALC_GEOMETRY || (object->data && ((ID *)object->data)->recalc & ID_RECALC_GEOMETRY) || - id->recalc & ID_RECALC_TRANSFORM) { + id->recalc & ID_RECALC_TRANSFORM) + { set_instances(); scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( prim_id, pxr::HdChangeTracker::AllDirty); @@ -174,7 +175,8 @@ void InstancerData::check_update(Object *object) if (l_it != light_instances_.end()) { Object *obj = (Object *)l_it->second.data->id; if (obj->id.recalc & (ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY) || - ((ID *)obj->data)->recalc & ID_RECALC_GEOMETRY) { + ((ID *)obj->data)->recalc & ID_RECALC_GEOMETRY) + { set_instances(); } return; diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index 98c1a7fd2946..f196cd510db3 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -27,7 +27,8 @@ void MeshData::init() Object *object = (Object *)id; if (object->type == OB_MESH && object->mode == OB_MODE_OBJECT && - BLI_listbase_is_empty(&object->modifiers)) { + BLI_listbase_is_empty(&object->modifiers)) + { write_mesh((Mesh *)object->data); } else { @@ -43,60 +44,43 @@ void MeshData::init() void MeshData::insert() { - //if (face_vertex_counts_.empty()) { - // return; - //} - - ID_LOG(2, ""); - scene_delegate_->GetRenderIndex().InsertRprim( - pxr::HdPrimTypeTokens->mesh, scene_delegate_, prim_id); + /* Empty, because insertion of rprims happen in update_sub_meshes() */ } void MeshData::remove() { - if (!scene_delegate_->GetRenderIndex().HasRprim(prim_id)) { - return; + for (int i = 0; i < submeshes_.size(); ++i) { + scene_delegate_->GetRenderIndex().RemoveRprim(submesh_prim_id(i)); + CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s: %d", prim_id.GetText(), i); } - - CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText()); - scene_delegate_->GetRenderIndex().RemoveRprim(prim_id); } void MeshData::update() { Object *object = (Object *)id; - pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) { init(); - bits = pxr::HdChangeTracker::AllDirty; + return; } - else { - if (id->recalc & ID_RECALC_SHADING) { - write_material(); - bits |= pxr::HdChangeTracker::DirtyMaterialId | pxr::HdChangeTracker::DirtyDoubleSided; - } - if (id->recalc & ID_RECALC_TRANSFORM) { - write_transform(); - bits |= pxr::HdChangeTracker::DirtyTransform; - } + + pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; + if (id->recalc & ID_RECALC_SHADING) { + write_materials(); + bits |= pxr::HdChangeTracker::DirtyMaterialId | pxr::HdChangeTracker::DirtyDoubleSided; + } + if (id->recalc & ID_RECALC_TRANSFORM) { + write_transform(); + bits |= pxr::HdChangeTracker::DirtyTransform; } if (bits == pxr::HdChangeTracker::Clean) { return; } - if (!scene_delegate_->GetRenderIndex().HasRprim(prim_id)) { - insert(); - return; + for (int i = 0; i < submeshes_.size(); ++i) { + scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(submesh_prim_id(i), bits); + ID_LOG(2, "%d", i); } - - //if (face_vertex_counts_.empty()) { - // /* Remove prim without faces */ - // remove(); - // return; - //} - ID_LOG(2, ""); - scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(prim_id, bits); } pxr::VtValue MeshData::get_data(pxr::TfToken const &key) const @@ -118,20 +102,22 @@ bool MeshData::update_visibility() { bool ret = ObjectData::update_visibility(); if (ret) { - ID_LOG(2, ""); - scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty( - prim_id, pxr::HdChangeTracker::DirtyVisibility); + for (int i = 0; i < submeshes_.size(); ++i) { + scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty( + submesh_prim_id(i), pxr::HdChangeTracker::DirtyVisibility); + ID_LOG(2, "%d", i); + } } return ret; } pxr::HdMeshTopology MeshData::mesh_topology(pxr::SdfPath const &id) const { - const SubMesh &m = sub_meshes_[0]; + const SubMesh &sm = submesh(id); return pxr::HdMeshTopology(pxr::PxOsdOpenSubdivTokens->none, pxr::HdTokens->rightHanded, - m.face_vertex_counts, - m.face_vertex_indices); + sm.face_vertex_counts, + sm.face_vertex_indices); } pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors( @@ -159,38 +145,38 @@ pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors( pxr::SdfPath MeshData::material_id(pxr::SdfPath const &id) const { - const SubMesh &m = sub_meshes_[0]; - if (!m.mat_data) { + const SubMesh &sm = submesh(id); + if (!sm.mat_data) { return pxr::SdfPath(); } - return m.mat_data->prim_id; + return sm.mat_data->prim_id; } bool MeshData::double_sided(pxr::SdfPath const &id) const { - const SubMesh &m = sub_meshes_[0]; - if (m.mat_data) { - return m.mat_data->double_sided; + const SubMesh &sm = submesh(id); + if (sm.mat_data) { + return sm.mat_data->double_sided; } return true; } void MeshData::update_double_sided(MaterialData *mat_data) { - SubMesh &m = sub_meshes_[0]; - - if (m.mat_data == mat_data) { - ID_LOG(2, ""); - scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty( - prim_id, pxr::HdChangeTracker::DirtyDoubleSided); + for (int i = 0; i < submeshes_.size(); ++i) { + if (submeshes_[i].mat_data == mat_data) { + scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty( + submesh_prim_id(i), pxr::HdChangeTracker::DirtyDoubleSided); + ID_LOG(2, "%d", i); + } } } void MeshData::available_materials(std::set &paths) const { - for (auto &m : sub_meshes_) { - if (m.mat_data && !m.mat_data->prim_id.IsEmpty()) { - paths.insert(m.mat_data->prim_id); + for (auto &sm : submeshes_) { + if (sm.mat_data && !sm.mat_data->prim_id.IsEmpty()) { + paths.insert(sm.mat_data->prim_id); } } } @@ -201,9 +187,9 @@ void MeshData::write_mesh(Mesh *mesh) normals_.clear(); uvs_.clear(); - BKE_mesh_calc_normals_split(mesh); - int tris_len = BKE_mesh_runtime_looptri_len(mesh); - if (tris_len == 0) { + update_sub_meshes(mesh); + + if (submeshes_.empty()) { return; } @@ -214,49 +200,16 @@ void MeshData::write_mesh(Mesh *mesh) vertices_.push_back(pxr::GfVec3f(v.x, v.y, v.z)); } - /* material meshes */ - sub_meshes_.clear(); - int mat_count = BKE_object_material_count_eval((Object *)id); - for (int i = 0; i < std::max(mat_count, 1); ++i) { - SubMesh m; - m.mat_index = i; - sub_meshes_.push_back(m); - } - - const int *material_indices = BKE_mesh_material_indices(mesh); - const int *looptri_polys = BKE_mesh_runtime_looptri_polys_ensure(mesh); - blender::Span corner_verts = mesh->corner_verts(); - blender::Span looptris = mesh->looptris(); - for (size_t i = 0; i < looptris.size(); ++i) { - int mat_ind = material_indices ? material_indices[looptri_polys[i]] : 0; - - const MLoopTri < = looptris[i]; - SubMesh &m = sub_meshes_[mat_ind]; - m.face_vertex_counts.push_back(3); - m.face_vertex_indices.push_back(corner_verts[lt.tri[0]]); - m.face_vertex_indices.push_back(corner_verts[lt.tri[1]]); - m.face_vertex_indices.push_back(corner_verts[lt.tri[2]]); - } - - for (auto it = sub_meshes_.begin(); it != sub_meshes_.end();) { - if (it->face_vertex_counts.empty()) { - it = sub_meshes_.erase(it); - } - else { - ++it; - } - } - write_normals(mesh); write_uv_maps(mesh); - write_material(); + write_materials(); } -void MeshData::write_material() +void MeshData::write_materials() { Object *object = (Object *)id; - for (int i = 0; i < sub_meshes_.size(); ++i) { - SubMesh &m = sub_meshes_[i]; + for (int i = 0; i < submeshes_.size(); ++i) { + SubMesh &m = submeshes_[i]; if (m.face_vertex_counts.empty()) { continue; } @@ -268,7 +221,8 @@ void MeshData::write_material() pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat); m.mat_data = scene_delegate_->material_data(p_id); if (!m.mat_data) { - scene_delegate_->materials_[p_id] = std::make_unique(scene_delegate_, mat, p_id); + scene_delegate_->materials_[p_id] = std::make_unique( + scene_delegate_, mat, p_id); m.mat_data = scene_delegate_->material_data(p_id); m.mat_data->init(); m.mat_data->insert(); @@ -292,6 +246,7 @@ void MeshData::write_uv_maps(Mesh *mesh) void MeshData::write_normals(Mesh *mesh) { + BKE_mesh_calc_normals_split(mesh); blender::Span loopTris = mesh->looptris(); const float(*lnors)[3] = (float(*)[3])CustomData_get_layer(&mesh->ldata, CD_NORMAL); if (lnors) { @@ -304,4 +259,77 @@ void MeshData::write_normals(Mesh *mesh) } } +pxr::SdfPath MeshData::submesh_prim_id(int index) const +{ + char name[16]; + snprintf(name, 16, "M_%04x", index); + return prim_id.AppendElementString(name); +} + +const MeshData::SubMesh &MeshData::submesh(pxr::SdfPath const &id) const +{ + int index; + sscanf(id.GetName().c_str(), "M_%x", &index); + return submeshes_[index]; +} + +void MeshData::update_sub_meshes(Mesh *mesh) +{ + int sub_meshes_prev_count = submeshes_.size(); + + /* Insert base submeshes */ + submeshes_.clear(); + int mat_count = BKE_object_material_count_eval((Object *)id); + for (int i = 0; i < std::max(mat_count, 1); ++i) { + SubMesh sm; + sm.mat_index = i; + submeshes_.push_back(sm); + } + + /* Fill submeshes data */ + const int *material_indices = BKE_mesh_material_indices(mesh); + const int *looptri_polys = BKE_mesh_runtime_looptri_polys_ensure(mesh); + blender::Span corner_verts = mesh->corner_verts(); + blender::Span looptris = mesh->looptris(); + for (size_t i = 0; i < looptris.size(); ++i) { + int mat_ind = material_indices ? material_indices[looptri_polys[i]] : 0; + + const MLoopTri < = looptris[i]; + SubMesh &sm = submeshes_[mat_ind]; + sm.face_vertex_counts.push_back(3); + sm.face_vertex_indices.push_back(corner_verts[lt.tri[0]]); + sm.face_vertex_indices.push_back(corner_verts[lt.tri[1]]); + sm.face_vertex_indices.push_back(corner_verts[lt.tri[2]]); + } + + /* Remove submeshes without faces */ + for (auto it = submeshes_.begin(); it != submeshes_.end();) { + if (it->face_vertex_counts.empty()) { + it = submeshes_.erase(it); + } + else { + ++it; + } + } + + /* Update prims in render index */ + auto &render_index = scene_delegate_->GetRenderIndex(); + int i; + for (i = 0; i < submeshes_.size(); ++i) { + pxr::SdfPath p = submesh_prim_id(i); + if (i < sub_meshes_prev_count) { + render_index.GetChangeTracker().MarkRprimDirty(p, pxr::HdChangeTracker::AllDirty); + ID_LOG(2, "Update %d", i); + } + else { + render_index.InsertRprim(pxr::HdPrimTypeTokens->mesh, scene_delegate_, p); + ID_LOG(2, "Insert %d", i); + } + } + for (; i < sub_meshes_prev_count; ++i) { + render_index.RemoveRprim(submesh_prim_id(i)); + ID_LOG(2, "Remove %d", i); + } +} + } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/scene_delegate/mesh.h b/source/blender/render/hydra/scene_delegate/mesh.h index f2a22386747e..5625797c9bd1 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.h +++ b/source/blender/render/hydra/scene_delegate/mesh.h @@ -43,15 +43,17 @@ class MeshData : public ObjectData { private: void write_mesh(Mesh *mesh); - void write_material(); + void write_materials(); void write_uv_maps(Mesh *mesh); void write_normals(Mesh *mesh); + pxr::SdfPath submesh_prim_id(int index) const; + const SubMesh &submesh(pxr::SdfPath const &id) const; + void update_sub_meshes(Mesh *mesh); pxr::VtVec3fArray vertices_; pxr::VtVec2fArray uvs_; pxr::VtVec3fArray normals_; - - std::vector sub_meshes_; + std::vector submeshes_; }; } // namespace blender::render::hydra -- 2.30.2 From de7e393e70f0a716ca313fe4a6317212a6e3bad9 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 19 May 2023 04:34:07 +0300 Subject: [PATCH 05/10] Adjusting BlenderSceneDelegate --- .../render/hydra/scene_delegate/blender_scene_delegate.cc | 5 +++-- source/blender/render/hydra/scene_delegate/mesh.cc | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc index ec01c9eb53e5..82f3ae650ae7 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -236,11 +236,12 @@ pxr::SdfPath BlenderSceneDelegate::world_prim_id() const ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id) const { - auto it = objects_.find(id); + pxr::SdfPath p_id = (id.GetName().find("SM_", 0) == 0) ? id.GetParentPath() : id; + auto it = objects_.find(p_id); if (it != objects_.end()) { return it->second.get(); } - InstancerData *i_data = instancer_data(id, true); + InstancerData *i_data = instancer_data(p_id, true); if (i_data) { return i_data->object_data(id); } diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index f196cd510db3..dce65a122759 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -262,14 +262,14 @@ void MeshData::write_normals(Mesh *mesh) pxr::SdfPath MeshData::submesh_prim_id(int index) const { char name[16]; - snprintf(name, 16, "M_%04x", index); + snprintf(name, 16, "SM_%04x", index); return prim_id.AppendElementString(name); } const MeshData::SubMesh &MeshData::submesh(pxr::SdfPath const &id) const { int index; - sscanf(id.GetName().c_str(), "M_%x", &index); + sscanf(id.GetName().c_str(), "SM_%x", &index); return submeshes_[index]; } -- 2.30.2 From 49896dfa07ef0a6ea285fc1d34979b167ea4992f Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sat, 20 May 2023 11:44:02 +0300 Subject: [PATCH 06/10] Fixed getting submesh data, simplified and improved code --- .../scene_delegate/blender_scene_delegate.cc | 4 + .../render/hydra/scene_delegate/mesh.cc | 150 +++++++----------- .../render/hydra/scene_delegate/mesh.h | 13 +- 3 files changed, 70 insertions(+), 97 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc index 585691063f85..a16eec37ce91 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -46,6 +46,10 @@ pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id) pxr::VtValue BlenderSceneDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const &key) { CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s, %s", id.GetText(), key.GetText()); + MeshData *m_data = mesh_data(id); + if (m_data) { + return m_data->get_data(id, key); + } ObjectData *obj_data = object_data(id); if (obj_data) { return obj_data->get_data(key); diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index dce65a122759..50791f20156d 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -29,22 +29,23 @@ void MeshData::init() if (object->type == OB_MESH && object->mode == OB_MODE_OBJECT && BLI_listbase_is_empty(&object->modifiers)) { - write_mesh((Mesh *)object->data); + write_submeshes((Mesh *)object->data); } else { Mesh *mesh = BKE_object_to_mesh(nullptr, object, false); if (mesh) { - write_mesh(mesh); + write_submeshes(mesh); } BKE_object_to_mesh_clear(object); } write_transform(); + write_materials(); } void MeshData::insert() { - /* Empty, because insertion of rprims happen in update_sub_meshes() */ + /* Empty, because insertion of rprims happen in write_submeshes() */ } void MeshData::remove() @@ -83,17 +84,17 @@ void MeshData::update() } } -pxr::VtValue MeshData::get_data(pxr::TfToken const &key) const +pxr::VtValue MeshData::get_data(pxr::SdfPath const &id, pxr::TfToken const &key) const { pxr::VtValue ret; if (key == pxr::HdTokens->points) { ret = vertices_; } else if (key == pxr::HdTokens->normals) { - ret = normals_; + ret = submesh(id).normals; } else if (key == pxr::HdPrimvarRoleTokens->textureCoordinate) { - ret = uvs_; + ret = submesh(id).uvs; } return ret; } @@ -130,11 +131,11 @@ pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors( } } else if (interpolation == pxr::HdInterpolationFaceVarying) { - if (!normals_.empty()) { + if (!submeshes_[0].normals.empty()) { primvars.emplace_back( pxr::HdTokens->normals, interpolation, pxr::HdPrimvarRoleTokens->normal); } - if (!uvs_.empty()) { + if (!submeshes_[0].uvs.empty()) { primvars.emplace_back(pxr::HdPrimvarRoleTokens->textureCoordinate, interpolation, pxr::HdPrimvarRoleTokens->textureCoordinate); @@ -181,84 +182,6 @@ void MeshData::available_materials(std::set &paths) const } } -void MeshData::write_mesh(Mesh *mesh) -{ - vertices_.clear(); - normals_.clear(); - uvs_.clear(); - - update_sub_meshes(mesh); - - if (submeshes_.empty()) { - return; - } - - /* 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)); - } - - write_normals(mesh); - write_uv_maps(mesh); - write_materials(); -} - -void MeshData::write_materials() -{ - Object *object = (Object *)id; - for (int i = 0; i < submeshes_.size(); ++i) { - SubMesh &m = submeshes_[i]; - if (m.face_vertex_counts.empty()) { - continue; - } - Material *mat = BKE_object_material_get_eval(object, m.mat_index); - if (!mat) { - m.mat_data = nullptr; - continue; - } - pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat); - m.mat_data = scene_delegate_->material_data(p_id); - if (!m.mat_data) { - scene_delegate_->materials_[p_id] = std::make_unique( - scene_delegate_, mat, p_id); - m.mat_data = scene_delegate_->material_data(p_id); - m.mat_data->init(); - m.mat_data->insert(); - } - } -} - -void MeshData::write_uv_maps(Mesh *mesh) -{ - blender::Span loopTris = mesh->looptris(); - const float(*luvs)[2] = (float(*)[2])CustomData_get_layer(&mesh->ldata, CD_PROP_FLOAT2); - if (luvs) { - uvs_.reserve(loopTris.size() * 3); - for (MLoopTri lt : loopTris) { - uvs_.push_back(pxr::GfVec2f(luvs[lt.tri[0]])); - uvs_.push_back(pxr::GfVec2f(luvs[lt.tri[1]])); - uvs_.push_back(pxr::GfVec2f(luvs[lt.tri[2]])); - } - } -} - -void MeshData::write_normals(Mesh *mesh) -{ - BKE_mesh_calc_normals_split(mesh); - blender::Span loopTris = mesh->looptris(); - const float(*lnors)[3] = (float(*)[3])CustomData_get_layer(&mesh->ldata, CD_NORMAL); - if (lnors) { - normals_.reserve(loopTris.size() * 3); - for (MLoopTri lt : loopTris) { - normals_.push_back(pxr::GfVec3f(lnors[lt.tri[0]])); - normals_.push_back(pxr::GfVec3f(lnors[lt.tri[1]])); - normals_.push_back(pxr::GfVec3f(lnors[lt.tri[2]])); - } - } -} - pxr::SdfPath MeshData::submesh_prim_id(int index) const { char name[16]; @@ -273,12 +196,13 @@ const MeshData::SubMesh &MeshData::submesh(pxr::SdfPath const &id) const return submeshes_[index]; } -void MeshData::update_sub_meshes(Mesh *mesh) +void MeshData::write_submeshes(Mesh *mesh) { int sub_meshes_prev_count = submeshes_.size(); + submeshes_.clear(); + vertices_.clear(); /* Insert base submeshes */ - submeshes_.clear(); int mat_count = BKE_object_material_count_eval((Object *)id); for (int i = 0; i < std::max(mat_count, 1); ++i) { SubMesh sm; @@ -291,15 +215,32 @@ void MeshData::update_sub_meshes(Mesh *mesh) const int *looptri_polys = BKE_mesh_runtime_looptri_polys_ensure(mesh); blender::Span corner_verts = mesh->corner_verts(); blender::Span looptris = mesh->looptris(); + + BKE_mesh_calc_normals_split(mesh); + const float(*lnors)[3] = (float(*)[3])CustomData_get_layer(&mesh->ldata, CD_NORMAL); + const float(*luvs)[2] = (float(*)[2])CustomData_get_layer(&mesh->ldata, CD_PROP_FLOAT2); + for (size_t i = 0; i < looptris.size(); ++i) { int mat_ind = material_indices ? material_indices[looptri_polys[i]] : 0; - const MLoopTri < = looptris[i]; SubMesh &sm = submeshes_[mat_ind]; + sm.face_vertex_counts.push_back(3); sm.face_vertex_indices.push_back(corner_verts[lt.tri[0]]); sm.face_vertex_indices.push_back(corner_verts[lt.tri[1]]); sm.face_vertex_indices.push_back(corner_verts[lt.tri[2]]); + + if (lnors) { + sm.normals.push_back(pxr::GfVec3f(lnors[lt.tri[0]])); + sm.normals.push_back(pxr::GfVec3f(lnors[lt.tri[1]])); + sm.normals.push_back(pxr::GfVec3f(lnors[lt.tri[2]])); + } + + if (luvs) { + sm.uvs.push_back(pxr::GfVec2f(luvs[lt.tri[0]])); + sm.uvs.push_back(pxr::GfVec2f(luvs[lt.tri[1]])); + sm.uvs.push_back(pxr::GfVec2f(luvs[lt.tri[2]])); + } } /* Remove submeshes without faces */ @@ -312,6 +253,15 @@ void MeshData::update_sub_meshes(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)); + } + } + /* Update prims in render index */ auto &render_index = scene_delegate_->GetRenderIndex(); int i; @@ -332,4 +282,26 @@ void MeshData::update_sub_meshes(Mesh *mesh) } } +void MeshData::write_materials() +{ + Object *object = (Object *)id; + for (int i = 0; i < submeshes_.size(); ++i) { + SubMesh &m = submeshes_[i]; + Material *mat = BKE_object_material_get_eval(object, m.mat_index + 1); + if (!mat) { + m.mat_data = nullptr; + continue; + } + pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat); + m.mat_data = scene_delegate_->material_data(p_id); + if (!m.mat_data) { + scene_delegate_->materials_[p_id] = std::make_unique( + scene_delegate_, mat, p_id); + m.mat_data = scene_delegate_->material_data(p_id); + m.mat_data->init(); + m.mat_data->insert(); + } + } +} + } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/scene_delegate/mesh.h b/source/blender/render/hydra/scene_delegate/mesh.h index 5625797c9bd1..edc0ad173c5e 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.h +++ b/source/blender/render/hydra/scene_delegate/mesh.h @@ -17,6 +17,8 @@ class MeshData : public ObjectData { struct SubMesh { pxr::VtIntArray face_vertex_counts; pxr::VtIntArray face_vertex_indices; + pxr::VtVec3fArray normals; + pxr::VtVec2fArray uvs; int mat_index = 0; MaterialData *mat_data = nullptr; }; @@ -29,7 +31,7 @@ class MeshData : public ObjectData { void remove() override; void update() override; - pxr::VtValue get_data(pxr::TfToken const &key) const override; + pxr::VtValue get_data(pxr::SdfPath const &id, pxr::TfToken const &key) const; bool update_visibility() override; pxr::HdMeshTopology mesh_topology(pxr::SdfPath const &id) const; @@ -42,17 +44,12 @@ class MeshData : public ObjectData { pxr::HdCullStyle cull_style = pxr::HdCullStyleBackUnlessDoubleSided; private: - void write_mesh(Mesh *mesh); - void write_materials(); - void write_uv_maps(Mesh *mesh); - void write_normals(Mesh *mesh); pxr::SdfPath submesh_prim_id(int index) const; const SubMesh &submesh(pxr::SdfPath const &id) const; - void update_sub_meshes(Mesh *mesh); + void write_submeshes(Mesh *mesh); + void write_materials(); pxr::VtVec3fArray vertices_; - pxr::VtVec2fArray uvs_; - pxr::VtVec3fArray normals_; std::vector submeshes_; }; -- 2.30.2 From 8a310c67fe65f9373f2e18c4ddebc2617b08267e Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sat, 20 May 2023 20:51:10 +0300 Subject: [PATCH 07/10] Fixed using submeshes in InstancerData --- .../hydra/scene_delegate/blender_scene_delegate.cc | 3 +-- .../render/hydra/scene_delegate/instancer.cc | 14 ++++++++------ source/blender/render/hydra/scene_delegate/mesh.cc | 9 +++++++++ source/blender/render/hydra/scene_delegate/mesh.h | 1 + 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc index a16eec37ce91..23f7ee906a51 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -138,7 +138,7 @@ pxr::HdCullStyle BlenderSceneDelegate::GetCullStyle(pxr::SdfPath const &id) pxr::SdfPath BlenderSceneDelegate::GetInstancerId(pxr::SdfPath const &prim_id) { CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", prim_id.GetText()); - InstancerData *i_data = instancer_data(prim_id.GetParentPath()); + InstancerData *i_data = instancer_data(prim_id, true); if (i_data) { return i_data->prim_id; } @@ -387,7 +387,6 @@ void BlenderSceneDelegate::check_updates() data.only_updated = true; ITER_BEGIN (DEG_iterator_ids_begin, DEG_iterator_ids_next, DEG_iterator_ids_end, &data, ID *, id) { - CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "Update: %s [%s]", diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index 4a0f9faaf7b1..be7ba5f0b5c8 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -109,9 +109,9 @@ bool InstancerData::update_visibility() pxr::GfMatrix4d InstancerData::get_transform(pxr::SdfPath const &id) const { - if (id.GetPathElementCount() == 4) { - const auto &inst = light_instances_.find(id.GetParentPath())->second; - return inst.transforms[light_prim_id_index(id)]; + auto l_it = light_instances_.find(id.GetParentPath()); + if (l_it != light_instances_.end()) { + return l_it->second.transforms[light_prim_id_index(id)]; } /* Mesh instance transform must be identity */ @@ -131,12 +131,12 @@ pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors( pxr::VtIntArray InstancerData::indices(pxr::SdfPath const &id) const { - return mesh_instances_.find(id)->second.indices; + return mesh_instances_.find(id.GetParentPath())->second.indices; } ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const { - auto m_it = mesh_instances_.find(id); + auto m_it = mesh_instances_.find(id.GetParentPath()); if (m_it != mesh_instances_.end()) { return m_it->second.data.get(); } @@ -151,7 +151,9 @@ pxr::SdfPathVector InstancerData::prototypes() const { pxr::SdfPathVector paths; for (auto &it : mesh_instances_) { - paths.push_back(it.first); + for (auto &p : it.second.data->submesh_paths()) { + paths.push_back(p); + } } return paths; } diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index 50791f20156d..8c8ef8bb86f5 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -182,6 +182,15 @@ void MeshData::available_materials(std::set &paths) const } } +pxr::SdfPathVector MeshData::submesh_paths() const +{ + pxr::SdfPathVector ret; + for (int i = 0; i < submeshes_.size(); ++i) { + ret.push_back(submesh_prim_id(i)); + } + return ret; +} + pxr::SdfPath MeshData::submesh_prim_id(int index) const { char name[16]; diff --git a/source/blender/render/hydra/scene_delegate/mesh.h b/source/blender/render/hydra/scene_delegate/mesh.h index edc0ad173c5e..750e9c2bdf39 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.h +++ b/source/blender/render/hydra/scene_delegate/mesh.h @@ -40,6 +40,7 @@ class MeshData : public ObjectData { bool double_sided(pxr::SdfPath const &id) const; void update_double_sided(MaterialData *mat_data); void available_materials(std::set &paths) const; + pxr::SdfPathVector submesh_paths() const; pxr::HdCullStyle cull_style = pxr::HdCullStyleBackUnlessDoubleSided; -- 2.30.2 From e191c99b74cacf59e1fa97ee9d8e9edf8c502858 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sat, 20 May 2023 21:54:23 +0300 Subject: [PATCH 08/10] Improved working with instances in InstancerData --- .../render/hydra/scene_delegate/instancer.cc | 82 +++++++++++-------- .../render/hydra/scene_delegate/instancer.h | 4 +- 2 files changed, 49 insertions(+), 37 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index be7ba5f0b5c8..eb4ad80f4803 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -36,7 +36,7 @@ bool InstancerData::is_supported(Object *object) void InstancerData::init() { ID_LOG(2, ""); - set_instances(); + write_instances(); } void InstancerData::insert() @@ -68,7 +68,7 @@ void InstancerData::update() (object->data && ((ID *)object->data)->recalc & ID_RECALC_GEOMETRY) || id->recalc & ID_RECALC_TRANSFORM) { - set_instances(); + write_instances(); scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( prim_id, pxr::HdChangeTracker::AllDirty); } @@ -109,9 +109,9 @@ bool InstancerData::update_visibility() pxr::GfMatrix4d InstancerData::get_transform(pxr::SdfPath const &id) const { - auto l_it = light_instances_.find(id.GetParentPath()); - if (l_it != light_instances_.end()) { - return l_it->second.transforms[light_prim_id_index(id)]; + LightInstance *l_inst = light_instance(id); + if (l_inst) { + return l_inst->transforms[light_prim_id_index(id)]; } /* Mesh instance transform must be identity */ @@ -131,18 +131,18 @@ pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors( pxr::VtIntArray InstancerData::indices(pxr::SdfPath const &id) const { - return mesh_instances_.find(id.GetParentPath())->second.indices; + return mesh_instance(id)->indices; } ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const { - auto m_it = mesh_instances_.find(id.GetParentPath()); - if (m_it != mesh_instances_.end()) { - return m_it->second.data.get(); + MeshInstance *m_inst = mesh_instance(id); + if (m_inst) { + return m_inst->data.get(); } - auto l_it = light_instances_.find(id.GetParentPath()); - if (l_it != light_instances_.end()) { - return l_it->second.data.get(); + LightInstance *l_inst = light_instance(id); + if (l_inst) { + return l_inst->data.get(); } return nullptr; } @@ -161,25 +161,25 @@ pxr::SdfPathVector InstancerData::prototypes() const void InstancerData::check_update(Object *object) { pxr::SdfPath path = object_prim_id(object); - auto m_it = mesh_instances_.find(path); - if (m_it != mesh_instances_.end()) { - m_it->second.data->update(); + MeshInstance *m_inst = mesh_instance(path); + if (m_inst) { + m_inst->data->update(); - if (m_it->second.data->id->recalc & ID_RECALC_TRANSFORM) { - set_instances(); + if (m_inst->data->id->recalc & ID_RECALC_TRANSFORM) { + write_instances(); scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( prim_id, pxr::HdChangeTracker::AllDirty); } return; } - auto l_it = light_instances_.find(path); - if (l_it != light_instances_.end()) { - Object *obj = (Object *)l_it->second.data->id; + LightInstance *l_inst = light_instance(path); + if (l_inst) { + Object *obj = (Object *)l_inst->data->id; if (obj->id.recalc & (ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY) || ((ID *)obj->data)->recalc & ID_RECALC_GEOMETRY) { - set_instances(); + write_instances(); } return; } @@ -198,7 +198,7 @@ void InstancerData::check_remove(std::set &available_objects) ret = true; } if (ret) { - set_instances(); + write_instances(); scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( prim_id, pxr::HdChangeTracker::AllDirty); } @@ -224,7 +224,7 @@ void InstancerData::available_materials(std::set &paths) const void InstancerData::update_as_parent() { - set_instances(); + write_instances(); scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( prim_id, pxr::HdChangeTracker::AllDirty); } @@ -258,7 +258,7 @@ int InstancerData::light_prim_id_index(pxr::SdfPath const &id) const return index; } -void InstancerData::set_instances() +void InstancerData::write_instances() { mesh_transforms_.clear(); for (auto &it : mesh_instances_) { @@ -278,31 +278,23 @@ void InstancerData::set_instances() pxr::SdfPath p_id = object_prim_id(ob); if (ob->type == OB_LAMP) { - LightInstance *inst; - auto it = light_instances_.find(p_id); - if (it == light_instances_.end()) { + LightInstance *inst = light_instance(p_id); + if (!inst) { inst = &light_instances_[p_id]; inst->data = std::make_unique(scene_delegate_, ob, p_id); inst->data->init(); } - else { - inst = &it->second; - } ID_LOG(2, "Light %s %d", inst->data->id->name, inst->transforms.size()); inst->transforms.push_back(gf_matrix_from_transform(dupli->mat)); } else { - MeshInstance *inst; - auto it = mesh_instances_.find(p_id); - if (it == mesh_instances_.end()) { + MeshInstance *inst = mesh_instance(p_id); + if (!inst) { inst = &mesh_instances_[p_id]; inst->data = std::make_unique(scene_delegate_, ob, p_id); inst->data->init(); inst->data->insert(); } - else { - inst = &it->second; - } ID_LOG(2, "Mesh %s %d", inst->data->id->name, mesh_transforms_.size()); inst->indices.push_back(mesh_transforms_.size()); mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat)); @@ -385,4 +377,22 @@ void InstancerData::update_light_instance(LightInstance &inst) } } +InstancerData::MeshInstance *InstancerData::mesh_instance(pxr::SdfPath const &id) const +{ + auto it = mesh_instances_.find(id.GetPathElementCount() == 4 ? id.GetParentPath() : id); + if (it == mesh_instances_.end()) { + return nullptr; + } + return const_cast(&it->second); +} + +InstancerData::LightInstance *InstancerData::light_instance(pxr::SdfPath const &id) const +{ + auto it = light_instances_.find(id.GetPathElementCount() == 4 ? id.GetParentPath() : id); + if (it == light_instances_.end()) { + return nullptr; + } + return const_cast(&it->second); +} + } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/scene_delegate/instancer.h b/source/blender/render/hydra/scene_delegate/instancer.h index d0454903abf8..1dfb1e98c4b8 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -49,8 +49,10 @@ class InstancerData : public ObjectData { pxr::SdfPath object_prim_id(Object *object) const; pxr::SdfPath light_prim_id(LightInstance const &inst, int index) const; int light_prim_id_index(pxr::SdfPath const &id) const; - void set_instances(); + void write_instances(); void update_light_instance(LightInstance &inst); + MeshInstance *mesh_instance(pxr::SdfPath const &id) const; + LightInstance *light_instance(pxr::SdfPath const &id) const; pxr::TfHashMap mesh_instances_; pxr::TfHashMap light_instances_; -- 2.30.2 From dff70f311ea629480c067c299fe7d1298e94aa5e Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sat, 20 May 2023 22:08:30 +0300 Subject: [PATCH 09/10] Fixed visibility of instance submeshes --- source/blender/render/hydra/scene_delegate/instancer.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index eb4ad80f4803..1a60741bb1b5 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -92,8 +92,9 @@ bool InstancerData::update_visibility() change_tracker.MarkInstancerDirty(prim_id, pxr::HdChangeTracker::DirtyVisibility); for (auto &it : mesh_instances_) { it.second.data->visible = visible; - change_tracker.MarkRprimDirty(it.second.data->prim_id, - pxr::HdChangeTracker::DirtyVisibility); + for (auto &p : it.second.data->submesh_paths()) { + change_tracker.MarkRprimDirty(p, pxr::HdChangeTracker::DirtyVisibility); + } } char name[16]; for (auto &it : light_instances_) { -- 2.30.2 From 78c001a396a802bec225addf50d3e936ca405e83 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Mon, 22 May 2023 21:43:54 +0300 Subject: [PATCH 10/10] Fix review comment --- .../render/hydra/scene_delegate/blender_scene_delegate.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc index 23f7ee906a51..a424b54e11e1 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -244,7 +244,7 @@ pxr::SdfPath BlenderSceneDelegate::world_prim_id() const ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id) const { - pxr::SdfPath p_id = (id.GetName().find("SM_", 0) == 0) ? id.GetParentPath() : id; + pxr::SdfPath p_id = (id.GetName().find("SM_") == 0) ? id.GetParentPath() : id; auto it = objects_.find(p_id); if (it != objects_.end()) { return it->second.get(); -- 2.30.2