diff --git a/scripts/modules/bpy_hydra.py b/scripts/modules/bpy_hydra.py index 2511d9937ede..3dcc3207927c 100644 --- a/scripts/modules/bpy_hydra.py +++ b/scripts/modules/bpy_hydra.py @@ -21,10 +21,15 @@ class CustomHydraRenderEngine(HydraRenderEngine): bpy_hydra.register_plugins(["/path/to/plugin")]) - def get_delegate_settings(self, engine_type): + def get_sync_settings(self, engine_type): return { - 'setting1': 1, - 'setting2': "2", + 'MaterialXFilenameKey': "MaterialXFilename", + } + + def get_render_settings(self, engine_type): + return { + 'enableTinyPrimCulling': True, + 'maxLights': 8, } ``` """ @@ -73,27 +78,52 @@ class HydraRenderEngine(bpy.types.RenderEngine): def unregister(cls): pass - def get_delegate_settings(self, engine_type): + def get_sync_settings(self, engine_type): + """ + Provide settings for Blender scene delegate. Available settings: + `MaterialXFilenameKey` - if provided then MaterialX file will be provided directly to render delegate + without converting to HdMaterialNetwork + """ + return {} + + def get_render_settings(self, engine_type): + """ + Provide render settings for render delegate. List of settings should be available in render delegate + documentation or in `pxr.UsdImagingGL.Engine.GetRendererSettingsList()` + """ return {} # final render def update(self, data, depsgraph): engine_type = 'PREVIEW' if self.is_preview else 'FINAL' self.engine_ptr = _bpy_hydra.engine_create(self.as_pointer(), engine_type, self.delegate_id) - delegate_settings = self.get_delegate_settings(engine_type) - _bpy_hydra.engine_sync(self.engine_ptr, depsgraph.as_pointer(), bpy.context.as_pointer(), delegate_settings) + + 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_sync(self.engine_ptr, depsgraph.as_pointer(), bpy.context.as_pointer()) def render(self, depsgraph): - if self.engine_ptr: - _bpy_hydra.engine_render(self.engine_ptr, depsgraph.as_pointer()) + if not self.engine_ptr: + return + + for key, val in self.get_render_settings('PREVIEW' if self.is_preview else 'FINAL').items(): + _bpy_hydra.engine_set_render_setting(self.engine_ptr, key, val) + + _bpy_hydra.engine_render(self.engine_ptr, depsgraph.as_pointer()) # viewport render def view_update(self, context, depsgraph): if not self.engine_ptr: self.engine_ptr = _bpy_hydra.engine_create(self.as_pointer(), 'VIEWPORT', self.delegate_id) - delegate_settings = self.get_delegate_settings('VIEWPORT') - _bpy_hydra.engine_sync(self.engine_ptr, depsgraph.as_pointer(), context.as_pointer(), delegate_settings) + for key, val in self.get_sync_settings('VIEWPORT').items(): + _bpy_hydra.engine_set_sync_setting(self.engine_ptr, key, val) + + _bpy_hydra.engine_sync(self.engine_ptr, depsgraph.as_pointer(), context.as_pointer()) + + for key, val in self.get_render_settings('VIEWPORT').items(): + _bpy_hydra.engine_set_render_setting(self.engine_ptr, key, val) def view_draw(self, context, depsgraph): if not self.engine_ptr: diff --git a/source/blender/render/hydra/engine.cc b/source/blender/render/hydra/engine.cc index 81476b694623..10c50c6b248e 100644 --- a/source/blender/render/hydra/engine.cc +++ b/source/blender/render/hydra/engine.cc @@ -18,12 +18,12 @@ namespace blender::render::hydra { CLG_LOGREF_DECLARE_GLOBAL(LOG_RENDER_HYDRA, "render.hydra"); Engine::Engine(RenderEngine *bl_engine, const std::string &render_delegate_name) - : bl_engine_(bl_engine), render_delegate_name_(render_delegate_name) + : render_delegate_name(render_delegate_name), bl_engine_(bl_engine) { pxr::HdRendererPluginRegistry ®istry = pxr::HdRendererPluginRegistry::GetInstance(); pxr::TF_PY_ALLOW_THREADS_IN_SCOPE(); - render_delegate_ = registry.CreateRenderDelegate(pxr::TfToken(render_delegate_name_)); + render_delegate_ = registry.CreateRenderDelegate(pxr::TfToken(render_delegate_name)); /* USD has limited support for Vulkan. To make it works USD should be built * with PXR_ENABLE_VULKAN_SUPPORT=TRUE which is not possible now */ @@ -43,9 +43,11 @@ 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( render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("freeCamera")); + scene_delegate_ = std::make_unique( + render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), this); render_task_delegate_ = std::make_unique( render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("renderTask")); - if (render_delegate_name_ == "HdStormRendererPlugin") { + if (render_delegate_name == "HdStormRendererPlugin") { simple_light_task_delegate_ = std::make_unique( render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("simpleLightTask")); @@ -54,6 +56,21 @@ Engine::Engine(RenderEngine *bl_engine, const std::string &render_delegate_name) engine_ = std::make_unique(); } +void Engine::sync(Depsgraph *depsgraph, bContext *context) +{ + scene_delegate_->populate(depsgraph, context); +} + +void Engine::set_sync_setting(const std::string &key, const pxr::VtValue &val) +{ + scene_delegate_->set_setting(key, val); +} + +void Engine::set_render_setting(const std::string &key, const pxr::VtValue &val) +{ + render_delegate_->SetRenderSetting(pxr::TfToken(key), val); +} + float Engine::renderer_percent_done() { pxr::VtDictionary render_stats = render_delegate_->GetRenderStats(); diff --git a/source/blender/render/hydra/engine.h b/source/blender/render/hydra/engine.h index 318db173f169..52e7c4f725a6 100644 --- a/source/blender/render/hydra/engine.h +++ b/source/blender/render/hydra/engine.h @@ -28,16 +28,18 @@ class Engine { Engine(RenderEngine *bl_engine, const std::string &render_delegate_name); virtual ~Engine() = default; - virtual void sync(Depsgraph *depsgraph, - bContext *context, - pxr::HdRenderSettingsMap &render_settings) = 0; + void sync(Depsgraph *depsgraph, bContext *context); virtual void render(Depsgraph *depsgraph) = 0; + void set_sync_setting(const std::string &key, const pxr::VtValue &val); + void set_render_setting(const std::string &key, const pxr::VtValue &val); + + std::string render_delegate_name; + protected: float renderer_percent_done(); RenderEngine *bl_engine_; - std::string render_delegate_name_; /* The order is important due to deletion order */ pxr::HgiUniquePtr hgi_; diff --git a/source/blender/render/hydra/final_engine.cc b/source/blender/render/hydra/final_engine.cc index 9f4bee9c6dd2..bdbade2ebb70 100644 --- a/source/blender/render/hydra/final_engine.cc +++ b/source/blender/render/hydra/final_engine.cc @@ -13,22 +13,6 @@ namespace blender::render::hydra { -void FinalEngine::sync(Depsgraph *depsgraph, - bContext *context, - pxr::HdRenderSettingsMap &render_settings) -{ - scene_delegate_ = std::make_unique( - render_index_.get(), - pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), - BlenderSceneDelegate::EngineType::FINAL, - render_delegate_name_); - scene_delegate_->populate(depsgraph, context); - - for (auto const &setting : render_settings) { - render_delegate_->SetRenderSetting(setting.first, setting.second); - } -} - void FinalEngine::render(Depsgraph *depsgraph) { prepare_for_render(depsgraph); diff --git a/source/blender/render/hydra/final_engine.h b/source/blender/render/hydra/final_engine.h index 585b4a36976e..25e44e8a288a 100644 --- a/source/blender/render/hydra/final_engine.h +++ b/source/blender/render/hydra/final_engine.h @@ -11,10 +11,7 @@ class FinalEngine : public Engine { public: using Engine::Engine; - virtual void sync(Depsgraph *depsgraph, - bContext *context, - pxr::HdRenderSettingsMap &render_settings) override; - virtual void render(Depsgraph *b_depsgraph) override; + void render(Depsgraph *b_depsgraph) override; protected: void update_render_result(); diff --git a/source/blender/render/hydra/preview_engine.cc b/source/blender/render/hydra/preview_engine.cc index 3b893f6937e1..93dcd8dea492 100644 --- a/source/blender/render/hydra/preview_engine.cc +++ b/source/blender/render/hydra/preview_engine.cc @@ -13,46 +13,36 @@ const double LIFETIME = 180.0; std::unique_ptr PreviewEngine::instance_; -PreviewEngine *PreviewEngine::get_instance(RenderEngine *bl_engine, - const std::string &render_delegate_name) +PreviewEngine *PreviewEngine::create(RenderEngine *bl_engine, + const std::string &render_delegate_name) { if (!instance_) { instance_ = std::make_unique(bl_engine, render_delegate_name); } - if (BLI_timer_is_registered((uintptr_t)instance_.get())) { - /* Unregister timer while PreviewEngine is working */ - BLI_timer_unregister((uintptr_t)instance_.get()); + else if (instance_->render_delegate_name != render_delegate_name) { + instance_->render_delegate_->Stop(); + instance_ = std::make_unique(bl_engine, render_delegate_name); + } + else { + instance_->bl_engine_ = bl_engine; + } + + instance_->scene_delegate_->clear(); + + if (BLI_timer_is_registered((uintptr_t)&instance_)) { + /* Unregister timer while PreviewEngine is working */ + BLI_timer_unregister((uintptr_t)&instance_); } - instance_->update(bl_engine, render_delegate_name); return instance_.get(); } -void PreviewEngine::schedule_free() +void PreviewEngine::free() { instance_->render_delegate_->Stop(); /* Register timer for schedule free PreviewEngine instance */ - BLI_timer_register((uintptr_t)instance_.get(), free_instance, nullptr, nullptr, LIFETIME, true); -} - -void PreviewEngine::sync(Depsgraph *depsgraph, - bContext *context, - pxr::HdRenderSettingsMap &render_settings) -{ - if (!scene_delegate_) { - scene_delegate_ = std::make_unique( - render_index_.get(), - pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), - BlenderSceneDelegate::EngineType::PREVIEW, - render_delegate_name_); - } - scene_delegate_->clear(); - scene_delegate_->populate(depsgraph, context); - - for (auto const &setting : render_settings) { - render_delegate_->SetRenderSetting(setting.first, setting.second); - } + BLI_timer_register((uintptr_t)&instance_, free_instance, nullptr, nullptr, LIFETIME, true); } void PreviewEngine::render(Depsgraph *depsgraph) @@ -96,15 +86,6 @@ double PreviewEngine::free_instance(uintptr_t uuid, void *user_data) return -1; } -void PreviewEngine::update(RenderEngine *bl_engine, const std::string &render_delegate_name) -{ - bl_engine_ = bl_engine; - if (render_delegate_name != render_delegate_name_) { - render_delegate_->Stop(); - instance_.reset(new PreviewEngine(bl_engine, render_delegate_name)); - } -} - void PreviewEngine::update_render_result(std::vector &pixels) { RenderResult *result = RE_engine_begin_result( diff --git a/source/blender/render/hydra/preview_engine.h b/source/blender/render/hydra/preview_engine.h index 65ab19dc455d..986f88f69e83 100644 --- a/source/blender/render/hydra/preview_engine.h +++ b/source/blender/render/hydra/preview_engine.h @@ -9,24 +9,19 @@ namespace blender::render::hydra { class PreviewEngine : public FinalEngine { public: - using FinalEngine::FinalEngine; + static PreviewEngine *create(RenderEngine *bl_engine, const std::string &render_delegate_name); + static void free(); - static PreviewEngine *get_instance(RenderEngine *bl_engine, - const std::string &render_delegate_name); - static void schedule_free(); - - void sync(Depsgraph *depsgraph, - bContext *context, - pxr::HdRenderSettingsMap &render_settings) override; void render(Depsgraph *depsgraph) override; private: - /* Singleton class instance */ + using FinalEngine::FinalEngine; static double free_instance(uintptr_t uuid, void *user_data); - static std::unique_ptr instance_; - void update(RenderEngine *bl_engine, const std::string &render_delegate_name); void update_render_result(std::vector &pixels); + + /* Singleton class instance */ + static std::unique_ptr instance_; }; } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/python.cc b/source/blender/render/hydra/python.cc index 5f6f319f62c1..335bbd283730 100644 --- a/source/blender/render/hydra/python.cc +++ b/source/blender/render/hydra/python.cc @@ -111,7 +111,7 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args) engine = new ViewportEngine(bl_engine, render_delegate_id); } else if (STREQ(engine_type, "PREVIEW")) { - engine = PreviewEngine::get_instance(bl_engine, render_delegate_id); + engine = PreviewEngine::create(bl_engine, render_delegate_id); } else { if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) { @@ -123,7 +123,6 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args) } CLOG_INFO(LOG_RENDER_HYDRA, 2, "Engine %016llx %s", engine, engine_type); - return PyLong_FromVoidPtr(engine); } @@ -137,7 +136,7 @@ static PyObject *engine_free_func(PyObject * /*self*/, PyObject *args) Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine); PreviewEngine *preview_engine = dynamic_cast(engine); if (preview_engine) { - PreviewEngine::schedule_free(); + PreviewEngine::free(); } else { delete engine; @@ -149,8 +148,8 @@ static PyObject *engine_free_func(PyObject * /*self*/, PyObject *args) static PyObject *engine_sync_func(PyObject * /*self*/, PyObject *args) { - PyObject *pyengine, *pydepsgraph, *pycontext, *pysettings; - if (!PyArg_ParseTuple(args, "OOOO", &pyengine, &pydepsgraph, &pycontext, &pysettings)) { + PyObject *pyengine, *pydepsgraph, *pycontext; + if (!PyArg_ParseTuple(args, "OOO", &pyengine, &pydepsgraph, &pycontext)) { Py_RETURN_NONE; } @@ -158,29 +157,7 @@ static PyObject *engine_sync_func(PyObject * /*self*/, PyObject *args) Depsgraph *depsgraph = (Depsgraph *)PyLong_AsVoidPtr(pydepsgraph); bContext *context = (bContext *)PyLong_AsVoidPtr(pycontext); - pxr::HdRenderSettingsMap settings; - PyObject *pyiter = PyObject_GetIter(pysettings); - if (pyiter) { - PyObject *pykey, *pyval; - while (pykey = PyIter_Next(pyiter)) { - pxr::TfToken key(PyUnicode_AsUTF8(pykey)); - pyval = PyDict_GetItem(pysettings, pykey); - - if (PyLong_Check(pyval)) { - settings[key] = PyLong_AsLong(pyval); - } - else if (PyFloat_Check(pyval)) { - settings[key] = PyFloat_AsDouble(pyval); - } - else if (PyUnicode_Check(pyval)) { - settings[key] = PyUnicode_AsUTF8(pyval); - } - Py_DECREF(pykey); - } - Py_DECREF(pyiter); - } - - engine->sync(depsgraph, context, settings); + engine->sync(depsgraph, context); CLOG_INFO(LOG_RENDER_HYDRA, 2, "Engine %016llx", engine); Py_RETURN_NONE; @@ -226,6 +203,54 @@ static PyObject *engine_view_draw_func(PyObject * /*self*/, PyObject *args) Py_RETURN_NONE; } +static pxr::VtValue get_setting_val(PyObject *pyval) +{ + pxr::VtValue val; + if (PyBool_Check(pyval)) { + val = Py_IsTrue(pyval); + } + else if (PyLong_Check(pyval)) { + val = PyLong_AsLong(pyval); + } + else if (PyFloat_Check(pyval)) { + val = PyFloat_AsDouble(pyval); + } + else if (PyUnicode_Check(pyval)) { + val = std::string(PyUnicode_AsUTF8(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 = (Engine *)PyLong_AsVoidPtr(pyengine); + engine->set_sync_setting(key, get_setting_val(pyval)); + + CLOG_INFO(LOG_RENDER_HYDRA, 3, "Engine %016llx: %s", engine, key); + Py_RETURN_NONE; +} + +static PyObject *engine_set_render_setting_func(PyObject * /*self*/, PyObject *args) +{ + PyObject *pyengine, *pyval; + char *key; + if (!PyArg_ParseTuple(args, "OsO", &pyengine, &key, &pyval)) { + Py_RETURN_NONE; + } + + Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine); + engine->set_render_setting(key, get_setting_val(pyval)); + + CLOG_INFO(LOG_RENDER_HYDRA, 3, "Engine %016llx: %s", engine, key); + Py_RETURN_NONE; +} + static PyMethodDef methods[] = { {"init", init_func, METH_VARARGS, ""}, {"register_plugins", register_plugins_func, METH_VARARGS, ""}, @@ -236,6 +261,8 @@ static PyMethodDef methods[] = { {"engine_sync", engine_sync_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, ""}, {NULL, NULL, 0, NULL}, }; diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc index 7cc48f1e2b47..264a8d43b6ec 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -14,11 +14,8 @@ CLG_LOGREF_DECLARE_GLOBAL(LOG_RENDER_HYDRA_SCENE, "render.hydra.scene"); BlenderSceneDelegate::BlenderSceneDelegate(pxr::HdRenderIndex *parent_index, pxr::SdfPath const &delegate_id, - BlenderSceneDelegate::EngineType engine_type, - const std::string &render_delegate_name) - : HdSceneDelegate(parent_index, delegate_id), - engine_type(engine_type), - render_delegate_name(render_delegate_name) + Engine *engine) + : HdSceneDelegate(parent_index, delegate_id), engine(engine) { } @@ -206,6 +203,13 @@ void BlenderSceneDelegate::clear() view3d = nullptr; } +void BlenderSceneDelegate::set_setting(const std::string &key, const pxr::VtValue &val) +{ + if (key == "MaterialXFilenameKey") { + settings.mx_filename_key = pxr::TfToken(val.Get()); + } +} + pxr::SdfPath BlenderSceneDelegate::prim_id(ID *id, const char *prefix) const { /* Making id of object in form like _ */ @@ -376,8 +380,8 @@ void BlenderSceneDelegate::check_updates() DEGIDIterData data = {0}; data.graph = depsgraph; data.only_updated = true; - ITER_BEGIN ( - DEG_iterator_ids_begin, DEG_iterator_ids_next, DEG_iterator_ids_end, &data, ID *, id) { + ITER_BEGIN (DEG_iterator_ids_begin, DEG_iterator_ids_next, DEG_iterator_ids_end, &data, ID *, id) + { CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, @@ -451,7 +455,8 @@ void BlenderSceneDelegate::add_new_objects() DEG_iterator_objects_end, &data, Object *, - object) { + object) + { update_objects(object); update_instancers(object); @@ -476,7 +481,8 @@ void BlenderSceneDelegate::remove_unused_objects() DEG_iterator_objects_end, &data, Object *, - object) { + object) + { if (ObjectData::is_supported(object)) { available_objects.insert(object_prim_id(object).GetName()); } @@ -554,7 +560,8 @@ void BlenderSceneDelegate::update_visibility() DEG_iterator_objects_end, &data, Object *, - object) { + object) + { if (!object_data(object_prim_id(object))) { update_objects(object); diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h index 11aef5cb3bd7..69ed762c2159 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h @@ -21,18 +21,21 @@ namespace blender::render::hydra { extern struct CLG_LogRef *LOG_RENDER_HYDRA_SCENE; +class Engine; + class BlenderSceneDelegate : public pxr::HdSceneDelegate { friend ObjectData; /* has access to instances */ friend MeshData; /* has access to materials */ friend MaterialData; /* has access to objects and instancers */ public: - enum class EngineType { VIEWPORT = 1, FINAL, PREVIEW }; + struct Settings { + pxr::TfToken mx_filename_key; + }; BlenderSceneDelegate(pxr::HdRenderIndex *parent_index, pxr::SdfPath const &delegate_id, - BlenderSceneDelegate::EngineType engine_type, - const std::string &render_delegate_name); + Engine *engine); ~BlenderSceneDelegate() override = default; /* Delegate methods */ @@ -55,14 +58,14 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate { void populate(Depsgraph *depsgraph, bContext *context); void clear(); + void set_setting(const std::string &key, const pxr::VtValue &val); - EngineType engine_type; Depsgraph *depsgraph = nullptr; bContext *context = nullptr; View3D *view3d = nullptr; Scene *scene = nullptr; - - std::string render_delegate_name; + Engine *engine; + Settings settings; private: pxr::SdfPath prim_id(ID *id, const char *prefix) const; diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index e10cd9972574..28198b3e630c 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -66,7 +66,8 @@ void InstancerData::update() Object *object = (Object *)id; if (id->recalc & ID_RECALC_GEOMETRY || (object->data && ((ID *)object->data)->recalc & ID_RECALC_GEOMETRY) || - id->recalc & ID_RECALC_TRANSFORM) { + id->recalc & ID_RECALC_TRANSFORM) + { set_instances(); scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( prim_id, pxr::HdChangeTracker::AllDirty); @@ -174,7 +175,8 @@ void InstancerData::check_update(Object *object) if (l_it != light_instances_.end()) { Object *obj = (Object *)l_it->second.data->id; if (obj->id.recalc & (ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY) || - ((ID *)obj->data)->recalc & ID_RECALC_GEOMETRY) { + ((ID *)obj->data)->recalc & ID_RECALC_GEOMETRY) + { set_instances(); } return; diff --git a/source/blender/render/hydra/scene_delegate/material.cc b/source/blender/render/hydra/scene_delegate/material.cc index cac62eda0be5..cd832a4f1816 100644 --- a/source/blender/render/hydra/scene_delegate/material.cc +++ b/source/blender/render/hydra/scene_delegate/material.cc @@ -14,6 +14,7 @@ #include "RNA_blender_cpp.h" #include "bpy_rna.h" +#include "../engine.h" #include "blender_scene_delegate.h" #include "material.h" #include "mtlx_hydra_adapter.h" @@ -31,8 +32,65 @@ void MaterialData::init() { ID_LOG(2, ""); double_sided = (((Material *)id)->blend_flag & MA_BL_CULL_BACKFACE) == 0; - material_network_map_ = pxr::VtValue(); + export_mtlx(); + if (scene_delegate_->settings.mx_filename_key.IsEmpty()) { + write_material_network_map(); + } +} + +void MaterialData::insert() +{ + ID_LOG(2, ""); + scene_delegate_->GetRenderIndex().InsertSprim( + pxr::HdPrimTypeTokens->material, scene_delegate_, prim_id); +} + +void MaterialData::remove() +{ + CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText()); + scene_delegate_->GetRenderIndex().RemoveSprim(pxr::HdPrimTypeTokens->material, prim_id); +} + +void MaterialData::update() +{ + ID_LOG(2, ""); + bool prev_double_sided = double_sided; + init(); + scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id, + pxr::HdMaterial::AllDirty); + if (prev_double_sided != double_sided) { + for (auto &it : scene_delegate_->objects_) { + MeshData *m_data = dynamic_cast(it.second.get()); + if (m_data) { + m_data->update_double_sided(this); + } + } + for (auto &it : scene_delegate_->instancers_) { + it.second->update_double_sided(this); + } + } +} + +pxr::VtValue MaterialData::get_data(pxr::TfToken const &key) const +{ + pxr::VtValue ret; + if (key == scene_delegate_->settings.mx_filename_key) { + if (!mtlx_path_.GetResolvedPath().empty()) { + ret = mtlx_path_; + } + ID_LOG(3, "%s", key.GetText()); + } + return ret; +} + +pxr::VtValue MaterialData::get_material_resource() const +{ + return material_network_map_; +} + +void MaterialData::export_mtlx() +{ /* Call of python function hydra.export_mtlx() */ PyGILState_STATE gstate; @@ -87,71 +145,25 @@ void MaterialData::init() mtlx_path_ = pxr::SdfAssetPath(path, path); ID_LOG(2, "mtlx=%s", mtlx_path_.GetResolvedPath().c_str()); +} - /* Calculate material network map */ - if (!path.empty()) { - pxr::HdRenderDelegate *render_delegate = scene_delegate_->GetRenderIndex().GetRenderDelegate(); - pxr::TfTokenVector shader_source_types = render_delegate->GetShaderSourceTypes(); - pxr::TfTokenVector render_contexts = render_delegate->GetMaterialRenderContexts(); - - pxr::HdMaterialNetworkMap network_map; - hdmtlx_convert_to_materialnetworkmap(path, shader_source_types, render_contexts, &network_map); - - material_network_map_ = network_map; - } - else { +void MaterialData::write_material_network_map() +{ + ID_LOG(2, ""); + if (mtlx_path_.GetResolvedPath().empty()) { material_network_map_ = pxr::VtValue(); + return; } -} -void MaterialData::insert() -{ - ID_LOG(2, ""); - scene_delegate_->GetRenderIndex().InsertSprim( - pxr::HdPrimTypeTokens->material, scene_delegate_, prim_id); -} + pxr::HdRenderDelegate *render_delegate = scene_delegate_->GetRenderIndex().GetRenderDelegate(); + pxr::TfTokenVector shader_source_types = render_delegate->GetShaderSourceTypes(); + pxr::TfTokenVector render_contexts = render_delegate->GetMaterialRenderContexts(); -void MaterialData::remove() -{ - CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText()); - scene_delegate_->GetRenderIndex().RemoveSprim(pxr::HdPrimTypeTokens->material, prim_id); -} + pxr::HdMaterialNetworkMap network_map; + hdmtlx_convert_to_materialnetworkmap( + mtlx_path_.GetResolvedPath(), shader_source_types, render_contexts, &network_map); -void MaterialData::update() -{ - ID_LOG(2, ""); - bool prev_double_sided = double_sided; - init(); - scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id, - pxr::HdMaterial::AllDirty); - if (prev_double_sided != double_sided) { - for (auto &it : scene_delegate_->objects_) { - MeshData *m_data = dynamic_cast(it.second.get()); - if (m_data) { - m_data->update_double_sided(this); - } - } - for (auto &it : scene_delegate_->instancers_) { - it.second->update_double_sided(this); - } - } -} - -pxr::VtValue MaterialData::get_data(pxr::TfToken const &key) const -{ - pxr::VtValue ret; - if (key.GetString() == "MaterialXFilename") { - if (!mtlx_path_.GetResolvedPath().empty()) { - ret = mtlx_path_; - } - ID_LOG(3, "%s", key.GetText()); - } - return ret; -} - -pxr::VtValue MaterialData::get_material_resource() const -{ - return material_network_map_; + material_network_map_ = network_map; } } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/scene_delegate/material.h b/source/blender/render/hydra/scene_delegate/material.h index f70a7ef11c5f..94df4d17b582 100644 --- a/source/blender/render/hydra/scene_delegate/material.h +++ b/source/blender/render/hydra/scene_delegate/material.h @@ -30,6 +30,9 @@ class MaterialData : public IdData { bool double_sided = true; private: + void export_mtlx(); + void write_material_network_map(); + pxr::SdfAssetPath mtlx_path_; pxr::VtValue material_network_map_; }; diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index 0bae621a101b..dcb47524b7d3 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -27,7 +27,8 @@ void MeshData::init() Object *object = (Object *)id; if (object->type == OB_MESH && object->mode == OB_MODE_OBJECT && - BLI_listbase_is_empty(&object->modifiers)) { + BLI_listbase_is_empty(&object->modifiers)) + { write_mesh((Mesh *)object->data); } else { diff --git a/source/blender/render/hydra/scene_delegate/world.cc b/source/blender/render/hydra/scene_delegate/world.cc index 184555ff0a3b..7b70f8697e4a 100644 --- a/source/blender/render/hydra/scene_delegate/world.cc +++ b/source/blender/render/hydra/scene_delegate/world.cc @@ -19,6 +19,7 @@ #include "BLI_path_util.h" #include "NOD_shader.h" +#include "../engine.h" #include "blender_scene_delegate.h" #include "image.h" #include "world.h" @@ -143,7 +144,7 @@ void WorldData::write_transform() transform = pxr::GfMatrix4d(pxr::GfRotation(pxr::GfVec3d(1.0, 0.0, 0.0), -90), pxr::GfVec3d()); /* TODO : do this check via RenderSettings*/ - if (scene_delegate_->render_delegate_name == "HdRprPlugin") { + if (scene_delegate_->engine->render_delegate_name == "HdRprPlugin") { transform *= pxr::GfMatrix4d(pxr::GfRotation(pxr::GfVec3d(1.0, 0.0, 0.0), -180), pxr::GfVec3d()); transform *= pxr::GfMatrix4d(pxr::GfRotation(pxr::GfVec3d(0.0, 0.0, 1.0), 90.0), diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index 1d2a68b88a29..e666e181cc03 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -217,24 +217,6 @@ void DrawTexture::free() texture_ = nullptr; } -void ViewportEngine::sync(Depsgraph *depsgraph, - bContext *context, - pxr::HdRenderSettingsMap &render_settings) -{ - if (!scene_delegate_) { - scene_delegate_ = std::make_unique( - render_index_.get(), - pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), - BlenderSceneDelegate::EngineType::VIEWPORT, - render_delegate_name_); - } - scene_delegate_->populate(depsgraph, context); - - for (auto const &setting : render_settings) { - render_delegate_->SetRenderSetting(setting.first, setting.second); - } -} - void ViewportEngine::render(Depsgraph *depsgraph) { /* Empty function */ diff --git a/source/blender/render/hydra/viewport_engine.h b/source/blender/render/hydra/viewport_engine.h index 2f893d71a9d1..a21ccda581e8 100644 --- a/source/blender/render/hydra/viewport_engine.h +++ b/source/blender/render/hydra/viewport_engine.h @@ -34,9 +34,6 @@ class ViewportEngine : public Engine { public: using Engine::Engine; - void sync(Depsgraph *depsgraph, - bContext *context, - pxr::HdRenderSettingsMap &render_settings) override; void render(Depsgraph *depsgraph) override; void render(Depsgraph *depsgraph, bContext *context);