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
13 changed files with 98 additions and 100 deletions
Showing only changes of commit c00f087fa5 - Show all commits

View File

@ -43,6 +43,8 @@ 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<pxr::HdxFreeCameraSceneDelegate>(
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("freeCamera"));
scene_delegate_ = std::make_unique<BlenderSceneDelegate>(
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), this);
render_task_delegate_ = std::make_unique<RenderTaskDelegate>(
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("renderTask"));
if (render_delegate_name == "HdStormRendererPlugin") {
@ -56,7 +58,7 @@ Engine::Engine(RenderEngine *bl_engine, const std::string &render_delegate_name)
void Engine::set_sync_setting(const pxr::TfToken &key, const pxr::VtValue &val)
{
settings[key] = val;
scene_delegate_->set_setting(key, val);
}
void Engine::set_render_setting(const pxr::TfToken &key, const pxr::VtValue &val)

View File

@ -25,8 +25,6 @@ extern struct CLG_LogRef *LOG_RENDER_HYDRA;
class Engine {
public:
enum class EngineType { VIEWPORT = 1, FINAL, PREVIEW };
Engine(RenderEngine *bl_engine, const std::string &render_delegate_name);
virtual ~Engine() = default;
@ -36,9 +34,7 @@ class Engine {
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;
std::string render_delegate_name;
pxr::TfHashMap<pxr::TfToken, pxr::VtValue, pxr::TfToken::HashFunctor> settings;
protected:
float renderer_percent_done();

View File

@ -13,16 +13,8 @@
namespace blender::render::hydra {
FinalEngine::FinalEngine(RenderEngine *bl_engine, const std::string &render_delegate_name)
: Engine(bl_engine, render_delegate_name)
{
type = EngineType::FINAL;
}
void FinalEngine::sync(Depsgraph *depsgraph, bContext *context)
{
scene_delegate_ = std::make_unique<BlenderSceneDelegate>(
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), this);
scene_delegate_->populate(depsgraph, context);
}

View File

@ -9,7 +9,7 @@ namespace blender::render::hydra {
class FinalEngine : public Engine {
public:
FinalEngine(RenderEngine *bl_engine, const std::string &render_delegate_name);
using Engine::Engine;
virtual void sync(Depsgraph *depsgraph, bContext *context) override;
virtual void render(Depsgraph *b_depsgraph) override;

View File

@ -13,12 +13,6 @@ const double LIFETIME = 180.0;
std::unique_ptr<PreviewEngine> PreviewEngine::instance_;
PreviewEngine::PreviewEngine(RenderEngine *bl_engine, const std::string &render_delegate_name)
: FinalEngine(bl_engine, render_delegate_name)
{
type = EngineType::PREVIEW;
}
PreviewEngine *PreviewEngine::get_instance(RenderEngine *bl_engine,
const std::string &render_delegate_name)
{
@ -44,10 +38,6 @@ void PreviewEngine::schedule_free()
void PreviewEngine::sync(Depsgraph *depsgraph, bContext *context)
{
if (!scene_delegate_) {
scene_delegate_ = std::make_unique<BlenderSceneDelegate>(
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), this);
}
scene_delegate_->clear();
scene_delegate_->populate(depsgraph, context);
}

View File

@ -9,8 +9,7 @@ namespace blender::render::hydra {
class PreviewEngine : public FinalEngine {
public:
PreviewEngine(RenderEngine *bl_engine, const std::string &render_delegate_name);
using FinalEngine::FinalEngine;
static PreviewEngine *get_instance(RenderEngine *bl_engine,
const std::string &render_delegate_name);
static void schedule_free();
@ -19,12 +18,13 @@ class PreviewEngine : public FinalEngine {
void render(Depsgraph *depsgraph) 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.
private:
/* Singleton class instance */
static double free_instance(uintptr_t uuid, void *user_data);
static std::unique_ptr<PreviewEngine> instance_;
void update(RenderEngine *bl_engine, const std::string &render_delegate_name);
void update_render_result(std::vector<float> &pixels);
/* Singleton class instance */
static std::unique_ptr<PreviewEngine> instance_;
};
} // namespace blender::render::hydra

View File

@ -216,7 +216,7 @@ static pxr::VtValue get_setting_val(PyObject *pyval)
val = PyFloat_AsDouble(pyval);
}
else if (PyUnicode_Check(pyval)) {
val = PyUnicode_AsUTF8(pyval);
val = std::string(PyUnicode_AsUTF8(pyval));
}
return val;
}

View File

@ -203,6 +203,13 @@ void BlenderSceneDelegate::clear()
view3d = nullptr;
}
void BlenderSceneDelegate::set_setting(const pxr::TfToken &key, const pxr::VtValue &val)
{
if (key.GetString() == "MaterialXFilenameKey") {
settings.mx_filename_key = pxr::TfToken(val.Get<std::string>());
}
}
pxr::SdfPath BlenderSceneDelegate::prim_id(ID *id, const char *prefix) const
{
/* Making id of object in form like <prefix>_<pointer in 16 hex digits format> */

View File

@ -29,6 +29,10 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
friend MaterialData; /* has access to objects and instancers */
public:
struct Settings {
pxr::TfToken mx_filename_key;
};
BlenderSceneDelegate(pxr::HdRenderIndex *parent_index,
pxr::SdfPath const &delegate_id,
Engine *engine);
@ -54,12 +58,14 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
void populate(Depsgraph *depsgraph, bContext *context);
void clear();
void set_setting(const pxr::TfToken &key, const pxr::VtValue &val);
Depsgraph *depsgraph = nullptr;
bContext *context = nullptr;
View3D *view3d = nullptr;
Scene *scene = nullptr;
Engine *engine;
Settings settings;
private:
pxr::SdfPath prim_id(ID *id, const char *prefix) const;

View File

@ -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<MeshData *>(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_;
}
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<MeshData *>(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

View File

@ -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_;
};

View File

@ -217,18 +217,8 @@ void DrawTexture::free()
texture_ = nullptr;
}
ViewportEngine::ViewportEngine(RenderEngine *bl_engine, const std::string &render_delegate_name)
: Engine(bl_engine, render_delegate_name)
{
type = EngineType::VIEWPORT;
}
void ViewportEngine::sync(Depsgraph *depsgraph, bContext *context)
{
if (!scene_delegate_) {
scene_delegate_ = std::make_unique<BlenderSceneDelegate>(
render_index_.get(), pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"), this);
}
scene_delegate_->populate(depsgraph, context);
}

View File

@ -32,7 +32,7 @@ class DrawTexture {
class ViewportEngine : public Engine {
public:
ViewportEngine(RenderEngine *bl_engine, const std::string &render_delegate_name);
using Engine::Engine;
void sync(Depsgraph *depsgraph, bContext *context) override;
void render(Depsgraph *depsgraph) override;