BLEN-359: Implement updates for instances in viewport #20

Merged
Bogdan Nagirniak merged 20 commits from BLEN-359_1 into hydra-render 2023-04-05 11:47:37 +02:00
8 changed files with 51 additions and 47 deletions
Showing only changes of commit a26d88dc62 - Show all commits

View File

@ -22,21 +22,6 @@ BlenderSceneDelegate::BlenderSceneDelegate(pxr::HdRenderIndex *parent_index,
{ {
} }
void BlenderSceneDelegate::set_material(MeshData &mesh_data)
{
Material *material = mesh_data.material();
if (!material) {
mesh_data.material_id = pxr::SdfPath::EmptyPath();
return;
}
pxr::SdfPath id = MaterialData::prim_id(this, material);
MaterialData *mat_data = material_data(id);
if (!mat_data) {
materials[id] = MaterialData::create(this, material);
}
mesh_data.material_id = id;
}
void BlenderSceneDelegate::update_material(Material *material) void BlenderSceneDelegate::update_material(Material *material)
{ {
MaterialData *mat_data = material_data(MaterialData::prim_id(this, material)); MaterialData *mat_data = material_data(MaterialData::prim_id(this, material));
@ -189,8 +174,12 @@ void BlenderSceneDelegate::update_collection(bool remove, bool visibility)
std::set<pxr::SdfPath> available_materials; std::set<pxr::SdfPath> available_materials;
for (auto &obj : objects) { for (auto &obj : objects) {
MeshData *m_data = dynamic_cast<MeshData *>(obj.second.get()); MeshData *m_data = dynamic_cast<MeshData *>(obj.second.get());
if (m_data && !m_data->material_id.IsEmpty()) { if (!m_data) {
available_materials.insert(m_data->material_id); continue;
}
pxr::SdfPath mat_id = m_data->material_id();
if (!mat_id.IsEmpty()) {
available_materials.insert(mat_id);
} }
} }
for (auto it = materials.begin(); it != materials.end(); ++it) { for (auto it = materials.begin(); it != materials.end(); ++it) {
@ -393,7 +382,7 @@ pxr::HdPrimvarDescriptorVector BlenderSceneDelegate::GetPrimvarDescriptors(
pxr::SdfPath BlenderSceneDelegate::GetMaterialId(pxr::SdfPath const &rprim_id) pxr::SdfPath BlenderSceneDelegate::GetMaterialId(pxr::SdfPath const &rprim_id)
{ {
return mesh_data(rprim_id)->material_id; return mesh_data(rprim_id)->material_id();
} }
pxr::VtValue BlenderSceneDelegate::GetMaterialResource(pxr::SdfPath const &id) pxr::VtValue BlenderSceneDelegate::GetMaterialResource(pxr::SdfPath const &id)

View File

@ -63,7 +63,6 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
void add_update_object(Object *object, bool geometry, bool transform, bool shading); void add_update_object(Object *object, bool geometry, bool transform, bool shading);
void add_update_instance(DupliObject *dupli); void add_update_instance(DupliObject *dupli);
void set_material(MeshData &mesh_data);
void update_material(Material *material); void update_material(Material *material);
void update_world(); void update_world();
void update_collection(bool remove, bool visibility); void update_collection(bool remove, bool visibility);

View File

@ -13,13 +13,6 @@ IdData::IdData(BlenderSceneDelegate *scene_delegate, ID *id)
{ {
} }
std::string IdData::name() const
{
char str[MAX_ID_FULL_NAME];
BKE_id_full_name_get(str, id, 0);
return str;
}
pxr::VtValue IdData::get_data(pxr::TfToken const &key) const pxr::VtValue IdData::get_data(pxr::TfToken const &key) const
{ {
return pxr::VtValue(); return pxr::VtValue();

View File

@ -26,8 +26,6 @@ class IdData {
virtual pxr::VtValue get_data(pxr::TfToken const &key) const; virtual pxr::VtValue get_data(pxr::TfToken const &key) const;
template<class T> const T get_data(pxr::TfToken const &key) const; template<class T> const T get_data(pxr::TfToken const &key) const;
std::string name() const;
protected: protected:
BlenderSceneDelegate *scene_delegate; BlenderSceneDelegate *scene_delegate;
ID *id; ID *id;

View File

@ -107,7 +107,7 @@ void MaterialData::export_mtlx()
Py_DECREF(result); Py_DECREF(result);
} }
else { else {
CLOG_ERROR(LOG_BSD, "Export error for %s", name().c_str()); CLOG_ERROR(LOG_BSD, "Export error for %s", id->name);
PyErr_Print(); PyErr_Print();
} }
Py_DECREF(module); Py_DECREF(module);
@ -115,7 +115,7 @@ void MaterialData::export_mtlx()
PyGILState_Release(gstate); PyGILState_Release(gstate);
mtlx_path = pxr::SdfAssetPath(path, path); mtlx_path = pxr::SdfAssetPath(path, path);
CLOG_INFO(LOG_BSD, 2, "Export: %s, mtlx=%s", name().c_str(), mtlx_path.GetResolvedPath().c_str()); CLOG_INFO(LOG_BSD, 2, "Export: %s, mtlx=%s", id->name, mtlx_path.GetResolvedPath().c_str());
} }
void MaterialData::insert() void MaterialData::insert()

View File

@ -13,7 +13,11 @@
namespace blender::render::hydra { namespace blender::render::hydra {
class MeshData;
class MaterialData : IdData { class MaterialData : IdData {
friend MeshData;
public: public:
static std::unique_ptr<MaterialData> create(BlenderSceneDelegate *scene_delegate, static std::unique_ptr<MaterialData> create(BlenderSceneDelegate *scene_delegate,
Material *material); Material *material);

View File

@ -16,7 +16,7 @@
namespace blender::render::hydra { namespace blender::render::hydra {
MeshData::MeshData(BlenderSceneDelegate *scene_delegate, Object *object) MeshData::MeshData(BlenderSceneDelegate *scene_delegate, Object *object)
: ObjectData(scene_delegate, object) : ObjectData(scene_delegate, object), mat_data(nullptr)
{ {
CLOG_INFO(LOG_BSD, 2, "%s, id=%s", id->name, p_id.GetText()); CLOG_INFO(LOG_BSD, 2, "%s, id=%s", id->name, p_id.GetText());
} }
@ -49,15 +49,6 @@ bool MeshData::update_visibility(View3D *view3d)
return ret; return ret;
} }
Material *MeshData::material()
{
Object *object = (Object *)id;
if (BKE_object_material_count_eval(object) == 0) {
return nullptr;
}
return BKE_object_material_get_eval(object, object->actcol);
}
pxr::HdMeshTopology MeshData::mesh_topology() pxr::HdMeshTopology MeshData::mesh_topology()
{ {
return pxr::HdMeshTopology(pxr::PxOsdOpenSubdivTokens->none, return pxr::HdMeshTopology(pxr::PxOsdOpenSubdivTokens->none,
@ -88,6 +79,14 @@ pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors(pxr::HdInterpolatio
return primvars; return primvars;
} }
pxr::SdfPath MeshData::material_id()
{
if (!mat_data) {
return pxr::SdfPath();
}
return mat_data->p_id;
}
pxr::HdPrimvarDescriptorVector MeshData::instancer_primvar_descriptors( pxr::HdPrimvarDescriptorVector MeshData::instancer_primvar_descriptors(
pxr::HdInterpolation interpolation) pxr::HdInterpolation interpolation)
{ {
@ -137,7 +136,7 @@ void MeshData::add_instance(DupliObject *dupli)
if (instancer_id.IsEmpty()) { if (instancer_id.IsEmpty()) {
instancer_id = prim_id(scene_delegate, (Object *)id).AppendElementString("Instancer"); instancer_id = prim_id(scene_delegate, (Object *)id).AppendElementString("Instancer");
scene_delegate->GetRenderIndex().InsertInstancer(scene_delegate, instancer_id); scene_delegate->GetRenderIndex().InsertInstancer(scene_delegate, instancer_id);
CLOG_INFO(LOG_BSD, 2, "Instancer: %s, id=%s", name().c_str(), instancer_id.GetText()); CLOG_INFO(LOG_BSD, 2, "Instancer: %s, id=%s", id->name, instancer_id.GetText());
} }
if (instances.empty()) { if (instances.empty()) {
// USD hides the prototype mesh when instancing in contrary to the Blender, so we must add it // USD hides the prototype mesh when instancing in contrary to the Blender, so we must add it
@ -200,6 +199,26 @@ void MeshData::set_mesh(Mesh *mesh)
} }
} }
void MeshData::set_material()
{
Object *object = (Object *)id;
Material *mat = nullptr;
if (BKE_object_material_count_eval(object) > 0) {
mat = BKE_object_material_get_eval(object, object->actcol);
}
if (!mat) {
mat_data = nullptr;
return;
}
pxr::SdfPath id = MaterialData::prim_id(scene_delegate, mat);
mat_data = scene_delegate->material_data(id);
if (!mat_data) {
scene_delegate->materials[id] = MaterialData::create(scene_delegate, mat);
mat_data = scene_delegate->material_data(id);
}
}
void MeshData::init() void MeshData::init()
{ {
CLOG_INFO(LOG_BSD, 2, "%s", id->name); CLOG_INFO(LOG_BSD, 2, "%s", id->name);
@ -217,7 +236,7 @@ void MeshData::init()
BKE_object_to_mesh_clear(object); BKE_object_to_mesh_clear(object);
} }
scene_delegate->set_material(*this); set_material();
} }
void MeshData::insert() void MeshData::insert()
@ -245,7 +264,6 @@ void MeshData::update()
pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean;
Object *object = (Object *)id; Object *object = (Object *)id;
if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) { if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) {
material_id = pxr::SdfPath::EmptyPath();
instancer_id = pxr::SdfPath::EmptyPath(); instancer_id = pxr::SdfPath::EmptyPath();
face_vertex_counts.clear(); face_vertex_counts.clear();
face_vertex_indices.clear(); face_vertex_indices.clear();
@ -258,7 +276,7 @@ void MeshData::update()
} }
else { else {
if (id->recalc & ID_RECALC_SHADING) { if (id->recalc & ID_RECALC_SHADING) {
scene_delegate->set_material(*this); set_material();
bits |= pxr::HdChangeTracker::DirtyMaterialId; bits |= pxr::HdChangeTracker::DirtyMaterialId;
} }
if (id->recalc & ID_RECALC_TRANSFORM) { if (id->recalc & ID_RECALC_TRANSFORM) {
@ -267,7 +285,6 @@ void MeshData::update()
} }
if (!scene_delegate->GetRenderIndex().HasRprim(p_id)) { if (!scene_delegate->GetRenderIndex().HasRprim(p_id)) {
/* Trying to insert prim */
insert(); insert();
return; return;
} }

View File

@ -9,6 +9,7 @@
#include "BKE_duplilist.h" #include "BKE_duplilist.h"
#include "object.h" #include "object.h"
#include "material.h"
namespace blender::render::hydra { namespace blender::render::hydra {
@ -23,9 +24,10 @@ class MeshData : public ObjectData {
pxr::VtValue get_data(pxr::TfToken const &key) const override; pxr::VtValue get_data(pxr::TfToken const &key) const override;
bool update_visibility(View3D *view3d) override; bool update_visibility(View3D *view3d) override;
Material *material();
pxr::HdMeshTopology mesh_topology(); pxr::HdMeshTopology mesh_topology();
pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation); pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation);
pxr::SdfPath material_id();
pxr::HdPrimvarDescriptorVector instancer_primvar_descriptors(pxr::HdInterpolation interpolation); pxr::HdPrimvarDescriptorVector instancer_primvar_descriptors(pxr::HdInterpolation interpolation);
pxr::VtIntArray instance_indices(); pxr::VtIntArray instance_indices();
size_t sample_instancer_transform(size_t max_sample_count, size_t sample_instancer_transform(size_t max_sample_count,
@ -38,11 +40,11 @@ class MeshData : public ObjectData {
void add_instance(DupliObject *dupli); void add_instance(DupliObject *dupli);
pxr::SdfPath material_id;
pxr::SdfPath instancer_id; pxr::SdfPath instancer_id;
private: private:
void set_mesh(Mesh *mesh); void set_mesh(Mesh *mesh);
void set_material();
pxr::VtIntArray face_vertex_counts; pxr::VtIntArray face_vertex_counts;
pxr::VtIntArray face_vertex_indices; pxr::VtIntArray face_vertex_indices;
@ -51,6 +53,8 @@ class MeshData : public ObjectData {
pxr::VtVec2fArray uvs; pxr::VtVec2fArray uvs;
pxr::VtMatrix4dArray instances; pxr::VtMatrix4dArray instances;
MaterialData *mat_data;
}; };
} // namespace blender::render::hydra } // namespace blender::render::hydra