Files
test2/source/blender/io/usd/hydra/volume_modifier.cc

137 lines
4.6 KiB
C++

/* SPDX-FileCopyrightText: 2011-2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "volume_modifier.hh"
#include <pxr/usdImaging/usdVolImaging/tokens.h>
#include "DNA_scene_types.h"
#include "BLI_path_utils.hh"
#include "BLI_string.h"
#include "BKE_mesh.h"
#include "BKE_modifier.hh"
#include "hydra_scene_delegate.hh"
namespace blender::io::hydra {
VolumeModifierData::VolumeModifierData(HydraSceneDelegate *scene_delegate,
const Object *object,
pxr::SdfPath const &prim_id)
: VolumeData(scene_delegate, object, prim_id)
{
}
bool VolumeModifierData::is_volume_modifier(const Object *object)
{
if (object->type != OB_MESH) {
return false;
}
const FluidModifierData *modifier = (const 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();
const Object *object = (const Object *)this->id;
const ModifierData *md = BKE_modifiers_findby_type(object, eModifierType_Fluid);
modifier_ = (const FluidModifierData *)BKE_modifier_get_evaluated(
scene_delegate_->depsgraph, const_cast<Object *>(object), const_cast<ModifierData *>(md));
if ((modifier_->domain->cache_data_format & FLUID_DOMAIN_FILE_OPENVDB) == 0) {
CLOG_WARN(LOG_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());
static const pxr::TfToken grid_tokens[] = {pxr::TfToken("density", pxr::TfToken::Immortal),
pxr::TfToken("flame", pxr::TfToken::Immortal),
pxr::TfToken("shadow", pxr::TfToken::Immortal),
pxr::TfToken("temperature", pxr::TfToken::Immortal),
pxr::TfToken("velocity", pxr::TfToken::Immortal)};
for (const auto &grid_name : grid_tokens) {
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().ptr());
}
std::string VolumeModifierData::get_cached_file_path(const std::string &directory, int frame)
{
char file_path[FILE_MAX];
char file_name[32];
SNPRINTF(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::io::hydra