Support multimaterials on one mesh #44

Merged
Bogdan Nagirniak merged 11 commits from BLEN-417 into hydra-render 2023-05-24 07:07:39 +02:00
2 changed files with 49 additions and 37 deletions
Showing only changes of commit e191c99b74 - Show all commits

View File

@ -36,7 +36,7 @@ bool InstancerData::is_supported(Object *object)
void InstancerData::init() void InstancerData::init()
{ {
ID_LOG(2, ""); ID_LOG(2, "");
set_instances(); write_instances();
} }
void InstancerData::insert() void InstancerData::insert()
@ -68,7 +68,7 @@ void InstancerData::update()
(object->data && ((ID *)object->data)->recalc & ID_RECALC_GEOMETRY) || (object->data && ((ID *)object->data)->recalc & ID_RECALC_GEOMETRY) ||
id->recalc & ID_RECALC_TRANSFORM) id->recalc & ID_RECALC_TRANSFORM)
{ {
set_instances(); write_instances();
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
prim_id, pxr::HdChangeTracker::AllDirty); prim_id, pxr::HdChangeTracker::AllDirty);
} }
@ -109,9 +109,9 @@ bool InstancerData::update_visibility()
pxr::GfMatrix4d InstancerData::get_transform(pxr::SdfPath const &id) const pxr::GfMatrix4d InstancerData::get_transform(pxr::SdfPath const &id) const
{ {
auto l_it = light_instances_.find(id.GetParentPath()); LightInstance *l_inst = light_instance(id);
if (l_it != light_instances_.end()) { if (l_inst) {
return l_it->second.transforms[light_prim_id_index(id)]; return l_inst->transforms[light_prim_id_index(id)];
} }
/* Mesh instance transform must be identity */ /* Mesh instance transform must be identity */
@ -131,18 +131,18 @@ pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors(
pxr::VtIntArray InstancerData::indices(pxr::SdfPath const &id) const pxr::VtIntArray InstancerData::indices(pxr::SdfPath const &id) const
{ {
return mesh_instances_.find(id.GetParentPath())->second.indices; return mesh_instance(id)->indices;
} }
ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const
{ {
auto m_it = mesh_instances_.find(id.GetParentPath()); MeshInstance *m_inst = mesh_instance(id);
if (m_it != mesh_instances_.end()) { if (m_inst) {
return m_it->second.data.get(); return m_inst->data.get();
} }
auto l_it = light_instances_.find(id.GetParentPath()); LightInstance *l_inst = light_instance(id);
if (l_it != light_instances_.end()) { if (l_inst) {
return l_it->second.data.get(); return l_inst->data.get();
} }
return nullptr; return nullptr;
} }
@ -161,25 +161,25 @@ pxr::SdfPathVector InstancerData::prototypes() const
void InstancerData::check_update(Object *object) void InstancerData::check_update(Object *object)
{ {
pxr::SdfPath path = object_prim_id(object); pxr::SdfPath path = object_prim_id(object);
auto m_it = mesh_instances_.find(path); MeshInstance *m_inst = mesh_instance(path);
if (m_it != mesh_instances_.end()) { if (m_inst) {
m_it->second.data->update(); m_inst->data->update();
if (m_it->second.data->id->recalc & ID_RECALC_TRANSFORM) { if (m_inst->data->id->recalc & ID_RECALC_TRANSFORM) {
set_instances(); write_instances();
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
prim_id, pxr::HdChangeTracker::AllDirty); prim_id, pxr::HdChangeTracker::AllDirty);
} }
return; return;
} }
auto l_it = light_instances_.find(path); LightInstance *l_inst = light_instance(path);
if (l_it != light_instances_.end()) { if (l_inst) {
Object *obj = (Object *)l_it->second.data->id; Object *obj = (Object *)l_inst->data->id;
if (obj->id.recalc & (ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY) || if (obj->id.recalc & (ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY) ||
((ID *)obj->data)->recalc & ID_RECALC_GEOMETRY) ((ID *)obj->data)->recalc & ID_RECALC_GEOMETRY)
{ {
set_instances(); write_instances();
} }
return; return;
} }
@ -198,7 +198,7 @@ void InstancerData::check_remove(std::set<std::string> &available_objects)
ret = true; ret = true;
} }
if (ret) { if (ret) {
set_instances(); write_instances();
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
prim_id, pxr::HdChangeTracker::AllDirty); prim_id, pxr::HdChangeTracker::AllDirty);
} }
@ -224,7 +224,7 @@ void InstancerData::available_materials(std::set<pxr::SdfPath> &paths) const
void InstancerData::update_as_parent() void InstancerData::update_as_parent()
{ {
set_instances(); write_instances();
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
prim_id, pxr::HdChangeTracker::AllDirty); prim_id, pxr::HdChangeTracker::AllDirty);
} }
@ -258,7 +258,7 @@ int InstancerData::light_prim_id_index(pxr::SdfPath const &id) const
return index; return index;
} }
void InstancerData::set_instances() void InstancerData::write_instances()
{ {
mesh_transforms_.clear(); mesh_transforms_.clear();
for (auto &it : mesh_instances_) { for (auto &it : mesh_instances_) {
@ -278,31 +278,23 @@ void InstancerData::set_instances()
pxr::SdfPath p_id = object_prim_id(ob); pxr::SdfPath p_id = object_prim_id(ob);
if (ob->type == OB_LAMP) { if (ob->type == OB_LAMP) {
LightInstance *inst; LightInstance *inst = light_instance(p_id);
auto it = light_instances_.find(p_id); if (!inst) {
if (it == light_instances_.end()) {
inst = &light_instances_[p_id]; inst = &light_instances_[p_id];
inst->data = std::make_unique<LightData>(scene_delegate_, ob, p_id); inst->data = std::make_unique<LightData>(scene_delegate_, ob, p_id);
inst->data->init(); inst->data->init();
} }
else {
inst = &it->second;
}
ID_LOG(2, "Light %s %d", inst->data->id->name, inst->transforms.size()); ID_LOG(2, "Light %s %d", inst->data->id->name, inst->transforms.size());
inst->transforms.push_back(gf_matrix_from_transform(dupli->mat)); inst->transforms.push_back(gf_matrix_from_transform(dupli->mat));
} }
else { else {
MeshInstance *inst; MeshInstance *inst = mesh_instance(p_id);
auto it = mesh_instances_.find(p_id); if (!inst) {
if (it == mesh_instances_.end()) {
inst = &mesh_instances_[p_id]; inst = &mesh_instances_[p_id];
inst->data = std::make_unique<MeshData>(scene_delegate_, ob, p_id); inst->data = std::make_unique<MeshData>(scene_delegate_, ob, p_id);
inst->data->init(); inst->data->init();
inst->data->insert(); inst->data->insert();
} }
else {
inst = &it->second;
}
ID_LOG(2, "Mesh %s %d", inst->data->id->name, mesh_transforms_.size()); ID_LOG(2, "Mesh %s %d", inst->data->id->name, mesh_transforms_.size());
inst->indices.push_back(mesh_transforms_.size()); inst->indices.push_back(mesh_transforms_.size());
mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat)); mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat));
@ -385,4 +377,22 @@ void InstancerData::update_light_instance(LightInstance &inst)
} }
} }
InstancerData::MeshInstance *InstancerData::mesh_instance(pxr::SdfPath const &id) const
{
auto it = mesh_instances_.find(id.GetPathElementCount() == 4 ? id.GetParentPath() : id);
if (it == mesh_instances_.end()) {
return nullptr;
}
return const_cast<MeshInstance *>(&it->second);
}
InstancerData::LightInstance *InstancerData::light_instance(pxr::SdfPath const &id) const
{
auto it = light_instances_.find(id.GetPathElementCount() == 4 ? id.GetParentPath() : id);
if (it == light_instances_.end()) {
return nullptr;
}
return const_cast<LightInstance *>(&it->second);
}
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

@ -49,8 +49,10 @@ class InstancerData : public ObjectData {
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;
void set_instances(); void write_instances();
void update_light_instance(LightInstance &inst); void update_light_instance(LightInstance &inst);
MeshInstance *mesh_instance(pxr::SdfPath const &id) const;
LightInstance *light_instance(pxr::SdfPath const &id) const;
pxr::TfHashMap<pxr::SdfPath, MeshInstance, pxr::SdfPath::Hash> mesh_instances_; pxr::TfHashMap<pxr::SdfPath, MeshInstance, pxr::SdfPath::Hash> mesh_instances_;
pxr::TfHashMap<pxr::SdfPath, LightInstance, pxr::SdfPath::Hash> light_instances_; pxr::TfHashMap<pxr::SdfPath, LightInstance, pxr::SdfPath::Hash> light_instances_;