diff --git a/doc/python_api/examples/bpy.types.HydraRenderEngine.py b/doc/python_api/examples/bpy.types.HydraRenderEngine.py index 380302cf98ab..f1bd20359c05 100644 --- a/doc/python_api/examples/bpy.types.HydraRenderEngine.py +++ b/doc/python_api/examples/bpy.types.HydraRenderEngine.py @@ -32,6 +32,12 @@ class CustomHydraRenderEngine(bpy.types.HydraRenderEngine): 'aovToken:Depth': "depth", } + # Settings used by the synchronization process. + def get_sync_settings(self, engine_type): + return { + 'lightToken:object:visibility:camera': False, + } + # RenderEngine methods for update, render and draw are implemented in # HydraRenderEngine. Optionally extra work can be done before or after # by implementing the methods like this. diff --git a/scripts/modules/bpy_types.py b/scripts/modules/bpy_types.py index 1e13263d552a..f0f034410c31 100644 --- a/scripts/modules/bpy_types.py +++ b/scripts/modules/bpy_types.py @@ -1269,6 +1269,13 @@ class HydraRenderEngine(RenderEngine): import _bpy_hydra _bpy_hydra.engine_free(self.engine_ptr) + def get_sync_settings(self, engine_type: str): + """ + Provide specific settings for Hydra scene delegate. Available settings: + "lightToken:": + """ + return {} + def get_render_settings(self, engine_type: str): """ Provide render settings for `HdRenderDelegate`. @@ -1285,6 +1292,9 @@ class HydraRenderEngine(RenderEngine): if not self.engine_ptr: return + for key, val in self.get_sync_settings(engine_type).items(): + _bpy_hydra.engine_set_sync_setting(self.engine_ptr, key, val) + _bpy_hydra.engine_update(self.engine_ptr, depsgraph, None) for key, val in self.get_render_settings('PREVIEW' if self.is_preview else 'FINAL').items(): @@ -1305,6 +1315,9 @@ class HydraRenderEngine(RenderEngine): if not self.engine_ptr: return + for key, val in self.get_sync_settings('VIEWPORT').items(): + _bpy_hydra.engine_set_sync_setting(self.engine_ptr, key, val) + _bpy_hydra.engine_update(self.engine_ptr, depsgraph, context) for key, val in self.get_render_settings('VIEWPORT').items(): diff --git a/source/blender/io/usd/hydra/hydra_scene_delegate.cc b/source/blender/io/usd/hydra/hydra_scene_delegate.cc index 763600d91798..ce60a1762a9b 100644 --- a/source/blender/io/usd/hydra/hydra_scene_delegate.cc +++ b/source/blender/io/usd/hydra/hydra_scene_delegate.cc @@ -227,6 +227,7 @@ void HydraSceneDelegate::clear() mat_data->remove(); } materials_.clear(); + sync_settings.light_tokens.clear(); depsgraph = nullptr; bmain = nullptr; @@ -234,6 +235,16 @@ void HydraSceneDelegate::clear() view3d = nullptr; } +void HydraSceneDelegate::set_sync_setting(const std::string &key, const pxr::VtValue &val) +{ + if (STRPREFIX(key.c_str(), "lightToken:")) { + sync_settings.light_tokens.add_overwrite(pxr::TfToken(key.substr(key.find(":") + 1)), val); + } + else { + CLOG_WARN(LOG_HYDRA_SCENE, "Unsupported setting: %s", key.c_str()); + } +} + pxr::SdfPath HydraSceneDelegate::prim_id(ID *id, const char *prefix) const { /* Making id of object in form like _ */ diff --git a/source/blender/io/usd/hydra/hydra_scene_delegate.h b/source/blender/io/usd/hydra/hydra_scene_delegate.h index 7402a4805a17..d775b4558558 100644 --- a/source/blender/io/usd/hydra/hydra_scene_delegate.h +++ b/source/blender/io/usd/hydra/hydra_scene_delegate.h @@ -37,6 +37,11 @@ class HydraSceneDelegate : public pxr::HdSceneDelegate { friend MaterialData; /* has access to objects and instancers */ public: + struct SyncSettings { + /* Is used by render addons to provide specific settings for objects. + * Currently it is used for lights only */ + Map light_tokens; + }; struct ShadingSettings { bool use_scene_lights = true; bool use_scene_world = true; @@ -51,6 +56,7 @@ class HydraSceneDelegate : public pxr::HdSceneDelegate { View3D *view3d = nullptr; Main *bmain = nullptr; Scene *scene = nullptr; + SyncSettings sync_settings; ShadingSettings shading_settings; private: @@ -86,6 +92,7 @@ class HydraSceneDelegate : public pxr::HdSceneDelegate { void populate(Depsgraph *depsgraph, View3D *v3d); void clear(); + void set_sync_setting(const std::string &key, const pxr::VtValue &val); private: pxr::SdfPath prim_id(ID *id, const char *prefix) const; diff --git a/source/blender/io/usd/hydra/light.cc b/source/blender/io/usd/hydra/light.cc index 2e5101fe8447..c71c404bca6f 100644 --- a/source/blender/io/usd/hydra/light.cc +++ b/source/blender/io/usd/hydra/light.cc @@ -140,6 +140,11 @@ pxr::VtValue LightData::get_data(pxr::TfToken const &key) const return pxr::VtValue(it->second); } + const pxr::VtValue *ret_ptr = scene_delegate_->sync_settings.light_tokens.lookup_ptr(key); + if (ret_ptr) { + return *ret_ptr; + } + return pxr::VtValue(); } diff --git a/source/blender/render/hydra/engine.cc b/source/blender/render/hydra/engine.cc index 6310b3611e66..835d09427247 100644 --- a/source/blender/render/hydra/engine.cc +++ b/source/blender/render/hydra/engine.cc @@ -85,9 +85,8 @@ void Engine::sync(Depsgraph *depsgraph, bContext *context) usd_scene_delegate_.reset(); if (!hydra_scene_delegate_) { - pxr::SdfPath scene_path = pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"); - hydra_scene_delegate_ = std::make_unique(render_index_.get(), - scene_path); + hydra_scene_delegate_ = std::make_unique( + render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene")); } hydra_scene_delegate_->populate(depsgraph, context ? CTX_wm_view3d(context) : nullptr); } @@ -100,14 +99,22 @@ void Engine::sync(Depsgraph *depsgraph, bContext *context) } if (!usd_scene_delegate_) { - pxr::SdfPath scene_path = pxr::SdfPath::AbsoluteRootPath().AppendElementString("usd_scene"); - usd_scene_delegate_ = std::make_unique(render_index_.get(), - scene_path); + usd_scene_delegate_ = std::make_unique( + render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("usd_scene")); } usd_scene_delegate_->populate(depsgraph); } } +void Engine::set_sync_setting(const std::string &key, const pxr::VtValue &val) +{ + if (!hydra_scene_delegate_) { + hydra_scene_delegate_ = std::make_unique( + render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene")); + } + hydra_scene_delegate_->set_sync_setting(key, val); +} + void Engine::set_render_setting(const std::string &key, const pxr::VtValue &val) { render_delegate_->SetRenderSetting(pxr::TfToken(key), val); diff --git a/source/blender/render/hydra/engine.h b/source/blender/render/hydra/engine.h index 7eaf9be36a40..73ad1d98bf7e 100644 --- a/source/blender/render/hydra/engine.h +++ b/source/blender/render/hydra/engine.h @@ -58,6 +58,7 @@ class Engine { void sync(Depsgraph *depsgraph, bContext *context); virtual void render() = 0; + void set_sync_setting(const std::string &key, const pxr::VtValue &val); virtual void set_render_setting(const std::string &key, const pxr::VtValue &val); protected: diff --git a/source/blender/render/hydra/python.cc b/source/blender/render/hydra/python.cc index 06a4b842d55e..eef7cc0a5364 100644 --- a/source/blender/render/hydra/python.cc +++ b/source/blender/render/hydra/python.cc @@ -146,6 +146,22 @@ static pxr::VtValue get_setting_val(PyObject *pyval) return val; } +static PyObject *engine_set_sync_setting_func(PyObject * /*self*/, PyObject *args) +{ + PyObject *pyengine, *pyval; + char *key; + if (!PyArg_ParseTuple(args, "OsO", &pyengine, &key, &pyval)) { + Py_RETURN_NONE; + } + + Engine *engine = static_cast(PyLong_AsVoidPtr(pyengine)); + + CLOG_INFO(LOG_HYDRA_RENDER, 3, "Engine %p: %s", engine, key); + engine->set_sync_setting(key, get_setting_val(pyval)); + + Py_RETURN_NONE; +} + static PyObject *engine_set_render_setting_func(PyObject * /*self*/, PyObject *args) { PyObject *pyengine, *pyval; @@ -183,6 +199,7 @@ static PyMethodDef methods[] = { {"engine_update", engine_update_func, METH_VARARGS, ""}, {"engine_render", engine_render_func, METH_VARARGS, ""}, {"engine_view_draw", engine_view_draw_func, METH_VARARGS, ""}, + {"engine_set_sync_setting", engine_set_sync_setting_func, METH_VARARGS, ""}, {"engine_set_render_setting", engine_set_render_setting_func, METH_VARARGS, ""}, {"cache_or_get_image_file", cache_or_get_image_file_func, METH_VARARGS, ""},