Fix review comments #27

Merged
Bogdan Nagirniak merged 14 commits from BLEN-392 into hydra-render 2023-04-21 15:02:44 +02:00
17 changed files with 361 additions and 363 deletions
Showing only changes of commit 27fda5fdbd - Show all commits

View File

@ -39,6 +39,8 @@ class Engine {
RenderEngine *bl_engine_; RenderEngine *bl_engine_;
/* The order is important due to deletion order */ /* The order is important due to deletion order */
pxr::HgiUniquePtr hgi_;
pxr::HdDriver hgi_driver_;
pxr::HdPluginRenderDelegateUniqueHandle render_delegate_; pxr::HdPluginRenderDelegateUniqueHandle render_delegate_;
std::unique_ptr<pxr::HdRenderIndex> render_index_; std::unique_ptr<pxr::HdRenderIndex> render_index_;
std::unique_ptr<BlenderSceneDelegate> scene_delegate_; std::unique_ptr<BlenderSceneDelegate> scene_delegate_;
@ -46,9 +48,6 @@ class Engine {
std::unique_ptr<pxr::HdxFreeCameraSceneDelegate> free_camera_delegate_; std::unique_ptr<pxr::HdxFreeCameraSceneDelegate> free_camera_delegate_;
std::unique_ptr<SimpleLightTaskDelegate> simple_light_task_delegate_; std::unique_ptr<SimpleLightTaskDelegate> simple_light_task_delegate_;
std::unique_ptr<pxr::HdEngine> engine_; std::unique_ptr<pxr::HdEngine> engine_;
pxr::HgiUniquePtr hgi_;
pxr::HdDriver hgi_driver_;
}; };
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

@ -32,11 +32,11 @@ pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id)
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText()); CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
ObjectData *obj_data = object_data(id); ObjectData *obj_data = object_data(id);
if (obj_data) { if (obj_data) {
return obj_data->transform(); return obj_data->transform;
} }
if (id == WorldData::prim_id(this)) { if (id == world_prim_id()) {
return world_data_->transform(); return world_data_->transform;
} }
return pxr::GfMatrix4d(); return pxr::GfMatrix4d();
@ -71,7 +71,7 @@ pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id,
if (l_data) { if (l_data) {
return l_data->get_data(key); return l_data->get_data(key);
} }
if (id == WorldData::prim_id(this)) { if (id == world_prim_id()) {
return world_data_->get_data(key); return world_data_->get_data(key);
} }
return pxr::VtValue(); return pxr::VtValue();
@ -111,7 +111,7 @@ pxr::VtValue BlenderSceneDelegate::GetMaterialResource(pxr::SdfPath const &id)
bool BlenderSceneDelegate::GetVisible(pxr::SdfPath const &id) bool BlenderSceneDelegate::GetVisible(pxr::SdfPath const &id)
{ {
if (id == WorldData::prim_id(this)) { if (id == world_prim_id()) {
return true; return true;
} }
@ -123,7 +123,7 @@ pxr::SdfPath BlenderSceneDelegate::GetInstancerId(pxr::SdfPath const &prim_id)
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", prim_id.GetText()); CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", prim_id.GetText());
InstancerData *i_data = instancer_data(prim_id.GetParentPath()); InstancerData *i_data = instancer_data(prim_id.GetParentPath());
if (i_data) { if (i_data) {
return i_data->p_id_; return i_data->prim_id;
} }
return pxr::SdfPath(); return pxr::SdfPath();
} }
@ -147,17 +147,17 @@ pxr::GfMatrix4d BlenderSceneDelegate::GetInstancerTransform(pxr::SdfPath const &
{ {
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", instancer_id.GetText()); CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", instancer_id.GetText());
InstancerData *i_data = instancer_data(instancer_id); InstancerData *i_data = instancer_data(instancer_id);
return i_data->transform(); return i_data->transform;
} }
void BlenderSceneDelegate::populate(Depsgraph *deps, bContext *cont) void BlenderSceneDelegate::populate(Depsgraph *deps, bContext *cont)
{ {
bool is_populated = depsgraph_ != nullptr; bool is_populated = depsgraph != nullptr;
depsgraph_ = deps; depsgraph = deps;
context_ = cont; context = cont;
scene_ = DEG_get_input_scene(depsgraph_); scene = DEG_get_input_scene(depsgraph);
view3d_ = CTX_wm_view3d(context_); view3d = CTX_wm_view3d(context);
if (is_populated) { if (is_populated) {
check_updates(); check_updates();
@ -187,7 +187,35 @@ void BlenderSceneDelegate::clear()
materials_.clear(); materials_.clear();
} }
ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id) pxr::SdfPath BlenderSceneDelegate::prim_id(ID *id, const char *prefix) const
{
/* Making id of object in form like <prefix>_<pointer in 16 hex digits format> */
char str[32];
snprintf(str, 32, "%s_%016llx", prefix, (uint64_t)id);
return GetDelegateID().AppendElementString(str);
}
pxr::SdfPath BlenderSceneDelegate::object_prim_id(Object *object) const
{
return prim_id((ID *)object, "O");
}
pxr::SdfPath BlenderSceneDelegate::material_prim_id(Material *mat) const
{
return prim_id((ID *)mat, "M");
}
pxr::SdfPath BlenderSceneDelegate::instancer_prim_id(Object *object) const
{
return prim_id((ID *)object, "I");
}
pxr::SdfPath BlenderSceneDelegate::world_prim_id() const
{
return GetDelegateID().AppendElementString("World");
}
ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id) const
{ {
auto it = objects_.find(id); auto it = objects_.find(id);
if (it != objects_.end()) { if (it != objects_.end()) {
@ -200,17 +228,17 @@ ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id)
return nullptr; return nullptr;
} }
MeshData *BlenderSceneDelegate::mesh_data(pxr::SdfPath const &id) MeshData *BlenderSceneDelegate::mesh_data(pxr::SdfPath const &id) const
{ {
return dynamic_cast<MeshData *>(object_data(id)); return dynamic_cast<MeshData *>(object_data(id));
} }
LightData *BlenderSceneDelegate::light_data(pxr::SdfPath const &id) LightData *BlenderSceneDelegate::light_data(pxr::SdfPath const &id) const
{ {
return dynamic_cast<LightData *>(object_data(id)); return dynamic_cast<LightData *>(object_data(id));
} }
MaterialData *BlenderSceneDelegate::material_data(pxr::SdfPath const &id) MaterialData *BlenderSceneDelegate::material_data(pxr::SdfPath const &id) const
{ {
auto it = materials_.find(id); auto it = materials_.find(id);
if (it == materials_.end()) { if (it == materials_.end()) {
@ -219,7 +247,7 @@ MaterialData *BlenderSceneDelegate::material_data(pxr::SdfPath const &id)
return it->second.get(); return it->second.get();
} }
InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id) InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id) const
{ {
auto it = instancers_.find(id); auto it = instancers_.find(id);
if (it != instancers_.end()) { if (it != instancers_.end()) {
@ -233,18 +261,18 @@ void BlenderSceneDelegate::update_objects(Object *object)
if (!ObjectData::is_supported(object)) { if (!ObjectData::is_supported(object)) {
return; return;
} }
pxr::SdfPath id = ObjectData::prim_id(this, object); pxr::SdfPath id = object_prim_id(object);
ObjectData *obj_data = object_data(id); ObjectData *obj_data = object_data(id);
if (obj_data) { if (obj_data) {
obj_data->update(); obj_data->update();
return; return;
} }
if (view3d_ && !BKE_object_is_visible_in_viewport(view3d_, object)) { if (view3d && !BKE_object_is_visible_in_viewport(view3d, object)) {
return; return;
} }
objects_[id] = ObjectData::create(this, object); objects_[id] = ObjectData::create(this, object, id);
obj_data = object_data(id); obj_data = object_data(id);
obj_data->update_visibility(view3d_); obj_data->update_visibility();
} }
void BlenderSceneDelegate::update_instancers(Object *object) void BlenderSceneDelegate::update_instancers(Object *object)
@ -254,7 +282,7 @@ void BlenderSceneDelegate::update_instancers(Object *object)
it.second->check_update(object); it.second->check_update(object);
} }
pxr::SdfPath id = InstancerData::prim_id(this, object); pxr::SdfPath id = instancer_prim_id(object);
InstancerData *i_data = instancer_data(id); InstancerData *i_data = instancer_data(id);
if (i_data) { if (i_data) {
if (object->transflag & OB_DUPLI) { if (object->transflag & OB_DUPLI) {
@ -269,20 +297,20 @@ void BlenderSceneDelegate::update_instancers(Object *object)
if ((object->transflag & OB_DUPLI) == 0) { if ((object->transflag & OB_DUPLI) == 0) {
return; return;
} }
if (view3d_ && !BKE_object_is_visible_in_viewport(view3d_, object)) { if (view3d && !BKE_object_is_visible_in_viewport(view3d, object)) {
return; return;
} }
instancers_[id] = InstancerData::create(this, object); instancers_[id] = InstancerData::create(this, object, id);
i_data = instancer_data(id); i_data = instancer_data(id);
i_data->update_visibility(view3d_); i_data->update_visibility();
} }
void BlenderSceneDelegate::update_world() 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::create(this, world, context_); world_data_ = WorldData::create(this, world, world_prim_id());
} }
} }
else { else {
@ -298,18 +326,17 @@ void BlenderSceneDelegate::update_world()
void BlenderSceneDelegate::check_updates() void BlenderSceneDelegate::check_updates()
{ {
/* Working with updates */
bool do_update_collection = false; bool do_update_collection = false;
bool do_update_visibility = false; bool do_update_visibility = false;
bool do_update_world = false; bool do_update_world = false;
unsigned int scene_recalc = scene_->id.recalc; unsigned int scene_recalc = scene->id.recalc;
if (scene_recalc) { if (scene_recalc) {
BogdanNagirniak marked this conversation as resolved Outdated

This block need to remove. It was moved below in earlier commit

This block need to remove. It was moved below in earlier commit
/* Checking scene updates */ /* Checking scene updates */
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, CLOG_INFO(LOG_RENDER_HYDRA_SCENE,
2, 2,
"Update: %s [%s]", "Update: %s [%s]",
((ID *)scene_)->name, ((ID *)scene)->name,
std::bitset<32>(scene_recalc).to_string().c_str()); std::bitset<32>(scene_recalc).to_string().c_str());
if (scene_recalc & ID_RECALC_BASE_FLAGS) { if (scene_recalc & ID_RECALC_BASE_FLAGS) {
@ -319,7 +346,7 @@ void BlenderSceneDelegate::check_updates()
do_update_collection = true; do_update_collection = true;
} }
if (scene_recalc & ID_RECALC_AUDIO_VOLUME) { if (scene_recalc & ID_RECALC_AUDIO_VOLUME) {
if ((scene_->world && !world_data_) || (!scene_->world && world_data_)) { if ((scene->world && !world_data_) || (!scene->world && world_data_)) {
do_update_world = true; do_update_world = true;
} }
} }
@ -327,16 +354,13 @@ void BlenderSceneDelegate::check_updates()
/* Checking other objects updates */ /* Checking other objects updates */
DEGIDIterData data = {0}; DEGIDIterData data = {0};
data.graph = depsgraph_; data.graph = depsgraph;
data.only_updated = true; data.only_updated = true;
ITER_BEGIN ( ITER_BEGIN (
DEG_iterator_ids_begin, DEG_iterator_ids_next, DEG_iterator_ids_end, &data, ID *, id) { DEG_iterator_ids_begin, DEG_iterator_ids_next, DEG_iterator_ids_end, &data, ID *, id) {
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, CLOG_INFO(
2, LOG_RENDER_HYDRA_SCENE, 2, "Update: %s [%s]", id->name, std::bitset<32>(id->recalc).to_string().c_str());
"Update: %s [%s]",
id->name,
std::bitset<32>(id->recalc).to_string().c_str());
switch (GS(id->name)) { switch (GS(id->name)) {
case ID_OB: { case ID_OB: {
@ -346,7 +370,7 @@ void BlenderSceneDelegate::check_updates()
} break; } break;
case ID_MA: { case ID_MA: {
MaterialData *mat_data = material_data(MaterialData::prim_id(this, (Material *)id)); MaterialData *mat_data = material_data(material_prim_id((Material *)id));
if (mat_data) { if (mat_data) {
mat_data->update(); mat_data->update();
} }
@ -358,6 +382,20 @@ void BlenderSceneDelegate::check_updates()
} }
} break; } break;
case ID_SCE: {
if (id->recalc & ID_RECALC_BASE_FLAGS) {
do_update_visibility = true;
}
if (id->recalc & (ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY)) {
do_update_collection = true;
}
if (id->recalc & ID_RECALC_AUDIO_VOLUME) {
if ((scene->world && !world_data_) || (!scene->world && world_data_)) {
do_update_world = true;
}
}
} break;
default: default:
break; break;
} }
@ -378,7 +416,7 @@ void BlenderSceneDelegate::check_updates()
void BlenderSceneDelegate::add_new_objects() void BlenderSceneDelegate::add_new_objects()
{ {
DEGObjectIterSettings settings = {0}; DEGObjectIterSettings settings = {0};
settings.depsgraph = depsgraph_; settings.depsgraph = depsgraph;
settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE | settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE |
DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET; DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET;
DEGObjectIterData data = {0}; DEGObjectIterData data = {0};
@ -408,7 +446,7 @@ void BlenderSceneDelegate::remove_unused_objects()
std::set<std::string> available_objects; std::set<std::string> available_objects;
DEGObjectIterSettings settings = {0}; DEGObjectIterSettings settings = {0};
settings.depsgraph = depsgraph_; settings.depsgraph = depsgraph;
settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET; settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET;
DEGObjectIterData data = {0}; DEGObjectIterData data = {0};
data.settings = &settings; data.settings = &settings;
@ -423,8 +461,8 @@ void BlenderSceneDelegate::remove_unused_objects()
if (!ObjectData::is_supported(object)) { if (!ObjectData::is_supported(object)) {
continue; continue;
} }
available_objects.insert(ObjectData::prim_id(this, object).GetName()); available_objects.insert(object_prim_id(object).GetName());
available_objects.insert(InstancerData::prim_id(this, object).GetName()); available_objects.insert(instancer_prim_id(object).GetName());
} }
ITER_END; ITER_END;
@ -478,15 +516,15 @@ void BlenderSceneDelegate::remove_unused_objects()
void BlenderSceneDelegate::update_visibility() void BlenderSceneDelegate::update_visibility()
{ {
for (auto &it : objects_) { for (auto &it : objects_) {
it.second->update_visibility(view3d_); it.second->update_visibility();
} }
for (auto &it : instancers_) { for (auto &it : instancers_) {
it.second->update_visibility(view3d_); it.second->update_visibility();
} }
/* Add objects which were invisible before and not added yet */ /* Add objects which were invisible before and not added yet */
DEGObjectIterSettings settings = {0}; DEGObjectIterSettings settings = {0};
settings.depsgraph = depsgraph_; settings.depsgraph = depsgraph;
settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE | settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE |
DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET; DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET;
DEGObjectIterData data = {0}; DEGObjectIterData data = {0};
@ -504,10 +542,10 @@ void BlenderSceneDelegate::update_visibility()
continue; continue;
} }
if (!object_data(ObjectData::prim_id(this, object))) { if (!object_data(object_prim_id(object))) {
update_objects(object); update_objects(object);
} }
if (!instancer_data(InstancerData::prim_id(this, object))) { if (!instancer_data(instancer_prim_id(object))) {
update_instancers(object); update_instancers(object);
} }
} }

View File

@ -21,8 +21,7 @@ namespace blender::render::hydra {
extern struct CLG_LogRef *LOG_RENDER_HYDRA_SCENE; /* BSD - Blender Scene Delegate */ extern struct CLG_LogRef *LOG_RENDER_HYDRA_SCENE; /* BSD - Blender Scene Delegate */
class BlenderSceneDelegate : public pxr::HdSceneDelegate { class BlenderSceneDelegate : public pxr::HdSceneDelegate {
friend MeshData; friend MeshData; /* has access to materials_*/
friend InstancerData;
public: public:
enum class EngineType { VIEWPORT = 1, FINAL, PREVIEW }; enum class EngineType { VIEWPORT = 1, FINAL, PREVIEW };
@ -52,13 +51,23 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
void clear(); void clear();
EngineType engine_type; EngineType engine_type;
Depsgraph *depsgraph = nullptr;
bContext *context = nullptr;
View3D *view3d = nullptr;
Scene *scene = nullptr;
private: private:
ObjectData *object_data(pxr::SdfPath const &id); pxr::SdfPath prim_id(ID *id, const char *prefix) const;
MeshData *mesh_data(pxr::SdfPath const &id); pxr::SdfPath object_prim_id(Object *object) const;
LightData *light_data(pxr::SdfPath const &id); pxr::SdfPath material_prim_id(Material *mat) const;
MaterialData *material_data(pxr::SdfPath const &id); pxr::SdfPath instancer_prim_id(Object *object) const;
InstancerData *instancer_data(pxr::SdfPath const &id); pxr::SdfPath world_prim_id() const;
ObjectData *object_data(pxr::SdfPath const &id) const;
MeshData *mesh_data(pxr::SdfPath const &id) const;
LightData *light_data(pxr::SdfPath const &id) const;
MaterialData *material_data(pxr::SdfPath const &id) const;
InstancerData *instancer_data(pxr::SdfPath const &id) const;
void update_objects(Object *object); void update_objects(Object *object);
void update_instancers(Object *object); void update_instancers(Object *object);
@ -68,11 +77,6 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
void remove_unused_objects(); void remove_unused_objects();
void update_visibility(); void update_visibility();
Depsgraph *depsgraph_ = nullptr;
bContext *context_ = nullptr;
View3D *view3d_ = nullptr;
Scene *scene_ = nullptr;
ObjectDataMap objects_; ObjectDataMap objects_;
MaterialDataMap materials_; MaterialDataMap materials_;
InstancerDataMap instancers_; InstancerDataMap instancers_;

View File

@ -3,13 +3,12 @@
#include "BKE_lib_id.h" #include "BKE_lib_id.h"
#include "blender_scene_delegate.h"
#include "id.h" #include "id.h"
namespace blender::render::hydra { namespace blender::render::hydra {
IdData::IdData(BlenderSceneDelegate *scene_delegate, ID *id) IdData::IdData(BlenderSceneDelegate *scene_delegate, ID *id, pxr::SdfPath const &prim_id)
: scene_delegate_(scene_delegate), id_(id) : id(id), prim_id(prim_id), scene_delegate_(scene_delegate)
{ {
} }

View File

@ -12,13 +12,10 @@
namespace blender::render::hydra { namespace blender::render::hydra {
class BlenderSceneDelegate; class BlenderSceneDelegate;
class InstancerData;
class IdData { class IdData {
friend InstancerData;
public: public:
IdData(BlenderSceneDelegate *scene_delegate, ID *id); IdData(BlenderSceneDelegate *scene_delegate, ID *id, pxr::SdfPath const &prim_id);
virtual ~IdData() = default; virtual ~IdData() = default;
virtual void init() = 0; virtual void init() = 0;
@ -29,10 +26,11 @@ class IdData {
virtual pxr::VtValue get_data(pxr::TfToken const &key) const; virtual pxr::VtValue get_data(pxr::TfToken const &key) const;
template<class T> const T get_data(pxr::TfToken const &key) const; template<class T> const T get_data(pxr::TfToken const &key) const;
ID *id;
pxr::SdfPath prim_id;
protected: protected:
BlenderSceneDelegate *scene_delegate_; BlenderSceneDelegate *scene_delegate_;
ID *id_;
pxr::SdfPath p_id_;
}; };
template<class T> const T IdData::get_data(pxr::TfToken const &key) const template<class T> const T IdData::get_data(pxr::TfToken const &key) const
@ -42,6 +40,6 @@ template<class T> const T IdData::get_data(pxr::TfToken const &key) const
#define ID_LOG(level, msg, ...) \ #define ID_LOG(level, msg, ...) \
CLOG_INFO( \ CLOG_INFO( \
LOG_RENDER_HYDRA_SCENE, level, "%s (%s): " msg, p_id_.GetText(), id_->name, __VA_ARGS__); LOG_RENDER_HYDRA_SCENE, level, "%s (%s): " msg, prim_id.GetText(), id->name, __VA_ARGS__);
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

@ -9,11 +9,21 @@
namespace blender::render::hydra { namespace blender::render::hydra {
InstancerData::InstancerData(BlenderSceneDelegate *scene_delegate, Object *object) InstancerData::InstancerData(BlenderSceneDelegate *scene_delegate,
: ObjectData(scene_delegate, object) Object *object,
pxr::SdfPath const &prim_id)
: ObjectData(scene_delegate, object, prim_id)
{ {
p_id_ = prim_id(scene_delegate, object); }
ID_LOG(2, "");
std::unique_ptr<InstancerData> InstancerData::create(BlenderSceneDelegate *scene_delegate,
Object *object,
pxr::SdfPath const &prim_id)
{
auto data = std::make_unique<InstancerData>(scene_delegate, object, prim_id);
data->init();
data->insert();
return data;
} }
bool InstancerData::is_supported(Object *object) bool InstancerData::is_supported(Object *object)
@ -32,24 +42,6 @@ bool InstancerData::is_supported(Object *object)
return false; return false;
} }
std::unique_ptr<InstancerData> InstancerData::create(BlenderSceneDelegate *scene_delegate,
Object *object)
{
auto data = std::make_unique<InstancerData>(scene_delegate, object);
data->init();
data->insert();
return data;
}
pxr::SdfPath InstancerData::prim_id(BlenderSceneDelegate *scene_delegate, Object *object)
{
/* Making id of instancer in form like I_<pointer in 16 hex digits format>. Example:
* I_000002073e369608 */
char str[32];
snprintf(str, 32, "I_%016llx", (uint64_t)object);
return scene_delegate->GetDelegateID().AppendElementString(str);
}
void InstancerData::init() void InstancerData::init()
{ {
ID_LOG(2, ""); ID_LOG(2, "");
@ -59,7 +51,7 @@ void InstancerData::init()
void InstancerData::insert() void InstancerData::insert()
{ {
ID_LOG(2, ""); ID_LOG(2, "");
scene_delegate_->GetRenderIndex().InsertInstancer(scene_delegate_, p_id_); scene_delegate_->GetRenderIndex().InsertInstancer(scene_delegate_, prim_id);
for (auto &it : instances_) { for (auto &it : instances_) {
it.second.obj_data->insert(); it.second.obj_data->insert();
} }
@ -67,11 +59,11 @@ void InstancerData::insert()
void InstancerData::remove() void InstancerData::remove()
{ {
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", p_id_.GetText()); CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText());
for (auto &it : instances_) { for (auto &it : instances_) {
it.second.obj_data->remove(); it.second.obj_data->remove();
} }
scene_delegate_->GetRenderIndex().RemoveInstancer(p_id_); scene_delegate_->GetRenderIndex().RemoveInstancer(prim_id);
} }
void InstancerData::update() void InstancerData::update()
@ -80,17 +72,17 @@ void InstancerData::update()
pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean;
Object *object = (Object *)id_; Object *object = (Object *)id;
if ((id_->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) { if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) {
set_instances(); set_instances();
bits |= pxr::HdChangeTracker::AllDirty; bits |= pxr::HdChangeTracker::AllDirty;
} }
else if (id_->recalc & ID_RECALC_TRANSFORM) { else if (id->recalc & ID_RECALC_TRANSFORM) {
set_instances(); set_instances();
bits |= pxr::HdChangeTracker::DirtyTransform; bits |= pxr::HdChangeTracker::DirtyTransform;
} }
if (bits != pxr::HdChangeTracker::Clean) { if (bits != pxr::HdChangeTracker::Clean) {
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(p_id_, bits); scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(prim_id, bits);
} }
} }
@ -104,32 +96,23 @@ pxr::VtValue InstancerData::get_data(pxr::TfToken const &key) const
return ret; return ret;
} }
pxr::GfMatrix4d InstancerData::transform() bool InstancerData::update_visibility()
{ {
return pxr::GfMatrix4d(1.0); bool ret = ObjectData::update_visibility();
}
bool InstancerData::update_visibility(View3D *view3d)
{
if (!view3d) {
return false;
}
bool ret = ObjectData::update_visibility(view3d);
if (ret) { if (ret) {
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
p_id_, pxr::HdChangeTracker::DirtyVisibility); prim_id, pxr::HdChangeTracker::DirtyVisibility);
for (auto &it : instances_) { for (auto &it : instances_) {
it.second.obj_data->visible = visible; it.second.obj_data->visible = visible;
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty( scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(
it.second.obj_data->p_id_, pxr::HdChangeTracker::DirtyVisibility); it.second.obj_data->prim_id, pxr::HdChangeTracker::DirtyVisibility);
} }
} }
return ret; return ret;
} }
pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors( pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors(
pxr::HdInterpolation interpolation) pxr::HdInterpolation interpolation) const
{ {
pxr::HdPrimvarDescriptorVector primvars; pxr::HdPrimvarDescriptorVector primvars;
if (interpolation == pxr::HdInterpolationInstance) { if (interpolation == pxr::HdInterpolationInstance) {
@ -139,17 +122,17 @@ pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors(
return primvars; return primvars;
} }
pxr::VtIntArray InstancerData::indices(pxr::SdfPath const &id) pxr::VtIntArray InstancerData::indices(pxr::SdfPath const &id) const
{ {
return instances_[id].indices; return instances_.find(id)->second.indices;
} }
ObjectData *InstancerData::object_data(pxr::SdfPath const &id) ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const
{ {
return instances_[id].obj_data.get(); return instances_.find(id)->second.obj_data.get();
} }
pxr::SdfPathVector InstancerData::prototypes() pxr::SdfPathVector InstancerData::prototypes() const
{ {
pxr::SdfPathVector paths; pxr::SdfPathVector paths;
for (auto &it : instances_) { for (auto &it : instances_) {
@ -160,8 +143,7 @@ pxr::SdfPathVector InstancerData::prototypes()
void InstancerData::check_update(Object *object) void InstancerData::check_update(Object *object)
{ {
pxr::SdfPath path = ObjectData::prim_id(scene_delegate_, object); pxr::SdfPath path = object_prim_id(object);
path = p_id_.AppendElementString(path.GetName());
auto it = instances_.find(path); auto it = instances_.find(path);
if (it == instances_.end()) { if (it == instances_.end()) {
return; return;
@ -175,7 +157,7 @@ void InstancerData::check_update(Object *object)
bits |= pxr::HdChangeTracker::DirtyTransform; bits |= pxr::HdChangeTracker::DirtyTransform;
} }
if (bits != pxr::HdChangeTracker::Clean) { if (bits != pxr::HdChangeTracker::Clean) {
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(p_id_, bits); scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(prim_id, bits);
} }
} }
@ -194,11 +176,11 @@ void InstancerData::check_remove(std::set<std::string> &available_objects)
if (ret) { if (ret) {
set_instances(); set_instances();
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
p_id_, pxr::HdChangeTracker::AllDirty); prim_id, pxr::HdChangeTracker::AllDirty);
} }
} }
void InstancerData::available_materials(std::set<pxr::SdfPath> &paths) void InstancerData::available_materials(std::set<pxr::SdfPath> &paths) const
{ {
for (auto &it : instances_) { for (auto &it : instances_) {
pxr::SdfPath mat_id = ((MeshData *)it.second.obj_data.get())->material_id(); pxr::SdfPath mat_id = ((MeshData *)it.second.obj_data.get())->material_id();
@ -208,6 +190,14 @@ void InstancerData::available_materials(std::set<pxr::SdfPath> &paths)
} }
} }
pxr::SdfPath InstancerData::object_prim_id(Object *object) const
{
/* Making id of object in form like <prefix>_<pointer in 16 hex digits format> */
char str[32];
snprintf(str, 32, "O_%016llx", (uint64_t)object);
return prim_id.AppendElementString(str);
}
void InstancerData::set_instances() void InstancerData::set_instances()
{ {
transforms_.clear(); transforms_.clear();
@ -216,29 +206,29 @@ void InstancerData::set_instances()
} }
int index = 0; int index = 0;
Instance *inst; Instance *inst;
pxr::SdfPath path; pxr::SdfPath p_id;
ListBase *lb = object_duplilist( ListBase *lb = object_duplilist(
scene_delegate_->depsgraph_, scene_delegate_->scene_, (Object *)id_); scene_delegate_->depsgraph, scene_delegate_->scene, (Object *)id);
LISTBASE_FOREACH (DupliObject *, dupli, lb) { LISTBASE_FOREACH (DupliObject *, dupli, lb) {
path = ObjectData::prim_id(scene_delegate_, dupli->ob); p_id = object_prim_id(dupli->ob);
path = p_id_.AppendElementString(path.GetName()); auto it = instances_.find(p_id);
auto it = instances_.find(path);
if (it == instances_.end()) { if (it == instances_.end()) {
inst = &instances_[path]; inst = &instances_[p_id];
if (!is_supported(dupli->ob)) { if (!is_supported(dupli->ob)) {
continue; continue;
} }
inst->obj_data = std::make_unique<InstanceMeshData>(scene_delegate_, dupli->ob, path); inst->obj_data = ObjectData::create(scene_delegate_, dupli->ob, p_id);
inst->obj_data->init();
inst->obj_data->insert(); /* Instance's transform should be identity */
inst->obj_data->transform = pxr::GfMatrix4d(1.0);
} }
else { else {
inst = &it->second; inst = &it->second;
} }
transforms_.push_back(gf_matrix_from_transform(dupli->mat)); transforms_.push_back(gf_matrix_from_transform(dupli->mat));
inst->indices.push_back(index); inst->indices.push_back(index);
ID_LOG(2, "Instance %s %d", inst->obj_data->id_->name, index); ID_LOG(2, "%s %d", inst->obj_data->id->name, index);
++index; ++index;
} }
free_object_duplilist(lb); free_object_duplilist(lb);
@ -254,17 +244,4 @@ void InstancerData::set_instances()
} }
} }
InstanceMeshData::InstanceMeshData(BlenderSceneDelegate *scene_delegate,
Object *object,
pxr::SdfPath const &p_id)
: MeshData(scene_delegate, object)
{
this->p_id_ = p_id;
}
pxr::GfMatrix4d InstanceMeshData::transform()
{
return pxr::GfMatrix4d(1.0);
}
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

@ -10,20 +10,18 @@
namespace blender::render::hydra { namespace blender::render::hydra {
class InstancerData : public ObjectData { class InstancerData : public ObjectData {
friend BlenderSceneDelegate;
struct Instance { struct Instance {
std::unique_ptr<ObjectData> obj_data; std::unique_ptr<ObjectData> obj_data;
pxr::VtIntArray indices; pxr::VtIntArray indices;
}; };
public: public:
InstancerData(BlenderSceneDelegate *scene_delegate, Object *object); InstancerData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
static bool is_supported(Object *object);
static std::unique_ptr<InstancerData> create(BlenderSceneDelegate *scene_delegate, static std::unique_ptr<InstancerData> create(BlenderSceneDelegate *scene_delegate,
Object *object); Object *object,
static pxr::SdfPath prim_id(BlenderSceneDelegate *scene_delegate, Object *object); pxr::SdfPath const &prim_id);
static bool is_supported(Object *object);
void init() override; void init() override;
void insert() override; void insert() override;
@ -31,18 +29,18 @@ class InstancerData : public ObjectData {
void update() override; void update() override;
pxr::VtValue get_data(pxr::TfToken const &key) const override; pxr::VtValue get_data(pxr::TfToken const &key) const override;
pxr::GfMatrix4d transform() override; bool update_visibility() override;
bool update_visibility(View3D *view3d) override;
pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation); pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const;
pxr::VtIntArray indices(pxr::SdfPath const &id); pxr::VtIntArray indices(pxr::SdfPath const &id) const;
ObjectData *object_data(pxr::SdfPath const &id); ObjectData *object_data(pxr::SdfPath const &id) const;
pxr::SdfPathVector prototypes(); pxr::SdfPathVector prototypes() const;
void check_update(Object *object); void check_update(Object *object);
void check_remove(std::set<std::string> &available_objects); void check_remove(std::set<std::string> &available_objects);
void available_materials(std::set<pxr::SdfPath> &paths); void available_materials(std::set<pxr::SdfPath> &paths) const;
private: private:
pxr::SdfPath object_prim_id(Object *object) const;
void set_instances(); void set_instances();
pxr::TfHashMap<pxr::SdfPath, Instance, pxr::SdfPath::Hash> instances_; pxr::TfHashMap<pxr::SdfPath, Instance, pxr::SdfPath::Hash> instances_;
@ -52,10 +50,4 @@ class InstancerData : public ObjectData {
using InstancerDataMap = using InstancerDataMap =
pxr::TfHashMap<pxr::SdfPath, std::unique_ptr<InstancerData>, pxr::SdfPath::Hash>; pxr::TfHashMap<pxr::SdfPath, std::unique_ptr<InstancerData>, pxr::SdfPath::Hash>;
class InstanceMeshData : public MeshData {
public:
InstanceMeshData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &p_id);
pxr::GfMatrix4d transform() override;
};
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

@ -14,17 +14,18 @@
namespace blender::render::hydra { namespace blender::render::hydra {
LightData::LightData(BlenderSceneDelegate *scene_delegate, Object *object) LightData::LightData(BlenderSceneDelegate *scene_delegate,
: ObjectData(scene_delegate, object) Object *object,
pxr::SdfPath const &prim_id)
: ObjectData(scene_delegate, object, prim_id)
{ {
ID_LOG(2, "");
} }
void LightData::init() void LightData::init()
{ {
ID_LOG(2, ""); ID_LOG(2, "");
Light *light = (Light *)((Object *)id_)->data; Light *light = (Light *)((Object *)id)->data;
data_.clear(); data_.clear();
float intensity = light->energy; float intensity = light->energy;
@ -79,30 +80,32 @@ void LightData::init()
break; break;
} }
p_type_ = prim_type(light); prim_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;
set_transform_to_object();
} }
void LightData::insert() void LightData::insert()
{ {
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", id_->name); ID_LOG(2, "");
scene_delegate_->GetRenderIndex().InsertSprim(p_type_, scene_delegate_, p_id_); scene_delegate_->GetRenderIndex().InsertSprim(prim_type_, scene_delegate_, prim_id);
} }
void LightData::remove() void LightData::remove()
{ {
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", id_->name); CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText());
scene_delegate_->GetRenderIndex().RemoveSprim(p_type_, p_id_); scene_delegate_->GetRenderIndex().RemoveSprim(prim_type_, prim_id);
} }
void LightData::update() void LightData::update()
{ {
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", id_->name); ID_LOG(2, "");
Light *light = (Light *)((Object *)id_)->data; Light *light = (Light *)((Object *)id)->data;
if (prim_type(light) != p_type_) { if (prim_type(light) != prim_type_) {
remove(); remove();
init(); init();
insert(); insert();
@ -110,14 +113,15 @@ void LightData::update()
} }
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();
bits = pxr::HdLight::AllDirty; bits = pxr::HdLight::AllDirty;
} }
else if (id_->recalc & ID_RECALC_TRANSFORM) { else if (id->recalc & ID_RECALC_TRANSFORM) {
set_transform_to_object();
bits = pxr::HdLight::DirtyTransform; bits = pxr::HdLight::DirtyTransform;
} }
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(p_id_, bits); scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id, bits);
} }
pxr::VtValue LightData::get_data(pxr::TfToken const &key) const pxr::VtValue LightData::get_data(pxr::TfToken const &key) const
@ -141,11 +145,11 @@ pxr::VtValue LightData::get_data(pxr::TfToken const &key) const
return ret; return ret;
} }
bool LightData::update_visibility(View3D *view3d) bool LightData::update_visibility()
{ {
bool ret = ObjectData::update_visibility(view3d); bool ret = ObjectData::update_visibility();
if (ret) { if (ret) {
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(p_id_, scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id,
pxr::HdLight::DirtyParams); pxr::HdLight::DirtyParams);
} }
return ret; return ret;

View File

@ -15,7 +15,7 @@ namespace blender::render::hydra {
class LightData : public ObjectData { class LightData : public ObjectData {
public: public:
LightData(BlenderSceneDelegate *scene_delegate, Object *object); LightData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
void init() override; void init() override;
void insert() override; void insert() override;
@ -23,13 +23,13 @@ class LightData : public ObjectData {
void update() override; void update() override;
pxr::VtValue get_data(pxr::TfToken const &key) const override; pxr::VtValue get_data(pxr::TfToken const &key) const override;
bool update_visibility(View3D *view3d) override; bool update_visibility() override;
private: private:
pxr::TfToken prim_type(Light *light); pxr::TfToken prim_type(Light *light);
std::map<pxr::TfToken, pxr::VtValue> data_; std::map<pxr::TfToken, pxr::VtValue> data_;
pxr::TfToken p_type_; pxr::TfToken prim_type_;
}; };
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

@ -20,31 +20,23 @@
namespace blender::render::hydra { namespace blender::render::hydra {
MaterialData::MaterialData(BlenderSceneDelegate *scene_delegate, Material *material) MaterialData::MaterialData(BlenderSceneDelegate *scene_delegate,
: IdData(scene_delegate, (ID *)material) Material *material,
pxr::SdfPath const &prim_id)
: IdData(scene_delegate, (ID *)material, prim_id)
{ {
p_id_ = prim_id(scene_delegate, material);
ID_LOG(2, "");
} }
std::unique_ptr<MaterialData> MaterialData::create(BlenderSceneDelegate *scene_delegate, std::unique_ptr<MaterialData> MaterialData::create(BlenderSceneDelegate *scene_delegate,
Material *material) Material *material,
pxr::SdfPath const &prim_id)
{ {
auto data = std::make_unique<MaterialData>(scene_delegate, material); auto data = std::make_unique<MaterialData>(scene_delegate, material, prim_id);
data->init(); data->init();
data->insert(); data->insert();
return data; return data;
} }
pxr::SdfPath MaterialData::prim_id(BlenderSceneDelegate *scene_delegate, Material *material)
{
/* Making id of material in form like M_<pointer in 16 hex digits format>.
* Example: M_000002074e812088 */
char str[32];
snprintf(str, 32, "M_%016llx", (uint64_t)material);
return scene_delegate->GetDelegateID().AppendElementString(str);
}
void MaterialData::init() void MaterialData::init()
{ {
ID_LOG(2, ""); ID_LOG(2, "");
@ -62,7 +54,7 @@ void MaterialData::init()
func = PyDict_GetItemString(dict, "export_mtlx"); func = PyDict_GetItemString(dict, "export_mtlx");
PointerRNA materialptr; PointerRNA materialptr;
RNA_pointer_create(NULL, &RNA_Material, id_, &materialptr); RNA_pointer_create(NULL, &RNA_Material, id, &materialptr);
PyObject *material = pyrna_struct_CreatePyObject(&materialptr); PyObject *material = pyrna_struct_CreatePyObject(&materialptr);
result = PyObject_CallFunction(func, "O", material); result = PyObject_CallFunction(func, "O", material);
@ -76,7 +68,7 @@ void MaterialData::init()
Py_DECREF(result); Py_DECREF(result);
} }
else { else {
CLOG_ERROR(LOG_RENDER_HYDRA_SCENE, "Export error for %s", id_->name); CLOG_ERROR(LOG_RENDER_HYDRA_SCENE, "Export error for %s", id->name);
PyErr_Print(); PyErr_Print();
} }
Py_DECREF(module); Py_DECREF(module);
@ -85,26 +77,41 @@ void MaterialData::init()
mtlx_path_ = pxr::SdfAssetPath(path, path); mtlx_path_ = pxr::SdfAssetPath(path, path);
ID_LOG(2, "mtlx=%s", mtlx_path_.GetResolvedPath().c_str()); ID_LOG(2, "mtlx=%s", mtlx_path_.GetResolvedPath().c_str());
/* Calculate material network map */
if (!path.empty()) {
pxr::HdRenderDelegate *render_delegate = scene_delegate_->GetRenderIndex().GetRenderDelegate();
pxr::TfTokenVector shader_source_types = render_delegate->GetShaderSourceTypes();
pxr::TfTokenVector render_contexts = render_delegate->GetMaterialRenderContexts();
pxr::HdMaterialNetworkMap network_map;
hdmtlx_convert_to_materialnetworkmap(path, shader_source_types, render_contexts, &network_map);
material_network_map_ = network_map;
}
else {
material_network_map_ = pxr::VtValue();
}
} }
void MaterialData::insert() void MaterialData::insert()
{ {
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", id_->name); ID_LOG(2, "");
scene_delegate_->GetRenderIndex().InsertSprim( scene_delegate_->GetRenderIndex().InsertSprim(
pxr::HdPrimTypeTokens->material, scene_delegate_, p_id_); pxr::HdPrimTypeTokens->material, scene_delegate_, prim_id);
} }
void MaterialData::remove() void MaterialData::remove()
{ {
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", id_->name); CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText());
scene_delegate_->GetRenderIndex().RemoveSprim(pxr::HdPrimTypeTokens->material, p_id_); scene_delegate_->GetRenderIndex().RemoveSprim(pxr::HdPrimTypeTokens->material, prim_id);
} }
void MaterialData::update() void MaterialData::update()
{ {
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", id_->name); ID_LOG(2, "");
init(); init();
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(p_id_, scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id,
pxr::HdMaterial::AllDirty); pxr::HdMaterial::AllDirty);
} }
@ -120,23 +127,8 @@ pxr::VtValue MaterialData::get_data(pxr::TfToken const &key) const
return ret; return ret;
} }
pxr::VtValue MaterialData::get_material_resource() pxr::VtValue MaterialData::get_material_resource() const
{ {
if (material_network_map_.IsEmpty()) {
const std::string &path = mtlx_path_.GetResolvedPath();
if (!path.empty()) {
pxr::HdRenderDelegate *render_delegate =
scene_delegate_->GetRenderIndex().GetRenderDelegate();
pxr::TfTokenVector shader_source_types = render_delegate->GetShaderSourceTypes();
pxr::TfTokenVector render_contexts = render_delegate->GetMaterialRenderContexts();
pxr::HdMaterialNetworkMap network_map;
hdmtlx_convert_to_materialnetworkmap(
path, shader_source_types, render_contexts, &network_map);
material_network_map_ = network_map;
}
}
return material_network_map_; return material_network_map_;
} }

View File

@ -13,17 +13,15 @@
namespace blender::render::hydra { namespace blender::render::hydra {
class MeshData; class MaterialData : public IdData {
class MaterialData : IdData {
friend MeshData;
public: public:
MaterialData(BlenderSceneDelegate *scene_delegate, Material *material); MaterialData(BlenderSceneDelegate *scene_delegate,
Material *material,
pxr::SdfPath const &prim_id);
static std::unique_ptr<MaterialData> create(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); pxr::SdfPath const &prim_id);
void init() override; void init() override;
void insert() override; void insert() override;
@ -31,7 +29,7 @@ class MaterialData : IdData {
void update() override; void update() override;
pxr::VtValue get_data(pxr::TfToken const &key) const override; pxr::VtValue get_data(pxr::TfToken const &key) const override;
pxr::VtValue get_material_resource(); pxr::VtValue get_material_resource() const;
private: private:
pxr::SdfAssetPath mtlx_path_; pxr::SdfAssetPath mtlx_path_;

View File

@ -15,17 +15,18 @@
namespace blender::render::hydra { namespace blender::render::hydra {
MeshData::MeshData(BlenderSceneDelegate *scene_delegate, Object *object) MeshData::MeshData(BlenderSceneDelegate *scene_delegate,
: ObjectData(scene_delegate, object), mat_data_(nullptr) Object *object,
pxr::SdfPath const &prim_id)
: ObjectData(scene_delegate, object, prim_id)
{ {
ID_LOG(2, "");
} }
void MeshData::init() void MeshData::init()
{ {
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", id_->name); ID_LOG(2, "");
Object *object = (Object *)id_; Object *object = (Object *)id;
if (object->type == OB_MESH && object->mode == OB_MODE_OBJECT && if (object->type == OB_MESH && object->mode == OB_MODE_OBJECT &&
BLI_listbase_is_empty(&object->modifiers)) { BLI_listbase_is_empty(&object->modifiers)) {
write_mesh((Mesh *)object->data); write_mesh((Mesh *)object->data);
@ -39,6 +40,7 @@ void MeshData::init()
} }
write_material(); write_material();
set_transform_to_object();
} }
void MeshData::insert() void MeshData::insert()
@ -47,35 +49,36 @@ void MeshData::insert()
return; return;
} }
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", id_->name); ID_LOG(2, "");
scene_delegate_->GetRenderIndex().InsertRprim( scene_delegate_->GetRenderIndex().InsertRprim(
pxr::HdPrimTypeTokens->mesh, scene_delegate_, p_id_); pxr::HdPrimTypeTokens->mesh, scene_delegate_, prim_id);
} }
void MeshData::remove() void MeshData::remove()
{ {
if (!scene_delegate_->GetRenderIndex().HasRprim(p_id_)) { if (!scene_delegate_->GetRenderIndex().HasRprim(prim_id)) {
return; return;
} }
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", id_->name); CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText());
scene_delegate_->GetRenderIndex().RemoveRprim(p_id_); scene_delegate_->GetRenderIndex().RemoveRprim(prim_id);
} }
void MeshData::update() void MeshData::update()
{ {
pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean;
Object *object = (Object *)id_; Object *object = (Object *)id;
if ((id_->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) { if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) {
init(); init();
bits = pxr::HdChangeTracker::AllDirty; bits = pxr::HdChangeTracker::AllDirty;
} }
else { else {
if (id_->recalc & ID_RECALC_SHADING) { if (id->recalc & ID_RECALC_SHADING) {
write_material(); write_material();
bits |= pxr::HdChangeTracker::DirtyMaterialId; bits |= pxr::HdChangeTracker::DirtyMaterialId;
} }
if (id_->recalc & ID_RECALC_TRANSFORM) { if (id->recalc & ID_RECALC_TRANSFORM) {
set_transform_to_object();
bits |= pxr::HdChangeTracker::DirtyTransform; bits |= pxr::HdChangeTracker::DirtyTransform;
} }
} }
@ -84,7 +87,7 @@ void MeshData::update()
return; return;
} }
if (!scene_delegate_->GetRenderIndex().HasRprim(p_id_)) { if (!scene_delegate_->GetRenderIndex().HasRprim(prim_id)) {
insert(); insert();
return; return;
} }
@ -94,8 +97,8 @@ void MeshData::update()
remove(); remove();
return; return;
} }
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", id_->name); ID_LOG(2, "");
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(p_id_, bits); scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(prim_id, bits);
} }
pxr::VtValue MeshData::get_data(pxr::TfToken const &key) const pxr::VtValue MeshData::get_data(pxr::TfToken const &key) const
@ -116,17 +119,17 @@ pxr::VtValue MeshData::get_data(pxr::TfToken const &key) const
return ret; return ret;
} }
bool MeshData::update_visibility(View3D *view3d) bool MeshData::update_visibility()
{ {
bool ret = ObjectData::update_visibility(view3d); bool ret = ObjectData::update_visibility();
if (ret) { if (ret) {
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty( scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(
p_id_, pxr::HdChangeTracker::DirtyVisibility); prim_id, pxr::HdChangeTracker::DirtyVisibility);
} }
return ret; return ret;
} }
pxr::HdMeshTopology MeshData::mesh_topology() pxr::HdMeshTopology MeshData::mesh_topology() const
{ {
return pxr::HdMeshTopology(pxr::PxOsdOpenSubdivTokens->none, return pxr::HdMeshTopology(pxr::PxOsdOpenSubdivTokens->none,
pxr::HdTokens->rightHanded, pxr::HdTokens->rightHanded,
@ -134,7 +137,8 @@ pxr::HdMeshTopology MeshData::mesh_topology()
face_vertex_indices_); face_vertex_indices_);
} }
pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors(pxr::HdInterpolation interpolation) pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors(
pxr::HdInterpolation interpolation) const
{ {
pxr::HdPrimvarDescriptorVector primvars; pxr::HdPrimvarDescriptorVector primvars;
if (interpolation == pxr::HdInterpolationVertex) { if (interpolation == pxr::HdInterpolationVertex) {
@ -156,12 +160,12 @@ pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors(pxr::HdInterpolatio
return primvars; return primvars;
} }
pxr::SdfPath MeshData::material_id() pxr::SdfPath MeshData::material_id() const
{ {
if (!mat_data_) { if (!mat_data_) {
return pxr::SdfPath(); return pxr::SdfPath();
} }
return mat_data_->p_id_; return mat_data_->prim_id;
} }
void MeshData::write_mesh(Mesh *mesh) void MeshData::write_mesh(Mesh *mesh)
@ -205,7 +209,7 @@ void MeshData::write_mesh(Mesh *mesh)
void MeshData::write_material() void MeshData::write_material()
{ {
Object *object = (Object *)id_; Object *object = (Object *)id;
Material *mat = nullptr; Material *mat = nullptr;
if (BKE_object_material_count_eval(object) > 0) { if (BKE_object_material_count_eval(object) > 0) {
mat = BKE_object_material_get_eval(object, object->actcol); mat = BKE_object_material_get_eval(object, object->actcol);
@ -215,11 +219,11 @@ void MeshData::write_material()
mat_data_ = nullptr; mat_data_ = nullptr;
return; return;
} }
pxr::SdfPath id = MaterialData::prim_id(scene_delegate_, mat); pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat);
mat_data_ = scene_delegate_->material_data(id); mat_data_ = scene_delegate_->material_data(p_id);
if (!mat_data_) { if (!mat_data_) {
scene_delegate_->materials_[id] = MaterialData::create(scene_delegate_, mat); scene_delegate_->materials_[p_id] = MaterialData::create(scene_delegate_, mat, p_id);
mat_data_ = scene_delegate_->material_data(id); mat_data_ = scene_delegate_->material_data(p_id);
} }
} }

View File

@ -15,7 +15,7 @@ namespace blender::render::hydra {
class MeshData : public ObjectData { class MeshData : public ObjectData {
public: public:
MeshData(BlenderSceneDelegate *scene_delegate, Object *object); MeshData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
void init() override; void init() override;
void insert() override; void insert() override;
@ -23,11 +23,11 @@ class MeshData : public ObjectData {
void update() override; void update() override;
pxr::VtValue get_data(pxr::TfToken const &key) const override; pxr::VtValue get_data(pxr::TfToken const &key) const override;
bool update_visibility(View3D *view3d) override; bool update_visibility() override;
pxr::HdMeshTopology mesh_topology(); pxr::HdMeshTopology mesh_topology() const;
pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation); pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const;
pxr::SdfPath material_id(); pxr::SdfPath material_id() const;
protected: protected:
void write_mesh(Mesh *mesh); void write_mesh(Mesh *mesh);
@ -42,7 +42,7 @@ class MeshData : public ObjectData {
pxr::VtVec3fArray normals_; pxr::VtVec3fArray normals_;
pxr::VtMatrix4dArray instances_; pxr::VtMatrix4dArray instances_;
MaterialData *mat_data_; MaterialData *mat_data_ = nullptr;
}; };
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

@ -11,10 +11,40 @@
namespace blender::render::hydra { namespace blender::render::hydra {
ObjectData::ObjectData(BlenderSceneDelegate *scene_delegate, Object *object) ObjectData::ObjectData(BlenderSceneDelegate *scene_delegate,
: IdData(scene_delegate, (ID *)object), visible(true) Object *object,
pxr::SdfPath const &prim_id)
: IdData(scene_delegate, (ID *)object, prim_id), transform(pxr::GfMatrix4d(1.0)), visible(true)
{ {
p_id_ = prim_id(scene_delegate, object); }
std::unique_ptr<ObjectData> ObjectData::create(BlenderSceneDelegate *scene_delegate,
Object *object,
pxr::SdfPath const &prim_id)
{
std::unique_ptr<ObjectData> data;
switch (object->type) {
case OB_MESH:
case OB_SURF:
case OB_FONT:
case OB_CURVES_LEGACY:
case OB_MBALL:
data = std::make_unique<MeshData>(scene_delegate, object, prim_id);
break;
case OB_LAMP:
data = std::make_unique<LightData>(scene_delegate, object, prim_id);
break;
default:
break;
}
if (data) {
data->init();
data->insert();
}
return data;
} }
bool ObjectData::is_supported(Object *object) bool ObjectData::is_supported(Object *object)
@ -34,56 +64,14 @@ bool ObjectData::is_supported(Object *object)
return false; return false;
} }
std::unique_ptr<ObjectData> ObjectData::create(BlenderSceneDelegate *scene_delegate, bool ObjectData::update_visibility()
Object *object)
{ {
std::unique_ptr<ObjectData> data; if (!scene_delegate_->view3d) {
switch (object->type) {
case OB_MESH:
case OB_SURF:
case OB_FONT:
case OB_CURVES_LEGACY:
case OB_MBALL:
data = std::make_unique<MeshData>(scene_delegate, object);
break;
case OB_LAMP:
data = std::make_unique<LightData>(scene_delegate, object);
break;
default:
break;
}
if (data) {
data->init();
data->insert();
}
return data;
}
pxr::SdfPath ObjectData::prim_id(BlenderSceneDelegate *scene_delegate, Object *object)
{
/* Making id of object in form like O_<pointer in 16 hex digits format>. Example:
* O_000002073e369608 */
char str[32];
snprintf(str, 32, "O_%016llx", (uint64_t)object);
return scene_delegate->GetDelegateID().AppendElementString(str);
}
pxr::GfMatrix4d ObjectData::transform()
{
return gf_matrix_from_transform(((Object *)id_)->object_to_world);
}
bool ObjectData::update_visibility(View3D *view3d)
{
if (!view3d) {
return false; return false;
} }
bool prev_visible = visible; bool prev_visible = visible;
visible = BKE_object_is_visible_in_viewport(view3d, (Object *)id_); visible = BKE_object_is_visible_in_viewport(scene_delegate_->view3d, (Object *)id);
bool ret = visible != prev_visible; bool ret = visible != prev_visible;
if (ret) { if (ret) {
ID_LOG(2, ""); ID_LOG(2, "");
@ -91,4 +79,9 @@ bool ObjectData::update_visibility(View3D *view3d)
return ret; return ret;
} }
void ObjectData::set_transform_to_object()
{
transform = gf_matrix_from_transform(((Object *)id)->object_to_world);
}
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

@ -16,16 +16,20 @@ namespace blender::render::hydra {
class ObjectData : public IdData { class ObjectData : public IdData {
public: public:
ObjectData(BlenderSceneDelegate *scene_delegate, Object *object); ObjectData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
static std::unique_ptr<ObjectData> create(BlenderSceneDelegate *scene_delegate,
Object *object,
pxr::SdfPath const &prim_id);
static bool is_supported(Object *object); static bool is_supported(Object *object);
static std::unique_ptr<ObjectData> create(BlenderSceneDelegate *scene_delegate, Object *object);
static pxr::SdfPath prim_id(BlenderSceneDelegate *scene_delegate, Object *object);
virtual pxr::GfMatrix4d transform(); virtual bool update_visibility();
virtual bool update_visibility(View3D *view3d);
pxr::GfMatrix4d transform;
bool visible; bool visible;
protected:
void set_transform_to_object();
}; };
using ObjectDataMap = using ObjectDataMap =

View File

@ -28,33 +28,30 @@
namespace blender::render::hydra { namespace blender::render::hydra {
WorldData::WorldData(BlenderSceneDelegate *scene_delegate, World *world, bContext *context) WorldData::WorldData(BlenderSceneDelegate *scene_delegate,
: IdData(scene_delegate, (ID *)world), context_(context) World *world,
pxr::SdfPath const &prim_id)
: IdData(scene_delegate, (ID *)world, prim_id)
{ {
p_id_ = prim_id(scene_delegate);
ID_LOG(2, "");
} }
std::unique_ptr<WorldData> WorldData::create(BlenderSceneDelegate *scene_delegate, std::unique_ptr<WorldData> WorldData::create(BlenderSceneDelegate *scene_delegate,
World *world, World *world,
bContext *context) pxr::SdfPath const &prim_id)
{ {
auto data = std::make_unique<WorldData>(scene_delegate, world, context); auto data = std::make_unique<WorldData>(scene_delegate, world, prim_id);
data->init(); data->init();
data->insert(); data->insert();
return data; return data;
} }
pxr::SdfPath WorldData::prim_id(BlenderSceneDelegate *scene_delegate)
{
return scene_delegate->GetDelegateID().AppendElementString("World");
}
void WorldData::init() void WorldData::init()
{ {
ID_LOG(2, ""); ID_LOG(2, "");
World *world = (World *)id_; set_transform();
World *world = (World *)id;
data_.clear(); data_.clear();
data_[pxr::UsdLuxTokens->orientToStageUpAxis] = true; data_[pxr::UsdLuxTokens->orientToStageUpAxis] = true;
@ -101,8 +98,8 @@ void WorldData::init()
Image *image = (Image *)color_input_node->id; Image *image = (Image *)color_input_node->id;
if (image) { if (image) {
Main *bmain = CTX_data_main(context_); Main *bmain = CTX_data_main(scene_delegate_->context);
Scene *scene = CTX_data_scene(context_); Scene *scene = scene_delegate_->scene;
ReportList reports; ReportList reports;
ImageSaveOptions opts; ImageSaveOptions opts;
@ -127,44 +124,29 @@ void WorldData::insert()
{ {
ID_LOG(2, ""); ID_LOG(2, "");
scene_delegate_->GetRenderIndex().InsertSprim( scene_delegate_->GetRenderIndex().InsertSprim(
pxr::HdPrimTypeTokens->domeLight, scene_delegate_, p_id_); pxr::HdPrimTypeTokens->domeLight, scene_delegate_, prim_id);
} }
void WorldData::remove() void WorldData::remove()
{ {
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", id_->name); CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText());
scene_delegate_->GetRenderIndex().RemoveSprim(pxr::HdPrimTypeTokens->domeLight, p_id_); scene_delegate_->GetRenderIndex().RemoveSprim(pxr::HdPrimTypeTokens->domeLight, prim_id);
} }
void WorldData::update() void WorldData::update()
{ {
ID_LOG(2, ""); ID_LOG(2, "");
init(); init();
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(p_id_, scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id,
pxr::HdLight::AllDirty); pxr::HdLight::AllDirty);
} }
void WorldData::update(World *world) void WorldData::update(World *world)
{ {
id_ = (ID *)world; id = (ID *)world;
update(); update();
} }
pxr::GfMatrix4d WorldData::transform()
{
pxr::GfMatrix4d transform = pxr::GfMatrix4d(pxr::GfRotation(pxr::GfVec3d(1.0, 0.0, 0.0), -90),
pxr::GfVec3d());
/* TODO : do this check via RenderSettings*/
if (scene_delegate_->GetRenderIndex().GetRenderDelegate()->GetRendererDisplayName() == "RPR") {
transform *= pxr::GfMatrix4d(pxr::GfRotation(pxr::GfVec3d(1.0, 0.0, 0.0), -180),
pxr::GfVec3d());
transform *= pxr::GfMatrix4d(pxr::GfRotation(pxr::GfVec3d(0.0, 0.0, 1.0), 90.0),
pxr::GfVec3d());
}
return transform;
}
pxr::VtValue WorldData::get_data(pxr::TfToken const &key) const pxr::VtValue WorldData::get_data(pxr::TfToken const &key) const
{ {
pxr::VtValue ret; pxr::VtValue ret;
@ -175,4 +157,17 @@ pxr::VtValue WorldData::get_data(pxr::TfToken const &key) const
return ret; return ret;
} }
void WorldData::set_transform()
{
transform = pxr::GfMatrix4d(pxr::GfRotation(pxr::GfVec3d(1.0, 0.0, 0.0), -90), pxr::GfVec3d());
/* TODO : do this check via RenderSettings*/
if (scene_delegate_->GetRenderIndex().GetRenderDelegate()->GetRendererDisplayName() == "RPR") {
transform *= pxr::GfMatrix4d(pxr::GfRotation(pxr::GfVec3d(1.0, 0.0, 0.0), -180),
pxr::GfVec3d());
transform *= pxr::GfMatrix4d(pxr::GfRotation(pxr::GfVec3d(0.0, 0.0, 1.0), 90.0),
pxr::GfVec3d());
}
}
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

@ -20,12 +20,11 @@ namespace blender::render::hydra {
class WorldData : public IdData { class WorldData : public IdData {
public: public:
WorldData(BlenderSceneDelegate *scene_delegate, World *world, bContext *context); WorldData(BlenderSceneDelegate *scene_delegate, World *world, pxr::SdfPath const &prim_id);
static std::unique_ptr<WorldData> create(BlenderSceneDelegate *scene_delegate, static std::unique_ptr<WorldData> create(BlenderSceneDelegate *scene_delegate,
World *world, World *world,
bContext *context); pxr::SdfPath const &prim_id);
static pxr::SdfPath prim_id(BlenderSceneDelegate *scene_delegate);
void init() override; void init() override;
void insert() override; void insert() override;
@ -33,12 +32,14 @@ class WorldData : public IdData {
void update() override; void update() override;
void update(World *world); void update(World *world);
pxr::GfMatrix4d transform();
pxr::VtValue get_data(pxr::TfToken const &key) const override; pxr::VtValue get_data(pxr::TfToken const &key) const override;
pxr::GfMatrix4d transform;
private: private:
void set_transform();
std::map<pxr::TfToken, pxr::VtValue> data_; std::map<pxr::TfToken, pxr::VtValue> data_;
bContext *context_;
}; };
} // namespace blender::render::hydra } // namespace blender::render::hydra