Make object visibility and instancing creation to be calculated via depsgraph #57

Merged
Bogdan Nagirniak merged 16 commits from BLEN-442 into hydra-render 2023-07-08 10:09:53 +02:00
7 changed files with 15 additions and 188 deletions
Showing only changes of commit 58c2e57538 - Show all commits

View File

@ -19,8 +19,6 @@ BlenderSceneDelegate::BlenderSceneDelegate(pxr::HdRenderIndex *parent_index,
Engine *engine) Engine *engine)
: HdSceneDelegate(parent_index, delegate_id), engine(engine) : HdSceneDelegate(parent_index, delegate_id), engine(engine)
{ {
instancer_data_ = std::make_unique<InstancerData>(
this, nullptr, GetDelegateID().AppendElementString("Instancer"));
} }
pxr::HdMeshTopology BlenderSceneDelegate::GetMeshTopology(pxr::SdfPath const &id) pxr::HdMeshTopology BlenderSceneDelegate::GetMeshTopology(pxr::SdfPath const &id)
@ -217,15 +215,11 @@ void BlenderSceneDelegate::clear()
for (auto &obj_data : objects_.values()) { for (auto &obj_data : objects_.values()) {
obj_data->remove(); obj_data->remove();
} }
for (auto &i_data : instancers_.values()) { objects_.clear();
i_data->remove(); instancer_data_->remove();
}
for (auto &mat_data : materials_.values()) { for (auto &mat_data : materials_.values()) {
mat_data->remove(); mat_data->remove();
} }
objects_.clear();
instancers_.clear();
materials_.clear(); materials_.clear();
depsgraph = nullptr; depsgraph = nullptr;
@ -262,9 +256,9 @@ pxr::SdfPath BlenderSceneDelegate::material_prim_id(Material *mat) const
return prim_id((ID *)mat, "M"); return prim_id((ID *)mat, "M");
} }
pxr::SdfPath BlenderSceneDelegate::instancer_prim_id(Object *object) const pxr::SdfPath BlenderSceneDelegate::instancer_prim_id() const
{ {
return prim_id((ID *)object, "I"); return GetDelegateID().AppendElementString("Instancer");
} }
pxr::SdfPath BlenderSceneDelegate::world_prim_id() const pxr::SdfPath BlenderSceneDelegate::world_prim_id() const
@ -331,75 +325,9 @@ InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id, bool
if (instancer_data_ && p_id == instancer_data_->prim_id) { if (instancer_data_ && p_id == instancer_data_->prim_id) {
return instancer_data_.get(); return instancer_data_.get();
} }
//auto i_data = instancers_.lookup_ptr(p_id);
//if (i_data) {
// return i_data->get();
//}
return nullptr; return nullptr;
} }
void BlenderSceneDelegate::update_objects(Object *object)
{
if (!ObjectData::is_supported(object)) {
return;
}
pxr::SdfPath id = object_prim_id(object);
ObjectData *obj_data = object_data(id);
if (obj_data) {
obj_data->update_parent();
obj_data->update();
obj_data->update_visibility();
return;
}
if (!ObjectData::is_visible(this, object)) {
/* Do not export new object if it is invisible */
return;
}
objects_.add_new(id, ObjectData::create(this, object, id));
obj_data = object_data(id);
obj_data->update_parent();
obj_data->init();
obj_data->insert();
}
void BlenderSceneDelegate::update_instancers(Object *object)
{
/* Check object inside instancers */
for (auto &i_data : instancers_.values()) {
i_data->check_update(object);
}
pxr::SdfPath id = instancer_prim_id(object);
InstancerData *i_data = instancer_data(id);
if (i_data) {
if ((object->transflag & OB_DUPLI) == 0) {
/* Object isn't instancer anymore and should be removed */
i_data->remove();
instancers_.remove(id);
return;
}
i_data->update();
return;
}
if ((object->transflag & OB_DUPLI) == 0) {
return;
}
if (!InstancerData::is_visible(this, object)) {
/* Do not export new instancer if it is invisible */
return;
}
i_data = instancers_.lookup_or_add(id, std::make_unique<InstancerData>(this, object, id)).get();
i_data->init();
i_data->insert();
}
void BlenderSceneDelegate::update_world() void BlenderSceneDelegate::update_world()
{ {
World *world = scene->world; World *world = scene->world;
@ -429,8 +357,6 @@ void BlenderSceneDelegate::check_updates()
DEGIDIterData data = {0}; DEGIDIterData data = {0};
data.graph = depsgraph; data.graph = depsgraph;
data.only_updated = true; data.only_updated = true;
eEvaluationMode deg_mode = DEG_get_mode(depsgraph);
ITER_BEGIN (DEG_iterator_ids_begin, DEG_iterator_ids_next, DEG_iterator_ids_end, &data, ID *, id) ITER_BEGIN (DEG_iterator_ids_begin, DEG_iterator_ids_next, DEG_iterator_ids_end, &data, ID *, id)
{ {
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, CLOG_INFO(LOG_RENDER_HYDRA_SCENE,
@ -488,39 +414,6 @@ void BlenderSceneDelegate::check_updates()
} }
} }
void BlenderSceneDelegate::add_new_objects()
{
DEGObjectIterSettings settings = {0};
settings.depsgraph = depsgraph;
settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
DEG_ITER_OBJECT_FLAG_VISIBLE;
DEGObjectIterData data = {0};
data.settings = &settings;
data.graph = settings.depsgraph;
data.flag = settings.flags;
eEvaluationMode deg_mode = DEG_get_mode(depsgraph);
ITER_BEGIN (DEG_iterator_objects_begin,
DEG_iterator_objects_next,
DEG_iterator_objects_end,
&data,
Object *,
object)
{
CLOG_INFO(LOG_RENDER_HYDRA_SCENE,
2,
"Visibility: %s [%s]",
object->id.name,
std::bitset<3>(BKE_object_visibility(object, deg_mode)).to_string().c_str());
update_objects(object);
//update_instancers(object);
}
ITER_END;
instancer_data_->init();
instancer_data_->insert();
}
void BlenderSceneDelegate::update_collection() void BlenderSceneDelegate::update_collection()
{ {
/* Add or update available objects */ /* Add or update available objects */
@ -560,6 +453,12 @@ void BlenderSceneDelegate::update_collection()
} }
ITER_END; ITER_END;
if (!instancer_data_) {
instancer_data_ = std::make_unique<InstancerData>(this, instancer_prim_id());
instancer_data_->init();
instancer_data_->insert();
}
/* Remove unused objects */ /* Remove unused objects */
objects_.remove_if([&](auto item) { objects_.remove_if([&](auto item) {
bool ret = !available_objects.contains(item.key.GetName()); bool ret = !available_objects.contains(item.key.GetName());
@ -592,46 +491,4 @@ void BlenderSceneDelegate::update_collection()
}); });
} }
void BlenderSceneDelegate::update_visibility()
{
/* Updating visibility of existing objects/instancers */
for (auto &val : objects_.values()) {
val->update_visibility();
}
for (auto &val : instancers_.values()) {
val->update_visibility();
}
/* Add objects/instancers which were invisible before and not added yet */
DEGObjectIterSettings settings = {0};
settings.depsgraph = depsgraph;
settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET;
DEGObjectIterData data = {0};
data.settings = &settings;
data.graph = settings.depsgraph;
data.flag = settings.flags;
eEvaluationMode deg_mode = DEG_get_mode(depsgraph);
ITER_BEGIN (DEG_iterator_objects_begin,
DEG_iterator_objects_next,
DEG_iterator_objects_end,
&data,
Object *,
object)
{
CLOG_INFO(LOG_RENDER_HYDRA_SCENE,
2,
"Visibility: %s [%s]",
object->id.name,
std::bitset<3>(BKE_object_visibility(object, deg_mode)).to_string().c_str());
if (!object_data(object_prim_id(object))) {
update_objects(object);
}
if (!instancer_data(instancer_prim_id(object))) {
update_instancers(object);
}
}
ITER_END;
}
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

@ -76,7 +76,7 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
pxr::SdfPath prim_id(ID *id, const char *prefix) const; pxr::SdfPath prim_id(ID *id, const char *prefix) const;
pxr::SdfPath object_prim_id(Object *object) const; pxr::SdfPath object_prim_id(Object *object) const;
pxr::SdfPath material_prim_id(Material *mat) const; pxr::SdfPath material_prim_id(Material *mat) const;
pxr::SdfPath instancer_prim_id(Object *object) const; pxr::SdfPath instancer_prim_id() const;
pxr::SdfPath world_prim_id() const; pxr::SdfPath world_prim_id() const;
ObjectData *object_data(pxr::SdfPath const &id) const; ObjectData *object_data(pxr::SdfPath const &id) const;
@ -86,17 +86,12 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
MaterialData *material_data(pxr::SdfPath const &id) const; MaterialData *material_data(pxr::SdfPath const &id) const;
InstancerData *instancer_data(pxr::SdfPath const &id, bool child_id = false) const; InstancerData *instancer_data(pxr::SdfPath const &id, bool child_id = false) const;
void update_objects(Object *object);
void update_instancers(Object *object);
void update_world(); void update_world();
void check_updates(); void check_updates();
void add_new_objects();
void update_collection(); void update_collection();
void update_visibility();
ObjectDataMap objects_; ObjectDataMap objects_;
MaterialDataMap materials_; MaterialDataMap materials_;
InstancerDataMap instancers_;
std::unique_ptr<InstancerData> instancer_data_; std::unique_ptr<InstancerData> instancer_data_;
std::unique_ptr<WorldData> world_data_; std::unique_ptr<WorldData> world_data_;
}; };

View File

@ -12,10 +12,8 @@
namespace blender::render::hydra { namespace blender::render::hydra {
InstancerData::InstancerData(BlenderSceneDelegate *scene_delegate, InstancerData::InstancerData(BlenderSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id)
Object *object, : ObjectData(scene_delegate, nullptr, prim_id)
pxr::SdfPath const &prim_id)
: ObjectData(scene_delegate, object, prim_id)
{ {
} }

View File

@ -25,7 +25,7 @@ class InstancerData : public ObjectData {
}; };
public: public:
InstancerData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id); InstancerData(BlenderSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id);
static bool is_supported(Object *object); static bool is_supported(Object *object);
static bool is_visible(BlenderSceneDelegate *scene_delegate, Object *object); static bool is_visible(BlenderSceneDelegate *scene_delegate, Object *object);

View File

@ -67,9 +67,7 @@ void MaterialData::update()
m_data->update_double_sided(this); m_data->update_double_sided(this);
} }
} }
for (auto &i_data : scene_delegate_->instancers_.values()) { scene_delegate_->instancer_data_->update_double_sided(this);
i_data->update_double_sided(this);
}
} }
} }

View File

@ -82,24 +82,6 @@ bool ObjectData::update_visibility()
return visible != prev_visible; return visible != prev_visible;
} }
void ObjectData::update_parent()
{
Object *object = (Object *)id;
if (parent_ != object->parent) {
ID_LOG(1, "");
parent_ = object->parent;
/* Looking for corresponded instancer and update it as parent */
for (Object *ob = parent_; ob != nullptr; ob = ob->parent) {
InstancerData *i_data = scene_delegate_->instancer_data(
scene_delegate_->instancer_prim_id(ob));
if (i_data) {
i_data->update_as_parent();
}
}
}
}
void ObjectData::write_transform() void ObjectData::write_transform()
{ {
transform = gf_matrix_from_transform(((Object *)id)->object_to_world); transform = gf_matrix_from_transform(((Object *)id)->object_to_world);

View File

@ -26,15 +26,12 @@ class ObjectData : public IdData {
static bool is_visible(BlenderSceneDelegate *scene_delegate, Object *object); static bool is_visible(BlenderSceneDelegate *scene_delegate, Object *object);
virtual bool update_visibility(); virtual bool update_visibility();
void update_parent();
pxr::GfMatrix4d transform; pxr::GfMatrix4d transform;
bool visible = true; bool visible = true;
protected: protected:
void write_transform(); void write_transform();
Object *parent_ = nullptr;
}; };
using ObjectDataMap = Map<pxr::SdfPath, std::unique_ptr<ObjectData>>; using ObjectDataMap = Map<pxr::SdfPath, std::unique_ptr<ObjectData>>;