Blender V5.0
usd_utils.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "usd_utils.hh"
6
7#include "BLI_array.hh"
8#include "BLI_string_ref.hh"
9#include "BLI_string_utf8.h"
10
11#include <pxr/base/tf/stringUtils.h>
12#include <pxr/base/tf/unicodeUtils.h>
13#include <pxr/usd/usd/prim.h>
14#include <pxr/usd/usd/stage.h>
15
16namespace blender::io::usd {
17
18std::string make_safe_name(const StringRef name, bool allow_unicode)
19{
20 if (name.is_empty()) {
21 return "_";
22 }
23
24 /* Create temporary buffer with exact amount of space required. */
25 const bool has_leading_digit = std::isdigit(name[0]);
26 Array<char, 64> storage(name.size() + (has_leading_digit ? 1 : 0));
27 MutableSpan<char> buf(storage);
28
29 /* Insert a leading '_' to account for names starting with digits. */
30 size_t offset = 0;
31 bool first = true;
32 if (has_leading_digit) {
33 buf[0] = '_';
34 offset = 1;
35 first = false;
36 }
37
38 if (!allow_unicode) {
39 buf.take_back(name.size()).copy_from(name);
40 offset += name.size();
41 return pxr::TfMakeValidIdentifier({buf.data(), offset});
42 }
43
44 for (auto cp : pxr::TfUtf8CodePointView{name}) {
45 constexpr pxr::TfUtf8CodePoint cp_underscore = pxr::TfUtf8CodePointFromAscii('_');
46 const bool cp_allowed = first ? (cp == cp_underscore || pxr::TfIsUtf8CodePointXidStart(cp)) :
47 pxr::TfIsUtf8CodePointXidContinue(cp);
48 if (!cp_allowed) {
49 offset += BLI_str_utf8_from_unicode(uint32_t('_'), buf.data() + offset, buf.size() - offset);
50 }
51 else {
52 offset += BLI_str_utf8_from_unicode(cp.AsUInt32(), buf.data() + offset, buf.size() - offset);
53 }
54
55 first = false;
56 }
57
58 return {buf.data(), offset};
59}
60
61pxr::SdfPath get_unique_path(pxr::UsdStageRefPtr stage, const std::string &path)
62{
63 std::string unique_path = path;
64 int suffix = 2;
65 while (stage->GetPrimAtPath(pxr::SdfPath(unique_path)).IsValid()) {
66 unique_path = path + std::to_string(suffix++);
67 }
68
69 return pxr::SdfPath(unique_path);
70}
71
72} // namespace blender::io::usd
size_t BLI_str_utf8_from_unicode(unsigned int c, char *dst, size_t dst_maxncpy) ATTR_NONNULL(2)
constexpr int64_t size() const
Definition BLI_span.hh:493
constexpr MutableSpan take_back(const int64_t n) const
Definition BLI_span.hh:640
constexpr T * data() const
Definition BLI_span.hh:539
constexpr void copy_from(Span< T > values) const
Definition BLI_span.hh:739
pxr::SdfPath get_unique_path(pxr::UsdStageRefPtr stage, const std::string &path)
Definition usd_utils.cc:61
std::string make_safe_name(const StringRef name, bool allow_unicode)
Definition usd_utils.cc:18
const char * name