From f777cf428f65a7aecb7abbefba1e600a2ffbb33f Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 7 Apr 2023 20:26:31 +0300 Subject: [PATCH 01/15] Support several instancers on one object. Refactoring: moving ObjectData of base object to InstancerData. --- .../scene_delegate/blender_scene_delegate.cc | 11 ++- .../blender/render/hydra/scene_delegate/id.h | 8 +- .../render/hydra/scene_delegate/instancer.cc | 82 ++++++------------- .../render/hydra/scene_delegate/instancer.h | 16 ++-- .../render/hydra/scene_delegate/object.cc | 6 +- 5 files changed, 53 insertions(+), 70 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 38346736b41e..b33d78f524af 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -55,9 +55,12 @@ bool BlenderSceneDelegate::GetVisible(pxr::SdfPath const &id) pxr::SdfPath BlenderSceneDelegate::GetInstancerId(pxr::SdfPath const &prim_id) { CLOG_INFO(LOG_BSD, 3, "%s", prim_id.GetText()); - InstancerData *i_data = instancer_data(prim_id, true); + if (prim_id.GetParentPath() == GetDelegateID()) { + return pxr::SdfPath(); + } + InstancerData *i_data = instancer_data(prim_id.GetParentPath()); if (i_data) { - return i_data->instancer_id; + return i_data->p_id; } return pxr::SdfPath(); } @@ -75,7 +78,7 @@ pxr::VtIntArray BlenderSceneDelegate::GetInstanceIndices(pxr::SdfPath const &ins { CLOG_INFO(LOG_BSD, 3, "%s, %s", instancer_id.GetText(), prototype_id.GetText()); InstancerData *i_data = instancer_data(instancer_id); - return i_data->instance_indices(); + return i_data->indices(); } pxr::GfMatrix4d BlenderSceneDelegate::GetInstancerTransform(pxr::SdfPath const &instancer_id) @@ -381,7 +384,7 @@ pxr::HdPrimvarDescriptorVector BlenderSceneDelegate::GetPrimvarDescriptors( InstancerData *i_data = instancer_data(id); if (i_data) { - return i_data->instancer_primvar_descriptors(interpolation); + return i_data->primvar_descriptors(interpolation); } return pxr::HdPrimvarDescriptorVector(); diff --git a/source/blender/render/hydra/scene_delegate/id.h b/source/blender/render/hydra/scene_delegate/id.h index 8d36f8e2d3c1..e1e36cad586b 100644 --- a/source/blender/render/hydra/scene_delegate/id.h +++ b/source/blender/render/hydra/scene_delegate/id.h @@ -26,10 +26,11 @@ class IdData { virtual pxr::VtValue get_data(pxr::TfToken const &key) const; template const T get_data(pxr::TfToken const &key) const; - protected: - BlenderSceneDelegate *scene_delegate; ID *id; pxr::SdfPath p_id; + + protected: + BlenderSceneDelegate *scene_delegate; }; template const T IdData::get_data(pxr::TfToken const &key) const @@ -37,4 +38,7 @@ template const T IdData::get_data(pxr::TfToken const &key) const return get_data(key).Get(); } +#define ID_LOG(level, msg, ...) \ + CLOG_INFO(LOG_BSD, level, "%s (%s): " msg, p_id.GetText(), id->name, __VA_ARGS__); + } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index 8c5cd75e72e8..19e5489e52e6 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -44,20 +44,16 @@ pxr::SdfPath InstancerData::prim_id(BlenderSceneDelegate *scene_delegate, Object } InstancerData::InstancerData(BlenderSceneDelegate *scene_delegate, Object *object) - : MeshData(scene_delegate, object), parent_obj(object) + : ObjectData(scene_delegate, object) { - id = nullptr; p_id = prim_id(scene_delegate, object); - instancer_id = p_id.AppendElementString("Instancer"); - CLOG_INFO(LOG_BSD, 2, "%s, instancer_id=%s", ((ID *)parent_obj)->name, instancer_id.GetText()); + ID_LOG(2, ""); } void InstancerData::init() { - CLOG_INFO(LOG_BSD, 2, "%s", ((ID *)parent_obj)->name); - + ID_LOG(2, ""); set_instances(); - MeshData::init(); } pxr::GfMatrix4d InstancerData::transform() @@ -71,11 +67,9 @@ bool InstancerData::update_visibility(View3D *view3d) return false; } - bool prev_visible = visible; - visible = BKE_object_is_visible_in_viewport(view3d, parent_obj); - bool ret = visible != prev_visible; + bool ret = ObjectData::update_visibility(view3d); if (ret) { - scene_delegate->GetRenderIndex().GetChangeTracker().MarkRprimDirty( + scene_delegate->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( p_id, pxr::HdChangeTracker::DirtyVisibility); } return ret; @@ -83,16 +77,15 @@ bool InstancerData::update_visibility(View3D *view3d) pxr::VtValue InstancerData::get_data(pxr::TfToken const &key) const { - CLOG_INFO(LOG_BSD, 3, "%s [%s]", id->name, key.GetText()); - + ID_LOG(3, "%s", key.GetText()); + pxr::VtValue ret; if (key == pxr::HdInstancerTokens->instanceTransform) { - return pxr::VtValue(transforms); + ret = transforms; } - return MeshData::get_data(key); + return ret; } -pxr::HdPrimvarDescriptorVector InstancerData::instancer_primvar_descriptors( - pxr::HdInterpolation interpolation) +pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors(pxr::HdInterpolation interpolation) { pxr::HdPrimvarDescriptorVector primvars; if (interpolation == pxr::HdInterpolationInstance) { @@ -102,7 +95,7 @@ pxr::HdPrimvarDescriptorVector InstancerData::instancer_primvar_descriptors( return primvars; } -pxr::VtIntArray InstancerData::instance_indices() +pxr::VtIntArray InstancerData::indices() { pxr::VtIntArray ret(transforms.size()); for (size_t i = 0; i < ret.size(); ++i) { @@ -116,78 +109,57 @@ bool InstancerData::is_base(Object *object) const return (ID *)object == id; } -bool InstancerData::set_instances() +void InstancerData::set_instances() { - ID *prev_id = id; - id = nullptr; transforms.clear(); - ListBase *lb = object_duplilist(scene_delegate->depsgraph, scene_delegate->scene, parent_obj); + ListBase *lb = object_duplilist(scene_delegate->depsgraph, scene_delegate->scene, (Object *)id); LISTBASE_FOREACH (DupliObject *, dupli, lb) { - if (!id) { + if (!m_data) { /* TODO: We create instances only for object in first dupli. Instances should be created for all objects */ - id = (ID *)dupli->ob; + m_data = ObjectData::create(scene_delegate, dupli->ob); + m_data->p_id = p_id.AppendElementString(m_data->p_id.GetName()); } - if (id != (ID *)dupli->ob) { + if (m_data->id != (ID *)dupli->ob) { continue; } transforms.push_back(gf_matrix_from_transform(dupli->mat)); - CLOG_INFO( - LOG_BSD, 2, "Instance %s (%s) %d", id->name, ((ID *)dupli->ob)->name, dupli->random_id); + ID_LOG(2, "Instance %s %d", m_data->id->name, dupli->random_id); } free_object_duplilist(lb); - - return id != prev_id; } void InstancerData::insert() { - CLOG_INFO(LOG_BSD, 2, "%s", ((ID *)parent_obj)->name); - MeshData::insert(); - - if (face_vertex_counts.empty()) { - return; - } - scene_delegate->GetRenderIndex().InsertInstancer(scene_delegate, instancer_id); + ID_LOG(2, ""); + scene_delegate->GetRenderIndex().InsertInstancer(scene_delegate, p_id); + m_data->insert(); } void InstancerData::remove() { - CLOG_INFO(LOG_BSD, 2, "%s", ((ID *)parent_obj)->name); - - if (!scene_delegate->GetRenderIndex().HasInstancer(instancer_id)) { - return; - } - scene_delegate->GetRenderIndex().RemoveInstancer(instancer_id); - - MeshData::remove(); + ID_LOG(2, ""); + m_data->remove(); + scene_delegate->GetRenderIndex().RemoveInstancer(p_id); } void InstancerData::update() { - CLOG_INFO(LOG_BSD, 2, "%s", ((ID *)parent_obj)->name); + ID_LOG(2, ""); pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; - unsigned int recalc = ((ID *)parent_obj)->recalc; Object *object = (Object *)id; if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) { - init(); - scene_delegate->GetRenderIndex().GetChangeTracker().MarkRprimDirty( - p_id, pxr::HdChangeTracker::AllDirty); - return; - } - - if ((recalc & ID_RECALC_GEOMETRY) || (((ID *)parent_obj->data)->recalc & ID_RECALC_GEOMETRY)) { init(); bits |= pxr::HdChangeTracker::AllDirty; } - else if (recalc & ID_RECALC_TRANSFORM || id->recalc & ID_RECALC_TRANSFORM) { + else if (id->recalc & ID_RECALC_TRANSFORM) { set_instances(); bits |= pxr::HdChangeTracker::DirtyTransform; } if (bits != pxr::HdChangeTracker::Clean) { - scene_delegate->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(instancer_id, bits); + scene_delegate->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(p_id, bits); } } diff --git a/source/blender/render/hydra/scene_delegate/instancer.h b/source/blender/render/hydra/scene_delegate/instancer.h index 0e33f1ac017a..754bd3f9f7e6 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -5,11 +5,11 @@ #include "BKE_duplilist.h" -#include "mesh.h" +#include "object.h" namespace blender::render::hydra { -class InstancerData : public MeshData { +class InstancerData : public ObjectData { public: static bool supported(Object *object); static std::unique_ptr create(BlenderSceneDelegate *scene_delegate, @@ -26,17 +26,17 @@ class InstancerData : public MeshData { pxr::GfMatrix4d transform() override; bool update_visibility(View3D *view3d) override; - pxr::HdPrimvarDescriptorVector instancer_primvar_descriptors(pxr::HdInterpolation interpolation); - pxr::VtIntArray instance_indices(); + pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation); + pxr::VtIntArray indices(); bool is_base(Object *object) const; - pxr::SdfPath instancer_id; + + std::unique_ptr m_data; private: - Object *parent_obj; pxr::VtMatrix4dArray transforms; - - bool set_instances(); + + void set_instances(); }; } // 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 6a120734296d..5c46b39b0a44 100644 --- a/source/blender/render/hydra/scene_delegate/object.cc +++ b/source/blender/render/hydra/scene_delegate/object.cc @@ -84,7 +84,11 @@ bool ObjectData::update_visibility(View3D *view3d) bool prev_visible = visible; visible = BKE_object_is_visible_in_viewport(view3d, (Object *)id); - return visible != prev_visible; + bool ret = visible != prev_visible; + if (ret) { + ID_LOG(2, ""); + } + return ret; } } // namespace blender::render::hydra -- 2.30.2 From 3dc02d52dfd11ef1209424f1b37dfc635de9ffc6 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Wed, 12 Apr 2023 20:06:48 +0300 Subject: [PATCH 02/15] Fixed showing instances --- .../scene_delegate/blender_scene_delegate.cc | 28 +++++++++---------- .../scene_delegate/blender_scene_delegate.h | 2 +- .../render/hydra/scene_delegate/material.cc | 1 + 3 files changed, 16 insertions(+), 15 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 b33d78f524af..f08c7350f263 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -55,9 +55,6 @@ bool BlenderSceneDelegate::GetVisible(pxr::SdfPath const &id) pxr::SdfPath BlenderSceneDelegate::GetInstancerId(pxr::SdfPath const &prim_id) { CLOG_INFO(LOG_BSD, 3, "%s", prim_id.GetText()); - if (prim_id.GetParentPath() == GetDelegateID()) { - return pxr::SdfPath(); - } InstancerData *i_data = instancer_data(prim_id.GetParentPath()); if (i_data) { return i_data->p_id; @@ -69,7 +66,8 @@ pxr::SdfPathVector BlenderSceneDelegate::GetInstancerPrototypes(pxr::SdfPath con { CLOG_INFO(LOG_BSD, 3, "%s", instancer_id.GetText()); pxr::SdfPathVector paths; - paths.push_back(instancer_id.GetParentPath()); + InstancerData *i_data = instancer_data(instancer_id); + paths.push_back(i_data->m_data->p_id); return paths; } @@ -196,23 +194,28 @@ void BlenderSceneDelegate::add_update_object(Object *object) void BlenderSceneDelegate::add_update_instancer(Object *object) { pxr::SdfPath id = InstancerData::prim_id(this, object); - InstancerData *i_data = instancer_data(id, true); + InstancerData *i_data = instancer_data(id); if (i_data) { i_data->update(); return; } objects[id] = InstancerData::create(this, object); - i_data = instancer_data(id, true); + i_data = instancer_data(id); i_data->update_visibility(view3d); } ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id) { auto it = objects.find(id); - if (it == objects.end()) { - return nullptr; + if (it != objects.end()) { + return it->second.get(); } - return it->second.get(); + it = objects.find(id.GetParentPath()); + if (it != objects.end()) { + InstancerData *i_data = (InstancerData *)it->second.get(); + return i_data->m_data.get(); + } + return nullptr; } MeshData *BlenderSceneDelegate::mesh_data(pxr::SdfPath const &id) @@ -234,12 +237,9 @@ MaterialData *BlenderSceneDelegate::material_data(pxr::SdfPath const &id) return it->second.get(); } -InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id, bool base_prim) +InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id) { - if (base_prim) { - return dynamic_cast(object_data(id)); - } - return dynamic_cast(object_data(id.GetParentPath())); + return dynamic_cast(object_data(id)); } InstancerData *BlenderSceneDelegate::instancer_data(Object *object) 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 0ee8bb3d0f21..d4afff5abdc5 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h @@ -58,7 +58,7 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate { MeshData *mesh_data(pxr::SdfPath const &id); LightData *light_data(pxr::SdfPath const &id); MaterialData *material_data(pxr::SdfPath const &id); - InstancerData *instancer_data(pxr::SdfPath const &id, bool base_prim = false); + InstancerData *instancer_data(pxr::SdfPath const &id); InstancerData *instancer_data(Object *object); void add_update_object(Object *object); diff --git a/source/blender/render/hydra/scene_delegate/material.cc b/source/blender/render/hydra/scene_delegate/material.cc index 3e20c74ef966..7d2bc1c97a17 100644 --- a/source/blender/render/hydra/scene_delegate/material.cc +++ b/source/blender/render/hydra/scene_delegate/material.cc @@ -101,6 +101,7 @@ pxr::VtValue MaterialData::get_data(pxr::TfToken const &key) const pxr::VtValue MaterialData::material_resource() { + return material_network_map; if (material_network_map.IsEmpty()) { const std::string &path = mtlx_path.GetResolvedPath(); if (!path.empty()) { -- 2.30.2 From a1bbf2512fa68e581ba7988c720ab95ed977bb7d Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Wed, 12 Apr 2023 20:58:25 +0300 Subject: [PATCH 03/15] Implemented support several instances on one Instancer --- .../scene_delegate/blender_scene_delegate.cc | 22 ++++---- .../render/hydra/scene_delegate/instancer.cc | 56 +++++++++++++------ .../render/hydra/scene_delegate/instancer.h | 18 +++--- 3 files changed, 59 insertions(+), 37 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 f08c7350f263..df82e09f3e02 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -65,10 +65,8 @@ pxr::SdfPath BlenderSceneDelegate::GetInstancerId(pxr::SdfPath const &prim_id) pxr::SdfPathVector BlenderSceneDelegate::GetInstancerPrototypes(pxr::SdfPath const &instancer_id) { CLOG_INFO(LOG_BSD, 3, "%s", instancer_id.GetText()); - pxr::SdfPathVector paths; InstancerData *i_data = instancer_data(instancer_id); - paths.push_back(i_data->m_data->p_id); - return paths; + return i_data->prototypes(); } pxr::VtIntArray BlenderSceneDelegate::GetInstanceIndices(pxr::SdfPath const &instancer_id, @@ -76,7 +74,7 @@ pxr::VtIntArray BlenderSceneDelegate::GetInstanceIndices(pxr::SdfPath const &ins { CLOG_INFO(LOG_BSD, 3, "%s, %s", instancer_id.GetText(), prototype_id.GetText()); InstancerData *i_data = instancer_data(instancer_id); - return i_data->indices(); + return i_data->indices(prototype_id); } pxr::GfMatrix4d BlenderSceneDelegate::GetInstancerTransform(pxr::SdfPath const &instancer_id) @@ -213,7 +211,7 @@ ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id) it = objects.find(id.GetParentPath()); if (it != objects.end()) { InstancerData *i_data = (InstancerData *)it->second.get(); - return i_data->m_data.get(); + return i_data->object_data(id); } return nullptr; } @@ -244,13 +242,13 @@ InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id) InstancerData *BlenderSceneDelegate::instancer_data(Object *object) { - InstancerData *i_data; - for (auto &it : objects) { - i_data = dynamic_cast(it.second.get()); - if (i_data && i_data->is_base(object)) { - return i_data; - } - } + //InstancerData *i_data; + //for (auto &it : objects) { + // i_data = dynamic_cast(it.second.get()); + // if (i_data && i_data->is_base(object)) { + // return i_data; + // } + //} return nullptr; } diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index 19e5489e52e6..5e1226a7efc2 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -95,36 +95,52 @@ pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors(pxr::HdInterpo return primvars; } -pxr::VtIntArray InstancerData::indices() +pxr::VtIntArray InstancerData::indices(pxr::SdfPath const &id) { - pxr::VtIntArray ret(transforms.size()); - for (size_t i = 0; i < ret.size(); ++i) { - ret[i] = i; - } - return ret; + return instances[id].indices; } -bool InstancerData::is_base(Object *object) const +ObjectData *InstancerData::object_data(pxr::SdfPath const &id) { - return (ID *)object == id; + return instances[id].obj_data.get(); +} + +pxr::SdfPathVector InstancerData::prototypes() +{ + pxr::SdfPathVector paths; + for (auto &it : instances) { + paths.push_back(it.first); + } + return paths; } void InstancerData::set_instances() { transforms.clear(); + for (auto &it : instances) { + it.second.indices.clear(); + } + int index = 0; + Instance *inst; + pxr::SdfPath path; + ListBase *lb = object_duplilist(scene_delegate->depsgraph, scene_delegate->scene, (Object *)id); LISTBASE_FOREACH (DupliObject *, dupli, lb) { - if (!m_data) { - /* TODO: We create instances only for object in first dupli. - Instances should be created for all objects */ - m_data = ObjectData::create(scene_delegate, dupli->ob); - m_data->p_id = p_id.AppendElementString(m_data->p_id.GetName()); + path = ObjectData::prim_id(scene_delegate, dupli->ob); + path = p_id.AppendElementString(path.GetName()); + auto it = instances.find(path); + if (it == instances.end()) { + inst = &instances[path]; + inst->obj_data = ObjectData::create(scene_delegate, dupli->ob); + inst->obj_data->p_id = path; } - if (m_data->id != (ID *)dupli->ob) { - continue; + else { + inst = &it->second; } transforms.push_back(gf_matrix_from_transform(dupli->mat)); - ID_LOG(2, "Instance %s %d", m_data->id->name, dupli->random_id); + inst->indices.push_back(index); + ID_LOG(2, "Instance %s %d", inst->obj_data->id->name, index); + ++index; } free_object_duplilist(lb); } @@ -133,13 +149,17 @@ void InstancerData::insert() { ID_LOG(2, ""); scene_delegate->GetRenderIndex().InsertInstancer(scene_delegate, p_id); - m_data->insert(); + for (auto &it : instances) { + it.second.obj_data->insert(); + } } void InstancerData::remove() { ID_LOG(2, ""); - m_data->remove(); + for (auto &it : instances) { + it.second.obj_data->remove(); + } scene_delegate->GetRenderIndex().RemoveInstancer(p_id); } diff --git a/source/blender/render/hydra/scene_delegate/instancer.h b/source/blender/render/hydra/scene_delegate/instancer.h index 754bd3f9f7e6..3c33874cfe26 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -10,6 +10,11 @@ namespace blender::render::hydra { class InstancerData : public ObjectData { + struct Instance { + std::unique_ptr obj_data; + pxr::VtIntArray indices; + }; + public: static bool supported(Object *object); static std::unique_ptr create(BlenderSceneDelegate *scene_delegate, @@ -27,16 +32,15 @@ class InstancerData : public ObjectData { bool update_visibility(View3D *view3d) override; pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation); - pxr::VtIntArray indices(); - - bool is_base(Object *object) const; - - std::unique_ptr m_data; + pxr::VtIntArray indices(pxr::SdfPath const &id); + ObjectData *object_data(pxr::SdfPath const &id); + pxr::SdfPathVector prototypes(); private: - pxr::VtMatrix4dArray transforms; - void set_instances(); + + pxr::TfHashMap instances; + pxr::VtMatrix4dArray transforms; }; } // namespace blender::render::hydra -- 2.30.2 From c57651f9bb13737f33bb4040bd4eae125e37879d Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 13 Apr 2023 06:13:29 +0300 Subject: [PATCH 04/15] Fixed instance transform --- .../blender/render/hydra/scene_delegate/id.cc | 2 +- .../render/hydra/scene_delegate/instancer.cc | 22 +++++++++++++++++-- .../render/hydra/scene_delegate/instancer.h | 8 ++++++- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/id.cc b/source/blender/render/hydra/scene_delegate/id.cc index 7c0a28be9de2..8caee1c0e3f6 100644 --- a/source/blender/render/hydra/scene_delegate/id.cc +++ b/source/blender/render/hydra/scene_delegate/id.cc @@ -9,7 +9,7 @@ namespace blender::render::hydra { IdData::IdData(BlenderSceneDelegate *scene_delegate, ID *id) - : scene_delegate(scene_delegate), id(id) + : id(id), scene_delegate(scene_delegate) { } diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index 5e1226a7efc2..e8e184887d6b 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -54,6 +54,9 @@ void InstancerData::init() { ID_LOG(2, ""); set_instances(); + for (auto &it : instances) { + it.second.obj_data->init(); + } } pxr::GfMatrix4d InstancerData::transform() @@ -131,8 +134,10 @@ void InstancerData::set_instances() auto it = instances.find(path); if (it == instances.end()) { inst = &instances[path]; - inst->obj_data = ObjectData::create(scene_delegate, dupli->ob); - inst->obj_data->p_id = path; + if (!supported(dupli->ob)) { + continue; + } + inst->obj_data = std::make_unique(scene_delegate, dupli->ob, path); } else { inst = &it->second; @@ -183,4 +188,17 @@ void InstancerData::update() } } +InstanceMeshData::InstanceMeshData(BlenderSceneDelegate *scene_delegate, + Object *object, + pxr::SdfPath const &p_id) + : MeshData(scene_delegate, object) +{ + this->p_id = p_id; +} + +pxr::GfMatrix4d InstanceMeshData::transform() +{ + return pxr::GfMatrix4d(1.0); +} + } // 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 3c33874cfe26..abdf341edeca 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -5,7 +5,7 @@ #include "BKE_duplilist.h" -#include "object.h" +#include "mesh.h" namespace blender::render::hydra { @@ -43,4 +43,10 @@ class InstancerData : public ObjectData { pxr::VtMatrix4dArray transforms; }; +class InstanceMeshData : public MeshData { + public: + InstanceMeshData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &p_id); + pxr::GfMatrix4d transform() override; +}; + } // namespace blender::render::hydra -- 2.30.2 From 8359745e421872a4970ea747883394d8c5af9d30 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 13 Apr 2023 06:55:43 +0300 Subject: [PATCH 05/15] Continuing --- .../scene_delegate/blender_scene_delegate.cc | 5 ----- .../render/hydra/scene_delegate/instancer.cc | 15 ++++++++++++--- 2 files changed, 12 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 df82e09f3e02..6d239318d4d9 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -414,11 +414,6 @@ pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id) return world_data->transform(); } - InstancerData *i_data = instancer_data(id); - if (i_data) { - return i_data->transform(); - } - return pxr::GfMatrix4d(); } diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index e8e184887d6b..d7ae27cddd9c 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -54,9 +54,6 @@ void InstancerData::init() { ID_LOG(2, ""); set_instances(); - for (auto &it : instances) { - it.second.obj_data->init(); - } } pxr::GfMatrix4d InstancerData::transform() @@ -138,6 +135,8 @@ void InstancerData::set_instances() continue; } inst->obj_data = std::make_unique(scene_delegate, dupli->ob, path); + inst->obj_data->init(); + inst->obj_data->insert(); } else { inst = &it->second; @@ -148,6 +147,16 @@ void InstancerData::set_instances() ++index; } free_object_duplilist(lb); + + /* Remove intances without indices */ + for (auto it = instances.begin(); it != instances.end(); ++it) { + if (!it->second.indices.empty()) { + continue; + } + it->second.obj_data->remove(); + instances.erase(it); + it = instances.begin(); + } } void InstancerData::insert() -- 2.30.2 From 857c4f016000cd566cac603c84dd5fbaf7decc0c Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 13 Apr 2023 09:22:22 +0300 Subject: [PATCH 06/15] Moving to use separate set of instancers --- .../scene_delegate/blender_scene_delegate.cc | 31 +++++++------------ .../scene_delegate/blender_scene_delegate.h | 2 +- .../render/hydra/scene_delegate/instancer.cc | 12 +++++++ .../render/hydra/scene_delegate/instancer.h | 4 +++ 4 files changed, 28 insertions(+), 21 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 6d239318d4d9..be28efd24c27 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -170,10 +170,10 @@ void BlenderSceneDelegate::add_update_object(Object *object) if ((object->transflag & OB_DUPLI) && InstancerData::supported(object)) { add_update_instancer(object); } - InstancerData *i_data = instancer_data(object); - if (i_data) { - i_data->update(); - } + //InstancerData *i_data = instancer_data(object); + //if (i_data) { + // i_data->update(); + //} pxr::SdfPath id = ObjectData::prim_id(this, object); ObjectData *obj_data = object_data(id); @@ -197,7 +197,7 @@ void BlenderSceneDelegate::add_update_instancer(Object *object) i_data->update(); return; } - objects[id] = InstancerData::create(this, object); + instancers[id] = InstancerData::create(this, object); i_data = instancer_data(id); i_data->update_visibility(view3d); } @@ -208,9 +208,8 @@ ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id) if (it != objects.end()) { return it->second.get(); } - it = objects.find(id.GetParentPath()); - if (it != objects.end()) { - InstancerData *i_data = (InstancerData *)it->second.get(); + InstancerData *i_data = instancer_data(id.GetParentPath()); + if (i_data) { return i_data->object_data(id); } return nullptr; @@ -237,18 +236,10 @@ MaterialData *BlenderSceneDelegate::material_data(pxr::SdfPath const &id) InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id) { - return dynamic_cast(object_data(id)); -} - -InstancerData *BlenderSceneDelegate::instancer_data(Object *object) -{ - //InstancerData *i_data; - //for (auto &it : objects) { - // i_data = dynamic_cast(it.second.get()); - // if (i_data && i_data->is_base(object)) { - // return i_data; - // } - //} + auto it = instancers.find(id); + if (it != instancers.end()) { + return it->second.get(); + } return nullptr; } 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 d4afff5abdc5..d4fd46f9b4c3 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h @@ -59,7 +59,6 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate { LightData *light_data(pxr::SdfPath const &id); MaterialData *material_data(pxr::SdfPath const &id); InstancerData *instancer_data(pxr::SdfPath const &id); - InstancerData *instancer_data(Object *object); void add_update_object(Object *object); void add_update_instancer(Object *object); @@ -74,6 +73,7 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate { ObjectDataMap objects; MaterialDataMap materials; + InstancerDataMap instancers; std::unique_ptr world_data; }; diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index d7ae27cddd9c..606d8e66b72e 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -114,6 +114,18 @@ pxr::SdfPathVector InstancerData::prototypes() return paths; } +void InstancerData::update(Object *object) +{ + pxr::SdfPath path = ObjectData::prim_id(scene_delegate, object); + path = p_id.AppendElementString(path.GetName()); + auto it = instances.find(path); + if (it == instances.end()) { + return; + } + ObjectData *obj_data = it->second.obj_data.get(); + obj_data->update(); +} + void InstancerData::set_instances() { transforms.clear(); diff --git a/source/blender/render/hydra/scene_delegate/instancer.h b/source/blender/render/hydra/scene_delegate/instancer.h index abdf341edeca..8666f7c42144 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -35,6 +35,7 @@ class InstancerData : public ObjectData { pxr::VtIntArray indices(pxr::SdfPath const &id); ObjectData *object_data(pxr::SdfPath const &id); pxr::SdfPathVector prototypes(); + void update(Object *object); private: void set_instances(); @@ -43,6 +44,9 @@ class InstancerData : public ObjectData { pxr::VtMatrix4dArray transforms; }; +using InstancerDataMap = + pxr::TfHashMap, pxr::SdfPath::Hash>; + class InstanceMeshData : public MeshData { public: InstanceMeshData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &p_id); -- 2.30.2 From 038e480837486640fb20636bf2adc37398fbce4e Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 13 Apr 2023 09:52:37 +0300 Subject: [PATCH 07/15] Implementing updates --- .../scene_delegate/blender_scene_delegate.cc | 7 +++-- .../render/hydra/scene_delegate/instancer.cc | 26 +++++++++++++++++-- .../render/hydra/scene_delegate/instancer.h | 3 ++- 3 files changed, 29 insertions(+), 7 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 be28efd24c27..8c9a0b76a55a 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -170,10 +170,9 @@ void BlenderSceneDelegate::add_update_object(Object *object) if ((object->transflag & OB_DUPLI) && InstancerData::supported(object)) { add_update_instancer(object); } - //InstancerData *i_data = instancer_data(object); - //if (i_data) { - // i_data->update(); - //} + for (auto &it : instancers) { + it.second->check_update(object); + } pxr::SdfPath id = ObjectData::prim_id(this, object); ObjectData *obj_data = object_data(id); diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index 606d8e66b72e..7fedf0f37f21 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -114,7 +114,7 @@ pxr::SdfPathVector InstancerData::prototypes() return paths; } -void InstancerData::update(Object *object) +void InstancerData::check_update(Object *object) { pxr::SdfPath path = ObjectData::prim_id(scene_delegate, object); path = p_id.AppendElementString(path.GetName()); @@ -124,6 +124,28 @@ void InstancerData::update(Object *object) } ObjectData *obj_data = it->second.obj_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(p_id, bits); + } +} + +void InstancerData::check_remove(Object *object) +{ + pxr::SdfPath path = ObjectData::prim_id(scene_delegate, object); + path = p_id.AppendElementString(path.GetName()); + auto it = instances.find(path); + if (it == instances.end()) { + return; + } + set_instances(); + scene_delegate->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( + p_id, pxr::HdChangeTracker::AllDirty); } void InstancerData::set_instances() @@ -197,7 +219,7 @@ void InstancerData::update() Object *object = (Object *)id; if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) { - init(); + set_instances(); bits |= pxr::HdChangeTracker::AllDirty; } else if (id->recalc & ID_RECALC_TRANSFORM) { diff --git a/source/blender/render/hydra/scene_delegate/instancer.h b/source/blender/render/hydra/scene_delegate/instancer.h index 8666f7c42144..6277f1ce8b27 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -35,7 +35,8 @@ class InstancerData : public ObjectData { pxr::VtIntArray indices(pxr::SdfPath const &id); ObjectData *object_data(pxr::SdfPath const &id); pxr::SdfPathVector prototypes(); - void update(Object *object); + void check_update(Object *object); + void check_remove(Object *object); private: void set_instances(); -- 2.30.2 From a5d7819d035d3c5395b23d7290f3ce5afeb471c5 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 13 Apr 2023 12:36:38 +0300 Subject: [PATCH 08/15] Fixed visibility --- .../hydra/scene_delegate/blender_scene_delegate.cc | 7 +++++-- .../blender/render/hydra/scene_delegate/instancer.cc | 10 +++++++--- source/blender/render/hydra/scene_delegate/instancer.h | 2 +- 3 files changed, 13 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 8c9a0b76a55a..b2b4071a1ffa 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -88,8 +88,11 @@ void BlenderSceneDelegate::update_collection(bool remove, bool visibility) { if (visibility) { /* Check and update visibility */ - for (auto &obj : objects) { - obj.second->update_visibility(view3d); + for (auto &it : objects) { + it.second->update_visibility(view3d); + } + for (auto &it : instancers) { + it.second->update_visibility(view3d); } } diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index 7fedf0f37f21..4bb0da8a750d 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -71,6 +71,11 @@ bool InstancerData::update_visibility(View3D *view3d) if (ret) { scene_delegate->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( p_id, pxr::HdChangeTracker::DirtyVisibility); + for (auto &it : instances) { + it.second.obj_data->visible = visible; + scene_delegate->GetRenderIndex().GetChangeTracker().MarkRprimDirty( + it.second.obj_data->p_id, pxr::HdChangeTracker::DirtyVisibility); + } } return ret; } @@ -135,10 +140,9 @@ void InstancerData::check_update(Object *object) } } -void InstancerData::check_remove(Object *object) +void InstancerData::check_remove(pxr::SdfPath const &obj_id) { - pxr::SdfPath path = ObjectData::prim_id(scene_delegate, object); - path = p_id.AppendElementString(path.GetName()); + pxr::SdfPath path = p_id.AppendElementString(obj_id.GetName()); auto it = instances.find(path); if (it == instances.end()) { return; diff --git a/source/blender/render/hydra/scene_delegate/instancer.h b/source/blender/render/hydra/scene_delegate/instancer.h index 6277f1ce8b27..4fc964bfafdd 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -36,7 +36,7 @@ class InstancerData : public ObjectData { ObjectData *object_data(pxr::SdfPath const &id); pxr::SdfPathVector prototypes(); void check_update(Object *object); - void check_remove(Object *object); + void check_remove(pxr::SdfPath const &obj_id); private: void set_instances(); -- 2.30.2 From 87625b0da8aacf81293722efceb6ef5049f38de6 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 13 Apr 2023 13:46:18 +0300 Subject: [PATCH 09/15] Fixing remove --- .../hydra/scene_delegate/blender_scene_delegate.cc | 7 +++++-- .../blender/render/hydra/scene_delegate/instancer.cc | 10 ++++++++++ source/blender/render/hydra/scene_delegate/instancer.h | 1 + 3 files changed, 16 insertions(+), 2 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 b2b4071a1ffa..a7f434540c9e 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -147,8 +147,8 @@ void BlenderSceneDelegate::update_collection(bool remove, bool visibility) /* remove unused materials */ std::set available_materials; - for (auto &obj : objects) { - MeshData *m_data = dynamic_cast(obj.second.get()); + for (auto &it : objects) { + MeshData *m_data = dynamic_cast(it.second.get()); if (!m_data) { continue; } @@ -157,6 +157,9 @@ void BlenderSceneDelegate::update_collection(bool remove, bool visibility) available_materials.insert(mat_id); } } + for (auto &it : instancers) { + it.second->available_materials(available_materials); + } for (auto it = materials.begin(); it != materials.end(); ++it) { if (available_materials.find(it->first) != available_materials.end()) { continue; diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index 4bb0da8a750d..597a6cf24be6 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -152,6 +152,16 @@ void InstancerData::check_remove(pxr::SdfPath const &obj_id) p_id, pxr::HdChangeTracker::AllDirty); } +void InstancerData::available_materials(std::set &paths) +{ + for (auto &it : instances) { + pxr::SdfPath mat_id = ((MeshData *)it.second.obj_data.get())->material_id(); + if (!mat_id.IsEmpty()) { + paths.insert(mat_id); + } + } +} + void InstancerData::set_instances() { transforms.clear(); diff --git a/source/blender/render/hydra/scene_delegate/instancer.h b/source/blender/render/hydra/scene_delegate/instancer.h index 4fc964bfafdd..0c4f01b3a909 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -37,6 +37,7 @@ class InstancerData : public ObjectData { pxr::SdfPathVector prototypes(); void check_update(Object *object); void check_remove(pxr::SdfPath const &obj_id); + void available_materials(std::set &paths); private: void set_instances(); -- 2.30.2 From 2223d8b4426947b13a0e3e444a8cd23643a16978 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 13 Apr 2023 14:01:54 +0300 Subject: [PATCH 10/15] Improve logging --- .../blender/render/hydra/scene_delegate/light.cc | 10 +++++----- .../render/hydra/scene_delegate/material.cc | 14 +++++++------- source/blender/render/hydra/scene_delegate/mesh.cc | 10 +++++----- .../blender/render/hydra/scene_delegate/world.cc | 10 +++++----- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/light.cc b/source/blender/render/hydra/scene_delegate/light.cc index 3b104e7f11e1..75b7d635c18d 100644 --- a/source/blender/render/hydra/scene_delegate/light.cc +++ b/source/blender/render/hydra/scene_delegate/light.cc @@ -17,12 +17,12 @@ namespace blender::render::hydra { LightData::LightData(BlenderSceneDelegate *scene_delegate, Object *object) : ObjectData(scene_delegate, object) { - CLOG_INFO(LOG_BSD, 2, "%s id=%s", id->name, p_id.GetText()); + ID_LOG(2, ""); } void LightData::init() { - CLOG_INFO(LOG_BSD, 2, "%s", id->name); + ID_LOG(2, ""); Light *light = (Light *)((Object *)id)->data; data.clear(); @@ -154,19 +154,19 @@ bool LightData::update_visibility(View3D *view3d) void LightData::insert() { - CLOG_INFO(LOG_BSD, 2, "%s", id->name); + ID_LOG(2, ""); scene_delegate->GetRenderIndex().InsertSprim(p_type, scene_delegate, p_id); } void LightData::remove() { - CLOG_INFO(LOG_BSD, 2, "%s", id->name); + ID_LOG(2, ""); scene_delegate->GetRenderIndex().RemoveSprim(p_type, p_id); } void LightData::update() { - CLOG_INFO(LOG_BSD, 2, "%s", id->name); + ID_LOG(2, ""); Light *light = (Light *)((Object *)id)->data; if (prim_type(light) != p_type) { diff --git a/source/blender/render/hydra/scene_delegate/material.cc b/source/blender/render/hydra/scene_delegate/material.cc index 7d2bc1c97a17..fad86c9ccd67 100644 --- a/source/blender/render/hydra/scene_delegate/material.cc +++ b/source/blender/render/hydra/scene_delegate/material.cc @@ -42,12 +42,12 @@ MaterialData::MaterialData(BlenderSceneDelegate *scene_delegate, Material *mater : IdData(scene_delegate, (ID *)material) { p_id = prim_id(scene_delegate, material); - CLOG_INFO(LOG_BSD, 2, "%s, id=%s", id->name, p_id.GetText()); + ID_LOG(2, ""); } void MaterialData::init() { - CLOG_INFO(LOG_BSD, 2, "%s", id->name); + ID_LOG(2, ""); material_network_map = pxr::VtValue(); @@ -84,7 +84,7 @@ void MaterialData::init() PyGILState_Release(gstate); mtlx_path = pxr::SdfAssetPath(path, path); - CLOG_INFO(LOG_BSD, 2, "Export: %s, mtlx=%s", id->name, mtlx_path.GetResolvedPath().c_str()); + ID_LOG(2, "mtlx=%s", mtlx_path.GetResolvedPath().c_str()); } pxr::VtValue MaterialData::get_data(pxr::TfToken const &key) const @@ -94,7 +94,7 @@ pxr::VtValue MaterialData::get_data(pxr::TfToken const &key) const if (!mtlx_path.GetResolvedPath().empty()) { ret = mtlx_path; } - CLOG_INFO(LOG_BSD, 3, "%s", key.GetText()); + ID_LOG(3, "%s", key.GetText()); } return ret; } @@ -121,20 +121,20 @@ pxr::VtValue MaterialData::material_resource() void MaterialData::insert() { - CLOG_INFO(LOG_BSD, 2, "%s", id->name); + ID_LOG(2, ""); scene_delegate->GetRenderIndex().InsertSprim( pxr::HdPrimTypeTokens->material, scene_delegate, p_id); } void MaterialData::remove() { - CLOG_INFO(LOG_BSD, 2, "%s", id->name); + ID_LOG(2, ""); scene_delegate->GetRenderIndex().RemoveSprim(pxr::HdPrimTypeTokens->material, p_id); } void MaterialData::update() { - CLOG_INFO(LOG_BSD, 2, "%s", id->name); + ID_LOG(2, ""); init(); scene_delegate->GetRenderIndex().GetChangeTracker().MarkSprimDirty(p_id, pxr::HdMaterial::AllDirty); diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index e2d44c017174..77057fc27713 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -18,7 +18,7 @@ namespace blender::render::hydra { MeshData::MeshData(BlenderSceneDelegate *scene_delegate, Object *object) : ObjectData(scene_delegate, object), mat_data(nullptr) { - CLOG_INFO(LOG_BSD, 2, "%s, id=%s", id->name, p_id.GetText()); + ID_LOG(2, ""); } pxr::VtValue MeshData::get_data(pxr::TfToken const &key) const @@ -167,7 +167,7 @@ void MeshData::set_material() void MeshData::init() { - CLOG_INFO(LOG_BSD, 2, "%s", id->name); + ID_LOG(2, ""); Object *object = (Object *)id; if (object->type == OB_MESH && object->mode == OB_MODE_OBJECT && @@ -191,7 +191,7 @@ void MeshData::insert() return; } - CLOG_INFO(LOG_BSD, 2, "%s", id->name); + ID_LOG(2, ""); scene_delegate->GetRenderIndex().InsertRprim(pxr::HdPrimTypeTokens->mesh, scene_delegate, p_id); } @@ -201,7 +201,7 @@ void MeshData::remove() return; } - CLOG_INFO(LOG_BSD, 2, "%s", id->name); + ID_LOG(2, ""); scene_delegate->GetRenderIndex().RemoveRprim(p_id); } @@ -237,7 +237,7 @@ void MeshData::update() remove(); return; } - CLOG_INFO(LOG_BSD, 2, "%s", id->name); + ID_LOG(2, ""); scene_delegate->GetRenderIndex().GetChangeTracker().MarkRprimDirty(p_id, bits); } diff --git a/source/blender/render/hydra/scene_delegate/world.cc b/source/blender/render/hydra/scene_delegate/world.cc index 993574853c7f..8d8d7c3bd2b0 100644 --- a/source/blender/render/hydra/scene_delegate/world.cc +++ b/source/blender/render/hydra/scene_delegate/world.cc @@ -47,12 +47,12 @@ WorldData::WorldData(BlenderSceneDelegate *scene_delegate, World *world, bContex : IdData(scene_delegate, (ID *)world), context(context) { p_id = prim_id(scene_delegate); - CLOG_INFO(LOG_BSD, 2, "%s, id=%s", id->name, p_id.GetText()); + ID_LOG(2, ""); } void WorldData::init() { - CLOG_INFO(LOG_BSD, 2, "%s", id->name); + ID_LOG(2, ""); World *world = (World *)id; data.clear(); @@ -150,20 +150,20 @@ pxr::VtValue WorldData::get_data(pxr::TfToken const &key) const void WorldData::insert() { - CLOG_INFO(LOG_BSD, 2, "%s", id->name); + ID_LOG(2, ""); scene_delegate->GetRenderIndex().InsertSprim( pxr::HdPrimTypeTokens->domeLight, scene_delegate, p_id); } void WorldData::remove() { - CLOG_INFO(LOG_BSD, 2, "%s", id->name); + ID_LOG(2, ""); scene_delegate->GetRenderIndex().RemoveSprim(pxr::HdPrimTypeTokens->domeLight, p_id); } void WorldData::update() { - CLOG_INFO(LOG_BSD, 2, "%s", id->name); + ID_LOG(2, ""); init(); scene_delegate->GetRenderIndex().GetChangeTracker().MarkSprimDirty(p_id, pxr::HdLight::AllDirty); } -- 2.30.2 From 4b533ffc2077a48a8988d756c5303f139a60ea4e Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 13 Apr 2023 15:17:19 +0300 Subject: [PATCH 11/15] Refactoring: update_collection() splitted to several functions --- .../scene_delegate/blender_scene_delegate.cc | 380 +++++++++--------- .../scene_delegate/blender_scene_delegate.h | 12 +- 2 files changed, 207 insertions(+), 185 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 a7f434540c9e..ac158cc22573 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -24,25 +24,6 @@ BlenderSceneDelegate::BlenderSceneDelegate(pxr::HdRenderIndex *parent_index, { } -void BlenderSceneDelegate::update_world() -{ - World *world = scene->world; - if (!world_data) { - if (world) { - world_data = WorldData::create(this, world, context); - } - } - else { - if (world) { - world_data->update(world); - } - else { - world_data->remove(); - world_data = nullptr; - } - } -} - bool BlenderSceneDelegate::GetVisible(pxr::SdfPath const &id) { if (id == WorldData::prim_id(this)) { @@ -84,93 +65,6 @@ pxr::GfMatrix4d BlenderSceneDelegate::GetInstancerTransform(pxr::SdfPath const & return i_data->transform(); } -void BlenderSceneDelegate::update_collection(bool remove, bool visibility) -{ - if (visibility) { - /* Check and update visibility */ - for (auto &it : objects) { - it.second->update_visibility(view3d); - } - for (auto &it : instancers) { - it.second->update_visibility(view3d); - } - } - - /* Export of new visible objects which were not exported before */ - std::set available_objects; - pxr::SdfPath id; - - DEGObjectIterSettings settings = {0}; - settings.depsgraph = depsgraph; - settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE | - DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET; - DEGObjectIterData data = {0}; - data.settings = &settings; - data.graph = settings.depsgraph; - data.flag = settings.flags; - ITER_BEGIN (DEG_iterator_objects_begin, - DEG_iterator_objects_next, - DEG_iterator_objects_end, - &data, - Object *, - object) { - - CLOG_INFO(LOG_BSD, 2, "Add %s", ((ID *)object)->name); - if (!ObjectData::supported(object)) { - continue; - } - - id = ObjectData::prim_id(this, object); - if (remove) { - available_objects.insert(id); - if ((object->transflag & OB_DUPLI) && InstancerData::supported(object)) { - available_objects.insert(InstancerData::prim_id(this, object)); - } - } - - if (!object_data(id)) { - add_update_object(object); - } - } - ITER_END; - - if (remove) { - /* remove unused objects */ - for (auto it = objects.begin(); it != objects.end(); ++it) { - if (available_objects.find(it->first) != available_objects.end()) { - continue; - } - it->second->remove(); - objects.erase(it); - it = objects.begin(); - } - - /* remove unused materials */ - 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); - } - } - for (auto &it : instancers) { - it.second->available_materials(available_materials); - } - for (auto it = materials.begin(); it != materials.end(); ++it) { - if (available_materials.find(it->first) != available_materials.end()) { - continue; - } - it->second->remove(); - materials.erase(it); - it = materials.begin(); - } - } -} - void BlenderSceneDelegate::add_update_object(Object *object) { if ((object->transflag & OB_DUPLI) && InstancerData::supported(object)) { @@ -257,82 +151,11 @@ void BlenderSceneDelegate::populate(Depsgraph *deps, bContext *cont) scene = DEG_get_input_scene(depsgraph); view3d = CTX_wm_view3d(context); - if (!is_populated) { - /* Export initial objects */ - update_collection(false, false); - update_world(); - return; + if (is_populated) { + check_updates(); } - - /* Working with updates */ - bool do_update_collection = false; - bool do_update_visibility = false; - bool do_update_world = false; - - unsigned int scene_recalc = ((ID *)scene)->recalc; - if (scene_recalc) { - /* Checking scene updates */ - CLOG_INFO(LOG_BSD, - 2, - "Update: %s [%s]", - ((ID *)scene)->name, - std::bitset<32>(scene_recalc).to_string().c_str()); - - if (scene_recalc & ID_RECALC_BASE_FLAGS) { - do_update_visibility = true; - } - if (scene_recalc & (ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY)) { - do_update_collection = true; - } - if (scene_recalc & ID_RECALC_AUDIO_VOLUME) { - if ((scene->world && !world_data) || (!scene->world && world_data)) { - do_update_world = true; - } - } - if (do_update_collection || do_update_visibility) { - update_collection(do_update_collection, do_update_visibility); - } - } - - /* Checking other objects 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) { - - CLOG_INFO( - LOG_BSD, 2, "Update: %s [%s]", id->name, std::bitset<32>(id->recalc).to_string().c_str()); - - switch (GS(id->name)) { - case ID_OB: { - Object *object = (Object *)id; - if (!ObjectData::supported(object)) { - break; - } - add_update_object(object); - } break; - - case ID_MA: { - MaterialData *mat_data = material_data(MaterialData::prim_id(this, (Material *)id)); - if (mat_data) { - mat_data->update(); - } - } break; - - case ID_WO: { - if (id->recalc & ID_RECALC_SHADING) { - do_update_world = true; - } - } break; - - default: - break; - } - } - ITER_END; - - if (do_update_world) { + else { + add_new_objects(); update_world(); } } @@ -426,6 +249,201 @@ pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id, return pxr::VtValue(); } + +void BlenderSceneDelegate::update_world() +{ + World *world = scene->world; + if (!world_data) { + if (world) { + world_data = WorldData::create(this, world, context); + } + } + else { + if (world) { + world_data->update(world); + } + else { + world_data->remove(); + world_data = nullptr; + } + } +} + +void BlenderSceneDelegate::check_updates() +{ + /* Working with updates */ + bool do_update_collection = false; + bool do_update_visibility = false; + bool do_update_world = false; + + unsigned int scene_recalc = scene->id.recalc; + if (scene_recalc) { + /* Checking scene updates */ + CLOG_INFO(LOG_BSD, + 2, + "Update: %s [%s]", + ((ID *)scene)->name, + std::bitset<32>(scene_recalc).to_string().c_str()); + + if (scene_recalc & ID_RECALC_BASE_FLAGS) { + do_update_visibility = true; + } + if (scene_recalc & (ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY)) { + do_update_collection = true; + } + if (scene_recalc & ID_RECALC_AUDIO_VOLUME) { + if ((scene->world && !world_data) || (!scene->world && world_data)) { + do_update_world = true; + } + } + } + + /* Checking other objects 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) { + + CLOG_INFO( + LOG_BSD, 2, "Update: %s [%s]", id->name, std::bitset<32>(id->recalc).to_string().c_str()); + + switch (GS(id->name)) { + case ID_OB: { + Object *object = (Object *)id; + if (!ObjectData::supported(object)) { + break; + } + add_update_object(object); + } break; + + case ID_MA: { + MaterialData *mat_data = material_data(MaterialData::prim_id(this, (Material *)id)); + if (mat_data) { + mat_data->update(); + } + } break; + + case ID_WO: { + if (id->recalc & ID_RECALC_SHADING) { + do_update_world = true; + } + } break; + + default: + break; + } + } + ITER_END; + + if (do_update_world) { + update_world(); + } + if (do_update_collection) { + remove_unused_objects(); + } + if (do_update_visibility) { + update_visibility(); + } +} + +void BlenderSceneDelegate::add_new_objects() +{ + DEGObjectIterSettings settings = {0}; + settings.depsgraph = depsgraph; + settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE | + DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET; + DEGObjectIterData data = {0}; + data.settings = &settings; + data.graph = settings.depsgraph; + data.flag = settings.flags; + ITER_BEGIN (DEG_iterator_objects_begin, + DEG_iterator_objects_next, + DEG_iterator_objects_end, + &data, + Object *, + object) { + + if (!ObjectData::supported(object)) { + continue; + } + + add_update_object(object); + } + ITER_END; +} + +void BlenderSceneDelegate::remove_unused_objects() +{ + /* Export of new visible objects which were not exported before */ + std::set available_objects; + + DEGObjectIterSettings settings = {0}; + settings.depsgraph = depsgraph; + settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET; + DEGObjectIterData data = {0}; + data.settings = &settings; + data.graph = settings.depsgraph; + data.flag = settings.flags; + ITER_BEGIN (DEG_iterator_objects_begin, + DEG_iterator_objects_next, + DEG_iterator_objects_end, + &data, + Object *, + object) { + if (!ObjectData::supported(object)) { + continue; + } + available_objects.insert(ObjectData::prim_id(this, object)); + available_objects.insert(InstancerData::prim_id(this, object)); + } + ITER_END; + + /* remove unused objects */ + for (auto it = objects.begin(); it != objects.end(); ++it) { + if (available_objects.find(it->first) != available_objects.end()) { + continue; + } + it->second->remove(); + objects.erase(it); + it = objects.begin(); + } + + /* remove unused materials */ + 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); + } + } + for (auto &it : instancers) { + it.second->available_materials(available_materials); + } + for (auto it = materials.begin(); it != materials.end(); ++it) { + if (available_materials.find(it->first) != available_materials.end()) { + continue; + } + it->second->remove(); + materials.erase(it); + it = materials.begin(); + } +} + +void BlenderSceneDelegate::update_visibility() +{ + for (auto &it : objects) { + it.second->update_visibility(view3d); + } + for (auto &it : instancers) { + it.second->update_visibility(view3d); + } +} + void BlenderSceneDelegate::clear() { for (auto &it : materials) { 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 d4fd46f9b4c3..ea71f84bb99d 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h @@ -32,9 +32,6 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate { BlenderSceneDelegate::EngineType engine_type); ~BlenderSceneDelegate() override = default; - void populate(Depsgraph *depsgraph, bContext *context); - void clear(); - // delegate methods pxr::HdMeshTopology GetMeshTopology(pxr::SdfPath const &id) override; pxr::GfMatrix4d GetTransform(pxr::SdfPath const &id) override; @@ -51,6 +48,9 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate { pxr::SdfPath const &prototype_id) override; pxr::GfMatrix4d GetInstancerTransform(pxr::SdfPath const &instancer_id) override; + void populate(Depsgraph *depsgraph, bContext *context); + void clear(); + EngineType engine_type; private: @@ -63,7 +63,11 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate { void add_update_object(Object *object); void add_update_instancer(Object *object); void update_world(); - void update_collection(bool remove, bool visibility); + void check_updates(); + void add_new_objects(); + void remove_unused_objects(); + void update_visibility(); + private: Depsgraph *depsgraph; -- 2.30.2 From 44e7e31f459639cfa0f135600963fb14f8f8a442 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 13 Apr 2023 16:34:41 +0300 Subject: [PATCH 12/15] Fixed remove object from instancer --- .../scene_delegate/blender_scene_delegate.cc | 53 ++++++++++++++++--- .../render/hydra/scene_delegate/instancer.cc | 25 +++++---- .../render/hydra/scene_delegate/instancer.h | 2 +- .../render/hydra/scene_delegate/light.cc | 2 +- .../render/hydra/scene_delegate/mesh.cc | 2 +- 5 files changed, 65 insertions(+), 19 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 ac158cc22573..a38c20bfbe97 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -375,8 +375,8 @@ void BlenderSceneDelegate::add_new_objects() void BlenderSceneDelegate::remove_unused_objects() { - /* Export of new visible objects which were not exported before */ - std::set available_objects; + /* Get available objects */ + std::set available_objects; DEGObjectIterSettings settings = {0}; settings.depsgraph = depsgraph; @@ -394,14 +394,26 @@ void BlenderSceneDelegate::remove_unused_objects() if (!ObjectData::supported(object)) { continue; } - available_objects.insert(ObjectData::prim_id(this, object)); - available_objects.insert(InstancerData::prim_id(this, object)); + available_objects.insert(ObjectData::prim_id(this, object).GetName()); + available_objects.insert(InstancerData::prim_id(this, object).GetName()); } ITER_END; - /* remove unused objects */ + /* Remove unused instancers */ + for (auto it = instancers.begin(); it != instancers.end(); ++it) { + if (available_objects.find(it->first.GetName()) != available_objects.end()) { + /* Remove objects from instancers */ + it->second->check_remove(available_objects); + continue; + } + it->second->remove(); + instancers.erase(it); + it = instancers.begin(); + } + + /* Remove unused objects */ for (auto it = objects.begin(); it != objects.end(); ++it) { - if (available_objects.find(it->first) != available_objects.end()) { + if (available_objects.find(it->first.GetName()) != available_objects.end()) { continue; } it->second->remove(); @@ -409,7 +421,8 @@ void BlenderSceneDelegate::remove_unused_objects() it = objects.begin(); } - /* remove unused materials */ + + /* Remove unused materials */ std::set available_materials; for (auto &it : objects) { MeshData *m_data = dynamic_cast(it.second.get()); @@ -442,6 +455,32 @@ void BlenderSceneDelegate::update_visibility() for (auto &it : instancers) { it.second->update_visibility(view3d); } + + /* Add objects which were invisible before and not added yet */ + DEGObjectIterSettings settings = {0}; + settings.depsgraph = depsgraph; + settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE | + DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET; + DEGObjectIterData data = {0}; + data.settings = &settings; + data.graph = settings.depsgraph; + data.flag = settings.flags; + ITER_BEGIN (DEG_iterator_objects_begin, + DEG_iterator_objects_next, + DEG_iterator_objects_end, + &data, + Object *, + object) { + + if (!ObjectData::supported(object)) { + continue; + } + + if (!object_data(ObjectData::prim_id(this, object))) { + add_update_object(object); + } + } + ITER_END; } void BlenderSceneDelegate::clear() diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index 597a6cf24be6..91dfd6505ad1 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -140,16 +140,23 @@ void InstancerData::check_update(Object *object) } } -void InstancerData::check_remove(pxr::SdfPath const &obj_id) +void InstancerData::check_remove(std::set &available_objects) { - pxr::SdfPath path = p_id.AppendElementString(obj_id.GetName()); - auto it = instances.find(path); - if (it == instances.end()) { - return; + bool ret = false; + for (auto it = instances.begin(); it != 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(); + ret = true; + } + if (ret) { + set_instances(); + scene_delegate->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(p_id, + pxr::HdChangeTracker::AllDirty); } - set_instances(); - scene_delegate->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( - p_id, pxr::HdChangeTracker::AllDirty); } void InstancerData::available_materials(std::set &paths) @@ -218,7 +225,7 @@ void InstancerData::insert() void InstancerData::remove() { - ID_LOG(2, ""); + CLOG_INFO(LOG_BSD, 2, "%s", p_id.GetText()); for (auto &it : instances) { it.second.obj_data->remove(); } diff --git a/source/blender/render/hydra/scene_delegate/instancer.h b/source/blender/render/hydra/scene_delegate/instancer.h index 0c4f01b3a909..848f6b426a63 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -36,7 +36,7 @@ class InstancerData : public ObjectData { ObjectData *object_data(pxr::SdfPath const &id); pxr::SdfPathVector prototypes(); void check_update(Object *object); - void check_remove(pxr::SdfPath const &obj_id); + void check_remove(std::set &available_objects); void available_materials(std::set &paths); private: diff --git a/source/blender/render/hydra/scene_delegate/light.cc b/source/blender/render/hydra/scene_delegate/light.cc index 75b7d635c18d..bd5169b34d72 100644 --- a/source/blender/render/hydra/scene_delegate/light.cc +++ b/source/blender/render/hydra/scene_delegate/light.cc @@ -160,7 +160,7 @@ void LightData::insert() void LightData::remove() { - ID_LOG(2, ""); + CLOG_INFO(LOG_BSD, 2, "%s", p_id.GetText()); scene_delegate->GetRenderIndex().RemoveSprim(p_type, p_id); } diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index 77057fc27713..fdb558aaa9ba 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -201,7 +201,7 @@ void MeshData::remove() return; } - ID_LOG(2, ""); + CLOG_INFO(LOG_BSD, 2, "%s", p_id.GetText()); scene_delegate->GetRenderIndex().RemoveRprim(p_id); } -- 2.30.2 From cae406cd600a5b50a6a5e7ef35493e580b76ddf7 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Thu, 13 Apr 2023 16:44:55 +0300 Subject: [PATCH 13/15] Cleanup --- source/blender/render/hydra/scene_delegate/material.cc | 1 - source/blender/render/hydra/scene_delegate/world.cc | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/source/blender/render/hydra/scene_delegate/material.cc b/source/blender/render/hydra/scene_delegate/material.cc index fad86c9ccd67..d31056690f34 100644 --- a/source/blender/render/hydra/scene_delegate/material.cc +++ b/source/blender/render/hydra/scene_delegate/material.cc @@ -101,7 +101,6 @@ pxr::VtValue MaterialData::get_data(pxr::TfToken const &key) const pxr::VtValue MaterialData::material_resource() { - return material_network_map; if (material_network_map.IsEmpty()) { const std::string &path = mtlx_path.GetResolvedPath(); if (!path.empty()) { diff --git a/source/blender/render/hydra/scene_delegate/world.cc b/source/blender/render/hydra/scene_delegate/world.cc index 8d8d7c3bd2b0..71de469f2a71 100644 --- a/source/blender/render/hydra/scene_delegate/world.cc +++ b/source/blender/render/hydra/scene_delegate/world.cc @@ -157,7 +157,7 @@ void WorldData::insert() void WorldData::remove() { - ID_LOG(2, ""); + CLOG_INFO(LOG_BSD, 2, "%s", p_id.GetText()); scene_delegate->GetRenderIndex().RemoveSprim(pxr::HdPrimTypeTokens->domeLight, p_id); } -- 2.30.2 From a788c49c42e0521cd36ea826d1c5993362d0c2cd Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 14 Apr 2023 15:23:17 +0300 Subject: [PATCH 14/15] Improved working with instancers --- .../scene_delegate/blender_scene_delegate.cc | 45 ++++++++++++------- .../scene_delegate/blender_scene_delegate.h | 4 +- .../render/hydra/scene_delegate/material.cc | 2 +- 3 files changed, 33 insertions(+), 18 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 a38c20bfbe97..8730ab1092ae 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -65,15 +65,11 @@ pxr::GfMatrix4d BlenderSceneDelegate::GetInstancerTransform(pxr::SdfPath const & return i_data->transform(); } -void BlenderSceneDelegate::add_update_object(Object *object) +void BlenderSceneDelegate::update_objects(Object *object) { - if ((object->transflag & OB_DUPLI) && InstancerData::supported(object)) { - add_update_instancer(object); + if (!ObjectData::supported(object)) { + return; } - for (auto &it : instancers) { - it.second->check_update(object); - } - pxr::SdfPath id = ObjectData::prim_id(this, object); ObjectData *obj_data = object_data(id); if (obj_data) { @@ -88,12 +84,29 @@ void BlenderSceneDelegate::add_update_object(Object *object) obj_data->update_visibility(view3d); } -void BlenderSceneDelegate::add_update_instancer(Object *object) +void BlenderSceneDelegate::update_instancers(Object *object) { + /* Check object inside instancers */ + for (auto &it : instancers) { + it.second->check_update(object); + } + pxr::SdfPath id = InstancerData::prim_id(this, object); InstancerData *i_data = instancer_data(id); if (i_data) { - i_data->update(); + if (object->transflag & OB_DUPLI) { + i_data->update(); + } + else { + i_data->remove(); + instancers.erase(id); + } + return; + } + if ((object->transflag & OB_DUPLI) == 0) { + return; + } + if (view3d && !BKE_object_is_visible_in_viewport(view3d, object)) { return; } instancers[id] = InstancerData::create(this, object); @@ -311,10 +324,8 @@ void BlenderSceneDelegate::check_updates() switch (GS(id->name)) { case ID_OB: { Object *object = (Object *)id; - if (!ObjectData::supported(object)) { - break; - } - add_update_object(object); + update_objects(object); + update_instancers(object); } break; case ID_MA: { @@ -368,7 +379,8 @@ void BlenderSceneDelegate::add_new_objects() continue; } - add_update_object(object); + update_objects(object); + update_instancers(object); } ITER_END; } @@ -477,7 +489,10 @@ void BlenderSceneDelegate::update_visibility() } if (!object_data(ObjectData::prim_id(this, object))) { - add_update_object(object); + update_objects(object); + } + if (!instancer_data(InstancerData::prim_id(this, object))) { + update_instancers(object); } } ITER_END; 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 ea71f84bb99d..724bfc02fe0c 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h @@ -60,8 +60,8 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate { MaterialData *material_data(pxr::SdfPath const &id); InstancerData *instancer_data(pxr::SdfPath const &id); - void add_update_object(Object *object); - void add_update_instancer(Object *object); + void update_objects(Object *object); + void update_instancers(Object *object); void update_world(); void check_updates(); void add_new_objects(); diff --git a/source/blender/render/hydra/scene_delegate/material.cc b/source/blender/render/hydra/scene_delegate/material.cc index d31056690f34..5738f89d6dd5 100644 --- a/source/blender/render/hydra/scene_delegate/material.cc +++ b/source/blender/render/hydra/scene_delegate/material.cc @@ -127,7 +127,7 @@ void MaterialData::insert() void MaterialData::remove() { - ID_LOG(2, ""); + CLOG_INFO(LOG_BSD, 2, "%s", p_id.GetText()); scene_delegate->GetRenderIndex().RemoveSprim(pxr::HdPrimTypeTokens->material, p_id); } -- 2.30.2 From 26fe283bedda2df343bf409df4ef029f20aeae78 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Tue, 18 Apr 2023 18:05:40 +0300 Subject: [PATCH 15/15] Fixes after merging --- .../scene_delegate/blender_scene_delegate.cc | 682 ++++++++---------- .../blender/render/hydra/scene_delegate/id.h | 3 + .../render/hydra/scene_delegate/instancer.cc | 99 ++- .../render/hydra/scene_delegate/instancer.h | 7 +- 4 files changed, 352 insertions(+), 439 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 b6a3729db414..d9c9cb912448 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -20,24 +20,6 @@ BlenderSceneDelegate::BlenderSceneDelegate(pxr::HdRenderIndex *parent_index, { } -void BlenderSceneDelegate::populate(Depsgraph *deps, bContext *cont) -{ - bool is_populated = depsgraph_ != nullptr; - - depsgraph_ = deps; - context_ = cont; - scene_ = DEG_get_input_scene(depsgraph_); - view3d_ = CTX_wm_view3d(context_); - - if (is_populated) { - check_updates(); - } - else { - add_new_objects(); - update_world(); - } -} - pxr::HdMeshTopology BlenderSceneDelegate::GetMeshTopology(pxr::SdfPath const &id) { CLOG_INFO(LOG_BSD, 3, "%s", id.GetText()); @@ -45,6 +27,21 @@ pxr::HdMeshTopology BlenderSceneDelegate::GetMeshTopology(pxr::SdfPath const &id return m_data->mesh_topology(); } +pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id) +{ + CLOG_INFO(LOG_BSD, 3, "%s", id.GetText()); + ObjectData *obj_data = object_data(id); + if (obj_data) { + return obj_data->transform(); + } + + if (id == WorldData::prim_id(this)) { + return world_data_->transform(); + } + + return pxr::GfMatrix4d(); +} + pxr::VtValue BlenderSceneDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const &key) { CLOG_INFO(LOG_BSD, 3, "%s, %s", id.GetText(), key.GetText()); @@ -67,6 +64,19 @@ pxr::VtValue BlenderSceneDelegate::Get(pxr::SdfPath const &id, pxr::TfToken cons return pxr::VtValue(); } +pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id, + pxr::TfToken const &key) +{ + LightData *l_data = light_data(id); + if (l_data) { + return l_data->get_data(key); + } + if (id == WorldData::prim_id(this)) { + return world_data_->get_data(key); + } + return pxr::VtValue(); +} + pxr::HdPrimvarDescriptorVector BlenderSceneDelegate::GetPrimvarDescriptors( pxr::SdfPath const &id, pxr::HdInterpolation interpolation) { @@ -94,55 +104,194 @@ pxr::VtValue BlenderSceneDelegate::GetMaterialResource(pxr::SdfPath const &id) { MaterialData *mat_data = material_data(id); if (mat_data) { - return mat_data->material_resource(); + return mat_data->get_material_resource(); } return pxr::VtValue(); } -pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id) +bool BlenderSceneDelegate::GetVisible(pxr::SdfPath const &id) { - CLOG_INFO(LOG_BSD, 3, "%s", id.GetText()); + if (id == WorldData::prim_id(this)) { + return true; + } + + return object_data(id)->visible; +} + +pxr::SdfPath BlenderSceneDelegate::GetInstancerId(pxr::SdfPath const &prim_id) +{ + CLOG_INFO(LOG_BSD, 3, "%s", prim_id.GetText()); + InstancerData *i_data = instancer_data(prim_id.GetParentPath()); + if (i_data) { + return i_data->p_id_; + } + return pxr::SdfPath(); +} + +pxr::SdfPathVector BlenderSceneDelegate::GetInstancerPrototypes(pxr::SdfPath const &instancer_id) +{ + CLOG_INFO(LOG_BSD, 3, "%s", instancer_id.GetText()); + InstancerData *i_data = instancer_data(instancer_id); + return i_data->prototypes(); +} + +pxr::VtIntArray BlenderSceneDelegate::GetInstanceIndices(pxr::SdfPath const &instancer_id, + pxr::SdfPath const &prototype_id) +{ + CLOG_INFO(LOG_BSD, 3, "%s, %s", instancer_id.GetText(), prototype_id.GetText()); + InstancerData *i_data = instancer_data(instancer_id); + return i_data->indices(prototype_id); +} + +pxr::GfMatrix4d BlenderSceneDelegate::GetInstancerTransform(pxr::SdfPath const &instancer_id) +{ + CLOG_INFO(LOG_BSD, 3, "%s", instancer_id.GetText()); + InstancerData *i_data = instancer_data(instancer_id); + return i_data->transform(); +} + +void BlenderSceneDelegate::populate(Depsgraph * deps, bContext * cont) +{ + bool is_populated = depsgraph_ != nullptr; + + depsgraph_ = deps; + context_ = cont; + scene_ = DEG_get_input_scene(depsgraph_); + view3d_ = CTX_wm_view3d(context_); + + if (is_populated) { + check_updates(); + } + else { + add_new_objects(); + update_world(); + } +} + +void BlenderSceneDelegate::clear() +{ + for (auto &it : objects_) { + it.second->remove(); + } + + for (auto &it : instancers_) { + it.second->remove(); + } + + for (auto &it : materials_) { + it.second->remove(); + } + + objects_.clear(); + instancers_.clear(); + materials_.clear(); +} + +ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id) +{ + auto it = objects_.find(id); + if (it != objects_.end()) { + return it->second.get(); + } + InstancerData *i_data = instancer_data(id.GetParentPath()); + if (i_data) { + return i_data->object_data(id); + } + return nullptr; +} + +MeshData *BlenderSceneDelegate::mesh_data(pxr::SdfPath const &id) +{ + return dynamic_cast(object_data(id)); +} + +LightData *BlenderSceneDelegate::light_data(pxr::SdfPath const &id) +{ + return dynamic_cast(object_data(id)); +} + +MaterialData *BlenderSceneDelegate::material_data(pxr::SdfPath const &id) +{ + auto it = materials_.find(id); + if (it == materials_.end()) { + return nullptr; + } + return it->second.get(); +} + +InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id) +{ + auto it = instancers_.find(id); + if (it != instancers_.end()) { + return it->second.get(); + } + return nullptr; +} + +void BlenderSceneDelegate::update_objects(Object *object) +{ + if (!ObjectData::is_supported(object)) { + return; + } + pxr::SdfPath id = ObjectData::prim_id(this, object); ObjectData *obj_data = object_data(id); if (obj_data) { - return obj_data->transform(); + obj_data->update(); + return; } - - if (id == WorldData::prim_id(this)) { - return world_data->transform(); + if (view3d_ && !BKE_object_is_visible_in_viewport(view3d_, object)) { + return; } - - return pxr::GfMatrix4d(); + objects_[id] = ObjectData::create(this, object); + obj_data = object_data(id); + obj_data->update_visibility(view3d_); } -pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id, - pxr::TfToken const &key) +void BlenderSceneDelegate::update_instancers(Object *object) { - LightData *l_data = light_data(id); - if (l_data) { - return l_data->get_data(key); + /* Check object inside instancers */ + for (auto &it : instancers_) { + it.second->check_update(object); } - if (id == WorldData::prim_id(this)) { - return world_data->get_data(key); - } - return pxr::VtValue(); -} + pxr::SdfPath id = InstancerData::prim_id(this, object); + InstancerData *i_data = instancer_data(id); + if (i_data) { + if (object->transflag & OB_DUPLI) { + i_data->update(); + } + else { + i_data->remove(); + instancers_.erase(id); + } + return; + } + if ((object->transflag & OB_DUPLI) == 0) { + return; + } + if (view3d_ && !BKE_object_is_visible_in_viewport(view3d_, object)) { + return; + } + instancers_[id] = InstancerData::create(this, object); + i_data = instancer_data(id); + i_data->update_visibility(view3d_); +} void BlenderSceneDelegate::update_world() { - World *world = scene->world; - if (!world_data) { + World *world = scene_->world; + if (!world_data_) { if (world) { - world_data = WorldData::create(this, world, context); + world_data_ = WorldData::create(this, world, context_); } } else { if (world) { - world_data->update(world); + world_data_->update(world); } else { - world_data->remove(); - world_data = nullptr; + world_data_->remove(); + world_data_ = nullptr; } } } @@ -154,7 +303,7 @@ void BlenderSceneDelegate::check_updates() bool do_update_visibility = false; bool do_update_world = false; - unsigned int scene_recalc = scene_->id->recalc; + unsigned int scene_recalc = scene_->id.recalc; if (scene_recalc) { /* Checking scene updates */ CLOG_INFO(LOG_BSD, @@ -223,308 +372,8 @@ void BlenderSceneDelegate::check_updates() } } -void BlenderSceneDelegate::clear() +void BlenderSceneDelegate::add_new_objects() { - for (auto &it : materials_) { - it.second->remove(); - } - - for (auto &it : objects_) { - it.second->remove(); - } - - materials_.clear(); - objects_.clear(); -} - -pxr::HdMeshTopology BlenderSceneDelegate::GetMeshTopology(pxr::SdfPath const &id) -{ - DEGObjectIterSettings settings = {0}; - settings.depsgraph = depsgraph; - settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE | - DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET; - DEGObjectIterData data = {0}; - data.settings = &settings; - data.graph = settings.depsgraph; - data.flag = settings.flags; - ITER_BEGIN (DEG_iterator_objects_begin, - DEG_iterator_objects_next, - DEG_iterator_objects_end, - &data, - Object *, - object) { - -pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id) -{ - CLOG_INFO(LOG_BSD, 3, "%s", id.GetText()); - ObjectData *obj_data = object_data(id); - if (obj_data) { - return obj_data->transform(); - } - - if (id == WorldData::prim_id(this)) { - return world_data_->transform(); - } - - InstancerData *i_data = instancer_data(id); - if (i_data) { - return i_data->transform(); - } - - return pxr::GfMatrix4d(); -} - -pxr::VtValue BlenderSceneDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const &key) -{ - CLOG_INFO(LOG_BSD, 3, "%s, %s", id.GetText(), key.GetText()); - - update_objects(object); - update_instancers(object); - } - ITER_END; -} - -pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id, - pxr::TfToken const &key) -{ - LightData *l_data = light_data(id); - if (l_data) { - return l_data->get_data(key); - } - if (id == WorldData::prim_id(this)) { - return world_data_->get_data(key); - } - return pxr::VtValue(); -} - -pxr::HdPrimvarDescriptorVector BlenderSceneDelegate::GetPrimvarDescriptors( - pxr::SdfPath const &id, pxr::HdInterpolation interpolation) -{ - /* Get available objects */ - std::set available_objects; - - DEGObjectIterSettings settings = {0}; - settings.depsgraph = depsgraph; - settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET; - DEGObjectIterData data = {0}; - data.settings = &settings; - data.graph = settings.depsgraph; - data.flag = settings.flags; - ITER_BEGIN (DEG_iterator_objects_begin, - DEG_iterator_objects_next, - DEG_iterator_objects_end, - &data, - Object *, - object) { - if (!ObjectData::supported(object)) { - continue; - } - available_objects.insert(ObjectData::prim_id(this, object).GetName()); - available_objects.insert(InstancerData::prim_id(this, object).GetName()); - } - ITER_END; - - /* Remove unused instancers */ - for (auto it = instancers.begin(); it != instancers.end(); ++it) { - if (available_objects.find(it->first.GetName()) != available_objects.end()) { - /* Remove objects from instancers */ - it->second->check_remove(available_objects); - continue; - } - it->second->remove(); - instancers.erase(it); - it = instancers.begin(); - } - - /* Remove unused objects */ - for (auto it = objects.begin(); it != objects.end(); ++it) { - if (available_objects.find(it->first.GetName()) != available_objects.end()) { - continue; - } - it->second->remove(); - objects.erase(it); - it = objects.begin(); - } - - -pxr::VtValue BlenderSceneDelegate::GetMaterialResource(pxr::SdfPath const &id) -{ - MaterialData *mat_data = material_data(id); - if (mat_data) { - return mat_data->get_material_resource(); - } - for (auto &it : instancers) { - it.second->available_materials(available_materials); - } - for (auto it = materials.begin(); it != materials.end(); ++it) { - if (available_materials.find(it->first) != available_materials.end()) { - continue; - } - it->second->remove(); - materials.erase(it); - it = materials.begin(); - } -} - -bool BlenderSceneDelegate::GetVisible(pxr::SdfPath const &id) -{ - if (id == WorldData::prim_id(this)) { - return true; - } - - return object_data(id)->visible; -} - -pxr::SdfPath BlenderSceneDelegate::GetInstancerId(pxr::SdfPath const &prim_id) -{ - CLOG_INFO(LOG_BSD, 3, "%s", prim_id.GetText()); - InstancerData *i_data = instancer_data(prim_id, true); - if (i_data) { - return i_data->instancer_id; - } - return pxr::SdfPath(); -} - -pxr::SdfPathVector BlenderSceneDelegate::GetInstancerPrototypes(pxr::SdfPath const &instancer_id) -{ - CLOG_INFO(LOG_BSD, 3, "%s", instancer_id.GetText()); - pxr::SdfPathVector paths; - paths.push_back(instancer_id.GetParentPath()); - return paths; -} - -pxr::VtIntArray BlenderSceneDelegate::GetInstanceIndices(pxr::SdfPath const &instancer_id, - pxr::SdfPath const &prototype_id) -{ - CLOG_INFO(LOG_BSD, 3, "%s, %s", instancer_id.GetText(), prototype_id.GetText()); - InstancerData *i_data = instancer_data(instancer_id); - return i_data->instance_indices(); -} - -pxr::GfMatrix4d BlenderSceneDelegate::GetInstancerTransform(pxr::SdfPath const &instancer_id) -{ - CLOG_INFO(LOG_BSD, 3, "%s", instancer_id.GetText()); - InstancerData *i_data = instancer_data(instancer_id); - return i_data->transform(); -} - -ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id) -{ - auto it = objects_.find(id); - if (it == objects_.end()) { - return nullptr; - } - return it->second.get(); -} - -MeshData *BlenderSceneDelegate::mesh_data(pxr::SdfPath const &id) -{ - return dynamic_cast(object_data(id)); -} - -LightData *BlenderSceneDelegate::light_data(pxr::SdfPath const &id) -{ - return dynamic_cast(object_data(id)); -} - -MaterialData *BlenderSceneDelegate::material_data(pxr::SdfPath const &id) -{ - auto it = materials_.find(id); - if (it == materials_.end()) { - return nullptr; - } - return it->second.get(); -} - -InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id, bool base_prim) -{ - if (base_prim) { - return dynamic_cast(object_data(id)); - } - return dynamic_cast(object_data(id.GetParentPath())); -} - -InstancerData *BlenderSceneDelegate::instancer_data(Object *object) -{ - InstancerData *i_data; - for (auto &it : objects_) { - i_data = dynamic_cast(it.second.get()); - if (i_data && i_data->is_base(object)) { - return i_data; - } - } - return nullptr; -} - -void BlenderSceneDelegate::add_update_object(Object *object) -{ - if ((object->transflag & OB_DUPLI) && InstancerData::is_supported(object)) { - add_update_instancer(object); - } - InstancerData *i_data = instancer_data(object); - if (i_data) { - i_data->update(); - } - - pxr::SdfPath id = ObjectData::prim_id(this, object); - ObjectData *obj_data = object_data(id); - if (obj_data) { - obj_data->update(); - return; - } - if (view3d_ && !BKE_object_is_visible_in_viewport(view3d_, object)) { - return; - } - objects_[id] = ObjectData::create(this, object); - obj_data = object_data(id); - obj_data->update_visibility(view3d_); -} - -void BlenderSceneDelegate::add_update_instancer(Object *object) -{ - pxr::SdfPath id = InstancerData::prim_id(this, object); - InstancerData *i_data = instancer_data(id, true); - if (i_data) { - i_data->update(); - return; - } - objects_[id] = InstancerData::create(this, object); - i_data = instancer_data(id, true); - i_data->update_visibility(view3d_); -} - -void BlenderSceneDelegate::update_world() -{ - World *world = scene_->world; - if (!world_data_) { - if (world) { - world_data_ = WorldData::create(this, world, context_); - } - } - else { - if (world) { - world_data_->update(world); - } - else { - world_data_->remove(); - world_data_ = nullptr; - } - } -} - -void BlenderSceneDelegate::update_collection(bool remove, bool visibility) -{ - if (visibility) { - /* Check and update visibility */ - for (auto &obj : objects_) { - obj.second->update_visibility(view3d_); - } - } - - /* Export of new visible objects which were not exported before */ - std::set available_objects; - pxr::SdfPath id; - DEGObjectIterSettings settings = {0}; settings.depsgraph = depsgraph_; settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE | @@ -540,57 +389,126 @@ void BlenderSceneDelegate::update_collection(bool remove, bool visibility) Object *, object) { - CLOG_INFO(LOG_BSD, 2, "Add %s", ((ID *)object)->name); if (!ObjectData::is_supported(object)) { continue; } - id = ObjectData::prim_id(this, object); - if (remove) { - available_objects.insert(id); - if ((object->transflag & OB_DUPLI) && InstancerData::is_supported(object)) { - available_objects.insert(InstancerData::prim_id(this, object)); - } - } + update_objects(object); + update_instancers(object); + } + ITER_END; +} - if (!object_data(id)) { - add_update_object(object); +void BlenderSceneDelegate::remove_unused_objects() +{ + /* Get available objects */ + std::set available_objects; + + DEGObjectIterSettings settings = {0}; + settings.depsgraph = depsgraph_; + settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET; + DEGObjectIterData data = {0}; + data.settings = &settings; + data.graph = settings.depsgraph; + data.flag = settings.flags; + ITER_BEGIN (DEG_iterator_objects_begin, + DEG_iterator_objects_next, + DEG_iterator_objects_end, + &data, + Object *, + object) { + if (!ObjectData::is_supported(object)) { + continue; } + available_objects.insert(ObjectData::prim_id(this, object).GetName()); + available_objects.insert(InstancerData::prim_id(this, object).GetName()); } ITER_END; - if (remove) { - /* remove unused objects */ - for (auto it = objects_.begin(); it != objects_.end(); ++it) { - if (available_objects.find(it->first) != available_objects.end()) { - continue; - } - it->second->remove(); - objects_.erase(it); - it = objects_.begin(); + /* Remove unused instancers */ + for (auto it = instancers_.begin(); it != instancers_.end(); ++it) { + if (available_objects.find(it->first.GetName()) != available_objects.end()) { + /* Remove objects from instancers */ + it->second->check_remove(available_objects); + continue; } + it->second->remove(); + instancers_.erase(it); + it = instancers_.begin(); + } - /* remove unused materials */ - std::set available_materials; - for (auto &obj : objects_) { - MeshData *m_data = dynamic_cast(obj.second.get()); - if (!m_data) { - continue; - } - pxr::SdfPath mat_id = m_data->material_id(); - if (!mat_id.IsEmpty()) { - available_materials.insert(mat_id); - } + /* Remove unused objects */ + for (auto it = objects_.begin(); it != objects_.end(); ++it) { + if (available_objects.find(it->first.GetName()) != available_objects.end()) { + continue; } - for (auto it = materials_.begin(); it != materials_.end(); ++it) { - if (available_materials.find(it->first) != available_materials.end()) { - continue; - } - it->second->remove(); - materials_.erase(it); - it = materials_.begin(); + it->second->remove(); + objects_.erase(it); + it = objects_.begin(); + } + + /* Remove unused materials */ + 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); + } + } + for (auto &it : instancers_) { + it.second->available_materials(available_materials); + } + for (auto it = materials_.begin(); it != materials_.end(); ++it) { + if (available_materials.find(it->first) != available_materials.end()) { + continue; + } + it->second->remove(); + materials_.erase(it); + it = materials_.begin(); } } +void BlenderSceneDelegate::update_visibility() +{ + for (auto &it : objects_) { + it.second->update_visibility(view3d_); + } + for (auto &it : instancers_) { + it.second->update_visibility(view3d_); + } + + /* Add objects which were invisible before and not added yet */ + DEGObjectIterSettings settings = {0}; + settings.depsgraph = depsgraph_; + settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE | + DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET; + DEGObjectIterData data = {0}; + data.settings = &settings; + data.graph = settings.depsgraph; + data.flag = settings.flags; + ITER_BEGIN (DEG_iterator_objects_begin, + DEG_iterator_objects_next, + DEG_iterator_objects_end, + &data, + Object *, + object) { + + if (!ObjectData::is_supported(object)) { + continue; + } + + if (!object_data(ObjectData::prim_id(this, object))) { + update_objects(object); + } + if (!instancer_data(InstancerData::prim_id(this, object))) { + update_instancers(object); + } + } + ITER_END; +} + } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/scene_delegate/id.h b/source/blender/render/hydra/scene_delegate/id.h index 2b02095be752..15411cbb046f 100644 --- a/source/blender/render/hydra/scene_delegate/id.h +++ b/source/blender/render/hydra/scene_delegate/id.h @@ -12,8 +12,11 @@ namespace blender::render::hydra { class BlenderSceneDelegate; +class InstancerData; class IdData { + friend InstancerData; + public: IdData(BlenderSceneDelegate *scene_delegate, ID *id); virtual ~IdData() = default; diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index 040ecf3eee6c..87dadf4bd70f 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -10,12 +10,10 @@ namespace blender::render::hydra { InstancerData::InstancerData(BlenderSceneDelegate *scene_delegate, Object *object) - : MeshData(scene_delegate, object), parent_obj_(object) + : ObjectData(scene_delegate, object) { - id_ = nullptr; p_id_ = prim_id(scene_delegate, object); - instancer_id = p_id_.AppendElementString("Instancer"); - CLOG_INFO(LOG_BSD, 2, "%s, instancer_id=%s", ((ID *)parent_obj_)->name, instancer_id.GetText()); + ID_LOG(2, ""); } bool InstancerData::is_supported(Object *object) @@ -52,13 +50,6 @@ pxr::SdfPath InstancerData::prim_id(BlenderSceneDelegate *scene_delegate, Object return scene_delegate->GetDelegateID().AppendElementString(str); } -InstancerData::InstancerData(BlenderSceneDelegate *scene_delegate, Object *object) - : ObjectData(scene_delegate, object) -{ - p_id = prim_id(scene_delegate, object); - ID_LOG(2, ""); -} - void InstancerData::init() { ID_LOG(2, ""); @@ -68,19 +59,19 @@ void InstancerData::init() void InstancerData::insert() { ID_LOG(2, ""); - scene_delegate->GetRenderIndex().InsertInstancer(scene_delegate, p_id); - for (auto &it : instances) { + scene_delegate_->GetRenderIndex().InsertInstancer(scene_delegate_, p_id_); + for (auto &it : instances_) { it.second.obj_data->insert(); } } void InstancerData::remove() { - CLOG_INFO(LOG_BSD, 2, "%s", p_id.GetText()); - for (auto &it : instances) { + CLOG_INFO(LOG_BSD, 2, "%s", p_id_.GetText()); + for (auto &it : instances_) { it.second.obj_data->remove(); } - scene_delegate->GetRenderIndex().RemoveInstancer(p_id); + scene_delegate_->GetRenderIndex().RemoveInstancer(p_id_); } void InstancerData::update() @@ -89,17 +80,17 @@ void InstancerData::update() pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; - Object *object = (Object *)id; - if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) { + Object *object = (Object *)id_; + if ((id_->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) { set_instances(); bits |= pxr::HdChangeTracker::AllDirty; } - else if (id->recalc & ID_RECALC_TRANSFORM) { + else if (id_->recalc & ID_RECALC_TRANSFORM) { set_instances(); bits |= pxr::HdChangeTracker::DirtyTransform; } if (bits != pxr::HdChangeTracker::Clean) { - scene_delegate->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(p_id, bits); + scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(p_id_, bits); } } @@ -108,7 +99,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 = transforms_; } return ret; } @@ -126,12 +117,12 @@ bool InstancerData::update_visibility(View3D *view3d) bool ret = ObjectData::update_visibility(view3d); if (ret) { - scene_delegate->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( - p_id, pxr::HdChangeTracker::DirtyVisibility); - for (auto &it : instances) { + scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( + p_id_, pxr::HdChangeTracker::DirtyVisibility); + for (auto &it : instances_) { it.second.obj_data->visible = visible; - scene_delegate->GetRenderIndex().GetChangeTracker().MarkRprimDirty( - it.second.obj_data->p_id, pxr::HdChangeTracker::DirtyVisibility); + scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty( + it.second.obj_data->p_id_, pxr::HdChangeTracker::DirtyVisibility); } } return ret; @@ -149,18 +140,18 @@ pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors(pxr::HdInterpo pxr::VtIntArray InstancerData::indices(pxr::SdfPath const &id) { - return instances[id].indices; + return instances_[id].indices; } ObjectData *InstancerData::object_data(pxr::SdfPath const &id) { - return instances[id].obj_data.get(); + return instances_[id].obj_data.get(); } pxr::SdfPathVector InstancerData::prototypes() { pxr::SdfPathVector paths; - for (auto &it : instances) { + for (auto &it : instances_) { paths.push_back(it.first); } return paths; @@ -168,10 +159,10 @@ pxr::SdfPathVector InstancerData::prototypes() void InstancerData::check_update(Object *object) { - pxr::SdfPath path = ObjectData::prim_id(scene_delegate, object); - path = p_id.AppendElementString(path.GetName()); - auto it = instances.find(path); - if (it == instances.end()) { + pxr::SdfPath path = ObjectData::prim_id(scene_delegate_, object); + path = p_id_.AppendElementString(path.GetName()); + auto it = instances_.find(path); + if (it == instances_.end()) { return; } ObjectData *obj_data = it->second.obj_data.get(); @@ -183,32 +174,32 @@ void InstancerData::check_update(Object *object) bits |= pxr::HdChangeTracker::DirtyTransform; } if (bits != pxr::HdChangeTracker::Clean) { - scene_delegate->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(p_id, bits); + scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(p_id_, bits); } } void InstancerData::check_remove(std::set &available_objects) { bool ret = false; - for (auto it = instances.begin(); it != instances.end(); ++it) { + for (auto it = instances_.begin(); it != 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(); + instances_.erase(it); + it = instances_.begin(); ret = true; } if (ret) { set_instances(); - scene_delegate->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(p_id, + scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(p_id_, pxr::HdChangeTracker::AllDirty); } } void InstancerData::available_materials(std::set &paths) { - for (auto &it : instances) { + for (auto &it : instances_) { pxr::SdfPath mat_id = ((MeshData *)it.second.obj_data.get())->material_id(); if (!mat_id.IsEmpty()) { paths.insert(mat_id); @@ -218,25 +209,25 @@ void InstancerData::available_materials(std::set &paths) void InstancerData::set_instances() { - transforms.clear(); - for (auto &it : instances) { + transforms_.clear(); + for (auto &it : instances_) { it.second.indices.clear(); } int index = 0; Instance *inst; pxr::SdfPath path; - ListBase *lb = object_duplilist(scene_delegate->depsgraph, scene_delegate->scene, (Object *)id); + ListBase *lb = object_duplilist(scene_delegate_->depsgraph_, scene_delegate_->scene_, (Object *)id_); LISTBASE_FOREACH (DupliObject *, dupli, lb) { - path = ObjectData::prim_id(scene_delegate, dupli->ob); - path = p_id.AppendElementString(path.GetName()); - auto it = instances.find(path); - if (it == instances.end()) { - inst = &instances[path]; - if (!supported(dupli->ob)) { + path = ObjectData::prim_id(scene_delegate_, dupli->ob); + path = p_id_.AppendElementString(path.GetName()); + auto it = instances_.find(path); + if (it == instances_.end()) { + inst = &instances_[path]; + if (!is_supported(dupli->ob)) { continue; } - inst->obj_data = std::make_unique(scene_delegate, dupli->ob, path); + inst->obj_data = std::make_unique(scene_delegate_, dupli->ob, path); inst->obj_data->init(); inst->obj_data->insert(); } @@ -245,19 +236,19 @@ void InstancerData::set_instances() } transforms_.push_back(gf_matrix_from_transform(dupli->mat)); inst->indices.push_back(index); - ID_LOG(2, "Instance %s %d", inst->obj_data->id->name, index); + ID_LOG(2, "Instance %s %d", inst->obj_data->id_->name, index); ++index; } free_object_duplilist(lb); /* Remove intances without indices */ - for (auto it = instances.begin(); it != instances.end(); ++it) { + for (auto it = instances_.begin(); it != instances_.end(); ++it) { if (!it->second.indices.empty()) { continue; } it->second.obj_data->remove(); - instances.erase(it); - it = instances.begin(); + instances_.erase(it); + it = instances_.begin(); } } @@ -266,7 +257,7 @@ InstanceMeshData::InstanceMeshData(BlenderSceneDelegate *scene_delegate, pxr::SdfPath const &p_id) : MeshData(scene_delegate, object) { - this->p_id = p_id; + this->p_id_ = p_id; } pxr::GfMatrix4d InstanceMeshData::transform() diff --git a/source/blender/render/hydra/scene_delegate/instancer.h b/source/blender/render/hydra/scene_delegate/instancer.h index f42846ecac17..ddd23e6cc468 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -10,6 +10,8 @@ namespace blender::render::hydra { class InstancerData : public ObjectData { + friend BlenderSceneDelegate; + struct Instance { std::unique_ptr obj_data; pxr::VtIntArray indices; @@ -39,13 +41,12 @@ class InstancerData : public ObjectData { void check_update(Object *object); void check_remove(std::set &available_objects); void available_materials(std::set &paths); - bool is_base(Object *object) const; private: void set_instances(); - pxr::TfHashMap instances; - pxr::VtMatrix4dArray transforms; + pxr::TfHashMap instances_; + pxr::VtMatrix4dArray transforms_; }; using InstancerDataMap = -- 2.30.2