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)
{
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;
for (auto &obj : objects) {
MeshData *m_data = dynamic_cast<MeshData *>(obj.second.get());
if (m_data && !m_data->material_id.IsEmpty()) {
available_materials.insert(m_data->material_id);
if (!m_data) {
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) {
@ -393,7 +382,7 @@ pxr::HdPrimvarDescriptorVector BlenderSceneDelegate::GetPrimvarDescriptors(
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)

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_instance(DupliObject *dupli);
void set_material(MeshData &mesh_data);
void update_material(Material *material);
void update_world();
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
{
return pxr::VtValue();

View File

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

View File

@ -107,7 +107,7 @@ void MaterialData::export_mtlx()
Py_DECREF(result);
}
else {
CLOG_ERROR(LOG_BSD, "Export error for %s", name().c_str());
CLOG_ERROR(LOG_BSD, "Export error for %s", id->name);
PyErr_Print();
}
Py_DECREF(module);
@ -115,7 +115,7 @@ void MaterialData::export_mtlx()
PyGILState_Release(gstate);
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()

View File

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

View File

@ -16,7 +16,7 @@
namespace blender::render::hydra {
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());
}
@ -49,15 +49,6 @@ bool MeshData::update_visibility(View3D *view3d)
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()
{
return pxr::HdMeshTopology(pxr::PxOsdOpenSubdivTokens->none,
@ -88,6 +79,14 @@ pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors(pxr::HdInterpolatio
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::HdInterpolation interpolation)
{
@ -137,7 +136,7 @@ void MeshData::add_instance(DupliObject *dupli)
if (instancer_id.IsEmpty()) {
instancer_id = prim_id(scene_delegate, (Object *)id).AppendElementString("Instancer");
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()) {
// 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()
{
CLOG_INFO(LOG_BSD, 2, "%s", id->name);
@ -217,7 +236,7 @@ void MeshData::init()
BKE_object_to_mesh_clear(object);
}
scene_delegate->set_material(*this);
set_material();
}
void MeshData::insert()
@ -245,7 +264,6 @@ void MeshData::update()
pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean;
Object *object = (Object *)id;
if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) {
material_id = pxr::SdfPath::EmptyPath();
instancer_id = pxr::SdfPath::EmptyPath();
face_vertex_counts.clear();
face_vertex_indices.clear();
@ -258,7 +276,7 @@ void MeshData::update()
}
else {
if (id->recalc & ID_RECALC_SHADING) {
scene_delegate->set_material(*this);
set_material();
bits |= pxr::HdChangeTracker::DirtyMaterialId;
}
if (id->recalc & ID_RECALC_TRANSFORM) {
@ -267,7 +285,6 @@ void MeshData::update()
}
if (!scene_delegate->GetRenderIndex().HasRprim(p_id)) {
/* Trying to insert prim */
insert();
return;
}

View File

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