Create possibility to provide render settings via BlenderSceneDelegate #41

Merged
Bogdan Nagirniak merged 10 commits from BLEN-349 into hydra-render 2023-05-19 20:19:17 +02:00
9 changed files with 99 additions and 110 deletions
Showing only changes of commit 4529c674dc - Show all commits

View File

@ -17,10 +17,8 @@ namespace blender::render::hydra {
CLG_LOGREF_DECLARE_GLOBAL(LOG_RENDER_HYDRA, "render.hydra"); CLG_LOGREF_DECLARE_GLOBAL(LOG_RENDER_HYDRA, "render.hydra");
Engine::Engine(RenderEngine *bl_engine, Engine::Engine(RenderEngine *bl_engine, const std::string &render_delegate_name)
const std::string &render_delegate_name, : render_delegate_name(render_delegate_name), bl_engine_(bl_engine)
SettingsMap &settings)
: render_delegate_name(render_delegate_name), settings(settings), bl_engine_(bl_engine)
{ {
pxr::HdRendererPluginRegistry &registry = pxr::HdRendererPluginRegistry::GetInstance(); pxr::HdRendererPluginRegistry &registry = pxr::HdRendererPluginRegistry::GetInstance();
@ -56,6 +54,16 @@ Engine::Engine(RenderEngine *bl_engine,
engine_ = std::make_unique<pxr::HdEngine>(); engine_ = std::make_unique<pxr::HdEngine>();
} }
void Engine::set_sync_setting(const pxr::TfToken &key, const pxr::VtValue &val)
{
settings[key] = val;
}
void Engine::set_render_setting(const pxr::TfToken &key, const pxr::VtValue &val)
{
render_delegate_->SetRenderSetting(key, val);
}
float Engine::renderer_percent_done() float Engine::renderer_percent_done()
{ {
pxr::VtDictionary render_stats = render_delegate_->GetRenderStats(); pxr::VtDictionary render_stats = render_delegate_->GetRenderStats();

View File

@ -23,21 +23,22 @@ namespace blender::render::hydra {
extern struct CLG_LogRef *LOG_RENDER_HYDRA; extern struct CLG_LogRef *LOG_RENDER_HYDRA;
typedef pxr::TfHashMap<pxr::TfToken, pxr::VtValue, pxr::TfToken::HashFunctor> SettingsMap;
class Engine { class Engine {
public: public:
enum class EngineType { VIEWPORT = 1, FINAL, PREVIEW }; enum class EngineType { VIEWPORT = 1, FINAL, PREVIEW };
Engine(RenderEngine *bl_engine, const std::string &render_delegate_name, SettingsMap &settings); Engine(RenderEngine *bl_engine, const std::string &render_delegate_name);
virtual ~Engine() = default; virtual ~Engine() = default;
virtual void sync(Depsgraph *depsgraph, bContext *context, SettingsMap &render_settings) = 0; virtual void sync(Depsgraph *depsgraph, bContext *context) = 0;
virtual void render(Depsgraph *depsgraph) = 0; virtual void render(Depsgraph *depsgraph) = 0;
void set_sync_setting(const pxr::TfToken &key, const pxr::VtValue &val);
void set_render_setting(const pxr::TfToken &key, const pxr::VtValue &val);
EngineType type; EngineType type;
std::string render_delegate_name; std::string render_delegate_name;
SettingsMap settings; pxr::TfHashMap<pxr::TfToken, pxr::VtValue, pxr::TfToken::HashFunctor> settings;
protected: protected:
float renderer_percent_done(); float renderer_percent_done();

View File

@ -13,25 +13,17 @@
namespace blender::render::hydra { namespace blender::render::hydra {
FinalEngine::FinalEngine(RenderEngine *bl_engine, FinalEngine::FinalEngine(RenderEngine *bl_engine, const std::string &render_delegate_name)
const std::string &render_delegate_name, : Engine(bl_engine, render_delegate_name)
SettingsMap &settings)
: Engine(bl_engine, render_delegate_name, settings)
{ {
type = EngineType::FINAL; type = EngineType::FINAL;
} }
void FinalEngine::sync(Depsgraph *depsgraph, void FinalEngine::sync(Depsgraph *depsgraph, bContext *context)
bContext *context,
pxr::HdRenderSettingsMap &render_settings)
{ {
scene_delegate_ = std::make_unique<BlenderSceneDelegate>( scene_delegate_ = std::make_unique<BlenderSceneDelegate>(
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), this); render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), this);
scene_delegate_->populate(depsgraph, context); scene_delegate_->populate(depsgraph, context);
for (auto const &setting : render_settings) {
render_delegate_->SetRenderSetting(setting.first, setting.second);
}
} }
void FinalEngine::render(Depsgraph *depsgraph) void FinalEngine::render(Depsgraph *depsgraph)

View File

@ -9,13 +9,9 @@ namespace blender::render::hydra {
class FinalEngine : public Engine { class FinalEngine : public Engine {
public: public:
FinalEngine(RenderEngine *bl_engine, FinalEngine(RenderEngine *bl_engine, const std::string &render_delegate_name);
const std::string &render_delegate_name,
SettingsMap &settings);
virtual void sync(Depsgraph *depsgraph, virtual void sync(Depsgraph *depsgraph, bContext *context) override;
bContext *context,
pxr::HdRenderSettingsMap &render_settings) override;
virtual void render(Depsgraph *b_depsgraph) override; virtual void render(Depsgraph *b_depsgraph) override;
protected: protected:

View File

@ -13,26 +13,23 @@ const double LIFETIME = 180.0;
std::unique_ptr<PreviewEngine> PreviewEngine::instance_; std::unique_ptr<PreviewEngine> PreviewEngine::instance_;
PreviewEngine::PreviewEngine(RenderEngine *bl_engine, PreviewEngine::PreviewEngine(RenderEngine *bl_engine, const std::string &render_delegate_name)
const std::string &render_delegate_name, : FinalEngine(bl_engine, render_delegate_name)
SettingsMap &settings)
: FinalEngine(bl_engine, render_delegate_name, settings)
{ {
type = EngineType::PREVIEW; type = EngineType::PREVIEW;
} }
PreviewEngine *PreviewEngine::get_instance(RenderEngine *bl_engine, PreviewEngine *PreviewEngine::get_instance(RenderEngine *bl_engine,
const std::string &render_delegate_name, const std::string &render_delegate_name)
SettingsMap &settings)
{ {
if (!instance_) { if (!instance_) {
instance_ = std::make_unique<PreviewEngine>(bl_engine, render_delegate_name, settings); instance_ = std::make_unique<PreviewEngine>(bl_engine, render_delegate_name);
} }
if (BLI_timer_is_registered((uintptr_t)instance_.get())) { if (BLI_timer_is_registered((uintptr_t)instance_.get())) {
/* Unregister timer while PreviewEngine is working */ /* Unregister timer while PreviewEngine is working */
BLI_timer_unregister((uintptr_t)instance_.get()); BLI_timer_unregister((uintptr_t)instance_.get());
} }
instance_->update(bl_engine, render_delegate_name, settings); instance_->update(bl_engine, render_delegate_name);
return instance_.get(); return instance_.get();
} }
@ -45,9 +42,7 @@ void PreviewEngine::schedule_free()
BLI_timer_register((uintptr_t)instance_.get(), free_instance, nullptr, nullptr, LIFETIME, true); BLI_timer_register((uintptr_t)instance_.get(), free_instance, nullptr, nullptr, LIFETIME, true);
} }
void PreviewEngine::sync(Depsgraph *depsgraph, void PreviewEngine::sync(Depsgraph *depsgraph, bContext *context)
bContext *context,
pxr::HdRenderSettingsMap &render_settings)
{ {
if (!scene_delegate_) { if (!scene_delegate_) {
scene_delegate_ = std::make_unique<BlenderSceneDelegate>( scene_delegate_ = std::make_unique<BlenderSceneDelegate>(
@ -55,10 +50,6 @@ void PreviewEngine::sync(Depsgraph *depsgraph,
} }
scene_delegate_->clear(); scene_delegate_->clear();
scene_delegate_->populate(depsgraph, context); scene_delegate_->populate(depsgraph, context);
for (auto const &setting : render_settings) {
render_delegate_->SetRenderSetting(setting.first, setting.second);
}
} }
void PreviewEngine::render(Depsgraph *depsgraph) void PreviewEngine::render(Depsgraph *depsgraph)
@ -102,14 +93,12 @@ double PreviewEngine::free_instance(uintptr_t uuid, void *user_data)
return -1; return -1;
} }
void PreviewEngine::update(RenderEngine *bl_engine, void PreviewEngine::update(RenderEngine *bl_engine, const std::string &render_delegate_name)
const std::string &render_delegate_name,
SettingsMap &settings)
{ {
bl_engine_ = bl_engine; bl_engine_ = bl_engine;
if (render_delegate_name != render_delegate_name) { if (render_delegate_name != render_delegate_name) {
render_delegate_->Stop(); render_delegate_->Stop();
instance_.reset(new PreviewEngine(bl_engine, render_delegate_name, settings)); instance_.reset(new PreviewEngine(bl_engine, render_delegate_name));
} }
} }

View File

@ -9,18 +9,13 @@ namespace blender::render::hydra {
class PreviewEngine : public FinalEngine { class PreviewEngine : public FinalEngine {
public: public:
PreviewEngine(RenderEngine *bl_engine, PreviewEngine(RenderEngine *bl_engine, const std::string &render_delegate_name);
const std::string &render_delegate_name,
SettingsMap &settings);
static PreviewEngine *get_instance(RenderEngine *bl_engine, static PreviewEngine *get_instance(RenderEngine *bl_engine,
const std::string &render_delegate_name, const std::string &render_delegate_name);
SettingsMap &settings);
static void schedule_free(); static void schedule_free();
void sync(Depsgraph *depsgraph, void sync(Depsgraph *depsgraph, bContext *context) override;
Review

Why did you move it here?

Why did you move it here?
Review

PreviewEngine should be created via PreviewEngine::create() therefore constructor moved to private section.

`PreviewEngine` should be created via `PreviewEngine::create()` therefore constructor moved to private section.
bContext *context,
pxr::HdRenderSettingsMap &render_settings) override;
void render(Depsgraph *depsgraph) override; void render(Depsgraph *depsgraph) override;
private: private:
@ -28,9 +23,7 @@ class PreviewEngine : public FinalEngine {
static double free_instance(uintptr_t uuid, void *user_data); static double free_instance(uintptr_t uuid, void *user_data);
static std::unique_ptr<PreviewEngine> instance_; static std::unique_ptr<PreviewEngine> instance_;
void update(RenderEngine *bl_engine, void update(RenderEngine *bl_engine, const std::string &render_delegate_name);
const std::string &render_delegate_name,
SettingsMap &settings);
void update_render_result(std::vector<float> &pixels); void update_render_result(std::vector<float> &pixels);
}; };

View File

@ -96,56 +96,29 @@ static PyObject *get_render_plugins_func(PyObject * /*self*/, PyObject *args)
return ret; return ret;
} }
static SettingsMap get_settings(PyObject *pysettings)
{
SettingsMap 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);
}
return settings;
}
static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args) static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args)
{ {
PyObject *pyengine, *pysettings; PyObject *pyengine;
char *engine_type, *render_delegate_id; char *engine_type, *render_delegate_id;
if (!PyArg_ParseTuple(args, "OssO", &pyengine, &engine_type, &render_delegate_id, &pysettings)) { if (!PyArg_ParseTuple(args, "Oss", &pyengine, &engine_type, &render_delegate_id)) {
Py_RETURN_NONE; Py_RETURN_NONE;
} }
RenderEngine *bl_engine = (RenderEngine *)PyLong_AsVoidPtr(pyengine); RenderEngine *bl_engine = (RenderEngine *)PyLong_AsVoidPtr(pyengine);
SettingsMap settings = get_settings(pysettings);
Engine *engine; Engine *engine;
if (STREQ(engine_type, "VIEWPORT")) { if (STREQ(engine_type, "VIEWPORT")) {
engine = new ViewportEngine(bl_engine, render_delegate_id, settings); engine = new ViewportEngine(bl_engine, render_delegate_id);
} }
else if (STREQ(engine_type, "PREVIEW")) { else if (STREQ(engine_type, "PREVIEW")) {
engine = PreviewEngine::get_instance(bl_engine, render_delegate_id, settings); engine = PreviewEngine::get_instance(bl_engine, render_delegate_id);
} }
else { else {
if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) { if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) {
engine = new FinalEngineGL(bl_engine, render_delegate_id, settings); engine = new FinalEngineGL(bl_engine, render_delegate_id);
} }
else { else {
engine = new FinalEngine(bl_engine, render_delegate_id, settings); engine = new FinalEngine(bl_engine, render_delegate_id);
} }
} }
@ -175,17 +148,16 @@ static PyObject *engine_free_func(PyObject * /*self*/, PyObject *args)
static PyObject *engine_sync_func(PyObject * /*self*/, PyObject *args) static PyObject *engine_sync_func(PyObject * /*self*/, PyObject *args)
{ {
PyObject *pyengine, *pydepsgraph, *pycontext, *pysettings; PyObject *pyengine, *pydepsgraph, *pycontext;
if (!PyArg_ParseTuple(args, "OOOO", &pyengine, &pydepsgraph, &pycontext, &pysettings)) { if (!PyArg_ParseTuple(args, "OOO", &pyengine, &pydepsgraph, &pycontext)) {
Py_RETURN_NONE; Py_RETURN_NONE;
} }
Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine); Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine);
Depsgraph *depsgraph = (Depsgraph *)PyLong_AsVoidPtr(pydepsgraph); Depsgraph *depsgraph = (Depsgraph *)PyLong_AsVoidPtr(pydepsgraph);
bContext *context = (bContext *)PyLong_AsVoidPtr(pycontext); bContext *context = (bContext *)PyLong_AsVoidPtr(pycontext);
SettingsMap settings = get_settings(pysettings);
engine->sync(depsgraph, context, settings); engine->sync(depsgraph, context);
CLOG_INFO(LOG_RENDER_HYDRA, 2, "Engine %016llx", engine); CLOG_INFO(LOG_RENDER_HYDRA, 2, "Engine %016llx", engine);
Py_RETURN_NONE; Py_RETURN_NONE;
@ -231,6 +203,54 @@ static PyObject *engine_view_draw_func(PyObject * /*self*/, PyObject *args)
Py_RETURN_NONE; 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 = 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(pxr::TfToken(key), get_setting_val(pyval));
CLOG_INFO(LOG_RENDER_HYDRA, 2, "Engine %016llx", engine);
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(pxr::TfToken(key), get_setting_val(pyval));
CLOG_INFO(LOG_RENDER_HYDRA, 2, "Engine %016llx", engine);
Py_RETURN_NONE;
}
static PyMethodDef methods[] = { static PyMethodDef methods[] = {
{"init", init_func, METH_VARARGS, ""}, {"init", init_func, METH_VARARGS, ""},
{"register_plugins", register_plugins_func, METH_VARARGS, ""}, {"register_plugins", register_plugins_func, METH_VARARGS, ""},
@ -241,6 +261,8 @@ static PyMethodDef methods[] = {
{"engine_sync", engine_sync_func, METH_VARARGS, ""}, {"engine_sync", engine_sync_func, METH_VARARGS, ""},
{"engine_render", engine_render_func, METH_VARARGS, ""}, {"engine_render", engine_render_func, METH_VARARGS, ""},
{"engine_view_draw", engine_view_draw_func, METH_VARARGS, ""}, {"engine_view_draw", engine_view_draw_func, METH_VARARGS, ""},
{"engine_sync_setting", engine_set_sync_setting_func, METH_VARARGS, ""},
{"engine_render_setting", engine_set_render_setting_func, METH_VARARGS, ""},
{NULL, NULL, 0, NULL}, {NULL, NULL, 0, NULL},
}; };

View File

@ -217,27 +217,19 @@ void DrawTexture::free()
texture_ = nullptr; texture_ = nullptr;
} }
ViewportEngine::ViewportEngine(RenderEngine *bl_engine, ViewportEngine::ViewportEngine(RenderEngine *bl_engine, const std::string &render_delegate_name)
const std::string &render_delegate_name, : Engine(bl_engine, render_delegate_name)
SettingsMap &settings)
: Engine(bl_engine, render_delegate_name, settings)
{ {
type = EngineType::VIEWPORT; type = EngineType::VIEWPORT;
} }
void ViewportEngine::sync(Depsgraph *depsgraph, void ViewportEngine::sync(Depsgraph *depsgraph, bContext *context)
bContext *context,
pxr::HdRenderSettingsMap &render_settings)
{ {
if (!scene_delegate_) { if (!scene_delegate_) {
scene_delegate_ = std::make_unique<BlenderSceneDelegate>( scene_delegate_ = std::make_unique<BlenderSceneDelegate>(
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), this); render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), this);
} }
scene_delegate_->populate(depsgraph, context); scene_delegate_->populate(depsgraph, context);
for (auto const &setting : render_settings) {
render_delegate_->SetRenderSetting(setting.first, setting.second);
}
} }
void ViewportEngine::render(Depsgraph *depsgraph) void ViewportEngine::render(Depsgraph *depsgraph)

View File

@ -32,13 +32,9 @@ class DrawTexture {
class ViewportEngine : public Engine { class ViewportEngine : public Engine {
public: public:
ViewportEngine(RenderEngine *bl_engine, ViewportEngine(RenderEngine *bl_engine, const std::string &render_delegate_name);
const std::string &render_delegate_name,
SettingsMap &settings);
void sync(Depsgraph *depsgraph, void sync(Depsgraph *depsgraph, bContext *context) override;
bContext *context,
pxr::HdRenderSettingsMap &render_settings) override;
void render(Depsgraph *depsgraph) override; void render(Depsgraph *depsgraph) override;
void render(Depsgraph *depsgraph, bContext *context); void render(Depsgraph *depsgraph, bContext *context);