BLEN-359: Implement updates for instances in viewport #20

Merged
Bogdan Nagirniak merged 20 commits from BLEN-359_1 into hydra-render 2023-04-05 11:47:37 +02:00
14 changed files with 121 additions and 68 deletions
Showing only changes of commit 1e462a8aff - Show all commits

View File

@ -32,10 +32,10 @@ void BlenderSceneDelegate::set_material(MeshData &mesh_data)
pxr::SdfPath id = MaterialData::prim_id(this, material);
MaterialData *mat_data = material_data(id);
if (!mat_data) {
materials[id] = MaterialData::init(this, material);
materials[id] = MaterialData::create(this, material);
mat_data = material_data(id);
mat_data->export_mtlx();
mat_data->insert_prim();
mat_data->insert();
}
mesh_data.material_id = id;
}
@ -45,7 +45,7 @@ void BlenderSceneDelegate::update_material(Material *material)
MaterialData *mat_data = material_data(MaterialData::prim_id(this, material));
if (mat_data) {
mat_data->export_mtlx();
mat_data->mark_prim_dirty(IdData::DirtyBits::ALL_DIRTY);
mat_data->update(IdData::DirtyBits::ALL_DIRTY);
}
}
@ -55,17 +55,17 @@ void BlenderSceneDelegate::update_world()
World *world = scene->world;
if (!world_data) {
if (world) {
world_data = WorldData::init(this, world, context);
world_data->insert_prim();
world_data = WorldData::create(this, world, context);
world_data->insert();
}
}
else {
if (world) {
world_data = WorldData::init(this, world, context);
world_data->mark_prim_dirty(IdData::DirtyBits::ALL_DIRTY);
world_data = WorldData::create(this, world, context);
world_data->update(IdData::DirtyBits::ALL_DIRTY);
}
else {
world_data->remove_prim();
world_data->remove();
world_data = nullptr;
}
}
@ -136,7 +136,7 @@ void BlenderSceneDelegate::update_collection(bool remove, bool visibility)
/* Check and update visibility */
for (auto &obj : objects) {
if (obj.second->update_visibility(view3d)) {
obj.second->mark_prim_dirty(IdData::DirtyBits::DIRTY_VISIBILITY);
obj.second->update(IdData::DirtyBits::DIRTY_VISIBILITY);
};
}
}
@ -186,7 +186,7 @@ void BlenderSceneDelegate::update_collection(bool remove, bool visibility)
if (available_objects.find(it->first) != available_objects.end()) {
continue;
}
it->second->remove_prim();
it->second->remove();
objects.erase(it);
it = objects.begin();
}
@ -203,7 +203,7 @@ void BlenderSceneDelegate::update_collection(bool remove, bool visibility)
if (available_materials.find(it->first) != available_materials.end()) {
continue;
}
it->second->remove_prim();
it->second->remove();
materials.erase(it);
it = materials.begin();
}
@ -218,10 +218,10 @@ void BlenderSceneDelegate::add_update_object(Object *object,
pxr::SdfPath id = ObjectData::prim_id(this, object);
ObjectData *obj_data = object_data(id);
if (!obj_data) {
objects[id] = ObjectData::init(this, object);
objects[id] = ObjectData::create(this, object);
obj_data = object_data(id);
obj_data->update_visibility(view3d);
obj_data->insert_prim();
obj_data->insert();
MeshData *m_data = dynamic_cast<MeshData *>(obj_data);
if (m_data) {
set_material(*m_data);
@ -230,23 +230,23 @@ void BlenderSceneDelegate::add_update_object(Object *object,
}
if (geometry) {
objects[id] = ObjectData::init(this, object);
objects[id] = ObjectData::create(this, object);
obj_data = object_data(id);
obj_data->update_visibility(view3d);
MeshData *m_data = dynamic_cast<MeshData *>(obj_data);
if (m_data) {
set_material(*m_data);
}
obj_data->mark_prim_dirty(IdData::DirtyBits::ALL_DIRTY);
obj_data->update(IdData::DirtyBits::ALL_DIRTY);
return;
}
if (transform) {
obj_data->mark_prim_dirty(IdData::DirtyBits::DIRTY_TRANSFORM);
obj_data->update(IdData::DirtyBits::DIRTY_TRANSFORM);
}
if (shading) {
obj_data->mark_prim_dirty(IdData::DirtyBits::DIRTY_MATERIAL);
obj_data->update(IdData::DirtyBits::DIRTY_MATERIAL);
}
}

View File

@ -20,6 +20,8 @@ namespace blender::render::hydra {
extern struct CLG_LogRef *LOG_BSD; /* BSD - Blender Scene Delegate */
class BlenderSceneDelegate : public pxr::HdSceneDelegate {
friend MeshData;
public:
enum class EngineType { VIEWPORT = 1, FINAL, PREVIEW };

View File

@ -11,16 +11,24 @@ namespace blender::render::hydra {
IdData::IdData(BlenderSceneDelegate *scene_delegate, ID *id)
: scene_delegate(scene_delegate), id(id)
{
//p_id = prim_id();
//init();
//insert();
}
std::string IdData::name()
IdData::~IdData()
{
//remove();
}
std::string IdData::name() const
{
char str[MAX_ID_FULL_NAME];
BKE_id_full_name_get(str, id, 0);
return str;
}
pxr::VtValue IdData::get_data(pxr::TfToken const &key)
pxr::VtValue IdData::get_data(pxr::TfToken const &key) const
{
return pxr::VtValue();
}

View File

@ -16,17 +16,20 @@ class BlenderSceneDelegate;
class IdData {
public:
IdData(BlenderSceneDelegate *scene_delegate, ID *id);
virtual ~IdData() = default;
std::string name();
virtual pxr::VtValue get_data(pxr::TfToken const &key);
template<class T> const T get_data(pxr::TfToken const &key);
virtual ~IdData();
enum class DirtyBits { DIRTY_TRANSFORM = 1, DIRTY_VISIBILITY, DIRTY_MATERIAL, ALL_DIRTY };
virtual pxr::SdfPath prim_id() const = 0;
virtual void init() = 0;
virtual void insert() = 0;
virtual void remove() = 0;
virtual void update(DirtyBits dirty_bits) = 0;
virtual void insert_prim() = 0;
virtual void remove_prim() = 0;
virtual void mark_prim_dirty(DirtyBits dirty_bits) = 0;
virtual pxr::VtValue get_data(pxr::TfToken const &key) const;
template<class T> const T get_data(pxr::TfToken const &key) const;
std::string name() const;
protected:
BlenderSceneDelegate *scene_delegate;
@ -34,7 +37,7 @@ class IdData {
pxr::SdfPath p_id;
};
template<class T> const T IdData::get_data(pxr::TfToken const &key)
template<class T> const T IdData::get_data(pxr::TfToken const &key) const
{
return get_data(key).Get<T>();
}

View File

@ -112,7 +112,7 @@ pxr::TfToken LightData::prim_type()
return ret;
}
pxr::VtValue LightData::get_data(pxr::TfToken const &key)
pxr::VtValue LightData::get_data(pxr::TfToken const &key) const
{
pxr::VtValue ret;
auto it = data.find(key);
@ -133,19 +133,23 @@ pxr::VtValue LightData::get_data(pxr::TfToken const &key)
return ret;
}
void LightData::insert_prim()
void LightData::init()
{
}
void LightData::insert()
{
scene_delegate->GetRenderIndex().InsertSprim(prim_type(), scene_delegate, p_id);
CLOG_INFO(LOG_BSD, 2, "Add: %s id=%s", name().c_str(), p_id.GetString().c_str());
}
void LightData::remove_prim()
void LightData::remove()
{
scene_delegate->GetRenderIndex().RemoveSprim(prim_type(), p_id);
CLOG_INFO(LOG_BSD, 2, "Remove: %s", name().c_str());
}
void LightData::mark_prim_dirty(DirtyBits dirty_bits)
void LightData::update(DirtyBits dirty_bits)
{
/* TODO: prim_type was changed we have to do remove..add light */

View File

@ -15,10 +15,11 @@ class LightData : public ObjectData {
public:
LightData(BlenderSceneDelegate *scene_delegate, Object *object);
pxr::VtValue get_data(pxr::TfToken const &key) override;
void insert_prim() override;
void remove_prim() override;
void mark_prim_dirty(DirtyBits dirty_bits) override;
void init() override;
void insert() override;
void remove() override;
void update(DirtyBits dirty_bits) override;
pxr::VtValue get_data(pxr::TfToken const &key) const override;
private:
std::map<pxr::TfToken, pxr::VtValue> data;

View File

@ -20,7 +20,7 @@
namespace blender::render::hydra {
std::unique_ptr<MaterialData> MaterialData::init(BlenderSceneDelegate *scene_delegate,
std::unique_ptr<MaterialData> MaterialData::create(BlenderSceneDelegate *scene_delegate,
Material *material)
{
return std::make_unique<MaterialData>(scene_delegate, material);
@ -41,7 +41,16 @@ MaterialData::MaterialData(BlenderSceneDelegate *scene_delegate, Material *mater
p_id = prim_id(scene_delegate, material);
}
pxr::VtValue MaterialData::get_data(pxr::TfToken const &key)
pxr::SdfPath MaterialData::prim_id() const
{
return pxr::SdfPath();
}
void MaterialData::init()
{
}
pxr::VtValue MaterialData::get_data(pxr::TfToken const &key) const
{
pxr::VtValue ret;
if (key.GetString() == "MaterialXFilename") {
@ -109,20 +118,20 @@ void MaterialData::export_mtlx()
CLOG_INFO(LOG_BSD, 2, "Export: %s, mtlx=%s", name().c_str(), mtlx_path.GetResolvedPath().c_str());
}
void MaterialData::insert_prim()
void MaterialData::insert()
{
scene_delegate->GetRenderIndex().InsertSprim(
pxr::HdPrimTypeTokens->material, scene_delegate, p_id);
CLOG_INFO(LOG_BSD, 2, "Add: %s id=%s", name().c_str(), p_id.GetString().c_str());
}
void MaterialData::remove_prim()
void MaterialData::remove()
{
scene_delegate->GetRenderIndex().RemoveSprim(pxr::HdPrimTypeTokens->material, p_id);
CLOG_INFO(LOG_BSD, 2, "Remove: %s", name().c_str());
}
void MaterialData::mark_prim_dirty(DirtyBits dirty_bits)
void MaterialData::update(DirtyBits dirty_bits)
{
pxr::HdDirtyBits bits = pxr::HdMaterial::Clean;
switch (dirty_bits) {

View File

@ -15,16 +15,18 @@ namespace blender::render::hydra {
class MaterialData : IdData {
public:
static std::unique_ptr<MaterialData> init(BlenderSceneDelegate *scene_delegate,
static std::unique_ptr<MaterialData> create(BlenderSceneDelegate *scene_delegate,
Material *material);
static pxr::SdfPath prim_id(BlenderSceneDelegate *scene_delegate, Material *material);
MaterialData(BlenderSceneDelegate *scene_delegate, Material *material);
pxr::VtValue get_data(pxr::TfToken const &key) override;
void insert_prim() override;
void remove_prim() override;
void mark_prim_dirty(DirtyBits dirty_bits) override;
pxr::SdfPath prim_id() const override;
void init() override;
void insert() override;
void remove() override;
void update(DirtyBits dirty_bits) override;
pxr::VtValue get_data(pxr::TfToken const &key) const override;
pxr::VtValue material_resource();
void export_mtlx();

View File

@ -31,7 +31,7 @@ MeshData::MeshData(BlenderSceneDelegate *scene_delegate, Object *object)
}
}
pxr::VtValue MeshData::get_data(pxr::TfToken const &key)
pxr::VtValue MeshData::get_data(pxr::TfToken const &key) const
{
pxr::VtValue ret;
if (key == pxr::HdTokens->points) {
@ -200,7 +200,11 @@ void MeshData::set_mesh(Mesh *mesh)
}
}
void MeshData::insert_prim()
void MeshData::init()
{
}
void MeshData::insert()
{
if (face_vertex_counts.empty()) {
return;
@ -210,7 +214,7 @@ void MeshData::insert_prim()
CLOG_INFO(LOG_BSD, 2, "Add: %s id=%s", name().c_str(), p_id.GetString().c_str());
}
void MeshData::remove_prim()
void MeshData::remove()
{
if (!scene_delegate->GetRenderIndex().HasRprim(p_id)) {
return;
@ -220,17 +224,17 @@ void MeshData::remove_prim()
CLOG_INFO(LOG_BSD, 2, "Remove: %s", name().c_str());
}
void MeshData::mark_prim_dirty(DirtyBits dirty_bits)
void MeshData::update(DirtyBits dirty_bits)
{
if (!scene_delegate->GetRenderIndex().HasRprim(p_id)) {
/* Trying to insert prim */
insert_prim();
insert();
return;
}
if (face_vertex_counts.empty()) {
/* Remove prim without faces */
remove_prim();
remove();
return;
}

View File

@ -16,11 +16,12 @@ class MeshData : public ObjectData {
public:
MeshData(BlenderSceneDelegate *scene_delegate, Object *object);
pxr::VtValue get_data(pxr::TfToken const &key) override;
void init() override;
void insert() override;
void remove() override;
void update(DirtyBits dirty_bits) override;
void insert_prim() override;
void remove_prim() override;
void mark_prim_dirty(DirtyBits dirty_bits) override;
pxr::VtValue get_data(pxr::TfToken const &key) const override;
Material *material();
pxr::HdMeshTopology mesh_topology();

View File

@ -28,7 +28,7 @@ bool ObjectData::supported(Object *object)
return false;
}
std::unique_ptr<ObjectData> ObjectData::init(BlenderSceneDelegate *scene_delegate, Object *object)
std::unique_ptr<ObjectData> ObjectData::create(BlenderSceneDelegate *scene_delegate, Object *object)
{
switch (object->type) {
case OB_MESH:
@ -63,6 +63,11 @@ ObjectData::ObjectData(BlenderSceneDelegate *scene_delegate, Object *object)
p_id = prim_id(scene_delegate, object);
}
pxr::SdfPath ObjectData::prim_id() const
{
return pxr::SdfPath();
}
int ObjectData::type()
{
return ((Object *)id)->type;

View File

@ -17,11 +17,13 @@ namespace blender::render::hydra {
class ObjectData : public IdData {
public:
static bool supported(Object *object);
static std::unique_ptr<ObjectData> init(BlenderSceneDelegate *scene_delegate, Object *object);
static std::unique_ptr<ObjectData> create(BlenderSceneDelegate *scene_delegate, Object *object);
static pxr::SdfPath prim_id(BlenderSceneDelegate *scene_delegate, Object *object);
ObjectData(BlenderSceneDelegate *scene_delegate, Object *object);
pxr::SdfPath prim_id() const override;
int type();
pxr::GfMatrix4d transform();
bool update_visibility(View3D *view3d);

View File

@ -28,7 +28,7 @@
namespace blender::render::hydra {
std::unique_ptr<WorldData> WorldData::init(BlenderSceneDelegate *scene_delegate,
std::unique_ptr<WorldData> WorldData::create(BlenderSceneDelegate *scene_delegate,
World *world,
bContext *context)
{
@ -100,6 +100,15 @@ WorldData::WorldData(BlenderSceneDelegate *scene_delegate, World *world, bContex
}
}
pxr::SdfPath WorldData::prim_id() const
{
return pxr::SdfPath();
}
void WorldData::init()
{
}
pxr::GfMatrix4d WorldData::transform()
{
pxr::GfMatrix4d transform = pxr::GfMatrix4d(pxr::GfRotation(pxr::GfVec3d(1.0, 0.0, 0.0), -90),
@ -115,7 +124,7 @@ pxr::GfMatrix4d WorldData::transform()
return transform;
}
pxr::VtValue WorldData::get_data(pxr::TfToken const &key)
pxr::VtValue WorldData::get_data(pxr::TfToken const &key) const
{
pxr::VtValue ret;
auto it = data.find(key);
@ -125,20 +134,20 @@ pxr::VtValue WorldData::get_data(pxr::TfToken const &key)
return ret;
}
void WorldData::insert_prim()
void WorldData::insert()
{
scene_delegate->GetRenderIndex().InsertSprim(
pxr::HdPrimTypeTokens->domeLight, scene_delegate, p_id);
CLOG_INFO(LOG_BSD, 2, "Add: id=%s", p_id.GetText());
}
void WorldData::remove_prim()
void WorldData::remove()
{
scene_delegate->GetRenderIndex().RemoveSprim(pxr::HdPrimTypeTokens->domeLight, p_id);
CLOG_INFO(LOG_BSD, 2, "Remove");
}
void WorldData::mark_prim_dirty(DirtyBits dirty_bits)
void WorldData::update(DirtyBits dirty_bits)
{
pxr::HdDirtyBits bits = pxr::HdLight::Clean;
switch (dirty_bits) {

View File

@ -20,19 +20,22 @@ namespace blender::render::hydra {
class WorldData : public IdData {
public:
static std::unique_ptr<WorldData> init(BlenderSceneDelegate *scene_delegate,
static std::unique_ptr<WorldData> create(BlenderSceneDelegate *scene_delegate,
World *world,
bContext *context);
static pxr::SdfPath prim_id(BlenderSceneDelegate *scene_delegate);
WorldData(BlenderSceneDelegate *scene_delegate, World *world, bContext *context);
pxr::SdfPath prim_id() const override;
void init() override;
void insert() override;
void remove() override;
void update(DirtyBits dirty_bits) override;
pxr::GfMatrix4d transform();
pxr::VtValue get_data(pxr::TfToken const &key) override;
void insert_prim() override;
void remove_prim() override;
void mark_prim_dirty(DirtyBits dirty_bits) override;
pxr::VtValue get_data(pxr::TfToken const &key) const override;
private:
std::map<pxr::TfToken, pxr::VtValue> data;