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>
12#include <pxr/usd/usd/common.h>
13#include <pxr/usd/usd/stage.h>
50 for (
const std::string_view pattern :
patterns) {
51 const std::string::size_type
pos = path.find(pattern);
52 if (
pos != std::string::npos) {
53 return {path.substr(0,
pos), path.substr(
pos + pattern.size())};
66 if (pxr::ArIsPackageRelativePath(src_path)) {
67 std::pair<std::string, std::string>
split = pxr::ArSplitPackageRelativePathInner(src_path);
68 if (
split.second.empty()) {
71 "%s: Couldn't determine package-relative file name from path %s",
87 const char *dest_dir_path,
94 BLI_path_join(dest_file_path,
sizeof(dest_file_path), dest_dir_path, base_name.c_str());
98 return dest_file_path;
104 "%s: Couldn't copy file %s to %s",
111 return dest_file_path;
115 const char *dest_dir_path,
121 if (splitPath.first.empty() || splitPath.second.empty()) {
134 const std::string src_udim = splitPath.first + std::to_string(
i) + splitPath.second;
142 BLI_path_join(ret_udim_path,
sizeof(ret_udim_path), dest_dir_path, src_file_name.c_str());
148 if (splitPath.first.empty() || splitPath.second.empty()) {
150 return ret_udim_path;
153 return splitPath.first +
UDIM_PATTERN + splitPath.second;
165 const pxr::ArResolver &ar = pxr::ArGetResolver();
168 if (!ar.Resolve(dst).IsEmpty()) {
175 pxr::ArResolvedPath src_path = ar.Resolve(src);
177 if (src_path.IsEmpty()) {
182 pxr::ArResolvedPath dst_path = ar.ResolveForNewAsset(dst);
184 if (dst_path.IsEmpty()) {
189 if (src_path == dst_path) {
192 "%s: Can't copy %s. The source and destination paths are the same",
194 src_path.GetPathString().c_str());
199 if (!ar.CanWriteAssetToPath(dst_path, &why_not)) {
202 "%s: Can't write to asset %s: %s",
204 dst_path.GetPathString().c_str(),
209 std::shared_ptr<pxr::ArAsset> src_asset = ar.OpenAsset(src_path);
213 "%s: Can't open source asset %s",
215 src_path.GetPathString().c_str());
219 const size_t size = src_asset->GetSize();
224 "%s: Will not copy zero size source asset %s",
226 src_path.GetPathString().c_str());
230 std::shared_ptr<const char> buf = src_asset->GetBuffer();
235 "%s: Null buffer for source asset %s",
237 src_path.GetPathString().c_str());
241 std::shared_ptr<pxr::ArWritableAsset> dst_asset = ar.OpenAssetForWrite(
242 dst_path, pxr::ArResolver::WriteMode::Replace);
246 "%s: Can't open destination asset %s for writing",
248 src_path.GetPathString().c_str());
252 size_t bytes_written = dst_asset->Write(src_asset->GetBuffer().get(), src_asset->GetSize(), 0);
254 if (bytes_written == 0) {
257 "%s: Error writing to destination asset %s",
259 dst_path.GetPathString().c_str());
262 if (!dst_asset->Close()) {
265 "%s: Couldn't close destination asset %s",
267 dst_path.GetPathString().c_str());
271 return bytes_written > 0;
276 return path && !pxr::ArGetResolver().Resolve(path).IsEmpty();
280 const char *import_dir,
284 if (import_dir[0] ==
'\0') {
287 "%s: Texture import directory path empty, couldn't import %s",
294 STRNCPY(dest_dir_path, import_dir);
298 if (basepath[0] ==
'\0') {
301 "%s: import directory is relative "
302 "but the blend file path is empty. "
303 "Please save the blend file before importing the USD "
304 "or provide an absolute import directory path. "
311 STRNCPY(path_temp, dest_dir_path);
313 STRNCPY(dest_dir_path, path_temp);
321 "%s: Couldn't create texture import directory %s",
356 pxr::SdfLayerHandle layer = stage->GetRootLayer();
358 if (layer->IsAnonymous()) {
360 RPT_WARNING,
"%s: Can't generate a textures directory path for anonymous stage", __func__);
364 const pxr::ArResolvedPath &stage_path = layer->GetResolvedPath();
366 if (stage_path.empty()) {
371 const pxr::ArResolver &ar = pxr::ArGetResolver();
374 std::string textures_dir = ar.CreateIdentifierForNewAsset(
"./textures", stage_path);
395 if (pxr::ArIsPackageRelativePath(path)) {
410 const pxr::ArResolver &ar = pxr::ArGetResolver();
412 std::string resolved_p1 = ar.ResolveForNewAsset(p1).GetPathString();
413 std::string resolved_p2 = ar.ResolveForNewAsset(p2).GetPathString();
415 return resolved_p1 == resolved_p2;
420 static bool inited =
false;
440 const pxr::ArResolver &ar = pxr::ArGetResolver();
441 pxr::ArResolvedPath resolved_path = ar.ResolveForNewAsset(path);
443 if (resolved_path.IsEmpty()) {
449 if (!ar.CanWriteAssetToPath(resolved_path, &why_not)) {
452 "Can't write to asset %s: %s",
453 resolved_path.GetPathString().c_str(),
458 std::shared_ptr<pxr::ArWritableAsset> dst_asset = ar.OpenAssetForWrite(
459 resolved_path, pxr::ArResolver::WriteMode::Replace);
463 "Can't open destination asset %s for writing",
464 resolved_path.GetPathString().c_str());
468 size_t bytes_written = dst_asset->Write(
data,
size, 0);
470 if (bytes_written == 0) {
473 "Error writing to destination asset %s",
474 resolved_path.GetPathString().c_str());
477 if (!dst_asset->Close()) {
480 "Couldn't close destination asset %s",
481 resolved_path.GetPathString().c_str());
485 return bytes_written > 0;
490 if (!
id || path.empty()) {
494 if (pxr::ArIsPackageRelativePath(path)) {
506 const StringRef prop_name =
"usd_source_path";
534 const StringRef prop_name =
"usd_source_path";
540 return static_cast<const char *
>(prop->
data.
pointer);
545 if (path.empty() || anchor.empty()) {
549 if (path == anchor) {
557 if (pxr::ArIsPackageRelativePath(path)) {
564 STRNCPY(rel_path, path.c_str());
582 const pxr::ArResolver &ar = pxr::ArGetResolver();
584 std::string resolved_path = ar.Resolve(path);
585 std::string resolved_anchor = ar.Resolve(anchor);
587 if (resolved_path.empty() || resolved_anchor.empty()) {
591 std::string prefix = pxr::TfStringGetCommonPrefix(path, anchor);
592 if (prefix.empty()) {
596 std::replace(prefix.begin(), prefix.end(),
'\\',
'/');
598 size_t last_slash_pos = prefix.find_last_of(
'/');
599 if (last_slash_pos == std::string::npos) {
609 resolved_path =
"/root" + resolved_path.substr(last_slash_pos);
610 resolved_anchor =
"/root" + resolved_anchor.substr(last_slash_pos);
615 if (anchor_parent_dir[0] ==
'\0') {
620 STRNCPY(result_path, resolved_path.c_str());
626 return std::string(result_path + 2);
635 pxr::ArResolvedPath resolved_path = for_import ? pxr::ArGetResolver().Resolve(path) :
636 pxr::ArGetResolver().ResolveForNewAsset(path);
638 const std::string &path_str = resolved_path.GetPathString();
640 if (!path_str.empty()) {
646 "In %s: resolved path %s exceeds path buffer length.",
IDProperty * IDP_GetPropertyFromGroup(const IDProperty *prop, blender::StringRef name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
IDProperty * IDP_New(char type, const IDPropertyTemplate *val, blender::StringRef 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)
char * STRNCPY(char(&dst)[N], const char *src)
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 void split(const char *text, const char *seps, char ***str, int *count)
BMesh const char void * data
static const SubDPattern * patterns[]
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
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::@322245216135312101230052362117316070016104030035 string
void WM_global_reportf(eReportType type, const char *format,...)