forked from blender/blender
BLEN-365: Improve creation algorithm of PreviewEngine #21
@ -19,7 +19,7 @@ class CustomHydraRenderEngine(HydraRenderEngine):
|
||||
def register(cls):
|
||||
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):
|
||||
return {
|
||||
@ -58,6 +58,7 @@ class HydraRenderEngine(bpy.types.RenderEngine):
|
||||
return
|
||||
|
||||
_bpy_hydra.engine_free(self.engine_ptr)
|
||||
del self.engine_ptr
|
||||
|
||||
@classmethod
|
||||
def register(cls):
|
||||
@ -74,20 +75,18 @@ class HydraRenderEngine(bpy.types.RenderEngine):
|
||||
|
||||
# final render
|
||||
def update(self, data, depsgraph):
|
||||
pass
|
||||
|
||||
def render(self, 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)
|
||||
_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
|
||||
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)
|
||||
|
||||
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>();
|
||||
|
||||
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()
|
||||
@ -54,6 +59,7 @@ Engine::~Engine()
|
||||
render_delegate = 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;
|
||||
bl_engine = nullptr;
|
||||
}
|
||||
|
||||
float Engine::renderer_percent_done()
|
||||
|
@ -34,12 +34,12 @@ class Engine {
|
||||
bContext *context,
|
||||
pxr::HdRenderSettingsMap &render_settings) = 0;
|
||||
virtual void render(Depsgraph *depsgraph) = 0;
|
||||
|
||||
RenderEngine *bl_engine;
|
||||
protected:
|
||||
float renderer_percent_done();
|
||||
|
||||
protected:
|
||||
RenderEngine *bl_engine;
|
||||
|
||||
|
||||
pxr::HdPluginRenderDelegateUniqueHandle render_delegate;
|
||||
std::unique_ptr<pxr::HdRenderIndex> render_index;
|
||||
|
@ -16,10 +16,6 @@ void FinalEngine::sync(Depsgraph *depsgraph,
|
||||
bContext *context,
|
||||
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);
|
||||
|
||||
for (auto const &setting : render_settings) {
|
||||
|
@ -12,19 +12,37 @@ void PreviewEngine::sync(Depsgraph *depsgraph,
|
||||
bContext *context,
|
||||
pxr::HdRenderSettingsMap &render_settings)
|
||||
{
|
||||
scene_delegate = std::make_unique<BlenderSceneDelegate>(
|
||||
render_index.get(),
|
||||
pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"),
|
||||
BlenderSceneDelegate::EngineType::PREVIEW);
|
||||
is_synced = false;
|
||||
|
||||
scene_delegate->clear_data();
|
||||
DagerD marked this conversation as resolved
Outdated
Bogdan Nagirniak
commented
Move this to clear() Move this to clear()
|
||||
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);
|
||||
|
||||
for (auto &prim : render_index->GetRprimIds()) {
|
||||
std::cout << "sync populate: " << prim.GetText() << "\n";
|
||||
}
|
||||
|
||||
for (auto const &setting : render_settings) {
|
||||
render_delegate->SetRenderSetting(setting.first, setting.second);
|
||||
}
|
||||
is_synced = true;
|
||||
}
|
||||
|
||||
void PreviewEngine::render(Depsgraph *depsgraph)
|
||||
{
|
||||
//if (!is_synced) {
|
||||
// return;
|
||||
//}
|
||||
Scene *scene = DEG_get_input_scene(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));
|
||||
|
||||
free_camera_delegate->SetCamera(camera);
|
||||
//render_task_delegate->clear_renderer_aovs();
|
||||
render_task_delegate->set_camera_and_viewport(free_camera_delegate->GetCameraId(),
|
||||
pxr::GfVec4d(0, 0, res[0], res[1]));
|
||||
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);
|
||||
}
|
||||
|
||||
void PreviewEngine::stop_renderer()
|
||||
{
|
||||
if (render_delegate) {
|
||||
render_delegate->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void PreviewEngine::update_render_result(const std::string &layer_name,
|
||||
int width,
|
||||
int height,
|
||||
|
@ -14,6 +14,9 @@ class PreviewEngine : public FinalEngine {
|
||||
bContext *context,
|
||||
pxr::HdRenderSettingsMap &render_settings) override;
|
||||
void render(Depsgraph *depsgraph) override;
|
||||
void stop_renderer();
|
||||
|
||||
bool is_synced = false;
|
||||
|
||||
protected:
|
||||
void update_render_result(const std::string &layer_name,
|
||||
|
@ -16,8 +16,25 @@
|
||||
#include "utils.h"
|
||||
#include "viewport_engine.h"
|
||||
|
||||
#include "BLI_timer.h"
|
||||
|
||||
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)
|
||||
{
|
||||
CLOG_INFO(LOG_EN, 1, "Init");
|
||||
@ -106,14 +123,22 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args)
|
||||
}
|
||||
|
||||
RenderEngine *bl_engine = (RenderEngine *)PyLong_AsVoidPtr(pyengine);
|
||||
|
||||
|
||||
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")) {
|
||||
engine = new ViewportEngine(bl_engine, render_delegate_id);
|
||||
}
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
|
@ -27,6 +27,7 @@ class RenderTaskDelegate : public pxr::HdSceneDelegate {
|
||||
|
||||
pxr::HdTaskSharedPtr get_task();
|
||||
void set_camera_and_viewport(pxr::SdfPath const &cameraId, pxr::GfVec4d const &viewport);
|
||||
void clear_renderer_aovs();
|
||||
|
||||
private:
|
||||
pxr::HdxRenderTaskParams task_params;
|
||||
|
@ -477,4 +477,10 @@ pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id,
|
||||
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
|
||||
|
@ -29,6 +29,7 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
|
||||
~BlenderSceneDelegate() override = default;
|
||||
|
||||
void populate(Depsgraph *depsgraph, bContext *context);
|
||||
void clear_data();
|
||||
|
||||
// delegate methods
|
||||
pxr::HdMeshTopology GetMeshTopology(pxr::SdfPath const &id) override;
|
||||
|
@ -244,12 +244,6 @@ void ViewportEngine::sync(Depsgraph *depsgraph,
|
||||
bContext *context,
|
||||
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);
|
||||
|
||||
for (auto const &setting : render_settings) {
|
||||
|
Loading…
Reference in New Issue
Block a user
There could be other types of engines