forked from blender/blender
Make object visibility and instancing creation to be calculated via depsgraph #57
@ -56,8 +56,9 @@ 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(LOG_RENDER_HYDRA_SCENE, \
|
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, \
|
||||||
level, \
|
level, \
|
||||||
"%s: " msg, \
|
"%s (%s): " msg, \
|
||||||
prim_id.GetText(), \
|
prim_id.GetText(), \
|
||||||
|
id ? id->name : "", \
|
||||||
##__VA_ARGS__);
|
##__VA_ARGS__);
|
||||||
|
|
||||||
} // namespace blender::render::hydra
|
} // namespace blender::render::hydra
|
||||||
|
@ -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) {
|
switch (object->type) {
|
||||||
case OB_MESH:
|
case OB_MESH:
|
||||||
@ -34,29 +34,6 @@ bool InstancerData::is_supported(Object *object)
|
|||||||
return false;
|
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()
|
void InstancerData::init()
|
||||||
{
|
{
|
||||||
ID_LOG(1, "");
|
ID_LOG(1, "");
|
||||||
@ -179,99 +156,6 @@ pxr::SdfPathVector InstancerData::prototypes() const
|
|||||||
return paths;
|
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
|
void InstancerData::available_materials(Set<pxr::SdfPath> &paths) const
|
||||||
{
|
{
|
||||||
for (auto &m_inst : mesh_instances_.values()) {
|
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)
|
void InstancerData::update_double_sided(MaterialData *mat_data)
|
||||||
{
|
{
|
||||||
for (auto &m_inst : mesh_instances_.values()) {
|
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
|
pxr::SdfPath InstancerData::object_prim_id(Object *object) const
|
||||||
{
|
{
|
||||||
/* Making id of object in form like <prefix>_<pointer in 16 hex digits format> */
|
/* 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;
|
DupliObject *dupli = d.dupli_object_current;
|
||||||
Object *ob = dupli->ob;
|
Object *ob = dupli->ob;
|
||||||
if (!is_supported(ob)) {
|
if (!is_instance_supported(ob)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!ObjectData::is_visible(scene_delegate_, d.dupli_parent)) {
|
if (!ObjectData::is_visible(scene_delegate_, d.dupli_parent)) {
|
||||||
|
@ -26,8 +26,7 @@ class InstancerData : public ObjectData {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
InstancerData(BlenderSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id);
|
InstancerData(BlenderSceneDelegate *scene_delegate, pxr::SdfPath const &prim_id);
|
||||||
static bool is_supported(Object *object);
|
static bool is_instance_supported(Object *object);
|
||||||
static bool is_visible(BlenderSceneDelegate *scene_delegate, Object *object);
|
|
||||||
|
|
||||||
void init() override;
|
void init() override;
|
||||||
void insert() override;
|
void insert() override;
|
||||||
@ -42,14 +41,10 @@ class InstancerData : public ObjectData {
|
|||||||
pxr::VtIntArray indices(pxr::SdfPath const &id) const;
|
pxr::VtIntArray indices(pxr::SdfPath const &id) const;
|
||||||
ObjectData *object_data(pxr::SdfPath const &id) const;
|
ObjectData *object_data(pxr::SdfPath const &id) const;
|
||||||
pxr::SdfPathVector prototypes() 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 available_materials(Set<pxr::SdfPath> &paths) const;
|
||||||
void update_as_parent();
|
|
||||||
void update_double_sided(MaterialData *mat_data);
|
void update_double_sided(MaterialData *mat_data);
|
||||||
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool is_instance_visible(Object *object);
|
|
||||||
pxr::SdfPath object_prim_id(Object *object) const;
|
pxr::SdfPath object_prim_id(Object *object) const;
|
||||||
pxr::SdfPath light_prim_id(LightInstance const &inst, int index) const;
|
pxr::SdfPath light_prim_id(LightInstance const &inst, int index) const;
|
||||||
int light_prim_id_index(pxr::SdfPath const &id) const;
|
int light_prim_id_index(pxr::SdfPath const &id) const;
|
||||||
@ -63,6 +58,4 @@ class InstancerData : public ObjectData {
|
|||||||
pxr::VtMatrix4dArray mesh_transforms_;
|
pxr::VtMatrix4dArray mesh_transforms_;
|
||||||
};
|
};
|
||||||
|
|
||||||
using InstancerDataMap = Map<pxr::SdfPath, std::unique_ptr<InstancerData>>;
|
|
||||||
|
|
||||||
} // namespace blender::render::hydra
|
} // namespace blender::render::hydra
|
||||||
|
Loading…
Reference in New Issue
Block a user
Please add comment why this is done in this way