Export volumes from object modifier (quick effect) #62

Merged
Bogdan Nagirniak merged 28 commits from BLEN-448 into hydra-render 2023-07-20 23:49:25 +02:00
3 changed files with 146 additions and 23 deletions
Showing only changes of commit 6ef2c7a976 - Show all commits

View File

@ -2,6 +2,8 @@
* Copyright 2011-2022 Blender Foundation */ * Copyright 2011-2022 Blender Foundation */
#include "BKE_object.h" #include "BKE_object.h"
#include "DNA_scene_types.h"
#include "DEG_depsgraph_query.h" #include "DEG_depsgraph_query.h"
#include "blender_scene_delegate.h" #include "blender_scene_delegate.h"
@ -26,9 +28,14 @@ std::unique_ptr<ObjectData> ObjectData::create(BlenderSceneDelegate *scene_deleg
{ {
std::unique_ptr<ObjectData> data; std::unique_ptr<ObjectData> data;
DagerD marked this conversation as resolved Outdated

Propose to create class VolumeModifierData::public VolumeData and separate logic in these two classes

Propose to create `class VolumeModifierData::public VolumeData` and separate logic in these two classes
if (VolumeData::is_volume_modifier(object))
{
return std::make_unique<VolumeData>(scene_delegate, object, prim_id);
}
switch (object->type) { switch (object->type) {
case OB_MESH:
case OB_SURF: case OB_SURF:
case OB_MESH:
case OB_FONT: case OB_FONT:
case OB_CURVES_LEGACY: case OB_CURVES_LEGACY:
case OB_MBALL: case OB_MBALL:

View File

@ -8,16 +8,33 @@
#include <pxr/usd/usdVol/tokens.h> #include <pxr/usd/usdVol/tokens.h>
#include <pxr/usdImaging/usdVolImaging/tokens.h> #include <pxr/usdImaging/usdVolImaging/tokens.h>
#include "DNA_scene_types.h"
#include "BKE_material.h" #include "BKE_material.h"
#include "BLI_path_util.h"
#include "BKE_modifier.h"
#include "DNA_fluid_types.h"
#include "BKE_volume.h" #include "BKE_volume.h"
#include "BLI_index_range.hh" #include "BLI_index_range.hh"
#include "BKE_object.h"
#include "DNA_volume_types.h" #include "DNA_volume_types.h"
#include "BKE_mesh.hh"
#include "blender_scene_delegate.h" #include "blender_scene_delegate.h"
#include "volume.h" #include "volume.h"
PXR_NAMESPACE_OPEN_SCOPE
TF_DEFINE_PRIVATE_TOKENS(grid_tokens_,
(density)(flame)(shadow)(temperature)(velocity));
PXR_NAMESPACE_CLOSE_SCOPE
namespace blender::render::hydra { namespace blender::render::hydra {
const Set<pxr::TfToken> supported_grids = {pxr::grid_tokens_->density,
pxr::grid_tokens_->flame,
pxr::grid_tokens_->shadow,
pxr::grid_tokens_->temperature,
pxr::grid_tokens_->velocity};
VolumeData::VolumeData(BlenderSceneDelegate *scene_delegate, VolumeData::VolumeData(BlenderSceneDelegate *scene_delegate,
Object *object, Object *object,
pxr::SdfPath const &prim_id) pxr::SdfPath const &prim_id)
@ -25,34 +42,23 @@ VolumeData::VolumeData(BlenderSceneDelegate *scene_delegate,
{ {
} }
bool VolumeData::is_volume_modifier(Object *object) {
FluidModifierData *volume_modifier = (FluidModifierData *)BKE_modifiers_findby_type(
object, eModifierType_Fluid);
return volume_modifier && volume_modifier->type & MOD_FLUID_TYPE_DOMAIN && volume_modifier->domain->type == FLUID_DOMAIN_TYPE_GAS;
}
void VolumeData::init() void VolumeData::init()
{ {
ID_LOG(1, ""); ID_LOG(1, "");
Volume *volume = (Volume *)((Object *)this->id)->data; if (is_volume_modifier((Object *)this->id)) {
Main *main = CTX_data_main(scene_delegate_->context); init_from_modifier();
if (!BKE_volume_load(volume, main)) {
return;
} }
filepath_ = BKE_volume_grids_frame_filepath(volume); else
{
if (volume->runtime.grids) { init_from_volume();
const int num_grids = BKE_volume_num_grids(volume);
if (num_grids) {
for (const int i : IndexRange(num_grids)) {
const VolumeGrid *grid = BKE_volume_grid_get_for_read(volume, i);
const std::string grid_name = BKE_volume_grid_name(grid);
field_descriptors_.emplace_back(pxr::TfToken(grid_name),
pxr::UsdVolImagingTokens->openvdbAsset,
prim_id.AppendElementString("VF_" + grid_name));
} }
} }
}
write_transform();
write_materials();
BKE_volume_unload(volume);
}
void VolumeData::insert() void VolumeData::insert()
{ {
@ -92,6 +98,13 @@ void VolumeData::update()
} }
if (id->recalc & ID_RECALC_TRANSFORM) { if (id->recalc & ID_RECALC_TRANSFORM) {
write_transform(); write_transform();
if (is_volume_modifier(object)) {
Mesh *mesh = BKE_object_to_mesh(nullptr, object, false);
transform *= pxr::GfMatrix4d(1.0).SetTranslate(pxr::GfVec3d(mesh->texspace_location[0] - 1,
mesh->texspace_location[1] - 1,
mesh->texspace_location[2] - 1));
BKE_object_to_mesh_clear(object);
}
bits |= pxr::HdChangeTracker::DirtyTransform; bits |= pxr::HdChangeTracker::DirtyTransform;
} }
@ -176,4 +189,101 @@ void VolumeData::write_materials()
} }
} }
std::string VolumeData::get_cached_file_path(std::string directory, int frame)
{
char file_path[FILE_MAX];
char file_name[32];
strcat(strcat(strcpy(file_name, 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;
}
void VolumeData::init_from_modifier() {
Object *object = (Object *)this->id;
FluidModifierData *volume_modifier = (FluidModifierData *)BKE_modifiers_findby_type(
object, eModifierType_Fluid);
Mesh *mesh = BKE_object_to_mesh(nullptr, object, false);
write_transform();
float dims[3];
BKE_object_dimensions_get(object, dims);
double x = 0.0;
double y = 0.0;
double z = 0.0;
//if (mesh->texspace_size[0] != 1.0) {
// x += mesh->texspace_size[0] * mesh->texspace_location[0] / 4;
//}
//if (mesh->texspace_size[1] != 1.0) {
// y += mesh->texspace_size[1] * mesh->texspace_location[1] / 4;
//}
//if (mesh->texspace_size[2] != 1.0) {
// z += mesh->texspace_size[2] * mesh->texspace_location[2] / 4;
//}
if (mesh->texspace_size[0] != 1.0) {
x = mesh->texspace_size[0] * dims[0] * mesh->texspace_location[0] / 2;
}
if (mesh->texspace_size[1] != 1.0) {
y = mesh->texspace_size[1] * dims[1] * mesh->texspace_location[1] / 2;
}
if (mesh->texspace_size[2] != 1.0) {
z = mesh->texspace_size[2] * dims[2] * mesh->texspace_location[2] / 2;
}
//pxr::GfMatrix4d loc = pxr::GfMatrix4d(1.0).SetTranslate(pxr::GfVec3d(mesh->texspace_location) - pxr::GfVec3d(x, y, z));
pxr::GfMatrix4d loc = pxr::GfMatrix4d(1.0).SetTranslate(
pxr::GfVec3d(mesh->texspace_location) - pxr::GfVec3d(1.0 * mesh->texspace_size[0],
1.0 * mesh->texspace_size[1],
1.0 * mesh->texspace_size[2]));
pxr::GfMatrix4d size = pxr::GfMatrix4d(1.0).SetScale(pxr::GfVec3d(mesh->texspace_size));
pxr::GfMatrix4d trans = pxr::GfMatrix4d(1.0).SetTranslate(pxr::GfVec3d(-x, -y, -z));
//transform *= loc * size * trans;
pxr::GfMatrix4d scale = pxr::GfMatrix4d(1.0).SetScale(pxr::GfVec3d(
dims[0] / object->scale[0] / 2, dims[1] / object->scale[1] / 2, dims[2] / object->scale[2] / 2));
transform = transform * size * loc; // * trans;// * size;
BKE_object_to_mesh_clear(object);
filepath_ = get_cached_file_path(volume_modifier->domain->cache_directory,
scene_delegate_->scene->r.cfra);
for (auto &grid_name : supported_grids) {
field_descriptors_.emplace_back(grid_name,
pxr::UsdVolImagingTokens->openvdbAsset,
prim_id.AppendElementString("VF_" + grid_name.GetString()));
}
write_materials();
}
void VolumeData::init_from_volume()
{
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);
if (volume->runtime.grids) {
const int num_grids = BKE_volume_num_grids(volume);
if (num_grids) {
for (const int i : IndexRange(num_grids)) {
const VolumeGrid *grid = BKE_volume_grid_get_for_read(volume, i);
const std::string grid_name = BKE_volume_grid_name(grid);
field_descriptors_.emplace_back(pxr::TfToken(grid_name),
pxr::UsdVolImagingTokens->openvdbAsset,
prim_id.AppendElementString("VF_" + grid_name));
}
}
}
BKE_volume_unload(volume);
write_transform();
write_materials();
}
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

@ -5,6 +5,8 @@
#include <pxr/imaging/hd/sceneDelegate.h> #include <pxr/imaging/hd/sceneDelegate.h>
#include "BLI_set.hh"
#include "object.h" #include "object.h"
namespace blender::render::hydra { namespace blender::render::hydra {
@ -13,6 +15,7 @@ class VolumeData : public ObjectData {
public: public:
VolumeData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id); VolumeData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
static bool is_volume_modifier(Object *object);
void init() override; void init() override;
void insert() override; void insert() override;
@ -28,6 +31,9 @@ class VolumeData : public ObjectData {
private: private:
void write_materials(); void write_materials();
std::string get_cached_file_path(std::string directory, int frame);
void init_from_modifier();
void init_from_volume();
std::string filepath_; std::string filepath_;
pxr::HdVolumeFieldDescriptorVector field_descriptors_; pxr::HdVolumeFieldDescriptorVector field_descriptors_;