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)
|
||||||
|
|
||||||
|
def render(self, depsgraph):
|
||||||
|
if hasattr(self, 'engine_ptr'):
|
||||||
_bpy_hydra.engine_render(self.engine_ptr, depsgraph.as_pointer())
|
_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);
|
||||||
DagerD marked this conversation as resolved
Outdated
|
|||||||
}
|
}
|
||||||
|
|
||||||
Engine::~Engine()
|
Engine::~Engine()
|
||||||
@ -54,6 +59,7 @@ Engine::~Engine()
|
|||||||
render_delegate = nullptr;
|
render_delegate = nullptr;
|
||||||
engine = nullptr;
|
engine = nullptr;
|
||||||
DagerD marked this conversation as resolved
Outdated
Bogdan Nagirniak
commented
This function is not needed This function is not needed
|
|||||||
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();
|
||||||
DagerD marked this conversation as resolved
Outdated
Bogdan Nagirniak
commented
Move this to clear() Move this to clear()
|
|||||||
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;
|
||||||
DagerD marked this conversation as resolved
Outdated
Bogdan Nagirniak
commented
move to PreviewEngine class as static move to PreviewEngine class as static
|
|||||||
|
static PreviewEngine *preview_engine;
|
||||||
DagerD marked this conversation as resolved
Outdated
Bogdan Nagirniak
commented
Use unique_ptr Use unique_ptr
|
|||||||
|
|
||||||
|
double timer_func(uintptr_t uuid, void *user_data)
|
||||||
|
{
|
||||||
|
if (preview_engine) {
|
||||||
|
preview_engine->stop_renderer();
|
||||||
DagerD marked this conversation as resolved
Outdated
Bogdan Nagirniak
commented
add logging add logging
Bogdan Nagirniak
commented
Do not stop render, check if it is in render process, then return preview_engine_lifetime. Do not stop render, check if it is in render process, then return preview_engine_lifetime.
|
|||||||
|
delete preview_engine;
|
||||||
|
preview_engine = nullptr;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return preview_engine_lifetime;
|
||||||
|
}
|
||||||
DagerD marked this conversation as resolved
Outdated
Bogdan Nagirniak
commented
Move this function to preview_engein.cc Move this function to preview_engein.cc
Probably it can be static function of PreviewEngine class
|
|||||||
|
|
||||||
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;
|
||||||
DagerD marked this conversation as resolved
Outdated
Bogdan Nagirniak
commented
This block should be like: This block should be like:
`engine = PreviewEngine::get(bl_engine, render_delegate_id);`
|
|||||||
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;
|
||||||
DagerD marked this conversation as resolved
Outdated
Bogdan Nagirniak
commented
Add PreviewEngine::update_engine() instead public usage of bl_engine Add PreviewEngine::update_engine() instead public usage of 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) {
|
||||||
@ -137,6 +162,12 @@ static PyObject *engine_free_func(PyObject * /*self*/, PyObject *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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()
|
||||||
DagerD marked this conversation as resolved
Outdated
Bogdan Nagirniak
commented
Rename to just "clear" Rename to just "clear"
|
|||||||
|
{
|
||||||
|
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
There could be other types of engines