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 {
|
||||||
@ -59,6 +59,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):
|
||||||
@ -75,15 +76,13 @@ 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 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
|
||||||
|
@ -5,17 +5,64 @@
|
|||||||
|
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "preview_engine.h"
|
#include "preview_engine.h"
|
||||||
|
#include "BLI_timer.h"
|
||||||
|
|
||||||
namespace blender::render::hydra {
|
namespace blender::render::hydra {
|
||||||
|
|
||||||
|
const double LIFETIME = 180.0;
|
||||||
|
|
||||||
|
std::unique_ptr<PreviewEngine> PreviewEngine::instance;
|
||||||
|
|
||||||
|
void PreviewEngine::schedule_free()
|
||||||
|
{
|
||||||
DagerD marked this conversation as resolved
Outdated
|
|||||||
|
instance->render_delegate->Stop();
|
||||||
|
|
||||||
|
/* Register timer for schedule free PreviewEngine instance */
|
||||||
|
BLI_timer_register((uintptr_t)instance.get(),
|
||||||
|
free_instance,
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
LIFETIME,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
|
PreviewEngine *PreviewEngine::get_instance(RenderEngine *bl_engine, const std::string &render_delegate_id)
|
||||||
|
{
|
||||||
|
if (!instance) {
|
||||||
|
instance = std::make_unique<PreviewEngine>(bl_engine, render_delegate_id);
|
||||||
|
}
|
||||||
|
if (BLI_timer_is_registered((uintptr_t)instance.get())) {
|
||||||
|
/* Unregister timer while PreviewEngine is working */
|
||||||
|
BLI_timer_unregister((uintptr_t)instance.get());
|
||||||
|
}
|
||||||
|
instance->update(bl_engine, render_delegate_id);
|
||||||
|
|
||||||
|
return instance.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
double PreviewEngine::free_instance(uintptr_t uuid, void *user_data)
|
||||||
|
{
|
||||||
|
if (!instance->render_task_delegate->is_converged()) {
|
||||||
|
/* Restart timer if render isn't completed */
|
||||||
|
return LIFETIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLOG_INFO(LOG_EN, 2, "");
|
||||||
|
instance = nullptr;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void PreviewEngine::sync(Depsgraph *depsgraph,
|
void PreviewEngine::sync(Depsgraph *depsgraph,
|
||||||
bContext *context,
|
bContext *context,
|
||||||
pxr::HdRenderSettingsMap &render_settings)
|
pxr::HdRenderSettingsMap &render_settings)
|
||||||
{
|
{
|
||||||
|
if (!scene_delegate) {
|
||||||
scene_delegate = std::make_unique<BlenderSceneDelegate>(
|
scene_delegate = std::make_unique<BlenderSceneDelegate>(
|
||||||
render_index.get(),
|
render_index.get(),
|
||||||
pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"),
|
pxr::SdfPath::AbsoluteRootPath().AppendElementString("scene"),
|
||||||
BlenderSceneDelegate::EngineType::PREVIEW);
|
BlenderSceneDelegate::EngineType::PREVIEW);
|
||||||
|
}
|
||||||
|
scene_delegate->clear();
|
||||||
scene_delegate->populate(depsgraph, context);
|
scene_delegate->populate(depsgraph, context);
|
||||||
|
|
||||||
for (auto const &setting : render_settings) {
|
for (auto const &setting : render_settings) {
|
||||||
@ -70,6 +117,12 @@ 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::update(RenderEngine *bl_engine, const std::string &render_delegate_id)
|
||||||
|
{
|
||||||
|
this->bl_engine = bl_engine;
|
||||||
|
/* TODO: recreate render_delegate when render_delegate_id is changed */
|
||||||
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
@ -8,21 +8,28 @@
|
|||||||
namespace blender::render::hydra {
|
namespace blender::render::hydra {
|
||||||
|
|
||||||
class PreviewEngine : public FinalEngine {
|
class PreviewEngine : public FinalEngine {
|
||||||
|
private:
|
||||||
|
/* Singleton class instance */
|
||||||
|
static std::unique_ptr<PreviewEngine> instance;
|
||||||
|
static double free_instance(uintptr_t uuid, void *user_data);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static PreviewEngine *get_instance(RenderEngine *bl_engine, const std::string &render_delegate_id);
|
||||||
|
static void schedule_free();
|
||||||
|
|
||||||
using FinalEngine::FinalEngine;
|
using FinalEngine::FinalEngine;
|
||||||
void sync(Depsgraph *depsgraph,
|
void sync(Depsgraph *depsgraph,
|
||||||
bContext *context,
|
bContext *context,
|
||||||
pxr::HdRenderSettingsMap &render_settings) override;
|
pxr::HdRenderSettingsMap &render_settings) override;
|
||||||
void render(Depsgraph *depsgraph) override;
|
void render(Depsgraph *depsgraph) override;
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
void update(RenderEngine *bl_engine, const std::string &render_delegate_id);
|
||||||
void update_render_result(const std::string &layer_name,
|
void update_render_result(const std::string &layer_name,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
std::vector<float> &pixels);
|
std::vector<float> &pixels);
|
||||||
|
|
||||||
protected:
|
|
||||||
pxr::HdRenderSettingsMap render_settings;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace blender::render::hydra
|
} // namespace blender::render::hydra
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
#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 PyObject *init_func(PyObject * /*self*/, PyObject *args)
|
static PyObject *init_func(PyObject * /*self*/, PyObject *args)
|
||||||
DagerD marked this conversation as resolved
Outdated
Bogdan Nagirniak
commented
move to PreviewEngine class as static move to PreviewEngine class as static
|
|||||||
@ -112,7 +114,7 @@ static PyObject *engine_create_func(PyObject * /*self*/, PyObject *args)
|
|||||||
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);
|
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) {
|
||||||
@ -136,7 +138,13 @@ static PyObject *engine_free_func(PyObject * /*self*/, PyObject *args)
|
|||||||
}
|
}
|
||||||
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
|
|||||||
|
|
||||||
Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine);
|
Engine *engine = (Engine *)PyLong_AsVoidPtr(pyengine);
|
||||||
|
PreviewEngine *preview_engine = dynamic_cast<PreviewEngine *>(engine);
|
||||||
|
if (preview_engine) {
|
||||||
|
PreviewEngine::schedule_free();
|
||||||
|
}
|
||||||
|
else {
|
||||||
delete engine;
|
delete engine;
|
||||||
|
}
|
||||||
|
|
||||||
CLOG_INFO(LOG_EN, 2, "Engine %016llx", engine);
|
CLOG_INFO(LOG_EN, 2, "Engine %016llx", engine);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
@ -434,4 +434,18 @@ pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id,
|
|||||||
return pxr::VtValue();
|
return pxr::VtValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BlenderSceneDelegate::clear()
|
||||||
|
{
|
||||||
|
for (auto &it : materials) {
|
||||||
DagerD marked this conversation as resolved
Outdated
Bogdan Nagirniak
commented
```
for (auto &it : materials) {
it.second->remove();
}
```
|
|||||||
|
it.second->remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &it : objects) {
|
||||||
|
it.second->remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
materials.clear();
|
||||||
|
objects.clear();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace blender::render::hydra
|
} // namespace blender::render::hydra
|
||||||
|
@ -33,6 +33,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();
|
||||||
|
|
||||||
// delegate methods
|
// delegate methods
|
||||||
pxr::HdMeshTopology GetMeshTopology(pxr::SdfPath const &id) override;
|
pxr::HdMeshTopology GetMeshTopology(pxr::SdfPath const &id) override;
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
#include <pxr/imaging/hd/tokens.h>
|
#include <pxr/imaging/hd/tokens.h>
|
||||||
#include <pxr/usd/usdLux/tokens.h>
|
#include <pxr/usd/usdLux/tokens.h>
|
||||||
|
|
||||||
#include "BKE_light.h"
|
|
||||||
#include "DNA_light_types.h"
|
#include "DNA_light_types.h"
|
||||||
|
|
||||||
#include "blender_scene_delegate.h"
|
#include "blender_scene_delegate.h"
|
||||||
@ -80,13 +79,14 @@ void LightData::init()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p_type = prim_type(light);
|
||||||
|
|
||||||
/* TODO: temporary value, it should be delivered through Python UI */
|
/* TODO: temporary value, it should be delivered through Python UI */
|
||||||
data[pxr::HdLightTokens->exposure] = 1.0f;
|
data[pxr::HdLightTokens->exposure] = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxr::TfToken LightData::prim_type()
|
pxr::TfToken LightData::prim_type(Light *light)
|
||||||
{
|
{
|
||||||
Light *light = (Light *)((Object *)id)->data;
|
|
||||||
pxr::TfToken ret;
|
pxr::TfToken ret;
|
||||||
switch (light->type) {
|
switch (light->type) {
|
||||||
case LA_LOCAL:
|
case LA_LOCAL:
|
||||||
@ -155,21 +155,27 @@ bool LightData::update_visibility(View3D *view3d)
|
|||||||
void LightData::insert()
|
void LightData::insert()
|
||||||
{
|
{
|
||||||
CLOG_INFO(LOG_BSD, 2, "%s", id->name);
|
CLOG_INFO(LOG_BSD, 2, "%s", id->name);
|
||||||
scene_delegate->GetRenderIndex().InsertSprim(prim_type(), scene_delegate, p_id);
|
scene_delegate->GetRenderIndex().InsertSprim(p_type, scene_delegate, p_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightData::remove()
|
void LightData::remove()
|
||||||
{
|
{
|
||||||
CLOG_INFO(LOG_BSD, 2, "%s", id->name);
|
CLOG_INFO(LOG_BSD, 2, "%s", id->name);
|
||||||
scene_delegate->GetRenderIndex().RemoveSprim(prim_type(), p_id);
|
scene_delegate->GetRenderIndex().RemoveSprim(p_type, p_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightData::update()
|
void LightData::update()
|
||||||
{
|
{
|
||||||
/* TODO: prim_type was changed we have to do remove..add light */
|
|
||||||
|
|
||||||
CLOG_INFO(LOG_BSD, 2, "%s", id->name);
|
CLOG_INFO(LOG_BSD, 2, "%s", id->name);
|
||||||
|
|
||||||
|
Light *light = (Light *)((Object *)id)->data;
|
||||||
|
if (prim_type(light) != p_type) {
|
||||||
|
remove();
|
||||||
|
init();
|
||||||
|
insert();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
pxr::HdDirtyBits bits = pxr::HdLight::Clean;
|
pxr::HdDirtyBits bits = pxr::HdLight::Clean;
|
||||||
if (id->recalc & ID_RECALC_GEOMETRY) {
|
if (id->recalc & ID_RECALC_GEOMETRY) {
|
||||||
init();
|
init();
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#include <pxr/usd/sdf/assetPath.h>
|
#include <pxr/usd/sdf/assetPath.h>
|
||||||
#include <pxr/usd/sdf/path.h>
|
#include <pxr/usd/sdf/path.h>
|
||||||
|
|
||||||
|
#include "BKE_light.h"
|
||||||
|
|
||||||
#include "object.h"
|
#include "object.h"
|
||||||
|
|
||||||
namespace blender::render::hydra {
|
namespace blender::render::hydra {
|
||||||
@ -24,7 +26,8 @@ class LightData : public ObjectData {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<pxr::TfToken, pxr::VtValue> data;
|
std::map<pxr::TfToken, pxr::VtValue> data;
|
||||||
DagerD marked this conversation as resolved
Outdated
Bogdan Nagirniak
commented
`pxr::TfToken p_type;`
make prim_type() with `Light *` parameter
|
|||||||
pxr::TfToken prim_type();
|
pxr::TfToken p_type;
|
||||||
|
pxr::TfToken prim_type(Light *light);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace blender::render::hydra
|
} // namespace blender::render::hydra
|
||||||
|
Loading…
Reference in New Issue
Block a user
Move this to clear()