From 4f4a7e4278dec00a6ab4f53728aff4236b0acefb Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 28 Apr 2023 10:25:01 +0300 Subject: [PATCH 01/17] Fix instances update when parent object is changed. Fixed transform for instance object. Added check of parent object change. --- .../hydra/scene_delegate/blender_scene_delegate.cc | 9 +++++++++ .../hydra/scene_delegate/blender_scene_delegate.h | 1 + .../blender/render/hydra/scene_delegate/instancer.cc | 11 ++++++++--- .../blender/render/hydra/scene_delegate/instancer.h | 1 + source/blender/render/hydra/scene_delegate/mesh.cc | 10 +++++++++- source/blender/render/hydra/scene_delegate/object.cc | 5 ++++- source/blender/render/hydra/scene_delegate/object.h | 4 +++- 7 files changed, 35 insertions(+), 6 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 b1a67394e5e7..22a2b3d1c697 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -307,6 +307,15 @@ void BlenderSceneDelegate::update_instancers(Object *object) i_data->update_visibility(); } +void BlenderSceneDelegate::update_instancer_as_parent(Object *object) +{ + pxr::SdfPath id = instancer_prim_id(object); + InstancerData *i_data = instancer_data(id); + if (i_data) { + i_data->update_as_parent(); + } +} + void BlenderSceneDelegate::update_world() { World *world = scene->world; diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h index 9e0b2f6e7c81..ad3621cd856f 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h @@ -74,6 +74,7 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate { void update_objects(Object *object); void update_instancers(Object *object); + void update_instancer_as_parent(Object *object); void update_world(); void check_updates(); void add_new_objects(); diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index b05a12bdb604..d87e5e7a5625 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -51,9 +51,6 @@ void InstancerData::insert() { ID_LOG(2, ""); scene_delegate_->GetRenderIndex().InsertInstancer(scene_delegate_, prim_id); - for (auto &it : instances_) { - it.second.obj_data->insert(); - } } void InstancerData::remove() @@ -149,6 +146,7 @@ void InstancerData::check_update(Object *object) } ObjectData *obj_data = it->second.obj_data.get(); obj_data->update(); + obj_data->transform = pxr::GfMatrix4d(1.0); pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; if (object->id.recalc & ID_RECALC_TRANSFORM) { @@ -189,6 +187,13 @@ void InstancerData::available_materials(std::set &paths) const } } +void InstancerData::update_as_parent() +{ + set_instances(); + scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( + prim_id, pxr::HdChangeTracker::AllDirty); +} + pxr::SdfPath InstancerData::object_prim_id(Object *object) const { /* Making id of object in form like _ */ diff --git a/source/blender/render/hydra/scene_delegate/instancer.h b/source/blender/render/hydra/scene_delegate/instancer.h index a4cf9f7bf534..02affd283958 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -38,6 +38,7 @@ class InstancerData : public ObjectData { void check_update(Object *object); void check_remove(std::set &available_objects); void available_materials(std::set &paths) const; + void update_as_parent(); private: pxr::SdfPath object_prim_id(Object *object) const; diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index c2797a05ae3c..cbaf4e9efa5f 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -65,8 +65,16 @@ void MeshData::remove() void MeshData::update() { - pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; Object *object = (Object *)id; + if ((id->recalc & ID_RECALC_TRANSFORM) && parent_ != object->parent) { + /* parent was changed */ + parent_ = object->parent; + if (parent_) { + scene_delegate_->update_instancer_as_parent(parent_); + } + } + + pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) { init(); bits = pxr::HdChangeTracker::AllDirty; diff --git a/source/blender/render/hydra/scene_delegate/object.cc b/source/blender/render/hydra/scene_delegate/object.cc index 658960dcdce5..a3dbd414f642 100644 --- a/source/blender/render/hydra/scene_delegate/object.cc +++ b/source/blender/render/hydra/scene_delegate/object.cc @@ -13,7 +13,10 @@ namespace blender::render::hydra { ObjectData::ObjectData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id) - : IdData(scene_delegate, (ID *)object, prim_id), transform(pxr::GfMatrix4d(1.0)), visible(true) + : IdData(scene_delegate, (ID *)object, prim_id), + transform(pxr::GfMatrix4d(1.0)), + visible(true), + parent_(object->parent) { } diff --git a/source/blender/render/hydra/scene_delegate/object.h b/source/blender/render/hydra/scene_delegate/object.h index b0a7371e27a9..911a19a8b0f4 100644 --- a/source/blender/render/hydra/scene_delegate/object.h +++ b/source/blender/render/hydra/scene_delegate/object.h @@ -29,7 +29,9 @@ class ObjectData : public IdData { bool visible; protected: - void write_transform(); + virtual void write_transform(); + + Object *parent_; }; using ObjectDataMap = -- 2.30.2 From 73aff3e5e0b731d8b4fb71e952327e89e1414cf7 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Mon, 1 May 2023 07:55:19 +0300 Subject: [PATCH 02/17] Improved update corresponded instancer as parent --- .../hydra/scene_delegate/blender_scene_delegate.cc | 9 --------- .../render/hydra/scene_delegate/blender_scene_delegate.h | 3 +-- source/blender/render/hydra/scene_delegate/mesh.cc | 8 ++++++-- 3 files changed, 7 insertions(+), 13 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 22a2b3d1c697..b1a67394e5e7 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -307,15 +307,6 @@ void BlenderSceneDelegate::update_instancers(Object *object) i_data->update_visibility(); } -void BlenderSceneDelegate::update_instancer_as_parent(Object *object) -{ - pxr::SdfPath id = instancer_prim_id(object); - InstancerData *i_data = instancer_data(id); - if (i_data) { - i_data->update_as_parent(); - } -} - void BlenderSceneDelegate::update_world() { World *world = scene->world; diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h index ad3621cd856f..e542a3e7d11b 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h @@ -21,7 +21,7 @@ namespace blender::render::hydra { extern struct CLG_LogRef *LOG_RENDER_HYDRA_SCENE; /* BSD - Blender Scene Delegate */ class BlenderSceneDelegate : public pxr::HdSceneDelegate { - friend MeshData; /* has access to materials_*/ + friend MeshData; /* has access to materials and instances */ public: enum class EngineType { VIEWPORT = 1, FINAL, PREVIEW }; @@ -74,7 +74,6 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate { void update_objects(Object *object); void update_instancers(Object *object); - void update_instancer_as_parent(Object *object); void update_world(); void check_updates(); void add_new_objects(); diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index cbaf4e9efa5f..257d2aa6100d 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -66,11 +66,15 @@ void MeshData::remove() void MeshData::update() { Object *object = (Object *)id; - if ((id->recalc & ID_RECALC_TRANSFORM) && parent_ != object->parent) { + if (parent_ != object->parent) { /* parent was changed */ parent_ = object->parent; if (parent_) { - scene_delegate_->update_instancer_as_parent(parent_); + pxr::SdfPath i_id = scene_delegate_->instancer_prim_id(parent_); + InstancerData *i_data = scene_delegate_->instancer_data(i_id); + if (i_data) { + i_data->update_as_parent(); + } } } -- 2.30.2 From 020305698f22a07a75a7c0b739a1e00a18b53cd8 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Mon, 1 May 2023 08:22:49 +0300 Subject: [PATCH 03/17] Fixed update parent in several hierarchy. Moved parent_ to MeshData --- source/blender/render/hydra/scene_delegate/mesh.cc | 10 ++++++---- source/blender/render/hydra/scene_delegate/mesh.h | 3 ++- source/blender/render/hydra/scene_delegate/object.cc | 5 +---- source/blender/render/hydra/scene_delegate/object.h | 4 +--- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index 257d2aa6100d..7c9063288668 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -17,7 +17,7 @@ namespace blender::render::hydra { MeshData::MeshData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id) - : ObjectData(scene_delegate, object, prim_id) + : ObjectData(scene_delegate, object, prim_id), parent_(object->parent) { } @@ -67,13 +67,15 @@ void MeshData::update() { Object *object = (Object *)id; if (parent_ != object->parent) { - /* parent was changed */ parent_ = object->parent; - if (parent_) { - pxr::SdfPath i_id = scene_delegate_->instancer_prim_id(parent_); + + /* Looking for corresponded instancer and update it as parent */ + for (Object *ob = parent_; ob != nullptr; ob = ob->parent) { + pxr::SdfPath i_id = scene_delegate_->instancer_prim_id(ob); InstancerData *i_data = scene_delegate_->instancer_data(i_id); if (i_data) { i_data->update_as_parent(); + break; } } } diff --git a/source/blender/render/hydra/scene_delegate/mesh.h b/source/blender/render/hydra/scene_delegate/mesh.h index 459411bc6a52..8d551a14f119 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.h +++ b/source/blender/render/hydra/scene_delegate/mesh.h @@ -29,7 +29,7 @@ class MeshData : public ObjectData { pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const; pxr::SdfPath material_id() const; - protected: + private: void write_mesh(Mesh *mesh); void write_material(); void write_uv_maps(Mesh *mesh); @@ -43,6 +43,7 @@ class MeshData : public ObjectData { pxr::VtMatrix4dArray instances_; MaterialData *mat_data_ = nullptr; + Object *parent_; }; } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/scene_delegate/object.cc b/source/blender/render/hydra/scene_delegate/object.cc index a3dbd414f642..658960dcdce5 100644 --- a/source/blender/render/hydra/scene_delegate/object.cc +++ b/source/blender/render/hydra/scene_delegate/object.cc @@ -13,10 +13,7 @@ namespace blender::render::hydra { ObjectData::ObjectData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id) - : IdData(scene_delegate, (ID *)object, prim_id), - transform(pxr::GfMatrix4d(1.0)), - visible(true), - parent_(object->parent) + : IdData(scene_delegate, (ID *)object, prim_id), transform(pxr::GfMatrix4d(1.0)), visible(true) { } diff --git a/source/blender/render/hydra/scene_delegate/object.h b/source/blender/render/hydra/scene_delegate/object.h index 911a19a8b0f4..b0a7371e27a9 100644 --- a/source/blender/render/hydra/scene_delegate/object.h +++ b/source/blender/render/hydra/scene_delegate/object.h @@ -29,9 +29,7 @@ class ObjectData : public IdData { bool visible; protected: - virtual void write_transform(); - - Object *parent_; + void write_transform(); }; using ObjectDataMap = -- 2.30.2 From 364cc1e6f10103d49ebbb74f36064aa616a25cda Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Mon, 1 May 2023 12:36:11 +0300 Subject: [PATCH 04/17] Preparations --- .../render/hydra/scene_delegate/instancer.cc | 42 +++++++++---------- .../render/hydra/scene_delegate/instancer.h | 6 ++- .../render/hydra/scene_delegate/mesh.cc | 3 -- .../render/hydra/scene_delegate/mesh.h | 1 - 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index d87e5e7a5625..cde68fa5df09 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -56,7 +56,7 @@ void InstancerData::insert() void InstancerData::remove() { CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText()); - for (auto &it : instances_) { + for (auto &it : mesh_instances_) { it.second.obj_data->remove(); } scene_delegate_->GetRenderIndex().RemoveInstancer(prim_id); @@ -87,7 +87,7 @@ pxr::VtValue InstancerData::get_data(pxr::TfToken const &key) const ID_LOG(3, "%s", key.GetText()); pxr::VtValue ret; if (key == pxr::HdInstancerTokens->instanceTransform) { - ret = transforms_; + ret = mesh_transforms_; } return ret; } @@ -98,7 +98,7 @@ bool InstancerData::update_visibility() if (ret) { scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( prim_id, pxr::HdChangeTracker::DirtyVisibility); - for (auto &it : instances_) { + for (auto &it : mesh_instances_) { it.second.obj_data->visible = visible; scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty( it.second.obj_data->prim_id, pxr::HdChangeTracker::DirtyVisibility); @@ -120,18 +120,18 @@ pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors( pxr::VtIntArray InstancerData::indices(pxr::SdfPath const &id) const { - return instances_.find(id)->second.indices; + return mesh_instances_.find(id)->second.indices; } ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const { - return instances_.find(id)->second.obj_data.get(); + return mesh_instances_.find(id)->second.obj_data.get(); } pxr::SdfPathVector InstancerData::prototypes() const { pxr::SdfPathVector paths; - for (auto &it : instances_) { + for (auto &it : mesh_instances_) { paths.push_back(it.first); } return paths; @@ -140,8 +140,8 @@ pxr::SdfPathVector InstancerData::prototypes() const void InstancerData::check_update(Object *object) { pxr::SdfPath path = object_prim_id(object); - auto it = instances_.find(path); - if (it == instances_.end()) { + auto it = mesh_instances_.find(path); + if (it == mesh_instances_.end()) { return; } ObjectData *obj_data = it->second.obj_data.get(); @@ -161,13 +161,13 @@ void InstancerData::check_update(Object *object) void InstancerData::check_remove(std::set &available_objects) { bool ret = false; - for (auto it = instances_.begin(); it != instances_.end(); ++it) { + for (auto it = mesh_instances_.begin(); it != mesh_instances_.end(); ++it) { if (available_objects.find(it->first.GetName()) != available_objects.end()) { continue; } it->second.obj_data->remove(); - instances_.erase(it); - it = instances_.begin(); + mesh_instances_.erase(it); + it = mesh_instances_.begin(); ret = true; } if (ret) { @@ -179,7 +179,7 @@ void InstancerData::check_remove(std::set &available_objects) void InstancerData::available_materials(std::set &paths) const { - for (auto &it : instances_) { + for (auto &it : mesh_instances_) { pxr::SdfPath mat_id = ((MeshData *)it.second.obj_data.get())->material_id(); if (!mat_id.IsEmpty()) { paths.insert(mat_id); @@ -204,8 +204,8 @@ pxr::SdfPath InstancerData::object_prim_id(Object *object) const void InstancerData::set_instances() { - transforms_.clear(); - for (auto &it : instances_) { + mesh_transforms_.clear(); + for (auto &it : mesh_instances_) { it.second.indices.clear(); } int index = 0; @@ -216,9 +216,9 @@ void InstancerData::set_instances() scene_delegate_->depsgraph, scene_delegate_->scene, (Object *)id); LISTBASE_FOREACH (DupliObject *, dupli, lb) { p_id = object_prim_id(dupli->ob); - auto it = instances_.find(p_id); - if (it == instances_.end()) { - inst = &instances_[p_id]; + auto it = mesh_instances_.find(p_id); + if (it == mesh_instances_.end()) { + inst = &mesh_instances_[p_id]; if (!is_supported(dupli->ob)) { continue; } @@ -230,7 +230,7 @@ void InstancerData::set_instances() else { inst = &it->second; } - transforms_.push_back(gf_matrix_from_transform(dupli->mat)); + mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat)); inst->indices.push_back(index); ID_LOG(2, "%s %d", inst->obj_data->id->name, index); ++index; @@ -238,13 +238,13 @@ void InstancerData::set_instances() free_object_duplilist(lb); /* Remove intances without indices */ - for (auto it = instances_.begin(); it != instances_.end(); ++it) { + for (auto it = mesh_instances_.begin(); it != mesh_instances_.end(); ++it) { if (!it->second.indices.empty()) { continue; } it->second.obj_data->remove(); - instances_.erase(it); - it = instances_.begin(); + mesh_instances_.erase(it); + it = mesh_instances_.begin(); } } diff --git a/source/blender/render/hydra/scene_delegate/instancer.h b/source/blender/render/hydra/scene_delegate/instancer.h index 02affd283958..7fa9a4f30f2f 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -44,8 +44,10 @@ class InstancerData : public ObjectData { pxr::SdfPath object_prim_id(Object *object) const; void set_instances(); - pxr::TfHashMap instances_; - pxr::VtMatrix4dArray transforms_; + pxr::TfHashMap mesh_instances_; + pxr::TfHashMap light_instances_; + pxr::VtMatrix4dArray mesh_transforms_; + pxr::VtMatrix4dArray light_transforms_; }; using InstancerDataMap = diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index 7c9063288668..cd250d1e615e 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -126,9 +126,6 @@ pxr::VtValue MeshData::get_data(pxr::TfToken const &key) const else if (key == pxr::HdPrimvarRoleTokens->textureCoordinate) { ret = uvs_; } - else if (key == pxr::HdInstancerTokens->instanceTransform) { - ret = instances_; - } return ret; } diff --git a/source/blender/render/hydra/scene_delegate/mesh.h b/source/blender/render/hydra/scene_delegate/mesh.h index 8d551a14f119..e4fe1ab0a56b 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.h +++ b/source/blender/render/hydra/scene_delegate/mesh.h @@ -40,7 +40,6 @@ class MeshData : public ObjectData { pxr::VtVec3fArray vertices_; pxr::VtVec2fArray uvs_; pxr::VtVec3fArray normals_; - pxr::VtMatrix4dArray instances_; MaterialData *mat_data_ = nullptr; Object *parent_; -- 2.30.2 From 33efcca4f6e8b947fe10ee737b56f69b249041b9 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Mon, 1 May 2023 16:01:23 +0300 Subject: [PATCH 05/17] Further preparations --- .../scene_delegate/blender_scene_delegate.cc | 18 +++++++++ .../scene_delegate/blender_scene_delegate.h | 1 + .../render/hydra/scene_delegate/instancer.cc | 38 +++++++++++++------ .../render/hydra/scene_delegate/instancer.h | 1 + 4 files changed, 47 insertions(+), 11 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 b1a67394e5e7..1fc2bdaea047 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -32,6 +32,12 @@ pxr::HdMeshTopology BlenderSceneDelegate::GetMeshTopology(pxr::SdfPath const &id pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id) { CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText()); + + pxr::SdfPath i_id = instancer_prim_id(id); + if (!i_id.IsEmpty()) { + InstancerData *i_data = instancer_data(i_id); + return i_data->get_transform(id); + } ObjectData *obj_data = object_data(id); if (obj_data) { return obj_data->transform; @@ -212,6 +218,18 @@ pxr::SdfPath BlenderSceneDelegate::instancer_prim_id(Object *object) const return prim_id((ID *)object, "I"); } +pxr::SdfPath BlenderSceneDelegate::instancer_prim_id(pxr::SdfPath const &child_id) const +{ + int n = child_id.GetPathElementCount(); + if (n == 3) { + return child_id.GetParentPath(); + } + if (n == 4) { + return child_id.GetParentPath().GetParentPath(); + } + return pxr::SdfPath(); +} + pxr::SdfPath BlenderSceneDelegate::world_prim_id() const { return GetDelegateID().AppendElementString("World"); diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h index e542a3e7d11b..b7d002dfeab9 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h @@ -64,6 +64,7 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate { pxr::SdfPath object_prim_id(Object *object) const; pxr::SdfPath material_prim_id(Material *mat) const; pxr::SdfPath instancer_prim_id(Object *object) const; + pxr::SdfPath instancer_prim_id(pxr::SdfPath const &child_id) const; pxr::SdfPath world_prim_id() const; ObjectData *object_data(pxr::SdfPath const &id) const; diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index cde68fa5df09..a2dc8523f1b4 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -107,6 +107,11 @@ bool InstancerData::update_visibility() return ret; } +pxr::GfMatrix4d InstancerData::get_transform(pxr::SdfPath const &id) const +{ + return pxr::GfMatrix4d(1.0); +} + pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors( pxr::HdInterpolation interpolation) const { @@ -146,7 +151,6 @@ void InstancerData::check_update(Object *object) } ObjectData *obj_data = it->second.obj_data.get(); obj_data->update(); - obj_data->transform = pxr::GfMatrix4d(1.0); pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; if (object->id.recalc & ID_RECALC_TRANSFORM) { @@ -211,24 +215,36 @@ void InstancerData::set_instances() int index = 0; Instance *inst; pxr::SdfPath p_id; + Object *ob; ListBase *lb = object_duplilist( scene_delegate_->depsgraph, scene_delegate_->scene, (Object *)id); LISTBASE_FOREACH (DupliObject *, dupli, lb) { + ob = dupli->ob; + if (!is_supported(ob)) { + continue; + } p_id = object_prim_id(dupli->ob); - auto it = mesh_instances_.find(p_id); - if (it == mesh_instances_.end()) { - inst = &mesh_instances_[p_id]; - if (!is_supported(dupli->ob)) { - continue; + if (ob->type == OB_LAMP) { + auto it = mesh_instances_.find(p_id); + if (it == mesh_instances_.end()) { + inst = &mesh_instances_[p_id]; + inst->obj_data = std::make_unique(scene_delegate_, ob, p_id); + inst->obj_data->init(); + } + else { + inst = &it->second; } - inst->obj_data = ObjectData::create(scene_delegate_, dupli->ob, p_id); - - /* Instance's transform should be identity */ - inst->obj_data->transform = pxr::GfMatrix4d(1.0); } else { - inst = &it->second; + auto it = mesh_instances_.find(p_id); + if (it == mesh_instances_.end()) { + inst = &mesh_instances_[p_id]; + inst->obj_data = ObjectData::create(scene_delegate_, ob, p_id); + } + else { + inst = &it->second; + } } mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat)); inst->indices.push_back(index); diff --git a/source/blender/render/hydra/scene_delegate/instancer.h b/source/blender/render/hydra/scene_delegate/instancer.h index 7fa9a4f30f2f..243a5a93e329 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -31,6 +31,7 @@ class InstancerData : public ObjectData { pxr::VtValue get_data(pxr::TfToken const &key) const override; bool update_visibility() override; + pxr::GfMatrix4d get_transform(pxr::SdfPath const &id) const; pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const; pxr::VtIntArray indices(pxr::SdfPath const &id) const; ObjectData *object_data(pxr::SdfPath const &id) const; -- 2.30.2 From 946f3a2ae4110af6d472a72897b44e9ee77df7fc Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Mon, 1 May 2023 17:35:45 +0300 Subject: [PATCH 06/17] Code improvements --- .../scene_delegate/blender_scene_delegate.cc | 38 ++++++++++--------- .../scene_delegate/blender_scene_delegate.h | 3 +- .../render/hydra/scene_delegate/instancer.cc | 1 + .../render/hydra/scene_delegate/mesh.cc | 4 +- 4 files changed, 24 insertions(+), 22 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 1fc2bdaea047..99f3ab0a36c8 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -33,11 +33,11 @@ pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id) { CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText()); - pxr::SdfPath i_id = instancer_prim_id(id); - if (!i_id.IsEmpty()) { - InstancerData *i_data = instancer_data(i_id); + InstancerData *i_data = instancer_data(id, true); + if (i_data) { return i_data->get_transform(id); } + ObjectData *obj_data = object_data(id); if (obj_data) { return obj_data->transform; @@ -218,18 +218,6 @@ pxr::SdfPath BlenderSceneDelegate::instancer_prim_id(Object *object) const return prim_id((ID *)object, "I"); } -pxr::SdfPath BlenderSceneDelegate::instancer_prim_id(pxr::SdfPath const &child_id) const -{ - int n = child_id.GetPathElementCount(); - if (n == 3) { - return child_id.GetParentPath(); - } - if (n == 4) { - return child_id.GetParentPath().GetParentPath(); - } - return pxr::SdfPath(); -} - pxr::SdfPath BlenderSceneDelegate::world_prim_id() const { return GetDelegateID().AppendElementString("World"); @@ -241,7 +229,7 @@ ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id) const if (it != objects_.end()) { return it->second.get(); } - InstancerData *i_data = instancer_data(id.GetParentPath()); + InstancerData *i_data = instancer_data(id, true); if (i_data) { return i_data->object_data(id); } @@ -267,9 +255,23 @@ MaterialData *BlenderSceneDelegate::material_data(pxr::SdfPath const &id) const return it->second.get(); } -InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id) const +InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id, bool child_id) const { - auto it = instancers_.find(id); + pxr::SdfPath p_id; + if (child_id) { + int n = id.GetPathElementCount(); + if (n == 3) { + p_id = id.GetParentPath(); + } + else if (n == 4) { + p_id = id.GetParentPath().GetParentPath(); + } + } + else { + p_id = id; + } + + auto it = instancers_.find(p_id); if (it != instancers_.end()) { return it->second.get(); } diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h index b7d002dfeab9..50cae4e36759 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h @@ -64,14 +64,13 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate { pxr::SdfPath object_prim_id(Object *object) const; pxr::SdfPath material_prim_id(Material *mat) const; pxr::SdfPath instancer_prim_id(Object *object) const; - pxr::SdfPath instancer_prim_id(pxr::SdfPath const &child_id) const; pxr::SdfPath world_prim_id() const; ObjectData *object_data(pxr::SdfPath const &id) const; MeshData *mesh_data(pxr::SdfPath const &id) const; LightData *light_data(pxr::SdfPath const &id) const; MaterialData *material_data(pxr::SdfPath const &id) const; - InstancerData *instancer_data(pxr::SdfPath const &id) const; + InstancerData *instancer_data(pxr::SdfPath const &id, bool child_id = false) const; void update_objects(Object *object); void update_instancers(Object *object); diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index a2dc8523f1b4..2e03e84602bb 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -225,6 +225,7 @@ void InstancerData::set_instances() continue; } p_id = object_prim_id(dupli->ob); + if (ob->type == OB_LAMP) { auto it = mesh_instances_.find(p_id); if (it == mesh_instances_.end()) { diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index cd250d1e615e..8545ca7824a6 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -71,8 +71,8 @@ void MeshData::update() /* Looking for corresponded instancer and update it as parent */ for (Object *ob = parent_; ob != nullptr; ob = ob->parent) { - pxr::SdfPath i_id = scene_delegate_->instancer_prim_id(ob); - InstancerData *i_data = scene_delegate_->instancer_data(i_id); + InstancerData *i_data = scene_delegate_->instancer_data( + scene_delegate_->instancer_prim_id(ob)); if (i_data) { i_data->update_as_parent(); break; -- 2.30.2 From 61f37c8d6acdd186fb8366ff23aefc407f538a5f Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Mon, 1 May 2023 19:37:10 +0300 Subject: [PATCH 07/17] Code improvements --- .../scene_delegate/blender_scene_delegate.cc | 18 ++++------------- .../render/hydra/scene_delegate/instancer.cc | 20 ++++++++++--------- 2 files changed, 15 insertions(+), 23 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 99f3ab0a36c8..af55fcf1ab17 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -32,49 +32,42 @@ pxr::HdMeshTopology BlenderSceneDelegate::GetMeshTopology(pxr::SdfPath const &id pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id) { CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText()); - InstancerData *i_data = instancer_data(id, true); if (i_data) { return i_data->get_transform(id); } - ObjectData *obj_data = object_data(id); if (obj_data) { return obj_data->transform; } - if (id == world_prim_id()) { return world_data_->transform; } - return pxr::GfMatrix4d(); } 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()); - ObjectData *obj_data = object_data(id); if (obj_data) { return obj_data->get_data(key); } - MaterialData *mat_data = material_data(id); if (mat_data) { return mat_data->get_data(key); } - InstancerData *i_data = instancer_data(id); if (i_data) { return i_data->get_data(key); } - return pxr::VtValue(); } pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id, pxr::TfToken const &key) { + CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s, %s", id.GetText(), key.GetText()); LightData *l_data = light_data(id); if (l_data) { return l_data->get_data(key); @@ -89,27 +82,26 @@ pxr::HdPrimvarDescriptorVector BlenderSceneDelegate::GetPrimvarDescriptors( pxr::SdfPath const &id, pxr::HdInterpolation interpolation) { CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s, %d", id.GetText(), interpolation); - MeshData *m_data = mesh_data(id); if (m_data) { return m_data->primvar_descriptors(interpolation); } - InstancerData *i_data = instancer_data(id); if (i_data) { return i_data->primvar_descriptors(interpolation); } - return pxr::HdPrimvarDescriptorVector(); } 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(); } pxr::VtValue BlenderSceneDelegate::GetMaterialResource(pxr::SdfPath const &id) { + CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText()); MaterialData *mat_data = material_data(id); if (mat_data) { return mat_data->get_material_resource(); @@ -119,10 +111,10 @@ pxr::VtValue BlenderSceneDelegate::GetMaterialResource(pxr::SdfPath const &id) bool BlenderSceneDelegate::GetVisible(pxr::SdfPath const &id) { + CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText()); if (id == world_prim_id()) { return true; } - return object_data(id)->visible; } @@ -181,11 +173,9 @@ void BlenderSceneDelegate::clear() for (auto &it : objects_) { it.second->remove(); } - for (auto &it : instancers_) { it.second->remove(); } - for (auto &it : materials_) { it.second->remove(); } diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index 2e03e84602bb..581b1d308bb1 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -212,7 +212,7 @@ void InstancerData::set_instances() for (auto &it : mesh_instances_) { it.second.indices.clear(); } - int index = 0; + int mesh_index = 0, light_index = 0; Instance *inst; pxr::SdfPath p_id; Object *ob; @@ -224,18 +224,20 @@ void InstancerData::set_instances() if (!is_supported(ob)) { continue; } - p_id = object_prim_id(dupli->ob); + p_id = object_prim_id(dupli->ob); if (ob->type == OB_LAMP) { - auto it = mesh_instances_.find(p_id); - if (it == mesh_instances_.end()) { - inst = &mesh_instances_[p_id]; + auto it = light_instances_.find(p_id); + if (it == light_instances_.end()) { + inst = &light_instances_[p_id]; inst->obj_data = std::make_unique(scene_delegate_, ob, p_id); inst->obj_data->init(); } else { inst = &it->second; } + mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat)); + inst->indices.push_back(mesh_index); } else { auto it = mesh_instances_.find(p_id); @@ -246,11 +248,11 @@ void InstancerData::set_instances() else { inst = &it->second; } + mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat)); + inst->indices.push_back(mesh_index); + ID_LOG(2, "%s %d", inst->obj_data->id->name, mesh_index); + ++mesh_index; } - mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat)); - inst->indices.push_back(index); - ID_LOG(2, "%s %d", inst->obj_data->id->name, index); - ++index; } free_object_duplilist(lb); -- 2.30.2 From 5cbf67c0f833849b0b86984a2efd59ebb67bbd42 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Tue, 2 May 2023 13:07:19 +0300 Subject: [PATCH 08/17] Continuing --- .../render/hydra/scene_delegate/instancer.cc | 42 ++++++++++++------- .../render/hydra/scene_delegate/instancer.h | 18 ++++++-- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index 581b1d308bb1..6152a35abc6d 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -8,6 +8,11 @@ namespace blender::render::hydra { +void InstancerData::LightInstance::update() +{ + +} + InstancerData::InstancerData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id) @@ -212,34 +217,35 @@ void InstancerData::set_instances() for (auto &it : mesh_instances_) { it.second.indices.clear(); } - int mesh_index = 0, light_index = 0; - Instance *inst; - pxr::SdfPath p_id; - Object *ob; + for (auto &it : light_instances_) { + it.second.transforms.clear(); + } ListBase *lb = object_duplilist( scene_delegate_->depsgraph, scene_delegate_->scene, (Object *)id); LISTBASE_FOREACH (DupliObject *, dupli, lb) { - ob = dupli->ob; + Object *ob = dupli->ob; if (!is_supported(ob)) { continue; } - p_id = object_prim_id(dupli->ob); + 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()) { inst = &light_instances_[p_id]; - inst->obj_data = std::make_unique(scene_delegate_, ob, p_id); - inst->obj_data->init(); + inst->data = std::make_unique(scene_delegate_, ob, p_id); + inst->data->init(); } else { inst = &it->second; } - mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat)); - inst->indices.push_back(mesh_index); + ID_LOG(2, "%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()) { inst = &mesh_instances_[p_id]; @@ -248,15 +254,14 @@ void InstancerData::set_instances() else { inst = &it->second; } + ID_LOG(2, "%s %d", inst->obj_data->id->name, mesh_transforms_.size()); + inst->indices.push_back(mesh_transforms_.size()); mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat)); - inst->indices.push_back(mesh_index); - ID_LOG(2, "%s %d", inst->obj_data->id->name, mesh_index); - ++mesh_index; } } free_object_duplilist(lb); - /* Remove intances without indices */ + /* Remove mesh intances without indices */ for (auto it = mesh_instances_.begin(); it != mesh_instances_.end(); ++it) { if (!it->second.indices.empty()) { continue; @@ -265,6 +270,15 @@ void InstancerData::set_instances() mesh_instances_.erase(it); it = mesh_instances_.begin(); } + + /* Update light intances and remove instances without transforms */ + for (auto it = light_instances_.begin(); it != light_instances_.end(); ++it) { + it->second.update(); + if (it->second.transforms.empty()) { + light_instances_.erase(it); + it = light_instances_.begin(); + } + } } } // 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 243a5a93e329..56e2624e0379 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -6,15 +6,26 @@ #include "BKE_duplilist.h" #include "mesh.h" +#include "light.h" namespace blender::render::hydra { class InstancerData : public ObjectData { - struct Instance { + struct MeshInstance { std::unique_ptr obj_data; pxr::VtIntArray indices; }; + struct LightInstance { + std::unique_ptr data; + pxr::VtMatrix4dArray transforms; + + void update(); + + private: + int count_ = 0; + }; + public: InstancerData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id); @@ -45,10 +56,9 @@ class InstancerData : public ObjectData { pxr::SdfPath object_prim_id(Object *object) const; void set_instances(); - pxr::TfHashMap mesh_instances_; - pxr::TfHashMap light_instances_; + pxr::TfHashMap mesh_instances_; + pxr::TfHashMap light_instances_; pxr::VtMatrix4dArray mesh_transforms_; - pxr::VtMatrix4dArray light_transforms_; }; using InstancerDataMap = -- 2.30.2 From 7b6e6bce20194ef65a1d1750a7da17013442000d Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Tue, 2 May 2023 19:45:00 +0300 Subject: [PATCH 09/17] Implementing LightInstance update --- .../render/hydra/scene_delegate/instancer.cc | 82 +++++++++++++++++-- .../render/hydra/scene_delegate/instancer.h | 7 +- .../render/hydra/scene_delegate/light.h | 4 + 3 files changed, 79 insertions(+), 14 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index 6152a35abc6d..3243759b67ec 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -2,17 +2,13 @@ * Copyright 2011-2022 Blender Foundation */ #include +#include #include "blender_scene_delegate.h" #include "instancer.h" namespace blender::render::hydra { -void InstancerData::LightInstance::update() -{ - -} - InstancerData::InstancerData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id) @@ -135,7 +131,15 @@ pxr::VtIntArray InstancerData::indices(pxr::SdfPath const &id) const ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const { - return mesh_instances_.find(id)->second.obj_data.get(); + auto m_it = mesh_instances_.find(id); + if (m_it != mesh_instances_.end()) { + return m_it->second.obj_data.get(); + } + auto l_it = light_instances_.find(id); + if (l_it != light_instances_.end()) { + return l_it->second.data.get(); + } + return nullptr; } pxr::SdfPathVector InstancerData::prototypes() const @@ -241,7 +245,7 @@ void InstancerData::set_instances() else { inst = &it->second; } - ID_LOG(2, "%s %d", inst->data->id->name, inst->transforms.size()); + ID_LOG(2, "Light %s %d", inst->data->id->name, inst->transforms.size()); inst->transforms.push_back(gf_matrix_from_transform(dupli->mat)); } else { @@ -254,7 +258,7 @@ void InstancerData::set_instances() else { inst = &it->second; } - ID_LOG(2, "%s %d", inst->obj_data->id->name, mesh_transforms_.size()); + ID_LOG(2, "Mesh %s %d", inst->obj_data->id->name, mesh_transforms_.size()); inst->indices.push_back(mesh_transforms_.size()); mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat)); } @@ -273,7 +277,7 @@ void InstancerData::set_instances() /* Update light intances and remove instances without transforms */ for (auto it = light_instances_.begin(); it != light_instances_.end(); ++it) { - it->second.update(); + update_light_instance(it->second); if (it->second.transforms.empty()) { light_instances_.erase(it); it = light_instances_.begin(); @@ -281,4 +285,64 @@ void InstancerData::set_instances() } } +void InstancerData::update_light_instance(LightInstance &inst) +{ + auto &render_index = scene_delegate_->GetRenderIndex(); + LightData &l_data = *inst.data; + + char name[16]; + int i; + pxr::SdfPath p; + + /* Remove old light instances */ + while (inst.count > inst.transforms.size()) { + --inst.count; + snprintf(name, 16, "L_%08x", inst.count); + p = l_data.prim_id.AppendElementString(name); + render_index.RemoveSprim(l_data.prim_type_, p); + ID_LOG(2, "Remove %s", p.GetText()); + } + + /* Update current light instances */ + if (inst.data->prim_type((Light *)((Object *)l_data.id)->data) != l_data.prim_type_) { + /* Recreate instances when prim_type was changed */ + for (i = 0; i < inst.count; ++i) { + snprintf(name, 16, "L_%08x", i); + p = l_data.prim_id.AppendElementString(name); + render_index.RemoveSprim(l_data.prim_type_, p); + ID_LOG(2, "Remove %s", p.GetText()); + } + inst.data->init(); + for (i = 0; i < inst.count; ++i) { + snprintf(name, 16, "L_%08x", i); + p = l_data.prim_id.AppendElementString(name); + render_index.InsertSprim(l_data.prim_type_, scene_delegate_, p); + ID_LOG(2, "Insert %s (%s)", p.GetText(), l_data.id->name); + } + } + else { + /* Update light instances*/ + pxr::HdDirtyBits bits = pxr::HdLight::DirtyTransform; + if (id->recalc & ID_RECALC_GEOMETRY) { + l_data.init(); + bits = pxr::HdLight::AllDirty; + } + for (i = 0; i < inst.count; ++i) { + snprintf(name, 16, "L_%08x", i); + p = l_data.prim_id.AppendElementString(name); + render_index.GetChangeTracker().MarkSprimDirty(p, bits); + ID_LOG(2, "Update %s (%s)", p.GetText(), l_data.id->name); + } + } + + /* Add new light instances */ + while (inst.count < inst.transforms.size()) { + snprintf(name, 16, "L_%08x", inst.count); + p = inst.data->prim_id.AppendElementString(name); + render_index.InsertSprim(l_data.prim_type_, scene_delegate_, p); + ID_LOG(2, "Insert %s (%s)", p.GetText(), l_data.id->name); + ++inst.count; + } +} + } // 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 56e2624e0379..f4387046bcc1 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -19,11 +19,7 @@ class InstancerData : public ObjectData { struct LightInstance { std::unique_ptr data; pxr::VtMatrix4dArray transforms; - - void update(); - - private: - int count_ = 0; + int count = 0; }; public: @@ -55,6 +51,7 @@ class InstancerData : public ObjectData { private: pxr::SdfPath object_prim_id(Object *object) const; void set_instances(); + void update_light_instance(LightInstance &inst); pxr::TfHashMap mesh_instances_; pxr::TfHashMap light_instances_; diff --git a/source/blender/render/hydra/scene_delegate/light.h b/source/blender/render/hydra/scene_delegate/light.h index 003f23997783..215b82c773c9 100644 --- a/source/blender/render/hydra/scene_delegate/light.h +++ b/source/blender/render/hydra/scene_delegate/light.h @@ -13,7 +13,11 @@ namespace blender::render::hydra { +class InstancerData; + class LightData : public ObjectData { + friend InstancerData; + public: LightData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id); -- 2.30.2 From 278f4d7175d8c51b5bb8c9e23d20a61eae6f2895 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Tue, 2 May 2023 21:02:27 +0300 Subject: [PATCH 10/17] Fixed getting light instances --- .../scene_delegate/blender_scene_delegate.cc | 4 +++ .../render/hydra/scene_delegate/instancer.cc | 36 +++++++++++++------ .../render/hydra/scene_delegate/instancer.h | 2 +- 3 files changed, 31 insertions(+), 11 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 af55fcf1ab17..10b5668ec80b 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -115,6 +115,10 @@ bool BlenderSceneDelegate::GetVisible(pxr::SdfPath const &id) if (id == world_prim_id()) { return true; } + InstancerData *i_data = instancer_data(id, true); + if (i_data) { + return i_data->visible; + } return object_data(id)->visible; } diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index 3243759b67ec..ebac2cbd9c07 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -34,6 +34,7 @@ bool InstancerData::is_supported(Object *object) case OB_FONT: case OB_CURVES_LEGACY: case OB_MBALL: + case OB_LAMP: return true; default: @@ -58,9 +59,14 @@ void InstancerData::remove() { CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText()); for (auto &it : mesh_instances_) { - it.second.obj_data->remove(); + it.second.data->remove(); } scene_delegate_->GetRenderIndex().RemoveInstancer(prim_id); + + for (auto &it : light_instances_) { + it.second.transforms.clear(); + update_light_instance(it.second); + } } void InstancerData::update() @@ -100,9 +106,9 @@ bool InstancerData::update_visibility() scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( prim_id, pxr::HdChangeTracker::DirtyVisibility); for (auto &it : mesh_instances_) { - it.second.obj_data->visible = visible; + it.second.data->visible = visible; scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty( - it.second.obj_data->prim_id, pxr::HdChangeTracker::DirtyVisibility); + it.second.data->prim_id, pxr::HdChangeTracker::DirtyVisibility); } } return ret; @@ -110,6 +116,14 @@ 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; + std::string name = id.GetName(); + int index; + sscanf_s(name.c_str(), "L_%x", &index); + return inst.transforms[index]; + } + return pxr::GfMatrix4d(1.0); } @@ -133,7 +147,7 @@ ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const { auto m_it = mesh_instances_.find(id); if (m_it != mesh_instances_.end()) { - return m_it->second.obj_data.get(); + return m_it->second.data.get(); } auto l_it = light_instances_.find(id); if (l_it != light_instances_.end()) { @@ -158,7 +172,7 @@ void InstancerData::check_update(Object *object) if (it == mesh_instances_.end()) { return; } - ObjectData *obj_data = it->second.obj_data.get(); + ObjectData *obj_data = it->second.data.get(); obj_data->update(); pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; @@ -178,7 +192,7 @@ void InstancerData::check_remove(std::set &available_objects) if (available_objects.find(it->first.GetName()) != available_objects.end()) { continue; } - it->second.obj_data->remove(); + it->second.data->remove(); mesh_instances_.erase(it); it = mesh_instances_.begin(); ret = true; @@ -193,7 +207,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.obj_data.get())->material_id(); + pxr::SdfPath mat_id = ((MeshData *)it.second.data.get())->material_id(); if (!mat_id.IsEmpty()) { paths.insert(mat_id); } @@ -253,12 +267,14 @@ void InstancerData::set_instances() auto it = mesh_instances_.find(p_id); if (it == mesh_instances_.end()) { inst = &mesh_instances_[p_id]; - inst->obj_data = ObjectData::create(scene_delegate_, ob, 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->obj_data->id->name, mesh_transforms_.size()); + 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)); } @@ -270,7 +286,7 @@ void InstancerData::set_instances() if (!it->second.indices.empty()) { continue; } - it->second.obj_data->remove(); + it->second.data->remove(); mesh_instances_.erase(it); it = mesh_instances_.begin(); } diff --git a/source/blender/render/hydra/scene_delegate/instancer.h b/source/blender/render/hydra/scene_delegate/instancer.h index f4387046bcc1..f05002dccae0 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -12,7 +12,7 @@ namespace blender::render::hydra { class InstancerData : public ObjectData { struct MeshInstance { - std::unique_ptr obj_data; + std::unique_ptr data; pxr::VtIntArray indices; }; -- 2.30.2 From 18fafb9f423e5792fddcbdb1a7e07be28199c61a Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Wed, 3 May 2023 09:32:33 +0300 Subject: [PATCH 11/17] Code improvements --- .../render/hydra/scene_delegate/instancer.cc | 50 ++++++++++++------- .../render/hydra/scene_delegate/instancer.h | 2 + 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index ebac2cbd9c07..47d7188bf840 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -103,12 +103,18 @@ bool InstancerData::update_visibility() { bool ret = ObjectData::update_visibility(); if (ret) { - scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( - prim_id, pxr::HdChangeTracker::DirtyVisibility); + auto &change_tracker = scene_delegate_->GetRenderIndex().GetChangeTracker(); + change_tracker.MarkInstancerDirty(prim_id, pxr::HdChangeTracker::DirtyVisibility); for (auto &it : mesh_instances_) { it.second.data->visible = visible; - scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty( - it.second.data->prim_id, pxr::HdChangeTracker::DirtyVisibility); + change_tracker.MarkRprimDirty(it.second.data->prim_id, pxr::HdChangeTracker::DirtyVisibility); + } + char name[16]; + for (auto &it : light_instances_) { + for (int i = 0; i < it.second.count; ++i) { + snprintf(name, 16, "L_%08x", i); + change_tracker.MarkRprimDirty(it.second.data->prim_id.AppendElementString(name), pxr::HdChangeTracker::DirtyVisibility); + } } } return ret; @@ -118,12 +124,10 @@ pxr::GfMatrix4d InstancerData::get_transform(pxr::SdfPath const &id) const { if (id.GetPathElementCount() == 4) { const auto &inst = light_instances_.find(id.GetParentPath())->second; - std::string name = id.GetName(); - int index; - sscanf_s(name.c_str(), "L_%x", &index); - return inst.transforms[index]; + return inst.transforms[light_prim_id_index(id)]; } + /* Mesh instance transform must be identity */ return pxr::GfMatrix4d(1.0); } @@ -306,15 +310,13 @@ void InstancerData::update_light_instance(LightInstance &inst) auto &render_index = scene_delegate_->GetRenderIndex(); LightData &l_data = *inst.data; - char name[16]; int i; pxr::SdfPath p; /* Remove old light instances */ while (inst.count > inst.transforms.size()) { --inst.count; - snprintf(name, 16, "L_%08x", inst.count); - p = l_data.prim_id.AppendElementString(name); + p = light_prim_id(inst, inst.count); render_index.RemoveSprim(l_data.prim_type_, p); ID_LOG(2, "Remove %s", p.GetText()); } @@ -323,15 +325,13 @@ void InstancerData::update_light_instance(LightInstance &inst) if (inst.data->prim_type((Light *)((Object *)l_data.id)->data) != l_data.prim_type_) { /* Recreate instances when prim_type was changed */ for (i = 0; i < inst.count; ++i) { - snprintf(name, 16, "L_%08x", i); - p = l_data.prim_id.AppendElementString(name); + p = light_prim_id(inst, i); render_index.RemoveSprim(l_data.prim_type_, p); ID_LOG(2, "Remove %s", p.GetText()); } inst.data->init(); for (i = 0; i < inst.count; ++i) { - snprintf(name, 16, "L_%08x", i); - p = l_data.prim_id.AppendElementString(name); + p = light_prim_id(inst, i); render_index.InsertSprim(l_data.prim_type_, scene_delegate_, p); ID_LOG(2, "Insert %s (%s)", p.GetText(), l_data.id->name); } @@ -344,8 +344,7 @@ void InstancerData::update_light_instance(LightInstance &inst) bits = pxr::HdLight::AllDirty; } for (i = 0; i < inst.count; ++i) { - snprintf(name, 16, "L_%08x", i); - p = l_data.prim_id.AppendElementString(name); + p = light_prim_id(inst, i); render_index.GetChangeTracker().MarkSprimDirty(p, bits); ID_LOG(2, "Update %s (%s)", p.GetText(), l_data.id->name); } @@ -353,12 +352,25 @@ void InstancerData::update_light_instance(LightInstance &inst) /* Add new light instances */ while (inst.count < inst.transforms.size()) { - snprintf(name, 16, "L_%08x", inst.count); - p = inst.data->prim_id.AppendElementString(name); + p = light_prim_id(inst, inst.count); render_index.InsertSprim(l_data.prim_type_, scene_delegate_, p); ID_LOG(2, "Insert %s (%s)", p.GetText(), l_data.id->name); ++inst.count; } } +pxr::SdfPath InstancerData::light_prim_id(LightInstance const &inst, int index) const +{ + char name[16]; + snprintf(name, 16, "L_%08x", index); + return inst.data->prim_id.AppendElementString(name); +} + +int InstancerData::light_prim_id_index(pxr::SdfPath const &id) const +{ + int index; + sscanf_s(id.GetName().c_str(), "L_%x", &index); + return index; +} + } // 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 f05002dccae0..d2c08cd1a81b 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -52,6 +52,8 @@ class InstancerData : public ObjectData { pxr::SdfPath object_prim_id(Object *object) const; void set_instances(); void update_light_instance(LightInstance &inst); + pxr::SdfPath light_prim_id(LightInstance const &inst, int index) const; + int light_prim_id_index(pxr::SdfPath const &id) const; pxr::TfHashMap mesh_instances_; pxr::TfHashMap light_instances_; -- 2.30.2 From a0ce1b09dd402a201ff8b7e4affa0a734ac6f0ce Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Wed, 3 May 2023 11:52:34 +0300 Subject: [PATCH 12/17] Fixing light update --- .../render/hydra/scene_delegate/instancer.cc | 73 ++++++++++++------- .../render/hydra/scene_delegate/instancer.h | 4 +- .../render/hydra/scene_delegate/light.cc | 6 +- 3 files changed, 53 insertions(+), 30 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index 47d7188bf840..cd6fde14da2a 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -172,20 +172,29 @@ pxr::SdfPathVector InstancerData::prototypes() const void InstancerData::check_update(Object *object) { pxr::SdfPath path = object_prim_id(object); - auto it = mesh_instances_.find(path); - if (it == mesh_instances_.end()) { + auto m_it = mesh_instances_.find(path); + if (m_it != mesh_instances_.end()) { + m_it->second.data->update(); + + pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; + if (m_it->second.data->id->recalc & ID_RECALC_TRANSFORM) { + set_instances(); + bits |= pxr::HdChangeTracker::DirtyTransform; + } + if (bits != pxr::HdChangeTracker::Clean) { + scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(prim_id, bits); + } return; } - ObjectData *obj_data = it->second.data.get(); - obj_data->update(); - pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; - if (object->id.recalc & ID_RECALC_TRANSFORM) { - set_instances(); - bits |= pxr::HdChangeTracker::DirtyTransform; - } - if (bits != pxr::HdChangeTracker::Clean) { - scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(prim_id, bits); + auto l_it = light_instances_.find(path); + 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) { + set_instances(); + } + return; } } @@ -206,6 +215,17 @@ void InstancerData::check_remove(std::set &available_objects) scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( prim_id, pxr::HdChangeTracker::AllDirty); } + + for (auto it = light_instances_.begin(); it != light_instances_.end(); ++it) { + if (available_objects.find(it->first.GetName()) != available_objects.end()) { + continue; + } + it->second.transforms.clear(); + update_light_instance(it->second); + + light_instances_.erase(it); + it = light_instances_.begin(); + } } void InstancerData::available_materials(std::set &paths) const @@ -233,6 +253,20 @@ pxr::SdfPath InstancerData::object_prim_id(Object *object) const return prim_id.AppendElementString(str); } +pxr::SdfPath InstancerData::light_prim_id(LightInstance const &inst, int index) const +{ + char name[16]; + snprintf(name, 16, "L_%08x", index); + return inst.data->prim_id.AppendElementString(name); +} + +int InstancerData::light_prim_id_index(pxr::SdfPath const &id) const +{ + int index; + sscanf_s(id.GetName().c_str(), "L_%x", &index); + return index; +} + void InstancerData::set_instances() { mesh_transforms_.clear(); @@ -339,7 +373,8 @@ void InstancerData::update_light_instance(LightInstance &inst) else { /* Update light instances*/ pxr::HdDirtyBits bits = pxr::HdLight::DirtyTransform; - if (id->recalc & ID_RECALC_GEOMETRY) { + Object *obj = (Object *)inst.data->id; + if (obj->id.recalc & ID_RECALC_GEOMETRY || ((ID *)obj->data)->recalc & ID_RECALC_GEOMETRY) { l_data.init(); bits = pxr::HdLight::AllDirty; } @@ -359,18 +394,4 @@ void InstancerData::update_light_instance(LightInstance &inst) } } -pxr::SdfPath InstancerData::light_prim_id(LightInstance const &inst, int index) const -{ - char name[16]; - snprintf(name, 16, "L_%08x", index); - return inst.data->prim_id.AppendElementString(name); -} - -int InstancerData::light_prim_id_index(pxr::SdfPath const &id) const -{ - int index; - sscanf_s(id.GetName().c_str(), "L_%x", &index); - return index; -} - } // 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 d2c08cd1a81b..ab4f75b4c02b 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -50,10 +50,10 @@ class InstancerData : public ObjectData { private: pxr::SdfPath object_prim_id(Object *object) const; - void set_instances(); - void update_light_instance(LightInstance &inst); 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 update_light_instance(LightInstance &inst); pxr::TfHashMap mesh_instances_; pxr::TfHashMap light_instances_; diff --git a/source/blender/render/hydra/scene_delegate/light.cc b/source/blender/render/hydra/scene_delegate/light.cc index ab4642f86389..98ad40fd39b5 100644 --- a/source/blender/render/hydra/scene_delegate/light.cc +++ b/source/blender/render/hydra/scene_delegate/light.cc @@ -113,7 +113,7 @@ void LightData::update() } pxr::HdDirtyBits bits = pxr::HdLight::Clean; - if (id->recalc & ID_RECALC_GEOMETRY) { + if (id->recalc & ID_RECALC_GEOMETRY || light->id.recalc & ID_RECALC_GEOMETRY) { init(); bits = pxr::HdLight::AllDirty; } @@ -121,7 +121,9 @@ void LightData::update() write_transform(); bits = pxr::HdLight::DirtyTransform; } - scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id, bits); + if (bits != pxr::HdChangeTracker::Clean) { + scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id, bits); + } } pxr::VtValue LightData::get_data(pxr::TfToken const &key) const -- 2.30.2 From 563df4486eb3782752d95169465cc1c54df26dd9 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Wed, 3 May 2023 13:20:39 +0300 Subject: [PATCH 13/17] Fixed light update --- source/blender/render/hydra/scene_delegate/instancer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index cd6fde14da2a..0784d0331e9d 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -153,7 +153,7 @@ ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const if (m_it != mesh_instances_.end()) { return m_it->second.data.get(); } - auto l_it = light_instances_.find(id); + auto l_it = light_instances_.find(id.GetParentPath()); if (l_it != light_instances_.end()) { return l_it->second.data.get(); } -- 2.30.2 From 54d3928b1afe757273cc84478114e7089fa042a6 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Wed, 3 May 2023 13:58:19 +0300 Subject: [PATCH 14/17] Improved working with parent object, fixed related bugs --- .../scene_delegate/blender_scene_delegate.cc | 4 +++ .../scene_delegate/blender_scene_delegate.h | 3 ++- .../render/hydra/scene_delegate/light.cc | 3 ++- .../render/hydra/scene_delegate/mesh.cc | 16 +----------- .../render/hydra/scene_delegate/mesh.h | 1 - .../render/hydra/scene_delegate/object.cc | 25 +++++++++++++++---- .../render/hydra/scene_delegate/object.h | 5 +++- 7 files changed, 33 insertions(+), 24 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 10b5668ec80b..426b7f59b2ed 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -280,6 +280,7 @@ void BlenderSceneDelegate::update_objects(Object *object) pxr::SdfPath id = object_prim_id(object); ObjectData *obj_data = object_data(id); if (obj_data) { + obj_data->update_parent(); obj_data->update(); return; } @@ -288,6 +289,9 @@ void BlenderSceneDelegate::update_objects(Object *object) } objects_[id] = ObjectData::create(this, object, id); obj_data = object_data(id); + obj_data->update_parent(); + obj_data->init(); + obj_data->insert(); obj_data->update_visibility(); } diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h index 50cae4e36759..a3a2cc8053cc 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h @@ -21,7 +21,8 @@ namespace blender::render::hydra { extern struct CLG_LogRef *LOG_RENDER_HYDRA_SCENE; /* BSD - Blender Scene Delegate */ class BlenderSceneDelegate : public pxr::HdSceneDelegate { - friend MeshData; /* has access to materials and instances */ + friend ObjectData; /* has access to instances */ + friend MeshData; /* has access to materials */ public: enum class EngineType { VIEWPORT = 1, FINAL, PREVIEW }; diff --git a/source/blender/render/hydra/scene_delegate/light.cc b/source/blender/render/hydra/scene_delegate/light.cc index 98ad40fd39b5..22d4657cc658 100644 --- a/source/blender/render/hydra/scene_delegate/light.cc +++ b/source/blender/render/hydra/scene_delegate/light.cc @@ -104,7 +104,8 @@ void LightData::update() { ID_LOG(2, ""); - Light *light = (Light *)((Object *)id)->data; + Object *object = (Object *)id; + Light *light = (Light *)object->data; if (prim_type(light) != prim_type_) { remove(); init(); diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index 8545ca7824a6..2404af678695 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -17,7 +17,7 @@ namespace blender::render::hydra { MeshData::MeshData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id) - : ObjectData(scene_delegate, object, prim_id), parent_(object->parent) + : ObjectData(scene_delegate, object, prim_id) { } @@ -66,20 +66,6 @@ void MeshData::remove() void MeshData::update() { Object *object = (Object *)id; - if (parent_ != object->parent) { - parent_ = object->parent; - - /* Looking for corresponded instancer and update it as parent */ - for (Object *ob = parent_; ob != nullptr; ob = ob->parent) { - InstancerData *i_data = scene_delegate_->instancer_data( - scene_delegate_->instancer_prim_id(ob)); - if (i_data) { - i_data->update_as_parent(); - break; - } - } - } - pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) { init(); diff --git a/source/blender/render/hydra/scene_delegate/mesh.h b/source/blender/render/hydra/scene_delegate/mesh.h index e4fe1ab0a56b..da62c1f70003 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.h +++ b/source/blender/render/hydra/scene_delegate/mesh.h @@ -42,7 +42,6 @@ class MeshData : public ObjectData { pxr::VtVec3fArray normals_; MaterialData *mat_data_ = nullptr; - Object *parent_; }; } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/scene_delegate/object.cc b/source/blender/render/hydra/scene_delegate/object.cc index 658960dcdce5..3e750df0c72b 100644 --- a/source/blender/render/hydra/scene_delegate/object.cc +++ b/source/blender/render/hydra/scene_delegate/object.cc @@ -13,7 +13,7 @@ namespace blender::render::hydra { ObjectData::ObjectData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id) - : IdData(scene_delegate, (ID *)object, prim_id), transform(pxr::GfMatrix4d(1.0)), visible(true) + : IdData(scene_delegate, (ID *)object, prim_id), transform(pxr::GfMatrix4d(1.0)) { } @@ -39,10 +39,6 @@ std::unique_ptr ObjectData::create(BlenderSceneDelegate *scene_deleg default: break; } - if (data) { - data->init(); - data->insert(); - } return data; } @@ -78,6 +74,25 @@ bool ObjectData::update_visibility() return ret; } +void ObjectData::update_parent() +{ + Object *object = (Object *)id; + if (parent_ != object->parent) { + ID_LOG(2, ""); + parent_ = object->parent; + + /* Looking for corresponded instancer and update it as parent */ + for (Object *ob = parent_; ob != nullptr; ob = ob->parent) { + InstancerData *i_data = scene_delegate_->instancer_data( + scene_delegate_->instancer_prim_id(ob)); + if (i_data) { + i_data->update_as_parent(); + break; + } + } + } +} + void ObjectData::write_transform() { transform = gf_matrix_from_transform(((Object *)id)->object_to_world); diff --git a/source/blender/render/hydra/scene_delegate/object.h b/source/blender/render/hydra/scene_delegate/object.h index b0a7371e27a9..b6d5e4e48d5e 100644 --- a/source/blender/render/hydra/scene_delegate/object.h +++ b/source/blender/render/hydra/scene_delegate/object.h @@ -24,12 +24,15 @@ class ObjectData : public IdData { static bool is_supported(Object *object); virtual bool update_visibility(); + void update_parent(); pxr::GfMatrix4d transform; - bool visible; + bool visible = true; protected: void write_transform(); + + Object *parent_ = nullptr; }; using ObjectDataMap = -- 2.30.2 From 3c642fabc99836722cdeb9ed5dd587e11181a196 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Wed, 3 May 2023 14:07:28 +0300 Subject: [PATCH 15/17] make format --- .../render/hydra/scene_delegate/blender_scene_delegate.h | 2 +- source/blender/render/hydra/scene_delegate/instancer.cc | 6 ++++-- source/blender/render/hydra/scene_delegate/instancer.h | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h index a3a2cc8053cc..73cd5f1f1111 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h @@ -22,7 +22,7 @@ extern struct CLG_LogRef *LOG_RENDER_HYDRA_SCENE; /* BSD - Blender Scene Delegat class BlenderSceneDelegate : public pxr::HdSceneDelegate { friend ObjectData; /* has access to instances */ - friend MeshData; /* has access to materials */ + friend MeshData; /* has access to materials */ public: enum class EngineType { VIEWPORT = 1, FINAL, PREVIEW }; diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index 0784d0331e9d..1bfa6c0fd07c 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -107,13 +107,15 @@ 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); + change_tracker.MarkRprimDirty(it.second.data->prim_id, + pxr::HdChangeTracker::DirtyVisibility); } char name[16]; for (auto &it : light_instances_) { for (int i = 0; i < it.second.count; ++i) { snprintf(name, 16, "L_%08x", i); - change_tracker.MarkRprimDirty(it.second.data->prim_id.AppendElementString(name), pxr::HdChangeTracker::DirtyVisibility); + change_tracker.MarkRprimDirty(it.second.data->prim_id.AppendElementString(name), + pxr::HdChangeTracker::DirtyVisibility); } } } diff --git a/source/blender/render/hydra/scene_delegate/instancer.h b/source/blender/render/hydra/scene_delegate/instancer.h index ab4f75b4c02b..ee921e9859f5 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -5,8 +5,8 @@ #include "BKE_duplilist.h" -#include "mesh.h" #include "light.h" +#include "mesh.h" namespace blender::render::hydra { -- 2.30.2 From 3b1a8d14990986a3b8a2c97c5854abd164f444bd Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 4 May 2023 09:42:42 +0300 Subject: [PATCH 16/17] Fixes after merge. Removed MaterialData::create(), WorldData::create(), InstancerData::create() as not needed. --- .../hydra/scene_delegate/blender_scene_delegate.cc | 8 ++++++-- .../blender/render/hydra/scene_delegate/instancer.cc | 10 ---------- source/blender/render/hydra/scene_delegate/instancer.h | 4 ---- source/blender/render/hydra/scene_delegate/material.cc | 10 ---------- source/blender/render/hydra/scene_delegate/material.h | 4 ---- source/blender/render/hydra/scene_delegate/mesh.cc | 6 ++++-- source/blender/render/hydra/scene_delegate/mesh.h | 1 - source/blender/render/hydra/scene_delegate/world.cc | 10 ---------- source/blender/render/hydra/scene_delegate/world.h | 4 ---- 9 files changed, 10 insertions(+), 47 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 426b7f59b2ed..840a996fe3bf 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -320,8 +320,10 @@ void BlenderSceneDelegate::update_instancers(Object *object) if (view3d && !BKE_object_is_visible_in_viewport(view3d, object)) { return; } - instancers_[id] = InstancerData::create(this, object, id); + instancers_[id] = std::make_unique(this, object, id); i_data = instancer_data(id); + i_data->init(); + i_data->insert(); i_data->update_visibility(); } @@ -330,7 +332,9 @@ void BlenderSceneDelegate::update_world() World *world = scene->world; if (!world_data_) { if (world) { - world_data_ = WorldData::create(this, world, world_prim_id()); + world_data_ = std::make_unique(this, world, world_prim_id()); + world_data_->init(); + world_data_->insert(); } } else { diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index 1bfa6c0fd07c..e5ae57372778 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -16,16 +16,6 @@ InstancerData::InstancerData(BlenderSceneDelegate *scene_delegate, { } -std::unique_ptr InstancerData::create(BlenderSceneDelegate *scene_delegate, - Object *object, - pxr::SdfPath const &prim_id) -{ - auto data = std::make_unique(scene_delegate, object, prim_id); - data->init(); - data->insert(); - return data; -} - bool InstancerData::is_supported(Object *object) { switch (object->type) { diff --git a/source/blender/render/hydra/scene_delegate/instancer.h b/source/blender/render/hydra/scene_delegate/instancer.h index ee921e9859f5..cb9410768431 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -24,10 +24,6 @@ class InstancerData : public ObjectData { public: InstancerData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id); - - static std::unique_ptr create(BlenderSceneDelegate *scene_delegate, - Object *object, - pxr::SdfPath const &prim_id); static bool is_supported(Object *object); void init() override; diff --git a/source/blender/render/hydra/scene_delegate/material.cc b/source/blender/render/hydra/scene_delegate/material.cc index 380d9826d352..9033c25cfea5 100644 --- a/source/blender/render/hydra/scene_delegate/material.cc +++ b/source/blender/render/hydra/scene_delegate/material.cc @@ -27,16 +27,6 @@ MaterialData::MaterialData(BlenderSceneDelegate *scene_delegate, { } -std::unique_ptr MaterialData::create(BlenderSceneDelegate *scene_delegate, - Material *material, - pxr::SdfPath const &prim_id) -{ - auto data = std::make_unique(scene_delegate, material, prim_id); - data->init(); - data->insert(); - return data; -} - void MaterialData::init() { ID_LOG(2, ""); diff --git a/source/blender/render/hydra/scene_delegate/material.h b/source/blender/render/hydra/scene_delegate/material.h index 2f6371cd3438..985e95acb786 100644 --- a/source/blender/render/hydra/scene_delegate/material.h +++ b/source/blender/render/hydra/scene_delegate/material.h @@ -19,10 +19,6 @@ class MaterialData : public IdData { Material *material, pxr::SdfPath const &prim_id); - static std::unique_ptr create(BlenderSceneDelegate *scene_delegate, - Material *material, - pxr::SdfPath const &prim_id); - void init() override; void insert() override; void remove() override; diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index 7fc3d53ea6bd..be5636d08888 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -17,7 +17,7 @@ namespace blender::render::hydra { MeshData::MeshData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id) - : ObjectData(scene_delegate, object, prim_id), parent_(object->parent) + : ObjectData(scene_delegate, object, prim_id) { } @@ -218,8 +218,10 @@ void MeshData::write_material() 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] = MaterialData::create(scene_delegate_, mat, p_id); + 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(); } } diff --git a/source/blender/render/hydra/scene_delegate/mesh.h b/source/blender/render/hydra/scene_delegate/mesh.h index e4fe1ab0a56b..da62c1f70003 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.h +++ b/source/blender/render/hydra/scene_delegate/mesh.h @@ -42,7 +42,6 @@ class MeshData : public ObjectData { pxr::VtVec3fArray normals_; MaterialData *mat_data_ = nullptr; - Object *parent_; }; } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/scene_delegate/world.cc b/source/blender/render/hydra/scene_delegate/world.cc index 3fca6378aae1..184555ff0a3b 100644 --- a/source/blender/render/hydra/scene_delegate/world.cc +++ b/source/blender/render/hydra/scene_delegate/world.cc @@ -34,16 +34,6 @@ WorldData::WorldData(BlenderSceneDelegate *scene_delegate, { } -std::unique_ptr WorldData::create(BlenderSceneDelegate *scene_delegate, - World *world, - pxr::SdfPath const &prim_id) -{ - auto data = std::make_unique(scene_delegate, world, prim_id); - data->init(); - data->insert(); - return data; -} - void WorldData::init() { ID_LOG(2, ""); diff --git a/source/blender/render/hydra/scene_delegate/world.h b/source/blender/render/hydra/scene_delegate/world.h index 083e0daff78a..2eb62555c555 100644 --- a/source/blender/render/hydra/scene_delegate/world.h +++ b/source/blender/render/hydra/scene_delegate/world.h @@ -22,10 +22,6 @@ class WorldData : public IdData { public: WorldData(BlenderSceneDelegate *scene_delegate, World *world, pxr::SdfPath const &prim_id); - static std::unique_ptr create(BlenderSceneDelegate *scene_delegate, - World *world, - pxr::SdfPath const &prim_id); - void init() override; void insert() override; void remove() override; -- 2.30.2 From 7834da5971616759c602b68327c7aab859dcddbe Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 4 May 2023 10:41:12 +0300 Subject: [PATCH 17/17] Fixed Instancer transform update for HdStorm --- .../render/hydra/scene_delegate/instancer.cc | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index e5ae57372778..50bc558c20fb 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -63,19 +63,12 @@ void InstancerData::update() { ID_LOG(2, ""); - pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; - Object *object = (Object *)id; - if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) { + if (id->recalc & ID_RECALC_GEOMETRY || ((ID *)object->data)->recalc & ID_RECALC_GEOMETRY || + id->recalc & ID_RECALC_TRANSFORM) { set_instances(); - bits |= pxr::HdChangeTracker::AllDirty; - } - else if (id->recalc & ID_RECALC_TRANSFORM) { - set_instances(); - bits |= pxr::HdChangeTracker::DirtyTransform; - } - if (bits != pxr::HdChangeTracker::Clean) { - scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(prim_id, bits); + scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( + prim_id, pxr::HdChangeTracker::AllDirty); } } @@ -168,13 +161,10 @@ void InstancerData::check_update(Object *object) if (m_it != mesh_instances_.end()) { m_it->second.data->update(); - pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; if (m_it->second.data->id->recalc & ID_RECALC_TRANSFORM) { set_instances(); - bits |= pxr::HdChangeTracker::DirtyTransform; - } - if (bits != pxr::HdChangeTracker::Clean) { - scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(prim_id, bits); + scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( + prim_id, pxr::HdChangeTracker::AllDirty); } return; } -- 2.30.2