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

View File

@ -49,8 +49,10 @@ class InstancerData : public ObjectData {
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;
void set_instances();
void write_instances();
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, LightInstance, pxr::SdfPath::Hash> light_instances_;