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); pxr::SdfPath id = MaterialData::prim_id(this, material);
MaterialData *mat_data = material_data(id); MaterialData *mat_data = material_data(id);
if (!mat_data) { if (!mat_data) {
materials[id] = MaterialData::init(this, material); materials[id] = MaterialData::create(this, material);
mat_data = material_data(id); mat_data = material_data(id);
mat_data->export_mtlx(); mat_data->export_mtlx();
mat_data->insert_prim(); mat_data->insert();
} }
mesh_data.material_id = id; 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)); MaterialData *mat_data = material_data(MaterialData::prim_id(this, material));
if (mat_data) { if (mat_data) {
mat_data->export_mtlx(); 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; World *world = scene->world;
if (!world_data) { if (!world_data) {
if (world) { if (world) {
world_data = WorldData::init(this, world, context); world_data = WorldData::create(this, world, context);
world_data->insert_prim(); world_data->insert();
} }
} }
else { else {
if (world) { if (world) {
world_data = WorldData::init(this, world, context); world_data = WorldData::create(this, world, context);
world_data->mark_prim_dirty(IdData::DirtyBits::ALL_DIRTY); world_data->update(IdData::DirtyBits::ALL_DIRTY);
} }
else { else {
world_data->remove_prim(); world_data->remove();
world_data = nullptr; world_data = nullptr;
} }
} }
@ -136,7 +136,7 @@ void BlenderSceneDelegate::update_collection(bool remove, bool visibility)
/* Check and update visibility */ /* Check and update visibility */
for (auto &obj : objects) { for (auto &obj : objects) {
if (obj.second->update_visibility(view3d)) { 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()) { if (available_objects.find(it->first) != available_objects.end()) {
continue; continue;
} }
it->second->remove_prim(); it->second->remove();
objects.erase(it); objects.erase(it);
it = objects.begin(); it = objects.begin();
} }
@ -203,7 +203,7 @@ void BlenderSceneDelegate::update_collection(bool remove, bool visibility)
if (available_materials.find(it->first) != available_materials.end()) { if (available_materials.find(it->first) != available_materials.end()) {
continue; continue;
} }
it->second->remove_prim(); it->second->remove();
materials.erase(it); materials.erase(it);
it = materials.begin(); it = materials.begin();
} }
@ -218,10 +218,10 @@ void BlenderSceneDelegate::add_update_object(Object *object,
pxr::SdfPath id = ObjectData::prim_id(this, object); pxr::SdfPath id = ObjectData::prim_id(this, object);
ObjectData *obj_data = object_data(id); ObjectData *obj_data = object_data(id);
if (!obj_data) { if (!obj_data) {
objects[id] = ObjectData::init(this, object); objects[id] = ObjectData::create(this, object);
obj_data = object_data(id); obj_data = object_data(id);
obj_data->update_visibility(view3d); obj_data->update_visibility(view3d);
obj_data->insert_prim(); obj_data->insert();
MeshData *m_data = dynamic_cast<MeshData *>(obj_data); MeshData *m_data = dynamic_cast<MeshData *>(obj_data);
if (m_data) { if (m_data) {
set_material(*m_data); set_material(*m_data);
@ -230,23 +230,23 @@ void BlenderSceneDelegate::add_update_object(Object *object,
} }
if (geometry) { if (geometry) {
objects[id] = ObjectData::init(this, object); objects[id] = ObjectData::create(this, object);
obj_data = object_data(id); obj_data = object_data(id);
obj_data->update_visibility(view3d); obj_data->update_visibility(view3d);
MeshData *m_data = dynamic_cast<MeshData *>(obj_data); MeshData *m_data = dynamic_cast<MeshData *>(obj_data);
if (m_data) { if (m_data) {
set_material(*m_data); set_material(*m_data);
} }
obj_data->mark_prim_dirty(IdData::DirtyBits::ALL_DIRTY); obj_data->update(IdData::DirtyBits::ALL_DIRTY);
return; return;
} }
if (transform) { if (transform) {
obj_data->mark_prim_dirty(IdData::DirtyBits::DIRTY_TRANSFORM); obj_data->update(IdData::DirtyBits::DIRTY_TRANSFORM);
} }
if (shading) { 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 */ extern struct CLG_LogRef *LOG_BSD; /* BSD - Blender Scene Delegate */
class BlenderSceneDelegate : public pxr::HdSceneDelegate { class BlenderSceneDelegate : public pxr::HdSceneDelegate {
friend MeshData;
public: public:
enum class EngineType { VIEWPORT = 1, FINAL, PREVIEW }; enum class EngineType { VIEWPORT = 1, FINAL, PREVIEW };

View File

@ -11,16 +11,24 @@ namespace blender::render::hydra {
IdData::IdData(BlenderSceneDelegate *scene_delegate, ID *id) IdData::IdData(BlenderSceneDelegate *scene_delegate, ID *id)
: scene_delegate(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]; char str[MAX_ID_FULL_NAME];
BKE_id_full_name_get(str, id, 0); BKE_id_full_name_get(str, id, 0);
return str; return str;
} }
pxr::VtValue IdData::get_data(pxr::TfToken const &key) pxr::VtValue IdData::get_data(pxr::TfToken const &key) const
{ {
return pxr::VtValue(); return pxr::VtValue();
} }

View File

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

View File

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

View File

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

View File

@ -20,7 +20,7 @@
namespace blender::render::hydra { namespace blender::render::hydra {
std::unique_ptr<MaterialData> MaterialData::init(BlenderSceneDelegate *scene_delegate, std::unique_ptr<MaterialData> MaterialData::create(BlenderSceneDelegate *scene_delegate,
Material *material) Material *material)
{ {
return std::make_unique<MaterialData>(scene_delegate, 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); 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; pxr::VtValue ret;
if (key.GetString() == "MaterialXFilename") { 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()); 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( scene_delegate->GetRenderIndex().InsertSprim(
pxr::HdPrimTypeTokens->material, scene_delegate, p_id); pxr::HdPrimTypeTokens->material, scene_delegate, p_id);
CLOG_INFO(LOG_BSD, 2, "Add: %s id=%s", name().c_str(), p_id.GetString().c_str()); 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); scene_delegate->GetRenderIndex().RemoveSprim(pxr::HdPrimTypeTokens->material, p_id);
CLOG_INFO(LOG_BSD, 2, "Remove: %s", name().c_str()); 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; pxr::HdDirtyBits bits = pxr::HdMaterial::Clean;
switch (dirty_bits) { switch (dirty_bits) {

View File

@ -15,16 +15,18 @@ namespace blender::render::hydra {
class MaterialData : IdData { class MaterialData : IdData {
public: public:
static std::unique_ptr<MaterialData> init(BlenderSceneDelegate *scene_delegate, static std::unique_ptr<MaterialData> create(BlenderSceneDelegate *scene_delegate,
Material *material); Material *material);
static pxr::SdfPath prim_id(BlenderSceneDelegate *scene_delegate, Material *material); static pxr::SdfPath prim_id(BlenderSceneDelegate *scene_delegate, Material *material);
MaterialData(BlenderSceneDelegate *scene_delegate, Material *material); MaterialData(BlenderSceneDelegate *scene_delegate, Material *material);
pxr::VtValue get_data(pxr::TfToken const &key) override; pxr::SdfPath prim_id() const override;
void insert_prim() override; void init() override;
void remove_prim() override; void insert() override;
void mark_prim_dirty(DirtyBits dirty_bits) override; void remove() override;
void update(DirtyBits dirty_bits) override;
pxr::VtValue get_data(pxr::TfToken const &key) const override;
pxr::VtValue material_resource(); pxr::VtValue material_resource();
void export_mtlx(); 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; pxr::VtValue ret;
if (key == pxr::HdTokens->points) { 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()) { if (face_vertex_counts.empty()) {
return; 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()); 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)) { if (!scene_delegate->GetRenderIndex().HasRprim(p_id)) {
return; return;
@ -220,17 +224,17 @@ void MeshData::remove_prim()
CLOG_INFO(LOG_BSD, 2, "Remove: %s", name().c_str()); 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)) { if (!scene_delegate->GetRenderIndex().HasRprim(p_id)) {
/* Trying to insert prim */ /* Trying to insert prim */
insert_prim(); insert();
return; return;
} }
if (face_vertex_counts.empty()) { if (face_vertex_counts.empty()) {
/* Remove prim without faces */ /* Remove prim without faces */
remove_prim(); remove();
return; return;
} }

View File

@ -16,11 +16,12 @@ class MeshData : public ObjectData {
public: public:
MeshData(BlenderSceneDelegate *scene_delegate, Object *object); 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; pxr::VtValue get_data(pxr::TfToken const &key) const override;
void remove_prim() override;
void mark_prim_dirty(DirtyBits dirty_bits) override;
Material *material(); Material *material();
pxr::HdMeshTopology mesh_topology(); pxr::HdMeshTopology mesh_topology();

View File

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

View File

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

View File

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

View File

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