5 #include <pxr/base/tf/pathUtils.h>
6 #include <pxr/usd/usdVol/openVDBAsset.h>
7 #include <pxr/usd/usdVol/volume.h>
47 auto vdb_file_path = resolve_vdb_file(volume);
48 if (!vdb_file_path.has_value()) {
50 "USD Export: failed to resolve .vdb file for object: %s",
56 if (
auto relative_vdb_file_path = construct_vdb_relative_file_path(*vdb_file_path)) {
57 vdb_file_path = relative_vdb_file_path;
61 "USD Export: couldn't construct relative file path for .vdb file, absolute path "
62 "will be used instead");
69 pxr::UsdVolVolume usd_volume = pxr::UsdVolVolume::Define(
stage, volume_path);
74 const std::string grid_id = pxr::TfMakeValidIdentifier(grid_name);
75 const pxr::SdfPath grid_path = volume_path.AppendPath(pxr::SdfPath(grid_id));
76 pxr::UsdVolOpenVDBAsset usd_grid = pxr::UsdVolOpenVDBAsset::Define(
stage, grid_path);
77 usd_grid.GetFieldNameAttr().Set(pxr::TfToken(grid_name), timecode);
78 usd_grid.GetFilePathAttr().Set(pxr::SdfAssetPath(*vdb_file_path), timecode);
79 usd_volume.CreateFieldRelationship(pxr::TfToken(grid_id), grid_path);
85 const pxr::VtArray<pxr::GfVec3f> volume_extent = {pxr::GfVec3f(&volume_bound_min[0]),
86 pxr::GfVec3f(&volume_bound_max[0])};
87 usd_volume.GetExtentAttr().Set(volume_extent, timecode);
93 std::optional<std::string> USDVolumeWriter::resolve_vdb_file(
const Volume *volume)
const
95 std::optional<std::string> vdb_file_path;
101 vdb_file_path = construct_vdb_file_path(volume);
108 if (!vdb_file_path.has_value()) {
110 if (vdb_file_path->empty()) {
115 return vdb_file_path;
118 std::optional<std::string> USDVolumeWriter::construct_vdb_file_path(
const Volume *volume)
const
121 if (usd_file_path.empty()) {
130 sizeof(usd_directory_path),
131 sizeof(usd_file_name));
133 if (usd_directory_path[0] ==
'\0' || usd_file_name[0] ==
'\0') {
137 const char *vdb_directory_name =
"volumes";
141 strcat(vdb_directory_path, vdb_directory_name);
147 if (!timecode.IsDefault()) {
148 const int frame = (int)timecode.GetValue();
152 strcat(vdb_file_name,
".vdb");
155 BLI_path_join(vdb_file_path,
sizeof(vdb_file_path), vdb_directory_path, vdb_file_name,
NULL);
157 return vdb_file_path;
160 std::optional<std::string> USDVolumeWriter::construct_vdb_relative_file_path(
161 const std::string &vdb_file_path)
const
164 if (usd_file_path.empty()) {
180 std::string relative_path_processed = pxr::TfNormPath(relative_path + 2);
181 if (relative_path_processed[0] !=
'.') {
182 relative_path_processed.insert(0,
"./");
185 return relative_path_processed;
const VolumeGrid * BKE_volume_grid_get_for_read(const struct Volume *volume, int grid_index)
void BKE_volume_unload(struct Volume *volume)
bool BKE_volume_save(const struct Volume *volume, const struct Main *bmain, struct ReportList *reports, const char *filepath)
const char * BKE_volume_grids_frame_filepath(const struct Volume *volume)
const char * BKE_volume_grid_name(const struct VolumeGrid *grid)
int BKE_volume_num_grids(const struct Volume *volume)
bool BKE_volume_load(const struct Volume *volume, const struct Main *bmain)
File and directory operations.
bool BLI_dir_create_recursive(const char *dir) ATTR_NONNULL()
MINLINE int integer_digits_i(int i)
bool BLI_path_is_rel(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
bool BLI_path_frame(char *path, int frame, int digits) ATTR_NONNULL()
void BLI_split_dirfile(const char *string, char *dir, char *file, size_t dirlen, size_t filelen)
size_t BLI_path_join(char *__restrict dst, size_t dst_len, const char *path_first,...) ATTR_NONNULL(1
void BLI_path_rel(char *file, const char *relfile) ATTR_NONNULL()
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
pxr::UsdTimeCode get_export_time_code() const
std::string get_export_file_path() const
const USDExporterContext usd_export_context_
virtual bool check_is_animated(const HierarchyContext &context) const override
virtual void do_write(HierarchyContext &context) override
USDVolumeWriter(const USDExporterContext &ctx)
const USDExportParams & export_params
const pxr::SdfPath usd_path
const pxr::UsdStageRefPtr stage
bool BKE_volume_min_max(const Volume *volume, float3 &r_min, float3 &r_max)
void WM_reportf(eReportType type, const char *format,...)