forked from blender/blender
BLEN-359: Implement updates for instances in viewport #20
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user