diff --git a/source/blender/render/hydra/CMakeLists.txt b/source/blender/render/hydra/CMakeLists.txt index 1b993328380d..f60ad496eaf1 100644 --- a/source/blender/render/hydra/CMakeLists.txt +++ b/source/blender/render/hydra/CMakeLists.txt @@ -62,10 +62,16 @@ set(SRC sceneDelegate/blenderSceneDelegate.h sceneDelegate/blenderSceneDelegate.cc + sceneDelegate/id.h + sceneDelegate/id.cc sceneDelegate/object.h sceneDelegate/object.cc sceneDelegate/material.h sceneDelegate/material.cc + sceneDelegate/mesh.h + sceneDelegate/mesh.cc + sceneDelegate/light.h + sceneDelegate/light.cc sceneDelegate/world.h sceneDelegate/world.cc ) diff --git a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc index d1668b8c9bac..12a3dabab13d 100644 --- a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc +++ b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.cc @@ -25,75 +25,65 @@ BlenderSceneDelegate::BlenderSceneDelegate(HdRenderIndex* parentIndex, SdfPath c { } -void BlenderSceneDelegate::set_material(ObjectData &obj_data) +void BlenderSceneDelegate::set_material(MeshData &mesh_data) { - Material *material = obj_data.material(); + Material *material = mesh_data.material(); if (!material) { - obj_data.set_material_id(SdfPath::EmptyPath()); + mesh_data.material_id = SdfPath::EmptyPath(); return; } - SdfPath mat_id = material_id(material); - if (!material_data(mat_id)) { - MaterialData mat_data(material); - GetRenderIndex().InsertSprim(HdPrimTypeTokens->material, this, mat_id); - mat_data.export_mtlx(); - materials[mat_id] = mat_data; - LOG(INFO) << "Add material: " << mat_id << ", mtlx=" << mat_data.mtlx_path.GetResolvedPath(); + SdfPath id = MaterialData::prim_id(this, material); + MaterialData *mat_data = material_data(id); + if (!mat_data) { + materials[id] = MaterialData::init(this, material); + mat_data = material_data(id); + mat_data->export_mtlx(); + mat_data->insert_prim(); } - obj_data.set_material_id(mat_id); + mesh_data.material_id = id; } void BlenderSceneDelegate::update_material(Material *material) { - SdfPath mat_id = material_id(material); - MaterialData *mat_data = material_data(mat_id); + MaterialData *mat_data = material_data(MaterialData::prim_id(this, material)); if (mat_data) { mat_data->export_mtlx(); - LOG(INFO) << "Update material: " << mat_id << ", mtlx=" << mat_data->mtlx_path.GetResolvedPath(); - GetRenderIndex().GetChangeTracker().MarkSprimDirty(mat_id, HdMaterial::AllDirty); + mat_data->mark_prim_dirty(IdData::DirtyBits::AllDirty); } } -void BlenderSceneDelegate::add_update_world(World *world) +void BlenderSceneDelegate::update_world() { - SdfPath world_light_id = world_id(); - - LOG(INFO) << "Add world: " << world_light_id; - - if (!world) { - world_data = nullptr; - GetRenderIndex().RemoveSprim(HdPrimTypeTokens->domeLight, world_light_id); - return; - } - + World *world = (World *)b_depsgraph->scene().world().ptr.data; if (!world_data) { - world_data = make_unique(world, (bContext *)b_context->ptr.data); - GetRenderIndex().InsertSprim(HdPrimTypeTokens->domeLight, this, world_light_id); + if (world) { + world_data = WorldData::init(this, world, (bContext *)b_context->ptr.data); + world_data->insert_prim(); + } } else { - world_data = make_unique(world, (bContext *)b_context->ptr.data); - GetRenderIndex().GetChangeTracker().MarkSprimDirty(world_light_id, HdLight::AllDirty); + if (world) { + world_data = WorldData::init(this, world, (bContext *)b_context->ptr.data); + world_data->mark_prim_dirty(IdData::DirtyBits::AllDirty); + } + else { + world_data->remove_prim(); + world_data = nullptr; + } } } bool BlenderSceneDelegate::GetVisible(SdfPath const &id) { - ObjectData *obj_data = object_data(id); - LOG(INFO) << "GetVisible: " << id.GetAsString(); - - HdRenderIndex &index = GetRenderIndex(); - - if (id == world_id()) { - return world_data->is_visible(); + if (id == WorldData::prim_id(this)) { + return true; } - return obj_data->is_visible(); + return object_data(id)->visible; } void BlenderSceneDelegate::update_collection() { - HdRenderIndex &index = GetRenderIndex(); - /* add new objects */ std::set available_objects; for (auto &inst : b_depsgraph->object_instances) { @@ -104,8 +94,7 @@ void BlenderSceneDelegate::update_collection() if (!supported_object(object)) { continue; } - SdfPath obj_id = object_id(object); - available_objects.insert(obj_id); + available_objects.insert(ObjectData::prim_id(this, object)); if (!is_populated) { add_update_object(object, true, true, true); @@ -121,13 +110,7 @@ void BlenderSceneDelegate::update_collection() if (available_objects.find(it->first) != available_objects.end()) { continue; } - LOG(INFO) << "Remove: " << it->first; - if (it->second.prim_type() == HdPrimTypeTokens->mesh) { - index.RemoveRprim(it->first); - } - else if (it->second.prim_type() != HdBlenderTokens->empty) { - index.RemoveSprim(it->second.prim_type(), it->first); - } + it->second->remove_prim(); objects.erase(it); it = objects.begin(); } @@ -135,16 +118,16 @@ void BlenderSceneDelegate::update_collection() /* remove unused materials */ std::set available_materials; for (auto &obj : objects) { - if (obj.second.has_data(HdBlenderTokens->materialId)) { - available_materials.insert(obj.second.get_data(HdBlenderTokens->materialId).Get()); + MeshData *m_data = dynamic_cast(obj.second.get()); + if (m_data && !m_data->material_id.IsEmpty()) { + available_materials.insert(m_data->material_id); } } for (auto it = materials.begin(); it != materials.end(); ++it) { if (available_materials.find(it->first) != available_materials.end()) { continue; } - LOG(INFO) << "Remove material: " << it->first; - index.RemoveSprim(HdPrimTypeTokens->material, it->first); + it->second->remove_prim(); materials.erase(it); it = materials.begin(); } @@ -152,56 +135,38 @@ void BlenderSceneDelegate::update_collection() void BlenderSceneDelegate::add_update_object(Object *object, bool geometry, bool transform, bool shading) { - HdRenderIndex &index = GetRenderIndex(); - - SdfPath obj_id = object_id(object); - ObjectData *obj_data = object_data(obj_id); + SdfPath id = ObjectData::prim_id(this, object); + ObjectData *obj_data = object_data(id); if (!obj_data) { - ObjectData new_obj_data(object); - new_obj_data.update_visibility(view3d); - if (new_obj_data.prim_type() == HdPrimTypeTokens->mesh) { - LOG(INFO) << "Add mesh object: " << new_obj_data.name() << " id=" << obj_id; - index.InsertRprim(new_obj_data.prim_type(), this, obj_id); - set_material(new_obj_data); + objects[id] = ObjectData::init(this, object); + obj_data = object_data(id); + obj_data->update_visibility(view3d); + obj_data->insert_prim(); + MeshData *m_data = dynamic_cast(obj_data); + if (m_data) { + set_material(*m_data); } - else if (new_obj_data.type() == OB_LAMP) { - LOG(INFO) << "Add light object: " << new_obj_data.name() << " id=" << obj_id; - index.InsertSprim(new_obj_data.prim_type(), this, obj_id); - } - objects[obj_id] = new_obj_data; return; } if (geometry) { - LOG(INFO) << "Full updated: " << obj_id; - ObjectData new_obj_data(object); - new_obj_data.update_visibility(view3d); - if (new_obj_data.prim_type() == HdPrimTypeTokens->mesh) { - set_material(new_obj_data); - index.GetChangeTracker().MarkRprimDirty(obj_id, HdChangeTracker::AllDirty); + objects[id] = ObjectData::init(this, object); + obj_data = object_data(id); + obj_data->update_visibility(view3d); + MeshData *m_data = dynamic_cast(obj_data); + if (m_data) { + set_material(*m_data); } - else if (new_obj_data.type() == OB_LAMP) { - index.GetChangeTracker().MarkSprimDirty(obj_id, HdLight::AllDirty); - } - objects[obj_id] = new_obj_data; + obj_data->mark_prim_dirty(IdData::DirtyBits::AllDirty); return; } if (transform) { - LOG(INFO) << "Transform updated: " << obj_id; - if (obj_data->prim_type() == HdPrimTypeTokens->mesh) { - index.GetChangeTracker().MarkRprimDirty(obj_id, HdChangeTracker::DirtyTransform); - } - else if (obj_data->type() == OB_LAMP) { - index.GetChangeTracker().MarkSprimDirty(obj_id, HdLight::DirtyTransform); - } + obj_data->mark_prim_dirty(IdData::DirtyBits::DirtyTransform); } if (shading) { - LOG(INFO) << "Shading updated: " << obj_id; - if (obj_data->prim_type() == HdPrimTypeTokens->mesh) { - index.GetChangeTracker().MarkRprimDirty(obj_id, HdChangeTracker::DirtyMaterialId); - } + obj_data->mark_prim_dirty(IdData::DirtyBits::DirtyMaterial); } } @@ -211,7 +176,17 @@ ObjectData *BlenderSceneDelegate::object_data(SdfPath const &id) if (it == objects.end()) { return nullptr; } - return &it->second; + return it->second.get(); +} + +MeshData *BlenderSceneDelegate::mesh_data(SdfPath const &id) +{ + return static_cast(object_data(id)); +} + +LightData *BlenderSceneDelegate::light_data(SdfPath const &id) +{ + return static_cast(object_data(id)); } MaterialData *BlenderSceneDelegate::material_data(SdfPath const &id) @@ -220,28 +195,7 @@ MaterialData *BlenderSceneDelegate::material_data(SdfPath const &id) if (it == materials.end()) { return nullptr; } - return &it->second; -} - -SdfPath BlenderSceneDelegate::object_id(Object *object) -{ - /* Making id of object in form like O_. Example: O_000002073e369608 */ - char str[32]; - snprintf(str, 32, "O_%016llx", (uint64_t)object); - return GetDelegateID().AppendElementString(str); -} - -SdfPath BlenderSceneDelegate::material_id(Material *material) -{ - /* Making id of material in form like M_. Example: M_000002074e812088 */ - char str[32]; - snprintf(str, 32, "M_%016llx", (uint64_t)material); - return GetDelegateID().AppendElementString(str); -} - -SdfPath BlenderSceneDelegate::world_id() -{ - return GetDelegateID().AppendElementString("World"); + return it->second.get(); } bool BlenderSceneDelegate::supported_object(Object *object) @@ -259,16 +213,14 @@ void BlenderSceneDelegate::Populate(BL::Depsgraph &b_deps, BL::Context &b_cont) { LOG(INFO) << "Populate " << is_populated; - view3d = (View3D *)b_cont.space_data().ptr.data; b_depsgraph = &b_deps; b_context = &b_cont; + view3d = (View3D *)b_context->space_data().ptr.data; if (!is_populated) { /* Export initial objects */ update_collection(); - - World *world = (World *)b_depsgraph->scene().world().ptr.data; - add_update_world(world); + update_world(); is_populated = true; return; @@ -277,13 +229,14 @@ void BlenderSceneDelegate::Populate(BL::Depsgraph &b_deps, BL::Context &b_cont) /* Working with updates */ bool do_update_collection = false; bool do_update_visibility = false; + bool do_update_world = false; for (auto &update : b_depsgraph->updates) { BL::ID id = update.id(); - LOG(INFO) << "Update: " << id.name_full() << " " + LOG(INFO) << "Update: " << id.name_full() << " [" << update.is_updated_transform() << update.is_updated_geometry() - << update.is_updated_shading(); + << update.is_updated_shading() << "]"; if (id.is_a(&RNA_Object)) { Object *object = (Object *)id.ptr.data; @@ -313,23 +266,21 @@ void BlenderSceneDelegate::Populate(BL::Depsgraph &b_deps, BL::Context &b_cont) } if (id.is_a(&RNA_Scene)) { - World *world = (World *)b_depsgraph->scene().world().ptr.data; - add_update_world(world); if (!update.is_updated_geometry() && !update.is_updated_transform() && !update.is_updated_shading()) { do_update_visibility = true; + + Scene *scene = (Scene *)id.ptr.data; + if ((scene->world && !world_data) || (!scene->world && world_data)) { + do_update_world = true; + } } continue; } if (id.is_a(&RNA_World)) { - World *world = (World *)b_depsgraph->scene().world().ptr.data; - add_update_world(world); - continue; - } - - if (id.is_a(&RNA_ShaderNodeTree)) { - World *world = (World *)b_depsgraph->scene().world().ptr.data; - add_update_world(world); + if (update.is_updated_shading()) { + do_update_world = true; + } continue; } } @@ -340,22 +291,18 @@ void BlenderSceneDelegate::Populate(BL::Depsgraph &b_deps, BL::Context &b_cont) if (do_update_visibility) { update_visibility(); } + if (do_update_world) { + update_world(); + } + } void BlenderSceneDelegate::update_visibility() { - HdRenderIndex &index = GetRenderIndex(); - /* Check and update visibility */ for (auto &obj : objects) { - if (obj.second.update_visibility(view3d)) { - LOG(INFO) << "Visible changed: " << obj.first.GetAsString() << " " << obj.second.is_visible(); - if (obj.second.prim_type() == HdPrimTypeTokens->mesh) { - index.GetChangeTracker().MarkRprimDirty(obj.first, HdChangeTracker::DirtyVisibility); - } - else if (obj.second.type() == OB_LAMP) { - index.GetChangeTracker().MarkSprimDirty(obj.first, HdLight::DirtyParams); - } + if (obj.second->update_visibility(view3d)) { + obj.second->mark_prim_dirty(IdData::DirtyBits::DirtyVisibility); }; } @@ -369,8 +316,7 @@ void BlenderSceneDelegate::update_visibility() continue; } - SdfPath obj_id = object_id(object); - if (!object_data(obj_id)) { + if (!object_data(ObjectData::prim_id(this, object))) { add_update_object(object, true, true, true); } } @@ -378,113 +324,65 @@ void BlenderSceneDelegate::update_visibility() HdMeshTopology BlenderSceneDelegate::GetMeshTopology(SdfPath const& id) { - LOG(INFO) << "GetMeshTopology: " << id.GetAsString(); - ObjectData &obj_data = objects[id]; - return HdMeshTopology(PxOsdOpenSubdivTokens->catmullClark, HdTokens->rightHanded, - obj_data.get_data(HdBlenderTokens->faceCounts), - obj_data.get_data(HdTokens->pointsIndices)); + MeshData *m_data = mesh_data(id); + return m_data->mesh_topology(); } VtValue BlenderSceneDelegate::Get(SdfPath const& id, TfToken const& key) { - LOG(INFO) << "Get: " << id.GetAsString() << " [" << key.GetString() << "]"; - - VtValue ret; ObjectData *obj_data = object_data(id); if (obj_data) { - if (obj_data->has_data(key)) { - ret = obj_data->get_data(key); - } + return obj_data->get_data(key); } - else if (key.GetString() == "MaterialXFilename") { - MaterialData &mat_data = materials[id]; - if (!mat_data.mtlx_path.GetResolvedPath().empty()) { - ret = mat_data.mtlx_path; - } + + MaterialData *mat_data = material_data(id); + if (mat_data) { + return mat_data->get_data(key); } - else if (key == HdStRenderBufferTokens->stormMsaaSampleCount) { - // TODO: temporary value, it should be delivered through Python UI - ret = 16; - } - return ret; + return VtValue(); } HdPrimvarDescriptorVector BlenderSceneDelegate::GetPrimvarDescriptors(SdfPath const& id, HdInterpolation interpolation) { - LOG(INFO) << "GetPrimvarDescriptors: " << id.GetAsString() << " " << interpolation; - HdPrimvarDescriptorVector primvars; - ObjectData &obj_data = objects[id]; - if (interpolation == HdInterpolationVertex) { - if (obj_data.has_data(HdTokens->points)) { - primvars.emplace_back(HdTokens->points, interpolation, HdPrimvarRoleTokens->point); - } - } - else if (interpolation == HdInterpolationFaceVarying) { - if (obj_data.has_data(HdTokens->normals)) { - primvars.emplace_back(HdTokens->normals, interpolation, HdPrimvarRoleTokens->normal); - } - if (obj_data.has_data(HdPrimvarRoleTokens->textureCoordinate)) { - primvars.emplace_back(HdPrimvarRoleTokens->textureCoordinate, interpolation, HdPrimvarRoleTokens->textureCoordinate); - } - } - return primvars; + return mesh_data(id)->primvar_descriptors(interpolation); } SdfPath BlenderSceneDelegate::GetMaterialId(SdfPath const & rprimId) { - SdfPath ret; - ObjectData *obj_data = object_data(rprimId); - if (obj_data && obj_data->has_data(HdBlenderTokens->materialId)) { - ret = obj_data->get_data(HdBlenderTokens->materialId); - } - - LOG(INFO) << "GetMaterialId [" << rprimId.GetAsString() << "] = " << ret.GetAsString(); - return ret; + return mesh_data(rprimId)->material_id; } VtValue BlenderSceneDelegate::GetMaterialResource(SdfPath const& id) { - LOG(INFO) << "GetMaterialResource: " << id.GetAsString(); + MaterialData *mat_data = material_data(id); + if (mat_data) { + return mat_data->material_resource(); + } return VtValue(); } GfMatrix4d BlenderSceneDelegate::GetTransform(SdfPath const& id) { - LOG(INFO) << "GetTransform: " << id.GetAsString(); - - HdRenderIndex &index = GetRenderIndex(); - - if (id == world_id()) { - return world_data->transform(index.GetRenderDelegate()->GetRendererDisplayName()); + ObjectData *obj_data = object_data(id); + if (obj_data) { + return obj_data->transform(); } - - return objects[id].transform(); + if (id == WorldData::prim_id(this)) { + return world_data->transform(); + } + return GfMatrix4d(); } VtValue BlenderSceneDelegate::GetLightParamValue(SdfPath const& id, TfToken const& key) { - LOG(INFO) << "GetLightParamValue: " << id.GetAsString() << " [" << key.GetString() << "]"; - VtValue ret; - - HdRenderIndex &index = GetRenderIndex(); - - ObjectData *obj_data = object_data(id); - if (obj_data) { - if (obj_data->has_data(key)) { - ret = obj_data->get_data(key); - } - else if (key == HdLightTokens->exposure) { - // TODO: temporary value, it should be delivered through Python UI - ret = 1.0f; - } + LightData *l_data = light_data(id); + if (l_data) { + return l_data->get_data(key); } - else if (id == world_id()) { - if (world_data->has_data(key)) { - ret = world_data->get_data(key); - } + if (id == WorldData::prim_id(this)) { + return world_data->get_data(key); } - - return ret; + return VtValue(); } } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h index ea244055be46..080eda40e6b6 100644 --- a/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h +++ b/source/blender/render/hydra/sceneDelegate/blenderSceneDelegate.h @@ -15,6 +15,8 @@ #include "RNA_blender_cpp.h" #include "object.h" +#include "mesh.h" +#include "light.h" #include "world.h" using namespace pxr; @@ -40,16 +42,15 @@ public: private: ObjectData *object_data(SdfPath const &id); + MeshData *mesh_data(SdfPath const &id); + LightData *light_data(SdfPath const &id); MaterialData *material_data(SdfPath const &id); - SdfPath object_id(Object *object); - SdfPath material_id(Material *material); - SdfPath world_id(); bool supported_object(Object *object); void add_update_object(Object *object, bool geometry, bool transform, bool shading); - void set_material(ObjectData &obj_data); + void set_material(MeshData &mesh_data); void update_material(Material *material); - void add_update_world(World *world); + void update_world(); void update_collection(); void update_visibility(); diff --git a/source/blender/render/hydra/sceneDelegate/id.cc b/source/blender/render/hydra/sceneDelegate/id.cc new file mode 100644 index 000000000000..54852c34617e --- /dev/null +++ b/source/blender/render/hydra/sceneDelegate/id.cc @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#include "BKE_lib_id.h" + +#include "id.h" + +using namespace pxr; + +namespace blender::render::hydra { + +IdData::IdData(pxr::HdSceneDelegate *scene_delegate, ID *id) + : scene_delegate(scene_delegate) + , id(id) +{ +} + +std::string IdData::name() +{ + char str[MAX_ID_FULL_NAME]; + BKE_id_full_name_get(str, id, 0); + return str; +} + +VtValue IdData::get_data(TfToken const &key) +{ + return VtValue(); +} + +} // namespace blender::render::hydra diff --git a/source/blender/render/hydra/sceneDelegate/id.h b/source/blender/render/hydra/sceneDelegate/id.h new file mode 100644 index 000000000000..ecd8fe14bcf7 --- /dev/null +++ b/source/blender/render/hydra/sceneDelegate/id.h @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#pragma once + +#include +#include +#include + +#include "DNA_ID.h" + +namespace blender::render::hydra { + +class IdData { + public: + IdData(pxr::HdSceneDelegate *scene_delegate, ID *id); + virtual ~IdData() = default; + + std::string name(); + virtual pxr::VtValue get_data(pxr::TfToken const &key); + template const T get_data(pxr::TfToken const &key); + + enum class DirtyBits { + DirtyTransform = 1, + DirtyVisibility, + DirtyMaterial, + AllDirty + }; + + virtual void insert_prim() = 0; + virtual void remove_prim() = 0; + virtual void mark_prim_dirty(DirtyBits dirty_bits) = 0; + + protected: + pxr::HdSceneDelegate *scene_delegate; + ID *id; +}; + +template const T IdData::get_data(pxr::TfToken const &key) +{ + return get_data(key).Get(); +} + +} // namespace blender::render::hydra diff --git a/source/blender/render/hydra/sceneDelegate/light.cc b/source/blender/render/hydra/sceneDelegate/light.cc new file mode 100644 index 000000000000..f3cddffb438b --- /dev/null +++ b/source/blender/render/hydra/sceneDelegate/light.cc @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#include + +#include +#include +#include + +#include "glog/logging.h" + +#include "BKE_light.h" +#include "DNA_light_types.h" + +#include "light.h" + +using namespace pxr; +using namespace boost::algorithm; + +namespace blender::render::hydra { + +LightData::LightData(pxr::HdSceneDelegate *scene_delegate, Object *object) + : ObjectData(scene_delegate, object) +{ + Light *light = (Light *)((Object *)id)->data; + + data[HdLightTokens->intensity] = light->energy; + data[HdLightTokens->color] = GfVec3f(light->r, light->g, light->b); + + switch (light->type) { + case LA_LOCAL: + data[HdLightTokens->radius] = light->area_size / 2; + break; + + case LA_SUN: + data[HdLightTokens->angle] = light->sun_angle * 180.0 / M_PI; + break; + + case LA_SPOT: + data[HdLightTokens->shapingConeAngle] = light->spotsize / 2; + data[HdLightTokens->shapingConeSoftness] = light->spotblend; + data[UsdLuxTokens->treatAsPoint] = true; + break; + + case LA_AREA: + switch (light->area_shape) { + case LA_AREA_SQUARE: + data[HdLightTokens->width] = light->area_size; + data[HdLightTokens->height] = light->area_size; + break; + case LA_AREA_RECT: + data[HdLightTokens->width] = light->area_size; + data[HdLightTokens->height] = light->area_sizey; + break; + + case LA_AREA_DISK: + data[HdLightTokens->radius] = light->area_size / 2; + break; + + case LA_AREA_ELLIPSE: + data[HdLightTokens->radius] = (light->area_size + light->area_sizey) / 4; + break; + + default: + break; + } + data[HdLightTokens->normalize] = true; + break; + + default: + break; + } + + /* TODO: temporary value, it should be delivered through Python UI */ + data[HdLightTokens->exposure] = 1.0f; +} + +pxr::TfToken LightData::prim_type() +{ + Light *light = (Light *)((Object *)id)->data; + TfToken ret; + switch (light->type) { + case LA_LOCAL: + case LA_SPOT: + ret = HdPrimTypeTokens->sphereLight; + break; + + case LA_SUN: + ret = HdPrimTypeTokens->distantLight; + break; + + case LA_AREA: + switch (light->area_shape) { + case LA_AREA_SQUARE: + case LA_AREA_RECT: + ret = HdPrimTypeTokens->rectLight; + break; + + case LA_AREA_DISK: + case LA_AREA_ELLIPSE: + ret = HdPrimTypeTokens->diskLight; + break; + + default: + ret = HdPrimTypeTokens->rectLight; + } + break; + + default: + ret = HdPrimTypeTokens->sphereLight; + } + return ret; +} + +VtValue LightData::get_data(TfToken const &key) +{ + LOG(INFO) << "Get data light: " << name() << " [" << key.GetString() << "]"; + + VtValue ret; + auto it = data.find(key); + if (it != data.end()) { + ret = it->second; + } + else { + std::string n = key.GetString(); + if (contains(n, "object:visibility:")) { + if (ends_with(n, "camera") || ends_with(n, "shadow")) { + ret = false; + } + else { + ret = true; + } + } + } + return ret; +} + +void LightData::insert_prim() +{ + SdfPath p_id = prim_id(scene_delegate, (Object *)id); + scene_delegate->GetRenderIndex().InsertSprim(prim_type(), scene_delegate, p_id); + LOG(INFO) << "Add light: " << name() << " id=" << p_id.GetAsString(); +} + +void LightData::remove_prim() +{ + SdfPath p_id = prim_id(scene_delegate, (Object *)id); + scene_delegate->GetRenderIndex().RemoveSprim(prim_type(), p_id); + LOG(INFO) << "Remove light: " << name(); +} + +void LightData::mark_prim_dirty(DirtyBits dirty_bits) +{ + HdDirtyBits bits = HdLight::Clean; + switch (dirty_bits) { + case DirtyBits::DirtyTransform: + bits = HdLight::DirtyTransform; + break; + case DirtyBits::DirtyVisibility: + bits = HdLight::DirtyParams; + break; + case DirtyBits::AllDirty: + bits = HdLight::AllDirty; + break; + default: + break; + } + SdfPath p_id = prim_id(scene_delegate, (Object *)id); + scene_delegate->GetRenderIndex().GetChangeTracker().MarkSprimDirty(p_id, bits); + LOG(INFO) << "Update light: " << name() << " [" << (int)dirty_bits << "]"; +} + +} // namespace blender::render::hydra diff --git a/source/blender/render/hydra/sceneDelegate/light.h b/source/blender/render/hydra/sceneDelegate/light.h new file mode 100644 index 000000000000..794a0deee730 --- /dev/null +++ b/source/blender/render/hydra/sceneDelegate/light.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#pragma once + +#include +#include +#include "pxr/base/tf/hashmap.h" + +#include "object.h" + +namespace blender::render::hydra { + +class LightData: public ObjectData { + public: + LightData(pxr::HdSceneDelegate *scene_delegate, Object *object); + + pxr::VtValue get_data(pxr::TfToken const &key) override; + void insert_prim() override; + void remove_prim() override; + void mark_prim_dirty(DirtyBits dirty_bits) override; + + private: + std::map data; + pxr::TfToken prim_type(); +}; + +} // namespace blender::render::hydra diff --git a/source/blender/render/hydra/sceneDelegate/material.cc b/source/blender/render/hydra/sceneDelegate/material.cc index de3d7e21ee8d..492157bfa5cd 100644 --- a/source/blender/render/hydra/sceneDelegate/material.cc +++ b/source/blender/render/hydra/sceneDelegate/material.cc @@ -3,6 +3,11 @@ #include +#include +#include + +#include "glog/logging.h" + #include "BKE_material.h" #include "BKE_lib_id.h" @@ -12,32 +17,50 @@ using namespace pxr; namespace blender::render::hydra { -MaterialData::MaterialData() - : material(nullptr) +std::unique_ptr MaterialData::init(pxr::HdSceneDelegate *scene_delegate, Material *material) +{ + return std::make_unique(scene_delegate, material); +} + +pxr::SdfPath MaterialData::prim_id(pxr::HdSceneDelegate *scene_delegate, Material *material) +{ + /* Making id of material in form like M_. + * Example: M_000002074e812088 */ + char str[32]; + snprintf(str, 32, "M_%016llx", (uint64_t)material); + return scene_delegate->GetDelegateID().AppendElementString(str); +} + +MaterialData::MaterialData(pxr::HdSceneDelegate *scene_delegate, Material *material) + : IdData(scene_delegate, (ID *)material) { } -MaterialData::MaterialData(Material *material) - : material(material) +VtValue MaterialData::get_data(TfToken const &key) { + VtValue ret; + if (key.GetString() == "MaterialXFilename") { + if (!mtlx_path.GetResolvedPath().empty()) { + ret = mtlx_path; + } + } + return ret; } -std::string MaterialData::name() +pxr::VtValue MaterialData::material_resource() { - char str[MAX_ID_FULL_NAME]; - BKE_id_full_name_get(str, (ID *)material, 0); - return str; + /* TODO: Implement return of HdMaterialNetwork */ + return pxr::VtValue(); } void MaterialData::export_mtlx() { /* Call of python function hydra.export_mtlx() */ - PyObject *module, *dict, *func, *result; - PyGILState_STATE gstate; gstate = PyGILState_Ensure(); + PyObject *module, *dict, *func, *result; module = PyImport_ImportModule("hydra"); dict = PyModule_GetDict(module); func = PyDict_GetItemString(dict, "export_mtlx"); @@ -51,6 +74,36 @@ void MaterialData::export_mtlx() PyGILState_Release(gstate); mtlx_path = SdfAssetPath(path, path); + LOG(INFO) << "Material export: " << name() << " mtlx=" << mtlx_path.GetResolvedPath(); +} + +void MaterialData::insert_prim() +{ + SdfPath p_id = prim_id(scene_delegate, (Material *)id); + scene_delegate->GetRenderIndex().InsertSprim(HdPrimTypeTokens->material, scene_delegate, p_id); + LOG(INFO) << "Add material: " << name() << " id=" << p_id.GetAsString(); +} + +void MaterialData::remove_prim() +{ + SdfPath p_id = prim_id(scene_delegate, (Material *)id); + scene_delegate->GetRenderIndex().RemoveSprim(HdPrimTypeTokens->material, p_id); + LOG(INFO) << "Remove material: " << name(); +} + +void MaterialData::mark_prim_dirty(DirtyBits dirty_bits) +{ + HdDirtyBits bits = HdMaterial::Clean; + switch (dirty_bits) { + case DirtyBits::AllDirty: + bits = HdMaterial::AllDirty; + break; + default: + break; + } + SdfPath p_id = prim_id(scene_delegate, (Material *)id); + scene_delegate->GetRenderIndex().GetChangeTracker().MarkSprimDirty(p_id, bits); + LOG(INFO) << "Update material: " << name() << ", mtlx=" << mtlx_path.GetResolvedPath(); } } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/sceneDelegate/material.h b/source/blender/render/hydra/sceneDelegate/material.h index 35e8dfd8f3bb..e0ea0c129b54 100644 --- a/source/blender/render/hydra/sceneDelegate/material.h +++ b/source/blender/render/hydra/sceneDelegate/material.h @@ -3,28 +3,36 @@ #pragma once -#include - #include #include +#include "pxr/base/tf/hashmap.h" #include "DNA_material_types.h" +#include "id.h" + namespace blender::render::hydra { -class MaterialData { +class MaterialData; +using MaterialDataMap = pxr::TfHashMap, pxr::SdfPath::Hash>; + +class MaterialData: IdData { public: - MaterialData(); - MaterialData(Material *material); + static std::unique_ptr init(pxr::HdSceneDelegate *scene_delegate, Material *material); + static pxr::SdfPath prim_id(pxr::HdSceneDelegate *scene_delegate, Material *material); - std::string name(); + MaterialData(pxr::HdSceneDelegate *scene_delegate, Material *material); + + pxr::VtValue get_data(pxr::TfToken const &key) override; + void insert_prim() override; + void remove_prim() override; + void mark_prim_dirty(DirtyBits dirty_bits) override; + + pxr::VtValue material_resource(); void export_mtlx(); - pxr::SdfAssetPath mtlx_path; - private: - Material *material; +private: + pxr::SdfAssetPath mtlx_path; }; -using MaterialDataMap = std::map; - } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/sceneDelegate/mesh.cc b/source/blender/render/hydra/sceneDelegate/mesh.cc new file mode 100644 index 000000000000..cec931983feb --- /dev/null +++ b/source/blender/render/hydra/sceneDelegate/mesh.cc @@ -0,0 +1,187 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#include +#include + +#include "glog/logging.h" + +#include "BKE_mesh.h" +#include "BKE_mesh_runtime.h" +#include "BKE_object.h" +#include "BKE_material.h" + + +#include "mesh.h" + +using namespace pxr; + +namespace blender::render::hydra { + +MeshData::MeshData(pxr::HdSceneDelegate *scene_delegate, Object *object) + : ObjectData(scene_delegate, object) +{ + if (object->type == OB_MESH && object->mode == OB_MODE_OBJECT && + BLI_listbase_is_empty(&object->modifiers)) { + set_mesh((Mesh *)object->data); + } + else { + Mesh *mesh = BKE_object_to_mesh(nullptr, object, false); + set_mesh(mesh); + BKE_object_to_mesh_clear(object); + } +} + +VtValue MeshData::get_data(TfToken const &key) +{ + VtValue ret; + if (key == HdTokens->points) { + ret = vertices; + } + else if (key == HdTokens->normals) { + ret = normals; + } + else if (key == HdPrimvarRoleTokens->textureCoordinate) { + ret = uvs; + } + 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); +} + +HdMeshTopology MeshData::mesh_topology() +{ + return HdMeshTopology(PxOsdOpenSubdivTokens->catmullClark, HdTokens->rightHanded, + face_vertex_counts, face_vertex_indices); +} + +HdPrimvarDescriptorVector MeshData::primvar_descriptors(HdInterpolation interpolation) +{ + HdPrimvarDescriptorVector primvars; + if (interpolation == HdInterpolationVertex) { + if (!vertices.empty()) { + primvars.emplace_back(HdTokens->points, interpolation, HdPrimvarRoleTokens->point); + } + } + else if (interpolation == HdInterpolationFaceVarying) { + if (!vertices.empty()) { + primvars.emplace_back(HdTokens->normals, interpolation, HdPrimvarRoleTokens->normal); + } + if (!uvs.empty()) { + primvars.emplace_back(HdPrimvarRoleTokens->textureCoordinate, interpolation, + HdPrimvarRoleTokens->textureCoordinate); + } + } + return primvars; +} + +void MeshData::set_mesh(Mesh *mesh) +{ + BKE_mesh_calc_normals_split(mesh); + int tris_len = BKE_mesh_runtime_looptri_len(mesh); + if (tris_len == 0) { + return; + } + + blender::Span loopTris = mesh->looptris(); + + /* face_vertex_counts */ + face_vertex_counts = VtIntArray(tris_len, 3); + + /* face_vertex_indices */ + blender::Span loops = mesh->loops(); + face_vertex_indices.reserve(loopTris.size() * 3); + for (MLoopTri lt : loopTris) { + face_vertex_indices.push_back(loops[lt.tri[0]].v); + face_vertex_indices.push_back(loops[lt.tri[1]].v); + face_vertex_indices.push_back(loops[lt.tri[2]].v); + } + + /* vertices */ + vertices.reserve(mesh->totvert); + blender::Span verts = mesh->vert_positions(); + for (blender::float3 v : verts) { + vertices.push_back(GfVec3f(v.x, v.y, v.z)); + } + + /* normals */ + const float(*lnors)[3] = (float(*)[3])CustomData_get_layer(&mesh->ldata, CD_NORMAL); + if (lnors) { + normals.reserve(loopTris.size() * 3); + for (MLoopTri lt : loopTris) { + normals.push_back(GfVec3f(lnors[lt.tri[0]])); + normals.push_back(GfVec3f(lnors[lt.tri[1]])); + normals.push_back(GfVec3f(lnors[lt.tri[2]])); + } + } + + /* uvs*/ + const float(*luvs)[2] = (float(*)[2])CustomData_get_layer(&mesh->ldata, CD_PROP_FLOAT2); + if (luvs) { + uvs.reserve(loopTris.size() * 3); + for (MLoopTri lt : loopTris) { + uvs.push_back(GfVec2f(luvs[lt.tri[0]])); + uvs.push_back(GfVec2f(luvs[lt.tri[1]])); + uvs.push_back(GfVec2f(luvs[lt.tri[2]])); + } + } +} + +void MeshData::insert_prim() +{ + if (face_vertex_counts.empty()) { + return; + } + + SdfPath p_id = prim_id(scene_delegate, (Object *)id); + scene_delegate->GetRenderIndex().InsertRprim(HdPrimTypeTokens->mesh, scene_delegate, p_id); + LOG(INFO) << "Add mesh: " << name() << " id=" << p_id.GetAsString(); +} + +void MeshData::remove_prim() +{ + SdfPath p_id = prim_id(scene_delegate, (Object *)id); + if (!scene_delegate->GetRenderIndex().HasRprim(p_id)) { + return; + } + + scene_delegate->GetRenderIndex().RemoveRprim(p_id); + LOG(INFO) << "Remove mesh: " << name(); +} + +void MeshData::mark_prim_dirty(DirtyBits dirty_bits) +{ + SdfPath p_id = prim_id(scene_delegate, (Object *)id); + if (!scene_delegate->GetRenderIndex().HasRprim(p_id)) { + return; + } + + HdDirtyBits bits = HdChangeTracker::Clean; + switch (dirty_bits) { + case DirtyBits::DirtyTransform: + bits = HdChangeTracker::DirtyTransform; + break; + case DirtyBits::DirtyVisibility: + bits = HdChangeTracker::DirtyVisibility; + break; + case DirtyBits::DirtyMaterial: + bits = HdChangeTracker::DirtyMaterialId; + break; + case DirtyBits::AllDirty: + bits = HdChangeTracker::AllDirty; + break; + default: + break; + } + scene_delegate->GetRenderIndex().GetChangeTracker().MarkRprimDirty(p_id, bits); + LOG(INFO) << "Update mesh: " << name() << " [" << (int)dirty_bits << "]"; +} + +} // namespace blender::render::hydra diff --git a/source/blender/render/hydra/sceneDelegate/mesh.h b/source/blender/render/hydra/sceneDelegate/mesh.h new file mode 100644 index 000000000000..194ed2879cd6 --- /dev/null +++ b/source/blender/render/hydra/sceneDelegate/mesh.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#pragma once + +#include +#include + +#include "object.h" + +namespace blender::render::hydra { + +class MeshData: public ObjectData { +public: + MeshData(pxr::HdSceneDelegate *scene_delegate, Object *object); + + pxr::VtValue get_data(pxr::TfToken const &key) override; + + void insert_prim() override; + void remove_prim() override; + void mark_prim_dirty(DirtyBits dirty_bits) override; + + Material *material(); + pxr::HdMeshTopology mesh_topology(); + pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation); + + pxr::SdfPath material_id; + + private: + void set_mesh(Mesh *mesh); + + pxr::VtIntArray face_vertex_counts; + pxr::VtIntArray face_vertex_indices; + pxr::VtVec3fArray vertices; + pxr::VtVec3fArray normals; + pxr::VtVec2fArray uvs; +}; + +} // namespace blender::render::hydra diff --git a/source/blender/render/hydra/sceneDelegate/object.cc b/source/blender/render/hydra/sceneDelegate/object.cc index f10c210b3ef6..7bb7912b4cc3 100644 --- a/source/blender/render/hydra/sceneDelegate/object.cc +++ b/source/blender/render/hydra/sceneDelegate/object.cc @@ -1,173 +1,60 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ -#include -#include -#include -#include -#include -#include - -#include "DNA_light_types.h" -#include "DNA_camera_types.h" - #include "BKE_object.h" -#include "BKE_lib_id.h" -#include "BKE_material.h" -#include "BKE_light.h" -#include "BKE_mesh.h" -#include "BKE_mesh_runtime.h" -#include "BKE_layer.h" #include "object.h" +#include "mesh.h" +#include "light.h" #include "../utils.h" -PXR_NAMESPACE_OPEN_SCOPE -TF_DEFINE_PUBLIC_TOKENS(HdBlenderTokens, HD_BLENDER_TOKENS); -PXR_NAMESPACE_CLOSE_SCOPE - using namespace pxr; namespace blender::render::hydra { -ObjectData::ObjectData() - : object(nullptr) - , visible(true) -{ - -} - -ObjectData::ObjectData(Object *object) - : object(object) +std::unique_ptr ObjectData::init(pxr::HdSceneDelegate *scene_delegate, Object *object) { switch (object->type) { case OB_MESH: - if (object->mode == OB_MODE_OBJECT && BLI_listbase_is_empty(&object->modifiers)) { - set_as_mesh(); - } - else { - set_as_meshable(); - } - break; - case OB_SURF: case OB_FONT: case OB_CURVES: case OB_CURVES_LEGACY: case OB_MBALL: - set_as_meshable(); - break; + return std::make_unique(scene_delegate, object); case OB_LAMP: - set_as_light(); - break; + return std::make_unique(scene_delegate, object); default: break; } + return nullptr; } -std::string ObjectData::name() +pxr::SdfPath ObjectData::prim_id(pxr::HdSceneDelegate *scene_delegate, Object *object) +{ + /* Making id of object in form like O_. Example: + * O_000002073e369608 */ + char str[32]; + snprintf(str, 32, "O_%016llx", (uint64_t)object); + return scene_delegate->GetDelegateID().AppendElementString(str); +} + +ObjectData::ObjectData(pxr::HdSceneDelegate *scene_delegate, Object *object) + : IdData(scene_delegate, (ID *)object) + , visible(true) { - char str[MAX_ID_FULL_NAME]; - BKE_id_full_name_get(str, (ID *)object, 0); - return str; } int ObjectData::type() { - return object->type; -} - -TfToken ObjectData::prim_type() -{ - TfToken ret = HdBlenderTokens->empty; - Light *light; - switch (object->type) { - case OB_MESH: - case OB_SURF: - case OB_FONT: - case OB_CURVES: - case OB_CURVES_LEGACY: - case OB_MBALL: - if (!has_data(HdTokens->points)) { - break; - } - ret = HdPrimTypeTokens->mesh; - break; - - case OB_LAMP: - light = (Light *)object->data; - switch (light->type) { - case LA_LOCAL: - case LA_SPOT: - ret = HdPrimTypeTokens->sphereLight; - break; - - case LA_SUN: - ret = HdPrimTypeTokens->distantLight; - break; - - case LA_AREA: - switch (light->area_shape) { - case LA_AREA_SQUARE: - case LA_AREA_RECT: - ret = HdPrimTypeTokens->rectLight; - break; - - case LA_AREA_DISK: - case LA_AREA_ELLIPSE: - ret = HdPrimTypeTokens->diskLight; - break; - - default: - ret = HdPrimTypeTokens->rectLight; - } - break; - - default: - ret = HdPrimTypeTokens->sphereLight; - } - break; - - default: - break; - } - - return ret; + return ((Object *)id)->type; } GfMatrix4d ObjectData::transform() { - return gf_matrix_from_transform(object->object_to_world); -} - -Material *ObjectData::material() -{ - if (BKE_object_material_count_eval(object) == 0) { - return nullptr; - } - return BKE_object_material_get_eval(object, object->actcol); -} - -VtValue &ObjectData::get_data(TfToken const &key) -{ - return data[key]; -} - -bool ObjectData::has_data(TfToken const &key) -{ - return data.find(key) != data.end(); -} - -void ObjectData::set_material_id(SdfPath const &id) -{ - if (id.IsEmpty()) { - data.erase(HdBlenderTokens->materialId); - } - else { - data[HdBlenderTokens->materialId] = id; - } + return gf_matrix_from_transform(((Object *)id)->object_to_world); } bool ObjectData::update_visibility(View3D *view3d) @@ -177,136 +64,8 @@ bool ObjectData::update_visibility(View3D *view3d) } bool prev_visible = visible; - visible = BKE_object_is_visible_in_viewport(view3d, object); + visible = BKE_object_is_visible_in_viewport(view3d, (Object *)id); return visible != prev_visible; } -bool ObjectData::is_visible() -{ - return visible; -} - -void ObjectData::set_as_mesh() -{ - Mesh *mesh = (Mesh *)object->data; - set_mesh(mesh); -} - -void ObjectData::set_as_meshable() -{ - Mesh *mesh = BKE_object_to_mesh(nullptr, object, false); - set_mesh(mesh); - BKE_object_to_mesh_clear(object); -} - -void ObjectData::set_mesh(Mesh *mesh) -{ - BKE_mesh_calc_normals_split(mesh); - int tris_len = BKE_mesh_runtime_looptri_len(mesh); - if (tris_len == 0) { - return; - } - - blender::Span loopTris = mesh->looptris(); - - /* faceVertexCounts */ - data[HdBlenderTokens->faceCounts] = VtIntArray(tris_len, 3); - - /* faceVertexIndices */ - VtIntArray faceVertexIndices; - blender::Span loops = mesh->loops(); - faceVertexIndices.reserve(loopTris.size() * 3); - for (MLoopTri lt : loopTris) { - faceVertexIndices.push_back(loops[lt.tri[0]].v); - faceVertexIndices.push_back(loops[lt.tri[1]].v); - faceVertexIndices.push_back(loops[lt.tri[2]].v); - } - data[HdTokens->pointsIndices] = faceVertexIndices; - - /* vertices */ - VtVec3fArray vertices; - vertices.reserve(mesh->totvert); - blender::Span verts = mesh->vert_positions(); - for (blender::float3 v : verts) { - vertices.push_back(GfVec3f(v.x, v.y, v.z)); - } - data[HdTokens->points] = vertices; - - /* normals */ - const float(*lnors)[3] = (float(*)[3])CustomData_get_layer(&mesh->ldata, CD_NORMAL); - if (lnors) { - VtVec3fArray normals; - normals.reserve(loopTris.size() * 3); - for (MLoopTri lt : loopTris) { - normals.push_back(GfVec3f(lnors[lt.tri[0]])); - normals.push_back(GfVec3f(lnors[lt.tri[1]])); - normals.push_back(GfVec3f(lnors[lt.tri[2]])); - } - data[HdTokens->normals] = normals; - } - - /* UVs*/ - const float(*luvs)[2] = (float(*)[2])CustomData_get_layer(&mesh->ldata, CD_PROP_FLOAT2); - if (luvs) { - VtVec2fArray uvs; - uvs.reserve(loopTris.size() * 3); - for (MLoopTri lt : loopTris) { - uvs.push_back(GfVec2f(luvs[lt.tri[0]])); - uvs.push_back(GfVec2f(luvs[lt.tri[1]])); - uvs.push_back(GfVec2f(luvs[lt.tri[2]])); - } - data[HdPrimvarRoleTokens->textureCoordinate] = uvs; - } -} - -void ObjectData::set_as_light() -{ - Light *light = (Light *)object->data; - data[HdLightTokens->intensity] = light->energy; - data[HdLightTokens->color] = GfVec3f(light->r, light->g, light->b); - - switch (light->type) { - case LA_LOCAL: - data[HdLightTokens->radius] = light->area_size / 2; - break; - - case LA_SUN: - data[HdLightTokens->angle] = light->sun_angle * 180.0 / M_PI; - break; - - case LA_SPOT: - data[HdLightTokens->shapingConeAngle] = light->spotsize / 2; - data[HdLightTokens->shapingConeSoftness] = light->spotblend; - data[UsdLuxTokens->treatAsPoint] = 1; - break; - - case LA_AREA: - switch (light->area_shape) { - case LA_AREA_SQUARE: - data[HdLightTokens->width] = light->area_size; - data[HdLightTokens->height] = light->area_size; - break; - case LA_AREA_RECT: - data[HdLightTokens->width] = light->area_size; - data[HdLightTokens->height] = light->area_sizey; - break; - - case LA_AREA_DISK: - data[HdLightTokens->radius] = light->area_size / 2; - break; - - case LA_AREA_ELLIPSE: - data[HdLightTokens->radius] = (light->area_size + light->area_sizey) / 4; - break; - - default: - break; - } - break; - - default: - break; - } -} - } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/sceneDelegate/object.h b/source/blender/render/hydra/sceneDelegate/object.h index ae3ab672ed86..dab439d4559b 100644 --- a/source/blender/render/hydra/sceneDelegate/object.h +++ b/source/blender/render/hydra/sceneDelegate/object.h @@ -3,66 +3,34 @@ #pragma once -#include - #include -#include -#include -#include "pxr/base/tf/staticTokens.h" +#include "pxr/base/tf/hashmap.h" #include "DNA_object_types.h" +#include "BKE_layer.h" +#include "id.h" #include "material.h" -PXR_NAMESPACE_OPEN_SCOPE -#define HD_BLENDER_TOKENS \ - (materialId) \ - (faceCounts) \ - (empty) - -TF_DECLARE_PUBLIC_TOKENS(HdBlenderTokens, HD_BLENDER_TOKENS); -PXR_NAMESPACE_CLOSE_SCOPE - namespace blender::render::hydra { +class ObjectData; +using ObjectDataMap = pxr::TfHashMap, pxr::SdfPath::Hash>; -class ObjectData { +class ObjectData: public IdData { public: - ObjectData(); - ObjectData(Object *object); + static std::unique_ptr init(pxr::HdSceneDelegate *scene_delegate, Object *object); + static pxr::SdfPath prim_id(pxr::HdSceneDelegate *scene_delegate, Object *object); + + ObjectData(pxr::HdSceneDelegate *scene_delegate, Object *object); - std::string name(); int type(); - pxr::TfToken prim_type(); pxr::GfMatrix4d transform(); - Material *material(); - - pxr::VtValue &get_data(pxr::TfToken const &key); - template - const T &get_data(pxr::TfToken const &key); - bool has_data(pxr::TfToken const &key); - - void set_material_id(pxr::SdfPath const &id); bool update_visibility(View3D *view3d); - bool is_visible(); - private: - Object *object; - std::map data; bool visible; - - void set_as_mesh(); - void set_as_meshable(); - void set_mesh(Mesh *mesh); - void set_as_light(); }; -using ObjectDataMap = std::map; -template -const T &ObjectData::get_data(pxr::TfToken const &key) -{ - return get_data(key).Get(); -} } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/sceneDelegate/world.cc b/source/blender/render/hydra/sceneDelegate/world.cc index 2accd814d821..290eca4f5568 100644 --- a/source/blender/render/hydra/sceneDelegate/world.cc +++ b/source/blender/render/hydra/sceneDelegate/world.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "BKE_context.h" @@ -19,31 +20,36 @@ #include "BKE_image.h" #include "NOD_shader.h" +#include "glog/logging.h" + #include "world.h" #include "../utils.h" /* TODO : add custom tftoken "transparency"? */ using namespace pxr; -using namespace std; namespace blender::render::hydra { -WorldData::WorldData() - : b_context(nullptr), - world(nullptr) +std::unique_ptr WorldData::init(pxr::HdSceneDelegate *scene_delegate, + World *world, bContext *context) { + return std::make_unique(scene_delegate, world, context); } -WorldData::WorldData(World *world, bContext *b_context) - : b_context(b_context), - world(world) +SdfPath WorldData::prim_id(HdSceneDelegate *scene_delegate) { - data.clear(); + return scene_delegate->GetDelegateID().AppendElementString("World"); +} +WorldData::WorldData(pxr::HdSceneDelegate *scene_delegate, World *world, bContext *context) + : IdData(scene_delegate, (ID *)world) +{ data[UsdLuxTokens->orientToStageUpAxis] = true; if (world->use_nodes) { + /* TODO: Create nodes parsing system */ + bNode *output_node = ntreeShaderOutputNode(world->nodetree, SHD_OUTPUT_ALL); bNodeSocket input_socket = output_node->input_by_identifier("Surface"); bNodeLink const *link = input_socket.directly_linked_links()[0]; @@ -69,16 +75,16 @@ WorldData::WorldData(World *world, bContext *b_context) Image *image = (Image *)color_input_node->id; if (image) { - Main *bmain = CTX_data_main(b_context); - Scene *scene = CTX_data_scene(b_context); + Main *bmain = CTX_data_main(context); + Scene *scene = CTX_data_scene(context); ReportList reports; ImageSaveOptions opts; opts.im_format.imtype = R_IMF_IMTYPE_PNG; - string cached_image_path = cache_image(bmain, scene, image, &tex->iuser, &opts, &reports); - if (!cached_image_path.empty()) { - data[HdLightTokens->textureFile] = SdfAssetPath(cached_image_path, cached_image_path); + std::string image_path = cache_image(bmain, scene, image, &tex->iuser, &opts, &reports); + if (!image_path.empty()) { + data[HdLightTokens->textureFile] = SdfAssetPath(image_path, image_path); } } } @@ -91,35 +97,55 @@ WorldData::WorldData(World *world, bContext *b_context) } } -GfMatrix4d WorldData::transform(string const &renderer_name) +GfMatrix4d WorldData::transform() { - GfMatrix4d transform = GfMatrix4d().SetIdentity(); + GfMatrix4d transform = GfMatrix4d(GfRotation(GfVec3d(1.0, 0.0, 0.0), -90), GfVec3d()); - if (has_data(UsdLuxTokens->orientToStageUpAxis)) { - transform *= GfMatrix4d(GfRotation(GfVec3d(1.0, 0.0, 0.0), -90), GfVec3d()); - } /* TODO : do this check via RenderSettings*/ - if (renderer_name == "RPR") { + if (scene_delegate->GetRenderIndex().GetRenderDelegate()->GetRendererDisplayName() == "RPR") { transform *= GfMatrix4d(GfRotation(GfVec3d(1.0, 0.0, 0.0), -180), GfVec3d()); transform *= GfMatrix4d(GfRotation(GfVec3d(0.0, 0.0, 1.0), 90.0), GfVec3d()); } - return transform; } -VtValue &WorldData::get_data(TfToken const &key) +VtValue WorldData::get_data(TfToken const &key) { - return data[key]; + VtValue ret; + auto it = data.find(key); + if (it != data.end()) { + ret = it->second; + } + return ret; } -bool WorldData::has_data(TfToken const &key) +void WorldData::insert_prim() { - return data.find(key) != data.end(); + SdfPath p_id = prim_id(scene_delegate); + scene_delegate->GetRenderIndex().InsertSprim(HdPrimTypeTokens->domeLight, scene_delegate, p_id); + LOG(INFO) << "Add World: id=" << p_id.GetAsString(); } -bool WorldData::is_visible() +void WorldData::remove_prim() { - return true; + SdfPath p_id = prim_id(scene_delegate); + scene_delegate->GetRenderIndex().RemoveSprim(HdPrimTypeTokens->domeLight, p_id); + LOG(INFO) << "Remove World"; +} + +void WorldData::mark_prim_dirty(DirtyBits dirty_bits) +{ + HdDirtyBits bits = HdLight::Clean; + switch (dirty_bits) { + case DirtyBits::AllDirty: + bits = HdLight::AllDirty; + break; + default: + break; + } + SdfPath p_id = prim_id(scene_delegate); + scene_delegate->GetRenderIndex().GetChangeTracker().MarkSprimDirty(p_id, bits); + LOG(INFO) << "Update World"; } } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/sceneDelegate/world.h b/source/blender/render/hydra/sceneDelegate/world.h index b61d5b4824a0..04a08b29ed09 100644 --- a/source/blender/render/hydra/sceneDelegate/world.h +++ b/source/blender/render/hydra/sceneDelegate/world.h @@ -14,33 +14,26 @@ #include "DNA_view3d_types.h" #include "DNA_world_types.h" +#include "id.h" + namespace blender::render::hydra { -class WorldData { +class WorldData: public IdData { public: - WorldData(); - WorldData(World *world, bContext *b_context); + static std::unique_ptr init(pxr::HdSceneDelegate *scene_delegate, World *world, bContext *context); + static pxr::SdfPath prim_id(pxr::HdSceneDelegate *scene_delegate); - pxr::TfToken prim_type(); - pxr::GfMatrix4d transform(std::string const &renderer_name); + WorldData(pxr::HdSceneDelegate *scene_delegate, World *world, bContext *context); - pxr::VtValue &get_data(pxr::TfToken const &key); - template - const T &get_data(pxr::TfToken const &key); - bool has_data(pxr::TfToken const &key); - bool is_visible(); + pxr::GfMatrix4d transform(); + + pxr::VtValue get_data(pxr::TfToken const &key) override; + void insert_prim() override; + void remove_prim() override; + void mark_prim_dirty(DirtyBits dirty_bits) override; - bContext *b_context; - World *world; - private: std::map data; }; -template -const T &WorldData::get_data(pxr::TfToken const &key) -{ - return get_data(key).Get(); -} - } // namespace blender::render::hydra