diff --git a/source/blender/render/hydra/CMakeLists.txt b/source/blender/render/hydra/CMakeLists.txt index b48afc4feb21..d5301388f81e 100644 --- a/source/blender/render/hydra/CMakeLists.txt +++ b/source/blender/render/hydra/CMakeLists.txt @@ -75,6 +75,8 @@ endif() set(SRC python.cc + camera.h + camera.cc engine.h engine.cc final_engine.h @@ -83,8 +85,6 @@ set(SRC preview_engine.cc viewport_engine.h viewport_engine.cc - camera.h - camera.cc render_task_delegate.cc render_task_delegate.h @@ -116,6 +116,8 @@ set(SRC scene_delegate/usd_scene_delegate.hh scene_delegate/volume.cc scene_delegate/volume.h + scene_delegate/volume_modifier.cc + scene_delegate/volume_modifier.h scene_delegate/world.cc scene_delegate/world.h ) diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h index a6f7cee1e202..e8d84af886c7 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h @@ -19,6 +19,7 @@ #include "object.h" #include "settings.h" #include "volume.h" +#include "volume_modifier.h" #include "world.h" namespace blender::render::hydra { diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index 5edae5b175f6..1ed788404c6e 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -13,7 +13,7 @@ #include "mesh.h" PXR_NAMESPACE_OPEN_SCOPE -TF_DEFINE_PRIVATE_TOKENS(_tokens, (st)); +TF_DEFINE_PRIVATE_TOKENS(tokens_, (st)); PXR_NAMESPACE_CLOSE_SCOPE namespace blender::render::hydra { @@ -95,7 +95,7 @@ pxr::VtValue MeshData::get_data(pxr::SdfPath const &id, pxr::TfToken const &key) if (key == pxr::HdTokens->normals) { return pxr::VtValue(submesh(id).normals); } - else if (key == pxr::_tokens->st) { + else if (key == pxr::tokens_->st) { return pxr::VtValue(submesh(id).uvs); } return get_data(key); @@ -144,7 +144,7 @@ pxr::HdPrimvarDescriptorVector MeshData::primvar_descriptors( } if (!submeshes_[0].uvs.empty()) { primvars.emplace_back( - pxr::_tokens->st, interpolation, pxr::HdPrimvarRoleTokens->textureCoordinate); + pxr::tokens_->st, interpolation, pxr::HdPrimvarRoleTokens->textureCoordinate); } } return primvars; diff --git a/source/blender/render/hydra/scene_delegate/object.cc b/source/blender/render/hydra/scene_delegate/object.cc index 80a7a3ab30f9..6817026b3fc0 100644 --- a/source/blender/render/hydra/scene_delegate/object.cc +++ b/source/blender/render/hydra/scene_delegate/object.cc @@ -31,6 +31,10 @@ std::unique_ptr ObjectData::create(BlenderSceneDelegate *scene_deleg case OB_FONT: case OB_CURVES_LEGACY: case OB_MBALL: + if (VolumeModifierData::is_volume_modifier(object)) { + obj_data = std::make_unique(scene_delegate, object, prim_id); + break; + } obj_data = std::make_unique(scene_delegate, object, prim_id); break; case OB_CURVES: diff --git a/source/blender/render/hydra/scene_delegate/volume.cc b/source/blender/render/hydra/scene_delegate/volume.cc index cba60bc6d8e1..27586a99e887 100644 --- a/source/blender/render/hydra/scene_delegate/volume.cc +++ b/source/blender/render/hydra/scene_delegate/volume.cc @@ -27,13 +27,15 @@ VolumeData::VolumeData(BlenderSceneDelegate *scene_delegate, void VolumeData::init() { - ID_LOGN(1, ""); + field_descriptors_.clear(); + Volume *volume = (Volume *)((Object *)this->id)->data; Main *main = CTX_data_main(scene_delegate_->context); if (!BKE_volume_load(volume, main)) { return; } filepath_ = BKE_volume_grids_frame_filepath(volume); + ID_LOGN(1, "%s", filepath_.c_str()); if (volume->runtime.grids) { const int num_grids = BKE_volume_num_grids(volume); @@ -64,14 +66,14 @@ void VolumeData::insert() for (auto &desc : field_descriptors_) { scene_delegate_->GetRenderIndex().InsertBprim( desc.fieldPrimType, scene_delegate_, desc.fieldId); - ID_LOGN(1, "Volume field %s", desc.fieldId.GetText()); + ID_LOGN(2, "Volume field %s", desc.fieldId.GetText()); } } void VolumeData::remove() { for (auto &desc : field_descriptors_) { - ID_LOG(1, "%s", desc.fieldId.GetText()); + ID_LOG(2, "%s", desc.fieldId.GetText()); scene_delegate_->GetRenderIndex().RemoveBprim(desc.fieldPrimType, desc.fieldId); } ID_LOG(1, ""); diff --git a/source/blender/render/hydra/scene_delegate/volume.h b/source/blender/render/hydra/scene_delegate/volume.h index f58d2106668e..a3c858598c38 100644 --- a/source/blender/render/hydra/scene_delegate/volume.h +++ b/source/blender/render/hydra/scene_delegate/volume.h @@ -29,7 +29,6 @@ class VolumeData : public ObjectData { protected: void write_materials() override; - private: std::string filepath_; pxr::HdVolumeFieldDescriptorVector field_descriptors_; MaterialData *mat_data_ = nullptr; diff --git a/source/blender/render/hydra/scene_delegate/volume_modifier.cc b/source/blender/render/hydra/scene_delegate/volume_modifier.cc new file mode 100644 index 000000000000..fc436f0deb5b --- /dev/null +++ b/source/blender/render/hydra/scene_delegate/volume_modifier.cc @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#include + +#include "BKE_mesh.h" +#include "BKE_modifier.h" +#include "BLI_path_util.h" +#include "DNA_scene_types.h" +#include "DNA_volume_types.h" + +#include "blender_scene_delegate.h" +#include "volume_modifier.h" + +PXR_NAMESPACE_OPEN_SCOPE +TF_DEFINE_PRIVATE_TOKENS(grid_tokens_, (density)(flame)(shadow)(temperature)(velocity)); +PXR_NAMESPACE_CLOSE_SCOPE + +namespace blender::render::hydra { + +VolumeModifierData::VolumeModifierData(BlenderSceneDelegate *scene_delegate, + Object *object, + pxr::SdfPath const &prim_id) + : VolumeData(scene_delegate, object, prim_id) +{ +} + +bool VolumeModifierData::is_volume_modifier(Object *object) +{ + if (object->type != OB_MESH) { + return false; + } + + FluidModifierData *modifier = (FluidModifierData *)BKE_modifiers_findby_type( + object, eModifierType_Fluid); + return modifier && modifier->type & MOD_FLUID_TYPE_DOMAIN && + modifier->domain->type == FLUID_DOMAIN_TYPE_GAS; +} + +void VolumeModifierData::init() +{ + field_descriptors_.clear(); + + Object *object = (Object *)this->id; + ModifierData *md = BKE_modifiers_findby_type(object, eModifierType_Fluid); + modifier_ = (FluidModifierData *)BKE_modifier_get_evaluated( + scene_delegate_->depsgraph, object, md); + + if ((modifier_->domain->cache_data_format & FLUID_DOMAIN_FILE_OPENVDB) == 0) { + CLOG_WARN(LOG_RENDER_HYDRA_SCENE, + "Volume %s is't exported: only OpenVDB file format supported", + prim_id.GetText()); + return; + } + + filepath_ = get_cached_file_path(modifier_->domain->cache_directory, + scene_delegate_->scene->r.cfra); + ID_LOG(1, "%s", filepath_.c_str()); + + for (auto &grid_name : pxr::grid_tokens_->allTokens) { + field_descriptors_.emplace_back(grid_name, + pxr::UsdVolImagingTokens->openvdbAsset, + prim_id.AppendElementString("VF_" + grid_name.GetString())); + } + + write_transform(); + write_materials(); +} + +void VolumeModifierData::update() +{ + Object *object = (Object *)id; + if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) { + remove(); + init(); + insert(); + return; + } + pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; + if (id->recalc & ID_RECALC_SHADING) { + write_materials(); + bits |= pxr::HdChangeTracker::DirtyMaterialId | pxr::HdChangeTracker::DirtyDoubleSided; + } + if (id->recalc & ID_RECALC_TRANSFORM) { + write_transform(); + bits |= pxr::HdChangeTracker::DirtyTransform; + } + + if (bits == pxr::HdChangeTracker::Clean) { + return; + } + + scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(prim_id, bits); + ID_LOG(1, ""); +} + +void VolumeModifierData::write_transform() +{ + Object *object = (Object *)this->id; + + /* set base scaling */ + transform = pxr::GfMatrix4d().SetScale( + pxr::GfVec3d(modifier_->domain->scale / modifier_->domain->global_size[0], + modifier_->domain->scale / modifier_->domain->global_size[1], + modifier_->domain->scale / modifier_->domain->global_size[2])); + /* positioning to center */ + transform *= pxr::GfMatrix4d().SetTranslate(pxr::GfVec3d(-1, -1, -1)); + + /* including texspace transform */ + float texspace_loc[3] = {0.0f, 0.0f, 0.0f}, texspace_scale[3] = {1.0f, 1.0f, 1.0f}; + BKE_mesh_texspace_get((Mesh *)object->data, texspace_loc, texspace_scale); + transform *= pxr::GfMatrix4d(1.0f).SetScale(pxr::GfVec3d(texspace_scale)) * + pxr::GfMatrix4d(1.0f).SetTranslate(pxr::GfVec3d(texspace_loc)); + + /* applying object transform */ + transform *= gf_matrix_from_transform(object->object_to_world); +} + +std::string VolumeModifierData::get_cached_file_path(std::string directory, int frame) +{ + char file_path[FILE_MAX]; + char file_name[32]; + snprintf( + file_name, sizeof(file_name), "%s_####%s", FLUID_NAME_DATA, FLUID_DOMAIN_EXTENSION_OPENVDB); + BLI_path_frame(file_name, sizeof(file_name), frame, 0); + BLI_path_join(file_path, sizeof(file_path), directory.c_str(), FLUID_DOMAIN_DIR_DATA, file_name); + + return file_path; +} + +} // namespace blender::render::hydra diff --git a/source/blender/render/hydra/scene_delegate/volume_modifier.h b/source/blender/render/hydra/scene_delegate/volume_modifier.h new file mode 100644 index 000000000000..12c1c6ecbf26 --- /dev/null +++ b/source/blender/render/hydra/scene_delegate/volume_modifier.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#pragma once + +#include "DNA_fluid_types.h" + +#include "volume.h" + +namespace blender::render::hydra { + +class VolumeModifierData : public VolumeData { + + public: + VolumeModifierData(BlenderSceneDelegate *scene_delegate, + Object *object, + pxr::SdfPath const &prim_id); + static bool is_volume_modifier(Object *object); + + void init() override; + void update() override; + + protected: + void write_transform() override; + + private: + std::string get_cached_file_path(std::string directory, int frame); + + FluidModifierData *modifier_; +}; + +} // namespace blender::render::hydra