From ccd619bdb21dd7db95f3dc27651d5b2e37e08183 Mon Sep 17 00:00:00 2001 From: Dawid-Kurek Date: Fri, 18 Jul 2025 15:55:18 +0200 Subject: [PATCH] Hydra: Pass camera's custom croperties to render delegate Makes it possible to read custom camera properties in a render delegate, e.g with HdSceneDelegate::GetCameraParamValue(). Pull Request: https://projects.blender.org/blender/blender/pulls/138918 --- source/blender/io/usd/CMakeLists.txt | 2 + .../blender/io/usd/hydra/camera_delegate.cc | 68 +++++++++++++++++++ .../blender/io/usd/hydra/camera_delegate.hh | 29 ++++++++ .../io/usd/hydra/hydra_scene_delegate.cc | 10 ++- .../io/usd/hydra/hydra_scene_delegate.hh | 4 ++ source/blender/render/hydra/engine.cc | 5 +- source/blender/render/hydra/engine.hh | 4 +- 7 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 source/blender/io/usd/hydra/camera_delegate.cc create mode 100644 source/blender/io/usd/hydra/camera_delegate.hh diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt index 29200c9aef4..d44efbdcdcf 100644 --- a/source/blender/io/usd/CMakeLists.txt +++ b/source/blender/io/usd/CMakeLists.txt @@ -165,6 +165,7 @@ set(SRC if(WITH_HYDRA) list(APPEND SRC + hydra/camera_delegate.cc hydra/curves.cc hydra/hydra_scene_delegate.cc hydra/id.cc @@ -179,6 +180,7 @@ if(WITH_HYDRA) hydra/volume_modifier.cc hydra/world.cc + hydra/camera_delegate.hh hydra/curves.hh hydra/hydra_scene_delegate.hh hydra/id.hh diff --git a/source/blender/io/usd/hydra/camera_delegate.cc b/source/blender/io/usd/hydra/camera_delegate.cc new file mode 100644 index 00000000000..bb000debe9a --- /dev/null +++ b/source/blender/io/usd/hydra/camera_delegate.cc @@ -0,0 +1,68 @@ +/* SPDX-FileCopyrightText: 2025 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "camera_delegate.hh" + +#include "DNA_ID.h" +#include "DNA_camera_types.h" +#include "DNA_scene_types.h" + +#include "BKE_idprop.hh" + +#include + +namespace blender::io::hydra { + +static pxr::VtValue vt_value(const IDProperty *prop) +{ + switch (prop->type) { + case IDP_INT: + return pxr::VtValue{IDP_Int(prop)}; + case IDP_FLOAT: + return pxr::VtValue{IDP_Float(prop)}; + case IDP_BOOLEAN: + return pxr::VtValue{bool(IDP_Bool(prop))}; + } + return pxr::VtValue{}; +} + +CameraDelegate::CameraDelegate(pxr::HdRenderIndex *render_index, pxr::SdfPath const &delegate_id) + : pxr::HdxFreeCameraSceneDelegate{render_index, delegate_id} +{ +} + +void CameraDelegate::sync(const Scene *scene) +{ + if (!scene || !scene->camera) { + return; + } + + const Camera *camera = static_cast(scene->camera->data); + if (camera_ == camera) { + return; + } + + camera_ = camera; + GetRenderIndex().GetChangeTracker().MarkSprimDirty(GetCameraId(), pxr::HdCamera::DirtyParams); +} + +void CameraDelegate::update(const ID *camera) +{ + if (&camera_->id == camera) { + GetRenderIndex().GetChangeTracker().MarkSprimDirty(GetCameraId(), pxr::HdCamera::DirtyParams); + } +} + +pxr::VtValue CameraDelegate::GetCameraParamValue(pxr::SdfPath const &id, pxr::TfToken const &key) +{ + if (camera_ && camera_->id.properties) { + const IDProperty *prop = IDP_GetPropertyFromGroup(camera_->id.properties, key.GetText()); + if (prop) { + return vt_value(prop); + } + } + return pxr::HdxFreeCameraSceneDelegate::GetCameraParamValue(id, key); +} + +} // namespace blender::io::hydra diff --git a/source/blender/io/usd/hydra/camera_delegate.hh b/source/blender/io/usd/hydra/camera_delegate.hh new file mode 100644 index 00000000000..bee51142da7 --- /dev/null +++ b/source/blender/io/usd/hydra/camera_delegate.hh @@ -0,0 +1,29 @@ +/* SPDX-FileCopyrightText: 2025 Blender Authors + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include + +struct Camera; +struct ID; +struct Scene; + +namespace blender::io::hydra { + +class CameraDelegate : public pxr::HdxFreeCameraSceneDelegate { + public: + CameraDelegate(pxr::HdRenderIndex *render_index, pxr::SdfPath const &delegate_id); + ~CameraDelegate() override = default; + + void sync(const Scene *scene); + void update(const ID *camera); + + pxr::VtValue GetCameraParamValue(pxr::SdfPath const &id, pxr::TfToken const &key) override; + + private: + const Camera *camera_{nullptr}; +}; + +} // namespace blender::io::hydra diff --git a/source/blender/io/usd/hydra/hydra_scene_delegate.cc b/source/blender/io/usd/hydra/hydra_scene_delegate.cc index 8d99822c35b..1f19488e51d 100644 --- a/source/blender/io/usd/hydra/hydra_scene_delegate.cc +++ b/source/blender/io/usd/hydra/hydra_scene_delegate.cc @@ -14,6 +14,7 @@ #include "BLI_listbase.h" #include "BLI_set.hh" #include "BLI_string.h" +#include "camera_delegate.hh" #include "DEG_depsgraph_query.hh" @@ -36,8 +37,11 @@ bool HydraSceneDelegate::ShadingSettings::operator==(const ShadingSettings &othe HydraSceneDelegate::HydraSceneDelegate(pxr::HdRenderIndex *parent_index, pxr::SdfPath const &delegate_id, + CameraDelegate *camera_delegate, const bool use_materialx) - : HdSceneDelegate(parent_index, delegate_id), use_materialx(use_materialx) + : HdSceneDelegate(parent_index, delegate_id), + use_materialx(use_materialx), + camera_delegate_(camera_delegate) { instancer_data_ = std::make_unique(this, instancer_prim_id()); world_data_ = std::make_unique(this, world_prim_id()); @@ -393,6 +397,10 @@ void HydraSceneDelegate::check_updates() } break; } + case ID_CA: { + camera_delegate_->update(id); + break; + } case ID_WO: { if (shading_settings.use_scene_world && id->recalc & ID_RECALC_SHADING) { do_update_world = true; diff --git a/source/blender/io/usd/hydra/hydra_scene_delegate.hh b/source/blender/io/usd/hydra/hydra_scene_delegate.hh index 744cdd4e2cf..465f3a3faaa 100644 --- a/source/blender/io/usd/hydra/hydra_scene_delegate.hh +++ b/source/blender/io/usd/hydra/hydra_scene_delegate.hh @@ -29,6 +29,7 @@ namespace blender::io::hydra { extern struct CLG_LogRef *LOG_HYDRA_SCENE; class Engine; +class CameraDelegate; class HydraSceneDelegate : public pxr::HdSceneDelegate { friend ObjectData; /* has access to materials */ @@ -59,9 +60,12 @@ class HydraSceneDelegate : public pxr::HdSceneDelegate { std::unique_ptr instancer_data_; std::unique_ptr world_data_; + CameraDelegate *camera_delegate_ = nullptr; + public: HydraSceneDelegate(pxr::HdRenderIndex *parent_index, pxr::SdfPath const &delegate_id, + CameraDelegate *camera_delegate, bool use_materialx); ~HydraSceneDelegate() override = default; diff --git a/source/blender/render/hydra/engine.cc b/source/blender/render/hydra/engine.cc index a4e3c6a7a22..659f48402a0 100644 --- a/source/blender/render/hydra/engine.cc +++ b/source/blender/render/hydra/engine.cc @@ -66,7 +66,7 @@ Engine::Engine(RenderEngine *bl_engine, const std::string &render_delegate_name) } render_index_.reset(pxr::HdRenderIndex::New(render_delegate_.Get(), hd_drivers)); - free_camera_delegate_ = std::make_unique( + free_camera_delegate_ = std::make_unique( render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("freeCamera")); if (bl_engine->type->flag & RE_USE_GPU_CONTEXT && GPU_backend_get_type() == GPU_BACKEND_OPENGL) { @@ -103,7 +103,7 @@ void Engine::sync(Depsgraph *depsgraph, bContext *context) if (!hydra_scene_delegate_) { pxr::SdfPath scene_path = pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"); hydra_scene_delegate_ = std::make_unique( - render_index_.get(), scene_path, use_materialx); + render_index_.get(), scene_path, free_camera_delegate_.get(), use_materialx); } hydra_scene_delegate_->populate(depsgraph, context ? CTX_wm_view3d(context) : nullptr); } @@ -122,6 +122,7 @@ void Engine::sync(Depsgraph *depsgraph, bContext *context) } usd_scene_delegate_->populate(depsgraph); } + free_camera_delegate_->sync(scene_); } void Engine::set_render_setting(const std::string &key, const pxr::VtValue &val) diff --git a/source/blender/render/hydra/engine.hh b/source/blender/render/hydra/engine.hh index 072ccad2b83..52d46432d0e 100644 --- a/source/blender/render/hydra/engine.hh +++ b/source/blender/render/hydra/engine.hh @@ -10,11 +10,11 @@ #include #include #include -#include #include #include #include +#include "hydra/camera_delegate.hh" #include "hydra/hydra_scene_delegate.hh" #include "hydra/settings.hh" #include "hydra/usd_scene_delegate.hh" @@ -44,11 +44,11 @@ class Engine { pxr::HdPluginRenderDelegateUniqueHandle render_delegate_; std::unique_ptr render_index_; + std::unique_ptr free_camera_delegate_; std::unique_ptr hydra_scene_delegate_; std::unique_ptr usd_scene_delegate_; std::unique_ptr render_task_delegate_; - std::unique_ptr free_camera_delegate_; std::unique_ptr light_tasks_delegate_; std::unique_ptr engine_;