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
3 changed files with 5 additions and 150 deletions
Showing only changes of commit 88be7d3cd9 - Show all commits

View File

@ -56,8 +56,9 @@ template<class T> const T IdData::get_data(pxr::TfToken const &key) const
#define ID_LOG(level, msg, ...) \
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, \
level, \
"%s: " msg, \
"%s (%s): " msg, \
prim_id.GetText(), \
id ? id->name : "", \
##__VA_ARGS__);
} // namespace blender::render::hydra

View File

@ -17,7 +17,7 @@ InstancerData::InstancerData(BlenderSceneDelegate *scene_delegate, pxr::SdfPath
{
}
bool InstancerData::is_supported(Object *object)
bool InstancerData::is_instance_supported(Object *object)
{
switch (object->type) {
case OB_MESH:
@ -34,29 +34,6 @@ bool InstancerData::is_supported(Object *object)
return false;
}
bool InstancerData::is_visible(BlenderSceneDelegate *scene_delegate, Object *object)
{
eEvaluationMode deg_mode = DEG_get_mode(scene_delegate->depsgraph);
int vis = BKE_object_visibility(object, deg_mode);
bool ret = vis & OB_VISIBLE_INSTANCES;
if (deg_mode == DAG_EVAL_VIEWPORT) {
ret &= BKE_object_is_visible_in_viewport(scene_delegate->view3d, object);
}
else {
if (ret) {
/* If some of parent object is instancer, then currenct object as instancer
* is invisible in Final render */
for (Object *ob = object->parent; ob != nullptr; ob = ob->parent) {
if (ob->transflag & OB_DUPLI) {
ret = false;
break;
}
}
}
}
return ret;
}
void InstancerData::init()
{
ID_LOG(1, "");
@ -179,99 +156,6 @@ pxr::SdfPathVector InstancerData::prototypes() const
return paths;
}
void InstancerData::check_update(Object *object)
{
pxr::SdfPath path = object_prim_id(object);
MeshInstance *m_inst = mesh_instance(path);
if (m_inst) {
if (!is_instance_visible(object)) {
m_inst->data->remove();
mesh_instances_.remove(path);
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
prim_id, pxr::HdChangeTracker::AllDirty);
return;
}
m_inst->data->update();
if (m_inst->data->id->recalc & ID_RECALC_TRANSFORM) {
write_instances();
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
prim_id, pxr::HdChangeTracker::AllDirty);
}
return;
}
LightInstance *l_inst = light_instance(path);
if (l_inst) {
if (!is_instance_visible(object)) {
l_inst->transforms.clear();
update_light_instance(*l_inst);
light_instances_.remove(path);
return;
}
Object *obj = (Object *)l_inst->data->id;
if (obj->id.recalc & (ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY) ||
((ID *)obj->data)->recalc & ID_RECALC_GEOMETRY)
{
write_instances();
}
return;
}
/* Checking if object wasn't added to instances before */
if (is_supported(object) && is_instance_visible(object)) {
bool do_write_instances = false;
ListBase *lb = object_duplilist(
scene_delegate_->depsgraph, scene_delegate_->scene, (Object *)id);
LISTBASE_FOREACH (DupliObject *, dupli, lb) {
if (dupli->ob == object) {
do_write_instances = true;
break;
}
}
free_object_duplilist(lb);
if (do_write_instances) {
write_instances();
if (!mesh_instances_.is_empty()) {
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
prim_id, pxr::HdChangeTracker::AllDirty);
}
}
}
}
void InstancerData::check_remove(Set<std::string> &available_objects)
{
bool ret = false;
mesh_instances_.remove_if([&](auto item) {
bool res = !available_objects.contains(item.key.GetName());
if (res) {
item.value.data->remove();
ret = true;
};
return res;
});
if (ret) {
write_instances();
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
prim_id, pxr::HdChangeTracker::AllDirty);
}
light_instances_.remove_if([&](auto item) {
bool res = !available_objects.contains(item.key.GetName());
if (res) {
item.value.transforms.clear();
update_light_instance(item.value);
};
return res;
});
}
void InstancerData::available_materials(Set<pxr::SdfPath> &paths) const
{
for (auto &m_inst : mesh_instances_.values()) {
@ -279,13 +163,6 @@ void InstancerData::available_materials(Set<pxr::SdfPath> &paths) const
}
}
void InstancerData::update_as_parent()
{
write_instances();
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
prim_id, pxr::HdChangeTracker::AllDirty);
}
void InstancerData::update_double_sided(MaterialData *mat_data)
{
for (auto &m_inst : mesh_instances_.values()) {
@ -293,22 +170,6 @@ void InstancerData::update_double_sided(MaterialData *mat_data)
}
}
bool InstancerData::is_instance_visible(Object *object)
{
eEvaluationMode deg_mode = DEG_get_mode(scene_delegate_->depsgraph);
int vis = BKE_object_visibility(object, deg_mode);
bool ret = vis & OB_VISIBLE_SELF;
if (deg_mode == DAG_EVAL_VIEWPORT) {
if (!ret && ((object->transflag & OB_DUPLI) == 0 ||
(object->transflag & OB_DUPLI &&
object->duplicator_visibility_flag & OB_DUPLI_FLAG_VIEWPORT)))
{
ret = true;
}
}
return ret;
}
pxr::SdfPath InstancerData::object_prim_id(Object *object) const
{
/* Making id of object in form like <prefix>_<pointer in 16 hex digits format> */
@ -361,7 +222,7 @@ void InstancerData::write_instances()
}
DupliObject *dupli = d.dupli_object_current;
Object *ob = dupli->ob;
if (!is_supported(ob)) {
if (!is_instance_supported(ob)) {
continue;
}
if (!ObjectData::is_visible(scene_delegate_, d.dupli_parent)) {

View File

@ -26,8 +26,7 @@ class InstancerData : public ObjectData {
public:
InstancerData(BlenderSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id);
static bool is_supported(Object *object);
static bool is_visible(BlenderSceneDelegate *scene_delegate, Object *object);
static bool is_instance_supported(Object *object);
void init() override;
void insert() override;
@ -42,14 +41,10 @@ class InstancerData : public ObjectData {
pxr::VtIntArray indices(pxr::SdfPath const &id) const;
ObjectData *object_data(pxr::SdfPath const &id) const;
pxr::SdfPathVector prototypes() const;
void check_update(Object *object);
void check_remove(Set<std::string> &available_objects);
void available_materials(Set<pxr::SdfPath> &paths) const;
void update_as_parent();
void update_double_sided(MaterialData *mat_data);

Please add comment why this is done in this way

Please add comment why this is done in this way
private:
bool is_instance_visible(Object *object);
pxr::SdfPath object_prim_id(Object *object) const;
pxr::SdfPath light_prim_id(LightInstance const &inst, int index) const;
int light_prim_id_index(pxr::SdfPath const &id) const;
@ -63,6 +58,4 @@ class InstancerData : public ObjectData {
pxr::VtMatrix4dArray mesh_transforms_;
};
using InstancerDataMap = Map<pxr::SdfPath, std::unique_ptr<InstancerData>>;
} // namespace blender::render::hydra