forked from blender/blender
BLEN-365: Improve creation algorithm of PreviewEngine #21
@ -19,7 +19,7 @@ class CustomHydraRenderEngine(HydraRenderEngine):
|
|||||||
def register(cls):
|
def register(cls):
|
||||||
super().register()
|
super().register()
|
||||||
|
|
||||||
bpy_hydra.register_plugins(["/path/to/plugin")], ["/additional/system/path")])
|
bpy_hydra.register_plugins(["/path/to/plugin")])
|
||||||
|
|
||||||
def get_delegate_settings(self, engine_type):
|
def get_delegate_settings(self, engine_type):
|
||||||
return {
|
return {
|
||||||
@ -58,6 +58,7 @@ class HydraRenderEngine(bpy.types.RenderEngine):
|
|||||||
return
|
return
|
||||||
|
|
||||||
_bpy_hydra.engine_free(self.engine_ptr)
|
_bpy_hydra.engine_free(self.engine_ptr)
|
||||||
|
del self.engine_ptr
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def register(cls):
|
def register(cls):
|
||||||
@ -74,20 +75,18 @@ class HydraRenderEngine(bpy.types.RenderEngine):
|
|||||||
|
|
||||||
# final render
|
# final render
|
||||||
def update(self, data, depsgraph):
|
def update(self, data, depsgraph):
|
||||||
pass
|
|
||||||
|
|
||||||
def render(self, depsgraph):
|
|
||||||
engine_type = 'PREVIEW' if self.is_preview else 'FINAL'
|
engine_type = 'PREVIEW' if self.is_preview else 'FINAL'
|
||||||
|
|
||||||
self.engine_ptr = _bpy_hydra.engine_create(self.as_pointer(), engine_type, self.delegate_id)
|
self.engine_ptr = _bpy_hydra.engine_create(self.as_pointer(), engine_type, self.delegate_id)
|
||||||
delegate_settings = self.get_delegate_settings(engine_type)
|
delegate_settings = self.get_delegate_settings(engine_type)
|
||||||
|
|
||||||
_bpy_hydra.engine_sync(self.engine_ptr, depsgraph.as_pointer(), bpy.context.as_pointer(), delegate_settings)
|
_bpy_hydra.engine_sync(self.engine_ptr, depsgraph.as_pointer(), bpy.context.as_pointer(), delegate_settings)
|
||||||
_bpy_hydra.engine_render(self.engine_ptr, depsgraph.as_pointer())
|
|
||||||
|
def render(self, depsgraph):
|
||||||
|
if hasattr(self, 'engine_ptr'):
|
||||||
|
_bpy_hydra.engine_render(self.engine_ptr, depsgraph.as_pointer())
|
||||||
|
|
||||||
# viewport render
|
# viewport render
|
||||||
def view_update(self, context, depsgraph):
|
def view_update(self, context, depsgraph):
|
||||||
if not self.engine_ptr:
|
if not hasattr(self, 'engine_ptr'):
|
||||||
self.engine_ptr = _bpy_hydra.engine_create(self.as_pointer(), 'VIEWPORT', self.delegate_id)
|
self.engine_ptr = _bpy_hydra.engine_create(self.as_pointer(), 'VIEWPORT', self.delegate_id)
|
||||||
|
|
||||||
delegate_settings = self.get_delegate_settings('VIEWPORT')
|
delegate_settings = self.get_delegate_settings('VIEWPORT')
|
||||||
|
@ -42,6 +42,11 @@ Engine::Engine(RenderEngine *bl_engine, const std::string &delegate_id) : bl_eng
|
|||||||
}
|
}
|
||||||
|
|
||||||
engine = std::make_unique<pxr::HdEngine>();
|
engine = std::make_unique<pxr::HdEngine>();
|
||||||
|
|
||||||
|
scene_delegate = std::make_unique<BlenderSceneDelegate>(
|
||||||
|
render_index.get(),
|
||||||
|
pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"),
|
||||||
|
BlenderSceneDelegate::EngineType::PREVIEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine::~Engine()
|
Engine::~Engine()
|
||||||
@ -54,6 +59,7 @@ Engine::~Engine()
|
|||||||
render_delegate = nullptr;
|
render_delegate = nullptr;
|
||||||
engine = nullptr;
|
engine = nullptr;
|
||||||
hgi = nullptr;
|
hgi = nullptr;
|
||||||
|
bl_engine = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Engine::renderer_percent_done()
|
float Engine::renderer_percent_done()
|
||||||
|
@ -34,12 +34,12 @@ class Engine {
|
|||||||
bContext *context,
|
bContext *context,
|
||||||
pxr::HdRenderSettingsMap &render_settings) = 0;
|
pxr::HdRenderSettingsMap &render_settings) = 0;
|
||||||
virtual void render(Depsgraph *depsgraph) = 0;
|
virtual void render(Depsgraph *depsgraph) = 0;
|
||||||
|
RenderEngine *bl_engine;
|
||||||
protected:
|
protected:
|
||||||
float renderer_percent_done();
|
float renderer_percent_done();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RenderEngine *bl_engine;
|
|
||||||
|
|
||||||
pxr::HdPluginRenderDelegateUniqueHandle render_delegate;
|
pxr::HdPluginRenderDelegateUniqueHandle render_delegate;
|
||||||
std::unique_ptr<pxr::HdRenderIndex> render_index;
|
std::unique_ptr<pxr::HdRenderIndex> render_index;
|
||||||
|
@ -16,10 +16,6 @@ void FinalEngine::sync(Depsgraph *depsgraph,
|
|||||||
bContext *context,
|
bContext *context,
|
||||||
pxr::HdRenderSettingsMap &render_settings)
|
pxr::HdRenderSettingsMap &render_settings)
|
||||||
{
|
{
|
||||||
scene_delegate = std::make_unique<BlenderSceneDelegate>(
|
|
||||||
render_index.get(),
|
|
||||||
pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"),
|
|
||||||
BlenderSceneDelegate::EngineType::FINAL);
|
|
||||||
scene_delegate->populate(depsgraph, context);
|
scene_delegate->populate(depsgraph, context);
|
||||||
|
|
||||||
for (auto const &setting : render_settings) {
|
for (auto const &setting : render_settings) {
|
||||||
|
@ -12,19 +12,37 @@ void PreviewEngine::sync(Depsgraph *depsgraph,
|
|||||||
bContext *context,
|
bContext *context,
|
||||||
pxr::HdRenderSettingsMap &render_settings)
|
pxr::HdRenderSettingsMap &render_settings)
|
||||||
{
|
{
|
||||||
scene_delegate = std::make_unique<BlenderSceneDelegate>(
|
is_synced = false;
|
||||||
render_index.get(),
|
|
||||||
pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"),
|
scene_delegate->clear_data();
|
||||||
BlenderSceneDelegate::EngineType::PREVIEW);
|
for (auto &prim : render_index->GetRprimIds()) {
|
||||||
|
render_index->RemoveRprim(prim);
|
||||||
|
render_index->RemoveInstancer(prim);
|
||||||
|
std::cout << "sync RemoveRprim: " << prim.GetText() << " " << render_index->HasRprim(prim)
|
||||||
|
<< "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &prim : render_index->GetRprimIds()) {
|
||||||
|
std::cout << "sync after Remove: " << prim.GetText() << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
scene_delegate->populate(depsgraph, context);
|
scene_delegate->populate(depsgraph, context);
|
||||||
|
|
||||||
|
for (auto &prim : render_index->GetRprimIds()) {
|
||||||
|
std::cout << "sync populate: " << prim.GetText() << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
for (auto const &setting : render_settings) {
|
for (auto const &setting : render_settings) {
|
||||||
render_delegate->SetRenderSetting(setting.first, setting.second);
|
render_delegate->SetRenderSetting(setting.first, setting.second);
|
||||||
}
|
}
|
||||||
|
is_synced = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreviewEngine::render(Depsgraph *depsgraph)
|
void PreviewEngine::render(Depsgraph *depsgraph)
|
||||||
{
|
{
|
||||||
|
//if (!is_synced) {
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
Scene *scene = DEG_get_input_scene(depsgraph);
|
Scene *scene = DEG_get_input_scene(depsgraph);
|
||||||
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
|
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
|
||||||
|
|
||||||
@ -35,6 +53,7 @@ void PreviewEngine::render(Depsgraph *depsgraph)
|
|||||||
CameraData(scene->camera, res, pxr::GfVec4f(0, 0, 1, 1)).gf_camera(pxr::GfVec4f(0, 0, 1, 1));
|
CameraData(scene->camera, res, pxr::GfVec4f(0, 0, 1, 1)).gf_camera(pxr::GfVec4f(0, 0, 1, 1));
|
||||||
|
|
||||||
free_camera_delegate->SetCamera(camera);
|
free_camera_delegate->SetCamera(camera);
|
||||||
|
//render_task_delegate->clear_renderer_aovs();
|
||||||
render_task_delegate->set_camera_and_viewport(free_camera_delegate->GetCameraId(),
|
render_task_delegate->set_camera_and_viewport(free_camera_delegate->GetCameraId(),
|
||||||
pxr::GfVec4d(0, 0, res[0], res[1]));
|
pxr::GfVec4d(0, 0, res[0], res[1]));
|
||||||
render_task_delegate->set_renderer_aov(pxr::HdAovTokens->color);
|
render_task_delegate->set_renderer_aov(pxr::HdAovTokens->color);
|
||||||
@ -70,6 +89,13 @@ void PreviewEngine::render(Depsgraph *depsgraph)
|
|||||||
update_render_result(layer_name, res[0], res[1], pixels);
|
update_render_result(layer_name, res[0], res[1], pixels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PreviewEngine::stop_renderer()
|
||||||
|
{
|
||||||
|
if (render_delegate) {
|
||||||
|
render_delegate->Stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PreviewEngine::update_render_result(const std::string &layer_name,
|
void PreviewEngine::update_render_result(const std::string &layer_name,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
|
@ -14,6 +14,9 @@ class PreviewEngine : public FinalEngine {
|
|||||||
bContext *context,
|
bContext *context,
|
||||||
pxr::HdRenderSettingsMap &render_settings) override;
|
pxr::HdRenderSettingsMap &render_settings) override;
|
||||||
void render(Depsgraph *depsgraph) override;
|
void render(Depsgraph *depsgraph) override;
|
||||||
|
void stop_renderer();
|
||||||
|
|
||||||
|
bool is_synced = false;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void update_render_result(const std::string &layer_name,
|
void update_render_result(const std::string &layer_name,
|
||||||
|
@ -16,8 +16,25 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "viewport_engine.h"
|
#include "viewport_engine.h"
|
||||||
|
|
||||||
|
#include "BLI_timer.h"
|
||||||
|
|
||||||
namespace blender::render::hydra {
|
namespace blender::render::hydra {
|
||||||
|
|
||||||
|
static double preview_engine_lifetime = 60.0;
|
||||||
|
static PreviewEngine *preview_engine;
|
||||||
|
|
||||||
|
double timer_func(uintptr_t uuid, void *user_data)
|
||||||
|
{
|
||||||
|
if (preview_engine) {
|
||||||
|
preview_engine->stop_renderer();
|
||||||
|
delete preview_engine;
|
||||||
|
preview_engine = nullptr;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return preview_engine_lifetime;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *init_func(PyObject * /*self*/, PyObject *args)
|
static PyObject *init_func(PyObject * /*self*/, PyObject *args)
|
||||||
{
|
{
|
||||||
CLOG_INFO(LOG_EN, 1, "Init");
|
CLOG_INFO(LOG_EN, 1, "Init");
|
||||||
@ -107,13 +124,21 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args)
|
|||||||
|
|
||||||
RenderEngine *bl_engine = (RenderEngine *)PyLong_AsVoidPtr(pyengine);
|
RenderEngine *bl_engine = (RenderEngine *)PyLong_AsVoidPtr(pyengine);
|
||||||
|
|
||||||
|
|
||||||
Engine *engine;
|
Engine *engine;
|
||||||
if (STREQ(engine_type, "VIEWPORT")) {
|
if (STREQ(engine_type, "VIEWPORT")) {
|
||||||
engine = new ViewportEngine(bl_engine, render_delegate_id);
|
engine = new ViewportEngine(bl_engine, render_delegate_id);
|
||||||
}
|
}
|
||||||
else if (STREQ(engine_type, "PREVIEW")) {
|
else if (STREQ(engine_type, "PREVIEW")) {
|
||||||
engine = new PreviewEngine(bl_engine, render_delegate_id);
|
if (!preview_engine) {
|
||||||
|
preview_engine = new PreviewEngine(bl_engine, render_delegate_id);
|
||||||
|
}
|
||||||
|
if (BLI_timer_is_registered(1)) {
|
||||||
|
BLI_timer_unregister(1);
|
||||||
|
}
|
||||||
|
preview_engine->bl_engine = bl_engine;
|
||||||
|
|
||||||
|
CLOG_INFO(LOG_EN, 2, "Engine %016llx %s", engine, engine_type);
|
||||||
|
return PyLong_FromVoidPtr(preview_engine);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) {
|
if (bl_engine->type->flag & RE_USE_GPU_CONTEXT) {
|
||||||
@ -136,7 +161,13 @@ static PyObject *engine_free_func(PyObject * /*self*/, PyObject *args)
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine *engine = (Engine *) PyLong_AsVoidPtr(pyengine);
|
Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine);
|
||||||
|
|
||||||
|
if (preview_engine) {
|
||||||
|
BLI_timer_register(1, timer_func, nullptr, nullptr, preview_engine_lifetime, true);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
delete engine;
|
delete engine;
|
||||||
|
|
||||||
CLOG_INFO(LOG_EN, 2, "Engine %016llx", engine);
|
CLOG_INFO(LOG_EN, 2, "Engine %016llx", engine);
|
||||||
|
@ -132,4 +132,13 @@ void RenderTaskDelegate::set_camera_and_viewport(pxr::SdfPath const &camera_id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderTaskDelegate::clear_renderer_aovs()
|
||||||
|
{
|
||||||
|
for (pxr::HdRenderPassAovBinding &binding : task_params.aovBindings) {
|
||||||
|
std::cout << "clear_renderer_aovs: " << binding.renderBufferId.GetText() << "\n";
|
||||||
|
GetRenderIndex().RemoveBprim(pxr::HdPrimTypeTokens->renderBuffer, binding.renderBufferId);
|
||||||
|
buffer_descriptors.erase(binding.renderBufferId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace blender::render::hydra
|
} // namespace blender::render::hydra
|
||||||
|
@ -27,6 +27,7 @@ class RenderTaskDelegate : public pxr::HdSceneDelegate {
|
|||||||
|
|
||||||
pxr::HdTaskSharedPtr get_task();
|
pxr::HdTaskSharedPtr get_task();
|
||||||
void set_camera_and_viewport(pxr::SdfPath const &cameraId, pxr::GfVec4d const &viewport);
|
void set_camera_and_viewport(pxr::SdfPath const &cameraId, pxr::GfVec4d const &viewport);
|
||||||
|
void clear_renderer_aovs();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
pxr::HdxRenderTaskParams task_params;
|
pxr::HdxRenderTaskParams task_params;
|
||||||
|
@ -477,4 +477,10 @@ pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id,
|
|||||||
return pxr::VtValue();
|
return pxr::VtValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BlenderSceneDelegate::clear_data()
|
||||||
|
{
|
||||||
|
objects.clear();
|
||||||
|
materials.clear();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace blender::render::hydra
|
} // namespace blender::render::hydra
|
||||||
|
@ -29,6 +29,7 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
|
|||||||
~BlenderSceneDelegate() override = default;
|
~BlenderSceneDelegate() override = default;
|
||||||
|
|
||||||
void populate(Depsgraph *depsgraph, bContext *context);
|
void populate(Depsgraph *depsgraph, bContext *context);
|
||||||
|
void clear_data();
|
||||||
|
|
||||||
// delegate methods
|
// delegate methods
|
||||||
pxr::HdMeshTopology GetMeshTopology(pxr::SdfPath const &id) override;
|
pxr::HdMeshTopology GetMeshTopology(pxr::SdfPath const &id) override;
|
||||||
|
@ -244,12 +244,6 @@ void ViewportEngine::sync(Depsgraph *depsgraph,
|
|||||||
bContext *context,
|
bContext *context,
|
||||||
pxr::HdRenderSettingsMap &render_settings)
|
pxr::HdRenderSettingsMap &render_settings)
|
||||||
{
|
{
|
||||||
if (!scene_delegate) {
|
|
||||||
scene_delegate = std::make_unique<BlenderSceneDelegate>(
|
|
||||||
render_index.get(),
|
|
||||||
pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"),
|
|
||||||
BlenderSceneDelegate::EngineType::VIEWPORT);
|
|
||||||
}
|
|
||||||
scene_delegate->populate(depsgraph, context);
|
scene_delegate->populate(depsgraph, context);
|
||||||
|
|
||||||
for (auto const &setting : render_settings) {
|
for (auto const &setting : render_settings) {
|
||||||
|
Loading…
Reference in New Issue
Block a user