8#include <pxr/usd/ar/asset.h>
9#include <pxr/usd/ar/packageUtils.h>
10#include <pxr/usd/ar/resolver.h>
11#include <pxr/usd/ar/writableAsset.h>
48 for (
const std::string_view pattern :
patterns) {
49 const std::string::size_type
pos = path.find(pattern);
50 if (
pos != std::string::npos) {
51 return {path.substr(0,
pos), path.substr(
pos + pattern.size())};
64 if (pxr::ArIsPackageRelativePath(src_path)) {
65 std::pair<std::string, std::string> split = pxr::ArSplitPackageRelativePathInner(src_path);
66 if (split.second.empty()) {
69 "%s: Couldn't determine package-relative file name from path %s",
85 const char *dest_dir_path,
92 BLI_path_join(dest_file_path,
sizeof(dest_file_path), dest_dir_path, base_name.c_str());
96 return dest_file_path;
99 if (!
copy_asset(src_path, dest_file_path, name_collision_mode, reports)) {
102 "%s: Couldn't copy file %s to %s",
109 return dest_file_path;
113 const char *dest_dir_path,
119 if (splitPath.first.empty() || splitPath.second.empty()) {
132 const std::string src_udim = splitPath.first + std::to_string(i) + splitPath.second;
140 BLI_path_join(ret_udim_path,
sizeof(ret_udim_path), dest_dir_path, src_file_name.c_str());
146 if (splitPath.first.empty() || splitPath.second.empty()) {
148 return ret_udim_path;
151 return splitPath.first +
UDIM_PATTERN + splitPath.second;
163 const pxr::ArResolver &ar = pxr::ArGetResolver();
166 if (!ar.Resolve(dst).IsEmpty()) {
173 pxr::ArResolvedPath src_path = ar.Resolve(src);
175 if (src_path.IsEmpty()) {
180 pxr::ArResolvedPath dst_path = ar.ResolveForNewAsset(dst);
182 if (dst_path.IsEmpty()) {
187 if (src_path == dst_path) {
190 "%s: Can't copy %s. The source and destination paths are the same",
192 src_path.GetPathString().c_str());
197 if (!ar.CanWriteAssetToPath(dst_path, &why_not)) {
200 "%s: Can't write to asset %s: %s",
202 dst_path.GetPathString().c_str(),
207 std::shared_ptr<pxr::ArAsset> src_asset = ar.OpenAsset(src_path);
211 "%s: Can't open source asset %s",
213 src_path.GetPathString().c_str());
217 const size_t size = src_asset->GetSize();
222 "%s: Will not copy zero size source asset %s",
224 src_path.GetPathString().c_str());
228 std::shared_ptr<const char> buf = src_asset->GetBuffer();
233 "%s: Null buffer for source asset %s",
235 src_path.GetPathString().c_str());
239 std::shared_ptr<pxr::ArWritableAsset> dst_asset = ar.OpenAssetForWrite(
240 dst_path, pxr::ArResolver::WriteMode::Replace);
244 "%s: Can't open destination asset %s for writing",
246 src_path.GetPathString().c_str());
250 size_t bytes_written = dst_asset->Write(src_asset->GetBuffer().get(), src_asset->GetSize(), 0);
252 if (bytes_written == 0) {
255 "%s: Error writing to destination asset %s",
257 dst_path.GetPathString().c_str());
260 if (!dst_asset->Close()) {
263 "%s: Couldn't close destination asset %s",
265 dst_path.GetPathString().c_str());
269 return bytes_written > 0;
274 return path && !pxr::ArGetResolver().Resolve(path).IsEmpty();
278 const char *import_dir,
282 if (import_dir[0] ==
'\0') {
285 "%s: Texture import directory path empty, couldn't import %s",
292 STRNCPY(dest_dir_path, import_dir);
296 if (basepath[0] ==
'\0') {
299 "%s: import directory is relative "
300 "but the blend file path is empty. "
301 "Please save the blend file before importing the USD "
302 "or provide an absolute import directory path. "
309 STRNCPY(path_temp, dest_dir_path);
311 STRNCPY(dest_dir_path, path_temp);
319 "%s: Couldn't create texture import directory %s",
354 pxr::SdfLayerHandle layer =
stage->GetRootLayer();
356 if (layer->IsAnonymous()) {
358 RPT_WARNING,
"%s: Can't generate a textures directory path for anonymous stage", __func__);
362 const pxr::ArResolvedPath &stage_path = layer->GetResolvedPath();
364 if (stage_path.empty()) {
369 const pxr::ArResolver &ar = pxr::ArGetResolver();
372 std::string textures_dir = ar.CreateIdentifierForNewAsset(
"./textures", stage_path);
393 if (pxr::ArIsPackageRelativePath(path)) {
408 const pxr::ArResolver &ar = pxr::ArGetResolver();
410 std::string resolved_p1 = ar.ResolveForNewAsset(p1).GetPathString();
411 std::string resolved_p2 = ar.ResolveForNewAsset(p2).GetPathString();
413 return resolved_p1 == resolved_p2;
418 static bool inited =
false;
438 const pxr::ArResolver &ar = pxr::ArGetResolver();
439 pxr::ArResolvedPath resolved_path = ar.ResolveForNewAsset(path);
441 if (resolved_path.IsEmpty()) {
447 if (!ar.CanWriteAssetToPath(resolved_path, &why_not)) {
450 "Can't write to asset %s: %s",
451 resolved_path.GetPathString().c_str(),
456 std::shared_ptr<pxr::ArWritableAsset> dst_asset = ar.OpenAssetForWrite(
457 resolved_path, pxr::ArResolver::WriteMode::Replace);
461 "Can't open destination asset %s for writing",
462 resolved_path.GetPathString().c_str());
466 size_t bytes_written = dst_asset->Write(data, size, 0);
468 if (bytes_written == 0) {
471 "Error writing to destination asset %s",
472 resolved_path.GetPathString().c_str());
475 if (!dst_asset->Close()) {
478 "Couldn't close destination asset %s",
479 resolved_path.GetPathString().c_str());
483 return bytes_written > 0;
488 if (!
id || path.empty()) {
492 if (pxr::ArIsPackageRelativePath(path)) {
504 const char *prop_name =
"usd_source_path";
532 const char *prop_name =
"usd_source_path";
538 return static_cast<const char *
>(prop->
data.
pointer);
543 if (path.empty() || anchor.empty()) {
547 if (path == anchor) {
555 if (pxr::ArIsPackageRelativePath(path)) {
562 STRNCPY(rel_path, path.c_str());
581 const pxr::ArResolver &ar = pxr::ArGetResolver();
583 std::string resolved_path = ar.Resolve(path);
584 std::string resolved_anchor = ar.Resolve(anchor);
586 if (resolved_path.empty() || resolved_anchor.empty()) {
590 std::string prefix = pxr::TfStringGetCommonPrefix(path, anchor);
591 if (prefix.empty()) {
595 std::replace(prefix.begin(), prefix.end(),
'\\',
'/');
597 size_t last_slash_pos = prefix.find_last_of(
'/');
598 if (last_slash_pos == std::string::npos) {
608 resolved_path =
"/root" + resolved_path.substr(last_slash_pos);
609 resolved_anchor =
"/root" + resolved_anchor.substr(last_slash_pos);
614 if (anchor_parent_dir[0] ==
'\0') {
619 STRNCPY(result_path, resolved_path.c_str());
623 (result_path[0] ==
'/') && (result_path[1] ==
'/'))
627 return std::string(result_path + 2);
636 pxr::ArResolvedPath resolved_path = for_import ? pxr::ArGetResolver().Resolve(path) :
637 pxr::ArGetResolver().ResolveForNewAsset(path);
639 const std::string &path_str = resolved_path.GetPathString();
641 if (!path_str.empty()) {
647 "In %s: resolved path %s exceeds path buffer length.",
IDProperty * IDP_GetPropertyFromGroup(const IDProperty *prop, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
IDProperty * IDP_New(char type, const IDPropertyTemplate *val, const char *name, eIDPropertyFlag flags={}) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
bool IDP_AddToGroup(IDProperty *group, IDProperty *prop) ATTR_NONNULL()
IDProperty * IDP_EnsureProperties(ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
const char * BKE_main_blendfile_path_from_global()
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_assert_msg(a, msg)
bool BLI_dir_create_recursive(const char *dirname) ATTR_NONNULL()
bool BLI_is_file(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
bool BLI_is_dir(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
File and directory operations.
bool BLI_path_abs(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1
int BLI_path_normalize(char *path) ATTR_NONNULL(1)
#define BLI_path_join(...)
void void void BLI_path_split_file_part(const char *filepath, char *file, size_t file_maxncpy) ATTR_NONNULL(1
bool BLI_path_is_rel(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
void void BLI_path_split_dir_part(const char *filepath, char *dir, size_t dir_maxncpy) ATTR_NONNULL(1
bool void BLI_path_rel(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1)
#define STRNCPY(dst, src)
int char char int int int int size_t BLI_strnlen(const char *str, size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
void BLI_string_replace_char(char *str, char src, char dst) ATTR_NONNULL(1)
static const SubDPattern * patterns[]
static std::string copy_asset_to_directory(const char *src_path, const char *dest_dir_path, eUSDTexNameCollisionMode name_collision_mode, ReportList *reports)
bool asset_exists(const char *path)
const char * temp_textures_dir()
bool should_import_asset(const std::string &path)
std::string import_asset(const char *src, const char *import_dir, eUSDTexNameCollisionMode name_collision_mode, ReportList *reports)
static std::string copy_udim_asset_to_directory(const char *src_path, const char *dest_dir_path, eUSDTexNameCollisionMode name_collision_mode, ReportList *reports)
bool write_to_path(const void *data, size_t size, const char *path, ReportList *reports)
bool is_udim_path(const std::string &path)
bool paths_equal(const char *p1, const char *p2)
static std::string get_asset_base_name(const char *src_path, ReportList *reports)
std::string get_relative_path(const std::string &path, const std::string &anchor)
constexpr int UDIM_START_TILE
@ USD_TEX_NAME_COLLISION_USE_EXISTING
@ USD_TEX_NAME_COLLISION_OVERWRITE
constexpr char UDIM_PATTERN[]
void USD_path_abs(char *path, const char *basepath, bool for_import)
std::string get_export_textures_dir(const pxr::UsdStageRefPtr stage)
static std::pair< std::string, std::string > split_udim_pattern(const std::string &path)
constexpr int UDIM_END_TILE
std::string get_usd_source_path(ID *id)
void ensure_usd_source_path_prop(const std::string &path, ID *id)
constexpr char UDIM_PATTERN2[]
bool copy_asset(const char *src, const char *dst, eUSDTexNameCollisionMode name_collision_mode, ReportList *reports)
static bool parent_dir_exists_on_file_system(const std::string &path)
void * BKE_tempdir_session
struct IDPropertyTemplate::@29 string
void WM_reportf(eReportType type, const char *format,...)